diff --git a/README.md b/README.md index a6d066c77..033031c97 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # centreon-plugins +[![License](https://img.shields.io/badge/License-APACHE2-brightgreen.svg)](https://github.com/centreon/centreon-plugins/blob/master/LICENSE.txt) +[![GitHub stars](https://img.shields.io/github/stars/centreon/centreon-plugins.svg)](https://github.com/centreon/centreon-plugins/stargazers) +[![GitHub forks](https://img.shields.io/github/forks/centreon/centreon-plugins.svg)](https://github.com/centreon/centreon-plugins/network) + “centreon-plugins” is a free and open source project to monitor systems. The project can be used with Centreon and all monitoring softwares compatible with Nagios plugins. You can monitor many systems: diff --git a/apps/activedirectory/local/mode/dfsrbacklog.pm b/apps/activedirectory/local/mode/dfsrbacklog.pm index 395cda9a2..538c3f094 100644 --- a/apps/activedirectory/local/mode/dfsrbacklog.pm +++ b/apps/activedirectory/local/mode/dfsrbacklog.pm @@ -33,7 +33,7 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'backlog', set => { + { label => 'backlog', nlabel => 'backlog.file.count', set => { key_values => [ { name => 'backlog' } ], output_template => 'Backlog File Count : %s', perfdatas => [ diff --git a/apps/antivirus/mcafee/webgateway/snmp/mode/versions.pm b/apps/antivirus/mcafee/webgateway/snmp/mode/versions.pm new file mode 100644 index 000000000..041cd431f --- /dev/null +++ b/apps/antivirus/mcafee/webgateway/snmp/mode/versions.pm @@ -0,0 +1,180 @@ +# +# Copyright 2019 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 apps::antivirus::mcafee::webgateway::snmp::mode::versions; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::statefile; +use Digest::MD5 qw(md5_hex); + +sub custom_version_calc { + my ($self, %options) = @_; + + $self->{result_values}->{output} = $options{extra_options}->{output_ref}; + $self->{result_values}->{version} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}}; + $self->{result_values}->{timestamp} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref} . '_timestamp'}; + $self->{result_values}->{since} = time() - $self->{result_values}->{timestamp}; + + return 0; +} + +sub custom_version_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{since}, + threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_version_output { + my ($self, %options) = @_; + + my $human_since = centreon::plugins::misc::change_seconds(value => $self->{result_values}->{since}); + my $msg = sprintf("%s: %s [Last update: %s]", $self->{result_values}->{output}, $self->{result_values}->{version}, $human_since); + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'dat-version', set => { + key_values => [ { name => 'pMFEDATVersion' }, { name => 'pMFEDATVersion_timestamp' } ], + closure_custom_calc => $self->can('custom_version_calc'), + closure_custom_calc_extra_options => { label_ref => 'pMFEDATVersion', output_ref => 'DAT Version' }, + closure_custom_output => $self->can('custom_version_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_version_threshold'), + } + }, + { label => 'tsdb-version', set => { + key_values => [ { name => 'pTSDBVersion' }, { name => 'pTSDBVersion_timestamp' } ], + closure_custom_calc => $self->can('custom_version_calc'), + closure_custom_calc_extra_options => { label_ref => 'pTSDBVersion', output_ref => 'TrustedSource Database Version' }, + closure_custom_output => $self->can('custom_version_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_version_threshold'), + } + }, + { label => 'proactive-version', set => { + key_values => [ { name => 'pAMProactiveVersion' }, { name => 'pAMProactiveVersion_timestamp' } ], + closure_custom_calc => $self->can('custom_version_calc'), + closure_custom_calc_extra_options => { label_ref => 'pAMProactiveVersion', output_ref => 'ProActive Database Version' }, + closure_custom_output => $self->can('custom_version_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_version_threshold'), + } + }, + ]; +} + +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-counters:s" => { name => 'filter_counters', default => '' }, + }); + + $self->{cache} = centreon::plugins::statefile->new(%options); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->{cache}->check_options(%options); +} + +my $oid_pMFEDATVersion = '.1.3.6.1.4.1.1230.2.7.1.20.4.0'; +my $oid_pAMProactiveVersion = '.1.3.6.1.4.1.1230.2.7.1.20.5.0'; +my $oid_pTSDBVersion = '.1.3.6.1.4.1.1230.2.7.1.20.6.0'; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{new_datas} = {}; + $self->{cache}->read(statefile => "mcafee_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all'))); + + my $results = $options{snmp}->get_leef(oids => [ $oid_pMFEDATVersion, $oid_pAMProactiveVersion, $oid_pTSDBVersion ], + nothing_quit => 1); + + $self->{global} = {}; + + $self->{new_datas} = { + pMFEDATVersion => $results->{$oid_pMFEDATVersion}, + pAMProactiveVersion => $results->{$oid_pAMProactiveVersion}, + pTSDBVersion => $results->{$oid_pTSDBVersion}, + }; + + foreach my $version (('pMFEDATVersion', 'pAMProactiveVersion', 'pTSDBVersion')) { + next if (!defined($self->{new_datas}->{$version}) || $self->{new_datas}->{$version} eq ''); + $self->{new_datas}->{$version . '_timestamp'} = ($self->{new_datas}->{$version} > $self->{cache}->{datas}->{$version}) ? time() : $self->{cache}->{datas}->{$version . '_timestamp'}; + $self->{new_datas}->{$version . '_timestamp'} = time() if (!defined($self->{new_datas}->{$version . '_timestamp'})); + } + + $self->{global} = { %{$self->{new_datas}} }; + + $self->{cache}->write(data => $self->{new_datas}); +} + +1; + +__END__ + +=head1 MODE + +Check signature databases versions +(last update is only guessed by version's changement, +it does not appear clearly in the MIB). + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +(Example: --filter-counters='dat') + +=item B<--warning-*> + +Threshold warning on last update. +Can be: 'dat-version', 'tsdb-version', 'proactive-version'. + +=item B<--critical-*> + +Threshold critical on last update. +Can be: 'dat-version', 'tsdb-version', 'proactive-version'. + +=back + +=cut diff --git a/apps/antivirus/mcafee/webgateway/snmp/plugin.pm b/apps/antivirus/mcafee/webgateway/snmp/plugin.pm index 49e246f89..5cbbb8416 100644 --- a/apps/antivirus/mcafee/webgateway/snmp/plugin.pm +++ b/apps/antivirus/mcafee/webgateway/snmp/plugin.pm @@ -38,6 +38,7 @@ sub new { 'ftp-statistics' => 'apps::antivirus::mcafee::webgateway::snmp::mode::ftpstatistics', 'http-statistics' => 'apps::antivirus::mcafee::webgateway::snmp::mode::httpstatistics', 'https-statistics' => 'apps::antivirus::mcafee::webgateway::snmp::mode::httpsstatistics', + 'versions' => 'apps::antivirus::mcafee::webgateway::snmp::mode::versions', ); return $self; diff --git a/apps/apache/serverstatus/mode/cpuload.pm b/apps/apache/serverstatus/mode/cpuload.pm index 076a0795a..1b0a0b331 100644 --- a/apps/apache/serverstatus/mode/cpuload.pm +++ b/apps/apache/serverstatus/mode/cpuload.pm @@ -32,24 +32,21 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/server-status/?auto" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "header:s@" => { name => 'header' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/server-status/?auto" }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "header:s@" => { name => 'header' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "timeout:s" => { name => 'timeout' }, + }); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -118,10 +115,6 @@ IP Addr/FQDN of the webserver host Port used by Apache -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Specify https if needed @@ -154,10 +147,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--header> Set HTTP headers (Multiple option) diff --git a/apps/apache/serverstatus/mode/requests.pm b/apps/apache/serverstatus/mode/requests.pm index 9a409d489..8fa141e58 100644 --- a/apps/apache/serverstatus/mode/requests.pm +++ b/apps/apache/serverstatus/mode/requests.pm @@ -33,28 +33,25 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/server-status/?auto" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "header:s@" => { name => 'header' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "warning-bytes:s" => { name => 'warning_bytes' }, - "critical-bytes:s" => { name => 'critical_bytes' }, - "warning-access:s" => { name => 'warning_access' }, - "critical-access:s" => { name => 'critical_access' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/server-status/?auto" }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "header:s@" => { name => 'header' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "warning-bytes:s" => { name => 'warning_bytes' }, + "critical-bytes:s" => { name => 'critical_bytes' }, + "warning-access:s" => { name => 'warning_access' }, + "critical-access:s" => { name => 'critical_access' }, + "timeout:s" => { name => 'timeout' }, + }); + $self->{http} = centreon::plugins::http->new(%options); $self->{statefile_value} = centreon::plugins::statefile->new(%options); return $self; } @@ -207,10 +204,6 @@ IP Addr/FQDN of the webserver host Port used by Apache -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Specify https if needed @@ -243,10 +236,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--header> Set HTTP headers (Multiple option) diff --git a/apps/apache/serverstatus/mode/responsetime.pm b/apps/apache/serverstatus/mode/responsetime.pm index f7f425b57..a10cdfd20 100644 --- a/apps/apache/serverstatus/mode/responsetime.pm +++ b/apps/apache/serverstatus/mode/responsetime.pm @@ -33,27 +33,24 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/server-status/?auto" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "header:s@" => { name => 'header' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "unknown-status:s" => { name => 'unknown_status', default => '' }, - "warning-status:s" => { name => 'warning_status' }, - "critical-status:s" => { name => 'critical_status', default => '%{http_code} < 200 or %{http_code} >= 300' }, - }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/server-status/?auto" }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "header:s@" => { name => 'header' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "timeout:s" => { name => 'timeout' }, + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status', default => '%{http_code} < 200 or %{http_code} >= 300' }, + }); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -142,18 +139,10 @@ Specify this option if you access server-status page over hidden basic authentic (Use with --credentials) -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--header> Set HTTP headers (Multiple option) diff --git a/apps/apache/serverstatus/mode/slotstates.pm b/apps/apache/serverstatus/mode/slotstates.pm index 6bf032970..b7df83972 100644 --- a/apps/apache/serverstatus/mode/slotstates.pm +++ b/apps/apache/serverstatus/mode/slotstates.pm @@ -20,124 +20,20 @@ package apps::apache::serverstatus::mode::slotstates; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; use centreon::plugins::http; -use centreon::plugins::values; - -my $instance_mode; - -my $maps_counters = { - global => { - '000_busy' => { set => { - key_values => [ { name => 'busy' }, { name => 'total' } ], - closure_custom_calc => \&custom_value_calc, closure_custom_calc_extra_options => { label_ref => 'busy' }, - closure_custom_output => \&custom_value_output, - closure_custom_threshold_check => \&custom_value_threshold, - closure_custom_perfdata => \&custom_value_perfdata, - } - }, - '001_free' => { set => { - key_values => [ { name => 'free' }, { name => 'total' } ], - closure_custom_calc => \&custom_value_calc, closure_custom_calc_extra_options => { label_ref => 'free' }, - closure_custom_output => \&custom_value_output, - closure_custom_threshold_check => \&custom_value_threshold, - closure_custom_perfdata => \&custom_value_perfdata, - } - }, - '002_waiting' => { set => { - key_values => [ { name => 'waiting' }, { name => 'total' } ], - closure_custom_calc => \&custom_value_calc, closure_custom_calc_extra_options => { label_ref => 'waiting' }, - closure_custom_output => \&custom_value_output, - closure_custom_threshold_check => \&custom_value_threshold, - closure_custom_perfdata => \&custom_value_perfdata, - } - }, - '003_starting' => { set => { - key_values => [ { name => 'starting' }, { name => 'total' } ], - closure_custom_calc => \&custom_value_calc, closure_custom_calc_extra_options => { label_ref => 'starting' }, - closure_custom_output => \&custom_value_output, - closure_custom_threshold_check => \&custom_value_threshold, - closure_custom_perfdata => \&custom_value_perfdata, - } - }, - '004_reading' => { set => { - key_values => [ { name => 'reading' }, { name => 'total' } ], - closure_custom_calc => \&custom_value_calc, closure_custom_calc_extra_options => { label_ref => 'reading' }, - closure_custom_output => \&custom_value_output, - closure_custom_threshold_check => \&custom_value_threshold, - closure_custom_perfdata => \&custom_value_perfdata, - } - }, - '005_sending' => { set => { - key_values => [ { name => 'sending' }, { name => 'total' } ], - closure_custom_calc => \&custom_value_calc, closure_custom_calc_extra_options => { label_ref => 'sending' }, - closure_custom_output => \&custom_value_output, - closure_custom_threshold_check => \&custom_value_threshold, - closure_custom_perfdata => \&custom_value_perfdata, - } - }, - '006_keepalive' => { set => { - key_values => [ { name => 'keepalive' }, { name => 'total' } ], - closure_custom_calc => \&custom_value_calc, closure_custom_calc_extra_options => { label_ref => 'keepalive' }, - closure_custom_output => \&custom_value_output, - closure_custom_threshold_check => \&custom_value_threshold, - closure_custom_perfdata => \&custom_value_perfdata, - } - }, - '007_dns-lookup' => { set => { - key_values => [ { name => 'dns_lookup' }, { name => 'total' } ], - closure_custom_calc => \&custom_value_calc, closure_custom_calc_extra_options => { label_ref => 'dns_lookup' }, - closure_custom_output => \&custom_value_output, - closure_custom_threshold_check => \&custom_value_threshold, - closure_custom_perfdata => \&custom_value_perfdata, - } - }, - '008_closing' => { set => { - key_values => [ { name => 'closing' }, { name => 'total' } ], - closure_custom_calc => \&custom_value_calc, closure_custom_calc_extra_options => { label_ref => 'closing' }, - closure_custom_output => \&custom_value_output, - closure_custom_threshold_check => \&custom_value_threshold, - closure_custom_perfdata => \&custom_value_perfdata, - } - }, - '009_logging' => { set => { - key_values => [ { name => 'logging' }, { name => 'total' } ], - closure_custom_calc => \&custom_value_calc, closure_custom_calc_extra_options => { label_ref => 'logging' }, - closure_custom_output => \&custom_value_output, - closure_custom_threshold_check => \&custom_value_threshold, - closure_custom_perfdata => \&custom_value_perfdata, - } - }, - '007_gracefuly-finished' => { set => { - key_values => [ { name => 'gracefuly_finished' }, { name => 'total' } ], - closure_custom_calc => \&custom_value_calc, closure_custom_calc_extra_options => { label_ref => 'gracefuly_finished' }, - closure_custom_output => \&custom_value_output, - closure_custom_threshold_check => \&custom_value_threshold, - closure_custom_perfdata => \&custom_value_perfdata, - } - }, - '007_idle-cleanup-worker' => { set => { - key_values => [ { name => 'idle_cleanup_worker' }, { name => 'total' } ], - closure_custom_calc => \&custom_value_calc, closure_custom_calc_extra_options => { label_ref => 'idle_cleanup_worker' }, - closure_custom_output => \&custom_value_output, - closure_custom_threshold_check => \&custom_value_threshold, - closure_custom_perfdata => \&custom_value_perfdata, - } - }, - }, -}; sub custom_value_threshold { my ($self, %options) = @_; my $exit = 'ok'; - if ($instance_mode->{option_results}->{units} eq '%') { - $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } else { - $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } return $exit; } @@ -146,19 +42,22 @@ sub custom_value_perfdata { my ($self, %options) = @_; my ($warning, $critical); - if ($instance_mode->{option_results}->{units} eq '%') { - $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1); - $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1); } else { - $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}); - $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}); + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}); } - $self->{output}->perfdata_add(label => $self->{result_values}->{label}, - value => $self->{result_values}->{used}, - warning => $warning, - critical => $critical, - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $self->{result_values}->{label}, + nlabel => $self->{nlabel}, + value => $self->{result_values}->{used}, + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{total} + ); } sub custom_value_output { @@ -188,129 +87,169 @@ sub custom_value_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', skipped_code => { -2 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'busy', nlabel => 'apache.slot.busy.count', set => { + key_values => [ { name => 'busy' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_value_calc'), closure_custom_calc_extra_options => { label_ref => 'busy' }, + closure_custom_output => $self->can('custom_value_output'), + closure_custom_threshold_check => $self->can('custom_value_threshold'), + closure_custom_perfdata => $self->can('custom_value_perfdata'), + } + }, + { label => 'free', nlabel => 'apache.slot.free.count', set => { + key_values => [ { name => 'free' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_value_calc'), closure_custom_calc_extra_options => { label_ref => 'free' }, + closure_custom_output => $self->can('custom_value_output'), + closure_custom_threshold_check => $self->can('custom_value_threshold'), + closure_custom_perfdata => $self->can('custom_value_perfdata'), + } + }, + { label => 'waiting', nlabel => 'apache.slot.waiting.count', set => { + key_values => [ { name => 'waiting' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_value_calc'), closure_custom_calc_extra_options => { label_ref => 'waiting' }, + closure_custom_output => $self->can('custom_value_output'), + closure_custom_threshold_check => $self->can('custom_value_threshold'), + closure_custom_perfdata => $self->can('custom_value_perfdata'), + } + }, + { label => 'starting', nlabel => 'apache.slot.starting.count', set => { + key_values => [ { name => 'starting' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_value_calc'), closure_custom_calc_extra_options => { label_ref => 'starting' }, + closure_custom_output => $self->can('custom_value_output'), + closure_custom_threshold_check => $self->can('custom_value_threshold'), + closure_custom_perfdata => $self->can('custom_value_perfdata'), + } + }, + { label => 'reading', nlabel => 'apache.slot.reading.count', set => { + key_values => [ { name => 'reading' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_value_calc'), closure_custom_calc_extra_options => { label_ref => 'reading' }, + closure_custom_output => $self->can('custom_value_output'), + closure_custom_threshold_check => $self->can('custom_value_threshold'), + closure_custom_perfdata => $self->can('custom_value_perfdata'), + } + }, + { label => 'sending', nlabel => 'apache.slot.sending.count', set => { + key_values => [ { name => 'sending' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_value_calc'), closure_custom_calc_extra_options => { label_ref => 'sending' }, + closure_custom_output => $self->can('custom_value_output'), + closure_custom_threshold_check => $self->can('custom_value_threshold'), + closure_custom_perfdata => $self->can('custom_value_perfdata'), + } + }, + { label => 'keepalive', nlabel => 'apache.slot.keepalive.count', set => { + key_values => [ { name => 'keepalive' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_value_calc'), closure_custom_calc_extra_options => { label_ref => 'keepalive' }, + closure_custom_output => $self->can('custom_value_output'), + closure_custom_threshold_check => $self->can('custom_value_threshold'), + closure_custom_perfdata => $self->can('custom_value_perfdata'), + } + }, + { label => 'dns-lookup', nlabel => 'apache.slot.dnslookup.count', set => { + key_values => [ { name => 'dns_lookup' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_value_calc'), closure_custom_calc_extra_options => { label_ref => 'dns_lookup' }, + closure_custom_output => $self->can('custom_value_output'), + closure_custom_threshold_check => $self->can('custom_value_threshold'), + closure_custom_perfdata => $self->can('custom_value_perfdata'), + } + }, + { label => 'closing', nlabel => 'apache.slot.closing.count', set => { + key_values => [ { name => 'closing' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_value_calc'), closure_custom_calc_extra_options => { label_ref => 'closing' }, + closure_custom_output => $self->can('custom_value_output'), + closure_custom_threshold_check => $self->can('custom_value_threshold'), + closure_custom_perfdata => $self->can('custom_value_perfdata'), + } + }, + { label => 'logging', nlabel => 'apache.slot.logging.count', set => { + key_values => [ { name => 'logging' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_value_calc'), closure_custom_calc_extra_options => { label_ref => 'logging' }, + closure_custom_output => $self->can('custom_value_output'), + closure_custom_threshold_check => $self->can('custom_value_threshold'), + closure_custom_perfdata => $self->can('custom_value_perfdata'), + } + }, + { label => 'gracefuly-finished', nlabel => 'apache.slot.gracefulyfinished.count', set => { + key_values => [ { name => 'gracefuly_finished' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_value_calc'), closure_custom_calc_extra_options => { label_ref => 'gracefuly_finished' }, + closure_custom_output => $self->can('custom_value_output'), + closure_custom_threshold_check => $self->can('custom_value_threshold'), + closure_custom_perfdata => $self->can('custom_value_perfdata'), + } + }, + { label => 'idle-cleanup-worker', nlabel => 'apache.slot.idlecleanupworker.count', set => { + key_values => [ { name => 'idle_cleanup_worker' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_value_calc'), closure_custom_calc_extra_options => { label_ref => 'idle_cleanup_worker' }, + closure_custom_output => $self->can('custom_value_output'), + closure_custom_threshold_check => $self->can('custom_value_threshold'), + closure_custom_perfdata => $self->can('custom_value_perfdata'), + } + }, + ]; +} + 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 => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/server-status/?auto" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "header:s@" => { name => 'header' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "units:s" => { name => 'units', default => '%' }, - }); - - $self->{http} = centreon::plugins::http->new(output => $self->{output}); - - foreach my $key (('global')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, - perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/server-status/?auto" }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "header:s@" => { name => 'header' }, + "timeout:s" => { name => 'timeout' }, + "units:s" => { name => 'units', default => '%' }, + }); + $self->{http} = centreon::plugins::http->new(%options); return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('global')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } + $self->SUPER::check_options(%options); - $instance_mode = $self; $self->{http}->set_options(%{$self->{option_results}}); } -sub run { +sub prefix_global_output { my ($self, %options) = @_; - - $self->manage_selection(); - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - - foreach (sort keys %{$maps_counters->{global}}) { - my $obj = $maps_counters->{global}->{$_}->{obj}; - - $obj->set(instance => 'global'); - - my ($value_check) = $obj->execute(values => $self->{global}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(); - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Slots $short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "Slots $long_msg"); - } - - $self->{output}->display(); - $self->{output}->exit(); + return 'Slots '; } sub manage_selection { my ($self, %options) = @_; - my $webcontent = $self->{http}->request(); + my ($webcontent) = $self->{http}->request(); my $ScoreBoard = ""; if ($webcontent =~ /^Scoreboard:\s+([^\s]+)/mi) { $ScoreBoard = $1; } - $self->{global} = { total => length($ScoreBoard), - free => ($ScoreBoard =~ tr/\.//), - busy => length($ScoreBoard) - ($ScoreBoard =~ tr/\.//), - waiting => ($ScoreBoard =~ tr/\_//), starting => ($ScoreBoard =~ tr/S//), - reading => ($ScoreBoard =~ tr/R//), sending => ($ScoreBoard =~ tr/W//), - keepalive => ($ScoreBoard =~ tr/K//), dns_lookup => ($ScoreBoard =~ tr/D//), - closing => ($ScoreBoard =~ tr/C//), logging => ($ScoreBoard =~ tr/L//), - gracefuly_finished => ($ScoreBoard =~ tr/G//), idle_cleanup_worker => ($ScoreBoard =~ tr/I//)}; + $self->{global} = { + total => length($ScoreBoard), + free => ($ScoreBoard =~ tr/\.//), + busy => length($ScoreBoard) - ($ScoreBoard =~ tr/\.//), + waiting => ($ScoreBoard =~ tr/\_//), starting => ($ScoreBoard =~ tr/S//), + reading => ($ScoreBoard =~ tr/R//), sending => ($ScoreBoard =~ tr/W//), + keepalive => ($ScoreBoard =~ tr/K//), dns_lookup => ($ScoreBoard =~ tr/D//), + closing => ($ScoreBoard =~ tr/C//), logging => ($ScoreBoard =~ tr/L//), + gracefuly_finished => ($ScoreBoard =~ tr/G//), idle_cleanup_worker => ($ScoreBoard =~ tr/I//) + }; } 1; @@ -331,10 +270,6 @@ IP Address or FQDN of the webserver host Port used by Apache -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Protocol used http or https @@ -367,10 +302,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--header> Set HTTP headers (Multiple option) diff --git a/apps/apache/serverstatus/mode/workers.pm b/apps/apache/serverstatus/mode/workers.pm index 9527b8c60..f94da1217 100644 --- a/apps/apache/serverstatus/mode/workers.pm +++ b/apps/apache/serverstatus/mode/workers.pm @@ -32,24 +32,21 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/server-status/?auto" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "header:s@" => { name => 'header' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/server-status/?auto" }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "header:s@" => { name => 'header' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "timeout:s" => { name => 'timeout' }, + }); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -122,10 +119,6 @@ IP Addr/FQDN of the webserver host Port used by Apache -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Protocol to use http or https, http is default @@ -158,10 +151,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--header> Set HTTP headers (Multiple option) @@ -176,4 +165,4 @@ Critical Threshold (%) of busy workers =back -=cut \ No newline at end of file +=cut diff --git a/apps/automation/ansible/cli/custom/cli.pm b/apps/automation/ansible/cli/custom/cli.pm new file mode 100644 index 000000000..508a9a09d --- /dev/null +++ b/apps/automation/ansible/cli/custom/cli.pm @@ -0,0 +1,179 @@ +# +# Copyright 2019 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 apps::automation::ansible::cli::custom::cli; + +use strict; +use warnings; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 50 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'ANSIBLE_LOAD_CALLBACK_PLUGINS=true ANSIBLE_STDOUT_CALLBACK=json ansible' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'CLI OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + return 0; +} + +sub execute { + my ($self, %options) = @_; + + $self->{output}->output_add(long_msg => "Command line: '" . $self->{option_results}->{command} . " " . $options{cmd_options} . "'", debug => 1); + + my ($response) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $options{cmd_options} + ); + + my $raw_results; + + eval { + $raw_results = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->output_add(long_msg => $response, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + + return $raw_results; +} + +sub ansible_list_hosts_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "$options{host_pattern} --module-name=setup"; + + return $cmd_options; +} + +sub ansible_list_hosts { + my ($self, %options) = @_; + + my $cmd_options = $self->ansible_list_hosts_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results; +} + +1; + +__END__ + +=head1 NAME + +Ansible CLI + +=head1 CLI OPTIONS + +Ansible CLI + +=over 8 + +=item B<--timeout> + +Set timeout in seconds (Default: 50). + +=item B<--sudo> + +Use 'sudo' to execute the command. + +=item B<--command> + +Command to get information (Default: 'ANSIBLE_LOAD_CALLBACK_PLUGINS=true ANSIBLE_STDOUT_CALLBACK=json ansible'). +Can be changed if you have output in a file. + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: none). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/apps/automation/ansible/cli/mode/discovery.pm b/apps/automation/ansible/cli/mode/discovery.pm new file mode 100644 index 000000000..7087bc164 --- /dev/null +++ b/apps/automation/ansible/cli/mode/discovery.pm @@ -0,0 +1,116 @@ +# +# Copyright 2019 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 apps::automation::ansible::cli::mode::discovery; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use JSON::XS; + +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 => { + "host-pattern:s" => { name => 'host_pattern', default => 'all' }, + "prettify" => { name => 'prettify' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + + my @disco_data; + my $disco_stats; + + $disco_stats->{start_time} = time(); + + my $result = $options{custom}->ansible_list_hosts(host_pattern => $self->{option_results}->{host_pattern}); + + $disco_stats->{end_time} = time(); + $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; + + foreach my $play (@{$result->{plays}}) { + foreach my $task (@{$play->{tasks}}) { + foreach my $host (keys %{$task->{hosts}}) { + my %host; + $host{ip} = $host; + $host{hostname} = $task->{hosts}->{$host}->{ansible_facts}->{ansible_hostname}; + $host{fqdn} = $task->{hosts}->{$host}->{ansible_facts}->{ansible_fqdn}; + $host{type} = $task->{hosts}->{$host}->{ansible_facts}->{ansible_system}; + $host{distribution} = $task->{hosts}->{$host}->{ansible_facts}->{ansible_distribution}; + $host{all_ips} = $task->{hosts}->{$host}->{ansible_facts}->{ansible_all_ipv4_addresses}; + push @disco_data, \%host; + } + } + } + + $disco_stats->{discovered_items} = @disco_data; + $disco_stats->{results} = \@disco_data; + + my $encoded_data; + eval { + if (defined($self->{option_results}->{prettify})) { + $encoded_data = JSON::XS->new->utf8->pretty->encode($disco_stats); + } else { + $encoded_data = JSON::XS->new->utf8->encode($disco_stats); + } + }; + if ($@) { + $encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}'; + } + + $self->{output}->output_add(short_msg => $encoded_data); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Resources discovery. + +=over 8 + +=item B<--host-pattern> + +Specify host pattern to look for (Default: 'all'). + +=item B<--prettify> + +Prettify JSON output. + +=back + +=cut diff --git a/apps/automation/ansible/cli/plugin.pm b/apps/automation/ansible/cli/plugin.pm new file mode 100644 index 000000000..14db5ee20 --- /dev/null +++ b/apps/automation/ansible/cli/plugin.pm @@ -0,0 +1,49 @@ +# +# Copyright 2019 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 apps::automation::ansible::cli::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'discovery' => 'apps::automation::ansible::cli::mode::discovery', + ); + + $self->{custom_modes}{cli} = 'apps::automation::ansible::cli::custom::cli'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Ansible using CLI. + +=cut diff --git a/apps/automation/ansible/tower/custom/towercli.pm b/apps/automation/ansible/tower/custom/towercli.pm new file mode 100644 index 000000000..a1bc10600 --- /dev/null +++ b/apps/automation/ansible/tower/custom/towercli.pm @@ -0,0 +1,254 @@ +# +# Copyright 2019 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 apps::automation::ansible::tower::custom::towercli; + +use strict; +use warnings; +use DateTime; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "host:s" => { name => 'host' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout', default => 50 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'tower-cli' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '' }, + "proxyurl:s" => { name => 'proxyurl' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'TOWERCLI OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + if (defined($self->{option_results}->{proxyurl}) && $self->{option_results}->{proxyurl} ne '') { + $ENV{HTTP_PROXY} = $self->{option_results}->{proxyurl}; + $ENV{HTTPS_PROXY} = $self->{option_results}->{proxyurl}; + } + + $self->{host} = (defined($self->{option_results}->{host})) ? $self->{option_results}->{host} : undef; + $self->{username} = (defined($self->{option_results}->{username})) ? $self->{option_results}->{username} : undef; + $self->{password} = (defined($self->{option_results}->{password})) ? $self->{option_results}->{password} : undef; + + return 0; +} + +sub execute { + my ($self, %options) = @_; + + $self->{output}->output_add(long_msg => "Command line: '" . $self->{option_results}->{command} . " " . $options{cmd_options} . "'", debug => 1); + + my ($response) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $options{cmd_options}); + + my $raw_results; + + eval { + $raw_results = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->output_add(long_msg => $response, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + + return $raw_results; +} + +sub tower_list_hosts_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "host list --insecure --all-pages --format json"; + $cmd_options .= " --tower-host '$self->{host}'" if (defined($self->{host}) && $self->{host} ne ''); + $cmd_options .= " --tower-username '$self->{username}'" if (defined($self->{username}) && $self->{username} ne ''); + $cmd_options .= " --tower-password '$self->{password}'" if (defined($self->{password}) && $self->{password} ne ''); + $cmd_options .= " --group '$options{group}'" if (defined($options{group}) && $options{group} ne ''); + $cmd_options .= " --inventory '$options{inventory}'" if (defined($options{inventory}) && $options{inventory} ne ''); + + return $cmd_options; +} + +sub tower_list_hosts { + my ($self, %options) = @_; + + my $cmd_options = $self->tower_list_hosts_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results; +} + +sub tower_list_inventories_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "inventory list --insecure --all-pages --format json"; + $cmd_options .= " --tower-host '$self->{host}'" if (defined($self->{host}) && $self->{host} ne ''); + $cmd_options .= " --tower-username '$self->{username}'" if (defined($self->{username}) && $self->{username} ne ''); + $cmd_options .= " --tower-password '$self->{password}'" if (defined($self->{password}) && $self->{password} ne ''); + + return $cmd_options; +} + +sub tower_list_inventories { + my ($self, %options) = @_; + + my $cmd_options = $self->tower_list_inventories_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results; +} + +sub tower_list_projects_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = "project list --insecure --all-pages --format json"; + $cmd_options .= " --tower-host '$self->{host}'" if (defined($self->{host}) && $self->{host} ne ''); + $cmd_options .= " --tower-username '$self->{username}'" if (defined($self->{username}) && $self->{username} ne ''); + $cmd_options .= " --tower-password '$self->{password}'" if (defined($self->{password}) && $self->{password} ne ''); + + return $cmd_options; +} + +sub tower_list_projects { + my ($self, %options) = @_; + + my $cmd_options = $self->tower_list_projects_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results; +} + +1; + +__END__ + +=head1 NAME + +Ansible Tower CLI + +=head1 TOWERCLI OPTIONS + +Ansible Tower CLI + +To install the Tower CLI : https://docs.ansible.com/ansible-tower/latest/html/towerapi/tower_cli.html#installation + +=over 8 + +=item B<--host> + +Ansible Tower host (Default uses setting in 'tower config'). + +=item B<--username> + +Ansible Tower username (Default uses setting in 'tower config'). + +=item B<--password> + +Ansible Tower password (Default uses setting in 'tower config'). + +=item B<--timeout> + +Set timeout in seconds (Default: 50). + +=item B<--sudo> + +Use 'sudo' to execute the command. + +=item B<--command> + +Command to get information (Default: 'tower-cli'). +Can be changed if you have output in a file. + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: none). + +=item B<--proxyurl> + +Proxy URL if any + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/apps/automation/ansible/tower/mode/dashboard.pm b/apps/automation/ansible/tower/mode/dashboard.pm new file mode 100644 index 000000000..a6d00946a --- /dev/null +++ b/apps/automation/ansible/tower/mode/dashboard.pm @@ -0,0 +1,176 @@ +# +# Copyright 2019 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 apps::automation::ansible::tower::mode::dashboard; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_output'}, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'hosts-total', nlabel => 'hosts.total.count', set => { + key_values => [ { name => 'hosts_total' } ], + output_template => 'Hosts Total: %d', + perfdatas => [ + { value => 'hosts_total_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'hosts-failed', nlabel => 'hosts.failed.count', set => { + key_values => [ { name => 'hosts_failed' },{ name => 'hosts_total' } ], + output_template => 'Hosts Failed: %d', + perfdatas => [ + { value => 'hosts_failed_absolute', template => '%d', min => 0, + max => 'hosts_total_absolute' }, + ], + } + }, + { label => 'inventories-total', nlabel => 'inventories.total.count', set => { + key_values => [ { name => 'inventories_total' } ], + output_template => 'Inventories Total: %d', + perfdatas => [ + { value => 'inventories_total_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'inventories-sync-failed', nlabel => 'inventories.sync.failed.count', set => { + key_values => [ { name => 'inventories_sync_failed' }, { name => 'inventories_total' } ], + output_template => 'Inventories Sync Failed: %d', + perfdatas => [ + { value => 'inventories_sync_failed_absolute', template => '%d', min => 0, + max => 'inventories_total_absolute' }, + ], + } + }, + { label => 'projects-total', nlabel => 'projects.total.count', set => { + key_values => [ { name => 'projects_total' } ], + output_template => 'Projects Total: %d', + perfdatas => [ + { value => 'projects_total_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'projects-sync-failed', nlabel => 'projects.sync.failed.count', set => { + key_values => [ { name => 'projects_sync_failed' }, { name => 'projects_total' } ], + output_template => 'Projects Sync Failed: %d', + perfdatas => [ + { value => 'projects_sync_failed_absolute', template => '%d', min => 0, + max => 'projects_total_absolute' }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global} = { + hosts_total => 0, hosts_failed => 0, + inventories_total => 0, inventories_sync_failed => 0, + projects_total => 0, projects_sync_failed => 0 + }; + + my $hosts = $options{custom}->tower_list_hosts(); + $self->{global}->{hosts_total} = $hosts->{count}; + foreach my $host (@{$hosts->{results}}) { + $self->{global}->{hosts_failed}++ if ($host->{has_active_failures}); + } + + my $inventories = $options{custom}->tower_list_inventories(); + $self->{global}->{inventories_total} = $inventories->{count}; + foreach my $inventory (@{$inventories->{results}}) { + $self->{global}->{inventories_sync_failed}++ if ($inventory->{inventory_sources_with_failures} > 0); + } + + my $projects = $options{custom}->tower_list_projects(); + $self->{global}->{projects_total} = $projects->{count}; + foreach my $project (@{$projects->{results}}) { + $self->{global}->{projects_sync_failed}++ if ($project->{status} =~ /failed|canceled/); + } +} + +1; + +__END__ + +=head1 MODE + +Check several counters available through Tower dashboard. + +=over 8 + +=item B<--warning-hosts-*-count> + +Threshold warning. +Can be: 'total', 'failed'. + +=item B<--critical-hosts-*-count> + +Threshold critical. +Can be: 'total', 'failed'. + +=item B<--warning-inventories-*-count> + +Threshold warning. +Can be: 'total', 'sync-failed'. + +=item B<--critical-inventories-*-count> + +Threshold critical. +Can be: 'total', 'sync-failed'. + +=item B<--warning-projects-*-count> + +Threshold warning. +Can be: 'total', 'sync-failed'. + +=item B<--critical-projects-*-count> + +Threshold critical. +Can be: 'total', 'sync-failed'. + +=back + +=cut diff --git a/apps/automation/ansible/tower/mode/discovery.pm b/apps/automation/ansible/tower/mode/discovery.pm new file mode 100644 index 000000000..940a7dce9 --- /dev/null +++ b/apps/automation/ansible/tower/mode/discovery.pm @@ -0,0 +1,122 @@ +# +# Copyright 2019 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 apps::automation::ansible::tower::mode::discovery; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use JSON::XS; + +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 => { + "group" => { name => 'group' }, + "inventory" => { name => 'inventory' }, + "prettify" => { name => 'prettify' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + + my @disco_data; + my $disco_stats; + + $disco_stats->{start_time} = time(); + + my $hosts = $options{custom}->tower_list_hosts( + group => $self->{option_results}->{group}, + inventory => $self->{option_results}->{inventory} + ); + + $disco_stats->{end_time} = time(); + $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; + + foreach my $host (@{$hosts->{results}}) { + my %host; + $host{name} = $host->{name}; + $host{id} = $host->{id}; + $host{description} = $host->{description}; + $host{type} = $host->{type}; + $host{inventory_id} = $host->{inventory}; + $host{inventory_name} = $host->{summary_fields}->{inventory}->{name}; + $host{groups} = $host->{summary_fields}->{groups}->{results}; + $host{enabled} = $host->{enabled}; + push @disco_data, \%host; + } + + $disco_stats->{discovered_items} = @disco_data; + $disco_stats->{results} = \@disco_data; + + my $encoded_data; + eval { + if (defined($self->{option_results}->{prettify})) { + $encoded_data = JSON::XS->new->utf8->pretty->encode($disco_stats); + } else { + $encoded_data = JSON::XS->new->utf8->encode($disco_stats); + } + }; + if ($@) { + $encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}'; + } + + $self->{output}->output_add(short_msg => $encoded_data); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Resources discovery. + +=over 8 + +=item B<--group> + +Specify host group. + +=item B<--inventory> + +Specify host inventory. + +=item B<--prettify> + +Prettify JSON output. + +=back + +=cut diff --git a/apps/automation/ansible/tower/mode/inventorystatistics.pm b/apps/automation/ansible/tower/mode/inventorystatistics.pm new file mode 100644 index 000000000..35d2609ee --- /dev/null +++ b/apps/automation/ansible/tower/mode/inventorystatistics.pm @@ -0,0 +1,220 @@ +# +# Copyright 2019 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 apps::automation::ansible::tower::mode::inventorystatistics; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_output', cb_init => 'skip_global' }, + { name => 'inventories', type => 1, cb_prefix_output => 'prefix_output_inventories', + message_multiple => 'All inventories statistics are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total', nlabel => 'inventories.total.count', set => { + key_values => [ { name => 'total' } ], + output_template => 'Total: %d', + perfdatas => [ + { value => 'total_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'failed', nlabel => 'inventories.failed.count', set => { + key_values => [ { name => 'failed' }, { name => 'total' } ], + output_template => 'Failed: %d', + perfdatas => [ + { value => 'failed_absolute', template => '%d', min => 0, + max => 'total_absolute' }, + ], + } + }, + ]; + $self->{maps_counters}->{inventories} = [ + { label => 'hosts-total', nlabel => 'inventory.hosts.total.count', set => { + key_values => [ { name => 'total_hosts' }, { name => 'display' } ], + output_template => 'Hosts total: %d', + perfdatas => [ + { value => 'total_hosts_absolute', template => '%d', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'hosts-failed', nlabel => 'inventory.hosts.failed.count', set => { + key_values => [ { name => 'hosts_with_active_failures' }, { name => 'total_hosts' }, + { name => 'display' } ], + output_template => 'Hosts failed: %d', + perfdatas => [ + { value => 'hosts_with_active_failures_absolute', template => '%d', + min => 0, max => 'total_hosts_absolute', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'sources-total', nlabel => 'inventory.sources.total.count', set => { + key_values => [ { name => 'total_inventory_sources' }, { name => 'display' } ], + output_template => 'Sources total: %d', + perfdatas => [ + { value => 'total_inventory_sources_absolute', template => '%d', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'sources-failed', nlabel => 'inventory.sources.failed.count', set => { + key_values => [ { name => 'inventory_sources_with_failures' }, { name => 'total_inventory_sources' }, + { name => 'display' } ], + output_template => 'Sources failed: %d', + perfdatas => [ + { value => 'inventory_sources_with_failures_absolute', template => '%d', + min => 0, max => 'total_inventory_sources_absolute', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'groups-total', nlabel => 'inventory.groups.total.count', set => { + key_values => [ { name => 'total_groups' }, { name => 'display' } ], + output_template => 'Groups total: %d', + perfdatas => [ + { value => 'total_groups_absolute', template => '%d', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'groups-failed', nlabel => 'inventory.groups.failed.count', set => { + key_values => [ { name => 'groups_with_active_failures' }, { name => 'total_groups' }, + { name => 'display' } ], + output_template => 'Groups failed: %d', + perfdatas => [ + { value => 'groups_with_active_failures_absolute', template => '%d', + min => 0, max => 'total_groups_absolute', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub skip_global { + my ($self, %options) = @_; + + scalar(keys %{$self->{inventories}}) > 1 ? return(0) : return(1); +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Inventories "; +} + +sub prefix_output_inventories { + my ($self, %options) = @_; + + return "Inventory '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-inventory" => { name => 'filter_inventory' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global} = { total => 0, failed => 0 }; + + my $inventories = $options{custom}->tower_list_inventories(); + + $self->{global}->{total} = $inventories->{count}; + + foreach my $inventory (@{$inventories->{results}}) { + next if (defined($self->{option_results}->{filter_inventory}) && $self->{option_results}->{filter_inventory} ne '' + && $inventory->{name} !~ /$self->{option_results}->{filter_inventory}/); + + $self->{inventories}->{$inventory->{id}} = { + display => $inventory->{name}, + total_hosts => $inventory->{total_hosts}, + hosts_with_active_failures => $inventory->{hosts_with_active_failures}, + total_inventory_sources => $inventory->{total_inventory_sources}, + inventory_sources_with_failures => $inventory->{inventory_sources_with_failures}, + total_groups => $inventory->{total_groups}, + groups_with_active_failures => $inventory->{groups_with_active_failures}, + }; + + $self->{global}->{failed}++ if ($inventory->{has_active_failures}); + } +} + +1; + +__END__ + +=head1 MODE + +Check inventories statistics. + +=over 8 + +=item B<--filter-inventory> + +Filter inventory name (Can use regexp). + +=item B<--warning-inventories-*-count> + +Threshold warning. +Can be: 'total', 'failed'. + +=item B<--critical-inventories-*-count> + +Threshold critical. +Can be: 'total', 'failed'. + +=item B<--warning-instance-inventory.*.*.count> + +Threshold warning. +Can be 'hosts', 'sources', 'groups' and 'total', 'failed'. + +=item B<--critical-instance-inventory.*.*.count> + +Threshold critical. +Can be 'hosts', 'sources', 'groups' and 'total', 'failed' +'indexes'. + +=back + +=cut diff --git a/apps/automation/ansible/tower/plugin.pm b/apps/automation/ansible/tower/plugin.pm new file mode 100644 index 000000000..092e57d28 --- /dev/null +++ b/apps/automation/ansible/tower/plugin.pm @@ -0,0 +1,51 @@ +# +# Copyright 2019 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 apps::automation::ansible::tower::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'dashboard' => 'apps::automation::ansible::tower::mode::dashboard', + 'discovery' => 'apps::automation::ansible::tower::mode::discovery', + 'inventory-statistics' => 'apps::automation::ansible::tower::mode::inventorystatistics', + ); + + $self->{custom_modes}{towercli} = 'apps::automation::ansible::tower::custom::towercli'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Ansible Tower using API (tower-cli or RestAPI). + +=cut diff --git a/apps/backup/netbackup/local/mode/jobstatus.pm b/apps/backup/netbackup/local/mode/jobstatus.pm index 3794feb12..f07bdd3ae 100644 --- a/apps/backup/netbackup/local/mode/jobstatus.pm +++ b/apps/backup/netbackup/local/mode/jobstatus.pm @@ -204,31 +204,30 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'bpdbjobs' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '-report -most_columns' }, - "exec-only" => { name => 'exec_only' }, - "filter-policy-name:s" => { name => 'filter_policy_name' }, - "filter-type:s" => { name => 'filter_type' }, - "filter-end-time:s" => { name => 'filter_end_time', default => 86400 }, - "filter-start-time:s" => { name => 'filter_start_time' }, - "ok-status:s" => { name => 'ok_status', default => '%{status} == 0' }, - "warning-status:s" => { name => 'warning_status', default => '%{status} == 1' }, - "critical-status:s" => { name => 'critical_status', default => '%{status} > 1' }, - "warning-long:s" => { name => 'warning_long' }, - "critical-long:s" => { name => 'critical_long' }, - "warning-frozen:s" => { name => 'warning_frozen' }, - "critical-frozen:s" => { name => 'critical_frozen', default => '%{state} =~ /active|queue/ && %{kb} == 0' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'bpdbjobs' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-report -most_columns' }, + "exec-only" => { name => 'exec_only' }, + "filter-policy-name:s" => { name => 'filter_policy_name' }, + "filter-type:s" => { name => 'filter_type' }, + "filter-end-time:s" => { name => 'filter_end_time', default => 86400 }, + "filter-start-time:s" => { name => 'filter_start_time' }, + "ok-status:s" => { name => 'ok_status', default => '%{status} == 0' }, + "warning-status:s" => { name => 'warning_status', default => '%{status} == 1' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} > 1' }, + "warning-long:s" => { name => 'warning_long' }, + "critical-long:s" => { name => 'critical_long' }, + "warning-frozen:s" => { name => 'warning_frozen' }, + "critical-frozen:s" => { name => 'critical_frozen', default => '%{state} =~ /active|queue/ && %{kb} == 0' }, + }); return $self; } @@ -237,8 +236,10 @@ sub check_options { my ($self, %options) = @_; $self->SUPER::check_options(%options); - $self->change_macros(macros => ['ok_status', 'warning_status', 'critical_status', 'warning_long', - 'critical_long', 'warning_frozen', 'critical_frozen']); + $self->change_macros(macros => [ + 'ok_status', 'warning_status', 'critical_status', 'warning_long', + 'critical_long', 'warning_frozen', 'critical_frozen'] + ); } sub policy_long_output { diff --git a/apps/backup/netbackup/local/mode/tapeusage.pm b/apps/backup/netbackup/local/mode/tapeusage.pm index f2a40f600..fe881099d 100644 --- a/apps/backup/netbackup/local/mode/tapeusage.pm +++ b/apps/backup/netbackup/local/mode/tapeusage.pm @@ -26,20 +26,18 @@ use strict; use warnings; use centreon::plugins::misc; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } @@ -56,10 +54,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); return $exit; @@ -113,33 +111,25 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'vmquery' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '-a -w' }, - "filter-scratch:s" => { name => 'filter_scratch', default => 'scratch' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'vmquery' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-a -w' }, + "filter-scratch:s" => { name => 'filter_scratch', default => 'scratch' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/apps/backup/quadstor/local/mode/vtldiskusage.pm b/apps/backup/quadstor/local/mode/vtldiskusage.pm index 31cc74dc1..930a0a6fa 100644 --- a/apps/backup/quadstor/local/mode/vtldiskusage.pm +++ b/apps/backup/quadstor/local/mode/vtldiskusage.pm @@ -51,19 +51,21 @@ sub custom_usage_perfdata { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -76,7 +78,7 @@ sub custom_usage_threshold { $threshold_value = $self->{result_values}->{prct_used}; $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } diff --git a/apps/backup/quadstor/local/mode/vtltapeusage.pm b/apps/backup/quadstor/local/mode/vtltapeusage.pm index 370d845c5..7a3f5d755 100644 --- a/apps/backup/quadstor/local/mode/vtltapeusage.pm +++ b/apps/backup/quadstor/local/mode/vtltapeusage.pm @@ -51,19 +51,21 @@ sub custom_usage_perfdata { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -76,7 +78,7 @@ sub custom_usage_threshold { $threshold_value = $self->{result_values}->{prct_used}; $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } diff --git a/apps/bind9/web/custom/api.pm b/apps/bind9/web/custom/api.pm new file mode 100644 index 000000000..aab1dea65 --- /dev/null +++ b/apps/bind9/web/custom/api.pm @@ -0,0 +1,452 @@ +# +# Copyright 2019 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 apps::bind9::web::custom::api; + +use strict; +use warnings; +use centreon::plugins::misc; +use centreon::plugins::http; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "url-path:s" => { name => 'url_path' }, + "timeout:s" => { name => 'timeout' }, + "unknown-status:s" => { name => 'unknown_status', default => '%{http_code} < 200 or %{http_code} >= 300' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{http} = centreon::plugins::http->new(%options); + + return $self; + +} + +# Method to manage multiples +sub set_options { + my ($self, %options) = @_; + # options{options_result} + + $self->{option_results} = $options{option_results}; +} + +# Method to manage multiples +sub set_defaults { + my ($self, %options) = @_; + # options{default} + + # Manage default value + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : undef; + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 8080; + $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'http'; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; + $self->{url_path} = (defined($self->{option_results}->{url_path})) ? $self->{option_results}->{url_path} : '/'; + $self->{unknown_status} = (defined($self->{option_results}->{unknown_status})) ? $self->{option_results}->{unknown_status} : undef; + $self->{warning_status} = (defined($self->{option_results}->{warning_status})) ? $self->{option_results}->{warning_status} : undef; + $self->{critical_status} = (defined($self->{option_results}->{critical_status})) ? $self->{option_results}->{critical_status} : undef; + + if (!defined($self->{hostname})) { + $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); + $self->{output}->option_exit(); + } + + return 0; +} + +sub get_uniq_id { + my ($self, %options) = @_; + + return $self->{hostname} . '_' . $self->{port}; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{url_path} = $self->{url_path}; + $self->{option_results}->{unknown_status} = $self->{unknown_status}; + $self->{option_results}->{warning_status} = $self->{warning_status}; + $self->{option_results}->{critical_status} = $self->{critical_status}; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub load_response { + my ($self, %options) = @_; + + if ($self->{response_type} eq 'xml') { + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'XML::XPath', + error_msg => "Cannot load module 'XML::XPath'."); + eval { + $self->{xpath_response} = XML::XPath->new(xml => $options{response}); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot load XML response"); + $self->{output}->option_exit(); + } + } +} + +sub request { + my ($self, %options) = @_; + + $self->settings(); + my $response = $self->{http}->request(); + + my ($content_type) = $self->{http}->get_header(name => 'Content-Type'); + if (!defined($content_type) || $content_type !~ /(xml|json)/i) { + $self->{output}->add_option_msg(short_msg => "content-type not set"); + $self->{output}->option_exit(); + } + + $self->{response_type} = $1; + if ($self->{response_type} eq 'json') { + $self->{output}->add_option_msg(short_msg => "json format unsupported"); + $self->{output}->option_exit(); + } + + $self->load_response(response => $response); + my $method = $self->can("get_api_version_$self->{response_type}"); + if (!defined($method)) { + $self->{output}->add_option_msg(short_msg => "method 'get_api_version_$self->{response_type}' unsupported"); + $self->{output}->option_exit(); + } + $self->$method(); + if (!defined($self->{api_version}) || $self->{api_version} !~ /^(\d+)/) { + $self->{output}->add_option_msg(short_msg => "cannot get api version"); + $self->{output}->option_exit(); + } + + $self->{api_version} = $1; +} + +sub get_api_version_xml { + my ($self, %options) = @_; + + eval { + my $nodesets = $self->{xpath_response}->find('//statistics/@version'); + my $node = $nodesets->get_node(1); + $self->{api_version} = $node->getNodeValue(); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot lookup: $@"); + $self->{output}->option_exit(); + } +} + +sub load_memory_xml_v3 { + my ($self, %options) = @_; + + my $memory = {}; + + my $nodesets = $self->{xpath_response}->find('//memory/summary'); + my $node_memory = $nodesets->get_node(1); + foreach my $node ($node_memory->getChildNodes()) { + my $name = $node->getLocalName(); + next if (!defined($name)); + if ($name eq 'TotalUse') { + $memory->{total_use} = $node->string_value; + } + if ($name eq 'InUse') { + $memory->{in_use} = $node->string_value; + } + } + + return $memory; +} + +sub load_memory_xml_v2 { + my ($self, %options) = @_; + + return $self->load_memory_xml_v3(); +} + +sub load_zones_xml_v3 { + my ($self, %options) = @_; + + my $zones = {}; + my $nodesets = $self->{xpath_response}->find('//views//zones/zone'); + foreach my $node ($nodesets->get_nodelist()) { + my $name = $node->getAttribute('name'); + next if (!defined($name)); + $zones->{$name} = { counters => { rcode => {}, qtype => {} } }; + foreach my $counters_node ($node->getChildNodes()) { + next if ($counters_node->getLocalName() ne 'counters'); + my $type = $counters_node->getAttribute('type'); + foreach my $counter_node ($counters_node->getChildNodes()) { + my $counter_name = $counter_node->getAttribute('name'); + $zones->{$name}->{counters}->{$type}->{$counter_name} = $counter_node->string_value; + } + } + } + + return $zones; +} + +sub load_zones_xml_v2 { + my ($self, %options) = @_; + + my $zones = {}; + my $nodesets = $self->{xpath_response}->find('//views//zones/zone'); + foreach my $node ($nodesets->get_nodelist()) { + my $name; + my $counters = {}; + foreach my $subnode ($node->getChildNodes()) { + my $tag_name = $subnode->getLocalName(); + $name = $subnode->string_value + if ($tag_name eq 'name'); + if ($tag_name eq 'counters') { + foreach my $counter_node ($subnode->getChildNodes()) { + $tag_name = $counter_node->getLocalName(); + next if (!defined($tag_name)); + $counters->{$tag_name} = $counter_node->string_value; + } + } + } + + if (defined($name)) { + $zones->{$name}->{counters}->{rcode} = $counters; + } + } + + return $zones; +} + +sub load_server_xml_v3 { + my ($self, %options) = @_; + + my $server = { counters => { } }; + my $nodesets = $self->{xpath_response}->find('//server//counters'); + foreach my $node ($nodesets->get_nodelist()) { + my $type = $node->getAttribute('type'); + next if (!defined($type)); + foreach my $counter_node ($node->getChildNodes()) { + my $counter_name = $counter_node->getAttribute('name'); + $server->{counters}->{$type} = {} + if (!defined($server->{counters}->{$type})); + $server->{counters}->{$type}->{$counter_name} = $counter_node->string_value; + } + } + + return $server; +} + +sub load_server_xml_v2 { + my ($self, %options) = @_; + + my $server = { counters => { opcode => {}, nsstat => {}, qtype => {} } }; + + my $nodesets = $self->{xpath_response}->find('//server//opcode'); + foreach my $node ($nodesets->get_nodelist()) { + my ($name, $value); + foreach my $counter_node ($node->getChildNodes()) { + my $tag_name = $counter_node->getLocalName(); + next if (!defined($tag_name)); + + $name = $counter_node->string_value if ($tag_name eq 'name'); + $value = $counter_node->string_value if ($tag_name eq 'counter'); + } + + if (defined($name) && defined($value)) { + $server->{counters}->{opcode}->{$name} = $value; + } + } + + $nodesets = $self->{xpath_response}->find('//server//rdtype'); + foreach my $node ($nodesets->get_nodelist()) { + my ($name, $value); + foreach my $counter_node ($node->getChildNodes()) { + my $tag_name = $counter_node->getLocalName(); + next if (!defined($tag_name)); + + $name = $counter_node->string_value if ($tag_name eq 'name'); + $value = $counter_node->string_value if ($tag_name eq 'counter'); + } + + if (defined($name) && defined($value)) { + $server->{counters}->{qtype}->{$name} = $value; + } + } + + $nodesets = $self->{xpath_response}->find('//server//nsstat'); + foreach my $node ($nodesets->get_nodelist()) { + my ($name, $value); + foreach my $counter_node ($node->getChildNodes()) { + my $tag_name = $counter_node->getLocalName(); + next if (!defined($tag_name)); + + $name = $counter_node->string_value if ($tag_name eq 'name'); + $value = $counter_node->string_value if ($tag_name eq 'counter'); + } + + if (defined($name) && defined($value)) { + $server->{counters}->{nsstat}->{$name} = $value; + } + } + + return $server; +} + +sub get_memory { + my ($self, %options) = @_; + + $self->request(); + my $method = $self->can("load_memory_$self->{response_type}_v$self->{api_version}"); + if (!defined($method)) { + $self->{output}->add_option_msg(short_msg => "method 'load_memory_$self->{response_type}_v$self->{api_version}' unsupported"); + $self->{output}->option_exit(); + } + + my $memory = $self->$method(); + if (!defined($memory->{in_use})) { + $self->{output}->add_option_msg(short_msg => "cannot find memory information"); + $self->{output}->option_exit(); + } + + return $memory; +} + +sub get_zones { + my ($self, %options) = @_; + + $self->request(); + my $method = $self->can("load_zones_$self->{response_type}_v$self->{api_version}"); + if (!defined($method)) { + $self->{output}->add_option_msg(short_msg => "method 'load_zones_$self->{response_type}_v$self->{api_version}' unsupported"); + $self->{output}->option_exit(); + } + + my $zones = $self->$method(); + if (scalar(keys %{$zones}) == 0) { + $self->{output}->add_option_msg(short_msg => "cannot find zones information"); + $self->{output}->option_exit(); + } + + return $zones; +} + +sub get_server { + my ($self, %options) = @_; + + $self->request(); + my $method = $self->can("load_server_$self->{response_type}_v$self->{api_version}"); + if (!defined($method)) { + $self->{output}->add_option_msg(short_msg => "method 'load_server_$self->{response_type}_v$self->{api_version}' unsupported"); + $self->{output}->option_exit(); + } + + my $server = $self->$method(); + if (scalar(keys %{$server->{counters}}) == 0) { + $self->{output}->add_option_msg(short_msg => "cannot find server information"); + $self->{output}->option_exit(); + } + + return $server; +} + +1; + +__END__ + +=head1 NAME + +Statistics Channels API + +=head1 SYNOPSIS + +Statistics Channels API custom mode + +=head1 API OPTIONS + +=over 8 + +=item B<--hostname> + +Statistics Channels hostname. + +=item B<--port> + +Port used (Default: 8080) + +=item B<--proto> + +Specify https if needed (Default: 'http') + +=item B<--url-path> + +Statistics Channel API Path (Default: '/'). + +=item B<--timeout> + +Set HTTP timeout + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/apps/bind9/web/mode/memoryusage.pm b/apps/bind9/web/mode/memoryusage.pm new file mode 100644 index 000000000..eda534b51 --- /dev/null +++ b/apps/bind9/web/mode/memoryusage.pm @@ -0,0 +1,130 @@ +# +# Copyright 2019 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 apps::bind9::web::mode::memoryusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => 'used', unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + + my $msg = sprintf("Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 0 } + ]; + + $self->{maps_counters}->{memory} = [ + { label => 'usage', set => { + key_values => [ { name => 'used' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +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 => { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->get_memory(); + $self->{memory} = { used => $result->{in_use}, total => $result->{total_use} }; +} + +1; + +__END__ + +=head1 MODE + +Check bind memory usage. + +=over 8 + +=item B<--warning-usage> + +Threshold warning. + +=item B<--critical-usage> + +Threshold critical. + +=back + +=cut diff --git a/apps/bind9/web/mode/serverusage.pm b/apps/bind9/web/mode/serverusage.pm new file mode 100644 index 000000000..9f996c75d --- /dev/null +++ b/apps/bind9/web/mode/serverusage.pm @@ -0,0 +1,128 @@ +# +# Copyright 2019 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 apps::bind9::web::mode::serverusage; + +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 => 'server', type => 0, skipped_code => { -1 => 1, -10 => 1, 11 => -1 } } + ]; + + $self->{maps_counters}->{server} = []; + + my @map = ( + ['opcode_query', 'opcode query : %s', 'opcode-query'], + ['opcode_iquery', 'opcode iquery : %s', 'opcode-iquery'], + ['opcode_status', 'opcode status : %s', 'opcode-status'], + ['opcode_notify', 'opcode notify : %s', 'opcode-notify'], + ['opcode_update', 'opcode update : %s', 'opcode-update'], + ['qtype_a', 'qtype A : %s', 'qtype-a'], + ['qtype_cname', 'qtype CNAME : %s', 'qtype-cname'], + ['qtype_mx', 'qtype MX : %s', 'qtype-mx'], + ['qtype_txt', 'qtype TXT : %s', 'qtype-txt'], + ['qtype_soa', 'qtype SOA : %s', 'qtype-soa'], + ['qtype_ptr', 'qtype PTR : %s', 'qtype-ptr'], + ['qtype_ns', 'qtype NS : %s', 'qtype-ns'], + ['nsstat_requestv4', 'nsstat request v4 : %s', 'nsstat-requestv4'], + ['nsstat_requestv6', 'nsstat request v6 : %s', 'nsstat-requestv6'], + ); + + for (my $i = 0; $i < scalar(@map); $i++) { + my $perf_label = $map[$i]->[2]; + $perf_label =~ s/-/_/g; + push @{$self->{maps_counters}->{server}}, { label => $map[$i]->[2], display_ok => 0, set => { + key_values => [ { name => $map[$i]->[0], diff => 1 } ], + output_template => $map[$i]->[1], + perfdatas => [ + { label => $perf_label, value => $map[$i]->[0] . '_absolute', template => '%s', min => 0 }, + ], + } + }; + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->get_server(); + $self->{server} = { }; + + # Not present in response if no request on the server + foreach ('a', 'cname', 'mx', 'txt', 'soa', 'ptr', 'ns', 'any') { + $self->{server}->{'qtype_' . $_} = 0; + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'All bind9 counters are ok'); + foreach my $type (keys %{$result->{counters}}) { + foreach my $counter (keys %{$result->{counters}->{$type}}) { + $self->{server}->{lc($type) . '_' . lc($counter)} = $result->{counters}->{$type}->{$counter}; + } + } + + $self->{cache_name} = "bind9_" . $self->{mode} . '_' . $options{custom}->get_uniq_id() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check bind global server usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='request' + +=item B<--warning-*> <--critical-*> + +Thresholds. +Can be: 'opcode-query', 'opcode-iquery', 'opcode-status', 'opcode-notify', 'opcode-update', +'qtype-a', 'qtype-cname', 'qtype-mx', 'qtype-txt', 'qtype-soa', 'qtype-ptr', 'qtype-ns', 'qtype-any', +'nsstat-requestv4', 'nsstat-requestv6'. + +=back + +=cut diff --git a/apps/bind9/web/mode/zoneusage.pm b/apps/bind9/web/mode/zoneusage.pm new file mode 100644 index 000000000..be327882f --- /dev/null +++ b/apps/bind9/web/mode/zoneusage.pm @@ -0,0 +1,151 @@ +# +# Copyright 2019 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 apps::bind9::web::mode::zoneusage; + +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 => 'zones', type => 1, cb_prefix_output => 'prefix_zone_output', message_multiple => 'All zone counters are ok', skipped_code => { -1 => 1, -10 => 1, 11 => -1 } } + ]; + + $self->{maps_counters}->{zones} = [ + { label => 'message', threshold => 0, set => { + key_values => [ { name => 'display' } ], + closure_custom_calc => sub { return 0; }, + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => sub { return 'ok'; }, + closure_custom_output => sub { return 'counters are ok' }, + } + }, + ]; + + my @map = ( + ['qtype_a', 'qtype A : %s', 'qtype-a'], + ['qtype_cname', 'qtype CNAME : %s', 'qtype-cname'], + ['qtype_mx', 'qtype MX : %s', 'qtype-mx'], + ['qtype_txt', 'qtype TXT : %s', 'qtype-txt'], + ['qtype_soa', 'qtype SOA : %s', 'qtype-soa'], + ['qtype_ptr', 'qtype PTR : %s', 'qtype-ptr'], + ['qtype_ns', 'qtype NS : %s', 'qtype-ns'], + ['rcode_requestv4', 'rcode request v4 : %s', 'rcode-requestv4'], + ['rcode_requestv6', 'rcode request v6 : %s', 'rcode-requestv6'], + ); + + for (my $i = 0; $i < scalar(@map); $i++) { + my $perf_label = $map[$i]->[2]; + $perf_label =~ s/-/_/g; + push @{$self->{maps_counters}->{zones}}, { label => $map[$i]->[2], display_ok => 0, set => { + key_values => [ { name => $map[$i]->[0], diff => 1 }, { name => 'display' } ], + output_template => $map[$i]->[1], + perfdatas => [ + { label => $perf_label, value => $map[$i]->[0] . '_absolute', template => '%s', min => 0, + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }; + } +} + +sub prefix_zone_output { + my ($self, %options) = @_; + + return "Zone '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->get_zones(); + $self->{zones} = { }; + + foreach my $zone_name (keys %{$result}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $zone_name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $zone_name . "': no matching filter.", debug => 1); + next; + } + + $self->{zones}->{$zone_name} = { display => $zone_name }; + foreach my $type (keys %{$result->{$zone_name}->{counters}}) { + foreach my $counter (keys %{$result->{$zone_name}->{counters}->{$type}}) { + $self->{zones}->{$zone_name}->{lc($type) . '_' . lc($counter)} = $result->{$zone_name}->{counters}->{$type}->{$counter}; + } + } + } + + if (scalar(keys %{$self->{zones}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No zone found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "bind9_" . $self->{mode} . '_' . $options{custom}->get_uniq_id() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check bind zone usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='request' + +=item B<--filter-name> + +Filter zone name (can be a regexp). + +=item B<--warning-*> <--critical-*> + +Thresholds. +Can be: qtype-a', 'qtype-cname', 'qtype-mx', 'qtype-txt', 'qtype-soa', 'qtype-ptr', 'qtype-ns', 'qtype-any', +'nsstat-requestv4', 'nsstat-requestv6'. + +=back + +=cut diff --git a/apps/bind9/web/plugin.pm b/apps/bind9/web/plugin.pm new file mode 100644 index 000000000..d28545fd3 --- /dev/null +++ b/apps/bind9/web/plugin.pm @@ -0,0 +1,51 @@ +# +# Copyright 2019 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 apps::bind9::web::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'memory-usage' => 'apps::bind9::web::mode::memoryusage', + 'server-usage' => 'apps::bind9::web::mode::serverusage', + 'zone-usage' => 'apps::bind9::web::mode::zoneusage', + ); + + $self->{custom_modes}{api} = 'apps::bind9::web::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Bind9 server through HTTP statistics channels. + +=cut diff --git a/apps/bluemind/mode/incoming.pm b/apps/bluemind/mode/incoming.pm index b0601660f..3a59faae7 100644 --- a/apps/bluemind/mode/incoming.pm +++ b/apps/bluemind/mode/incoming.pm @@ -34,24 +34,21 @@ sub new { bless $self, $class; $self->{version} = '1.1'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '8086'}, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/db" }, - "database:s" => { name => 'database' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "timeout:s" => { name => 'timeout' }, - "proxyurl:s" => { name => 'proxyurl' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', default => '8086'}, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/db" }, + "database:s" => { name => 'database' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); $self->{statefile_value} = centreon::plugins::statefile->new(%options); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -198,18 +195,10 @@ Specify username for API authentification Specify password for API authentification -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Threshold for HTTP timeout (Default: 5) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning> Warning Threshold for failure incoming mails diff --git a/apps/centreon/local/mode/bamservice.pm b/apps/centreon/local/mode/bamservice.pm new file mode 100644 index 000000000..8eb982913 --- /dev/null +++ b/apps/centreon/local/mode/bamservice.pm @@ -0,0 +1,114 @@ +# +# Copyright 2019 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 apps::centreon::local::mode::bamservice; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::dbi; + +use vars qw($centreon_config); + +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 => { + "centreon-config:s" => { name => 'centreon_config', default => '/etc/centreon/centreon-config.pm' }, + "bam-id:s" => { name => 'bam_id', }, + }); + $self->{options} = $options{options}; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{bam_id}) || $self->{option_results}->{bam_id} !~ /^[0-9]+$/) { + $self->{output}->add_option_msg(short_msg => "Need to specify bam-id (numeric value) option."); + $self->{output}->option_exit(); + } + require $self->{option_results}->{centreon_config}; +} + +sub run { + my ($self, %options) = @_; + + my $sql = centreon::plugins::dbi->new(options => $self->{options}, output => $self->{output}, nooptions => 1); + $sql->{data_source} = 'mysql:host=' . $centreon_config->{db_host} . 'port=' . $centreon_config->{db_port}; + $sql->{username} = $centreon_config->{db_user}; + $sql->{password} = $centreon_config->{db_passwd}; + $sql->connect(); + + $sql->query(query => "SELECT `name`,`current_level`,`level_w`,`level_c` FROM " . $centreon_config->{centreon_db} . + ".`mod_bam` WHERE `ba_id` = '" . $self->{option_results}->{bam_id} . "'" + ); + my ($name, $current_level, $level_w, $level_c) = $self->{sql}->fetchrow_array(); + if (!defined($current_level)) { + $self->{output}->add_option_msg(short_msg => "Cannot get bam information"); + $self->{output}->option_exit(); + } + + $self->{perfdata}->threshold_validate(label => 'warning', value => $level_w . ':'); + $self->{perfdata}->threshold_validate(label => 'critical', value => $level_c . ':'); + + my $exit = $self->{perfdata}->threshold_check(value => $current_level, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf('BA : %s - current_level = %s%%', $name, $current_level)); + $self->{output}->perfdata_add( + label => 'BA_Level', + unit => '%', + value => $current_level, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 0, + ); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Do Centreon bam-service checks. + +=over 8 + +=item B<--centreon-config> + +Centreon Database Config File (Default: '/etc/centreon/centreon-config.pm'). + +=item B<--bam-id> + +Bam-id to check (required). + +=back + +=cut diff --git a/apps/centreon/local/mode/brokerstats.pm b/apps/centreon/local/mode/brokerstats.pm index 388a1d311..0a8f2ee80 100644 --- a/apps/centreon/local/mode/brokerstats.pm +++ b/apps/centreon/local/mode/brokerstats.pm @@ -163,6 +163,13 @@ sub manage_selection { my $endpoint = $entry; $endpoint =~ s/endpoint //; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $endpoint !~ /$self->{option_results}->{filter_name}/i) { + $self->{output}->output_add(long_msg => "skipping endpoint '" . $endpoint . "': no matching filter name"); + next; + } + my $state = $json->{$entry}->{state}; my $type = 'output'; $type = 'input' if (!defined($json->{$entry}->{status})); @@ -228,6 +235,10 @@ Use 'sudo' to execute the command. Specify the centreon-broker json stats file (Required). Can be multiple. +=item B<--filter-name> + +Filter endpoint name. + =item B<--warning-*> Threshold warning. diff --git a/apps/centreon/local/plugin.pm b/apps/centreon/local/plugin.pm index 4253d3aa5..98e0ecd43 100644 --- a/apps/centreon/local/plugin.pm +++ b/apps/centreon/local/plugin.pm @@ -31,13 +31,14 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'broker-stats' => 'apps::centreon::local::mode::brokerstats', - 'centreon-plugins-version' => 'apps::centreon::local::mode::centreonpluginsversion', - 'downtime-trap' => 'apps::centreon::local::mode::downtimetrap', - 'dummy' => 'apps::centreon::local::mode::dummy', - 'metaservice' => 'apps::centreon::local::mode::metaservice', - 'retention-broker' => 'apps::centreon::local::mode::retentionbroker', - ); + 'bamservice' => 'apps::centreon::local::mode::bamservice', + 'broker-stats' => 'apps::centreon::local::mode::brokerstats', + 'centreon-plugins-version' => 'apps::centreon::local::mode::centreonpluginsversion', + 'downtime-trap' => 'apps::centreon::local::mode::downtimetrap', + 'dummy' => 'apps::centreon::local::mode::dummy', + 'metaservice' => 'apps::centreon::local::mode::metaservice', + 'retention-broker' => 'apps::centreon::local::mode::retentionbroker', + ); return $self; } diff --git a/apps/centreon/map/jmx/mode/syncstats.pm b/apps/centreon/map/jmx/mode/syncstats.pm new file mode 100644 index 000000000..41c922d8a --- /dev/null +++ b/apps/centreon/map/jmx/mode/syncstats.pm @@ -0,0 +1,278 @@ +# Copyright 2019 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 apps::centreon::map::jmx::mode::syncstats; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use JSON::XS; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'centreon', type => 0, cb_prefix_output => 'prefix_output_centreon' }, + { name => 'acl', type => 1, cb_prefix_output => 'prefix_output_acl', + message_multiple => 'All ACL synchronizations metrics are ok' }, + { name => 'resource', type => 1, cb_prefix_output => 'prefix_output_resource', + message_multiple => 'All resource synchronizations metrics are ok' }, + ]; + + $self->{maps_counters}->{centreon} = [ + { label => 'map-synchronization-centreon-count', + nlabel => 'map.synchronization.centreon.count', set => { + key_values => [ { name => 'count' } ], + output_template => 'Count: %d', + perfdatas => [ + { label => 'map.synchronization.centreon.count', value => 'count_absolute', template => '%d', + min => 0 }, + ], + } + }, + { label => 'map-synchronization-centreon-duration-average-milliseconds', + nlabel => 'map.synchronization.centreon.duration.average.milliseconds', set => { + key_values => [ { name => 'average' } ], + output_template => 'Average Duration: %.2f ms', + perfdatas => [ + { label => 'map.synchronization.centreon.duration.average.milliseconds', value => 'average_absolute', + template => '%.2f', min => 0, unit => 'ms' }, + ], + } + }, + { label => 'map-synchronization-centreon-duration-max-milliseconds', + nlabel => 'map.synchronization.centreon.duration.max.milliseconds', set => { + key_values => [ { name => 'max' } ], + output_template => 'Max Duration: %.2f ms', + perfdatas => [ + { label => 'map.synchronization.centreon.duration.max.milliseconds', value => 'max_absolute', + template => '%.2f', min => 0, unit => 'ms' }, + ], + } + }, + ]; + $self->{maps_counters}->{acl} = [ + { label => 'map-synchronization-acl-count', + nlabel => 'map.synchronization.acl.count', set => { + key_values => [ { name => 'count' }, { name => 'name' } ], + output_template => 'Count: %d', + perfdatas => [ + { label => 'map.synchronization.acl.count', value => 'count_absolute', template => '%d', + min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + { label => 'map-synchronization-acl-duration-average-milliseconds', + nlabel => 'map.synchronization.acl.duration.average.milliseconds', set => { + key_values => [ { name => 'average' }, { name => 'name' } ], + output_template => 'Average Duration: %.2f ms', + perfdatas => [ + { label => 'map.synchronization.acl.duration.average.milliseconds', value => 'average_absolute', + template => '%.2f', min => 0, unit => 'ms', label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + { label => 'map-synchronization-acl-duration-max-milliseconds', + nlabel => 'map.synchronization.acl.duration.max.milliseconds', set => { + key_values => [ { name => 'max' }, { name => 'name' } ], + output_template => 'Max Duration: %.2f ms', + perfdatas => [ + { label => 'map.synchronization.acl.duration.max.milliseconds', value => 'max_absolute', + template => '%.2f', min => 0, unit => 'ms', label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + ]; + $self->{maps_counters}->{resource} = [ + { label => 'map-synchronization-resource-count', + nlabel => 'map.synchronization.resource.count', set => { + key_values => [ { name => 'count' }, { name => 'name' } ], + output_template => 'Count: %d', + perfdatas => [ + { label => 'map.synchronization.resource.count', value => 'count_absolute', template => '%d', + min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + { label => 'map-synchronization-resource-duration-average-milliseconds', + nlabel => 'map.synchronization.resource.duration.average.milliseconds', set => { + key_values => [ { name => 'average' }, { name => 'name' } ], + output_template => 'Average Duration: %.2f ms', + perfdatas => [ + { label => 'map.synchronization.resource.duration.average.milliseconds', value => 'average_absolute', + template => '%.2f', min => 0, unit => 'ms', label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + { label => 'map-synchronization-resource-duration-max-milliseconds', + nlabel => 'map.synchronization.resource.duration.max.milliseconds', set => { + key_values => [ { name => 'max' }, { name => 'name' } ], + output_template => 'Max Duration: %.2f ms', + perfdatas => [ + { label => 'map.synchronization.resource.duration.max.milliseconds', value => 'max_absolute', + template => '%.2f', min => 0, unit => 'ms', label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + ]; +} + +sub prefix_output_centreon { + my ($self, %options) = @_; + + return "Centreon Synchronization "; +} + +sub prefix_output_acl { + my ($self, %options) = @_; + + return "ACL Synchronization '" . $options{instance_value}->{name} . "' "; +} + +sub prefix_output_resource { + my ($self, %options) = @_; + + return "Resource Synchronization '" . $options{instance_value}->{name} . "' "; +} + +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 => {}); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +my $mbean_engine = "com.centreon.studio.map:type=synchronizer,name=statistics"; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{request} = [ + { mbean => $mbean_engine } + ]; + + my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 0); + + $self->{centreon} = {}; + $self->{acl} = {}; + $self->{resource} = {}; + + my $decoded_centreon_stats; + my $decoded_acl_stats; + my $decoded_resource_stats; + eval { + $decoded_centreon_stats = JSON::XS->new->utf8->decode($result->{$mbean_engine}->{CentreonSyncStatistics}); + $decoded_acl_stats = JSON::XS->new->utf8->decode($result->{$mbean_engine}->{AclSyncStatistics}); + $decoded_resource_stats = JSON::XS->new->utf8->decode($result->{$mbean_engine}->{ResourceSyncStatistics}); + }; + if ($@) { + $self->{output}->output_add(long_msg => $result, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + $self->{centreon} = { + count => $decoded_centreon_stats->{count}, + average => $decoded_centreon_stats->{average}, + max => ($decoded_centreon_stats->{count} == 0) ? 0 : $decoded_centreon_stats->{max}, + }; + + foreach my $name (keys %{$decoded_acl_stats}) { + $self->{acl}->{$name}= { + name => $name, + count => $decoded_acl_stats->{$name}->{count}, + average => $decoded_acl_stats->{$name}->{average}, + max => ($decoded_acl_stats->{$name}->{count} == 0) ? 0 : $decoded_acl_stats->{$name}->{max}, + }; + } + + foreach my $name (keys %{$decoded_resource_stats}) { + $self->{resource}->{$name}= { + name => $name, + count => $decoded_resource_stats->{$name}->{count}, + average => $decoded_resource_stats->{$name}->{average}, + max => ($decoded_resource_stats->{$name}->{count} == 0) ? 0 : $decoded_resource_stats->{$name}->{max}, + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check synchronizer statistics. + +Example: + +perl centreon_plugins.pl --plugin=apps::centreon::map::jmx::plugin --custommode=jolokia +--url=http://10.30.2.22:8080/jolokia-war --mode=sync-stats + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +(Example: --filter-counters='centreon') + +=item B<--warning-*> + +Threshold warning. +Can be: 'map-synchronization-centreon-count', +'map-synchronization-centreon-duration-average-milliseconds', +'map-synchronization-centreon-duration-max-milliseconds'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'map-synchronization-centreon-count', +'map-synchronization-centreon-duration-average-milliseconds', +'map-synchronization-centreon-duration-max-milliseconds'. + +=item B<--warning-instance-*> + +Threshold warning. +Can be: 'map-synchronization-acl-count', 'map-synchronization-acl-duration-average-milliseconds', +'map-synchronization-acl-duration-max-milliseconds', 'map-synchronization-resource-count', +'map-synchronization-resource-duration-average-milliseconds', +'map-synchronization-resource-duration-max-milliseconds'. + +=item B<--critical-instance-*> + +Threshold critical. +Can be: 'map-synchronization-acl-count', 'map-synchronization-acl-duration-average-milliseconds', +'map-synchronization-acl-duration-max-milliseconds', 'map-synchronization-resource-count', +'map-synchronization-resource-duration-average-milliseconds', +'map-synchronization-resource-duration-max-milliseconds'. + +=back + +=cut + diff --git a/apps/centreon/map/jmx/plugin.pm b/apps/centreon/map/jmx/plugin.pm index c4fbbafb8..890e8cb32 100644 --- a/apps/centreon/map/jmx/plugin.pm +++ b/apps/centreon/map/jmx/plugin.pm @@ -30,12 +30,13 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'broker-stats' => 'apps::centreon::map::jmx::mode::brokerstats', - 'events' => 'apps::centreon::map::jmx::mode::events', - 'engine-stats' => 'apps::centreon::map::jmx::mode::enginestats', - 'open-views' => 'apps::centreon::map::jmx::mode::openviews', - 'sessions' => 'apps::centreon::map::jmx::mode::sessions', - ); + 'broker-stats' => 'apps::centreon::map::jmx::mode::brokerstats', + 'events' => 'apps::centreon::map::jmx::mode::events', + 'engine-stats' => 'apps::centreon::map::jmx::mode::enginestats', + 'open-views' => 'apps::centreon::map::jmx::mode::openviews', + 'sessions' => 'apps::centreon::map::jmx::mode::sessions', + 'sync-stats' => 'apps::centreon::map::jmx::mode::syncstats', + ); $self->{custom_modes}{jolokia} = 'centreon::common::protocols::jmx::custom::jolokia'; return $self; diff --git a/apps/centreon/sql/mode/pollerdelay.pm b/apps/centreon/sql/mode/pollerdelay.pm index 5718820d6..9329be835 100644 --- a/apps/centreon/sql/mode/pollerdelay.pm +++ b/apps/centreon/sql/mode/pollerdelay.pm @@ -20,76 +20,79 @@ package apps::centreon::sql::mode::pollerdelay; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'poller', type => 1, cb_prefix_output => 'prefix_poller_output', message_multiple => 'All poller delay for last update are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{poller} = [ + { label => 'delay', set => { + key_values => [ { name => 'delay' }, { name => 'display' } ], + output_template => 'delay for last update is %d seconds', + perfdatas => [ + { label => 'delay', value => 'delay_absolute', template => '%s', + unit => 's', label_extra_instance => 1 }, + ], + } + }, + ]; +} + +sub prefix_poller_output { + my ($self, %options) = @_; + + return "Poller '" . $options{instance_value}->{display} . "' : "; +} + 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:s" => { name => 'warning', default => 300 }, - "critical:s" => { name => 'critical', default => 600 }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); return $self; } -sub check_options { +sub manage_selection { my ($self, %options) = @_; - $self->SUPER::init(%options); - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical}. "'."); - $self->{output}->option_exit(); - } -} - -sub run { - my ($self, %options) = @_; - # $options{sql} = sqlmode object - $self->{sql} = $options{sql}; - - $self->{sql}->connect(); - $self->{sql}->query(query => q{ - SELECT instance_id,name,last_alive,running FROM centreon_storage.instances WHERE deleted = '0'; + $options{sql}->connect(); + $options{sql}->query(query => q{ + SELECT instance_id, name, last_alive, running FROM centreon_storage.instances WHERE deleted = '0'; }); - my $result = $self->{sql}->fetchall_arrayref(); - - my $timestamp = time(); - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All poller delay for last update are ok")); + + my $result = $options{sql}->fetchall_arrayref(); + $self->{poller} = {}; foreach my $row (@{$result}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $$row[1] !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping poller '" . $$row[1] . "': no matching filter.", debug => 1); + next; + } + if ($$row[3] == 0) { $self->{output}->output_add(severity => 'CRITICAL', short_msg => sprintf("%s is not running", $$row[1])); next; } - my $delay = $timestamp - $$row[2]; - my $exit_code = $self->{perfdata}->threshold_check(value => abs($delay), threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{output}->output_add(long_msg => sprintf("Delay for last update of %s is %d seconds", $$row[1], $delay)); - if (!$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit_code, - short_msg => sprintf("Delay for last update of %s is %d seconds", $$row[1], $delay)); - } - $self->{output}->perfdata_add(label => sprintf("delay_%s", $$row[1]), unit => 's', - value => $delay, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + + my $delay = time() - $$row[2]; + $self->{poller}->{$$row[1]} = { + display => $$row[1], + delay => abs($delay), + }; } - - $self->{output}->display(); - $self->{output}->exit(); } 1; @@ -103,11 +106,15 @@ The mode should be used with mysql plugin and dyn-mode option. =over 8 -=item B<--warning> +=item B<--filter-name> + +Filter by poller name (can be a regexp). + +=item B<--warning-delay> Threshold warning in seconds. -=item B<--critical> +=item B<--critical-delay> Threshold critical in seconds. diff --git a/apps/checkmyws/mode/status.pm b/apps/checkmyws/mode/status.pm index 4fa6eba63..eb2d057d5 100644 --- a/apps/checkmyws/mode/status.pm +++ b/apps/checkmyws/mode/status.pm @@ -42,20 +42,17 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname', default => 'api.checkmy.ws'}, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto', default => "https" }, - "urlpath:s" => { name => 'url_path', default => "/api/status" }, - "proxyurl:s" => { name => 'proxyurl' }, - "uid:s" => { name => 'uid' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname', default => 'api.checkmy.ws'}, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto', default => "https" }, + "urlpath:s" => { name => 'url_path', default => "/api/status" }, + "uid:s" => { name => 'uid' }, + "timeout:s" => { name => 'timeout' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -194,10 +191,6 @@ Checkmyws api host (Default: 'api.checkmy.ws') Port used by checkmyws -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Specify https if needed (Default: 'https') @@ -206,18 +199,10 @@ Specify https if needed (Default: 'https') Set path to get checkmyws information (Default: '/api/status') -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Threshold for HTTP timeout (Default: 5) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--uid> ID for checkmyws API diff --git a/apps/cisco/cms/restapi/custom/xmlapi.pm b/apps/cisco/cms/restapi/custom/xmlapi.pm index 4e9a1f263..d4f04f132 100644 --- a/apps/cisco/cms/restapi/custom/xmlapi.pm +++ b/apps/cisco/cms/restapi/custom/xmlapi.pm @@ -40,24 +40,21 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "url-path:s" => { name => 'url_path' }, - "port:s" => { name => 'port' }, - "proto:s" => { name => 'proto' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "url-path:s" => { name => 'url_path' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'XMLAPI OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -94,8 +91,6 @@ sub check_options { $self->{password} = (defined($self->{option_results}->{password})) ? $self->{option_results}->{password} : undef; $self->{url_path} = (defined($self->{option_results}->{url_path})) ? $self->{option_results}->{url_path} : '/api/v1'; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? $self->{option_results}->{proxyurl} : undef; - $self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef; if (!defined($self->{option_results}->{username}) || $self->{option_results}->{username} eq '') { $self->{output}->add_option_msg(short_msg => "Need to specify --username option."); @@ -120,7 +115,6 @@ sub build_options_for_httplib { $self->{option_results}->{password} = $self->{password}; $self->{option_results}->{credentials} = 1; $self->{option_results}->{basic} = 1; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; $self->{option_results}->{warning_status} = ''; $self->{option_results}->{critical_status} = ''; $self->{option_results}->{unknown_status} = ''; @@ -158,9 +152,8 @@ sub get_endpoint { $self->settings; my $content = $self->{http}->request(url_path => $self->{url_path} . $options{method}); - my $response = $self->{http}->get_response(); - if ($response->code() != 200) { + if ($self->{http}->get_code() != 200) { my $xml_result; eval { $xml_result = XMLin($content); @@ -230,18 +223,10 @@ Set API username Set API password -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL options if needed (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/apps/cisco/ise/restapi/custom/xmlapi.pm b/apps/cisco/ise/restapi/custom/xmlapi.pm index c796830ff..df7da19e3 100644 --- a/apps/cisco/ise/restapi/custom/xmlapi.pm +++ b/apps/cisco/ise/restapi/custom/xmlapi.pm @@ -40,24 +40,21 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "url-path:s" => { name => 'url_path' }, - "port:s" => { name => 'port' }, - "proto:s" => { name => 'proto' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "url-path:s" => { name => 'url_path' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'XMLAPI OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -94,8 +91,6 @@ sub check_options { $self->{password} = (defined($self->{option_results}->{password})) ? $self->{option_results}->{password} : undef; $self->{url_path} = (defined($self->{option_results}->{url_path})) ? $self->{option_results}->{url_path} : '/admin/API/mnt'; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? $self->{option_results}->{proxyurl} : undef; - $self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef; if (!defined($self->{option_results}->{username}) || $self->{option_results}->{username} eq '') { $self->{output}->add_option_msg(short_msg => "Need to specify --username option."); @@ -120,7 +115,6 @@ sub build_options_for_httplib { $self->{option_results}->{password} = $self->{password}; $self->{option_results}->{credentials} = 1; $self->{option_results}->{basic} = 1; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; $self->{option_results}->{warning_status} = ''; $self->{option_results}->{critical_status} = ''; } @@ -157,9 +151,8 @@ sub get_endpoint { $self->settings; my $content = $self->{http}->request(url_path => $self->{url_path} . $options{category}); - my $response = $self->{http}->get_response(); - if ($response->code() != 200) { + if ($self->{http}->get_code() != 200) { my $xml_result; eval { $xml_result = XMLin($content); @@ -229,18 +222,10 @@ Set API username Set API password -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL options if needed (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/apps/cluster/mscs/local/mode/networkstatus.pm b/apps/cluster/mscs/local/mode/networkstatus.pm index fd873bb26..7236f2c80 100644 --- a/apps/cluster/mscs/local/mode/networkstatus.pm +++ b/apps/cluster/mscs/local/mode/networkstatus.pm @@ -78,7 +78,7 @@ sub new { "filter-name:s" => { name => 'filter_name' }, "unknown-status:s" => { name => 'unknown_status', default => '%{state} =~ /unknown/' }, "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '%{state} =~ /down|paritioned|unavailable/' }, + "critical-status:s" => { name => 'critical_status', default => '%{state} =~ /down|partitioned|unavailable/' }, }); return $self; @@ -95,7 +95,7 @@ my %map_state = ( -1 => 'unknown', 0 => 'unavailable', 1 => 'down', - 2 => 'paritioned', + 2 => 'partitioned', 3 => 'up', ); @@ -153,7 +153,7 @@ Can used special variables like: %{state}, %{display} =item B<--critical-status> -Set critical threshold for status (Default: '%{state} =~ /down|paritioned|unavailable/'). +Set critical threshold for status (Default: '%{state} =~ /down|partitioned|unavailable/'). Can used special variables like: %{state}, %{display} =back diff --git a/apps/elasticsearch/restapi/custom/api.pm b/apps/elasticsearch/restapi/custom/api.pm index d58f82672..389f6b76b 100644 --- a/apps/elasticsearch/restapi/custom/api.pm +++ b/apps/elasticsearch/restapi/custom/api.pm @@ -40,23 +40,20 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s@" => { name => 'hostname' }, - "port:s@" => { name => 'port' }, - "proto:s@" => { name => 'proto' }, - "username:s@" => { name => 'username' }, - "password:s@" => { name => 'password' }, - "proxyurl:s@" => { name => 'proxyurl' }, - "timeout:s@" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s@" => { name => 'hostname' }, + "port:s@" => { name => 'port' }, + "proto:s@" => { name => 'proto' }, + "username:s@" => { name => 'username' }, + "password:s@" => { name => 'password' }, + "timeout:s@" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; @@ -93,7 +90,6 @@ sub check_options { $self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : ''; $self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{password}}) : ''; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef; if (!defined($self->{hostname})) { $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); @@ -114,7 +110,6 @@ sub build_options_for_httplib { $self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{port} = $self->{port}; $self->{option_results}->{proto} = $self->{proto}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; $self->{option_results}->{credentials} = 1; $self->{option_results}->{basic} = 1; $self->{option_results}->{username} = $self->{username}; @@ -187,18 +182,10 @@ Elasticsearch username. Elasticsearch password. -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/apps/exchange/2010/local/mode/imapmailbox.pm b/apps/exchange/2010/local/mode/imapmailbox.pm index 266ab55d0..1f4e85bfe 100644 --- a/apps/exchange/2010/local/mode/imapmailbox.pm +++ b/apps/exchange/2010/local/mode/imapmailbox.pm @@ -33,22 +33,22 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "remote-host:s" => { name => 'remote_host', }, - "remote-user:s" => { name => 'remote_user', }, - "remote-password:s" => { name => 'remote_password', }, - "no-ps" => { name => 'no_ps', }, - "timeout:s" => { name => 'timeout', default => 50 }, - "command:s" => { name => 'command', default => 'powershell.exe' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, - "ps-exec-only" => { name => 'ps_exec_only', }, - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', default => '%{result} !~ /Success/i' }, - "mailbox:s" => { name => 'mailbox', }, - "password:s" => { name => 'password', }, - }); + $options{options}->add_options(arguments => { + "remote-host:s" => { name => 'remote_host', }, + "remote-user:s" => { name => 'remote_user', }, + "remote-password:s" => { name => 'remote_password', }, + "no-ps" => { name => 'no_ps', }, + "timeout:s" => { name => 'timeout', default => 50 }, + "command:s" => { name => 'command', default => 'powershell.exe' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, + "ps-exec-only" => { name => 'ps_exec_only', }, + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', default => '%{result} !~ /Success/i' }, + "mailbox:s" => { name => 'mailbox', }, + "password:s" => { name => 'password', }, + }); + return $self; } @@ -85,7 +85,7 @@ sub run { remote_user => $self->{option_results}->{remote_user}, remote_password => $self->{option_results}->{remote_password}, mailbox => $self->{option_results}->{mailbox}, - password => $self->{option_results}->{password}, + password => $self->{option_results}->{password}, no_ps => $self->{option_results}->{no_ps}, ); $self->{option_results}->{command_options} .= " " . $ps; @@ -173,4 +173,4 @@ Set the password for the mailbox (Required). =back -=cut \ No newline at end of file +=cut diff --git a/apps/exchange/2010/local/mode/outlookwebservices.pm b/apps/exchange/2010/local/mode/outlookwebservices.pm index b0af52d65..f82d3b663 100644 --- a/apps/exchange/2010/local/mode/outlookwebservices.pm +++ b/apps/exchange/2010/local/mode/outlookwebservices.pm @@ -33,21 +33,22 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "remote-host:s" => { name => 'remote_host', }, - "remote-user:s" => { name => 'remote_user', }, - "remote-password:s" => { name => 'remote_password', }, - "no-ps" => { name => 'no_ps', }, - "timeout:s" => { name => 'timeout', default => 50 }, - "command:s" => { name => 'command', default => 'powershell.exe' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, - "ps-exec-only" => { name => 'ps_exec_only', }, - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', default => '%{type} !~ /Success|Information/i' }, - "mailbox:s" => { name => 'mailbox', }, - }); + $options{options}->add_options(arguments => { + "remote-host:s" => { name => 'remote_host', }, + "remote-user:s" => { name => 'remote_user', }, + "remote-password:s" => { name => 'remote_password', }, + "no-ps" => { name => 'no_ps', }, + "timeout:s" => { name => 'timeout', default => 50 }, + "command:s" => { name => 'command', default => 'powershell.exe' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, + "ps-exec-only" => { name => 'ps_exec_only', }, + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', default => '%{type} !~ /Success|Information/i' }, + "mailbox:s" => { name => 'mailbox', }, + "password:s" => { name => 'password', }, + }); + return $self; } @@ -81,6 +82,7 @@ sub run { remote_password => $self->{option_results}->{remote_password}, no_ps => $self->{option_results}->{no_ps}, mailbox => $self->{option_results}->{mailbox}, + password => $self->{option_results}->{password}, ); $self->{option_results}->{command_options} .= " " . $ps; my ($stdout) = centreon::plugins::misc::windows_execute(output => $self->{output}, @@ -161,6 +163,10 @@ Can used special variables like: %{type}, %{id}, %{message} Set the mailbox to check (Required). +=item B<--password> + +Set the password for the mailbox. + =back -=cut \ No newline at end of file +=cut diff --git a/apps/exchange/2010/local/mode/queues.pm b/apps/exchange/2010/local/mode/queues.pm index 449edef22..5a8ddbceb 100644 --- a/apps/exchange/2010/local/mode/queues.pm +++ b/apps/exchange/2010/local/mode/queues.pm @@ -144,13 +144,13 @@ Print powershell output. =item B<--warning> Set warning threshold. -Can used special variables like: %{status}, %{identity}, %{isvalid}, %{deliverytype} +Can used special variables like: %{status}, %{identity}, %{isvalid}, %{deliverytype}, %{messagecount} =item B<--critical> Set critical threshold (Default: '%{status} !~ /Ready|Active/i'). -Can used special variables like: %{status}, %{identity}, %{isvalid}, %{deliverytype} +Can used special variables like: %{status}, %{identity}, %{isvalid}, %{deliverytype}, %{messagecount} =back -=cut \ No newline at end of file +=cut diff --git a/apps/github/mode/commits.pm b/apps/github/mode/commits.pm index 253228685..86b0a4ad8 100644 --- a/apps/github/mode/commits.pm +++ b/apps/github/mode/commits.pm @@ -35,19 +35,16 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname', default => 'api.github.com' }, - "port:s" => { name => 'port', default => '443'}, - "proto:s" => { name => 'proto', default => 'https' }, - "timeout:s" => { name => 'timeout' }, - "proxyurl:s" => { name => 'proxyurl' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "owner:s" => { name => 'owner' }, - "repository:s" => { name => 'repository' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname', default => 'api.github.com' }, + "port:s" => { name => 'port', default => '443'}, + "proto:s" => { name => 'proto', default => 'https' }, + "timeout:s" => { name => 'timeout' }, + "owner:s" => { name => 'owner' }, + "repository:s" => { name => 'repository' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); $self->{statefile_value} = centreon::plugins::statefile->new(%options); return $self; @@ -140,18 +137,10 @@ Port used by GitHub's API (Default: '443') Specify https if needed (Default: 'https') -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Threshold for HTTP timeout (Default: 5) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--owner> Specify GitHub's owner diff --git a/apps/github/mode/issues.pm b/apps/github/mode/issues.pm index 53a674f11..92b36e784 100644 --- a/apps/github/mode/issues.pm +++ b/apps/github/mode/issues.pm @@ -33,22 +33,19 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname', default => 'api.github.com' }, - "port:s" => { name => 'port', default => '443'}, - "proto:s" => { name => 'proto', default => 'https' }, - "timeout:s" => { name => 'timeout' }, - "proxyurl:s" => { name => 'proxyurl' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "owner:s" => { name => 'owner' }, - "repository:s" => { name => 'repository' }, - "label:s" => { name => 'label', default => '' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname', default => 'api.github.com' }, + "port:s" => { name => 'port', default => '443'}, + "proto:s" => { name => 'proto', default => 'https' }, + "timeout:s" => { name => 'timeout' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "owner:s" => { name => 'owner' }, + "repository:s" => { name => 'repository' }, + "label:s" => { name => 'label', default => '' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -147,18 +144,10 @@ Port used by GitHub's API (Default: '443') Specify https if needed (Default: 'https') -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Threshold for HTTP timeout (Default: 5) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning> Threshold warning. diff --git a/apps/github/mode/pullrequests.pm b/apps/github/mode/pullrequests.pm index 173bdcab0..ca4b3cd15 100644 --- a/apps/github/mode/pullrequests.pm +++ b/apps/github/mode/pullrequests.pm @@ -33,21 +33,18 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname', default => 'api.github.com' }, - "port:s" => { name => 'port', default => '443' }, - "proto:s" => { name => 'proto', default => 'https' }, - "timeout:s" => { name => 'timeout' }, - "proxyurl:s" => { name => 'proxyurl' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "owner:s" => { name => 'owner' }, - "repository:s" => { name => 'repository' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname', default => 'api.github.com' }, + "port:s" => { name => 'port', default => '443' }, + "proto:s" => { name => 'proto', default => 'https' }, + "timeout:s" => { name => 'timeout' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "owner:s" => { name => 'owner' }, + "repository:s" => { name => 'repository' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -132,18 +129,10 @@ Port used by GitHub's API (Default: '443') Specify https if needed (Default: 'https') -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Threshold for HTTP timeout (Default: 5) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning> Threshold warning. diff --git a/apps/github/mode/stats.pm b/apps/github/mode/stats.pm index e0d5ab1c9..203e249b0 100644 --- a/apps/github/mode/stats.pm +++ b/apps/github/mode/stats.pm @@ -26,7 +26,6 @@ use strict; use warnings; use centreon::plugins::http; use JSON; -use Data::Dumper; sub new { my ($class, %options) = @_; @@ -34,19 +33,16 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname', default => 'api.github.com' }, - "port:s" => { name => 'port', default => '443'}, - "proto:s" => { name => 'proto', default => 'https' }, - "timeout:s" => { name => 'timeout' }, - "proxyurl:s" => { name => 'proxyurl' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "owner:s" => { name => 'owner' }, - "repository:s" => { name => 'repository' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname', default => 'api.github.com' }, + "port:s" => { name => 'port', default => '443'}, + "proto:s" => { name => 'proto', default => 'https' }, + "timeout:s" => { name => 'timeout' }, + "owner:s" => { name => 'owner' }, + "repository:s" => { name => 'repository' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -80,7 +76,6 @@ sub run { if ($@) { $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); - $self->{output}->output_add(long_msg => Data::Dumper::Dumper(), debug => 1); $self->{output}->option_exit(); } @@ -131,18 +126,10 @@ Specify https if needed (Default: 'https') Set path to get GitHub's status information (Default: '/repo/:owner/:repository') -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Threshold for HTTP timeout (Default: 5) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =cut diff --git a/apps/github/mode/status.pm b/apps/github/mode/status.pm index 0c038e4dd..96ab886f5 100644 --- a/apps/github/mode/status.pm +++ b/apps/github/mode/status.pm @@ -41,19 +41,16 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname', default => 'status.github.com' }, - "port:s" => { name => 'port', default => '443'}, - "proto:s" => { name => 'proto', default => 'https' }, - "urlpath:s" => { name => 'url_path', default => '/api/last-message.json' }, - "timeout:s" => { name => 'timeout' }, - "proxyurl:s" => { name => 'proxyurl' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname', default => 'status.github.com' }, + "port:s" => { name => 'port', default => '443'}, + "proto:s" => { name => 'proto', default => 'https' }, + "urlpath:s" => { name => 'url_path', default => '/api/last-message.json' }, + "timeout:s" => { name => 'timeout' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -151,18 +148,10 @@ Specify https if needed (Default: 'https') Set path to get GitHub's status information (Default: '/api/last-message.json') -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Threshold for HTTP timeout (Default: 5) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--threshold-overload> Set to overload default threshold values (syntax: status,regexp) diff --git a/apps/haproxy/snmp/mode/backendusage.pm b/apps/haproxy/snmp/mode/backendusage.pm index cbc2367b8..e753d5c8b 100644 --- a/apps/haproxy/snmp/mode/backendusage.pm +++ b/apps/haproxy/snmp/mode/backendusage.pm @@ -114,12 +114,11 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /UP/i' }, - }); + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' }, + 'warning-status:s' => { name => 'warning_status', default => '' }, + 'critical-status:s' => { name => 'critical_status', default => '%{status} !~ /UP/i' }, + }); return $self; } @@ -138,13 +137,26 @@ sub prefix_backend_output { } my $mapping = { - alBackendName => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.3' }, - alBackendQueueCur => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.4' }, - alBackendSessionCur => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.7' }, - alBackendSessionTotal => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.10' }, - alBackendBytesIN => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.12' }, - alBackendBytesOUT => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.13' }, - alBackendStatus => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.20' }, + entreprise => { + alBackendQueueCur => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.4' }, + alBackendSessionCur => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.7' }, + alBackendSessionTotal => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.10' }, + alBackendBytesIN => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.12' }, + alBackendBytesOUT => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.13' }, + alBackendStatus => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.20' }, + }, + csv => { + alBackendQueueCur => { oid => '.1.3.6.1.4.1.29385.106.1.1.2' }, + alBackendSessionCur => { oid => '.1.3.6.1.4.1.29385.106.1.1.4' }, + alBackendSessionTotal => { oid => '.1.3.6.1.4.1.29385.106.1.1.7' }, + alBackendBytesIN => { oid => '.1.3.6.1.4.1.29385.106.1.1.8' }, + alBackendBytesOUT => { oid => '.1.3.6.1.4.1.29385.106.1.1.9' }, + alBackendStatus => { oid => '.1.3.6.1.4.1.29385.106.1.1.17' }, + }, +}; +my $mapping_name = { + csv => '.1.3.6.1.4.1.29385.106.1.1.0', + entreprise => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.3', # alBackendName }; sub manage_selection { @@ -156,41 +168,50 @@ sub manage_selection { } $self->{backend} = {}; - my $snmp_result = $options{snmp}->get_multiple_table( - oids => [ - { oid => $mapping->{alBackendName}->{oid} }, - { oid => $mapping->{alBackendQueueCur}->{oid} }, - { oid => $mapping->{alBackendSessionCur}->{oid} }, - { oid => $mapping->{alBackendSessionTotal}->{oid} }, - { oid => $mapping->{alBackendBytesIN}->{oid} }, - { oid => $mapping->{alBackendBytesOUT}->{oid} }, - { oid => $mapping->{alBackendStatus}->{oid} }, - ], - return_type => 1, nothing_quit => 1); + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ { oid => $mapping_name->{csv} }, { oid => $mapping_name->{entreprise} } ], nothing_quit => 1); + my $branch = 'entreprise'; + if (defined($snmp_result->{ $mapping_name->{csv} }) && scalar(keys %{$snmp_result->{ $mapping_name->{csv} }}) > 0) { + $branch = 'csv'; + } - foreach my $oid (keys %{$snmp_result}) { - next if ($oid !~ /^$mapping->{alBackendName}->{oid}\.(.*)$/); + foreach my $oid (keys %{$snmp_result->{ $mapping_name->{$branch} }}) { + $oid =~ /^$mapping_name->{$branch}\.(.*)$/; my $instance = $1; - my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + my $name = $snmp_result->{$mapping_name->{$branch}}->{$oid}; if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $result->{alBackendName} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "skipping '" . $result->{wgPolicyName} . "': no matching filter.", debug => 1); + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping backend '" . $name . "'.", debug => 1); next; } - - $result->{alBackendBytesIN} *= 8; - $result->{alBackendBytesOUT} *= 8; - $self->{backend}->{$instance} = { display => $result->{alBackendName}, - %$result - }; + + $self->{backend}->{$instance} = { display => $name }; } - + if (scalar(keys %{$self->{backend}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No backend found."); $self->{output}->option_exit(); } + + $options{snmp}->load( + oids => [ + map($_->{oid}, values(%{$mapping->{$branch}})) + ], + instances => [keys %{$self->{backend}}], + instance_regexp => '^(.*)$' + ); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + foreach (keys %{$self->{backend}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping->{$branch}, results => $snmp_result, instance => $_); + + $result->{alBackendBytesIN} *= 8; + $result->{alBackendBytesOUT} *= 8; + + $self->{backend}->{$_} = { %{$self->{backend}->{$_}}, %$result }; + } + $self->{cache_name} = "haproxy_" . $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')) . '_' . (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); diff --git a/apps/haproxy/snmp/mode/frontendusage.pm b/apps/haproxy/snmp/mode/frontendusage.pm index 21b2fd165..bcb16c251 100644 --- a/apps/haproxy/snmp/mode/frontendusage.pm +++ b/apps/haproxy/snmp/mode/frontendusage.pm @@ -105,12 +105,11 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /OPEN/i' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /OPEN/i' }, + }); return $self; } @@ -129,12 +128,24 @@ sub prefix_frontend_output { } my $mapping = { - alFrontendName => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.3' }, - alFrontendSessionCur => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.4' }, - alFrontendSessionTotal => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.7' }, - alFrontendBytesIN => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.8' }, - alFrontendBytesOUT => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.9' }, - alFrontendStatus => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.13' }, + entreprise => { + alFrontendSessionCur => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.4' }, + alFrontendSessionTotal => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.7' }, + alFrontendBytesIN => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.8' }, + alFrontendBytesOUT => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.9' }, + alFrontendStatus => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.13' }, + }, + csv => { + alFrontendSessionCur => { oid => '.1.3.6.1.4.1.29385.106.1.0.4' }, + alFrontendSessionTotal => { oid => '.1.3.6.1.4.1.29385.106.1.0.7' }, + alFrontendBytesIN => { oid => '.1.3.6.1.4.1.29385.106.1.0.8' }, + alFrontendBytesOUT => { oid => '.1.3.6.1.4.1.29385.106.1.0.9' }, + alFrontendStatus => { oid => '.1.3.6.1.4.1.29385.106.1.0.17' }, + }, +}; +my $mapping_name = { + csv => '.1.3.6.1.4.1.29385.106.1.0.0', + entreprise => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.3', # alFrontendName }; sub manage_selection { @@ -146,39 +157,49 @@ sub manage_selection { } $self->{frontend} = {}; - my $snmp_result = $options{snmp}->get_multiple_table( - oids => [ - { oid => $mapping->{alFrontendName}->{oid} }, - { oid => $mapping->{alFrontendSessionCur}->{oid} }, - { oid => $mapping->{alFrontendSessionTotal}->{oid} }, - { oid => $mapping->{alFrontendBytesIN}->{oid} }, - { oid => $mapping->{alFrontendBytesOUT}->{oid} }, - { oid => $mapping->{alFrontendStatus}->{oid} }, - ], - return_type => 1, nothing_quit => 1); + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ { oid => $mapping_name->{csv} }, { oid => $mapping_name->{entreprise} } ], nothing_quit => 1); + my $branch = 'entreprise'; + if (defined($snmp_result->{ $mapping_name->{csv} }) && scalar(keys %{$snmp_result->{ $mapping_name->{csv} }}) > 0) { + $branch = 'csv'; + } - foreach my $oid (keys %{$snmp_result}) { - next if ($oid !~ /^$mapping->{alFrontendName}->{oid}\.(.*)$/); + foreach my $oid (keys %{$snmp_result->{ $mapping_name->{$branch} }}) { + $oid =~ /^$mapping_name->{$branch}\.(.*)$/; my $instance = $1; - my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + my $name = $snmp_result->{$mapping_name->{$branch}}->{$oid}; if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $result->{alFrontendName} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "skipping '" . $result->{wgPolicyName} . "': no matching filter.", debug => 1); + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping frontend '" . $name . "'.", debug => 1); next; } - - $result->{alFrontendBytesIN} *= 8; - $result->{alFrontendBytesOUT} *= 8; - $self->{frontend}->{$instance} = { display => $result->{alFrontendName}, - %$result - }; + + $self->{frontend}->{$instance} = { display => $name }; } - + if (scalar(keys %{$self->{frontend}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No frontend found."); $self->{output}->option_exit(); } + + $options{snmp}->load( + oids => [ + map($_->{oid}, values(%{$mapping->{$branch}})) + ], + instances => [keys %{$self->{frontend}}], + instance_regexp => '^(.*)$' + ); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{frontend}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping->{$branch}, results => $snmp_result, instance => $_); + + $result->{alFrontendBytesIN} *= 8; + $result->{alFrontendBytesOUT} *= 8; + + $self->{frontend}->{$_} = { %{$self->{frontend}->{$_}}, %$result }; + } $self->{cache_name} = "haproxy_" . $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')) . '_' . diff --git a/apps/hddtemp/remote/mode/temperature.pm b/apps/hddtemp/remote/mode/temperature.pm index 7ea273b0f..e55df715a 100644 --- a/apps/hddtemp/remote/mode/temperature.pm +++ b/apps/hddtemp/remote/mode/temperature.pm @@ -32,17 +32,16 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '7634' }, - "timeout:s" => { name => 'timeout', default => '10' }, - "name:s" => { name => 'name' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', default => '7634' }, + "timeout:s" => { name => 'timeout', default => '10' }, + "name:s" => { name => 'name' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + }); $self->{result} = {}; $self->{hostname} = undef; @@ -71,11 +70,12 @@ sub check_options { sub manage_selection { my ($self, %options) = @_; - my $oSocketConn = new IO::Socket::INET ( Proto => 'tcp', - PeerAddr => $self->{option_results}->{hostname}, - PeerPort => $self->{option_results}->{port}, - Timeout => $self->{option_results}->{timeout}, - ); + my $oSocketConn = new IO::Socket::INET ( + Proto => 'tcp', + PeerAddr => $self->{option_results}->{hostname}, + PeerPort => $self->{option_results}->{port}, + Timeout => $self->{option_results}->{timeout}, + ); if (!defined($oSocketConn)) { $self->{output}->add_option_msg(short_msg => "Could not connect."); @@ -147,14 +147,17 @@ sub run { $self->{result}->{$name}->{unit})); } - my $extra_label = ''; + my $extra_label; $extra_label = '_' . $name if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})); - $self->{output}->perfdata_add(label => 'temp' . $extra_label, - unit => $self->{result}->{$name}->{unit}, - value => sprintf("%.2f", $self->{result}->{$name}->{temperature}), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + $self->{output}->perfdata_add( + label => 'temp', + intances => $extra_label, + unit => $self->{result}->{$name}->{unit}, + value => sprintf("%.2f", $self->{result}->{$name}->{temperature}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0 + ); }; $self->{output}->display(); diff --git a/apps/iis/local/mode/webservicestatistics.pm b/apps/iis/local/mode/webservicestatistics.pm index c00a5b04a..fde285b10 100644 --- a/apps/iis/local/mode/webservicestatistics.pm +++ b/apps/iis/local/mode/webservicestatistics.pm @@ -185,13 +185,16 @@ sub check { $str_display .= $str_display_append . sprintf("%s %s /sec", $name, $value_display); $str_display_append = ', '; - my $extra_label = ''; + my $extra_label; $extra_label = '_' . $site_name if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})); - $self->{output}->perfdata_add(label => $name . $extra_label, unit => $counters->{$name}->{unit}, - value => sprintf("%.2f", $value_per_seconds), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_' . $name), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_' . $name), - min => 0); + $self->{output}->perfdata_add( + label => $name, unit => $counters->{$name}->{unit}, + instances => $extra_label, + value => sprintf("%.2f", $value_per_seconds), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_' . $name), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_' . $name), + min => 0 + ); } # No values computing. @@ -259,4 +262,4 @@ Counters are separated by comas. =back -=cut \ No newline at end of file +=cut diff --git a/apps/inin/mediaserver/snmp/mode/cmdsrvusage.pm b/apps/inin/mediaserver/snmp/mode/cmdsrvusage.pm index 8aab6cea7..c5ccb271b 100644 --- a/apps/inin/mediaserver/snmp/mode/cmdsrvusage.pm +++ b/apps/inin/mediaserver/snmp/mode/cmdsrvusage.pm @@ -51,19 +51,21 @@ sub custom_usage_perfdata { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -76,7 +78,7 @@ sub custom_usage_threshold { $threshold_value = $self->{result_values}->{prct_used}; $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } diff --git a/apps/inin/mediaserver/snmp/mode/diskusage.pm b/apps/inin/mediaserver/snmp/mode/diskusage.pm index b923b5152..645dd44e6 100644 --- a/apps/inin/mediaserver/snmp/mode/diskusage.pm +++ b/apps/inin/mediaserver/snmp/mode/diskusage.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -62,12 +60,12 @@ sub custom_usage_perfdata { my $label = 'used_' . $self->{result_values}->{display}; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free_' . $self->{result_values}->{display}; $value_perf = $self->{result_values}->{free}; } my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } @@ -84,10 +82,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); return $exit; @@ -127,21 +125,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/apps/java/weblogic/jmx/mode/workmanager.pm b/apps/java/weblogic/jmx/mode/workmanager.pm index 93fe91e45..dbba485b1 100644 --- a/apps/java/weblogic/jmx/mode/workmanager.pm +++ b/apps/java/weblogic/jmx/mode/workmanager.pm @@ -20,72 +20,16 @@ package apps::java::weblogic::jmx::mode::workmanager; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); -my $thresholds = { - health => [ - ['HEALTH_OK', 'OK'], - ['HEALTH_WARNING', 'WARNING'], - ['HEALTH_CRITICAL', 'CRITICAL'], - ['HEALTH_FAILED', 'CRITICAL'], - ['HEALTH_OVERLOADED', 'CRITICAL'], - ['LOW_MEMORY_REASON', 'CRITICAL'], - ], -}; -my $instance_mode; - -my $maps_counters = { - runtime => { - '000_status' => { set => { - key_values => [ { name => 'health_state' } ], - closure_custom_calc => \&custom_status_calc, - output_template => 'State : %s', output_error_template => 'State : %s', - output_use => 'health_state', - closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&custom_threshold_output, - } - }, - - '001_request-completed' => { set => { - key_values => [ { name => 'completed', diff => 1 }, { name => 'runtime' } ], - output_template => 'Requests completed : %s', - perfdatas => [ - { label => 'request_completed', value => 'completed_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'runtime_absolute' }, - ], - } - }, - '002_request-pending' => { set => { - key_values => [ { name => 'pending' }, { name => 'runtime' } ], - output_template => 'Requests pending : %s', - perfdatas => [ - { label => 'request_pending', value => 'pending_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'runtime_absolute' }, - ], - } - }, - '003_thread-stuck' => { set => { - key_values => [ { name => 'stuck' }, { name => 'runtime' } ], - output_template => 'Threads stuck : %s', - perfdatas => [ - { label => 'thread_stuck', value => 'stuck_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'runtime_absolute' }, - ], - } - }, - }, -}; - sub custom_threshold_output { my ($self, %options) = @_; - return $instance_mode->get_severity(section => 'health', value => $self->{result_values}->{health_state}); + return $self->{instance_mode}->get_severity(section => 'health', value => $self->{result_values}->{health_state}); } sub custom_status_calc { @@ -95,53 +39,78 @@ sub custom_status_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'wm', type => 1, cb_prefix_output => 'prefix_wm_output', message_multiple => 'All WorkerManagers are ok' } + ]; + + $self->{maps_counters}->{wm} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'health_state' } ], + closure_custom_calc => $self->can('custom_status_calc'), + output_template => 'State : %s', output_error_template => 'State : %s', + output_use => 'health_state', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_threshold_output'), + } + }, + { label => 'request-completed', set => { + key_values => [ { name => 'completed', diff => 1 }, { name => 'display' } ], + output_template => 'Requests completed : %s', + perfdatas => [ + { label => 'request_completed', value => 'completed_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'request-pending', set => { + key_values => [ { name => 'pending' }, { name => 'display' } ], + output_template => 'Requests pending : %s', + perfdatas => [ + { label => 'request_pending', value => 'pending_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'thread-stuck', set => { + key_values => [ { name => 'stuck' }, { name => 'display' } ], + output_template => 'Threads stuck : %s', + perfdatas => [ + { label => 'thread_stuck', value => 'stuck_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_wm_output { + my ($self, %options) = @_; + + return "WorkerManager '" . $options{instance_value}->{display} . "' "; +} + sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; - + $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-application:s" => { name => 'filter_application' }, - "filter-name:s" => { name => 'filter_name' }, - "filter-runtime:s" => { name => 'filter_runtime' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - - foreach my $key (('runtime')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new( - statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } + $options{options}->add_options(arguments => { + "filter-application:s" => { name => 'filter_application' }, + "filter-name:s" => { name => 'filter_name' }, + "filter-runtime:s" => { name => 'filter_runtime' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('runtime')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - $self->{statefile_value}->check_options(%options); - $instance_mode = $self; + $self->SUPER::check_options(%options); $self->{overload_th} = {}; foreach my $val (@{$self->{option_results}->{threshold_overload}}) { @@ -159,77 +128,16 @@ sub check_options { } } -sub run { - my ($self, %options) = @_; - $self->{connector} = $options{custom}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{runtime}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All WorkerManagers are ok'); - } - - my $matching = ''; - foreach (('filter_application', 'filter_name', 'filter_runtime')) { - $matching .= defined($self->{option_results}->{$_}) ? $self->{option_results}->{$_} : 'all'; - } - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "weblogic_" . $self->{mode} . '_' . md5_hex($self->{connector}->{url}) . '_' . md5_hex($matching)); - $self->{new_datas}->{last_timestamp} = time(); - - foreach my $id (sort keys %{$self->{runtime}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{runtime}}) { - my $obj = $maps_counters->{runtime}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{runtime}->{$id}, - new_datas => $self->{new_datas}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "WorkerManager '$id' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "WorkerManager '$id' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "WorkerManager '$id' $long_msg"); - } - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} +my $thresholds = { + health => [ + ['HEALTH_OK', 'OK'], + ['HEALTH_WARNING', 'WARNING'], + ['HEALTH_CRITICAL', 'CRITICAL'], + ['HEALTH_FAILED', 'CRITICAL'], + ['HEALTH_OVERLOADED', 'CRITICAL'], + ['LOW_MEMORY_REASON', 'CRITICAL'], + ], +}; sub get_severity { my ($self, %options) = @_; @@ -265,13 +173,13 @@ my %map_state = ( sub manage_selection { my ($self, %options) = @_; - $self->{request} = [ + my $request = [ { mbean => 'com.bea:ApplicationRuntime=*,Name=*,ServerRuntime=*,Type=WorkManagerRuntime', - attributes => [ { name => 'HealthState' }, { name => 'StuckThreadCount' }, { name => 'CompletedRequests' }, { name => 'PendingRequests' } ] } + attributes => [ { name => 'HealthState' }, { name => 'StuckThreadCount' }, { name => 'CompletedRequests' }, { name => 'PendingRequests' } ] } ]; - my $result = $self->{connector}->get_attributes(request => $self->{request}, nothing_quit => 1); + my $result = $options{custom}->get_attributes(request => $request, nothing_quit => 1); - $self->{runtime} = {}; + $self->{wm} = {}; foreach my $mbean (keys %{$result}) { next if ($mbean !~ /ApplicationRuntime=(.*?),Name=(.*?),ServerRuntime=(.*?),/); my ($app, $name, $runtime) = ($1, $2, $3); @@ -280,28 +188,40 @@ sub manage_selection { if (defined($self->{option_results}->{filter_application}) && $self->{option_results}->{filter_application} ne '' && $app !~ /$self->{option_results}->{filter_application}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $app . "': no matching filter application."); + $self->{output}->output_add(long_msg => "skipping '" . $app . "': no matching filter application."); next; } 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 name."); + $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter name."); next; } if (defined($self->{option_results}->{filter_runtime}) && $self->{option_results}->{filter_runtime} ne '' && $runtime !~ /$self->{option_results}->{filter_runtime}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $runtime . "': no matching filter runtime."); + $self->{output}->output_add(long_msg => "skipping '" . $runtime . "': no matching filter runtime."); next; } - $self->{runtime}->{$app . '/' . $name . '/' . $runtime} = { health_state => $health_state, runtime => $app . '/' . $name . '/' . $runtime, - completed => $result->{$mbean}->{CompletedRequests}, pending => $result->{$mbean}->{PendingRequests}, stuck => $result->{$mbean}->{StuckThreadCount} }; + $self->{wm}->{$app . '/' . $name . '/' . $runtime} = { + health_state => $health_state, + display => $app . '/' . $name . '/' . $runtime, + completed => $result->{$mbean}->{CompletedRequests}, + pending => $result->{$mbean}->{PendingRequests}, + stuck => $result->{$mbean}->{StuckThreadCount} + }; } - if (scalar(keys %{$self->{runtime}}) <= 0) { + if (scalar(keys %{$self->{wm}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No entry found."); $self->{output}->option_exit(); } + + $self->{cache_name} = "weblogic_" . $self->{mode} . '_' . md5_hex($self->{connector}->{url}) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_application}) ? md5_hex($self->{option_results}->{filter_application}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_runtime}) ? md5_hex($self->{option_results}->{filter_runtime}) : md5_hex('all')); + } 1; diff --git a/apps/jenkins/mode/jobstate.pm b/apps/jenkins/mode/jobstate.pm index c89de5509..3ba01e1b9 100644 --- a/apps/jenkins/mode/jobstate.pm +++ b/apps/jenkins/mode/jobstate.pm @@ -34,26 +34,23 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port' }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path' }, - "timeout:s" => { name => 'timeout' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "jobname:s" => { name => 'jobname' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "checkstyle" => { name => 'checkstyle' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path' }, + "timeout:s" => { name => 'timeout' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "jobname:s" => { name => 'jobname' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "checkstyle" => { name => 'checkstyle' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -180,18 +177,10 @@ Specify username for API authentification Specify password for API authentification -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Threshold for HTTP timeout (Default: 5) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning> Warning Threshold for tendency score diff --git a/apps/kayako/api/mode/listdepartment.pm b/apps/kayako/api/mode/listdepartment.pm index 0d67778cf..a3d98c6c2 100644 --- a/apps/kayako/api/mode/listdepartment.pm +++ b/apps/kayako/api/mode/listdepartment.pm @@ -36,20 +36,17 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port' }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => '/api/index.php?' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "kayako-api-key:s" => { name => 'kayako_api_key' }, - "kayako-secret-key:s" => { name => 'kayako_secret_key' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => '/api/index.php?' }, + "timeout:s" => { name => 'timeout' }, + "kayako-api-key:s" => { name => 'kayako_api_key' }, + "kayako-secret-key:s" => { name => 'kayako_secret_key' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -116,10 +113,6 @@ Port used by Apache Specify https if needed -=item B<--proxyurl> - -Proxy URL if any - =item B<--urlpath> This is the URL you should dispatch all GET, POST, PUT & DELETE requests to (Default: '/api/index.php?') @@ -128,10 +121,6 @@ This is the URL you should dispatch all GET, POST, PUT & DELETE requests to (Def Threshold for HTTP timeout. -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--kayako-api-key> This is your unique API key. diff --git a/apps/kayako/api/mode/listpriority.pm b/apps/kayako/api/mode/listpriority.pm index 1841c506e..aa4a6e146 100644 --- a/apps/kayako/api/mode/listpriority.pm +++ b/apps/kayako/api/mode/listpriority.pm @@ -36,20 +36,17 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port' }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => '/api/index.php?' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "kayako-api-key:s" => { name => 'kayako_api_key' }, - "kayako-secret-key:s" => { name => 'kayako_secret_key' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => '/api/index.php?' }, + "timeout:s" => { name => 'timeout' }, + "kayako-api-key:s" => { name => 'kayako_api_key' }, + "kayako-secret-key:s" => { name => 'kayako_secret_key' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -116,10 +113,6 @@ Port used by Apache Specify https if needed -=item B<--proxyurl> - -Proxy URL if any - =item B<--urlpath> This is the URL you should dispatch all GET, POST, PUT & DELETE requests to (Default: '/api/index.php?') @@ -128,10 +121,6 @@ This is the URL you should dispatch all GET, POST, PUT & DELETE requests to (Def Threshold for HTTP timeout. -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--kayako-api-key> This is your unique API key. diff --git a/apps/kayako/api/mode/liststaff.pm b/apps/kayako/api/mode/liststaff.pm index ffcc00bf6..ba73c2302 100644 --- a/apps/kayako/api/mode/liststaff.pm +++ b/apps/kayako/api/mode/liststaff.pm @@ -34,20 +34,17 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port' }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => '/api/index.php?' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "kayako-api-key:s" => { name => 'kayako_api_key' }, - "kayako-secret-key:s" => { name => 'kayako_secret_key' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => '/api/index.php?' }, + "timeout:s" => { name => 'timeout' }, + "kayako-api-key:s" => { name => 'kayako_api_key' }, + "kayako-secret-key:s" => { name => 'kayako_secret_key' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -114,10 +111,6 @@ Port used by Apache Specify https if needed -=item B<--proxyurl> - -Proxy URL if any - =item B<--urlpath> This is the URL you should dispatch all GET, POST, PUT & DELETE requests to (Default: '/api/index.php?') @@ -126,10 +119,6 @@ This is the URL you should dispatch all GET, POST, PUT & DELETE requests to (Def Threshold for HTTP timeout. -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--kayako-api-key> This is your unique API key. diff --git a/apps/kayako/api/mode/liststatus.pm b/apps/kayako/api/mode/liststatus.pm index 374940000..500afa70a 100644 --- a/apps/kayako/api/mode/liststatus.pm +++ b/apps/kayako/api/mode/liststatus.pm @@ -34,20 +34,17 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port' }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => '/api/index.php?' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "kayako-api-key:s" => { name => 'kayako_api_key' }, - "kayako-secret-key:s" => { name => 'kayako_secret_key' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => '/api/index.php?' }, + "timeout:s" => { name => 'timeout' }, + "kayako-api-key:s" => { name => 'kayako_api_key' }, + "kayako-secret-key:s" => { name => 'kayako_secret_key' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -114,10 +111,6 @@ Port used by Apache Specify https if needed -=item B<--proxyurl> - -Proxy URL if any - =item B<--urlpath> This is the URL you should dispatch all GET, POST, PUT & DELETE requests to (Default: '/api/index.php?') @@ -126,10 +119,6 @@ This is the URL you should dispatch all GET, POST, PUT & DELETE requests to (Def Threshold for HTTP timeout. -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--kayako-api-key> This is your unique API key. diff --git a/apps/kayako/api/mode/ticketcount.pm b/apps/kayako/api/mode/ticketcount.pm index 82820122a..832e8075f 100644 --- a/apps/kayako/api/mode/ticketcount.pm +++ b/apps/kayako/api/mode/ticketcount.pm @@ -45,30 +45,27 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port' }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => '/api/index.php?' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "kayako-api-key:s" => { name => 'kayako_api_key' }, - "kayako-secret-key:s" => { name => 'kayako_secret_key' }, - "reload-cache-time:s" => { name => 'reload_cache_time', default => 180 }, - "department-id:s" => { name => 'department_id' }, - "staff-id:s" => { name => 'staff_id' }, - "status-id:s" => { name => 'status_id' }, - "priority-id:s" => { name => 'priority_id' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "start-date:s" => { name => 'start_date' }, - "end-date:s" => { name => 'end_date' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => '/api/index.php?' }, + "timeout:s" => { name => 'timeout' }, + "kayako-api-key:s" => { name => 'kayako_api_key' }, + "kayako-secret-key:s" => { name => 'kayako_secret_key' }, + "reload-cache-time:s" => { name => 'reload_cache_time', default => 180 }, + "department-id:s" => { name => 'department_id' }, + "staff-id:s" => { name => 'staff_id' }, + "status-id:s" => { name => 'status_id' }, + "priority-id:s" => { name => 'priority_id' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "start-date:s" => { name => 'start_date' }, + "end-date:s" => { name => 'end_date' }, + }); $self->{statefile_cache} = centreon::plugins::statefile->new(%options); $self->{statefile_value} = centreon::plugins::statefile->new(%options); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -339,10 +336,6 @@ Port used by Apache Specify https if needed -=item B<--proxyurl> - -Proxy URL if any - =item B<--urlpath> This is the URL you should dispatch all GET, POST, PUT & DELETE requests to (Default: '/api/index.php?') @@ -351,10 +344,6 @@ This is the URL you should dispatch all GET, POST, PUT & DELETE requests to (Def Threshold for HTTP timeout. -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--kayako-api-key> This is your unique API key. (required) diff --git a/apps/keepalived/snmp/mode/vrrpstatus.pm b/apps/keepalived/snmp/mode/vrrpstatus.pm new file mode 100644 index 000000000..f275ba7e8 --- /dev/null +++ b/apps/keepalived/snmp/mode/vrrpstatus.pm @@ -0,0 +1,155 @@ +# +# Copyright 2019 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 apps::keepalived::snmp::mode::vrrpstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("state : %s [last state : %s, wanted state : '%s']", + $self->{result_values}->{instanceState}, $self->{result_values}->{instanceStateLast}, $self->{result_values}->{instanceWantedState}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{instanceWantedState} = $options{new_datas}->{$self->{instance} . '_instance_wanted_state'}; + $self->{result_values}->{instanceStateLast} = $options{old_datas}->{$self->{instance} . '_instance_state'}; + $self->{result_values}->{instanceState} = $options{new_datas}->{$self->{instance} . '_instance_state'}; + $self->{result_values}->{instancePrimaryInterface} = $options{new_datas}->{$self->{instance} . '_instance_primary_interface'}; + if (!defined($options{old_datas}->{$self->{instance} . '_instance_state'})) { + $self->{error_msg} = "buffer creation"; + return -2; + } + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'vrrp', type => 1, cb_prefix_output => 'prefix_vrrp_output', message_multiple => 'All VRRP instances are ok' }, + ]; + + $self->{maps_counters}->{vrrp} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'instance_primary_interface' }, { name => 'instance_wanted_state' }, { name => 'instance_state' } ], + 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 => \&catalog_status_threshold, + } + }, + ]; +} + +sub prefix_vrrp_output { + my ($self, %options) = @_; + + return "VRRP '" . $options{instance_value}->{instance_primary_interface} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + 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 => '%{instanceState} ne %{instanceWantedState} or %{instanceState} ne %{instanceStateLast}' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +my %map_instance_state = (0 => 'init', 1 => 'backup', 2 => 'master', 3 => 'fault', 4 => 'unknown'); +my %map_instance_wanted_state = (0 => 'init', 1 => 'backup', 2 => 'master', 3 => 'fault', 4 => 'unknown'); +my $mapping = { + vrrpInstanceState => { oid => '.1.3.6.1.4.1.9586.100.5.2.3.1.4', map => \%map_instance_state }, + vrrpInstanceWantedState => { oid => '.1.3.6.1.4.1.9586.100.5.2.3.1.6', map => \%map_instance_wanted_state }, + vrrpInstancePrimaryInterface => { oid => '.1.3.6.1.4.1.9586.100.5.2.3.1.10' }, +}; + +my $oid_vrrpInstanceEntry = '.1.3.6.1.4.1.9586.100.5.2.3.1'; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{vrrp} = {}; + my $snmp_result = $options{snmp}->get_table(oid => $oid_vrrpInstanceEntry, end => $mapping->{vrrpInstancePrimaryInterface}->{oid}, + nothing_quit => 1); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{vrrpInstanceState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $self->{vrrp}->{$instance} = { + instance_primary_interface => $result->{vrrpInstancePrimaryInterface}, + instance_wanted_state => $result->{vrrpInstanceWantedState}, + instance_state => $result->{vrrpInstanceState}, + }; + } + + $self->{cache_name} = "keepalived_" . $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')); +} + +1; + +__END__ + +=head1 MODE + +Check VRRP instances status. + +=over 8 + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{instanceWantedState}, %{instanceStateLast}, %{instanceState}, %{instancePrimaryInterface} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{instanceState} ne %{instanceWantedState} or %{instanceState} ne %{instanceStateLast}'). +Can used special variables like: %{instanceWantedState}, %{instanceStateLast}, %{instanceState}, %{instancePrimaryInterface} + +=back + +=cut diff --git a/apps/keepalived/snmp/plugin.pm b/apps/keepalived/snmp/plugin.pm new file mode 100644 index 000000000..2bdf299d8 --- /dev/null +++ b/apps/keepalived/snmp/plugin.pm @@ -0,0 +1,48 @@ +# +# Copyright 2019 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 apps::keepalived::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}} = ( + 'vrrp-status' => 'apps::keepalived::snmp::mode::vrrpstatus', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Keepalived in SNMP. + +=cut diff --git a/apps/kingdee/eas/custom/api.pm b/apps/kingdee/eas/custom/api.pm index dcee5e5bc..b4fe2021e 100644 --- a/apps/kingdee/eas/custom/api.pm +++ b/apps/kingdee/eas/custom/api.pm @@ -39,23 +39,20 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s@" => { name => 'hostname' }, - "proto:s@" => { name => 'proto' }, - "port:s@" => { name => 'port' }, - "username:s@" => { name => 'username' }, - "password:s@" => { name => 'password' }, - "proxyurl:s@" => { name => 'proxyurl' }, - "timeout:s@" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s@" => { name => 'hostname' }, + "proto:s@" => { name => 'proto' }, + "port:s@" => { name => 'port' }, + "username:s@" => { name => 'username' }, + "password:s@" => { name => 'password' }, + "timeout:s@" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; @@ -92,7 +89,6 @@ sub check_options { $self->{proto} = (defined($self->{option_results}->{proto})) ? shift(@{$self->{option_results}->{proto}}) : 'http'; $self->{port} = (defined($self->{option_results}->{port})) ? shift(@{$self->{option_results}->{port}}) : 80; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef; if (!defined($self->{hostname})) { $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); @@ -113,7 +109,6 @@ sub build_options_for_httplib { $self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{port} = $self->{port}; $self->{option_results}->{proto} = $self->{proto}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; $self->{option_results}->{credentials} = 1; $self->{option_results}->{basic} = 1; $self->{option_results}->{username} = $self->{username}; @@ -169,18 +164,10 @@ Kingdee username. Kingdee password. -=item B<--proxyurl> - -Proxy URL if any. - =item B<--timeout> Set HTTP timeout in seconds (Default: '10'). -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/apps/lmsensors/mode/fan.pm b/apps/lmsensors/mode/fan.pm deleted file mode 100644 index 69b725562..000000000 --- a/apps/lmsensors/mode/fan.pm +++ /dev/null @@ -1,178 +0,0 @@ -# -# Copyright 2019 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 apps::lmsensors::mode::fan; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my $oid_SensorDesc = '.1.3.6.1.4.1.2021.13.16.3.1.2'; # fan entry description -my $oid_SensorValue = '.1.3.6.1.4.1.2021.13.16.3.1.3'; # fan entry value (RPM) - -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:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "name" => { name => 'use_name' }, - "sensor:s" => { name => 'sensor' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - }); - - $self->{Sensor_id_selected} = []; - - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } - -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - $self->manage_selection(); - - $self->{snmp}->load(oids => [$oid_SensorDesc, $oid_SensorValue], instances => $self->{Sensor_id_selected}); - my $SensorValueResult = $self->{snmp}->get_leef(nothing_quit => 1); - - if (!defined($self->{option_results}->{sensor}) || defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All Fans are ok.'); - } - - foreach my $SensorId (sort @{$self->{Sensor_id_selected}}) { - my $SensorDesc = $SensorValueResult->{$oid_SensorDesc . '.' . $SensorId}; - my $SensorValue = $SensorValueResult->{$oid_SensorValue . '.' . $SensorId}; - - my $exit = $self->{perfdata}->threshold_check(value => $SensorValue, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - - $self->{output}->output_add(long_msg => sprintf("Sensor '%s' Fan: %s", - $SensorDesc, $SensorValue)); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || (defined($self->{option_results}->{sensor}) && !defined($self->{option_results}->{use_regexp}))) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Sensor '%s' Fan: %s", - $SensorDesc, $SensorValue)); - } - - my $label = 'sensor_fan'; - my $extra_label = ''; - $extra_label = '_' . $SensorId . "_" . $SensorDesc if (!defined($self->{option_results}->{sensor}) || defined($self->{option_results}->{use_regexp})); - $self->{output}->perfdata_add(label => $label . $extra_label, - value => $SensorValue, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical')); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub manage_selection { - my ($self, %options) = @_; - my $result = $self->{snmp}->get_table(oid => $oid_SensorDesc, nothing_quit => 1); - - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - next if ($key !~ /\.([0-9]+)$/); - my $SensorId = $1; - my $SensorDesc = $result->{$key}; - - next if (defined($self->{option_results}->{sensor}) && !defined($self->{option_results}->{use_name}) && !defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) - && $SensorId !~ /$self->{option_results}->{sensor}/i); - next if (defined($self->{option_results}->{use_name}) && defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi}) - && $SensorDesc !~ /$self->{option_results}->{sensor}/i); - next if (defined($self->{option_results}->{use_name}) && defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) - && $SensorDesc !~ /$self->{option_results}->{sensor}/); - next if (defined($self->{option_results}->{use_name}) && !defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) - && $SensorDesc ne $self->{option_results}->{sensor}); - - - push @{$self->{Sensor_id_selected}}, $SensorId; -} - - if (scalar(@{$self->{Sensor_id_selected}}) <= 0) { - if (defined($self->{option_results}->{sensor})) { - $self->{output}->add_option_msg(short_msg => "No Sensors found for '" . $self->{option_results}->{sensor} . "'."); - } else { - $self->{output}->add_option_msg(short_msg => "No Sensors found."); - }; - $self->{output}->option_exit(); - } -} - -1; - -__END__ - -=head1 MODE - -Check LM-Sensors: Fan Sensors - -=over 8 - -=item B<--warning> - -Threshold warning (Fan Speed, U/min) - -=item B<--critical> - -Threshold critical (Fan Speed, U/min) - -=item B<--sensor> - -Set the Sensor Desc (number expected) ex: 1, 2,... (empty means 'check all sensors'). - -=item B<--name> - -Allows to use Sensor Desc name with option --sensor instead of Sensor Desc oid index. - -=item B<--regexp> - -Allows to use regexp to filter sensordesc (with option --name). - -=item B<--regexp-isensitive> - -Allows to use regexp non case-sensitive (with --regexp). - -=back - -=cut diff --git a/apps/lmsensors/mode/misc.pm b/apps/lmsensors/mode/misc.pm deleted file mode 100644 index 512fcd4c0..000000000 --- a/apps/lmsensors/mode/misc.pm +++ /dev/null @@ -1,178 +0,0 @@ -# -# Copyright 2019 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 apps::lmsensors::mode::misc; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my $oid_SensorDesc = '.1.3.6.1.4.1.2021.13.16.5.1.2'; # misc entry description -my $oid_SensorValue = '.1.3.6.1.4.1.2021.13.16.5.1.3'; # misc entry value - -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:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "name" => { name => 'use_name' }, - "sensor:s" => { name => 'sensor' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - }); - - $self->{Sensor_id_selected} = []; - - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } - -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - $self->manage_selection(); - - $self->{snmp}->load(oids => [$oid_SensorDesc, $oid_SensorValue], instances => $self->{Sensor_id_selected}); - my $SensorValueResult = $self->{snmp}->get_leef(nothing_quit => 1); - - if (!defined($self->{option_results}->{sensor}) || defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All Sensors are ok.'); - } - - foreach my $SensorId (sort @{$self->{Sensor_id_selected}}) { - my $SensorDesc = $SensorValueResult->{$oid_SensorDesc . '.' . $SensorId}; - my $SensorValue = $SensorValueResult->{$oid_SensorValue . '.' . $SensorId} / 1000; - - my $exit = $self->{perfdata}->threshold_check(value => $SensorValue, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - - $self->{output}->output_add(long_msg => sprintf("Sensor '%s': %s", - $SensorDesc, $SensorValue)); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || (defined($self->{option_results}->{sensor}) && !defined($self->{option_results}->{use_regexp}))) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Sensor '%s': %s", - $SensorDesc, $SensorValue)); - } - - my $label = 'sensor_misc'; - my $extra_label = ''; - $extra_label = '_' . $SensorId . "_" . $SensorDesc if (!defined($self->{option_results}->{sensor}) || defined($self->{option_results}->{use_regexp})); - $self->{output}->perfdata_add(label => $label . $extra_label, - value => $SensorValue, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical')); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub manage_selection { - my ($self, %options) = @_; - my $result = $self->{snmp}->get_table(oid => $oid_SensorDesc, nothing_quit => 1); - - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - next if ($key !~ /\.([0-9]+)$/); - my $SensorId = $1; - my $SensorDesc = $result->{$key}; - - next if (defined($self->{option_results}->{sensor}) && !defined($self->{option_results}->{use_name}) && !defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) - && $SensorId !~ /$self->{option_results}->{sensor}/i); - next if (defined($self->{option_results}->{use_name}) && defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi}) - && $SensorDesc !~ /$self->{option_results}->{sensor}/i); - next if (defined($self->{option_results}->{use_name}) && defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) - && $SensorDesc !~ /$self->{option_results}->{sensor}/); - next if (defined($self->{option_results}->{use_name}) && !defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) - && $SensorDesc ne $self->{option_results}->{sensor}); - - - push @{$self->{Sensor_id_selected}}, $SensorId; -} - - if (scalar(@{$self->{Sensor_id_selected}}) <= 0) { - if (defined($self->{option_results}->{sensor})) { - $self->{output}->add_option_msg(short_msg => "No Sensors found for '" . $self->{option_results}->{sensor} . "'."); - } else { - $self->{output}->add_option_msg(short_msg => "No Sensors found."); - }; - $self->{output}->option_exit(); - } -} - -1; - -__END__ - -=head1 MODE - -Check LM-Sensors: Misc Sensors - -=over 8 - -=item B<--warning> - -Threshold warning - -=item B<--critical> - -Threshold critical - -=item B<--sensor> - -Set the Sensor Desc (number expected) ex: 1, 2,... (empty means 'check all sensors'). - -=item B<--name> - -Allows to use Sensor Desc name with option --sensor instead of Sensor Desc oid index. - -=item B<--regexp> - -Allows to use regexp to filter sensordesc (with option --name). - -=item B<--regexp-isensitive> - -Allows to use regexp non case-sensitive (with --regexp). - -=back - -=cut diff --git a/apps/lmsensors/mode/temperature.pm b/apps/lmsensors/mode/temperature.pm deleted file mode 100644 index 3b0abc72c..000000000 --- a/apps/lmsensors/mode/temperature.pm +++ /dev/null @@ -1,178 +0,0 @@ -# -# Copyright 2019 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 apps::lmsensors::mode::temperature; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my $oid_SensorDesc = '.1.3.6.1.4.1.2021.13.16.2.1.2'; # temperature entry description -my $oid_SensorValue = '.1.3.6.1.4.1.2021.13.16.2.1.3'; # temperature entry value (RPM) - -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:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "name" => { name => 'use_name' }, - "sensor:s" => { name => 'sensor' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - }); - - $self->{Sensor_id_selected} = []; - - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } - -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - $self->manage_selection(); - - $self->{snmp}->load(oids => [$oid_SensorDesc, $oid_SensorValue], instances => $self->{Sensor_id_selected}); - my $SensorValueResult = $self->{snmp}->get_leef(nothing_quit => 1); - - if (!defined($self->{option_results}->{sensor}) || defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All Temperatures are ok.'); - } - - foreach my $SensorId (sort @{$self->{Sensor_id_selected}}) { - my $SensorDesc = $SensorValueResult->{$oid_SensorDesc . '.' . $SensorId}; - my $SensorValue = $SensorValueResult->{$oid_SensorValue . '.' . $SensorId} / 1000; - - my $exit = $self->{perfdata}->threshold_check(value => $SensorValue, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - - $self->{output}->output_add(long_msg => sprintf("Sensor '%s' Temperature: %s", - $SensorDesc, $SensorValue)); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || (defined($self->{option_results}->{sensor}) && !defined($self->{option_results}->{use_regexp}))) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Sensor '%s' Temperature: %s", - $SensorDesc, $SensorValue)); - } - - my $label = 'sensor_temperature'; - my $extra_label = ''; - $extra_label = '_' . $SensorId . "_" . $SensorDesc if (!defined($self->{option_results}->{sensor}) || defined($self->{option_results}->{use_regexp})); - $self->{output}->perfdata_add(label => $label . $extra_label, - value => $SensorValue, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical')); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub manage_selection { - my ($self, %options) = @_; - my $result = $self->{snmp}->get_table(oid => $oid_SensorDesc, nothing_quit => 1); - - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - next if ($key !~ /\.([0-9]+)$/); - my $SensorId = $1; - my $SensorDesc = $result->{$key}; - - next if (defined($self->{option_results}->{sensor}) && !defined($self->{option_results}->{use_name}) && !defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) - && $SensorId !~ /$self->{option_results}->{sensor}/i); - next if (defined($self->{option_results}->{use_name}) && defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi}) - && $SensorDesc !~ /$self->{option_results}->{sensor}/i); - next if (defined($self->{option_results}->{use_name}) && defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) - && $SensorDesc !~ /$self->{option_results}->{sensor}/); - next if (defined($self->{option_results}->{use_name}) && !defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) - && $SensorDesc ne $self->{option_results}->{sensor}); - - - push @{$self->{Sensor_id_selected}}, $SensorId; -} - - if (scalar(@{$self->{Sensor_id_selected}}) <= 0) { - if (defined($self->{option_results}->{sensor})) { - $self->{output}->add_option_msg(short_msg => "No Sensors found for '" . $self->{option_results}->{sensor} . "'."); - } else { - $self->{output}->add_option_msg(short_msg => "No Sensors found."); - }; - $self->{output}->option_exit(); - } -} - -1; - -__END__ - -=head1 MODE - -Check LM-Sensors: Temperature Sensors - -=over 8 - -=item B<--warning> - -Threshold warning - -=item B<--critical> - -Threshold critical - -=item B<--sensor> - -Set the Sensor Desc (number expected) ex: 1, 2,... (empty means 'check all sensors'). - -=item B<--name> - -Allows to use Sensor Desc name with option --sensor instead of Sensor Desc oid index. - -=item B<--regexp> - -Allows to use regexp to filter sensordesc (with option --name). - -=item B<--regexp-isensitive> - -Allows to use regexp non case-sensitive (with --regexp). - -=back - -=cut diff --git a/apps/lmsensors/mode/voltage.pm b/apps/lmsensors/mode/voltage.pm deleted file mode 100644 index 9c742f696..000000000 --- a/apps/lmsensors/mode/voltage.pm +++ /dev/null @@ -1,178 +0,0 @@ -# -# Copyright 2019 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 apps::lmsensors::mode::voltage; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my $oid_SensorDesc = '.1.3.6.1.4.1.2021.13.16.4.1.2'; # voltage entry description -my $oid_SensorValue = '.1.3.6.1.4.1.2021.13.16.4.1.3'; # voltage entry value (mV) - -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:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "name" => { name => 'use_name' }, - "sensor:s" => { name => 'sensor' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - }); - - $self->{Sensor_id_selected} = []; - - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } - -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - $self->manage_selection(); - - $self->{snmp}->load(oids => [$oid_SensorDesc, $oid_SensorValue], instances => $self->{Sensor_id_selected}); - my $SensorValueResult = $self->{snmp}->get_leef(nothing_quit => 1); - - if (!defined($self->{option_results}->{sensor}) || defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All Voltages are ok.'); - } - - foreach my $SensorId (sort @{$self->{Sensor_id_selected}}) { - my $SensorDesc = $SensorValueResult->{$oid_SensorDesc . '.' . $SensorId}; - my $SensorValue = $SensorValueResult->{$oid_SensorValue . '.' . $SensorId} / 1000; - - my $exit = $self->{perfdata}->threshold_check(value => $SensorValue, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - - $self->{output}->output_add(long_msg => sprintf("Sensor '%s' Volt: %s", - $SensorDesc, $SensorValue)); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || (defined($self->{option_results}->{sensor}) && !defined($self->{option_results}->{use_regexp}))) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Sensor '%s' Volt: %s", - $SensorDesc, $SensorValue)); - } - - my $label = 'sensor_voltage'; - my $extra_label = ''; - $extra_label = '_' . $SensorId . "_" . $SensorDesc if (!defined($self->{option_results}->{sensor}) || defined($self->{option_results}->{use_regexp})); - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'V', - value => $SensorValue, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical')); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub manage_selection { - my ($self, %options) = @_; - my $result = $self->{snmp}->get_table(oid => $oid_SensorDesc, nothing_quit => 1); - - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - next if ($key !~ /\.([0-9]+)$/); - my $SensorId = $1; - my $SensorDesc = $result->{$key}; - - next if (defined($self->{option_results}->{sensor}) && !defined($self->{option_results}->{use_name}) && !defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) - && $SensorId !~ /$self->{option_results}->{sensor}/i); - next if (defined($self->{option_results}->{use_name}) && defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi}) - && $SensorDesc !~ /$self->{option_results}->{sensor}/i); - next if (defined($self->{option_results}->{use_name}) && defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) - && $SensorDesc !~ /$self->{option_results}->{sensor}/); - next if (defined($self->{option_results}->{use_name}) && !defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) - && $SensorDesc ne $self->{option_results}->{sensor}); - - - push @{$self->{Sensor_id_selected}}, $SensorId; -} - - if (scalar(@{$self->{Sensor_id_selected}}) <= 0) { - if (defined($self->{option_results}->{sensor})) { - $self->{output}->add_option_msg(short_msg => "No Sensors found for '" . $self->{option_results}->{sensor} . "'."); - } else { - $self->{output}->add_option_msg(short_msg => "No Sensors found."); - }; - $self->{output}->option_exit(); - } -} - -1; - -__END__ - -=head1 MODE - -Check LM-Sensors: Voltage Sensors - -=over 8 - -=item B<--warning> - -Threshold warning (Volt) - -=item B<--critical> - -Threshold critical (Volt) - -=item B<--sensor> - -Set the Sensor Desc (number expected) ex: 1, 2,... (empty means 'check all sensors'). - -=item B<--name> - -Allows to use Sensor Desc name with option --sensor instead of Sensor Desc oid index. - -=item B<--regexp> - -Allows to use regexp to filter sensordesc (with option --name). - -=item B<--regexp-isensitive> - -Allows to use regexp non case-sensitive (with --regexp). - -=back - -=cut diff --git a/apps/lmsensors/snmp/mode/components/fan.pm b/apps/lmsensors/snmp/mode/components/fan.pm new file mode 100644 index 000000000..e2de1751d --- /dev/null +++ b/apps/lmsensors/snmp/mode/components/fan.pm @@ -0,0 +1,76 @@ +# +# Copyright 2019 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 apps::lmsensors::snmp::mode::components::fan; + +use strict; +use warnings; + +my $mapping = { + lmFanSensorsDevice => { oid => '.1.3.6.1.4.1.2021.13.16.3.1.2' }, + lmFanSensorsValue => { oid => '.1.3.6.1.4.1.2021.13.16.3.1.3' }, +}; + +my $oid_lmFanSensorsEntry = '.1.3.6.1.4.1.2021.13.16.3.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_lmFanSensorsEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fans"); + $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; + return if ($self->check_filter(section => 'fan')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_lmFanSensorsEntry}})) { + next if ($oid !~ /^$mapping->{lmFanSensorsValue}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_lmFanSensorsEntry}, instance => $instance); + + next if ($self->check_filter(section => 'fan', instance => $instance, name => $result->{lmFanSensorsDevice})); + $self->{components}->{fan}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("fan '%s' speed is %s rpm [instance = %s]", + $result->{lmFanSensorsDevice}, $result->{lmFanSensorsValue}, $instance, + )); + + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, name => $result->{lmFanSensorsDevice}, value => $result->{lmFanSensorsValue}); + + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Fan '%s' speed is %s rpm", $result->{lmFanSensorsDevice}, $result->{lmFanSensorsValue})); + } + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'sensor.fan.speed.rpm', + instances => $result->{lmFanSensorsDevice}, + value => $result->{lmFanSensorsValue}, + warning => $warn, + critical => $crit, + min => 0, + ); + } +} + +1; diff --git a/apps/lmsensors/snmp/mode/components/misc.pm b/apps/lmsensors/snmp/mode/components/misc.pm new file mode 100644 index 000000000..0cf93d5b3 --- /dev/null +++ b/apps/lmsensors/snmp/mode/components/misc.pm @@ -0,0 +1,76 @@ +# +# Copyright 2019 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 apps::lmsensors::snmp::mode::components::misc; + +use strict; +use warnings; + +my $mapping = { + lmMiscSensorsDevice => { oid => '.1.3.6.1.4.1.2021.13.16.5.1.2' }, + lmMiscSensorsValue => { oid => '.1.3.6.1.4.1.2021.13.16.5.1.3' }, +}; + +my $oid_lmMiscSensorsEntry = '.1.3.6.1.4.1.2021.13.16.5.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_lmMiscSensorsEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking misc"); + $self->{components}->{misc} = {name => 'misc', total => 0, skip => 0}; + return if ($self->check_filter(section => 'misc')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_lmMiscSensorsEntry}})) { + next if ($oid !~ /^$mapping->{lmMiscSensorsValue}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_lmMiscSensorsEntry}, instance => $instance); + + next if ($self->check_filter(section => 'misc', instance => $instance, name => $result->{lmMiscSensorsDevice})); + $self->{components}->{misc}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("misc '%s' values is %s [instance = %s]", + $result->{lmMiscSensorsDevice}, $result->{lmMiscSensorsValue}, $instance, + )); + + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'misc', instance => $instance, name => $result->{lmMiscSensorsDevice}, value => $result->{lmMiscSensorsValue}); + + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Misc '%s' value is %s", $result->{lmMiscSensorsDevice}, $result->{lmMiscSensorsValue})); + } + $self->{output}->perfdata_add( + label => 'misc',, + nlabel => 'sensor.misc.current', + instances => $result->{lmMiscSensorsDevice}, + value => $result->{lmMiscSensorsValue}, + warning => $warn, + critical => $crit, + min => 0, + ); + } +} + +1; diff --git a/apps/lmsensors/snmp/mode/components/temperature.pm b/apps/lmsensors/snmp/mode/components/temperature.pm new file mode 100644 index 000000000..b80a3aedc --- /dev/null +++ b/apps/lmsensors/snmp/mode/components/temperature.pm @@ -0,0 +1,76 @@ +# +# Copyright 2019 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 apps::lmsensors::snmp::mode::components::temperature; + +use strict; +use warnings; + +my $mapping = { + lmTempSensorsDevice => { oid => '.1.3.6.1.4.1.2021.13.16.2.1.2' }, + lmTempSensorsValue => { oid => '.1.3.6.1.4.1.2021.13.16.2.1.3' }, +}; + +my $oid_lmTempSensorsEntry = '.1.3.6.1.4.1.2021.13.16.2.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_lmTempSensorsEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking temperatures"); + $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; + return if ($self->check_filter(section => 'temperature')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_lmTempSensorsEntry}})) { + next if ($oid !~ /^$mapping->{lmTempSensorsValue}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_lmTempSensorsEntry}, instance => $instance); + + next if ($self->check_filter(section => 'temperature', instance => $instance, name => $result->{lmTempSensorsDevice})); + $self->{components}->{temperature}->{total}++; + + $result->{lmTempSensorsValue} /= 1000; + $self->{output}->output_add(long_msg => sprintf("temperature '%s' is %s C [instance = %s]", + $result->{lmTempSensorsDevice}, $result->{lmTempSensorsValue}, $instance, + )); + + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, name => $result->{lmTempSensorsDevice}, value => $result->{lmTempSensorsValue}); + + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' is %s C", $result->{lmTempSensorsDevice}, $result->{lmTempSensorsValue})); + } + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'sensor.temperature.celsius', + instances => $result->{lmTempSensorsDevice}, + value => $result->{lmTempSensorsValue}, + warning => $warn, + critical => $crit, + ); + } +} + +1; diff --git a/apps/lmsensors/snmp/mode/components/voltage.pm b/apps/lmsensors/snmp/mode/components/voltage.pm new file mode 100644 index 000000000..c3a9a4412 --- /dev/null +++ b/apps/lmsensors/snmp/mode/components/voltage.pm @@ -0,0 +1,76 @@ +# +# Copyright 2019 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 apps::lmsensors::snmp::mode::components::voltage; + +use strict; +use warnings; + +my $mapping = { + lmVoltSensorsDevice => { oid => '.1.3.6.1.4.1.2021.13.16.4.1.2' }, + lmVoltSensorsValue => { oid => '.1.3.6.1.4.1.2021.13.16.4.1.3' }, +}; + +my $oid_lmVoltSensorsEntry = '.1.3.6.1.4.1.2021.13.16.4.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_lmVoltSensorsEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking voltages"); + $self->{components}->{voltage} = {name => 'voltages', total => 0, skip => 0}; + return if ($self->check_filter(section => 'voltage')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_lmVoltSensorsEntry}})) { + next if ($oid !~ /^$mapping->{lmVoltSensorsValue}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_lmVoltSensorsEntry}, instance => $instance); + + next if ($self->check_filter(section => 'voltage', instance => $instance, name => $result->{lmVoltSensorsDevice})); + $self->{components}->{voltage}->{total}++; + + $result->{lmVoltSensorsValue} /= 1000; + $self->{output}->output_add(long_msg => sprintf("voltage '%s' is %s V [instance = %s]", + $result->{lmVoltSensorsDevice}, $result->{lmVoltSensorsValue}, $instance, + )); + + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'voltage', instance => $instance, name => $result->{lmVoltSensorsDevice}, value => $result->{lmVoltSensorsValue}); + + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Voltage '%s' is %s V", $result->{lmVoltSensorsDevice}, $result->{lmVoltSensorsValue})); + } + $self->{output}->perfdata_add( + label => 'voltage', unit => 'V', + nlabel => 'sensor.voltage.volt', + instances => $result->{lmVoltSensorsDevice}, + value => $result->{lmVoltSensorsValue}, + warning => $warn, + critical => $crit, + ); + } +} + +1; diff --git a/apps/lmsensors/snmp/mode/sensors.pm b/apps/lmsensors/snmp/mode/sensors.pm new file mode 100644 index 000000000..c796274ea --- /dev/null +++ b/apps/lmsensors/snmp/mode/sensors.pm @@ -0,0 +1,101 @@ +# +# Copyright 2019 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 apps::lmsensors::snmp::mode::sensors; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(temperature|fan|voltage|misc)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|fan|voltage|misc)$'; + + $self->{cb_hook1} = 'get_version'; # before the loads + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + }; + + $self->{components_path} = 'apps::lmsensors::snmp::mode::components'; + $self->{components_module} = ['fan', 'temperature', 'voltage', 'misc']; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check components. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'fan', 'voltage', 'temperature', 'misc'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=power) +Can also exclude specific instance: --filter=power,3.3 + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=item B<--warning> + +Set warning threshold (syntax: type,instance,threshold) +Example: --warning='temperature,.*,20' + +=item B<--critical> + +Set critical threshold (syntax: type,instance,threshold) +Example: --critical='temperature,1,25' + +=back + +=cut + diff --git a/apps/lmsensors/plugin.pm b/apps/lmsensors/snmp/plugin.pm similarity index 76% rename from apps/lmsensors/plugin.pm rename to apps/lmsensors/snmp/plugin.pm index de4ca347c..fbb30a929 100644 --- a/apps/lmsensors/plugin.pm +++ b/apps/lmsensors/snmp/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package apps::lmsensors::plugin; +package apps::lmsensors::snmp::plugin; use strict; use warnings; @@ -31,11 +31,8 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'temperature' => 'apps::lmsensors::mode::temperature', - 'fan' => 'apps::lmsensors::mode::fan', - 'voltage' => 'apps::lmsensors::mode::voltage', - 'misc' => 'apps::lmsensors::mode::misc', - ); + 'sensors' => 'apps::lmsensors::snmp::mode::sensors', + ); return $self; } @@ -46,6 +43,6 @@ __END__ =head1 PLUGIN DESCRIPTION -Check with SNMP LM-Sensors Status +Check with SNMP LM-Sensors =cut diff --git a/apps/nginx/serverstatus/mode/connections.pm b/apps/nginx/serverstatus/mode/connections.pm index 0e8da72e5..beadcc04a 100644 --- a/apps/nginx/serverstatus/mode/connections.pm +++ b/apps/nginx/serverstatus/mode/connections.pm @@ -39,20 +39,17 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/nginx_status" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/nginx_status" }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + }); foreach (@{$maps}) { $options{options}->add_options(arguments => { 'warning-' . $_->{counter} . ':s' => { name => 'warning_' . $_->{counter} }, @@ -60,7 +57,7 @@ sub new { }); } - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -127,10 +124,6 @@ IP Addr/FQDN of the webserver host Port used by Apache -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Protocol to use http or https, http is default @@ -163,10 +156,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning-*> Warning Threshold. Can be: 'active', 'waiting', 'writing', 'reading'. @@ -177,4 +166,4 @@ Critical Threshold. Can be: 'active', 'waiting', 'writing', 'reading'. =back -=cut \ No newline at end of file +=cut diff --git a/apps/nginx/serverstatus/mode/requests.pm b/apps/nginx/serverstatus/mode/requests.pm index c1e8cd840..4c9216097 100644 --- a/apps/nginx/serverstatus/mode/requests.pm +++ b/apps/nginx/serverstatus/mode/requests.pm @@ -39,20 +39,17 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/nginx_status" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/nginx_status" }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + }); foreach (@{$maps}) { $options{options}->add_options(arguments => { 'warning-' . $_->{counter} . ':s' => { name => 'warning_' . $_->{counter} }, @@ -60,7 +57,7 @@ sub new { }); } $self->{statefile_value} = centreon::plugins::statefile->new(%options); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -175,10 +172,6 @@ IP Addr/FQDN of the webserver host Port used by Apache -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Specify https if needed @@ -211,10 +204,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning-*> Warning Threshold. Can be: 'accepts', 'handled', 'requests'. diff --git a/apps/nginx/serverstatus/mode/responsetime.pm b/apps/nginx/serverstatus/mode/responsetime.pm index 48624073e..027d840dc 100644 --- a/apps/nginx/serverstatus/mode/responsetime.pm +++ b/apps/nginx/serverstatus/mode/responsetime.pm @@ -33,26 +33,23 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/nginx_status" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "unknown-status:s" => { name => 'unknown_status', default => '' }, - "warning-status:s" => { name => 'warning_status' }, - "critical-status:s" => { name => 'critical_status', default => '%{http_code} < 200 or %{http_code} >= 300' }, - }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/nginx_status" }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "timeout:s" => { name => 'timeout' }, + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status', default => '%{http_code} < 200 or %{http_code} >= 300' }, + }); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -140,18 +137,10 @@ Specify this option if you access server-status page over hidden basic authentic (Use with --credentials) -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--unknown-status> Threshold warning for http response code diff --git a/apps/nsclient/restapi/mode/query.pm b/apps/nsclient/restapi/mode/query.pm index c945e9baa..1061bd88a 100644 --- a/apps/nsclient/restapi/mode/query.pm +++ b/apps/nsclient/restapi/mode/query.pm @@ -34,10 +34,8 @@ sub new { bless $self, $class; $self->{version} = '1.1'; - $options{options}->add_options(arguments => - { + $options{options}->add_options(arguments => { "hostname:s" => { name => 'hostname' }, - "http-peer-addr:s" => { name => 'http_peer_addr' }, "port:s" => { name => 'port', default => 8443 }, "proto:s" => { name => 'proto', default => 'https' }, "credentials" => { name => 'credentials' }, @@ -45,19 +43,15 @@ sub new { "username:s" => { name => 'username' }, "password:s" => { name => 'password' }, "legacy-password:s" => { name => 'legacy_password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "proxypac:s" => { name => 'proxypac' }, "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "ssl:s" => { name => 'ssl' }, "command:s" => { name => 'command' }, "arg:s@" => { name => 'arg' }, "unknown-status:s" => { name => 'unknown_status', default => '%{http_code} < 200 or %{http_code} >= 300' }, "warning-status:s" => { name => 'warning_status' }, "critical-status:s" => { name => 'critical_status', default => '' }, - }); + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -180,10 +174,6 @@ Query NSClient Rest API. IP Addr/FQDN of the host -=item B<--http-peer-addr> - -Set the address you want to connect (Useful if hostname is only a vhost. no ip resolve) - =item B<--port> Port used (Default: 8443) @@ -216,22 +206,10 @@ Specify this option if you access webpage over hidden basic authentication or yo Specify password for old authentification system. -=item B<--proxyurl> - -Proxy URL - -=item B<--proxypac> - -Proxy pac file (can be an url or local file) - =item B<--timeout> Threshold for HTTP timeout (Default: 5) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--command> Set command. diff --git a/apps/openldap/ldap/mode/systemusage.pm b/apps/openldap/ldap/mode/systemusage.pm new file mode 100644 index 000000000..42c907829 --- /dev/null +++ b/apps/openldap/ldap/mode/systemusage.pm @@ -0,0 +1,270 @@ +# +# Copyright 2019 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 apps::openldap::ldap::mode::systemusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use centreon::common::protocols::ldap::lib::ldap; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, message_separator => ' - ', skipped_code => { -10 => 1 } }, + { name => 'operation', type => 0, cb_prefix_output => 'prefix_operation_output', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{operation} = []; + foreach ('search', 'add', 'bind', 'unbind', 'delete') { + push @{$self->{maps_counters}->{operation}}, + { label => 'op-' . $_, nlabel => 'system.operations.' . $_ . '.completed.count', set => { + key_values => [ { name => 'operations_completed_' . $_, diff => 1 } ], + output_template => $_ . ' %s', + perfdatas => [ + { label => 'operations_' . $_, value => 'operations_completed_' . $_ . '_absolute', template => '%.2f', + min => 0 }, + ], + } + }; + } + + + $self->{maps_counters}->{global} = [ + { label => 'con-current', nlabel => 'system.connections.current.count', set => { + key_values => [ { name => 'connections_current' } ], + output_template => 'Current connections %s', + perfdatas => [ + { label => 'connections_current', value => 'connections_current_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'con-total', nlabel => 'system.connections.total.count', set => { + key_values => [ { name => 'connections_total', diff => 1 } ], + output_template => 'Total connections %s', + perfdatas => [ + { label => 'connections_total', value => 'connections_total_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'threads-active', nlabel => 'system.threads.active.percentage', set => { + key_values => [ { name => 'threads_active_prct' } ], + output_template => 'Current active threads %.2f %%', + perfdatas => [ + { label => 'threads_active', value => 'threads_active_prct_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'traffic', nlabel => 'system.traffic.bytespersecond', set => { + key_values => [ { name => 'traffic', diff => 1 } ], + output_change_bytes => 1, per_second => 1, + output_template => 'traffic %s %s/s', + perfdatas => [ + { label => 'traffic', value => 'traffic_per_second', template => '%s', + min => 0, unit => 'B/s', cast_int => 1 }, + ], + } + }, + ]; +} + +sub prefix_operation_output { + my ($self, %options) = @_; + + return 'Operation completed '; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + 'hostname:s' => { name => 'hostname' }, + 'search-base:s' => { name => 'search_base', default => 'cn=monitor' }, + 'ldap-connect-options:s@' => { name => 'ldap_connect_options' }, + 'ldap-starttls-options:s@' => { name => 'ldap_starttls_options' }, + 'ldap-bind-options:s@' => { name => 'ldap_bind_options' }, + 'tls' => { name => 'use_tls' }, + 'username:s' => { name => 'username' }, + 'password:s' => { name => 'password' }, + 'timeout:s' => { name => 'timeout', default => '30' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{hostname})) { + $self->{output}->add_option_msg(short_msg => 'Please set the hostname option'); + $self->{output}->option_exit(); + } + if (defined($self->{option_results}->{username}) && $self->{option_results}->{username} ne '' && + !defined($self->{option_results}->{password})) { + $self->{output}->add_option_msg(short_msg => "Please set --password option."); + $self->{output}->option_exit(); + } +} + +sub ldap_error { + my ($self, %options) = @_; + + if ($options{code} == 1) { + $self->{output}->output_add( + severity => 'unknown', + short_msg => $options{err_msg} + ); + $self->{output}->display(); + $self->{output}->exit(); + } +} + +sub search_monitor { + my ($self, %options) = @_; + + my ($ldap_handle, $code, $err_msg) = centreon::common::protocols::ldap::lib::ldap::connect( + hostname => $self->{option_results}->{hostname}, + username => $self->{option_results}->{username}, + password => $self->{option_results}->{password}, + timeout => $self->{option_results}->{timeout}, + ldap_connect_options => $self->{option_results}->{ldap_connect_options}, + use_tls => $self->{option_results}->{use_tls}, + ldap_starttls_options => $self->{option_results}->{ldap_starttls_options}, + ldap_bind_options => $self->{option_results}->{ldap_bind_options}, + ); + $self->ldap_error(code => $code, err_msg => $err_msg); + (my $search_result, $code, $err_msg) = centreon::common::protocols::ldap::lib::ldap::search( + ldap_handle => $ldap_handle, + search_base => $self->{option_results}->{search_base}, + search_filter => '(objectclass=*)', + ldap_search_options => ['attrs=monitoredInfo', 'attrs=monitorCounter', 'attrs=MonitorOpCompleted'], + ); + $self->ldap_error(code => $code, err_msg => $err_msg); + centreon::common::protocols::ldap::lib::ldap::quit(ldap_handle => $ldap_handle); + + return $search_result; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{operation} = {}; + $self->{global} = {}; + my $search_result = $self->search_monitor(); + foreach my $entry ($search_result->entries()) { + my $dn = $entry->dn(); + if ($dn =~ /cn=(Current|Total),cn=Connections/i) { + $self->{global}->{'connections_' . lc($1)} = $entry->get_value('monitorCounter'); + } elsif ($dn =~ /cn=(.*?),cn=Operations/i) { + $self->{operation}->{'operations_completed_' . lc($1)} = $entry->get_value('MonitorOpCompleted'); + } elsif ($dn =~ /cn=(Max|Active),cn=Threads/i) { + $self->{global}->{'threads_' . lc($1)} = $entry->get_value('monitoredInfo'); + } elsif ($dn =~ /cn=Bytes,cn=Statistics/i) { + $self->{global}->{traffic} = $entry->get_value('monitorCounter'); + } + } + + $self->{global}->{threads_active_prct} = $self->{global}->{threads_active} * 100 / $self->{global}->{threads_max}; + + $self->{cache_name} = "openldap_" . $self->{mode} . '_' . $self->{option_results}->{hostname} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check system usage (connections, threads, requests). + +=over 8 + +=item B<--hostname> + +IP Addr/FQDN of the openldap host (required). + +=item B<--search-base> + +Set the DN that is the base object entry relative to the backend monitor (Default: cn=monitor). + +=item B<--ldap-connect-options> + +Add custom ldap connect options: + +=over 16 + +=item B + +--ldap-connect-options='scheme=ldaps' + +=item B + +--ldap-connect-options='version=2' + +=back + +=item B<--ldap-starttls-options> + +Add custom start tls options (need --tls option): + +=over 16 + +=item B + +--ldap-starttls-options='verify=none' + +=back + +=item B<--ldap-bind-options> + +Add custom bind options (can force noauth) (not really useful now). + +=item B<--username> + +Specify username for authentification (can be a DN) + +=item B<--password> + +Specify password for authentification + +=item B<--timeout> + +Connection timeout in seconds (Default: 30) + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'con-current', 'con-total', 'threads-active', 'traffic', +'op-add', 'op-search', 'op-bind', 'op-unbind', 'op-delete'. + +=back + +=cut diff --git a/storage/hp/3par/7000/plugin.pm b/apps/openldap/ldap/plugin.pm similarity index 53% rename from storage/hp/3par/7000/plugin.pm rename to apps/openldap/ldap/plugin.pm index 67d62aa87..46cc4cd6f 100644 --- a/storage/hp/3par/7000/plugin.pm +++ b/apps/openldap/ldap/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package storage::hp::3par::7000::plugin; +package apps::openldap::ldap::plugin; use strict; use warnings; @@ -29,19 +29,10 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.0'; + $self->{version} = '0.1'; %{$self->{modes}} = ( - 'physicaldisk' => 'storage::hp::3par::7000::mode::physicaldisk', - 'psu' => 'storage::hp::3par::7000::mode::psu', - 'node' => 'storage::hp::3par::7000::mode::node', - 'battery' => 'storage::hp::3par::7000::mode::battery', - 'wsapi' => 'storage::hp::3par::7000::mode::wsapi', - 'cim' => 'storage::hp::3par::7000::mode::cim', - 'temperature' => 'storage::hp::3par::7000::mode::temperature', - 'storage' => 'storage::hp::3par::7000::mode::storage', - 'iscsi' => 'storage::hp::3par::7000::mode::iscsi', - 'volume' => 'storage::hp::3par::7000::mode::volume', - ); + 'system-usage' => 'apps::openldap::ldap::mode::systemusage', + ); return $self; } @@ -52,6 +43,6 @@ __END__ =head1 PLUGIN DESCRIPTION -Check HP 3par 7000 series in SSH. +Check OpenLDAP through the monitor backend. =cut diff --git a/apps/openweathermap/restapi/custom/api.pm b/apps/openweathermap/restapi/custom/api.pm new file mode 100644 index 000000000..d39b3342d --- /dev/null +++ b/apps/openweathermap/restapi/custom/api.pm @@ -0,0 +1,201 @@ +# +# Copyright 2019 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 apps::openweathermap::restapi::custom::api; + +use strict; +use warnings; +use centreon::plugins::http; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "url-path:s" => { name => 'url_path' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "api-token:s" => { name => 'api_token' }, + "timeout:s" => { name => 'timeout' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{http} = centreon::plugins::http->new(%options); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : 'api.openweathermap.org'; + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443; + $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; + $self->{url_path} = (defined($self->{option_results}->{url_path})) ? $self->{option_results}->{url_path} : '/data/2.5'; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; + $self->{api_token} = (defined($self->{option_results}->{api_token})) ? $self->{option_results}->{api_token} : ''; + + if (!defined($self->{api_token}) || $self->{api_token} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --api-token option."); + $self->{output}->option_exit(); + } + + return 0; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{url_path} = $self->{url_path}; + $self->{option_results}->{warning_status} = ''; + $self->{option_results}->{critical_status} = ''; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->add_header(key => 'Accept', value => 'application/json'); + + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub set_token { + my ($self, %options) = @_; + push @{$self->{get_param}}, 'APPID=' . $self->{api_token}; +} + +sub request_api { + my ($self, %options) = @_; + + $self->set_token(); + $self->settings; + + foreach my $get_param (@{$options{get_param}}) { + push @{$self->{get_param}}, $get_param; + } + my $content = $self->{http}->request( + url_path => $self->{url_path} . $options{url_path}, + get_param => \@{$self->{get_param}} + ); + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + if (!defined($decoded->{code}) || $decoded->{code} != 200) { + $self->{output}->output_add(long_msg => "Error message : " . $decoded->{errorDetails}, debug => 1); + $self->{output}->add_option_msg(short_msg => "API return error code '" . $decoded->{result} . "' (add --debug option for detailed message)"); + $self->{output}->option_exit(); + } + return $decoded; +} + +1; + +__END__ + +=head1 NAME + +OpenWeatherMap Rest API + +=head1 SYNOPSIS + +OpenWeatherMap Rest API custom mode + +=head1 REST API OPTIONS + +OpenWeatherMap Rest API + +=over 8 + +=item B<--hostname> + +OpenWeatherMap API hostname (Default: 'api.openweathermap.org') + +=item B<--port> + +API port (Default: 443) + +=item B<--proto> + +Specify https if needed (Default: 'https') + +=item B<--url-path> + +API URL path (Default: '/data/2.5') + +=item B<--timeout> + +Set HTTP timeout + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/apps/openweathermap/restapi/mode/cityweather.pm b/apps/openweathermap/restapi/mode/cityweather.pm new file mode 100644 index 000000000..6398f1118 --- /dev/null +++ b/apps/openweathermap/restapi/mode/cityweather.pm @@ -0,0 +1,189 @@ +# +# Copyright 2019 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 apps::openweathermap::restapi::mode::cityweather; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf("Weather: '%s'", $self->{result_values}->{weather}); +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{weather} = $options{new_datas}->{$self->{instance} . '_weather'}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'city', type => 0, cb_prefix_output => 'prefix_city_output' } + ]; + + $self->{maps_counters}->{city} = [ + { label => 'weather', set => { + key_values => [ { name => 'weather' } ], + 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 => \&catalog_status_threshold, + } + }, + { label => 'temperature', nlabel => 'temperature.celsius', set => { + key_values => [ { name => 'temperature' } ], + output_template => 'Temperature: %d C', + perfdatas => [ + { label => 'temperature', value => 'temperature_absolute', template => '%d', + unit => 'C' } + ], + } + }, + { label => 'humidity', nlabel => 'humidity.percentage', set => { + key_values => [ { name => 'humidity' } ], + output_template => 'Humidity: %.2f%%', + perfdatas => [ + { label => 'humidity', value => 'humidity_absolute', template => '%.1f', + min => 0, max => 100, unit => '%' } + ], + } + }, + { label => 'clouds', nlabel => 'clouds.percentage', set => { + key_values => [ { name => 'clouds' } ], + output_template => 'Clouds: %.2f%%', + perfdatas => [ + { label => 'clouds', value => 'clouds_absolute', template => '%.1f', + min => 0, max => 100, unit => '%' } + ], + } + }, + { label => 'wind', nlabel => 'wind.speed.meterspersecond', set => { + key_values => [ { name => 'wind' } ], + output_template => 'Wind: %.2f m/s', + perfdatas => [ + { label => 'wind', value => 'wind_absolute', template => '%.1f', + min => 0, unit => 'm/s' } + ], + } + } + ]; +} + +sub prefix_city_output { + my ($self, %options) = @_; + + return $self->{option_results}->{city_name} . " "; +} + +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 => { + "city-name:s" => { name => 'city_name' }, + "warning-weather:s" => { name => 'warning_weather', default => '' }, + "critical-weather:s" => { name => 'critical_weather', default => '' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_weather', 'critical_weather']); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->request_api( + url_path => "/weather?", + get_param => ["q=" . $self->{option_results}->{city_name}] + ); + + $self->{city} = { + wind => $results->{wind}->{speed}, + humidity => $results->{main}->{humidity}, + temperature => $results->{main}->{temp} - 273.15, + clouds => $results->{clouds}->{all}, + weather => @{$results->{weather}->[0]}{main} + }; +} + +1; + +__END__ + +=head1 MODE + +Check city weather + +=over 8 + +=item B<--city-name> + +City name (e.g London or ISO 3166 code like London,uk) + +=item B<--warning-weather> + +Set warning threshold for weather string desc (Default: ''). +Can used special variables like: %{weather} + +=item B<--critical-weather> + +Set critical threshold for weather string desc (Default: ''). +Can used special variables like: %{weather} +Example : + --critical-weather='%{weather} eq "Clouds' + +=item B<--warning-*> + +Set warning threshold for each metric gathered +Can be : + - temperature (Celsius) + - humidity (%) + - clouds (% coverage) + - wind (speed m/s) + +=item B<--critical-*> + +Set critical threshold for each metric gathered +Can be : + - temperature (Celsius) + - humidity (%) + - clouds (% coverage) + - wind (speed m/s) + +=back + +=cut diff --git a/apps/openweathermap/restapi/plugin.pm b/apps/openweathermap/restapi/plugin.pm new file mode 100644 index 000000000..ee325863f --- /dev/null +++ b/apps/openweathermap/restapi/plugin.pm @@ -0,0 +1,55 @@ +# +# Copyright 2019 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 apps::openweathermap::restapi::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'city-weather' => 'apps::openweathermap::restapi::mode::cityweather', + ); + + $self->{custom_modes}{api} = 'apps::openweathermap::restapi::custom::api'; + return $self; +} + +sub init { + my ( $self, %options ) = @_; + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Openweathermap data + +=cut diff --git a/apps/php/apc/web/mode/filecache.pm b/apps/php/apc/web/mode/filecache.pm index 576ae11d0..015881d0a 100644 --- a/apps/php/apc/web/mode/filecache.pm +++ b/apps/php/apc/web/mode/filecache.pm @@ -200,22 +200,19 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/apc.php" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/apc.php" }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout', default => 30 }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -262,10 +259,6 @@ IP Addr/FQDN of the webserver host Port used by web server -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Specify https if needed @@ -298,10 +291,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout (Default: 30) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning-*> Threshold warning. diff --git a/apps/php/apc/web/mode/memory.pm b/apps/php/apc/web/mode/memory.pm index 492002161..dd262bf88 100644 --- a/apps/php/apc/web/mode/memory.pm +++ b/apps/php/apc/web/mode/memory.pm @@ -96,22 +96,19 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/apc.php" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/apc.php" }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout', default => 30 }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -159,10 +156,6 @@ IP Addr/FQDN of the webserver host Port used by web server -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Specify https if needed @@ -195,10 +188,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout (Default: 30) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning-*> Threshold warning. diff --git a/apps/php/fpm/web/mode/usage.pm b/apps/php/fpm/web/mode/usage.pm index 4014e48e3..93bccd9fc 100644 --- a/apps/php/fpm/web/mode/usage.pm +++ b/apps/php/fpm/web/mode/usage.pm @@ -140,21 +140,19 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/fpm-status" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout', default => 5 }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/fpm-status" }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout', default => 5 }, + }); + + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -202,10 +200,6 @@ IP Addr/FQDN of the webserver host Port used by web server -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Specify https if needed @@ -238,10 +232,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout (Default: 5) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning-*> Threshold warning. diff --git a/apps/protocols/http/mode/expectedcontent.pm b/apps/protocols/http/mode/expectedcontent.pm index ee6e6d1e8..91a0f7431 100644 --- a/apps/protocols/http/mode/expectedcontent.pm +++ b/apps/protocols/http/mode/expectedcontent.pm @@ -20,12 +20,87 @@ package apps::protocols::http::mode::expectedcontent; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; use centreon::plugins::http; use Time::HiRes qw(gettimeofday tv_interval); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_content_threshold { + my ($self, %options) = @_; + + $self->{instance_mode}->{content_status} = catalog_status_threshold($self, %options); + return $self->{instance_mode}->{content_status}; +} + + +sub custom_content_output { + my ($self, %options) = @_; + + my $msg = 'HTTP test(s)'; + if (!$self->{output}->is_status(value => $self->{instance_mode}->{content_status}, compare => 'ok', litteral => 1)) { + my $filter = $self->{instance_mode}->{option_results}->{lc($self->{instance_mode}->{content_status}) . '_content'}; + $filter =~ s/\$self->\{result_values\}->/%/g; + $msg = sprintf("Content test [filter: '%s']", $filter); + } + + return $msg; +} + +sub custom_content_calc { + my ($self, %options) = @_; + + $self->{result_values}->{content} = $options{new_datas}->{$self->{instance} . '_content'}; + $self->{result_values}->{code} = $options{new_datas}->{$self->{instance} . '_code'}; + $self->{result_values}->{header} = $options{new_datas}->{$self->{instance} . '_header'}; + $self->{result_values}->{first_header} = $options{new_datas}->{$self->{instance} . '_first_header'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'content', threshold => 0, set => { + key_values => [ { name => 'content' }, { name => 'code' }, { name => 'first_header' }, { name => 'header' } ], + closure_custom_output => $self->can('custom_content_output'), + closure_custom_calc => $self->can('custom_content_calc'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_content_threshold'), + } + }, + { label => 'size', display_ok => 0, set => { + key_values => [ { name => 'size' } ], + output_template => 'Content size : %s', + perfdatas => [ + { label => 'size', value => 'size_absolute', template => '%s', min => 0, unit => 'B' }, + ], + } + }, + { label => 'time', display_ok => 0, set => { + key_values => [ { name => 'time' } ], + output_template => 'Response time : %.3fs', + perfdatas => [ + { label => 'time', value => 'time_absolute', template => '%.3f', min => 0, unit => 's' }, + ], + } + }, + { label => 'extracted', display_ok => 0, set => { + key_values => [ { name => 'extracted' } ], + output_template => 'Extracted value : %s', + perfdatas => [ + { label => 'value', value => 'extracted_absolute', template => '%s' }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; @@ -33,124 +108,87 @@ sub new { bless $self, $class; $self->{version} = '1.2'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "http-peer-addr:s" => { name => 'http_peer_addr' }, - "port:s" => { name => 'port', }, - "method:s" => { name => 'method' }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "ntlm" => { name => 'ntlm' }, # Deprecated - "ntlmv2" => { name => 'ntlmv2' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "proxypac:s" => { name => 'proxypac' }, - "expected-string:s" => { name => 'expected_string' }, - "timeout:s" => { name => 'timeout' }, - "no-follow" => { name => 'no_follow', }, - "ssl:s" => { name => 'ssl', }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "cert-file:s" => { name => 'cert_file' }, - "key-file:s" => { name => 'key_file' }, - "cacert-file:s" => { name => 'cacert_file' }, - "cert-pwd:s" => { name => 'cert_pwd' }, - "cert-pkcs12" => { name => 'cert_pkcs12' }, - "header:s@" => { name => 'header' }, - "get-param:s@" => { name => 'get_param' }, - "post-param:s@" => { name => 'post_param' }, - "cookies-file:s" => { name => 'cookies_file' }, - "unknown-status:s" => { name => 'unknown_status' }, - "warning-status:s" => { name => 'warning_status' }, - "critical-status:s" => { name => 'critical_status' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "warning-size:s" => { name => 'warning_size' }, - "critical-size:s" => { name => 'critical_size' }, - }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "method:s" => { name => 'method' }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "ntlmv2" => { name => 'ntlmv2' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "expected-string:s" => { name => 'expected_string' }, + "extracted-pattern:s" => { name => 'extracted_pattern' }, + "timeout:s" => { name => 'timeout' }, + "no-follow" => { name => 'no_follow', }, + "cert-file:s" => { name => 'cert_file' }, + "key-file:s" => { name => 'key_file' }, + "cacert-file:s" => { name => 'cacert_file' }, + "cert-pwd:s" => { name => 'cert_pwd' }, + "cert-pkcs12" => { name => 'cert_pkcs12' }, + "header:s@" => { name => 'header' }, + "get-param:s@" => { name => 'get_param' }, + "post-param:s@" => { name => 'post_param' }, + "cookies-file:s" => { name => 'cookies_file' }, + "unknown-status:s" => { name => 'unknown_status' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status' }, + "unknown-content:s" => { name => 'unknown_content', default => '' }, + "warning-content:s" => { name => 'warning_content', default => '' }, + "critical-content:s" => { name => 'critical_content', default => '' }, + }); + + $self->{http} = centreon::plugins::http->new(%options); return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->SUPER::check_options(%options); - if (!defined($self->{option_results}->{expected_string})) { - $self->{output}->add_option_msg(short_msg => "You need to specify --expected-string option."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'warning-size', value => $self->{option_results}->{warning_size})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning-size threshold '" . $self->{option_results}->{warning_size} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical-size', value => $self->{option_results}->{critical_size})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical-size threshold '" . $self->{option_results}->{critical_size} . "'."); - $self->{output}->option_exit(); + # Legacy compat + if (defined($self->{option_results}->{expected_string}) && $self->{option_results}->{expected_string} ne '') { + $self->{option_results}->{critical_content} = "%{content} !~ /$self->{option_results}->{expected_string}/mi"; } + $self->{http}->set_options(%{$self->{option_results}}); + $self->change_macros(macros => ['warning_content', 'critical_content', 'unknown_content']); } -sub run { +sub manage_selection { my ($self, %options) = @_; my $timing0 = [gettimeofday]; my $webcontent = $self->{http}->request(); my $timeelapsed = tv_interval($timing0, [gettimeofday]); - + + $self->{global} = { + time => $timeelapsed, + content => $webcontent, + code => $self->{http}->get_code(), + header => $self->{http}->get_header(), + first_header => $self->{http}->get_first_header(), + }; + + if (defined($self->{option_results}->{extracted_pattern}) && $self->{option_results}->{extracted_pattern} ne '' && + $webcontent =~ /$self->{option_results}->{extracted_pattern}/mi) { + my $extracted = $1; + if (defined($extracted) && $extracted =~ /(\d+([\.,]\d+)?)/) { + $extracted =~ s/,/\./; + $self->{global}->{extracted} = $extracted, + } + } + $self->{output}->output_add(long_msg => $webcontent); - if ($webcontent =~ /$self->{option_results}->{expected_string}/mi) { - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("'%s' is present in content.", $self->{option_results}->{expected_string})); - } else { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("'%s' is not present in content.", $self->{option_results}->{expected_string})); - } - - # Time check - my $exit = $self->{perfdata}->threshold_check(value => $timeelapsed, - threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Response time : %.3fs", $timeelapsed)); - } - $self->{output}->perfdata_add(label => "time", unit => 's', - value => sprintf('%.3f', $timeelapsed), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); # Size check { require bytes; - my $content_size = bytes::length($webcontent); - $exit = $self->{perfdata}->threshold_check(value => $content_size, - threshold => [ { label => 'critical-size', exit_litteral => 'critical' }, { label => 'warning-size', exit_litteral => 'warning' } ]); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Content size : %s", $content_size)); - } - $self->{output}->perfdata_add(label => "size", unit => 'B', - value => $content_size, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-size'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-size'), - min => 0); + $self->{global}->{size} = bytes::length($webcontent); } - - $self->{output}->display(); - $self->{output}->exit(); } 1; @@ -167,22 +205,10 @@ Check Webpage content IP Addr/FQDN of the Webserver host -=item B<--http-peer-addr> - -Set the address you want to connect (Useful if hostname is only a vhost. no ip resolve) - =item B<--port> Port used by Webserver -=item B<--proxyurl> - -Proxy URL - -=item B<--proxypac> - -Proxy pac file (can be an url or local file) - =item B<--method> Specify http method used (Default: 'GET') @@ -227,10 +253,6 @@ Threshold for HTTP timeout (Default: 5) Do not follow http redirect -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--cert-file> Specify certificate to send to the webserver @@ -267,6 +289,10 @@ Set POST params (Multiple option. Example: --post-param='key=value') Save cookies in a file (Example: '/tmp/lwp_cookies.dat') +=item B<--extracted-pattern> + +Set pattern to extracted a number (used --warning-extracted and --critical-extracted option). + =item B<--unknown-status> Threshold warning for http response code (Default: '%{http_code} < 200 or %{http_code} >= 300') @@ -279,11 +305,11 @@ Threshold warning for http response code Threshold critical for http response code -=item B<--warning> +=item B<--warning-time> Threshold warning in seconds (Webpage response time) -=item B<--critical> +=item B<--critical-time> Threshold critical in seconds (Webpage response time) @@ -295,9 +321,28 @@ Threshold warning for content size Threshold critical for content size -=item B<--expected-string> +=item B<--warning-extracted> -Specify String to check on the Webpage +Threshold warning for extracted value + +=item B<--critical-extracted> + +Threshold critical for extracted value + +=item B<--unknown-content> + +Set warning threshold for content page (Default: ''). +Can used special variables like: %{content}, %{header}, %{first_header}, %{code} + +=item B<--warning-content> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{content}, %{header}, %{first_header}, %{code} + +=item B<--critical-content> + +Set critical threshold for content page (Default: ''). +Can used special variables like: %{content}, %{header}, %{first_header}, %{code} =back diff --git a/apps/protocols/http/mode/jsoncontent.pm b/apps/protocols/http/mode/jsoncontent.pm index 4d3dc09f6..4322b69ec 100644 --- a/apps/protocols/http/mode/jsoncontent.pm +++ b/apps/protocols/http/mode/jsoncontent.pm @@ -35,51 +35,47 @@ sub new { bless $self, $class; $self->{version} = '1.2'; - $options{options}->add_options(arguments => - { - "data:s" => { name => 'data' }, - "lookup:s@" => { name => 'lookup' }, - "hostname:s" => { name => 'hostname' }, - "http-peer-addr:s" => { name => 'http_peer_addr' }, - "vhost:s" => { name => 'vhost' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "ntlm" => { name => 'ntlm' }, # Deprecated - "ntlmv2" => { name => 'ntlmv2' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "proxypac:s" => { name => 'proxypac' }, - "header:s@" => { name => 'header' }, - "get-param:s@" => { name => 'get_param' }, - "timeout:s" => { name => 'timeout', default => 10 }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "ssl:s" => { name => 'ssl', }, - "cert-file:s" => { name => 'cert_file' }, - "key-file:s" => { name => 'key_file' }, - "cacert-file:s" => { name => 'cacert_file' }, - "cert-pwd:s" => { name => 'cert_pwd' }, - "cert-pkcs12" => { name => 'cert_pkcs12' }, - "unknown-status:s" => { name => 'unknown_status' }, - "warning-status:s" => { name => 'warning_status' }, - "critical-status:s" => { name => 'critical_status' }, - "warning-numeric:s" => { name => 'warning_numeric' }, - "critical-numeric:s" => { name => 'critical_numeric' }, - "warning-string:s" => { name => 'warning_string' }, - "critical-string:s" => { name => 'critical_string' }, - "unknown-string:s" => { name => 'unknown_string' }, - "warning-time:s" => { name => 'warning_time' }, - "critical-time:s" => { name => 'critical_time' }, - "threshold-value:s" => { name => 'threshold_value', default => 'count' }, - "format-ok:s" => { name => 'format_ok', default => '%{count} element(s) found' }, - "format-warning:s" => { name => 'format_warning', default => '%{count} element(s) found' }, - "format-critical:s" => { name => 'format_critical', default => '%{count} element(s) found' }, - "format-unknown:s" => { name => 'format_unknown', default => '%{count} element(s) found' }, - "values-separator:s" => { name => 'values_separator', default => ', ' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "vhost:s" => { name => 'vhost' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "ntlmv2" => { name => 'ntlmv2' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "header:s@" => { name => 'header' }, + "get-param:s@" => { name => 'get_param' }, + "timeout:s" => { name => 'timeout', default => 10 }, + "cert-file:s" => { name => 'cert_file' }, + "key-file:s" => { name => 'key_file' }, + "cacert-file:s" => { name => 'cacert_file' }, + "cert-pwd:s" => { name => 'cert_pwd' }, + "cert-pkcs12" => { name => 'cert_pkcs12' }, + "unknown-status:s" => { name => 'unknown_status' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status' }, + "warning-numeric:s" => { name => 'warning_numeric' }, + "critical-numeric:s" => { name => 'critical_numeric' }, + "warning-string:s" => { name => 'warning_string' }, + "critical-string:s" => { name => 'critical_string' }, + "unknown-string:s" => { name => 'unknown_string' }, + "warning-time:s" => { name => 'warning_time' }, + "critical-time:s" => { name => 'critical_time' }, + "threshold-value:s" => { name => 'threshold_value', default => 'count' }, + "format-ok:s" => { name => 'format_ok', default => '%{count} element(s) found' }, + "format-warning:s" => { name => 'format_warning', default => '%{count} element(s) found' }, + "format-critical:s" => { name => 'format_critical', default => '%{count} element(s) found' }, + "format-unknown:s" => { name => 'format_unknown', default => '%{count} element(s) found' }, + "format-lookup:s" => { name => 'format_lookup'}, + "values-separator:s" => { name => 'values_separator', default => ', ' }, + "lookup-perfdatas-nagios:s" => { name => 'lookup_perfdatas_nagios'}, + "data:s" => { name => 'data' }, + "lookup:s@" => { name => 'lookup' }, + }); + $self->{count} = 0; $self->{count_ok} = 0; $self->{count_warning} = 0; @@ -92,7 +88,7 @@ sub new { $self->{values_string_warning} = []; $self->{values_string_critical} = []; $self->{values_string_unknown} = []; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -154,7 +150,12 @@ sub display_output { foreach my $severity (('ok', 'warning', 'critical', 'unknown')) { next if (scalar(@{$self->{'values_' . $severity}}) == 0 && scalar(@{$self->{'values_string_' . $severity}}) == 0); - my $format = $self->{option_results}->{'format_' . $severity}; + my $format = ''; + if(defined($self->{option_results}->{format_lookup}) && $self->{option_results}->{format_lookup} ne '') { + $format = $self->{format_from_json}; + } else { + $format = $self->{option_results}->{'format_' . $severity}; + } while ($format =~ /%\{(.*?)\}/g) { my $replace = ''; if (ref($self->{$1}) eq 'ARRAY') { @@ -169,24 +170,29 @@ sub display_output { } } -sub lookup { +sub decode_json_response { my ($self, %options) = @_; - my ($xpath, @values); - + + return if (defined($self->{json_response_decoded})); my $json = JSON->new; - my $content; eval { - $content = $json->decode($self->{json_response}); + $self->{json_response_decoded} = $json->decode($self->{json_response}); }; if ($@) { $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); $self->{output}->option_exit(); } +} +sub lookup { + my ($self, %options) = @_; + my ($xpath, @values); + + $self->decode_json_response(); foreach my $xpath_find (@{$self->{option_results}->{lookup}}) { eval { my $jpath = JSON::Path->new($xpath_find); - @values = $jpath->values($content); + @values = $jpath->values($self->{json_response_decoded}); }; if ($@) { $self->{output}->add_option_msg(short_msg => "Cannot lookup: $@"); @@ -244,10 +250,60 @@ sub lookup { } } } + + if (defined($self->{option_results}->{format_lookup}) && $self->{option_results}->{format_lookup} ne '') { + my $xpath_find = $self->{option_results}->{format_lookup}; + eval { + my $jpath = JSON::Path->new($xpath_find); + $self->{format_from_json} = $jpath->value($self->{json_response_decoded}); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot lookup output message: $@"); + $self->{output}->option_exit(); + } + + $self->{output}->output_add(long_msg => "Lookup perfdatas XPath $xpath_find:"); + } $self->display_output(); } +sub lookup_perfdata_nagios { + my ($self, %options) = @_; + + return if (!defined($self->{option_results}->{lookup_perfdatas_nagios}) || $self->{option_results}->{lookup_perfdatas_nagios} eq ''); + + $self->decode_json_response(); + + my $perfdata_string; + my $xpath_find = $self->{option_results}->{lookup_perfdatas_nagios}; + eval { + my $jpath = JSON::Path->new($xpath_find); + $perfdata_string = $jpath->value($self->{json_response_decoded}); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot lookup perfdatas: $@"); + $self->{output}->option_exit(); + } + + $self->{output}->output_add(long_msg => "Lookup perfdatas XPath $xpath_find:"); + + my @metrics = split(/ /, $perfdata_string); + foreach my $single_metric (@metrics) { + my ($label, $perfdatas) = split(/=/, $single_metric); + my ($value_w_unit, $warn, $crit, $min, $max) = split(/;/, $perfdatas); + # separate the value from the unit + my ($value, $unit) = $value_w_unit =~ /(^[0-9]+\.*\,*[0-9]*)(.*)/g; + + $self->{output}->perfdata_add(label => $label, unit => $unit, + value => $value, + warning => $warn, + critical => $crit, + min => $min, + max => $max); + } +} + sub run { my ($self, %options) = @_; @@ -279,6 +335,8 @@ sub run { critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-time'), min => 0); + $self->lookup_perfdata_nagios(); + $self->{output}->display(); $self->{output}->exit(); } @@ -306,12 +364,23 @@ Set file with JSON request What to lookup in JSON response (JSON XPath string) (can be multiple) See: http://goessner.net/articles/JsonPath/ +=item B<--lookup-perfdatas-nagios> + +Take perfdatas from the JSON response (JSON XPath string) +Chain must be formated in Nagios format. +Ex : "rta=10.752ms;50.000;100.000;0; pl=0%;20;40;; rtmax=10.802ms;;;;" + =back FORMAT OPTIONS: =over 8 +=item B<--format-lookup> + +Take the output message from the JSON response (JSON XPath string) +Override all the format options but substitute are still applied. + =item B<--format-ok> Output format (Default: '%{count} element(s) found') @@ -385,22 +454,10 @@ HTTP OPTIONS: IP Addr/FQDN of the Webserver host -=item B<--http-peer-addr> - -Set the address you want to connect (Useful if hostname is only a vhost. no ip resolve) - =item B<--port> Port used by Webserver -=item B<--proxyurl> - -Proxy URL - -=item B<--proxypac> - -Proxy pac file (can be an url or local file) - =item B<--proto> Specify https if needed @@ -437,10 +494,6 @@ Specify this option if you access webpage over ntlmv2 authentication (Use with - Threshold for HTTP timeout (Default: 10) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--cert-file> Specify certificate to send to the webserver diff --git a/apps/protocols/http/mode/response.pm b/apps/protocols/http/mode/response.pm index f1a26ae1b..8d7b8fb03 100644 --- a/apps/protocols/http/mode/response.pm +++ b/apps/protocols/http/mode/response.pm @@ -33,45 +33,38 @@ sub new { bless $self, $class; $self->{version} = '1.1'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "http-peer-addr:s" => { name => 'http_peer_addr' }, - "port:s" => { name => 'port', }, - "method:s" => { name => 'method' }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "ntlm" => { name => 'ntlm' }, # Deprecated - "ntlmv2" => { name => 'ntlmv2' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "proxypac:s" => { name => 'proxypac' }, - "timeout:s" => { name => 'timeout' }, - "no-follow" => { name => 'no_follow', }, - "ssl:s" => { name => 'ssl' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "cert-file:s" => { name => 'cert_file' }, - "key-file:s" => { name => 'key_file' }, - "cacert-file:s" => { name => 'cacert_file' }, - "cert-pwd:s" => { name => 'cert_pwd' }, - "cert-pkcs12" => { name => 'cert_pkcs12' }, - "header:s@" => { name => 'header' }, - "get-param:s@" => { name => 'get_param' }, - "post-param:s@" => { name => 'post_param' }, - "cookies-file:s" => { name => 'cookies_file' }, - "unknown-status:s" => { name => 'unknown_status', default => '' }, - "warning-status:s" => { name => 'warning_status' }, - "critical-status:s" => { name => 'critical_status', default => '%{http_code} < 200 or %{http_code} >= 300' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "warning-size:s" => { name => 'warning_size' }, - "critical-size:s" => { name => 'critical_size' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "method:s" => { name => 'method' }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "ntlmv2" => { name => 'ntlmv2' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + "no-follow" => { name => 'no_follow', }, + "cert-file:s" => { name => 'cert_file' }, + "key-file:s" => { name => 'key_file' }, + "cacert-file:s" => { name => 'cacert_file' }, + "cert-pwd:s" => { name => 'cert_pwd' }, + "cert-pkcs12" => { name => 'cert_pkcs12' }, + "header:s@" => { name => 'header' }, + "get-param:s@" => { name => 'get_param' }, + "post-param:s@" => { name => 'post_param' }, + "cookies-file:s" => { name => 'cookies_file' }, + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status', default => '%{http_code} < 200 or %{http_code} >= 300' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "warning-size:s" => { name => 'warning_size' }, + "critical-size:s" => { name => 'critical_size' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -153,10 +146,6 @@ Check Webpage response and size. IP Addr/FQDN of the webserver host -=item B<--http-peer-addr> - -Set the address you want to connect (Useful if hostname is only a vhost. no ip resolve) - =item B<--port> Port used by Webserver @@ -197,14 +186,6 @@ Specify this option if you access webpage over hidden basic authentication or yo Specify this option if you access webpage over ntlmv2 authentication (Use with --credentials and --port options) -=item B<--proxyurl> - -Proxy URL - -=item B<--proxypac> - -Proxy pac file (can be an url or local file) - =item B<--timeout> Threshold for HTTP timeout (Default: 5) @@ -213,10 +194,6 @@ Threshold for HTTP timeout (Default: 5) Do not follow http redirect -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--cert-file> Specify certificate to send to the webserver diff --git a/apps/protocols/http/mode/soapcontent.pm b/apps/protocols/http/mode/soapcontent.pm index 43dc8cb8e..0faf14460 100644 --- a/apps/protocols/http/mode/soapcontent.pm +++ b/apps/protocols/http/mode/soapcontent.pm @@ -34,49 +34,42 @@ sub new { bless $self, $class; $self->{version} = '1.2'; - $options{options}->add_options(arguments => - { - "service-soap:s" => { name => 'service_soap' }, - "data:s" => { name => 'data' }, - "lookup:s@" => { name => 'lookup' }, - "hostname:s" => { name => 'hostname' }, - "http-peer-addr:s" => { name => 'http_peer_addr' }, - "vhost:s" => { name => 'vhost' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "ntlm" => { name => 'ntlm' }, # Deprecated - "ntlmv2" => { name => 'ntlmv2' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "proxypac:s" => { name => 'proxypac' }, - "header:s@" => { name => 'header' }, - "timeout:s" => { name => 'timeout', default => 10 }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "ssl:s" => { name => 'ssl', }, - "cert-file:s" => { name => 'cert_file' }, - "key-file:s" => { name => 'key_file' }, - "cacert-file:s" => { name => 'cacert_file' }, - "cert-pwd:s" => { name => 'cert_pwd' }, - "cert-pkcs12" => { name => 'cert_pkcs12' }, - "unknown-status:s" => { name => 'unknown_status' }, - "warning-status:s" => { name => 'warning_status' }, - "critical-status:s" => { name => 'critical_status' }, - "warning-numeric:s" => { name => 'warning_numeric' }, - "critical-numeric:s" => { name => 'critical_numeric' }, - "warning-string:s" => { name => 'warning_string' }, - "critical-string:s" => { name => 'critical_string' }, - "warning-time:s" => { name => 'warning_time' }, - "critical-time:s" => { name => 'critical_time' }, - "threshold-value:s" => { name => 'threshold_value', default => 'count' }, - "format-ok:s" => { name => 'format_ok', default => '%{count} element(s) found' }, - "format-warning:s" => { name => 'format_warning', default => '%{count} element(s) found' }, - "format-critical:s" => { name => 'format_critical', default => '%{count} element(s) found' }, - "values-separator:s" => { name => 'values_separator', default => ', ' }, - }); + $options{options}->add_options(arguments => { + "service-soap:s" => { name => 'service_soap' }, + "data:s" => { name => 'data' }, + "lookup:s@" => { name => 'lookup' }, + "hostname:s" => { name => 'hostname' }, + "vhost:s" => { name => 'vhost' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "ntlmv2" => { name => 'ntlmv2' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "header:s@" => { name => 'header' }, + "timeout:s" => { name => 'timeout', default => 10 }, + "cert-file:s" => { name => 'cert_file' }, + "key-file:s" => { name => 'key_file' }, + "cacert-file:s" => { name => 'cacert_file' }, + "cert-pwd:s" => { name => 'cert_pwd' }, + "cert-pkcs12" => { name => 'cert_pkcs12' }, + "unknown-status:s" => { name => 'unknown_status' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status' }, + "warning-numeric:s" => { name => 'warning_numeric' }, + "critical-numeric:s" => { name => 'critical_numeric' }, + "warning-string:s" => { name => 'warning_string' }, + "critical-string:s" => { name => 'critical_string' }, + "warning-time:s" => { name => 'warning_time' }, + "critical-time:s" => { name => 'critical_time' }, + "threshold-value:s" => { name => 'threshold_value', default => 'count' }, + "format-ok:s" => { name => 'format_ok', default => '%{count} element(s) found' }, + "format-warning:s" => { name => 'format_warning', default => '%{count} element(s) found' }, + "format-critical:s" => { name => 'format_critical', default => '%{count} element(s) found' }, + "values-separator:s" => { name => 'values_separator', default => ', ' }, + }); $self->{count} = 0; $self->{count_ok} = 0; $self->{count_warning} = 0; @@ -87,7 +80,7 @@ sub new { $self->{values_string_ok} = []; $self->{values_string_warning} = []; $self->{values_string_critical} = []; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -165,8 +158,7 @@ sub check_encoding { my ($self, %options) = @_; my $charset; - my $headers = $self->{http}->get_header(); - my $content_type = $headers->header('Content-Type'); + my ($content_type) = $self->{http}->get_header(name => 'Content-Type'); if (defined($content_type) && $content_type =~ /charset\s*=\s*(\S+)/i) { $charset = $1; } @@ -394,22 +386,10 @@ HTTP OPTIONS: IP Addr/FQDN of the Webserver host -=item B<--http-peer-addr> - -Set the address you want to connect (Useful if hostname is only a vhost. no ip resolve) - =item B<--port> Port used by Webserver -=item B<--proxyurl> - -Proxy URL - -=item B<--proxypac> - -Proxy pac file (can be an url or local file) - =item B<--proto> Specify https if needed @@ -446,10 +426,6 @@ Specify this option if you access webpage over ntlmv2 authentication (Use with - Threshold for HTTP timeout (Default: 10) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--cert-file> Specify certificate to send to the webserver @@ -476,7 +452,7 @@ Set HTTP headers (Multiple option) =item B<--unknown-status> -Threshold warning for http response code (Default: '%{http_code} < 200 or %{http_code} >= 300') +Threshold unknown for http response code (Default: '%{http_code} < 200 or %{http_code} >= 300') =item B<--warning-status> diff --git a/apps/protocols/ldap/lib/ldap.pm b/apps/protocols/ldap/lib/ldap.pm deleted file mode 100644 index b68fb5c20..000000000 --- a/apps/protocols/ldap/lib/ldap.pm +++ /dev/null @@ -1,132 +0,0 @@ -# -# Copyright 2019 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 apps::protocols::ldap::lib::ldap; - -use strict; -use warnings; -use Net::LDAP; - -my $ldap_handle; -my $connected = 0; - -sub quit { - if ($connected == 1) { - $ldap_handle->unbind; - } -} - -sub search { - my ($self, %options) = @_; - my %ldap_search_options = (); - - $ldap_search_options{base} = $self->{option_results}->{search_base}; - $ldap_search_options{filter} = $self->{option_results}->{search_filter}; - my $attrs; - foreach my $option (@{$self->{option_results}->{ldap_search_options}}) { - next if ($option !~ /^(.+?)=(.+)$/); - if ($1 =~ /attrs/) { - $attrs = [] if (!defined($attrs)); - push @$attrs, $2; - } else { - $ldap_search_options{$1} = $2; - } - } - $ldap_search_options{attrs} = $attrs if (defined($attrs)); - my $search_result = $ldap_handle->search(%ldap_search_options); - if ($search_result->code) { - $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => 'Search operation error: ' . $search_result->error); - $self->{output}->display(); - $self->{output}->exit(); - } - - return $search_result; -} - -sub connect { - my ($self, %options) = @_; - my %ldap_connect_options = (); - my %ldap_bind_options = (); - - if (defined($self->{option_results}->{username}) && $self->{option_results}->{username} ne '' && - !defined($self->{option_results}->{password})) { - $self->{output}->add_option_msg(short_msg => "Please set --password option."); - $self->{output}->option_exit(); - } - - my $connection_exit = defined($options{connection_exit}) ? $options{connection_exit} : 'unknown'; - $ldap_connect_options{timeout} = $self->{option_results}->{timeout} if (defined($self->{option_results}->{timeout})); - foreach my $option (@{$self->{option_results}->{ldap_connect_options}}) { - next if ($option !~ /^(.+?)=(.+)$/); - $ldap_connect_options{$1} = $2; - } - - $ldap_handle = Net::LDAP->new($self->{option_results}->{hostname}, %ldap_connect_options); - - if (!defined($ldap_handle)) { - $self->{output}->output_add(severity => $connection_exit, - short_msg => 'Unable to connect to LDAP: ' . $@); - $self->{output}->display(); - $self->{output}->exit(); - } - - # TLS Process - if (defined($self->{option_results}->{use_tls})) { - my %ldap_starttls_options = (); - - foreach my $option (@{$self->{option_results}->{ldap_starttls_options}}) { - next if ($option !~ /^(.+?)=(.+)$/); - $ldap_starttls_options{$1} = $2; - } - - my $tls_result = $ldap_handle->start_tls(%ldap_starttls_options); - if ($tls_result->code) { - $self->{output}->output_add(severity => $connection_exit, - short_msg => 'Start TLS operation error: ' . $tls_result->error); - $self->{output}->display(); - $self->{output}->exit(); - } - } - - # Bind process - my $username; - if (defined($self->{option_results}->{username}) && $self->{option_results}->{username} ne '') { - $ldap_bind_options{password} = $self->{option_results}->{password}; - $username = $self->{option_results}->{username}; - } - - foreach my $option (@{$self->{option_results}->{ldap_bind_options}}) { - next if ($option !~ /^(.+?)=(.+)$/); - $ldap_bind_options{$1} = $2; - } - - my $bind_result = $ldap_handle->bind($username, %ldap_bind_options); - if ($bind_result->code) { - $self->{output}->output_add(severity => $connection_exit, - short_msg => 'Bind operation error: ' . $bind_result->error); - $self->{output}->display(); - $self->{output}->exit(); - } - - $connected = 1; -} - -1; diff --git a/apps/protocols/ldap/mode/login.pm b/apps/protocols/ldap/mode/login.pm index 2fb5ec758..74c7d3eff 100644 --- a/apps/protocols/ldap/mode/login.pm +++ b/apps/protocols/ldap/mode/login.pm @@ -25,7 +25,7 @@ use base qw(centreon::plugins::mode); use strict; use warnings; use Time::HiRes qw(gettimeofday tv_interval); -use apps::protocols::ldap::lib::ldap; +use centreon::common::protocols::ldap::lib::ldap; sub new { my ($class, %options) = @_; @@ -33,19 +33,19 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "ldap-connect-options:s@" => { name => 'ldap_connect_options' }, - "ldap-starttls-options:s@" => { name => 'ldap_starttls_options' }, - "ldap-bind-options:s@" => { name => 'ldap_bind_options' }, - "tls" => { name => 'use_tls' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "timeout:s" => { name => 'timeout', default => '30' }, - }); + $options{options}->add_options(arguments => { + 'hostname:s' => { name => 'hostname' }, + 'ldap-connect-options:s@' => { name => 'ldap_connect_options' }, + 'ldap-starttls-options:s@' => { name => 'ldap_starttls_options' }, + 'ldap-bind-options:s@' => { name => 'ldap_bind_options' }, + 'tls' => { name => 'use_tls' }, + 'username:s' => { name => 'username' }, + 'password:s' => { name => 'password' }, + 'warning:s' => { name => 'warning' }, + 'critical:s' => { name => 'critical' }, + 'timeout:s' => { name => 'timeout', default => '30' }, + }); + return $self; } @@ -63,7 +63,13 @@ sub check_options { } if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Please set the hostname option"); + $self->{output}->add_option_msg(short_msg => 'Please set the hostname option'); + $self->{output}->option_exit(); + } + + if (defined($self->{option_results}->{username}) && $self->{option_results}->{username} ne '' && + !defined($self->{option_results}->{password})) { + $self->{output}->add_option_msg(short_msg => "Please set --password option."); $self->{output}->option_exit(); } } @@ -73,16 +79,31 @@ sub run { my $timing0 = [gettimeofday]; - apps::protocols::ldap::lib::ldap::connect($self, connection_exit => 'critical'); - apps::protocols::ldap::lib::ldap::quit(); + my ($ldap_handle, $code, $err_msg) = centreon::common::protocols::ldap::lib::ldap::connect( + hostname => $self->{option_results}->{hostname}, + username => $self->{option_results}->{username}, + password => $self->{option_results}->{password}, + timeout => $self->{option_results}->{timeout}, + ldap_connect_options => $self->{option_results}->{ldap_connect_options}, + use_tls => $self->{option_results}->{use_tls}, + ldap_starttls_options => $self->{option_results}->{ldap_starttls_options}, + ldap_bind_options => $self->{option_results}->{ldap_bind_options}, + ); + if ($code == 1) { + $self->{output}->output_add(severity => 'critical', + short_msg => $err_msg); + $self->{output}->display(); + $self->{output}->exit(); + } + centreon::common::protocols::ldap::lib::ldap::quit(ldap_handle => $ldap_handle); my $timeelapsed = tv_interval ($timing0, [gettimeofday]); my $exit = $self->{perfdata}->threshold_check(value => $timeelapsed, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Response time %.3f second(s)", $timeelapsed)); - $self->{output}->perfdata_add(label => "time", unit => 's', + short_msg => sprintf('Response time %.3f second(s)', $timeelapsed)); + $self->{output}->perfdata_add(label => 'time', unit => 's', value => sprintf('%.3f', $timeelapsed), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical')); diff --git a/apps/protocols/ldap/mode/search.pm b/apps/protocols/ldap/mode/search.pm index 9eb2f6860..5a8bad0e1 100644 --- a/apps/protocols/ldap/mode/search.pm +++ b/apps/protocols/ldap/mode/search.pm @@ -20,12 +20,39 @@ package apps::protocols::ldap::mode::search; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; use Time::HiRes qw(gettimeofday tv_interval); -use apps::protocols::ldap::lib::ldap; +use centreon::common::protocols::ldap::lib::ldap; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'entries', nlabel => 'ldap.request.entries.count', set => { + key_values => [ { name => 'entries' } ], + output_template => 'Number of results returned: %s', + perfdatas => [ + { value => 'entries_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'time', display_ok => 0, nlabel => 'ldap.request.time.second', set => { + key_values => [ { name => 'time' } ], + output_template => 'Response time : %.3fs', + perfdatas => [ + { label => 'time', value => 'time_absolute', template => '%.3f', min => 0, unit => 's' }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; @@ -33,80 +60,117 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "search-base:s" => { name => 'search_base' }, - "search-filter:s" => { name => 'search_filter' }, - "ldap-connect-options:s@" => { name => 'ldap_connect_options' }, - "ldap-starttls-options:s@" => { name => 'ldap_starttls_options' }, - "ldap-bind-options:s@" => { name => 'ldap_bind_options' }, - "ldap-search-options:s@" => { name => 'ldap_search_options' }, - "tls" => { name => 'use_tls' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "timeout:s" => { name => 'timeout', default => '30' }, - }); + $options{options}->add_options(arguments => { + 'hostname:s' => { name => 'hostname' }, + 'search-base:s' => { name => 'search_base' }, + 'search-filter:s' => { name => 'search_filter' }, + 'ldap-connect-options:s@' => { name => 'ldap_connect_options' }, + 'ldap-starttls-options:s@' => { name => 'ldap_starttls_options' }, + 'ldap-bind-options:s@' => { name => 'ldap_bind_options' }, + 'ldap-search-options:s@' => { name => 'ldap_search_options' }, + 'tls' => { name => 'use_tls' }, + 'username:s' => { name => 'username' }, + 'password:s' => { name => 'password' }, + 'timeout:s' => { name => 'timeout', default => '30' }, + 'display-entry:s' => { name => 'display_entry' }, + }); + return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } + $self->SUPER::check_options(%options); if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Please set the hostname option"); + $self->{output}->add_option_msg(short_msg => 'Please set the hostname option'); + $self->{output}->option_exit(); + } + if (defined($self->{option_results}->{username}) && $self->{option_results}->{username} ne '' && + !defined($self->{option_results}->{password})) { + $self->{output}->add_option_msg(short_msg => "Please set --password option."); $self->{output}->option_exit(); } if (!defined($self->{option_results}->{search_base})) { - $self->{output}->add_option_msg(short_msg => "Please set the search-base option"); + $self->{output}->add_option_msg(short_msg => 'Please set the search-base option'); $self->{output}->option_exit(); } if (!defined($self->{option_results}->{search_filter})) { - $self->{output}->add_option_msg(short_msg => "Please set the search-filter option"); + $self->{output}->add_option_msg(short_msg => 'Please set the search-filter option'); $self->{output}->option_exit(); } + + $self->{option_results}->{ldap_search_options} = [] if (!defined($self->{option_results}->{ldap_search_options})); + + if (defined($self->{option_results}->{display_entry}) && $self->{option_results}->{display_entry} ne '') { + while ($self->{option_results}->{display_entry} =~ /%\{(.*?)\}/g) { + push @{$self->{option_results}->{ldap_search_options}}, 'attrs=' . $1; + } + } } -sub run { +sub ldap_error { + my ($self, %options) = @_; + + if ($options{code} == 1) { + $self->{output}->output_add( + severity => 'unknown', + short_msg => $options{err_msg} + ); + $self->{output}->display(); + $self->{output}->exit(); + } +} + +sub display_entries { + my ($self, %options) = @_; + + return if (!defined($self->{option_results}->{display_entry}) || $self->{option_results}->{display_entry} eq ''); + + foreach my $entry ($options{result}->entries()) { + my $display = $self->{option_results}->{display_entry}; + while ($display =~ /%\{(.*?)\}/g) { + my $attr = $1; + my $value = $entry->get_value($attr); + $value = '' if (!defined($value)); + $display =~ s/%\{$attr\}/$value/g; + } + + $self->{output}->output_add(long_msg => $display); + } +} + +sub manage_selection { my ($self, %options) = @_; my $timing0 = [gettimeofday]; - apps::protocols::ldap::lib::ldap::connect($self); - my $search_result = apps::protocols::ldap::lib::ldap::search($self); - apps::protocols::ldap::lib::ldap::quit(); + my ($ldap_handle, $code, $err_msg) = centreon::common::protocols::ldap::lib::ldap::connect( + hostname => $self->{option_results}->{hostname}, + username => $self->{option_results}->{username}, + password => $self->{option_results}->{password}, + timeout => $self->{option_results}->{timeout}, + ldap_connect_options => $self->{option_results}->{ldap_connect_options}, + use_tls => $self->{option_results}->{use_tls}, + ldap_starttls_options => $self->{option_results}->{ldap_starttls_options}, + ldap_bind_options => $self->{option_results}->{ldap_bind_options}, + ); + $self->ldap_error(code => $code, err_msg => $err_msg); + (my $search_result, $code, $err_msg) = centreon::common::protocols::ldap::lib::ldap::search( + ldap_handle => $ldap_handle, + search_base => $self->{option_results}->{search_base}, + search_filter => $self->{option_results}->{search_filter}, + ldap_search_options => $self->{option_results}->{ldap_search_options}, + ); + $self->ldap_error(code => $code, err_msg => $err_msg); + centreon::common::protocols::ldap::lib::ldap::quit(ldap_handle => $ldap_handle); - my $timeelapsed = tv_interval ($timing0, [gettimeofday]); - - my $num_entries = scalar($search_result->entries); - my $exit = $self->{perfdata}->threshold_check(value => $num_entries, - threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Number of results returned: %s", $num_entries)); - - $self->{output}->perfdata_add(label => "time", unit => 's', - value => sprintf('%.3f', $timeelapsed), - min => 0); - $self->{output}->perfdata_add(label => "entries", - value => $num_entries, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + $self->{global} = { + time => tv_interval($timing0, [gettimeofday]), + entries => scalar($search_result->entries) + }; - $self->{output}->display(); - $self->{output}->exit(); + $self->display_entries(result => $search_result); } 1; @@ -173,6 +237,10 @@ Add custom bind options (can force noauth) (not really useful now). Add custom search options (can change the scope for example). +=item B<--display-entry> + +Display ldap entries (with --verbose option) (Example: '%{cn} account locked') + =item B<--username> Specify username for authentification (can be a DN) @@ -185,11 +253,19 @@ Specify password for authentification Connection timeout in seconds (Default: 30) -=item B<--warning> +=item B<--warning-time> + +Threshold warning in seconds + +=item B<--critical-time> + +Threshold critical in seconds + +=item B<--warning-entries> Threshold warning (number of results) -=item B<--critical> +=item B<--critical-entries> Threshold critical (number of results) diff --git a/apps/protocols/nrpe/custom/nrpe.pm b/apps/protocols/nrpe/custom/nrpe.pm new file mode 100644 index 000000000..248a588e5 --- /dev/null +++ b/apps/protocols/nrpe/custom/nrpe.pm @@ -0,0 +1,141 @@ +# +# Copyright 2019 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 apps::protocols::nrpe::custom::nrpe; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::nrpe; + +my %errors_num = (0 => 'OK', 1 => 'WARNING', 2 => 'CRITICAL', 3 => 'UNKNOWN'); + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'CUSTOM MODE OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{nrpe} = centreon::plugins::nrpe->new(%options); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : ''; + + if (!defined($self->{hostname}) || $self->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --hostname option."); + $self->{output}->option_exit(); + } + + $self->{nrpe}->check_options(option_results => $self->{option_results}); + + return 0; +} + +sub format_result { + my ($self, %options) = @_; + + my %result = ( + code => ($options{content}->{result_code} =~ /^[0-3]$/) ? $errors_num{$options{content}->{result_code}} : $options{content}->{result_code}, + message => $options{content}->{buffer}, + perf => [] + ); + return \%result; +} + +sub request { + my ($self, %options) = @_; + + my ($content) = $self->{nrpe}->request(check => $options{command}, arg => $options{arg}); + + my $result = $self->format_result(content => $content); + + return $result; +} + +1; + +__END__ + +=head1 NAME + +NRPE protocol + +=head1 CUSTOM MODE OPTIONS + +NRPE protocol + +=over 8 + +=item B<--hostname> + +Remote hostname or IP address. + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/apps/protocols/nrpe/custom/nsclient.pm b/apps/protocols/nrpe/custom/nsclient.pm new file mode 100644 index 000000000..ff1ef4475 --- /dev/null +++ b/apps/protocols/nrpe/custom/nsclient.pm @@ -0,0 +1,341 @@ +# +# Copyright 2019 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 apps::protocols::nrpe::custom::nsclient; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::http; +use URI::Encode; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "legacy-password:s" => { name => 'legacy_password' }, + "timeout:s" => { name => 'timeout' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'CUSTOM MODE OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{http} = centreon::plugins::http->new(%options); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : ''; + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 8443; + $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; + $self->{username} = (defined($self->{option_results}->{username})) ? $self->{option_results}->{username} : undef; + $self->{password} = (defined($self->{option_results}->{password})) ? $self->{option_results}->{password} : undef; + $self->{legacy_password} = (defined($self->{option_results}->{legacy_password})) ? $self->{option_results}->{legacy_password} : undef; + $self->{credentials} = (defined($self->{option_results}->{credentials})) ? 1 : undef; + $self->{basic} = (defined($self->{option_results}->{basic})) ? 1 : undef; + + if (!defined($self->{hostname}) || $self->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --hostname option."); + $self->{output}->option_exit(); + } + return 0; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{warning_status} = ''; + $self->{option_results}->{critical_status} = ''; + $self->{option_results}->{unknown_status} = '%{http_code} < 200 or %{http_code} >= 300'; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + if (defined($self->{legacy_password}) && $self->{legacy_password} ne '') { + $self->{http}->add_header(key => 'password', value => $self->{legacy_password}); + } + $self->{http}->set_options(%{$self->{option_results}}); +} + +# Two kind of outputs. +# 1- +# { +# "header": { +# "source_id": "" +# }, +# "payload": [{ +# "command": "check_centreon_plugins", +# "lines": [{ +# "message": "OK: Reboot Pending : False | 'value1'=10;;;; 'value2'=10;;;;\r\nlong1\r\nlong2" +# }], +# "result": "OK" +# }] +# } +# 2- Can be also "int_value". +# { +# "header": { +# "source_id": "" +# }, +# "payload": [{ +# "command": "check_drivesize", +# "lines": [{ +# "message": "OK All 1 drive(s) are ok", +# "perf": [{ +# "alias": "C", +# "float_value": { +# "critical": 44.690621566027403, +# "maximum": 49.656246185302734, +# "minimum": 0.00000000000000000, +# "unit": "GB", +# "value": 21.684593200683594, +# "warning": 39.724996947683394 +# } +# }, +# { +# "alias": "C", +# "float_value": { +# "critical": 90.000000000000000, +# "maximum": 100.00000000000000, +# "minimum": 0.00000000000000000, +# "unit": "%", +# "value": 44.000000000000000, +# "warning": 80.000000000000000 +# } +# } +# ] +# }], +# "result": "OK" +# }] +# } + +sub output_perf { + my ($self, %options) = @_; + + my %result = ( + code => $options{result}, + message => $options{data}->{message} + ); + + foreach (@{$options{data}->{perf}}) { + my $perf = defined($_->{float_value}) ? $_->{float_value} : $_->{int_value}; + my $printf_format = '%d'; + $printf_format = '%.3f' if (defined($_->{float_value})); + + push @{$result{perf}}, { + label => $_->{alias}, + unit => $perf->{unit}, + value => sprintf($printf_format, $perf->{value}), + warning => defined($perf->{warning}) ? sprintf($printf_format, $perf->{warning}) : undef, + critical => defined($perf->{critical}) ? sprintf($printf_format, $perf->{critical}) : undef, + min => defined($perf->{minimum}) ? sprintf($printf_format, $perf->{minimum}) : undef, + max => defined($perf->{maximum}) ? sprintf($printf_format, $perf->{maximum}) : undef, + }; + } + return \%result; +} + +sub output_noperf { + my ($self, %options) = @_; + + my %result = ( + code => $options{result}, + message => $options{data}->{message}, + perf => [] + ); + return \%result; +} + +sub format_result { + my ($self, %options) = @_; + + my $decoded; + eval { + $decoded = decode_json($options{content}); + }; + if ($@) { + $self->{output}->output_add(long_msg => $options{content}, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + + my $entry = $decoded->{payload}->[0]; + $entry->{lines}->[0]->{message} =~ s/\r//msg; + if (defined($entry->{lines}->[0]->{perf})) { + return $self->output_perf(result => $entry->{result}, data => $entry->{lines}->[0]); + } else { + return $self->output_noperf(result => $entry->{result}, data => $entry->{lines}->[0]); + } +} + +sub request { + my ($self, %options) = @_; + + $self->settings(); + + my $uri = URI::Encode->new({encode_reserved => 1}); + my ($encoded_args, $append) = ('', ''); + if (defined($options{arg})) { + foreach (@{$options{arg}}) { + $encoded_args .= $append . $uri->encode($_); + $append = '&'; + } + } + + my ($content) = $self->{http}->request(url_path => '/query/' . $options{command} . '?' . $encoded_args); + if (!defined($content) || $content eq '') { + $self->{output}->add_option_msg(short_msg => "API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + $self->{output}->output_add(long_msg => "nsclient return = " . $content, debug => 1); + + my $result = $self->format_result(content => $content); + + return $result; +} + +1; + +__END__ + +=head1 NAME + +NSClient++ Rest API + +=head1 CUSTOM MODE OPTIONS + +NSClient++ Rest API + +=over 8 + +=item B<--hostname> + +Remote hostname or IP address. + +=item B<--port> + +Port used (Default: 8443) + +=item B<--proto> + +Specify https if needed (Default: 'https') + +=item B<--credentials> + +Specify this option if you access webpage with authentication + +=item B<--username> + +Specify username for authentication (Mandatory if --credentials is specified) + +=item B<--password> + +Specify password for authentication (Mandatory if --credentials is specified) + +=item B<--basic> + +Specify this option if you access webpage over basic authentication and don't want a '401 UNAUTHORIZED' error to be logged on your webserver. + +Specify this option if you access webpage over hidden basic authentication or you'll get a '404 NOT FOUND' error. + +(Use with --credentials) + +=item B<--legacy-password> + +Specify password for old authentication system. + +=item B<--timeout> + +Set timeout in seconds (Default: 10). + +=item B<--unknown-status> + +Threshold warning for http response code. +(Default: '%{http_code} < 200 or %{http_code} >= 300') + +=item B<--warning-status> + +Threshold warning for http response code. + +=item B<--critical-status> + +Threshold critical for http response code. + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/apps/protocols/nrpe/mode/query.pm b/apps/protocols/nrpe/mode/query.pm new file mode 100644 index 000000000..fa862d99d --- /dev/null +++ b/apps/protocols/nrpe/mode/query.pm @@ -0,0 +1,116 @@ +# +# Copyright 2019 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 apps::protocols::nrpe::mode::query; + +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 => { + "command:s" => { name => 'command' }, + "arg:s@" => { name => 'arg' }, + "sanitize-message:s" => { name => 'sanitize_message' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{command}) || $self->{option_results}->{command} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set --command option"); + $self->{output}->option_exit(); + } +} + +sub sanitize_message { + my ($self, %options) = @_; + + $self->{display_options}->{nolabel} = 1; + return $options{message} unless (defined($self->{option_results}->{sanitize_message})); + + my $message = $options{message}; + foreach my $code (('OK', 'WARNING', 'CRITICAL', 'UNKNOWN')) { + foreach my $separator (('-', ':')) { + if ($message =~ /^\w+\s*$code\s*$separator\s*(.*)$/) { + delete $self->{display_options}->{nolabel}; + return $1; + } + } + } + return $message; +} + +sub run { + my ($self, %options) = @_; + + my $result = $options{custom}->request( + command => $self->{option_results}->{command}, + arg => $self->{option_results}->{arg} + ); + + $self->{output}->output_add( + severity => $result->{code}, + short_msg => $self->sanitize_message(message => $result->{message}) + ); + + foreach (@{$result->{perf}}) { + $self->{output}->perfdata_add(%{$_}); + } + $self->{display_options}->{force_ignore_perfdata} = 1 if (scalar(@{$result->{perf}}) == 0); + + $self->{output}->display(%{$self->{display_options}}); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Trigger commands against NRPE/NSClient agent. + +=item B<--command> + +Set command. + +=item B<--arg> + +Set arguments (Multiple option. Example: --arg='arg1' --arg='arg2'). + +=item B<--sanitize-message> + +Sanitize message by removing heading code and +separator from returned message (ie "OK - "). + +=back + +=cut diff --git a/apps/protocols/nrpe/plugin.pm b/apps/protocols/nrpe/plugin.pm new file mode 100644 index 000000000..b1ce1cf05 --- /dev/null +++ b/apps/protocols/nrpe/plugin.pm @@ -0,0 +1,50 @@ + # +# Copyright 2019 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 apps::protocols::nrpe::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'query' => 'apps::protocols::nrpe::mode::query', + ); + + $self->{custom_modes}{nrpe} = 'apps::protocols::nrpe::custom::nrpe'; + $self->{custom_modes}{nsclient} = 'apps::protocols::nrpe::custom::nsclient'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Trigger commands against NRPE/NSClient agent. + +=cut diff --git a/apps/protocols/snmp/mode/responsetime.pm b/apps/protocols/snmp/mode/responsetime.pm new file mode 100644 index 000000000..95fad6ac8 --- /dev/null +++ b/apps/protocols/snmp/mode/responsetime.pm @@ -0,0 +1,179 @@ +# +# Copyright 2019 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 apps::protocols::snmp::mode::responsetime; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Time::HiRes qw(gettimeofday tv_interval); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_output' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'rta', set => { + key_values => [ { name => 'rta' } ], + output_template => 'rta %.3fms', + perfdatas => [ + { label => 'rta', value => 'rta_absolute', template => '%.3f', min => 0, unit => 'ms' }, + ], + } + }, + { label => 'rtmax', display_ok => 0, set => { + key_values => [ { name => 'rtmax' } ], + perfdatas => [ + { label => 'rtmax', value => 'rtmax_absolute', template => '%.3f', min => 0, unit => 'ms' }, + ], + } + }, + { label => 'rtmin', display_ok => 0, set => { + key_values => [ { name => 'rtmin' } ], + perfdatas => [ + { label => 'rtmin', value => 'rtmin_absolute', template => '%.3f', min => 0, unit => 'ms' }, + ], + } + }, + { label => 'pl', set => { + key_values => [ { name => 'pl' } ], + output_template => 'lost %s%%', + perfdatas => [ + { label => 'pl', value => 'pl_absolute', template => '%s', min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "SNMP Agent "; +} + +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 => { + "timeout:s" => { name => 'timeout' }, + "packets:s" => { name => 'packets' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->{option_timeout} = 5; + $self->{option_packets} = 5; + if (defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /(\d+)/) { + $self->{option_timeout} = $1; + } + if (defined($self->{option_results}->{packets}) && $self->{option_results}->{packets} =~ /(\d+)/) { + $self->{option_packets} = $1; + } + + $options{snmp}->set_snmp_connect_params(Timeout => $self->{option_timeout} * (10**6)); + $options{snmp}->set_snmp_connect_params(Retries => 0); + $options{snmp}->set_snmp_params(subsetleef => 1); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $sysDescr = ".1.3.6.1.2.1.1.1.0"; + my $total_time_elapsed = 0; + my $max_time_elapsed = 0; + my $min_time_elapsed = 0; + my $total_packet_lost = 0; + for (my $i = 0; $i < $self->{option_packets}; $i++) { + my $timing0 = [gettimeofday]; + my $return = $options{snmp}->get_leef(oids => [$sysDescr], nothing_quit => 0, dont_quit => 1); + my $timeelapsed = tv_interval($timing0, [gettimeofday]); + + if (!defined($return)) { + $total_packet_lost++; + } else { + $total_time_elapsed += $timeelapsed; + $max_time_elapsed = $timeelapsed if ($timeelapsed > $max_time_elapsed); + $min_time_elapsed = $timeelapsed if ($timeelapsed < $min_time_elapsed || $min_time_elapsed == 0); + } + } + + $self->{global} = { + rta => $total_time_elapsed * 1000 / $self->{option_packets}, + rtmax => $max_time_elapsed * 1000, + rtmin => $min_time_elapsed * 1000, + pl => int($total_packet_lost * 100 / $self->{option_packets}), + }; +} + +1; + +__END__ + +=head1 MODE + +Check SNMP agent response time. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example : --filter-counters='rta' + +=item B<--timeout> + +Set timeout in seconds (Default: 5). + +=item B<--packets> + +Number of packets to send (Default: 5). + +=item B<--warning-rta> + +Response time threshold warning in milliseconds + +=item B<--critical-rta> + +Response time threshold critical in milliseconds + +=item B<--warning-pl> + +Packets lost threshold warning in % + +=item B<--critical-pl> + +Packets lost threshold critical in % + +=back + +=cut diff --git a/apps/protocols/snmp/plugin.pm b/apps/protocols/snmp/plugin.pm index dd19db079..49b06dffc 100644 --- a/apps/protocols/snmp/plugin.pm +++ b/apps/protocols/snmp/plugin.pm @@ -33,6 +33,7 @@ sub new { %{$self->{modes}} = ( 'dynamic-command' => 'snmp_standard::mode::dynamiccommand', 'numeric-value' => 'snmp_standard::mode::numericvalue', + 'response-time' => 'apps::protocols::snmp::mode::responsetime', 'string-value' => 'snmp_standard::mode::stringvalue', 'uptime' => 'snmp_standard::mode::uptime', ); diff --git a/apps/protocols/telnet/mode/scenario.pm b/apps/protocols/telnet/mode/scenario.pm index 5df5ca056..966faa363 100644 --- a/apps/protocols/telnet/mode/scenario.pm +++ b/apps/protocols/telnet/mode/scenario.pm @@ -34,14 +34,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "scenario:s" => { name => 'scenario' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => 23 }, - }); + $options{options}->add_options(arguments => { + "scenario:s" => { name => 'scenario' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', default => 23 }, + }); return $self; } @@ -55,7 +54,7 @@ sub check_options { # {"cmd": "open", "options": { "Host": "10.0.0.1", "Port": "23", "Timeout": "30" } }, # {"cmd": "login", "options": { "Name": "admin", "Password": "pass", "Timeout": "5" } }, # {"cmd": "waitfor", "options": { "Match": "/string/", "Timeout": "5" } }, - # {"cmd": "put", "options": { "String": "/mystring/", "Timeout": "5" } }, + # {"cmd": "put", "options": { "String": "mystring", "Timeout": "5" } }, # {"cmd": "close" } #] if (!defined($self->{option_results}->{scenario})) { diff --git a/apps/protocols/tftp/mode/commands.pm b/apps/protocols/tftp/mode/commands.pm new file mode 100644 index 000000000..c2618a0d5 --- /dev/null +++ b/apps/protocols/tftp/mode/commands.pm @@ -0,0 +1,262 @@ +# +# Copyright 2019 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 apps::protocols::tftp::mode::commands; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use Net::TFTP; +use Time::HiRes qw(gettimeofday tv_interval); + +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} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'command', type => 1, cb_prefix_output => 'prefix_command_output', message_multiple => 'All commands are ok' } + ]; + + $self->{maps_counters}->{command} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { 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 => \&catalog_status_threshold + } + }, + { label => 'time', display_ok => 0, set => { + key_values => [ { name => 'timeelapsed' }, { name => 'display' } ], + output_template => 'response time %.3fs', + perfdatas => [ + { label => 'time', value => 'timeelapsed_absolute', template => '%.3f', + min => 0, unit => 's', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + + ]; +} + +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 => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', default => 69 }, + "timeout:s" => { name => 'timeout', default => 5 }, + "retries:s" => { name => 'retries', default => 5 }, + "block-size:s" => { name => 'block_size', default => 512 }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} ne "ok"' }, + "command:s@" => { name => 'command' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status']); + + if (!defined($self->{option_results}->{hostname}) || $self->{option_results}->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set the --hostname option"); + $self->{output}->option_exit(); + } + + $self->{option_results}->{command} = [] + if (!defined($self->{option_results}->{command})); +} + +sub prefix_command_output { + my ($self, %options) = @_; + + return "Command '" . $options{instance_value}->{display} . "' "; +} + +sub put_command { + my ($self, %options) = @_; + + my $status = 'ok'; + if (!$options{tftp}->put($options{localfile}, $options{remotefile})) { + $status = $options{tftp}->error; + } + + return $status; +} + +sub get_command { + my ($self, %options) = @_; + + my ($status, $stdout); + { + local *STDOUT; + open STDOUT, '>', \$stdout; + + if (!$options{tftp}->get($options{remotefile}, \*STDOUT)) { + $status = $options{tftp}->error; + } else { + $status = 'ok'; + } + } + + return $status; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $tftp = Net::TFTP->new( + $self->{option_results}->{hostname}, + Timeout => $self->{option_results}->{timeout}, + Retries => $self->{option_results}->{retries}, + Port => $self->{option_results}->{port}, + BlockSize => $self->{option_results}->{block_size}, + ); + + $self->{command} = {}; + my $i = 0; + foreach (@{$self->{option_results}->{command}}) { + my ($label, $command, $arg1, $arg2) = split /,/; + + if (!defined($command) || $command !~ /(put|get)/) { + $self->{output}->add_option_msg(short_msg => "Unknown command. Please use 'get' or 'put' command name"); + $self->{output}->option_exit(); + } + + $i++; + $command = $1; + $label = $i + if (!defined($label) || $label eq ''); + if (!defined($arg1) || $arg1 eq '') { + $self->{output}->add_option_msg(short_msg => "Unknown first argument. first argument is required."); + $self->{output}->option_exit(); + } + + if ($command eq 'put' && (!defined($arg2) || $arg2 eq '')) { + $self->{output}->add_option_msg(short_msg => "Unknown second argument. second argument is required for 'put' command."); + $self->{output}->option_exit(); + } + + my $status; + my $timing0 = [gettimeofday]; + if ($command eq 'put') { + $status = $self->put_command(tftp => $tftp, localfile => $arg1, remotefile => $arg2); + } else { + $status = $self->get_command(tftp => $tftp, remotefile => $arg1); + } + my $timeelapsed = tv_interval($timing0, [gettimeofday]); + + $self->{command}->{$i} = { + display => $label, + status => $status, + timeelapsed => $timeelapsed, + }; + } + + if (scalar(keys %{$self->{command}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No command found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check tftp commands. + +=over 8 + +=item B<--hostname> + +TFTP server name (required). + +=item B<--port> + +TFTP port (Default: 69). + +=item B<--timeout> + +TFTP timeout in seconds (Default: 5). + +=item B<--retries> + +TFTP number of retries (Default: 5). + +=item B<--block-size> + +TFTP size of blocks to use in the transfer (Default: 512). + +=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} ne "ok"'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-time> + +Threshold warning. + +=item B<--critical-time> + +Threshold critical. + +=item B<--command> + +TFP command. +Example: --command='labeldisplay,get,remotefile' --command='labeldisplay2,put,localfile,remotefile" + +=back + +=cut diff --git a/apps/protocols/tftp/plugin.pm b/apps/protocols/tftp/plugin.pm new file mode 100644 index 000000000..4a7f6dc28 --- /dev/null +++ b/apps/protocols/tftp/plugin.pm @@ -0,0 +1,48 @@ +# +# Copyright 2019 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 apps::protocols::tftp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_simple); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'commands' => 'apps::protocols::tftp::mode::commands', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check an TFTP server. + +=cut diff --git a/apps/protocols/x509/mode/certificate.pm b/apps/protocols/x509/mode/certificate.pm index 3f06ceb46..09b5ab04f 100644 --- a/apps/protocols/x509/mode/certificate.pm +++ b/apps/protocols/x509/mode/certificate.pm @@ -165,7 +165,6 @@ sub manage_selection { my $alt_subjects = ''; for (my $i = 0; $i < $#subject_alt_names; $i += 2) { my ($type, $name) = ($subject_alt_names[$i], $subject_alt_names[$i + 1]); - next if ($name eq $subject); if ($type == GEN_IPADD) { $name = inet_ntoa($name); } diff --git a/apps/proxmox/ve/restapi/custom/api.pm b/apps/proxmox/ve/restapi/custom/api.pm index 25878ab69..055452e4c 100644 --- a/apps/proxmox/ve/restapi/custom/api.pm +++ b/apps/proxmox/ve/restapi/custom/api.pm @@ -44,27 +44,24 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port'}, - "proto:s" => { name => 'proto' }, - "api-username:s" => { name => 'api_username' }, - "api-password:s" => { name => 'api_password' }, - "realm:s" => { name => 'realm' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "reload-cache-time:s" => { name => 'reload_cache_time', default => 7200 }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port'}, + "proto:s" => { name => 'proto' }, + "api-username:s" => { name => 'api_username' }, + "api-password:s" => { name => 'api_password' }, + "realm:s" => { name => 'realm' }, + "timeout:s" => { name => 'timeout' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "reload-cache-time:s" => { name => 'reload_cache_time', default => 7200 }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); $self->{cache} = centreon::plugins::statefile->new(%options); return $self; @@ -99,7 +96,6 @@ sub check_options { $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 8006; $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? $self->{option_results}->{proxyurl} : undef; $self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef; $self->{api_username} = (defined($self->{option_results}->{api_username})) ? $self->{option_results}->{api_username} : undef; $self->{api_password} = (defined($self->{option_results}->{api_password})) ? $self->{option_results}->{api_password} : undef; @@ -143,7 +139,6 @@ sub build_options_for_httplib { $self->{option_results}->{proto} = $self->{proto}; $self->{option_results}->{ssl_opt} = $self->{ssl_opt}; $self->{option_results}->{timeout} = $self->{timeout}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; $self->{option_results}->{warning_status} = ''; $self->{option_results}->{critical_status} = ''; $self->{option_results}->{unknown_status} = ''; @@ -540,22 +535,10 @@ Set Proxmox VE Password Set Proxmox VE Realm (pam, pve or custom) (Default: 'pam'). -=item B<--proxyurl> - -Proxy URL if any. - -=item B<--proxypac> - -Proxy pac file (can be an url or local file). - =item B<--timeout> Threshold for HTTP timeout. -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =cut diff --git a/apps/proxmox/ve/restapi/mode/nodeusage.pm b/apps/proxmox/ve/restapi/mode/nodeusage.pm index 9c462b865..7c07ed031 100644 --- a/apps/proxmox/ve/restapi/mode/nodeusage.pm +++ b/apps/proxmox/ve/restapi/mode/nodeusage.pm @@ -56,22 +56,21 @@ sub custom_cpu_calc { sub custom_memory_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => 'memory_used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'memory_used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_memory_threshold { my ($self, %options) = @_; my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, - threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -104,22 +103,21 @@ sub custom_memory_calc { sub custom_swap_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => 'swap_used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'swap_used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_swap_threshold { my ($self, %options) = @_; my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, - threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -152,22 +150,21 @@ sub custom_swap_calc { sub custom_fs_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => 'fs_used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'fs_used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_fs_threshold { my ($self, %options) = @_; my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, - threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } diff --git a/apps/proxmox/ve/restapi/mode/storageusage.pm b/apps/proxmox/ve/restapi/mode/storageusage.pm index a108df6ca..b8fdf7a4c 100644 --- a/apps/proxmox/ve/restapi/mode/storageusage.pm +++ b/apps/proxmox/ve/restapi/mode/storageusage.pm @@ -46,22 +46,21 @@ sub custom_status_calc { sub custom_storage_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => 'storage_used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'storage_used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } -sub custom_disc_threshold { +sub custom_storage_threshold { my ($self, %options) = @_; my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, - threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } diff --git a/apps/proxmox/ve/restapi/mode/vmusage.pm b/apps/proxmox/ve/restapi/mode/vmusage.pm index e26f513f1..1568d748d 100644 --- a/apps/proxmox/ve/restapi/mode/vmusage.pm +++ b/apps/proxmox/ve/restapi/mode/vmusage.pm @@ -56,22 +56,21 @@ sub custom_cpu_calc { sub custom_memory_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => 'memory_used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'memory_used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_memory_threshold { my ($self, %options) = @_; my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, - threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -101,6 +100,53 @@ sub custom_memory_calc { return 0; } +sub custom_swap_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + label => 'swap_used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); +} + +sub custom_swap_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_swap_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + + my $msg = sprintf("Swap Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_swap_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_swap_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_swap_usage'}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + return 0; +} + sub set_counters { my ($self, %options) = @_; @@ -157,6 +203,14 @@ sub set_counters { ], } }, + { label => 'swap', set => { + key_values => [ { name => 'swap_usage' }, { name => 'swap_total' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_swap_calc'), + closure_custom_output => $self->can('custom_swap_output'), + closure_custom_perfdata => $self->can('custom_swap_perfdata'), + closure_custom_threshold_check => $self->can('custom_swap_threshold'), + } + }, ]; $self->{maps_counters}->{vms_traffic} = [ @@ -312,13 +366,13 @@ Example: --filter-counters='^vm-status$' Threshold warning. Can be: 'read-iops', 'write-iops', 'traffic-in', 'traffic-out', -'cpu' (%), 'memory' (%). +'cpu' (%), 'memory' (%), 'swap' (%). =item B<--critical-*> Threshold critical. Can be: 'read-iops', 'write-iops', 'traffic-in', 'traffic-out', -'cpu' (%), 'memory' (%). +'cpu' (%), 'memory' (%), 'swap' (%). =item B<--warning-vm-status> diff --git a/apps/pvx/restapi/custom/api.pm b/apps/pvx/restapi/custom/api.pm index 8663d4b80..b2d354164 100644 --- a/apps/pvx/restapi/custom/api.pm +++ b/apps/pvx/restapi/custom/api.pm @@ -42,28 +42,25 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "api-key:s" => { name => 'api_key' }, - "hostname:s" => { name => 'hostname' }, - "url-path:s" => { name => 'url_path' }, - "port:s" => { name => 'port' }, - "proto:s" => { name => 'proto' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "timeframe:s" => { name => 'timeframe' }, - }); + $options{options}->add_options(arguments => { + "api-key:s" => { name => 'api_key' }, + "hostname:s" => { name => 'hostname' }, + "url-path:s" => { name => 'url_path' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + "timeframe:s" => { name => 'timeframe' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'RESTAPI OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; @@ -100,8 +97,6 @@ sub check_options { $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; $self->{url_path} = (defined($self->{option_results}->{url_path})) ? $self->{option_results}->{url_path} : '/api'; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? $self->{option_results}->{proxyurl} : undef; - $self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef; $self->{username} = (defined($self->{option_results}->{username})) ? $self->{option_results}->{username} : undef; $self->{password} = (defined($self->{option_results}->{password})) ? $self->{option_results}->{password} : undef; $self->{credentials} = (defined($self->{option_results}->{credentials})) ? 1 : undef; @@ -127,7 +122,6 @@ sub build_options_for_httplib { $self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{port} = $self->{port}; $self->{option_results}->{proto} = $self->{proto}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; $self->{option_results}->{credentials} = $self->{credentials}; $self->{option_results}->{basic} = $self->{basic}; $self->{option_results}->{username} = $self->{username}; @@ -263,18 +257,10 @@ Specify this option if you access the API over hidden basic authentication or yo (Use with --credentials) -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/apps/redis/cli/mode/memory.pm b/apps/redis/cli/mode/memory.pm index eb434294e..5c7f2a472 100644 --- a/apps/redis/cli/mode/memory.pm +++ b/apps/redis/cli/mode/memory.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; @@ -42,10 +40,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{result_values}->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{result_values}->{label}, exit_litteral => 'warning' } ]); return $exit; @@ -200,7 +198,6 @@ sub prefix_stats_output { return "Statistics: "; } - sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -208,22 +205,14 @@ sub new { $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - my $metrics = { used_memory => { label => 'used', display => 'Used' }, used_memory_rss => { label => 'rss', display => 'Rss' }, diff --git a/apps/redis/restapi/custom/api.pm b/apps/redis/restapi/custom/api.pm index 2d5937cd0..ec48605bf 100644 --- a/apps/redis/restapi/custom/api.pm +++ b/apps/redis/restapi/custom/api.pm @@ -40,25 +40,21 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "interval:s@" => { name => 'interval' }, - "hostname:s@" => { name => 'hostname' }, - "port:s@" => { name => 'port' }, - "proto:s@" => { name => 'proto' }, - "username:s@" => { name => 'username' }, - "password:s@" => { name => 'password' }, - "proxyurl:s@" => { name => 'proxyurl' }, - "timeout:s@" => { name => 'timeout' }, - "ssl:s@" => { name => 'ssl' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "interval:s@" => { name => 'interval' }, + "hostname:s@" => { name => 'hostname' }, + "port:s@" => { name => 'port' }, + "proto:s@" => { name => 'proto' }, + "username:s@" => { name => 'username' }, + "password:s@" => { name => 'password' }, + "timeout:s@" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; @@ -95,8 +91,6 @@ sub check_options { $self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : ''; $self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{password}}) : ''; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef; - $self->{ssl} = (defined($self->{option_results}->{ssl})) ? shift(@{$self->{option_results}->{ssl}}) : 'tlsv1'; $self->{interval} = (defined($self->{option_results}->{interval})) ? shift(@{$self->{option_results}->{interval}}) : '15min'; if (!defined($self->{hostname})) { @@ -119,12 +113,10 @@ sub build_options_for_httplib { $self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{port} = $self->{port}; $self->{option_results}->{proto} = $self->{proto}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; $self->{option_results}->{credentials} = 1; $self->{option_results}->{basic} = 1; $self->{option_results}->{username} = $self->{username}; $self->{option_results}->{password} = $self->{password}; - $self->{option_results}->{ssl} = $self->{ssl}; $self->{option_results}->{warning_status} = ''; $self->{option_results}->{critical_status} = ''; } @@ -226,18 +218,10 @@ Cluster username. Cluster password. -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/apps/redis/restapi/mode/clusterstats.pm b/apps/redis/restapi/mode/clusterstats.pm index d5635534e..e1eb4be5c 100644 --- a/apps/redis/restapi/mode/clusterstats.pm +++ b/apps/redis/restapi/mode/clusterstats.pm @@ -26,8 +26,6 @@ use strict; use warnings; use Digest::MD5 qw(md5_hex); -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; @@ -43,10 +41,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{result_values}->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{result_values}->{label}, exit_litteral => 'warning' } ]); return $exit; @@ -224,26 +222,18 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); - - return $self; -} + $options{options}->add_options(arguments => { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; + return $self; } sub manage_selection { my ($self, %options) = @_; - my $result = $options{custom}->get(path => '/v1/cluster/stats/last?interval='.$options{custom}->get_interval()); + my $result = $options{custom}->get(path => '/v1/cluster/stats/last?interval=' . $options{custom}->get_interval()); my $result2 = $options{custom}->get(path => '/v1/cluster'); my $result3 = $options{custom}->get(path => '/v1/nodes'); diff --git a/apps/rrdcached/mode/stats.pm b/apps/rrdcached/mode/stats.pm index 7ad9be931..dbc5d9fb6 100644 --- a/apps/rrdcached/mode/stats.pm +++ b/apps/rrdcached/mode/stats.pm @@ -25,7 +25,6 @@ use base qw(centreon::plugins::mode); use strict; use warnings; use IO::Socket; -use Data::Dumper; sub new { my ($class, %options) = @_; diff --git a/apps/rudder/restapi/custom/api.pm b/apps/rudder/restapi/custom/api.pm new file mode 100644 index 000000000..2be87b374 --- /dev/null +++ b/apps/rudder/restapi/custom/api.pm @@ -0,0 +1,228 @@ +# +# Copyright 2019 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 apps::rudder::restapi::custom::api; + +use strict; +use warnings; +use centreon::plugins::http; +use DateTime; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "url-path:s" => { name => 'url_path' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "api-token:s" => { name => 'api_token' }, + "timeout:s" => { name => 'timeout' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{http} = centreon::plugins::http->new(%options); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : undef; + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443; + $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; + $self->{url_path} = (defined($self->{option_results}->{url_path})) ? $self->{option_results}->{url_path} : '/rudder/api/latest'; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; + $self->{api_token} = (defined($self->{option_results}->{api_token})) ? $self->{option_results}->{api_token} : ''; + + if (!defined($self->{hostname}) || $self->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --hostname option."); + $self->{output}->option_exit(); + } + if (!defined($self->{api_token}) || $self->{api_token} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --api-token option."); + $self->{output}->option_exit(); + } + + return 0; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{url_path} = $self->{url_path}; + $self->{option_results}->{warning_status} = ''; + $self->{option_results}->{critical_status} = ''; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->add_header(key => 'Accept', value => 'application/json'); + if (defined($self->{access_token})) { + $self->{http}->add_header(key => 'X-API-Token', value => $self->{access_token}); + } + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub get_connection_info { + my ($self, %options) = @_; + + return $self->{hostname} . ":" . $self->{port}; +} + +sub get_hostname { + my ($self, %options) = @_; + + return $self->{hostname}; +} + +sub get_port { + my ($self, %options) = @_; + + return $self->{port}; +} + +sub get_token { + my ($self, %options) = @_; + + return $self->{option_results}->{api_token}; +} + +sub request_api { + my ($self, %options) = @_; + + if (!defined($self->{access_token})) { + $self->{access_token} = $self->get_token(); + } + + $self->settings; + + $self->{output}->output_add(long_msg => "Query URL: '" . $self->{proto} . "://" . $self->{hostname} . + $self->{url_path} . $options{url_path} . "'", debug => 1); + + my $content = $self->{http}->request(url_path => $self->{url_path} . $options{url_path}); + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + if (!defined($decoded->{result}) || $decoded->{result} ne "success") { + $self->{output}->output_add(long_msg => "Error message : " . $decoded->{errorDetails}, debug => 1); + $self->{output}->add_option_msg(short_msg => "API return error code '" . $decoded->{result} . "' (add --debug option for detailed message)"); + $self->{output}->option_exit(); + } + + return $decoded->{data}; +} + +1; + +__END__ + +=head1 NAME + +Rudder Rest API + +=head1 SYNOPSIS + +Rudder Rest API custom mode + +=head1 REST API OPTIONS + +Rudder Rest API + +=over 8 + +=item B<--hostname> + +Rudder API hostname. + +=item B<--port> + +API port (Default: 443) + +=item B<--proto> + +Specify https if needed (Default: 'https') + +=item B<--url-path> + +API URL path (Default: '/rudder/api/latest') + +=item B<--timeout> + +Set HTTP timeout + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/apps/rudder/restapi/mode/discovery.pm b/apps/rudder/restapi/mode/discovery.pm new file mode 100644 index 000000000..e5450abb9 --- /dev/null +++ b/apps/rudder/restapi/mode/discovery.pm @@ -0,0 +1,121 @@ +# +# Copyright 2019 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 apps::rudder::restapi::mode::discovery; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use JSON::XS; + +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 => { + "prettify" => { name => 'prettify' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + + my @disco_data; + my $disco_stats; + + $disco_stats->{start_time} = time(); + + my $results = $options{custom}->request_api(url_path => '/nodes'); + + foreach my $node (@{$results->{nodes}}) { + my %node; + $node{name} = $node->{hostname}; + $node{type} = $node->{machine}->{type}; + $node{os} = $node->{os}->{name}; + $node{version} = $node->{os}->{version}; + $node{status} = $node->{status}; + $node{state} = $node->{state}; + $node{id} = $node->{id}; + $node{ip} = $node->{ipAddresses}; + + push @disco_data, \%node; + } + + $results = $options{custom}->request_api(url_path => '/nodes/pending'); + + foreach my $node (@{$results->{nodes}}) { + my %node; + $node{name} = $node->{hostname}; + $node{type} = $node->{machine}->{type}; + $node{os} = $node->{os}->{name}; + $node{version} = $node->{os}->{version}; + $node{status} = $node->{status}; + $node{state} = $node->{state}; + $node{id} = $node->{id}; + $node{ip} = $node->{ipAddresses}; + + push @disco_data, \%node; + } + + $disco_stats->{end_time} = time(); + $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; + $disco_stats->{discovered_items} = @disco_data; + $disco_stats->{results} = \@disco_data; + + my $encoded_data; + eval { + if (defined($self->{option_results}->{prettify})) { + $encoded_data = JSON::XS->new->utf8->pretty->encode($disco_stats); + } else { + $encoded_data = JSON::XS->new->utf8->encode($disco_stats); + } + }; + if ($@) { + $encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}'; + } + + $self->{output}->output_add(short_msg => $encoded_data); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Resources discovery. + +=over 8 + +=back + +=cut diff --git a/apps/rudder/restapi/mode/globalcompliance.pm b/apps/rudder/restapi/mode/globalcompliance.pm new file mode 100644 index 000000000..7b788440f --- /dev/null +++ b/apps/rudder/restapi/mode/globalcompliance.pm @@ -0,0 +1,164 @@ +# +# Copyright 2019 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 apps::rudder::restapi::mode::globalcompliance; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + label => 'value', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{detail} : undef, + value => $self->{result_values}->{value}, + min => 0, max => 100, unit => '%' + ); +} + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf("value is '%.2f%%'", $self->{result_values}->{value}); +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{detail} = $options{new_datas}->{$self->{instance} . '_detail'}; + $self->{result_values}->{value} = $options{new_datas}->{$self->{instance} . '_value'}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'compliances', type => 1, cb_prefix_output => 'prefix_compliances_output', + message_multiple => 'All compliance details are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'global-compliance', set => { + key_values => [ { name => 'compliance' } ], + output_template => 'Global Compliance: %.2f%%', + perfdatas => [ + { label => 'global_compliance', value => 'compliance_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; + $self->{maps_counters}->{compliances} = [ + { label => 'status', set => { + key_values => [ { name => 'value' }, { name => 'detail' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => $self->can('custom_status_perfdata'), + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + ]; +} + +sub prefix_compliances_output { + my ($self, %options) = @_; + + return "Compliance Detail '" . $options{instance_value}->{detail} . "' "; +} + +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 => '' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{compliances} = {}; + + my $results = $options{custom}->request_api(url_path => '/compliance'); + + $self->{global}->{compliance} = $results->{globalCompliance}->{compliance}; + + foreach my $detail (keys %{$results->{globalCompliance}->{complianceDetails}}) { + $self->{compliances}->{$detail} = { + detail => $detail, + value => $results->{globalCompliance}->{complianceDetails}->{$detail}, + } + } +} + +1; + +__END__ + +=head1 MODE + +Check global compliance and compliance details. + +=over 8 + +=item B<--warning-global-compliance> + +Set warning threshold on global compliance. + +=item B<--critical-global-compliance> + +Set critical threshold on global compliance. + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{detail}, %{value} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{detail}, %{value} + +Example : + --critical-status='%{detail} eq "error" && %{value} > 5' + +=back + +=cut diff --git a/apps/rudder/restapi/mode/listnodes.pm b/apps/rudder/restapi/mode/listnodes.pm new file mode 100644 index 000000000..5954f5c36 --- /dev/null +++ b/apps/rudder/restapi/mode/listnodes.pm @@ -0,0 +1,146 @@ +# +# Copyright 2019 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 apps::rudder::restapi::mode::listnodes; + +use base qw(centreon::plugins::templates::counter); + +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' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->request_api(url_path => '/nodes'); + + foreach my $node (@{$results->{nodes}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $node->{hostname} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{hostname} . "': no matching filter name.", debug => 1); + next; + } + + $self->{nodes}->{$node->{id}} = { + name => $node->{hostname}, + type => $node->{machine}->{type}, + os => $node->{os}->{name}, + version => $node->{os}->{version}, + status => $node->{status}, + id => $node->{id}, + } + } + + $results = $options{custom}->request_api(url_path => '/nodes/pending'); + + foreach my $node (@{$results->{nodes}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $node->{hostname} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{hostname} . "': no matching filter name.", debug => 1); + next; + } + + $self->{nodes}->{$node->{id}} = { + name => $node->{hostname}, + type => $node->{machine}->{type}, + os => $node->{os}->{name}, + version => $node->{os}->{version}, + status => $node->{status}, + id => $node->{id}, + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $node (sort keys %{$self->{nodes}}) { + $self->{output}->output_add(long_msg => sprintf("[name = %s] [type = %s] [os = %s] [version = %s] [status = %s] [id = %s]", + $self->{nodes}->{$node}->{name}, + $self->{nodes}->{$node}->{type}, + $self->{nodes}->{$node}->{os}, + $self->{nodes}->{$node}->{version}, + $self->{nodes}->{$node}->{status}, + $self->{nodes}->{$node}->{id})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List nodes:'); + $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', 'os', 'version', 'id']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $node (sort keys %{$self->{nodes}}) { + $self->{output}->add_disco_entry( + name => $self->{nodes}->{$node}->{name}, + type => $self->{nodes}->{$node}->{type}, + os => $self->{nodes}->{$node}->{os}, + version => $self->{nodes}->{$node}->{version}, + status => $self->{nodes}->{$node}->{status}, + id => $self->{nodes}->{$node}->{id}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List nodes. + +=over 8 + +=item B<--filter-name> + +Filter node name (can be a regexp). + +=back + +=cut diff --git a/apps/rudder/restapi/mode/listrules.pm b/apps/rudder/restapi/mode/listrules.pm new file mode 100644 index 000000000..c11137650 --- /dev/null +++ b/apps/rudder/restapi/mode/listrules.pm @@ -0,0 +1,126 @@ +# +# Copyright 2019 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 apps::rudder::restapi::mode::listrules; + +use base qw(centreon::plugins::templates::counter); + +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' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->request_api(url_path => '/rules'); + + foreach my $rule (@{$results->{rules}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $rule->{displayName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $rule->{hostname} . "': no matching filter name.", debug => 1); + next; + } + + my @tags; + foreach my $tag (@{$rule->{tags}}) { + push @tags, (keys %{$tag})[0] . ':' . (values %{$tag})[0]; + } + + $self->{rules}->{$rule->{id}} = { + name => $rule->{displayName}, + tags => join(',', @tags), + enabled => $rule->{enabled}, + id => $rule->{id}, + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $rule (sort keys %{$self->{rules}}) { + $self->{output}->output_add(long_msg => sprintf("[name = %s] [tags = %s] [enabled = %s] [id = %s]", + $self->{rules}->{$rule}->{name}, + $self->{rules}->{$rule}->{tags}, + $self->{rules}->{$rule}->{enabled}, + $self->{rules}->{$rule}->{id})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List rules:'); + $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', 'tags', 'enabled', 'id']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $rule (sort keys %{$self->{rules}}) { + $self->{output}->add_disco_entry( + name => $self->{rules}->{$rule}->{name}, + tags => $self->{rules}->{$rule}->{tags}, + enabled => $self->{rules}->{$rule}->{enabled}, + id => $self->{rules}->{$rule}->{id}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List rules. + +=over 8 + +=item B<--filter-name> + +Filter rule name (can be a regexp). + +=back + +=cut diff --git a/apps/rudder/restapi/mode/nodecompliance.pm b/apps/rudder/restapi/mode/nodecompliance.pm new file mode 100644 index 000000000..cf670fcad --- /dev/null +++ b/apps/rudder/restapi/mode/nodecompliance.pm @@ -0,0 +1,192 @@ +# +# Copyright 2019 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 apps::rudder::restapi::mode::nodecompliance; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf("Compliance: %.2f%%", $self->{result_values}->{compliance}); +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{rule} = $options{new_datas}->{$self->{instance} . '_rule'}; + $self->{result_values}->{compliance} = $options{new_datas}->{$self->{instance} . '_compliance'}; + $self->{result_values}->{display} = $self->{instance}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'nodes', type => 3, cb_prefix_output => 'prefix_node_output', cb_long_output => 'long_output', + message_multiple => 'All nodes compliance are ok', indent_long_output => ' ', + group => [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'rules', display_long => 1, cb_prefix_output => 'prefix_rule_output', + message_multiple => 'All rules compliance are ok', type => 1 }, + ] + } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'node-compliance', set => { + key_values => [ { name => 'compliance' }, { name => 'display' } ], + output_template => 'Compliance: %.2f%%', + perfdatas => [ + { label => 'node_compliance', value => 'compliance_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; + $self->{maps_counters}->{rules} = [ + { label => 'status', set => { + key_values => [ { name => 'compliance' }, { name => 'rule' } ], + 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 => \&catalog_status_threshold, + } + }, + ]; +} + +sub prefix_node_output { + my ($self, %options) = @_; + + return "Node '" . $options{instance_value}->{display} . "' [Id: " . $options{instance_value}->{id} . "] "; +} + +sub prefix_rule_output { + my ($self, %options) = @_; + + return "Rule '" . $options{instance_value}->{rule} . "' "; +} + +sub long_output { + my ($self, %options) = @_; + + return "Checking node '" . $options{instance_value}->{display} . "' [Id: " . $options{instance_value}->{id} . "] "; +} + +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' }, + "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); + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{nodes} = {}; + + my $results = $options{custom}->request_api(url_path => '/compliance/nodes?level=2'); + + foreach my $node (@{$results->{nodes}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $node->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{name} . "': no matching filter name.", debug => 1); + next; + } + + $self->{nodes}->{$node->{id}}->{id} = $node->{id}; + $self->{nodes}->{$node->{id}}->{display} = $node->{name}; + $self->{nodes}->{$node->{id}}->{global}->{compliance} = $node->{compliance}; + $self->{nodes}->{$node->{id}}->{global}->{display} = $node->{name}; + + foreach my $rule (@{$node->{rules}}) { + $self->{nodes}->{$node->{id}}->{rules}->{$rule->{id}} = { + rule => $rule->{name}, + compliance => $rule->{compliance}, + }; + } + } + + if (scalar(keys %{$self->{nodes}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No nodes found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check nodes compliance. + +=over 8 + +=item B<--filter-name> + +Filter node name (regexp can be used) + +=item B<--warning-node-compliance> + +Set warning threshold on node compliance. + +=item B<--critical-node-compliance> + +Set critical threshold on node compliance. + +=item B<--warning-status> + +Set warning threshold for status of rule compliance (Default: ''). +Can used special variables like: %{rule}, %{compliance} + +=item B<--critical-status> + +Set critical threshold for status of rule compliance (Default: ''). +Can used special variables like: %{rule}, %{compliance} + +Example : + --critical-status='%{rule} eq "Global configuration for all nodes" && %{compliance} < 95' + +=back + +=cut diff --git a/apps/rudder/restapi/mode/nodesoverallcompliance.pm b/apps/rudder/restapi/mode/nodesoverallcompliance.pm new file mode 100644 index 000000000..d9e469c40 --- /dev/null +++ b/apps/rudder/restapi/mode/nodesoverallcompliance.pm @@ -0,0 +1,189 @@ +# +# Copyright 2019 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 apps::rudder::restapi::mode::nodesoverallcompliance; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_compliance_perfdata { + my ($self, %options) = @_; + + my %total_options = (); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { + $total_options{total} = $self->{result_values}->{total}; + $total_options{cast_int} = 1; + } + + $self->{output}->perfdata_add(label => 'compliance_' . $self->{label}, + value => $self->{result_values}->{count}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), + unit => 'nodes', min => 0, max => $self->{result_values}->{total}); +} + +sub custom_compliance_threshold { + my ($self, %options) = @_; + + my $threshold_value = $self->{result_values}->{count}; + if ($self->{instance_mode}->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_count}; + } + my $exit = $self->{perfdata}->threshold_check(value => $threshold_value, + threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + return $exit; + +} + +sub custom_compliance_output { + my ($self, %options) = @_; + + my $msg = sprintf("%s: %d (%.2f%%)", + $self->{result_values}->{output}, + $self->{result_values}->{count}, + $self->{result_values}->{prct_count}); + return $msg; +} + +sub custom_compliance_calc { + my ($self, %options) = @_; + + $self->{result_values}->{label} = $options{extra_options}->{label}; + $self->{result_values}->{output} = $options{extra_options}->{output}; + $self->{result_values}->{count} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label}}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + + $self->{result_values}->{prct_count} = ($self->{result_values}->{total} != 0) ? $self->{result_values}->{count} * 100 / $self->{result_values}->{total} : 0; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_compliance_output' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'perfect', set => { + key_values => [ { name => 'perfect' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_compliance_calc'), + closure_custom_calc_extra_options => { label => 'perfect', output => 'Perfect (100%)' }, + closure_custom_output => $self->can('custom_compliance_output'), + closure_custom_threshold_check => $self->can('custom_compliance_threshold'), + closure_custom_perfdata => $self->can('custom_compliance_perfdata') + } + }, + { label => 'good', set => { + key_values => [ { name => 'good' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_compliance_calc'), + closure_custom_calc_extra_options => { label => 'good', output => 'Good (>75%)' }, + closure_custom_output => $self->can('custom_compliance_output'), + closure_custom_threshold_check => $self->can('custom_compliance_threshold'), + closure_custom_perfdata => $self->can('custom_compliance_perfdata') + } + }, + { label => 'average', set => { + key_values => [ { name => 'average' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_compliance_calc'), + closure_custom_calc_extra_options => { label => 'average', output => 'Average (>50%)' }, + closure_custom_output => $self->can('custom_compliance_output'), + closure_custom_threshold_check => $self->can('custom_compliance_threshold'), + closure_custom_perfdata => $self->can('custom_compliance_perfdata') + } + }, + { label => 'poor', set => { + key_values => [ { name => 'poor' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_compliance_calc'), + closure_custom_calc_extra_options => { label => 'poor', output => 'Poor (<50%)' }, + closure_custom_output => $self->can('custom_compliance_output'), + closure_custom_threshold_check => $self->can('custom_compliance_threshold'), + closure_custom_perfdata => $self->can('custom_compliance_perfdata') + } + }, + ]; +} + +sub prefix_compliance_output { + my ($self, %options) = @_; + + return "Nodes Count by Overall Compliance "; +} + +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 => { + "units:s" => { name => 'units', default => '%' }, + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global} = { perfect => 0, good => 0, average => 0, poor => 0, total => 0 }; + + my $results = $options{custom}->request_api(url_path => '/compliance/nodes?level=1'); + + foreach my $node (@{$results->{nodes}}) { + $self->{global}->{total}++; + $self->{global}->{poor}++ if ($node->{compliance} < 50); + $self->{global}->{average}++ if ($node->{compliance} >= 50 && $node->{compliance} < 75); + $self->{global}->{good}++ if ($node->{compliance} >= 75 && $node->{compliance} < 100); + $self->{global}->{perfect}++ if ($node->{compliance} == 100); + } +} + +1; + +__END__ + +=head1 MODE + +Check nodes count by overall compliance. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'perfect', 'good', 'average', 'poor'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'perfect', 'good', 'average', 'poor'. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'count'). + +=back + +=cut diff --git a/apps/rudder/restapi/mode/rulecompliance.pm b/apps/rudder/restapi/mode/rulecompliance.pm new file mode 100644 index 000000000..6b575ad23 --- /dev/null +++ b/apps/rudder/restapi/mode/rulecompliance.pm @@ -0,0 +1,198 @@ +# +# Copyright 2019 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 apps::rudder::restapi::mode::rulecompliance; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf("Compliance: %.2f%%", $self->{result_values}->{compliance}); +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{directive} = $options{new_datas}->{$self->{instance} . '_directive'}; + $self->{result_values}->{compliance} = $options{new_datas}->{$self->{instance} . '_compliance'}; + $self->{result_values}->{display} = $self->{instance}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'rules', type => 3, cb_prefix_output => 'prefix_rule_output', cb_long_output => 'long_output', + message_multiple => 'All rules compliance are ok', indent_long_output => ' ', + group => [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'directives', display_long => 1, cb_prefix_output => 'prefix_directive_output', + message_multiple => 'All directives compliance are ok', type => 1 }, + ] + } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'rule-compliance', set => { + key_values => [ { name => 'compliance' } ], + output_template => 'Compliance: %.2f%%', + perfdatas => [ + { label => 'rule_compliance', value => 'compliance_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1 }, + ], + } + }, + ]; + $self->{maps_counters}->{directives} = [ + { label => 'status', set => { + key_values => [ { name => 'compliance' }, { name => 'directive' } ], + 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 => \&catalog_status_threshold, + } + }, + ]; +} + +sub prefix_rule_output { + my ($self, %options) = @_; + + return "Rule '" . $options{instance_value}->{display} . "' [Id: " . $options{instance_value}->{id} . "] "; +} + +sub prefix_directive_output { + my ($self, %options) = @_; + + return "Directive '" . $options{instance_value}->{directive} . "' "; +} + +sub long_output { + my ($self, %options) = @_; + + return "Checking rule '" . $options{instance_value}->{display} . "' [Id: " . $options{instance_value}->{id} . "] "; +} + +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' }, + "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); + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + my %rules_mapping; + $self->{rules} = {}; + + my $results = $options{custom}->request_api(url_path => '/rules'); + + foreach my $rule (@{$results->{rules}}) { + $rules_mapping{$rule->{id}} = $rule->{displayName}; + } + + $results = $options{custom}->request_api(url_path => '/compliance/rules?level=2'); + + foreach my $rule (@{$results->{rules}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $rules_mapping{$rule->{id}} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $rules_mapping{$rule->{id}} . "': no matching filter name.", debug => 1); + next; + } + + $self->{rules}->{$rule->{id}}->{id} = $rule->{id}; + $self->{rules}->{$rule->{id}}->{display} = $rules_mapping{$rule->{id}}; + $self->{rules}->{$rule->{id}}->{global}->{compliance} = $rule->{compliance}; + + foreach my $directive (@{$rule->{directives}}) { + $self->{rules}->{$rule->{id}}->{directives}->{$directive->{id}} = { + directive => $directive->{name}, + compliance => $directive->{compliance}, + }; + } + } + + if (scalar(keys %{$self->{rules}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No rules found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check rules compliance. + +=over 8 + +=item B<--filter-name> + +Filter rule name (regexp can be used) + +=item B<--warning-rule-compliance> + +Set warning threshold on rule compliance. + +=item B<--critical-rule-compliance> + +Set critical threshold on rule compliance. + +=item B<--warning-status> + +Set warning threshold for status of directive compliance (Default: ''). +Can used special variables like: %{directive}, %{compliance} + +=item B<--critical-status> + +Set critical threshold for status of directive compliance (Default: ''). +Can used special variables like: %{directive}, %{compliance} + +Example : + --critical-status='%{directive} eq "Users" && %{compliance} < 85' + +=back + +=cut diff --git a/apps/rudder/restapi/mode/statistics.pm b/apps/rudder/restapi/mode/statistics.pm new file mode 100644 index 000000000..8ebd50aaf --- /dev/null +++ b/apps/rudder/restapi/mode/statistics.pm @@ -0,0 +1,153 @@ +# +# Copyright 2019 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 apps::rudder::restapi::mode::statistics; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'nodes', set => { + key_values => [ { name => 'nodes' } ], + output_template => 'Nodes: %d', + perfdatas => [ + { label => 'nodes', value => 'nodes_absolute', template => '%d', + min => 0 }, + ], + } + }, + { label => 'pending-nodes', set => { + key_values => [ { name => 'pending_nodes' } ], + output_template => 'Pending Nodes: %d', + perfdatas => [ + { label => 'pending_nodes', value => 'pending_nodes_absolute', template => '%d', + min => 0 }, + ], + } + }, + { label => 'rules', set => { + key_values => [ { name => 'rules' } ], + output_template => 'Rules: %d', + perfdatas => [ + { label => 'rules', value => 'rules_absolute', template => '%d', + min => 0 }, + ], + } + }, + { label => 'directives', set => { + key_values => [ { name => 'directives' } ], + output_template => 'Directives: %d', + perfdatas => [ + { label => 'directives', value => 'directives_absolute', template => '%d', + min => 0 }, + ], + } + }, + { label => 'groups', set => { + key_values => [ { name => 'groups' } ], + output_template => 'Groups: %d', + perfdatas => [ + { label => 'groups', value => 'groups_absolute', template => '%d', + min => 0 }, + ], + } + }, + { label => 'techniques', set => { + key_values => [ { name => 'techniques' } ], + output_template => 'Techniques: %d', + perfdatas => [ + { label => 'techniques', value => 'techniques_absolute', template => '%d', + 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 => { + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{compliances} = {}; + + my $results = $options{custom}->request_api(url_path => '/nodes?include=minimal'); + $self->{global}->{nodes} = scalar(@{$results->{nodes}}); + $results = $options{custom}->request_api(url_path => '/nodes/pending?include=minimal'); + $self->{global}->{pending_nodes} = scalar(@{$results->{nodes}}); + $results = $options{custom}->request_api(url_path => '/rules'); + $self->{global}->{rules} = scalar(@{$results->{rules}}); + $results = $options{custom}->request_api(url_path => '/directives'); + $self->{global}->{directives} = scalar(@{$results->{directives}}); + $results = $options{custom}->request_api(url_path => '/groups'); + $self->{global}->{groups} = scalar(@{$results->{groups}}); + $results = $options{custom}->request_api(url_path => '/techniques'); + $self->{global}->{techniques} = scalar(@{$results->{techniques}}); +} + +1; + +__END__ + +=head1 MODE + +Check statistics (objects count). + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'nodes', 'pending-nodes', 'rules', +'directives', 'groups', 'techniques'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'nodes', 'pending-nodes', 'rules', +'directives', 'groups', 'techniques'. + +=back + +=cut diff --git a/apps/rudder/restapi/plugin.pm b/apps/rudder/restapi/plugin.pm new file mode 100644 index 000000000..9f71e4508 --- /dev/null +++ b/apps/rudder/restapi/plugin.pm @@ -0,0 +1,62 @@ +# +# Copyright 2019 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 apps::rudder::restapi::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'discovery' => 'apps::rudder::restapi::mode::discovery', + 'global-compliance' => 'apps::rudder::restapi::mode::globalcompliance', + 'list-nodes' => 'apps::rudder::restapi::mode::listnodes', + 'list-rules' => 'apps::rudder::restapi::mode::listrules', + 'node-compliance' => 'apps::rudder::restapi::mode::nodecompliance', + 'nodes-overall-compliance' => 'apps::rudder::restapi::mode::nodesoverallcompliance', + 'rule-compliance' => 'apps::rudder::restapi::mode::rulecompliance', + 'statistics' => 'apps::rudder::restapi::mode::statistics', + ); + + $self->{custom_modes}{api} = 'apps::rudder::restapi::custom::api'; + return $self; +} + +sub init { + my ( $self, %options ) = @_; + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Rudder. + +=cut diff --git a/apps/sahipro/restapi/mode/scenario.pm b/apps/sahipro/restapi/mode/scenario.pm new file mode 100644 index 000000000..bbc754eab --- /dev/null +++ b/apps/sahipro/restapi/mode/scenario.pm @@ -0,0 +1,544 @@ +# +# Copyright 2019 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 apps::sahipro::restapi::mode::scenario; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use centreon::plugins::http; +use Time::HiRes; +use POSIX qw(strftime); +use XML::Simple; +use DateTime; + +my %handlers = (ALRM => {}); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf('status is %s', $self->{result_values}->{status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + foreach (keys %{$options{new_datas}}) { + if (/$self->{instance}_(step\d+_time)/) { + $self->{result_values}->{$1} = $options{new_datas}->{$_}; + } + } + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', skipped_code => { -10 => 1 } }, + { name => 'steps', type => 1, cb_prefix_output => 'prefix_step_output', message_multiple => 'All steps are ok', sort_method => 'num' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'status', threshold => 0, set => { + key_values => [], + manual_keys => 1, + 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 => \&catalog_status_threshold, + } + }, + { label => 'total-time', display_ok => 0, set => { + key_values => [ { name => 'time_taken' } ], + output_template => 'execution time : %s ms', + perfdatas => [ + { label => 'total_time', value => 'time_taken_absolute', template => '%s', min => 0, unit => 'ms' }, + ], + } + }, + { label => 'total-steps', display_ok => 0, set => { + key_values => [ { name => 'total_steps' } ], + output_template => 'total steps : %s', + perfdatas => [ + { label => 'total_steps', value => 'total_steps_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'failures', display_ok => 0, set => { + key_values => [ { name => 'failures' } ], + output_template => 'failures : %s', + perfdatas => [ + { label => 'failures', value => 'failures_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'errors', display_ok => 0, set => { + key_values => [ { name => 'errors' } ], + output_template => 'errors : %s', + perfdatas => [ + { label => 'errors', value => 'errors_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{steps} = [ + { label => 'step-time', set => { + key_values => [ { name => 'time_taken' }, { name => 'step' } ], + output_template => 'execution time : %s ms', + perfdatas => [ + { label => 'step_time', value => 'time_taken_absolute', template => '%s', + min => 0, unit => 'ms', label_extra_instance => 1, instance_use => 'step_absolute' }, + ], + } + }, + + ]; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Scenario "; +} + +sub prefix_step_output { + my ($self, %options) = @_; + + return "Step '" . $options{instance_value}->{step} . "' [" . $options{instance_value}->{display} . "] "; +} + +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 => { + "sahi-hostname:s" => { name => 'sahi_hostname' }, + "sahi-port:s" => { name => 'sahi_port', default => 9999 }, + "sahi-proto:s" => { name => 'sahi_proto', default => 'http' }, + "sahi-http-timeout:s" => { name => 'sahi_http_timeout', default => 5 }, + "sahi-endpoint:s" => { name => 'sahi_endpoint', default => '/_s_/dyn/' }, + "sahi-suite:s" => { name => 'sahi_suite' }, + "sahi-threads:s" => { name => 'sahi_threads', default => 1 }, + "sahi-startwith:s" => { name => 'sahi_startwith', default => 'BROWSER' }, + "sahi-browsertype:s" => { name => 'sahi_browsertype', default => 'chrome' }, + "sahi-baseurl:s" => { name => 'sahi_baseurl' }, + "timeout:s" => { name => 'timeout' }, + "retries-scenario-status:s" => { name => 'retries_scenario_status' }, + "interval-scenario-status:s" => { name => 'interval_scenario_status', default => 10 }, + "unknown-run-status:s" => { name => 'unknown_run_status', default => '%{http_code} < 200 or %{http_code} >= 300' }, + "warning-run-status:s" => { name => 'warning_run_status' }, + "critical-run-status:s" => { name => 'critical_run_status', default => '' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} ne "SUCCESS"' }, + }); + + $self->{http} = centreon::plugins::http->new(%options); + $self->set_signal_handlers(); + return $self; +} + +sub set_signal_handlers { + my $self = shift; + + $SIG{ALRM} = \&class_handle_ALRM; + $handlers{ALRM}->{$self} = sub { $self->handle_ALRM() }; +} + +sub class_handle_ALRM { + foreach (keys %{$handlers{ALRM}}) { + &{$handlers{ALRM}->{$_}}(); + } +} + +sub handle_ALRM { + my $self = shift; + + $self->killed_scenario(); + $self->{output}->add_option_msg(short_msg => "Cannot finished scenario execution (timeout received)"); + $self->{output}->option_exit(); +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + foreach my $option (('sahi_hostname', 'sahi_suite', 'sahi_startwith', 'sahi_browsertype')) { + (my $label = $option) =~ s/_/-/g; + if (!defined($self->{option_results}->{$option}) || $self->{option_results}->{$option} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set " . $label . " option"); + $self->{output}->option_exit(); + } + } + + if (!defined($self->{option_results}->{interval_scenario_status}) || $self->{option_results}->{interval_scenario_status} !~ /^\d+$/ || + $self->{option_results}->{interval_scenario_status} < 0) { + $self->{option_results}->{interval_scenario_status} = 10; + } + if (!defined($self->{option_results}->{retries_scenario_status}) || $self->{option_results}->{retries_scenario_status} !~ /^\d+$/ || + $self->{option_results}->{retries_scenario_status} < 0) { + $self->{option_results}->{retries_scenario_status} = 0; + } + + if (defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /^\d+$/ && + $self->{option_results}->{timeout} > 0) { + alarm($self->{option_results}->{timeout}); + } + + $self->change_macros(macros => ['warning_status', 'critical_status']); + $self->{http}->set_options(port => $self->{option_results}->{sahi_port}, proto => $self->{option_results}->{sahi_proto}); +} + +sub decode_xml_response { + my ($self, %options) = @_; + + my $content; + eval { + $content = XMLin($options{response}, ForceArray => $options{ForceArray}, KeyAttr => []); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode xml response: $@"); + $self->{output}->option_exit(); + } + + return $content; +} + +sub generate_user_defined_id { + my ($self, %options) = @_; + + my ($seconds, $microseconds) = Time::HiRes::gettimeofday(); + my $user_defined_id = strftime("%d%B%Y__%H_%M_%S_", localtime($seconds)); + $user_defined_id .= $microseconds; + + return $user_defined_id; +} + +sub time2ms { + my ($self, %options) = @_; + + #2019-02-26 10:38:47.407 + return -1 if ($options{time} !~ /^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2}).(\d+)/); + my $dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6, nanosecond => $7 * 1000000); + return $dt->hires_epoch; +} + +sub killed_scenario { + my ($self, %options) = @_; + + return if (!defined($self->{user_defined_id})); + $self->{http}->request( + proto => $self->{option_results}->{sahi_proto}, + port => $self->{option_results}->{sahi_port}, + hostname => $self->{option_results}->{sahi_hostname}, + url_path => $self->{option_results}->{sahi_endpoint} . 'SahiEndPoint_killAll', + timeout => $self->{option_results}->{sahi_http_timeout}, + unknown_status => '', warning_status => '', critical_status => '', + get_param => ['userDefinedId=' . $self->{user_defined_id}] + ); +} + +sub cleanup_scenario { + my ($self, %options) = @_; + + return if (!defined($self->{user_defined_id})); + $self->{http}->request( + proto => $self->{option_results}->{sahi_proto}, + port => $self->{option_results}->{sahi_port}, + hostname => $self->{option_results}->{sahi_hostname}, + url_path => $self->{option_results}->{sahi_endpoint} . 'SahiEndPoint_cleanup', + timeout => $self->{option_results}->{sahi_http_timeout}, + unknown_status => '', warning_status => '', critical_status => '', + get_param => ['userDefinedId=' . $self->{user_defined_id}] + ); +} + +sub run_scenario { + my ($self, %options) = @_; + + my $user_defined_id = $self->generate_user_defined_id(); + my ($content) = $self->{http}->request( + proto => $self->{option_results}->{sahi_proto}, + port => $self->{option_results}->{sahi_port}, + hostname => $self->{option_results}->{sahi_hostname}, + url_path => $self->{option_results}->{sahi_endpoint} . 'SahiEndPoint_run', + timeout => $self->{option_results}->{sahi_http_timeout}, + unknown_status => $self->{option_results}->{unknown_run_status}, + warning_status => $self->{option_results}->{warning_run_status}, + critical_status => $self->{option_results}->{critical_run_status}, + get_param => [ + 'threads=' . $self->{option_results}->{sahi_threads}, + 'startWith=' . $self->{option_results}->{sahi_startwith}, + 'browserType=' . $self->{option_results}->{sahi_browsertype}, + 'suite=' . $self->{option_results}->{sahi_suite}, + 'baseURL=' . (defined($self->{option_results}->{sahi_baseurl}) ? $self->{option_results}->{sahi_baseurl} : ''), + 'userDefinedId=' . $user_defined_id, + ] + ); + + if ($self->{http}->get_code() != 200) { + $self->{output}->add_option_msg(short_msg => "run scenario issue:" . $content); + $self->{output}->option_exit(); + } + + $self->{user_defined_id} = $user_defined_id; +} + +sub check_scenario_status { + my ($self, %options) = @_; + + my $content; + my $retries = 0; + while (1) { + ($content) = $self->{http}->request( + proto => $self->{option_results}->{sahi_proto}, + port => $self->{option_results}->{sahi_port}, + hostname => $self->{option_results}->{sahi_hostname}, + url_path => $self->{option_results}->{sahi_endpoint} . 'SahiEndPoint_status', + timeout => $self->{option_results}->{sahi_http_timeout}, + unknown_status => '', warning_status => '', critical_status => '', + get_param => ['userDefinedId=' . $self->{user_defined_id}] + ); + if ($self->{http}->get_code() != 200) { + if ($retries == $self->{option_results}->{retries_scenario_status}) { + $self->{output}->add_option_msg(short_msg => "check scenario status issue:" . $content); + $self->{output}->option_exit(); + } + $retries++; + } else { + $retries = 0; + } + + # other state: INITIAL, RUNNING + last if ($content =~ /SUCCESS|FAILURE|ABORTED|SKIPPED|USER_ABORTED/); + + sleep($self->{option_results}->{interval_scenario_status}); + } + + my $status = 'UNKNOWN'; + $status = $1 if ($content =~ /(SUCCESS|FAILURE|ABORTED|SKIPPED|USER_ABORTED)/); + + $self->{global}->{status} = $status; +} + +sub get_suite_report { + my ($self, %options) = @_; + + my ($content) = $self->{http}->request( + proto => $self->{option_results}->{sahi_proto}, + port => $self->{option_results}->{sahi_port}, + hostname => $self->{option_results}->{sahi_hostname}, + url_path => $self->{option_results}->{sahi_endpoint} . 'SahiEndPoint_suiteReport', + timeout => $self->{option_results}->{sahi_http_timeout}, + unknown_status => '', warning_status => '', critical_status => '', + get_param => [ + 'userDefinedId=' . $self->{user_defined_id}, + 'type=xml' + ] + ); + + if ($self->{http}->get_code() != 200) { + $self->cleanup_option_exit(short_msg => "get suite report issue:" . $content); + } + + my $response = $self->decode_xml_response(response => $content, ForceArray => ['summary']); + if (!defined($response->{suite}->{scriptSummaries}->{summary})) { + $self->{output}->output_add(long_msg => $response, debug => 1); + $self->cleanup_option_exit(short_msg => "get suite report issue: unknown response format"); + } + + # in milliseconds + $self->{global}->{time_taken} = $response->{suite}->{scriptSummaries}->{summary}->[0]->{TIMETAKEN}; + $self->{global}->{total_steps} = $response->{suite}->{scriptSummaries}->{summary}->[0]->{TOTALSTEPS}; + $self->{global}->{failures} = $response->{suite}->{scriptSummaries}->{summary}->[0]->{FAILURES}; + $self->{global}->{errors} = $response->{suite}->{scriptSummaries}->{summary}->[0]->{ERRORS}; + $self->{script_reportid} = $response->{suite}->{scriptSummaries}->{summary}->[0]->{SCRIPTREPORTID}; +} + +sub get_script_report { + my ($self, %options) = @_; + + my ($content) = $self->{http}->request( + proto => $self->{option_results}->{sahi_proto}, + port => $self->{option_results}->{sahi_port}, + hostname => $self->{option_results}->{sahi_hostname}, + url_path => $self->{option_results}->{sahi_endpoint} . 'SahiEndPoint_scriptReport', + timeout => $self->{option_results}->{sahi_http_timeout}, + unknown_status => '', warning_status => '', critical_status => '', + get_param => [ + 'id=' . $options{id}, + 'type=xml' + ] + ); + + if ($self->{http}->get_code() != 200) { + $self->cleanup_option_exit(short_msg => "get suite report issue:" . $content); + } + + my $response = $self->decode_xml_response(response => $content, ForceArray => ['step']); + if (!defined($response->{steps}->{step})) { + $self->{output}->output_add(long_msg => $response, debug => 1); + $self->cleanup_option_exit(short_msg => "get script report issue: unknown response format"); + } + + $self->{steps} = {}; + for (my $i = 0; $i < (scalar(@{$response->{steps}->{step}}) - 1); $i++) { + my $display = $response->{steps}->{step}->[$i]->{MESSAGETYPE}; + $display .= '.' . $response->{steps}->{step}->[$i]->{STEPMESSAGE} + if (defined($response->{steps}->{step}->[$i]->{STEPMESSAGE}) && $response->{steps}->{step}->[$i]->{STEPMESSAGE} ne ''); + $display =~ s/\|//g; + + my $current_time = $self->time2ms(time => $response->{steps}->{step}->[$i]->{MESSAGETIMESTAMP}); + my $next_time = $self->time2ms(time => $response->{steps}->{step}->[$i + 1]->{MESSAGETIMESTAMP}); + my $time_taken = int(($next_time * 1000) - ($current_time * 1000)); + + $self->{steps}->{$i} = { + step => $i, + display => $display, + time_taken => $time_taken, + }; + $self->{global}->{'step' . $i . '_time'} = $time_taken; + } +} + +sub cleanup_option_exit { + my ($self, %options) = @_; + + $self->cleanup_scenario(); + $self->{output}->add_option_msg(short_msg => $options{short_msg}); + $self->{output}->option_exit(); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global} = {}; + $self->run_scenario(); + $self->check_scenario_status(); + + if ($self->{global}->{status} =~ /FAILURE|SUCCESS/) { + $self->get_suite_report(); + $self->get_script_report(id => $self->{script_reportid}); + } + + $self->cleanup_scenario(); +} + +1; + +__END__ + +=head1 MODE + +Check scenario execution. + +=over 8 + +=item B<--sahi-hostname> + +IP Addr/FQDN of the host + +=item B<--sahi-port> + +Port used (Default: 9999) + +=item B<--sahi-proto> + +Specify https if needed (Default: 'http') + +=item B<--sahi-endpoint> + +Specify endpoint (Default: '/_s_/dyn/') + +=item B<--sahi-suite> + +Full path to scenario and scenario name (Required) + +=item B<--sahi-http-timeout> + +Timeout for each HTTP requests (Default: 5) + +=item B<--sahi-threads> + +Number of simultaneous browser instances that can be executed (Default: 1) + +=item B<--sahi-startwith> + +Specify the start mode (Default: BROWSER) + +=item B<--sahi-browsertype> + +Browser on which scripts will be executed (Default: chrome) + +=item B<--sahi-baseurl> + +Url where the script should start + +=item B<--timeout> + +Specify the global script timeout. If timeout is reached, scenario is killed. + +=item B<--retries-scenario-status> + +Specify the number of retries to get scenario status (if we fail to get the status). + +=item B<--interval-scenario-status> + +Specify time interval to get scenario status in seconds (Default: 10). + +=item B<--unknown-run-status> + +Threshold unknown for running scenario rest api response. +(Default: '%{http_code} < 200 or %{http_code} >= 300') + +=item B<--warning-run-status> + +Threshold warning for running scenario rest api response. + +=item B<--critical-run-status> + +Threshold critical for running scenario rest api response. + +=item B<--warning-status> + +Set warning threshold for scenario status. +Can used special variables like: %{status}. + +=item B<--critical-status> + +Set critical threshold for scenario status (Default: '%{status} ne "SUCCESS"'). +Can used special variables like: %{status}. + +=item B<--warning-*> B<--critical-*> + +Set thresholds. +Can be: 'total-time', 'total-steps', 'failures', 'errors', 'step-time'. + +=back + +=cut diff --git a/apps/sahipro/restapi/plugin.pm b/apps/sahipro/restapi/plugin.pm new file mode 100644 index 000000000..1b8884a93 --- /dev/null +++ b/apps/sahipro/restapi/plugin.pm @@ -0,0 +1,48 @@ +# +# Copyright 2019 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 apps::sahipro::restapi::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_simple); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'scenario' => 'apps::sahipro::restapi::mode::scenario', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Sahi Pro scenario with Rest API. + +=cut diff --git a/apps/sccm/local/mode/databasereplicationstatus.pm b/apps/sccm/local/mode/databasereplicationstatus.pm new file mode 100644 index 000000000..7867c1714 --- /dev/null +++ b/apps/sccm/local/mode/databasereplicationstatus.pm @@ -0,0 +1,281 @@ +# +# Copyright 2019 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 apps::sccm::local::mode::databasereplicationstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use JSON::XS; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use centreon::common::powershell::sccm::databasereplicationstatus; +use DateTime; + +my %map_link_status = ( + 1 => 'Degraded', + 2 => 'Active', + 3 => 'Failed', +); +my %map_status = ( + 100 => 'SITE_INSTALLING', + 105 => 'SITE_INSTALL_COMPLETE', + 110 => 'INACTIVE', + 115 => 'INITIALIZING', + 120 => 'MAINTENANCE_MODE', + 125 => 'ACTIVE', + 130 => 'DETACHING', + 135 => 'READY_TO_DETACH', + 199 => 'STATUS_UNKNOWN', + 200 => 'SITE_RECOVERED', + 205 => 'SITE_PREPARE_FOR_RECOVERY', + 210 => 'SITE_PREPARED_FOR_RECOVERY', + 215 => 'REPLCONFIG_REINITIALIZING', + 220 => 'REPLCONFIG_REINITIALIZED', + 225 => 'RECOVERY_IN_PROGRESS', + 230 => 'RECOVERING_DELTAS', + 250 => 'RECOVERY_RETRY', + 255 => 'RECOVERY_FAILED', +); +my %map_type = ( + 0 => 'Unknown', + 1 => 'SECONDARY', + 2 => 'PRIMARY', + 4 => 'CAS', +); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("Overall Link status is '%s'", $self->{result_values}->{status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_LinkStatus'}; + return 0; +} + +sub custom_site_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("status is '%s', Site-to-Site state is '%s' [Type: %s] [Last sync: %s]", + $self->{result_values}->{status}, + $self->{result_values}->{site_to_site_state}, + $self->{result_values}->{type}, + centreon::plugins::misc::change_seconds(value => $self->{result_values}->{last_sync_time})); + return $msg; +} + +sub custom_site_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_SiteStatus'}; + $self->{result_values}->{type} = $options{new_datas}->{$self->{instance} . '_SiteType'}; + $self->{result_values}->{site_to_site_state} = $options{new_datas}->{$self->{instance} . '_SiteToSiteGlobalState'}; + $self->{result_values}->{sync_time} = $options{new_datas}->{$self->{instance} . '_SiteToSiteGlobalSyncTime'}; + + my $tz = centreon::plugins::misc::set_timezone(name => $self->{option_results}->{timezone}); + $self->{result_values}->{sync_time} =~ /^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)$/; + my $sync_time = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6, %$tz); + + $self->{result_values}->{last_sync_time} = time() - $sync_time->epoch; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'sites', type => 1, cb_prefix_output => 'prefix_output_site', message_multiple => 'All sites status are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'link-status', threshold => 0, set => { + key_values => [ { name => 'LinkStatus' } ], + 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 => \&catalog_status_threshold, + } + }, + ]; + $self->{maps_counters}->{sites} = [ + { label => 'site-status', threshold => 0, set => { + key_values => [ { name => 'SiteType' }, { name => 'SiteStatus' }, { name => 'SiteToSiteGlobalState' }, + { name => 'SiteToSiteGlobalSyncTime' } ], + closure_custom_calc => $self->can('custom_site_status_calc'), + closure_custom_output => $self->can('custom_site_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + ]; +} + +sub prefix_output_site { + my ($self, %options) = @_; + + return "Site '" . $options{instance_value}->{display} . "' "; +} + +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 => { + "timeout:s" => { name => 'timeout', default => 30 }, + "command:s" => { name => 'command', default => 'powershell.exe' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, + "no-ps" => { name => 'no_ps' }, + "ps-exec-only" => { name => 'ps_exec_only' }, + "warning-link-status:s" => { name => 'warning_link_status', default => '' }, + "critical-link-status:s" => { name => 'critical_link_status', default => '' }, + "warning-site-status:s" => { name => 'warning_site_status', default => '' }, + "critical-site-status:s" => { name => 'critical_site_status', default => '' }, + "timezone:s" => { name => 'timezone', default => 'UTC' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_link_status', 'critical_link_status', + 'warning_site_status', 'critical_site_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $ps = centreon::common::powershell::sccm::databasereplicationstatus::get_powershell( + no_ps => $self->{option_results}->{no_ps}, + ); + + $self->{option_results}->{command_options} .= " " . $ps; + my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}); + if (defined($self->{option_results}->{ps_exec_only})) { + $self->{output}->output_add(severity => 'OK', + short_msg => $stdout); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($stdout); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + if (!defined($decoded->{LinkStatus})) { + $self->{output}->add_option_msg(short_msg => "No database replication"); + $self->{output}->option_exit(); + } + $self->{global}->{LinkStatus} = $map_link_status{$decoded->{LinkStatus}}; + + $self->{sites}->{$decoded->{Site1}} = { + display => $decoded->{Site1}, + SiteType => $map_type{$decoded->{SiteType1}}, + SiteStatus => $map_status{$decoded->{Site1Status}}, + SiteToSiteGlobalState => $decoded->{Site1ToSite2GlobalState}, + SiteToSiteGlobalSyncTime => $decoded->{Site1ToSite2GlobalSyncTime}, + }; + $self->{sites}->{$decoded->{Site2}} = { + display => $decoded->{Site2}, + SiteType => $map_type{$decoded->{SiteType2}}, + SiteStatus => $map_status{$decoded->{Site2Status}}, + SiteToSiteGlobalState => $decoded->{Site2ToSite1GlobalState}, + SiteToSiteGlobalSyncTime => $decoded->{Site2ToSite1GlobalSyncTime}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check database replication status. + +=over 8 + +=item B<--timeout> + +Set timeout time for command execution (Default: 30 sec) + +=item B<--no-ps> + +Don't encode powershell. To be used with --command and 'type' command. + +=item B<--command> + +Command to get information (Default: 'powershell.exe'). +Can be changed if you have output in a file. To be used with --no-ps option. + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: '-InputFormat none -NoLogo -EncodedCommand'). + +=item B<--ps-exec-only> + +Print powershell output. + +=item B<--warning-link-status> + +Set warning threshold for current synchronisation status (Default: '') +Can used special variables like: %{status}. + +=item B<--critical-link-status> + +Set critical threshold for current synchronisation status (Default: ''). +Can used special variables like: %{status}. + +=item B<--warning-site-status> + +Set warning threshold for current synchronisation status (Default: '') +Can used special variables like: %{status}, %{type}, %{site_to_site_state}, %{last_sync_time}. + +=item B<--critical-site-status> + +Set critical threshold for current synchronisation status (Default: ''). +Can used special variables like: %{status}, %{type}, %{site_to_site_state}, %{last_sync_time}. + +=back + +=cut diff --git a/apps/sccm/local/mode/sitestatus.pm b/apps/sccm/local/mode/sitestatus.pm new file mode 100644 index 000000000..81595c65b --- /dev/null +++ b/apps/sccm/local/mode/sitestatus.pm @@ -0,0 +1,239 @@ +# +# Copyright 2019 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 apps::sccm::local::mode::sitestatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use JSON::XS; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use centreon::common::powershell::sccm::sitestatus; + +my %map_mode = ( + 0 => 'Unknown', + 1 => 'Replication maintenance', + 2 => 'Recovery in progress', + 3 => 'Upgrade in progress', + 4 => 'Evaluation has expired', + 5 => 'Site expansion in progress', + 6 => 'Interop mode where there are primary sites, having the same version as the CAS, were not upgraded', + 7 => 'Interop mode where there are secondary sites, having the same version as the top-level site server, were not upgraded', +); +my %map_status = ( + 0 => 'Unknown', + 1 => 'ACTIVE', + 2 => 'PENDING', + 3 => 'FAILED', + 4 => 'DELETED', + 5 => 'UPGRADE', + 6 => 'Failed to delete or deinstall the secondary site', + 7 => 'Failed to upgrade the secondary site', + 8 => 'Secondary site recovery is in progress', + 9 => 'Failed to recover secondary site', +); +my %map_type = ( + 0 => 'Unknown', + 1 => 'SECONDARY', + 2 => 'PRIMARY', + 4 => 'CAS', +); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("status is '%s' [Type: %s] [Mode: '%s']", + $self->{result_values}->{status}, + $self->{result_values}->{type}, + $self->{result_values}->{mode}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{name} = $options{new_datas}->{$self->{instance} . '_SiteName'}; + $self->{result_values}->{type} = $options{new_datas}->{$self->{instance} . '_Type'}; + $self->{result_values}->{mode} = $options{new_datas}->{$self->{instance} . '_Mode'}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_Status'}; + $self->{result_values}->{secondary_site_status} = $options{new_datas}->{$self->{instance} . '_SecondarySiteCMUpdateStatus'}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'sites', type => 1, cb_prefix_output => 'prefix_output_site', message_multiple => 'All sites status are ok' }, + ]; + + $self->{maps_counters}->{sites} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'display' }, { name => 'SiteName' }, { name => 'Type' }, { name => 'Mode' }, + { name => 'Status' }, { name => 'SecondarySiteCMUpdateStatus' } ], + 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 => \&catalog_status_threshold, + } + }, + ]; +} + +sub prefix_output_site { + my ($self, %options) = @_; + + return "Site '" . $options{instance_value}->{display} . "' "; +} + +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 => { + "timeout:s" => { name => 'timeout', default => 30 }, + "command:s" => { name => 'command', default => 'powershell.exe' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, + "no-ps" => { name => 'no_ps' }, + "ps-exec-only" => { name => 'ps_exec_only' }, + "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); + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $ps = centreon::common::powershell::sccm::sitestatus::get_powershell( + no_ps => $self->{option_results}->{no_ps}, + ); + + $self->{option_results}->{command_options} .= " " . $ps; + my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}); + if (defined($self->{option_results}->{ps_exec_only})) { + $self->{output}->output_add(severity => 'OK', + short_msg => $stdout); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($stdout); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + if (ref($decoded) eq "ARRAY") { + foreach my $site (@{$decoded}) { + $self->{sites}->{$site->{SiteCode}} = { + display => $site->{SiteCode}, + SiteName => $site->{SiteName}, + Type => $map_type{$site->{Type}}, + Mode => $map_mode{$site->{Mode}}, + Status => $map_status{$site->{Status}}, + SecondarySiteCMUpdateStatus => $site->{SecondarySiteCMUpdateStatus}, + }; + } + } else { + $self->{sites}->{$decoded->{SiteCode}} = { + display => $decoded->{SiteCode}, + SiteName => $decoded->{SiteName}, + Type => $map_type{$decoded->{Type}}, + Mode => $map_mode{$decoded->{Mode}}, + Status => $map_status{$decoded->{Status}}, + SecondarySiteCMUpdateStatus => $decoded->{SecondarySiteCMUpdateStatus}, + }; + } + + if (scalar(keys %{$self->{sites}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No sites found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check sites status. + +=over 8 + +=item B<--timeout> + +Set timeout time for command execution (Default: 30 sec) + +=item B<--no-ps> + +Don't encode powershell. To be used with --command and 'type' command. + +=item B<--command> + +Command to get information (Default: 'powershell.exe'). +Can be changed if you have output in a file. To be used with --no-ps option. + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: '-InputFormat none -NoLogo -EncodedCommand'). + +=item B<--ps-exec-only> + +Print powershell output. + +=item B<--warning-status> + +Set warning threshold for current synchronisation status (Default: ''). +Can used special variables like: %{status}, %{mode}, %{type}, %{name}. + +=item B<--critical-status> + +Set critical threshold for current synchronisation status (Default: ''). +Can used special variables like: %{status}, %{mode}, %{type}, %{name}. + +=back + +=cut diff --git a/apps/sccm/local/plugin.pm b/apps/sccm/local/plugin.pm new file mode 100644 index 000000000..8e2f4170b --- /dev/null +++ b/apps/sccm/local/plugin.pm @@ -0,0 +1,49 @@ +# +# Copyright 2019 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 apps::sccm::local::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_simple); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'database-replication-status' => 'apps::sccm::local::mode::databasereplicationstatus', + 'site-status' => 'apps::sccm::local::mode::sitestatus', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check SCCM through powershell. + +=cut diff --git a/apps/slack/restapi/custom/api.pm b/apps/slack/restapi/custom/api.pm index da5526c36..e01afe177 100644 --- a/apps/slack/restapi/custom/api.pm +++ b/apps/slack/restapi/custom/api.pm @@ -40,23 +40,20 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port' }, - "proto:s" => { name => 'proto' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "api-path:s" => { name => 'api_path' }, - "api-token:s" => { name => 'api_token' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "timeout:s" => { name => 'timeout' }, + "api-path:s" => { name => 'api_path' }, + "api-token:s" => { name => 'api_token' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; @@ -91,8 +88,6 @@ sub check_options { $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : undef; $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? $self->{option_results}->{proxyurl} : undef; - $self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef; $self->{api_path} = (defined($self->{option_results}->{api_path})) ? $self->{option_results}->{api_path} : '/api'; $self->{api_token} = (defined($self->{option_results}->{api_token})) ? $self->{option_results}->{api_token} : undef; @@ -115,8 +110,6 @@ sub build_options_for_httplib { $self->{option_results}->{port} = $self->{port}; $self->{option_results}->{proto} = $self->{proto}; $self->{option_results}->{timeout} = $self->{timeout}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; - $self->{option_results}->{ssl_opt} = $self->{ssl_opt}; $self->{option_results}->{warning_status} = ''; $self->{option_results}->{critical_status} = ''; } @@ -140,7 +133,6 @@ sub request_api { my $content = $self->{http}->request(method => $options{method}, url_path => $self->{api_path} . $options{url_path}, query_form_post => $options{query_form_post}, critical_status => '', warning_status => '', unknown_status => ''); - my $response = $self->{http}->get_response(); my $decoded; eval { $decoded = decode_json($content); @@ -218,19 +210,10 @@ Slack API port Specify https if needed (Default: 'https') -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (Examples: --ssl-opt="SSL_version => TLSv1" ---ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/apps/slack/restapi/mode/countchannels.pm b/apps/slack/restapi/mode/countchannels.pm index 44a8d6ca3..988adfa7c 100644 --- a/apps/slack/restapi/mode/countchannels.pm +++ b/apps/slack/restapi/mode/countchannels.pm @@ -66,22 +66,22 @@ sub set_counters { sub custom_info_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{name} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - - $self->{output}->perfdata_add(label => 'members' . $extra_label, - value => $self->{result_values}->{num_members}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}), - min => 0); + $self->{output}->perfdata_add( + label => 'members', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{name} : undef, + value => $self->{result_values}->{num_members}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0 + ); } sub custom_info_threshold { my ($self, %options) = @_; my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{num_members}, - threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, - { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -108,10 +108,9 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-channel:s" => { name => 'filter_channel' }, - }); + $options{options}->add_options(arguments => { + "filter-channel:s" => { name => 'filter_channel' }, + }); return $self; } diff --git a/apps/squid/snmp/mode/cacheusage.pm b/apps/squid/snmp/mode/cacheusage.pm new file mode 100644 index 000000000..d2a435361 --- /dev/null +++ b/apps/squid/snmp/mode/cacheusage.pm @@ -0,0 +1,136 @@ +# +# Copyright 2019 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 apps::squid::snmp::mode::cacheusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, message_separator => ' - ', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'cpu', set => { + key_values => [ { name => 'cacheCpuUsage' } ], + output_template => 'Cpu usage : %s %%', + perfdatas => [ + { label => 'cpu', value => 'cacheCpuUsage_absolute', template => '%s', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'memory', set => { + key_values => [ { name => 'cacheMemUsage' } ], + output_template => 'Memory usage : %s %s', + output_change_bytes => 1, + perfdatas => [ + { label => 'memory', value => 'cacheMemUsage_absolute', template => '%s', + min => 0, unit => 'B' }, + ], + } + }, + { label => 'fd', set => { + key_values => [ { name => 'cacheCurrentFileDescrCnt' } ], + output_template => 'Number of file descriptors : %s', + perfdatas => [ + { label => 'fd', value => 'cacheCurrentFileDescrCnt_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'object', set => { + key_values => [ { name => 'cacheNumObjCount' } ], + output_template => 'Number of object stored : %s', + perfdatas => [ + { label => 'objects', value => 'cacheNumObjCount_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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my %oids = ( + cacheMemUsage => '.1.3.6.1.4.1.3495.1.3.1.3.0', + cacheCpuUsage => '.1.3.6.1.4.1.3495.1.3.1.5.0', + cacheNumObjCount => '.1.3.6.1.4.1.3495.1.3.1.7.0', + cacheCurrentFileDescrCnt => '.1.3.6.1.4.1.3495.1.3.1.12.0', + ); + my $snmp_result = $options{snmp}->get_leef(oids => [ + values %oids + ], nothing_quit => 1); + + $snmp_result->{$oids{cacheMemUsage}} *= 1024; + $self->{global} = {}; + foreach (keys %oids) { + $self->{global}->{$_} = $snmp_result->{$oids{$_}} if (defined($snmp_result->{$oids{$_}})); + } +} + +1; + +__END__ + +=head1 MODE + +Check cache usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^(cpu)$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'cpu', 'memory', 'fd', 'object'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'cpu', 'memory', 'fd', 'object'. + +=back + +=cut diff --git a/apps/squid/snmp/mode/protocolstats.pm b/apps/squid/snmp/mode/protocolstats.pm new file mode 100644 index 000000000..5a88020a2 --- /dev/null +++ b/apps/squid/snmp/mode/protocolstats.pm @@ -0,0 +1,250 @@ +# +# Copyright 2019 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 apps::squid::snmp::mode::protocolstats; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub custom_data_calc { + my ($self, %options) = @_; + + my $delta_value = $options{new_datas}->{$self->{instance} . '_cacheHttpHits'} - $options{old_datas}->{$self->{instance} . '_cacheHttpHits'}; + my $delta_total = $options{new_datas}->{$self->{instance} . '_cacheProtoClientHttpRequests'} - $options{old_datas}->{$self->{instance} . '_cacheProtoClientHttpRequests'}; + + $self->{result_values}->{hits_prct} = 100; + if ($delta_total > 0) { + $self->{result_values}->{hits_prct} = $delta_value * 100 / $delta_total; + } + return 0; +} + + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global_http', type => 0, cb_prefix_output => 'prefix_http_output', skipped_code => { -10 => 1 } }, + { name => 'global_icp', type => 0, cb_prefix_output => 'prefix_icp_output', skipped_code => { -10 => 1 } }, + { name => 'global', type => 0, cb_prefix_output => 'prefix_server_output', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global_http} = [ + { label => 'http-hits-rate', set => { + key_values => [ { name => 'cacheProtoClientHttpRequests', diff => 1 }, { name => 'cacheHttpHits', diff => 1 } ], + closure_custom_calc => $self->can('custom_data_calc'), + output_template => 'hits rate : %.2f %%', output_use => 'hits_prct', threshold_use => 'hits_prct', + perfdatas => [ + { label => 'http_hits_rate', value => 'hits_prct', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'http-errors', set => { + key_values => [ { name => 'cacheHttpErrors', diff => 1 } ], + output_template => 'errors : %s', + perfdatas => [ + { label => 'http_errors', value => 'cacheHttpErrors_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'http-traffic-in', set => { + key_values => [ { name => 'cacheHttpInKb', diff => 1 } ], + output_template => 'traffic in : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'http_traffic_in', value => 'cacheHttpInKb_per_second', template => '%s', + min => 0, unit => 'b/s' }, + ], + } + }, + { label => 'http-traffic-out', set => { + key_values => [ { name => 'cacheHttpOutKb', diff => 1 } ], + output_template => 'traffic Out : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'http_traffic_out', value => 'cacheHttpOutKb_per_second', template => '%s', + min => 0, unit => 'b/s' }, + ], + } + }, + ]; + + $self->{maps_counters}->{global_icp} = [ + { label => 'icp-traffic-in', set => { + key_values => [ { name => 'cacheIcpKbRecv', diff => 1 } ], + output_template => 'traffic in : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'icp_traffic_in', value => 'cacheIcpKbRecv_per_second', template => '%s', + min => 0, unit => 'b/s' }, + ], + } + }, + { label => 'icp-traffic-out', set => { + key_values => [ { name => 'cacheIcpKbSent', diff => 1 } ], + output_template => 'traffic Out : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'icp_traffic_out', value => 'cacheIcpKbSent_per_second', template => '%s', + min => 0, unit => 'b/s' }, + ], + } + }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'server-traffic-in', set => { + key_values => [ { name => 'cacheServerInKb', diff => 1 } ], + output_template => 'traffic in : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'server_traffic_in', value => 'cacheServerInKb_per_second', template => '%s', + min => 0, unit => 'b/s' }, + ], + } + }, + { label => 'server-traffic-out', set => { + key_values => [ { name => 'cacheServerOutKb', diff => 1 } ], + output_template => 'traffic Out : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'server_traffic_out', value => 'cacheServerOutKb_per_second', template => '%s', + min => 0, unit => 'b/s' }, + ], + } + }, + { label => 'clients', set => { + key_values => [ { name => 'cacheClients' } ], + output_template => 'current number of clients : %s', + perfdatas => [ + { label => 'clients', value => 'cacheClients_absolute', template => '%s', + min => 0 }, + ], + } + }, + ]; +} + +sub prefix_http_output { + my ($self, %options) = @_; + + return "HTTP "; +} + +sub prefix_icp_output { + my ($self, %options) = @_; + + return "ICP "; +} + +sub prefix_server_output { + my ($self, %options) = @_; + + return "Server "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my %oids = ( + cacheProtoClientHttpRequests => '.1.3.6.1.4.1.3495.1.3.2.1.1.0', + cacheHttpHits => '.1.3.6.1.4.1.3495.1.3.2.1.2.0', + cacheHttpErrors => '.1.3.6.1.4.1.3495.1.3.2.1.3.0', + cacheHttpInKb => '.1.3.6.1.4.1.3495.1.3.2.1.4.0', + cacheHttpOutKb => '.1.3.6.1.4.1.3495.1.3.2.1.5.0', + cacheIcpKbSent => '.1.3.6.1.4.1.3495.1.3.2.1.8.0', + cacheIcpKbRecv => '.1.3.6.1.4.1.3495.1.3.2.1.9.0', + cacheServerInKb => '.1.3.6.1.4.1.3495.1.3.2.1.12.0', + cacheServerOutKb => '.1.3.6.1.4.1.3495.1.3.2.1.13.0', + cacheClients => '.1.3.6.1.4.1.3495.1.3.2.1.15.0', + ); + my $snmp_result = $options{snmp}->get_leef(oids => [ + values %oids + ], nothing_quit => 1); + + $self->{global_http} = { + cacheProtoClientHttpRequests => $snmp_result->{$oids{cacheProtoClientHttpRequests}}, + cacheHttpHits => $snmp_result->{$oids{cacheHttpHits}}, + cacheHttpErrors => $snmp_result->{$oids{cacheHttpErrors}}, + cacheHttpInKb => $snmp_result->{$oids{cacheHttpInKb}} * 1024 * 8, + cacheHttpOutKb => $snmp_result->{$oids{cacheHttpOutKb}} * 1024 * 8, + }; + $self->{global_icp} = { + cacheIcpKbSent => $snmp_result->{$oids{cacheIcpKbSent}} * 1024 * 8, + cacheIcpKbRecv => $snmp_result->{$oids{cacheIcpKbRecv}} * 1024 * 8, + }; + $self->{global} = { + cacheServerInKb => $snmp_result->{$oids{cacheServerInKb}} * 1024 * 8, + cacheServerOutKb => $snmp_result->{$oids{cacheServerOutKb}} * 1024 * 8, + cacheClients => $snmp_result->{$oids{cacheClients}}, + }; + + $self->{cache_name} = "squid_" . $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')); +} + +1; + +__END__ + +=head1 MODE + +Check protocol statistics. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='http' + +=item B<--warning-*> + +Threshold warning. +Can be: 'http-hits-rate', 'http-errors', 'http-traffic-in', 'http-traffic-out', +'icp-traffic-in', 'icp-traffic-out', 'server-traffic-in', 'server-traffic-out', +'clients'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'http-hits-rate', 'http-errors', 'http-traffic-in', 'http-traffic-out', +'icp-traffic-in', 'icp-traffic-out', 'server-traffic-in', 'server-traffic-out', +'clients'. + +=back + +=cut diff --git a/apps/squid/snmp/plugin.pm b/apps/squid/snmp/plugin.pm new file mode 100644 index 000000000..ae0c4b96e --- /dev/null +++ b/apps/squid/snmp/plugin.pm @@ -0,0 +1,49 @@ +# +# Copyright 2019 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 apps::squid::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}} = ( + 'cache-usage' => 'apps::squid::snmp::mode::cacheusage', + 'protocol-stats' => 'apps::squid::snmp::mode::protocolstats', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Squid proxy in SNMP. + +=cut diff --git a/apps/tomcat/jmx/mode/connectorusage.pm b/apps/tomcat/jmx/mode/connectorusage.pm index 086cee978..0d458f56f 100644 --- a/apps/tomcat/jmx/mode/connectorusage.pm +++ b/apps/tomcat/jmx/mode/connectorusage.pm @@ -26,8 +26,6 @@ use strict; use warnings; use Digest::MD5 qw(md5_hex); -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -91,38 +89,38 @@ sub custom_usage_perfdata { my ($self, %options) = @_; my $use_th = 1; - $use_th = 0 if ($instance_mode->{option_results}->{units} eq '%' && $self->{result_values}->{max} <= 0); - - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + $use_th = 0 if ($self->{instance_mode}->{option_results}->{units} eq '%' && $self->{result_values}->{max} <= 0); my $value_perf = $self->{result_values}->{used}; my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%' && $self->{result_values}->{max} > 0) { + if ($self->{instance_mode}->{option_results}->{units} eq '%' && $self->{result_values}->{max} > 0) { $total_options{total} = $self->{result_values}->{max}; $total_options{cast_int} = 1; } my $label = $self->{label}; $label =~ s/-/_/g; - $self->{output}->perfdata_add(label => $label . $extra_label, - value => $value_perf, - warning => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options) : undef, - critical => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options) : undef, - min => 0, max => $self->{result_values}->{max} > 0 ? $self->{result_values}->{max} : undef); + $self->{output}->perfdata_add( + label => $label, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options) : undef, + critical => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options) : undef, + min => 0, max => $self->{result_values}->{max} > 0 ? $self->{result_values}->{max} : undef + ); } sub custom_usage_threshold { my ($self, %options) = @_; # Cannot use percent without total - return 'ok' if ($self->{result_values}->{max} <= 0 && $instance_mode->{option_results}->{units} eq '%'); + return 'ok' if ($self->{result_values}->{max} <= 0 && $self->{instance_mode}->{option_results}->{units} eq '%'); my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -167,19 +165,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "units:s" => { name => 'units', default => '%' }, - }); - return $self; -} + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + }); -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; + return $self; } sub manage_selection { diff --git a/apps/tomcat/jmx/mode/datasourceusage.pm b/apps/tomcat/jmx/mode/datasourceusage.pm index 12b62c9b2..46b355ac4 100644 --- a/apps/tomcat/jmx/mode/datasourceusage.pm +++ b/apps/tomcat/jmx/mode/datasourceusage.pm @@ -26,8 +26,6 @@ use strict; use warnings; use Digest::MD5 qw(md5_hex); -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -61,38 +59,38 @@ sub custom_usage_perfdata { my ($self, %options) = @_; my $use_th = 1; - $use_th = 0 if ($instance_mode->{option_results}->{units} eq '%' && $self->{result_values}->{max} <= 0); - - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + $use_th = 0 if ($self->{instance_mode}->{option_results}->{units} eq '%' && $self->{result_values}->{max} <= 0); my $value_perf = $self->{result_values}->{used}; my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%' && $self->{result_values}->{max} > 0) { + if ($self->{instance_mode}->{option_results}->{units} eq '%' && $self->{result_values}->{max} > 0) { $total_options{total} = $self->{result_values}->{max}; $total_options{cast_int} = 1; } my $label = $self->{label}; $label =~ s/-/_/g; - $self->{output}->perfdata_add(label => $label . $extra_label, - value => $value_perf, - warning => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options) : undef, - critical => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options) : undef, - min => 0, max => $self->{result_values}->{max} > 0 ? $self->{result_values}->{max} : undef); + $self->{output}->perfdata_add( + label => $label, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options) : undef, + critical => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options) : undef, + min => 0, max => $self->{result_values}->{max} > 0 ? $self->{result_values}->{max} : undef + ); } sub custom_usage_threshold { my ($self, %options) = @_; # Cannot use percent without total - return 'ok' if ($self->{result_values}->{max} <= 0 && $instance_mode->{option_results}->{units} eq '%'); + return 'ok' if ($self->{result_values}->{max} <= 0 && $self->{instance_mode}->{option_results}->{units} eq '%'); my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -137,19 +135,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "units:s" => { name => 'units', default => '%' }, - }); - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + }); - $instance_mode = $self; + return $self; } sub manage_selection { diff --git a/apps/tomcat/jmx/mode/webappssessions.pm b/apps/tomcat/jmx/mode/webappssessions.pm index 27ee8f9f9..790180e6a 100644 --- a/apps/tomcat/jmx/mode/webappssessions.pm +++ b/apps/tomcat/jmx/mode/webappssessions.pm @@ -26,8 +26,6 @@ use strict; use warnings; use Digest::MD5 qw(md5_hex); -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -61,38 +59,38 @@ sub custom_usage_perfdata { my ($self, %options) = @_; my $use_th = 1; - $use_th = 0 if ($instance_mode->{option_results}->{units} eq '%' && $self->{result_values}->{max} <= 0); - - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + $use_th = 0 if ($self->{instance_mode}->{option_results}->{units} eq '%' && $self->{result_values}->{max} <= 0); my $value_perf = $self->{result_values}->{used}; my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%' && $self->{result_values}->{max} > 0) { + if ($self->{instance_mode}->{option_results}->{units} eq '%' && $self->{result_values}->{max} > 0) { $total_options{total} = $self->{result_values}->{max}; $total_options{cast_int} = 1; } my $label = $self->{label}; $label =~ s/-/_/g; - $self->{output}->perfdata_add(label => $label . $extra_label, - value => $value_perf, - warning => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options) : undef, - critical => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options) : undef, - min => 0, max => $self->{result_values}->{max} > 0 ? $self->{result_values}->{max} : undef); + $self->{output}->perfdata_add( + label => $label, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options) : undef, + critical => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options) : undef, + min => 0, max => $self->{result_values}->{max} > 0 ? $self->{result_values}->{max} : undef + ); } sub custom_usage_threshold { my ($self, %options) = @_; # Cannot use percent without total - return 'ok' if ($self->{result_values}->{max} <= 0 && $instance_mode->{option_results}->{units} eq '%'); + return 'ok' if ($self->{result_values}->{max} <= 0 && $self->{instance_mode}->{option_results}->{units} eq '%'); my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -136,19 +134,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "units:s" => { name => 'units', default => '%' }, - }); - return $self; -} + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + }); -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; + return $self; } sub manage_selection { diff --git a/apps/tomcat/web/mode/applications.pm b/apps/tomcat/web/mode/applications.pm index 1d909cca9..8ede76459 100644 --- a/apps/tomcat/web/mode/applications.pm +++ b/apps/tomcat/web/mode/applications.pm @@ -31,27 +31,24 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '8080' }, - "proto:s" => { name => 'proto' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "urlpath:s" => { name => 'url_path', default => '/manager/text/list' }, - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - "filter-path:s" => { name => 'filter_path', }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', default => '8080' }, + "proto:s" => { name => 'proto' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + "urlpath:s" => { name => 'url_path', default => '/manager/text/list' }, + "name:s" => { name => 'name' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + "filter-path:s" => { name => 'filter_path', }, + }); $self->{result} = {}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -126,11 +123,14 @@ sub run { $self->{result}->{$name}->{state})); } - my $extra_label = ''; + my $extra_label; $extra_label = '_' . $name if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})); - $self->{output}->perfdata_add(label => 'status' . $extra_label, - value => sprintf("%.1f", $staterc), - min => 0); + $self->{output}->perfdata_add( + label => 'status', + instances => $extra_label, + value => sprintf("%.1f", $staterc), + min => 0 + ); }; $self->{output}->display(); @@ -155,10 +155,6 @@ IP Address or FQDN of the Tomcat Application Server Port used by Tomcat -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Protocol used http or https @@ -187,10 +183,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--urlpath> Path to the Tomcat Manager List (Default: Tomcat 7 '/manager/text/list') diff --git a/apps/tomcat/web/mode/listapplication.pm b/apps/tomcat/web/mode/listapplication.pm index 57ad1d817..3b4396cbe 100644 --- a/apps/tomcat/web/mode/listapplication.pm +++ b/apps/tomcat/web/mode/listapplication.pm @@ -31,26 +31,23 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '8080' }, - "proto:s" => { name => 'proto' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "urlpath:s" => { name => 'url_path', default => '/manager/text/list' }, - "filter-name:s" => { name => 'filter_name', }, - "filter-state:s" => { name => 'filter_state', }, - "filter-path:s" => { name => 'filter_path', }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', default => '8080' }, + "proto:s" => { name => 'proto' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + "urlpath:s" => { name => 'url_path', default => '/manager/text/list' }, + "filter-name:s" => { name => 'filter_name', }, + "filter-state:s" => { name => 'filter_state', }, + "filter-path:s" => { name => 'filter_path', }, + }); $self->{result} = {}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -138,10 +135,6 @@ IP Address or FQDN of the Tomcat Application Server Port used by Tomcat -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Protocol used http or https @@ -170,10 +163,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--url-path> Path to the Tomcat Manager List (Default: Tomcat 7 '/manager/text/list') diff --git a/apps/tomcat/web/mode/memory.pm b/apps/tomcat/web/mode/memory.pm index 61f316f9f..297651586 100644 --- a/apps/tomcat/web/mode/memory.pm +++ b/apps/tomcat/web/mode/memory.pm @@ -32,25 +32,22 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '8080' }, - "proto:s" => { name => 'proto' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "urlpath:s" => { name => 'url_path', default => '/manager/status?XML=true' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', default => '8080' }, + "proto:s" => { name => 'proto' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + "urlpath:s" => { name => 'url_path', default => '/manager/status?XML=true' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); $self->{result} = {}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -190,10 +187,6 @@ IP Address or FQDN of the Tomcat Application Server Port used by Tomcat -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Protocol used http or https @@ -222,10 +215,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--urlpath> Path to the Tomcat Manager XML (Default: '/manager/status?XML=true') diff --git a/apps/tomcat/web/mode/requestinfo.pm b/apps/tomcat/web/mode/requestinfo.pm index d36150e64..01e66073d 100644 --- a/apps/tomcat/web/mode/requestinfo.pm +++ b/apps/tomcat/web/mode/requestinfo.pm @@ -35,36 +35,33 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '8080' }, - "proto:s" => { name => 'proto' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "urlpath:s" => { name => 'url_path', default => '/manager/status?XML=true' }, - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - "warning-maxtime:s" => { name => 'warning_maxtime' }, - "critical-maxtime:s" => { name => 'critical_maxtime' }, - "warning-processingtime:s" => { name => 'warning_processingtime' }, - "critical-processingtime:s" => { name => 'critical_processingtime' }, - "warning-requestcount:s" => { name => 'warning_requestcount' }, - "critical-requestcount:s" => { name => 'critical_requestcount' }, - "warning-errorcount:s" => { name => 'warning_errorcount' }, - "critical-errorcount:s" => { name => 'critical_errorcount' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', default => '8080' }, + "proto:s" => { name => 'proto' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + "urlpath:s" => { name => 'url_path', default => '/manager/status?XML=true' }, + "name:s" => { name => 'name' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + "warning-maxtime:s" => { name => 'warning_maxtime' }, + "critical-maxtime:s" => { name => 'critical_maxtime' }, + "warning-processingtime:s" => { name => 'warning_processingtime' }, + "critical-processingtime:s" => { name => 'critical_processingtime' }, + "warning-requestcount:s" => { name => 'warning_requestcount' }, + "critical-requestcount:s" => { name => 'critical_requestcount' }, + "warning-errorcount:s" => { name => 'warning_errorcount' }, + "critical-errorcount:s" => { name => 'critical_errorcount' }, + }); $self->{result} = {}; $self->{hostname} = undef; $self->{statefile_value} = centreon::plugins::statefile->new(%options); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -278,30 +275,41 @@ sub run { $requestInfo_errorCount_absolute_per_sec)); } - my $extra_label = ''; + my $extra_label; $extra_label = '_' . $name if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})); - $self->{output}->perfdata_add(label => 'maxTime' . $extra_label, - value => sprintf("%.2f", $self->{result}->{$name}->{requestInfo_maxTime}), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + $self->{output}->perfdata_add( + label => 'maxTime', + instances => $extra_label, + value => sprintf("%.2f", $self->{result}->{$name}->{requestInfo_maxTime}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0 + ); - $self->{output}->perfdata_add(label => 'processingTime' . $extra_label, - value => sprintf("%.3f", $requestInfo_processingTime_absolute_per_sec), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); - - $self->{output}->perfdata_add(label => 'requestCount' . $extra_label, - value => sprintf("%.2f", $requestInfo_requestCount_absolute_per_sec), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); - $self->{output}->perfdata_add(label => 'errorCount' . $extra_label, - value => sprintf("%.2f", $requestInfo_errorCount_absolute_per_sec), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + $self->{output}->perfdata_add( + label => 'processingTime', + instances => $extra_label, + value => sprintf("%.3f", $requestInfo_processingTime_absolute_per_sec), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0 + ); + $self->{output}->perfdata_add( + label => 'requestCount', + instances => $extra_label, + value => sprintf("%.2f", $requestInfo_requestCount_absolute_per_sec), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0 + ); + $self->{output}->perfdata_add( + label => 'errorCount', + instances => $extra_label, + value => sprintf("%.2f", $requestInfo_errorCount_absolute_per_sec), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0 + ); }; $self->{statefile_value}->write(data => $new_datas); @@ -332,10 +340,6 @@ IP Address or FQDN of the Tomcat Application Server Port used by Tomcat -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Protocol used http or https @@ -364,10 +368,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--urlpath> Path to the Tomcat Manager XML (Default: '/manager/status?XML=true') diff --git a/apps/tomcat/web/mode/sessions.pm b/apps/tomcat/web/mode/sessions.pm index f6cc0c94a..61bc891a2 100644 --- a/apps/tomcat/web/mode/sessions.pm +++ b/apps/tomcat/web/mode/sessions.pm @@ -31,30 +31,27 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '8080' }, - "proto:s" => { name => 'proto' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "urlpath:s" => { name => 'url_path', default => '/manager/text/list' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - "filter-state:s" => { name => 'filter_state' }, - "filter-path:s" => { name => 'filter_path', }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', default => '8080' }, + "proto:s" => { name => 'proto' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + "urlpath:s" => { name => 'url_path', default => '/manager/text/list' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "name:s" => { name => 'name' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + "filter-state:s" => { name => 'filter_state' }, + "filter-path:s" => { name => 'filter_path', }, + }); $self->{result} = {}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -127,13 +124,16 @@ sub run { $self->{result}->{$name}->{sessions})); } - my $extra_label = ''; + my $extra_label; $extra_label = '_' . $name if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})); - $self->{output}->perfdata_add(label => 'sessions' . $extra_label, - value => sprintf("%.2f", $self->{result}->{$name}->{sessions}), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + $self->{output}->perfdata_add( + label => 'sessions', + instances => $extra_label, + value => sprintf("%.2f", $self->{result}->{$name}->{sessions}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0 + ); }; $self->{output}->display(); @@ -158,10 +158,6 @@ IP Address or FQDN of the Tomcat Application Server Port used by Tomcat -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Protocol used http or https @@ -190,10 +186,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--urlpath> Path to the Tomcat Manager List (Default: Tomcat 7 '/manager/text/list') diff --git a/apps/tomcat/web/mode/threads.pm b/apps/tomcat/web/mode/threads.pm index aa5382f1c..9385d23a4 100644 --- a/apps/tomcat/web/mode/threads.pm +++ b/apps/tomcat/web/mode/threads.pm @@ -33,29 +33,26 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '8080' }, - "proto:s" => { name => 'proto' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "urlpath:s" => { name => 'url_path', default => '/manager/status?XML=true' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', default => '8080' }, + "proto:s" => { name => 'proto' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + "urlpath:s" => { name => 'url_path', default => '/manager/status?XML=true' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "name:s" => { name => 'name' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + }); $self->{result} = {}; $self->{hostname} = undef; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -187,21 +184,27 @@ sub run { $self->{result}->{$name}->{currentThreadsBusy})); } - my $extra_label = ''; + my $extra_label; $extra_label = '_' . $name if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})); - $self->{output}->perfdata_add(label => 'currentThreadsBusy' . $extra_label, - value => $self->{result}->{$name}->{currentThreadsBusy}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0, - max => $self->{result}->{$name}->{maxThreads}); + $self->{output}->perfdata_add( + label => 'currentThreadsBusy', + instances => $extra_label, + value => $self->{result}->{$name}->{currentThreadsBusy}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, + max => $self->{result}->{$name}->{maxThreads} + ); - $self->{output}->perfdata_add(label => 'currentThreadCount' . $extra_label, - value => $self->{result}->{$name}->{currentThreadCount}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0, - max => $self->{result}->{$name}->{maxThreads}); + $self->{output}->perfdata_add( + label => 'currentThreadCount', + instances => $extra_label, + value => $self->{result}->{$name}->{currentThreadCount}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, + max => $self->{result}->{$name}->{maxThreads} + ); }; $self->{output}->display(); @@ -226,10 +229,6 @@ IP Address or FQDN of the Tomcat Application Server Port used by Tomcat -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Protocol used http or https @@ -258,10 +257,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--urlpath> Path to the Tomcat Manager XML (Default: '/manager/status?XML=true') diff --git a/apps/tomcat/web/mode/traffic.pm b/apps/tomcat/web/mode/traffic.pm index 5d533209a..edeadefc8 100644 --- a/apps/tomcat/web/mode/traffic.pm +++ b/apps/tomcat/web/mode/traffic.pm @@ -29,8 +29,6 @@ use Digest::MD5 qw(md5_hex); use XML::XPath; use URI::Escape; -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -63,35 +61,33 @@ sub set_counters { 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}); + if ($self->{instance_mode}->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); + } elsif ($self->{instance_mode}->{option_results}->{units_traffic} eq 'b/s') { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}); } - $self->{output}->perfdata_add(label => 'traffic_' . $self->{result_values}->{label} . $extra_label, unit => 'b/s', - value => sprintf("%.2f", $self->{result_values}->{traffic}), - warning => $warning, - critical => $critical, - min => 0, max => $self->{result_values}->{speed}); + $self->{output}->perfdata_add( + label => 'traffic_' . $self->{result_values}->{label}, unit => 'b/s', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{traffic}), + 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}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + if ($self->{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->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); + } elsif ($self->{instance_mode}->{option_results}->{units_traffic} eq 'b/s') { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } return $exit; } @@ -119,9 +115,9 @@ sub custom_traffic_calc { $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; my $diff_traffic = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label}} - $options{old_datas}->{$self->{instance} . '_' . $self->{result_values}->{label}}; $self->{result_values}->{traffic} = $diff_traffic / $options{delta_time}; - if (defined($instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}}) && $instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} =~ /[0-9]/) { - $self->{result_values}->{traffic_prct} = $self->{result_values}->{traffic} * 100 / ($instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000); - $self->{result_values}->{speed} = $instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000; + if (defined($self->{instance_mode}->{option_results}->{'speed_' . $self->{result_values}->{label}}) && $self->{instance_mode}->{option_results}->{'speed_' . $self->{result_values}->{label}} =~ /[0-9]/) { + $self->{result_values}->{traffic_prct} = $self->{result_values}->{traffic} * 100 / ($self->{instance_mode}->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000); + $self->{result_values}->{speed} = $self->{instance_mode}->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000; } return 0; } @@ -138,26 +134,23 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '8080' }, - "proto:s" => { name => 'proto' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "urlpath:s" => { name => 'url_path', default => '/manager/status?XML=true' }, - "filter-name:s" => { name => 'filter_name' }, - "speed-in:s" => { name => 'speed_in' }, - "speed-out:s" => { name => 'speed_out' }, - "units-traffic:s" => { name => 'units_traffic', default => '%' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', default => '8080' }, + "proto:s" => { name => 'proto' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + "urlpath:s" => { name => 'url_path', default => '/manager/status?XML=true' }, + "filter-name:s" => { name => 'filter_name' }, + "speed-in:s" => { name => 'speed_in' }, + "speed-out:s" => { name => 'speed_out' }, + "units-traffic:s" => { name => 'units_traffic', default => '%' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -171,7 +164,6 @@ sub check_options { } $self->{http}->set_options(%{$self->{option_results}}); - $instance_mode = $self; } my %xpath_to_check = ( @@ -285,10 +277,6 @@ IP Address or FQDN of the Tomcat Application Server Port used by Tomcat -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Protocol used http or https @@ -317,10 +305,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--urlpath> Path to the Tomcat Manager XML (Default: '/manager/status?XML=true') diff --git a/apps/toshiba/storemate/sql/mode/maintenanceplan.pm b/apps/toshiba/storemate/sql/mode/maintenanceplan.pm index 93060e984..e11d0a72f 100644 --- a/apps/toshiba/storemate/sql/mode/maintenanceplan.pm +++ b/apps/toshiba/storemate/sql/mode/maintenanceplan.pm @@ -27,6 +27,7 @@ use warnings; use centreon::plugins::misc; use centreon::plugins::statefile; use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use DateTime; sub custom_status_output { my ($self, %options) = @_; @@ -116,13 +117,13 @@ sub manage_selection { } my ($i, $current_time) = (1, time()); - my $tz = centreon::plugins::misc::set_timezone(name => $self->{option_results}->{timezone})); + my $tz = centreon::plugins::misc::set_timezone(name => $self->{option_results}->{timezone}); while (my $row = $self->{sql}->fetchrow_hashref()) { # date form: 2017-09-22 01:01:08.133 $row->{LOGDATE} =~ /^(\d+)-(\d+)-(\d+)\s+(\d+)[:\/](\d+)[:\/](\d+)/; my $dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6, - %tz); + %$tz); next if (defined($self->{option_results}->{memory}) && defined($last_time) && $last_time > $dt->epoch); diff --git a/apps/varnish/local/mode/backend.pm b/apps/varnish/local/mode/backend.pm deleted file mode 100644 index 52860546d..000000000 --- a/apps/varnish/local/mode/backend.pm +++ /dev/null @@ -1,242 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::backend; - -use base qw(centreon::plugins::templates::counter); -use strict; -use warnings; -use Digest::MD5 qw(md5_hex); -use JSON; - -sub set_counters { - my ($self, %options) = @_; - - $self->{maps_counters_type} = [ - { name => 'backend', type => 0, skipped_code => { -10 => 1 } }, - ]; - $self->{maps_counters}->{backend} = [ - { label => 'conn', set => { - key_values => [ { name => 'backend_conn', diff => 1 } ], - output_template => 'Backend con: %.2f/s', output_error_template => "Backend con: %s", - per_second => 1, - perfdatas => [ - { label => 'backend_conn', value => 'backend_conn_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'unhealthy', set => { - key_values => [ { name => 'backend_unhealthy', diff => 1 } ], - output_template => 'Backend unhealthy: %.2f/s', output_error_template => "Backend unhealthy: %s", - per_second => 1, - perfdatas => [ - { label => 'backend_unhealthy', value => 'backend_unhealthy_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'busy', set => { - key_values => [ { name => 'backend_busy', diff => 1 } ], - output_template => 'Backend busy: %.2f/s', output_error_template => "Backend busy: %s", - per_second => 1, - perfdatas => [ - { label => 'backend_miss', value => 'backend_miss_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'fail', set => { - key_values => [ { name => 'backend_fail', diff => 1 } ], - output_template => 'Backend fail: %.2f/s', output_error_template => "Backend fail: %s", - per_second => 1, - perfdatas => [ - { label => 'backend_fail', value => 'backend_fail_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'reuse', set => { - key_values => [ { name => 'backend_reuse', diff => 1 } ], - output_template => 'Backend reuse: %.2f/s', output_error_template => "Backend reuse: %s", - per_second => 1, - perfdatas => [ - { label => 'backend_reuse', value => 'backend_reuse_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'recycle', set => { - key_values => [ { name => 'backend_recycle', diff => 1 } ], - output_template => 'Backend recycle: %.2f/s', output_error_template => "Backend recycle: %s", - per_second => 1, - perfdatas => [ - { label => 'backend_recycle', value => 'backend_recycle_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'retry', set => { - key_values => [ { name => 'backend_retry', diff => 1 } ], - output_template => 'Backend retry: %.2f/s', output_error_template => "Backend retry: %s", - per_second => 1, - perfdatas => [ - { label => 'backend_retry', value => 'backend_retry_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'recycle', set => { - key_values => [ { name => 'backend_recycle', diff => 1 } ], - output_template => 'Backend recycle: %.2f/s', output_error_template => "Backend recycle: %s", - per_second => 1, - perfdatas => [ - { label => 'backend_recycle', value => 'backend_recycle_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'request', set => { - key_values => [ { name => 'backend_req', diff => 1 } ], - output_template => 'Backend requests: %.2f/s', output_error_template => "Backend requests: %s", - per_second => 1, - perfdatas => [ - { label => 'backend_req', value => 'backend_req_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - ], -} - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); - bless $self, $class; - - $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 -j 2>&1' }, - }); - - return $self; -}; - -sub manage_selection { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - -# "MAIN.backend_hit": {"type": "MAIN", "value": 18437, "flag": "a", "description": "Cache hits"}, -# "MAIN.backend_hitpass": {"type": "MAIN", "value": 3488, "flag": "a", "description": "Cache hits for pass"}, -# "MAIN.backend_miss": {"type": "MAIN", "value": 5782, "flag": "a", "description": "Cache misses"}, - my $json_data = decode_json($stdout); - - $self->{cache_name} = "cache_varnish_" . $self->{mode} . '_' . - (defined($self->{option_results}->{hostname}) ? md5_hex($self->{option_results}->{hostname}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); - - foreach my $counter (keys %{$json_data}) { - next if ($counter !~ /backend/); - my $value = $json_data->{$counter}->{value}; - $counter =~ s/^([A-Z])+\.//; - $self->{backend}->{$counter} = $value; - } -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 ') - -=item B<--warning-*> - -Warning Threshold for: -conn => Backend conn. success, -unhealthy => Backend conn. not attempted, -busy => Backend conn. too many, -fail => Backend conn. failures, -reuse => Backend conn. reuses, -toolate => Backend conn. was closed, -recycle => Backend conn. recycles, -retry => Backend conn. retry, -request => Backend requests made - -=item B<--critical-*> - -Critical Threshold for: -conn => Backend conn. success, -unhealthy => Backend conn. not attempted, -busy => Backend conn. too many, -fail => Backend conn. failures, -reuse => Backend conn. reuses, -toolate => Backend conn. was closed, -recycle => Backend conn. recycles, -retry => Backend conn. retry, -request => Backend requests made - -=back - -=cut diff --git a/apps/varnish/local/mode/bans.pm b/apps/varnish/local/mode/bans.pm deleted file mode 100644 index 556c042c0..000000000 --- a/apps/varnish/local/mode/bans.pm +++ /dev/null @@ -1,269 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::bans; - -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); - -my $maps_counters = { - n_ban => { thresholds => { - warning_total => { label => 'warning-total', exit_value => 'warning' }, - critical_total => { label => 'critical-total', exit_value => 'critical' }, - }, - output_msg => 'N total active bans: %.2f', - factor => 1, unit => '', - }, - n_ban_add => { thresholds => { - warning_add => { label => 'warning-add', exit_value => 'warning' }, - critical_add => { label => 'critical-add', exit_value => 'critical' }, - }, - output_msg => 'N new bans added: %.2f', - factor => 1, unit => '', - }, - n_ban_retire => { thresholds => { - warning_retire => { label => 'warning-retire', exit_value => 'warning' }, - critical_retire => { label => 'critical-retire', exit_value => 'critical' }, - }, - output_msg => 'N old bans deleted: %.2f', - factor => 1, unit => '', - }, - n_ban_obj_test => { thresholds => { - warning_objtest => { label => 'warning-objtest', exit_value => 'warning' }, - critical_objtest => { label => 'critical-objtest', exit_value => 'critical' }, - }, - output_msg => 'N objects tested: %.2f', - factor => 1, unit => '', - }, - n_ban_re_test => { thresholds => { - warning_retest => { label => 'warning-retest', exit_value => 'warning' }, - critical_retest => { label => 'critical-retest', exit_value => 'critical' }, - }, - output_msg => 'N regexps tested against: %.2f', - factor => 1, unit => '', - }, - n_ban_dups => { thresholds => { - warning_dups => { label => 'warning-dups', exit_value => 'warning' }, - critical_dups => { label => 'critical-dups', exit_value => 'critical' }, - }, - output_msg => 'N duplicate bans removed: %.2f', - factor => 1, unit => '', - }, -}; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, - }); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - return $self; -}; - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options} . $self->{option_results}->{command_options2}); - #print $stdout; - - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text - - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; - -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 ') - -=item B<--warning-*> - -Warning Threshold for: -total => N total active bans, -add => N new bans added, -retire => N old bans deleted, -objtest => N objects tested, -retest => N regexps tested against, -dups => N duplicate bans removed - -=item B<--critical-*> - -Critical Threshold for: -total => N total active bans, -add => N new bans added, -retire => N old bans deleted, -objtest => N objects tested, -retest => N regexps tested against, -dups => N duplicate bans removed - -=back - -=cut \ No newline at end of file diff --git a/apps/varnish/local/mode/cache.pm b/apps/varnish/local/mode/cache.pm deleted file mode 100644 index c25e76cdc..000000000 --- a/apps/varnish/local/mode/cache.pm +++ /dev/null @@ -1,170 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::cache; - -use base qw(centreon::plugins::templates::counter); -use strict; -use warnings; -use Digest::MD5 qw(md5_hex); -use JSON; - -sub set_counters { - my ($self, %options) = @_; - - $self->{maps_counters_type} = [ - { name => 'cache', type => 0, skipped_code => { -10 => 1 } }, - ]; - $self->{maps_counters}->{cache} = [ - { label => 'hit', set => { - key_values => [ { name => 'cache_hit', diff => 1 } ], - output_template => 'Cache hit: %.2f/s', output_error_template => "Cache hit: %s", - per_second => 1, - perfdatas => [ - { label => 'cache_hit', value => 'cache_hit_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'hitpass', set => { - key_values => [ { name => 'cache_hitpass', diff => 1 } ], - output_template => 'Cache hitpass : %.2f/s', output_error_template => "Cache hitpass : %s", - per_second => 1, - perfdatas => [ - { label => 'cache_hitpass', value => 'cache_hitpass_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'miss', set => { - key_values => [ { name => 'cache_miss', diff => 1 } ], - output_template => 'Cache miss : %.2f/s', output_error_template => "Cache miss : %s", - per_second => 1, - perfdatas => [ - { label => 'cache_miss', value => 'cache_miss_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - ], -} - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); - bless $self, $class; - - $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 -j 2>&1' }, - }); - - return $self; -}; - -sub manage_selection { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - -# "MAIN.cache_hit": {"type": "MAIN", "value": 18437, "flag": "a", "description": "Cache hits"}, -# "MAIN.cache_hitpass": {"type": "MAIN", "value": 3488, "flag": "a", "description": "Cache hits for pass"}, -# "MAIN.cache_miss": {"type": "MAIN", "value": 5782, "flag": "a", "description": "Cache misses"}, - my $json_data = decode_json($stdout); - - $self->{cache_name} = "cache_varnish_" . $self->{mode} . '_' . - (defined($self->{option_results}->{hostname}) ? md5_hex($self->{option_results}->{hostname}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); - - foreach my $counter (keys %{$json_data}) { - next if ($counter !~ /cache/); - my $value = $json_data->{$counter}->{value}; - $counter =~ s/^([A-Z])+\.//; - $self->{cache}->{$counter} = $value; - } -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 -j 2>&1') - -=item B<--warning-*> - -Warning Threshold for: -hit => Cache Hits, -hitpass => Cache hits for Pass, -miss => Cache Misses - -=item B<--critical-*> - -Critical Threshold for: -hit => Cache Hits, -hitpass => Cache hits for Pass, -miss => Cache Misses - -=back - -=cut diff --git a/apps/varnish/local/mode/clients.pm b/apps/varnish/local/mode/clients.pm deleted file mode 100644 index 28f76b1b1..000000000 --- a/apps/varnish/local/mode/clients.pm +++ /dev/null @@ -1,187 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::clients; - -use base qw(centreon::plugins::templates::counter); -use strict; -use warnings; -use Digest::MD5 qw(md5_hex); -use JSON; - -sub set_counters { - my ($self, %options) = @_; - - $self->{maps_counters_type} = [ - { name => 'clients', type => 0, skipped_code => { -10 => 1 } }, - ]; - $self->{maps_counters}->{clients} = [ - { label => 'request', set => { - key_values => [ { name => 'client_req' , diff => 1 } ], - output_template => 'Client request (Total): %.2f', output_error_template => "Client request: %s", - per_second => 1, - perfdatas => [ - { label => 'client_req', value => 'client_req_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'request-400', set => { - key_values => [ { name => 'client_req_400' , diff => 1 } ], - output_template => 'Client request (HTTP/400): %.2f', output_error_template => "Client request (HTTP/400): %s", - per_second => 1, - perfdatas => [ - { label => 'client_req_400', value => 'client_req_400_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'request-411', set => { - key_values => [ { name => 'client_req_411' , diff => 1 } ], - output_template => 'Client request (HTTP/411): %.2f', output_error_template => "Client request (HTTP/411): %s", - per_second => 1, - perfdatas => [ - { label => 'client_req_411', value => 'client_req_411_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'request-413', set => { - key_values => [ { name => 'client_req_413' , diff => 1 } ], - output_template => 'Client request (HTTP/413): %.2f', output_error_template => "Client request (HTTP/413): %s", - per_second => 1, - perfdatas => [ - { label => 'client_req_413', value => 'client_req_413_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'request-417', set => { - key_values => [ { name => 'client_req_417' , diff => 1 } ], - output_template => 'Client request (HTTP/417): %.2f', output_error_template => "Client request (HTTP/417): %s", - per_second => 1, - perfdatas => [ - { label => 'client_req_417', value => 'client_req_417_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - ], -} - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); - bless $self, $class; - - $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 -j 2>&1' }, - }); - - return $self; -}; - -sub manage_selection { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - -# "MAIN.client_req_400": {"type": "MAIN", "value": 0, "flag": "a", "description": "Client requests received, subject to 400 errors"}, -# "MAIN.client_req_411": {"type": "MAIN", "value": 0, "flag": "a", "description": "Client requests received, subject to 411 errors"}, -# "MAIN.client_req_413": {"type": "MAIN", "value": 0, "flag": "a", "description": "Client requests received, subject to 413 errors"}, -# "MAIN.client_req_417": {"type": "MAIN", "value": 0, "flag": "a", "description": "Client requests received, subject to 417 errors"}, -# "MAIN.client_req": {"type": "MAIN", "value": 13597, "flag": "a", "description": "Good client requests received"}, - - my $json_data = decode_json($stdout); - - $self->{cache_name} = "cache_varnish_" . $self->{mode} . '_' . - (defined($self->{option_results}->{hostname}) ? md5_hex($self->{option_results}->{hostname}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); - - foreach my $counter (keys %{$json_data}) { - next if ($counter !~ /^([A-Z])+\.client_.*/); - my $value = $json_data->{$counter}->{value}; - $counter =~ s/^([A-Z])+\.//; - $self->{clients}->{$counter} = $value; - } -}; - - -1; - -__END__ - -=head1 MODE - -Check client requests with varnishstat command (Varnish v4 required) - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 -j 2>&1') - -=item B<--warning-*> -Warning threshold per second. -Can be: (request,request-400,request-411,request-413,request-417) - -=item B<--critical-*> -Critical threshold per second : -Can be: (request,request-400,request-411,request-413,request-417) - -=back - -=cut diff --git a/apps/varnish/local/mode/connections.pm b/apps/varnish/local/mode/connections.pm deleted file mode 100644 index 5e4906668..000000000 --- a/apps/varnish/local/mode/connections.pm +++ /dev/null @@ -1,251 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::connections; - -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); - -my $maps_counters = { - client_conn => { thresholds => { - warning_conn => { label => 'warning-conn', exit_value => 'warning' }, - critical_conn => { label => 'critical-conn', exit_value => 'critical' }, - }, - output_msg => 'Client connections accepted: %.2f', - factor => 1, unit => '', - }, - client_drop => { thresholds => { - warning_drop => { label => 'warning-drop', exit_value => 'warning' }, - critical_drop => { label => 'critical-drop', exit_value => 'critical' }, - }, - output_msg => 'Connection dropped, no sess/wrk: %.2f', - factor => 1, unit => '', - }, - client_drop_late => { thresholds => { - warning_droplate => { label => 'warning-droplate', exit_value => 'warning' }, - critical_droplate => { label => 'critical-droplate', exit_value => 'critical' }, - }, - output_msg => 'Connection dropped late: %.2f', - factor => 1, unit => '', - }, - client_req => { thresholds => { - warning_req => { label => 'warning-req', exit_value => 'warning' }, - critical_req => { label => 'critical-req', exit_value => 'critical' }, - }, - output_msg => 'Client requests received: %.2f', - factor => 1, unit => '', - }, -}; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, - }); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - return $self; -}; - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options} . $self->{option_results}->{command_options2}); - #print $stdout; - - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text - - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; - -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 ') - -=item B<--warning-*> - -Warning Threshold for: -conn => Client connections accepted, -drop => Connection dropped, no sess/wrk, -droplate => Connection dropped late, -req => Client requests received - -=item B<--critical-*> - -Critical Threshold for: -conn => Client connections accepted, -drop => Connection dropped, no sess/wrk, -droplate => Connection dropped late, -req => Client requests received - -=back - -=cut \ No newline at end of file diff --git a/apps/varnish/local/mode/dns.pm b/apps/varnish/local/mode/dns.pm deleted file mode 100644 index 643d4cedf..000000000 --- a/apps/varnish/local/mode/dns.pm +++ /dev/null @@ -1,251 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::dns; - -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); - -my $maps_counters = { - dir_dns_lookups => { thresholds => { - warning_lookups => { label => 'warning-lookups', exit_value => 'warning' }, - critical_lookups => { label => 'critical-lookups', exit_value => 'critical' }, - }, - output_msg => 'HCB Lookups without lock: %.2f', - factor => 1, unit => '', - }, - dir_dns_failed => { thresholds => { - warning_failed => { label => 'warning-failed', exit_value => 'warning' }, - critical_failed => { label => 'critical-failed', exit_value => 'critical' }, - }, - output_msg => 'HCB Lookups with lock: %.2f', - factor => 1, unit => '', - }, - dir_dns_hit => { thresholds => { - warning_hit => { label => 'warning-hit', exit_value => 'warning' }, - critical_hit => { label => 'critical-hit', exit_value => 'critical' }, - }, - output_msg => 'HCB Inserts: %.2f', - factor => 1, unit => '', - }, - dir_dns_cache_full => { thresholds => { - warning_full => { label => 'warning-full', exit_value => 'warning' }, - critical_full => { label => 'critical-full', exit_value => 'critical' }, - }, - output_msg => 'HCB Inserts: %.2f', - factor => 1, unit => '', - }, -}; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, - }); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - return $self; -}; - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options} . $self->{option_results}->{command_options2}); - #print $stdout; - - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text - - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; - -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 ') - -=item B<--warning-*> - -Warning Threshold for: -lookups => DNS director lookups, -failed => DNS director failed lookups, -hit => DNS director cached lookups hit, -full => DNS director full dnscache - -=item B<--critical-*> - -Critical Threshold for: -lookups => DNS director lookups, -failed => DNS director failed lookups, -hit => DNS director cached lookups hit, -full => DNS director full dnscache - -=back - -=cut \ No newline at end of file diff --git a/apps/varnish/local/mode/esi.pm b/apps/varnish/local/mode/esi.pm deleted file mode 100644 index c6b4fca3e..000000000 --- a/apps/varnish/local/mode/esi.pm +++ /dev/null @@ -1,233 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::esi; - -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); - -my $maps_counters = { - esi_errors => { thresholds => { - warning_errors => { label => 'warning-errors', exit_value => 'warning' }, - critical_errors => { label => 'critical-errors', exit_value => 'critical' }, - }, - output_msg => 'ESI parse errors (unlock): %.2f', - factor => 1, unit => '', - }, - esi_warnings => { thresholds => { - warning_warnings => { label => 'warning-warnings', exit_value => 'warning' }, - critical_warnings => { label => 'critical-warnings', exit_value => 'critical' }, - }, - output_msg => 'ESI parse warnings (unlock): %.2f', - factor => 1, unit => '', - }, -}; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, - }); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - return $self; -}; - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options} . $self->{option_results}->{command_options2}); - #print $stdout; - - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text - - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; - -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 ') - -=item B<--warning-*> - -Warning Threshold for: -errors => ESI parse errors (unlock), -warnings => ESI parse warnings (unlock) - -=item B<--critical-*> - -Critical Threshold for: -errors => ESI parse errors (unlock), -warnings => ESI parse warnings (unlock) - -=back - -=cut \ No newline at end of file diff --git a/apps/varnish/local/mode/fetch.pm b/apps/varnish/local/mode/fetch.pm deleted file mode 100644 index 29f2534a0..000000000 --- a/apps/varnish/local/mode/fetch.pm +++ /dev/null @@ -1,323 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::fetch; - -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); - -my $maps_counters = { - fetch_head => { thresholds => { - warning_head => { label => 'warning-head', exit_value => 'warning' }, - critical_head => { label => 'critical-head', exit_value => 'critical' }, - }, - output_msg => 'Fetch head: %.2f', - factor => 1, unit => '', - }, - fetch_length => { thresholds => { - warning_length => { label => 'warning-length', exit_value => 'warning' }, - critical_length => { label => 'critical-length', exit_value => 'critical' }, - }, - output_msg => 'Fetch with Length: %.2f', - factor => 1, unit => '', - }, - fetch_chunked => { thresholds => { - warning_chunked => { label => 'warning-chunked', exit_value => 'warning' }, - critical_chunked => { label => 'critical-chunked', exit_value => 'critical' }, - }, - output_msg => 'Fetch chunked: %.2f', - factor => 1, unit => '', - }, - fetch_eof => { thresholds => { - warning_eof => { label => 'warning-eof', exit_value => 'warning' }, - critical_eof => { label => 'critical-eof', exit_value => 'critical' }, - }, - output_msg => 'Fetch EOF: %.2f', - factor => 1, unit => '', - }, - fetch_bad => { thresholds => { - warning_bad => { label => 'warning-bad', exit_value => 'warning' }, - critical_bad => { label => 'critical-bad', exit_value => 'critical' }, - }, - output_msg => 'Fetch had bad headers: %.2f', - factor => 1, unit => '', - }, - fetch_close => { thresholds => { - warning_close => { label => 'warning-close', exit_value => 'warning' }, - critical_close => { label => 'critical-close', exit_value => 'critical' }, - }, - output_msg => 'Fetch wanted close: %.2f', - factor => 1, unit => '', - }, - fetch_oldhttp => { thresholds => { - warning_oldhttp => { label => 'warning-oldhttp', exit_value => 'warning' }, - critical_oldhttp => { label => 'critical-oldhttp', exit_value => 'critical' }, - }, - output_msg => 'Fetch pre HTTP/1.1 closed: %.2f', - factor => 1, unit => '', - }, - fetch_zero => { thresholds => { - warning_zero => { label => 'warning-zero', exit_value => 'warning' }, - critical_zero => { label => 'critical-zero', exit_value => 'critical' }, - }, - output_msg => 'Fetch zero len: %.2f', - factor => 1, unit => '', - }, - fetch_failed => { thresholds => { - warning_failed => { label => 'warning-failed', exit_value => 'warning' }, - critical_failed => { label => 'critical-failed', exit_value => 'critical' }, - }, - output_msg => 'Fetch failed: %.2f', - factor => 1, unit => '', - }, - fetch_1xx => { thresholds => { - warning_1xx => { label => 'warning-1xx', exit_value => 'warning' }, - critical_1xx => { label => 'critical-1xx', exit_value => 'critical' }, - }, - output_msg => 'Fetch no body (1xx): %.2f', - factor => 1, unit => '', - }, - fetch_204 => { thresholds => { - warning_204 => { label => 'warning-204', exit_value => 'warning' }, - critical_204 => { label => 'critical-204', exit_value => 'critical' }, - }, - output_msg => 'Fetch no body (204): %.2f', - factor => 1, unit => '', - }, - fetch_304 => { thresholds => { - warning_304 => { label => 'warning-304', exit_value => 'warning' }, - critical_304 => { label => 'critical-304', exit_value => 'critical' }, - }, - output_msg => 'Fetch no body (304): %.2f', - factor => 1, unit => '', - }, -}; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, - }); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - return $self; -}; - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options} . $self->{option_results}->{command_options2}); - #print $stdout; - - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text - - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; - -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 ') - -=item B<--warning-*> - -Warning Threshold for: -head => Fetch head, -length => Fetch with Length, -chunked => Fetch chunked, -eof => Fetch EOF, -bad => Fetch had bad headers, -close => Fetch wanted close, -oldhttp => Fetch pre HTTP/1.1 closed, -zero => Fetch zero len, -failed => Fetch failed, -1xx => Fetch no body (1xx), -204 => Fetch no body (204), -304 => Fetch no body (304) - -=item B<--critical-*> - -Critical Threshold for: -head => Fetch head, -length => Fetch with Length, -chunked => Fetch chunked, -eof => Fetch EOF, -bad => Fetch had bad headers, -close => Fetch wanted close, -oldhttp => Fetch pre HTTP/1.1 closed, -zero => Fetch zero len, -failed => Fetch failed, -1xx => Fetch no body (1xx), -204 => Fetch no body (204), -304 => Fetch no body (304) - -=back - -=cut \ No newline at end of file diff --git a/apps/varnish/local/mode/hcb.pm b/apps/varnish/local/mode/hcb.pm deleted file mode 100644 index 284a0c305..000000000 --- a/apps/varnish/local/mode/hcb.pm +++ /dev/null @@ -1,242 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::hcb; - -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); - -my $maps_counters = { - hcb_nolock => { thresholds => { - warning_nolock => { label => 'warning-nolock', exit_value => 'warning' }, - critical_nolock => { label => 'critical-nolock', exit_value => 'critical' }, - }, - output_msg => 'HCB Lookups without lock: %.2f', - factor => 1, unit => '', - }, - hcb_lock => { thresholds => { - warning_lock => { label => 'warning-lock', exit_value => 'warning' }, - critical_lock => { label => 'critical-lock', exit_value => 'critical' }, - }, - output_msg => 'HCB Lookups with lock: %.2f', - factor => 1, unit => '', - }, - hcb_insert => { thresholds => { - warning_insert => { label => 'warning-insert', exit_value => 'warning' }, - critical_insert => { label => 'critical-insert', exit_value => 'critical' }, - }, - output_msg => 'HCB Inserts: %.2f', - factor => 1, unit => '', - }, -}; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, - }); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - return $self; -}; - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options} . $self->{option_results}->{command_options2}); - #print $stdout; - - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text - - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; - -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 ') - -=item B<--warning-*> - -Warning Threshold for: -nolock => HCB Lookups without lock, -lock => HCB Lookups with lock, -insert => HCB Inserts - -=item B<--critical-*> - -Critical Threshold for: -nolock => HCB Lookups without lock, -lock => HCB Lookups with lock, -insert => HCB Inserts - -=back - -=cut \ No newline at end of file diff --git a/apps/varnish/local/mode/n.pm b/apps/varnish/local/mode/n.pm deleted file mode 100644 index 72780302a..000000000 --- a/apps/varnish/local/mode/n.pm +++ /dev/null @@ -1,323 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::n; - -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); - -my $maps_counters = { - n_sess_mem => { thresholds => { - warning_mem => { label => 'warning-mem', exit_value => 'warning' }, - critical_mem => { label => 'critical-mem', exit_value => 'critical' }, - }, - output_msg => 'N struct sess_mem: %.2f', - factor => 1, unit => '', - }, - n_sess => { thresholds => { - warning_sess => { label => 'warning-sess', exit_value => 'warning' }, - critical_sess => { label => 'critical-sess', exit_value => 'critical' }, - }, - output_msg => 'N struct sess: %.2f', - factor => 1, unit => '', - }, - n_object => { thresholds => { - warning_object => { label => 'warning-object', exit_value => 'warning' }, - critical_object => { label => 'critical-object', exit_value => 'critical' }, - }, - output_msg => 'N struct object: %.2f', - factor => 1, unit => '', - }, - n_vampireobject => { thresholds => { - warning_vampireobject => { label => 'warning-vampireobject', exit_value => 'warning' }, - critical_vampireobject => { label => 'critical-vampireobject', exit_value => 'critical' }, - }, - output_msg => 'N unresurrected objects: %.2f', - factor => 1, unit => '', - }, - n_objectcore => { thresholds => { - warning_objectcore => { label => 'warning-objectcore', exit_value => 'warning' }, - critical_objectcore => { label => 'critical-objectcore', exit_value => 'critical' }, - }, - output_msg => 'N struct objectcore: %.2f', - factor => 1, unit => '', - }, - n_objecthead => { thresholds => { - warning_objecthead => { label => 'warning-objecthead', exit_value => 'warning' }, - critical_objecthead => { label => 'critical-objecthead', exit_value => 'critical' }, - }, - output_msg => 'N struct objecthead: %.2f', - factor => 1, unit => '', - }, - n_waitinglist => { thresholds => { - warning_waitinglist => { label => 'warning-waitinglist', exit_value => 'warning' }, - critical_waitinglist => { label => 'critical-waitinglist', exit_value => 'critical' }, - }, - output_msg => 'N struct waitinglist: %.2f', - factor => 1, unit => '', - }, - n_vbc => { thresholds => { - warning_vbc => { label => 'warning-vbc', exit_value => 'warning' }, - critical_vbc => { label => 'critical-vbc', exit_value => 'critical' }, - }, - output_msg => 'N struct vbc: %.2f', - factor => 1, unit => '', - }, - n_backend => { thresholds => { - warning_backend => { label => 'warning-backend', exit_value => 'warning' }, - critical_backend => { label => 'critical-backend', exit_value => 'critical' }, - }, - output_msg => 'N backends: %.2f', - factor => 1, unit => '', - }, - n_expired => { thresholds => { - warning_expired => { label => 'warning-expired', exit_value => 'warning' }, - critical_expired => { label => 'critical-expired', exit_value => 'critical' }, - }, - output_msg => 'N expired objects: %.2f', - factor => 1, unit => '', - }, - n_lru_nuked => { thresholds => { - warning_nuked => { label => 'warning-nuked', exit_value => 'warning' }, - critical_nuked => { label => 'critical-nuked', exit_value => 'critical' }, - }, - output_msg => 'N LRU nuked objects: %.2f', - factor => 1, unit => '', - }, - n_lru_moved => { thresholds => { - warning_moved => { label => 'warning-moved', exit_value => 'warning' }, - critical_moved => { label => 'critical-moved', exit_value => 'critical' }, - }, - output_msg => 'N LRU moved objects: %.2f', - factor => 1, unit => '', - }, -}; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, - }); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - return $self; -}; - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options} . $self->{option_results}->{command_options2}); - #print $stdout; - - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text - - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; - -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 ') - -=item B<--warning-*> - -Warning Threshold for: -n_sess_mem => N struct sess_mem, -n_sess => N struct sess, -n_object => N struct object, -n_vampireobject => N unresurrected objects, -n_objectcore => N struct objectcore, -n_objecthead => N struct objecthead, -n_waitinglist => N struct waitinglist, -n_vbc => N struct vbc, -n_backend => N backends, -n_expired => N expired objects, -n_lru_nuked => N LRU nuked objects, -n_lru_moved => N LRU moved objects - -=item B<--critical-*> - -Critical Threshold for: -n_sess_mem => N struct sess_mem, -n_sess => N struct sess, -n_object => N struct object, -n_vampireobject => N unresurrected objects, -n_objectcore => N struct objectcore, -n_objecthead => N struct objecthead, -n_waitinglist => N struct waitinglist, -n_vbc => N struct vbc, -n_backend => N backends, -n_expired => N expired objects, -n_lru_nuked => N LRU nuked objects, -n_lru_moved => N LRU moved objects - -=back - -=cut \ No newline at end of file diff --git a/apps/varnish/local/mode/objects.pm b/apps/varnish/local/mode/objects.pm deleted file mode 100644 index 051c4223f..000000000 --- a/apps/varnish/local/mode/objects.pm +++ /dev/null @@ -1,242 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::objects; - -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); - -my $maps_counters = { - n_objsendfile => { thresholds => { - warning_objsendfile => { label => 'warning-objsendfile', exit_value => 'warning' }, - critical_objsendfile => { label => 'critical-objsendfile', exit_value => 'critical' }, - }, - output_msg => 'Objects sent with sendfile: %.2f', - factor => 1, unit => '', - }, - n_objwrite => { thresholds => { - warning_objwrite => { label => 'warning-objwrite', exit_value => 'warning' }, - critical_objwrite => { label => 'critical-objwrite', exit_value => 'critical' }, - }, - output_msg => 'Objects sent with write: %.2f', - factor => 1, unit => '', - }, - n_objoverflow => { thresholds => { - warning_objoverflow => { label => 'warning-objoverflow', exit_value => 'warning' }, - critical_objoverflow => { label => 'critical-objoverflow', exit_value => 'critical' }, - }, - output_msg => 'Objects overflowing workspace: %.2f', - factor => 1, unit => '', - }, -}; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, - }); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - return $self; -}; - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options} . $self->{option_results}->{command_options2}); - #print $stdout; - - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text - - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; - -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 ') - -=item B<--warning-*> - -Warning Threshold for: -objsendfile => Objects sent with sendfile, -objwrite => Objects sent with write, -objoverflow => Objects overflowing workspace - -=item B<--critical-*> - -Critical Threshold for: -objsendfile => Objects sent with sendfile, -objwrite => Objects sent with write, -objoverflow => Objects overflowing workspace - -=back - -=cut \ No newline at end of file diff --git a/apps/varnish/local/mode/sessions.pm b/apps/varnish/local/mode/sessions.pm deleted file mode 100644 index f84dcd3f7..000000000 --- a/apps/varnish/local/mode/sessions.pm +++ /dev/null @@ -1,252 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::sessions; - -use base qw(centreon::plugins::templates::counter); -use strict; -use warnings; -use Digest::MD5 qw(md5_hex); -use JSON; - -sub set_counters { - my ($self, %options) = @_; - - $self->{maps_counters_type} = [ - { name => 'sessions', type => 0, skipped_code => { -10 => 1 } }, - ]; - $self->{maps_counters}->{sessions} = [ - { label => 'accepted', set => { - key_values => [ { name => 'sess_conn', diff => 1 } ], - output_template => 'Session accepted: %.2f/s', output_error_template => "Session accepted: %s", - per_second => 1, - perfdatas => [ - { label => 'sess_conn', value => 'sess_conn_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'dropped', set => { - key_values => [ { name => 'sess_drop', diff => 1 } ], - output_template => 'Session dropped: %.2f/s', output_error_template => "Session dropped: %s", - per_second => 1, - perfdatas => [ - { label => 'sess_drop', value => 'sess_drop_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'failed', set => { - key_values => [ { name => 'sess_fail', diff => 1 } ], - output_template => 'Session fail: %.2f/s', output_error_template => "Session fail: %s", - per_second => 1, - perfdatas => [ - { label => 'sess_fail', value => 'sess_fail_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'pipeoverflow', set => { - key_values => [ { name => 'sess_pipe_overflow', diff => 1 } ], - output_template => 'Sessions pipe overflow: %.2f/s', output_error_template => "Sessions pipe overflow: %s", - per_second => 1, - perfdatas => [ - { label => 'sess_pipe_overflow', value => 'sess_pipe_overflow_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'queued', set => { - key_values => [ { name => 'sess_queued' , diff => 1 } ], - output_template => 'Session queued: %.2f/s', output_error_template => "Session queued: %s", - per_second => 1, - perfdatas => [ - { label => 'sess_queued', value => 'sess_queued_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'dropped', set => { - key_values => [ { name => 'sess_dropped' , diff => 1 } ], - output_template => 'Session dropped: %.2f/s', output_error_template => "Session dropped: %s", - per_second => 1, - perfdatas => [ - { label => 'sess_dropped', value => 'sess_dropped_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'readahead', set => { - key_values => [ { name => 'sess_readahead' , diff => 1 } ], - output_template => 'Session readahead: %.2f/s', output_error_template => "Session readahead: %s", - per_second => 1, - perfdatas => [ - { label => 'sess_readahead', value => 'sess_readahead_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'closed', set => { - key_values => [ { name => 'sess_closed' , diff => 1 } ], - output_template => 'Session closed: %.2f/s', output_error_template => "Session closed: %s", - per_second => 1, - perfdatas => [ - { label => 'sess_closed', value => 'sess_closed_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'herd', set => { - key_values => [ { name => 'sess_herd' , diff => 1 } ], - output_template => 'Session herd: %.2f/s', output_error_template => "Session herd: %s", - per_second => 1, - perfdatas => [ - { label => 'sess_herd', value => 'sess_herd_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'linger', set => { - key_values => [ { name => 'sess_linger' , diff => 1 } ], - output_template => 'Session linger: %.2f/s', output_error_template => "Session linger: %s", - per_second => 1, - perfdatas => [ - { label => 'sess_linger', value => 'sess_linger_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'pipeline', set => { - key_values => [ { name => 'sess_pipeline' , diff => 1 } ], - output_template => 'Session pipeline: %.2f/s', output_error_template => "Session pipeline: %s", - per_second => 1, - perfdatas => [ - { label => 'sess_pipeline', value => 'sess_pipeline_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - ], -} - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); - bless $self, $class; - - $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 -j 2>&1' }, - }); - - return $self; -}; - -sub manage_selection { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - -# "MAIN.sess_conn": {"type": "MAIN", "value": 13598, "flag": "c", "description": "Sessions accepted"}, -# "MAIN.sess_drop": {"type": "MAIN", "value": 0, "flag": "c", "description": "Sessions dropped"}, -# "MAIN.sess_fail": {"type": "MAIN", "value": 0, "flag": "c", "description": "Session accept failures"}, -# "MAIN.sess_pipe_overflow": {"type": "MAIN", "value": 0, "flag": "c", "description": "Session pipe overflow"}, -# "MAIN.sess_queued": {"type": "MAIN", "value": 0, "flag": "c", "description": "Sessions queued for thread"}, -# "MAIN.sess_dropped": {"type": "MAIN", "value": 0, "flag": "c", "description": "Sessions dropped for thread"}, -# "MAIN.sess_closed": {"type": "MAIN", "value": 13211, "flag": "a", "description": "Session Closed"}, -# "MAIN.sess_pipeline": {"type": "MAIN", "value": 0, "flag": "a", "description": "Session Pipeline"}, -# "MAIN.sess_readahead": {"type": "MAIN", "value": 0, "flag": "a", "description": "Session Read Ahead"}, -# "MAIN.sess_herd": {"type": "MAIN", "value": 26, "flag": "a", "description": "Session herd"}, - - my $json_data = decode_json($stdout); - - $self->{cache_name} = "cache_varnish_" . $self->{mode} . '_' . - (defined($self->{option_results}->{hostname}) ? md5_hex($self->{option_results}->{hostname}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); - - foreach my $counter (keys %{$json_data}) { - next if ($counter !~ /^([A-Z])+\.sess_.*/); - my $value = $json_data->{$counter}->{value}; - $counter =~ s/^([A-Z])+\.//; - $self->{sessions}->{$counter} = $value; - } -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 -j 2>&1') - -=item B<--warning-*> -Warning Threshold per second. -Can be (accepted,closed,queued,failed,pipeline,readahead,linger,herd,dropped,pipeoverflow) - -=item B<--critical-*> -Critical Threshold per second for: -Can be (accepted,closed,queued,failed,pipeline,readahead,linger,herd,dropped,pipeoverflow) - -=back - -=cut diff --git a/apps/varnish/local/mode/shm.pm b/apps/varnish/local/mode/shm.pm deleted file mode 100644 index c8f94f11a..000000000 --- a/apps/varnish/local/mode/shm.pm +++ /dev/null @@ -1,196 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::shm; - -use base qw(centreon::plugins::templates::counter); -use strict; -use warnings; -use Digest::MD5 qw(md5_hex); -use JSON; - -sub set_counters { - my ($self, %options) = @_; - - $self->{maps_counters_type} = [ - { name => 'shm', type => 0, skipped_code => { -10 => 1 } }, - ]; - $self->{maps_counters}->{shm} = [ - { label => 'records', set => { - key_values => [ { name => 'shm_records', diff => 1 } ], - output_template => 'SHM Records: %.2f/s', output_error_template => "SHM Records: %s", - per_second => 1, - perfdatas => [ - { label => 'shm_records', value => 'shm_records_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'writes', set => { - key_values => [ { name => 'shm_writes', diff => 1 } ], - output_template => 'SHM Writes: %.2f/s', output_error_template => "SHM Writes: %s", - per_second => 1, - perfdatas => [ - { label => 'shm_writes', value => 'shm_writes_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'flushes', set => { - key_values => [ { name => 'shm_flushes', diff => 1 } ], - output_template => 'SHM Flushes: %.2f/s', output_error_template => "SHM Flushes: %s", - per_second => 1, - perfdatas => [ - { label => 'shm_flushes', value => 'shm_flushes_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'cont', set => { - key_values => [ { name => 'shm_cont', diff => 1 } ], - output_template => 'SHM Contention: %.2f/s', output_error_template => "SHM Contention: %s", - per_second => 1, - perfdatas => [ - { label => 'shm_cont', value => 'shm_cont_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'cycles', set => { - key_values => [ { name => 'shm_cycles', diff => 1 } ], - output_template => 'SHM Cycles: %.2f/s', output_error_template => "SHM Cycles: %s", - per_second => 1, - perfdatas => [ - { label => 'shm_cycles', value => 'shm_cycles_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - ], -} - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); - bless $self, $class; - - $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 -j 2>&1' }, - }); - - return $self; -}; - -sub manage_selection { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - -# "MAIN.shm_records": {"type": "MAIN", "value": 6992776, "flag": "a", "description": "SHM records"}, -# "MAIN.shm_writes": {"type": "MAIN", "value": 3947244, "flag": "a", "description": "SHM writes"}, -# "MAIN.shm_flushes": {"type": "MAIN", "value": 12354, "flag": "a", "description": "SHM flushes due to overflow"}, -# "MAIN.shm_cont": {"type": "MAIN", "value": 564, "flag": "a", "description": "SHM MTX contention"}, -# "MAIN.shm_cycles": {"type": "MAIN", "value": 3, "flag": "a", "description": "SHM cycles through buffer"}, - - my $json_data = decode_json($stdout); - - $self->{cache_name} = "cache_varnish_" . $self->{mode} . '_' . - (defined($self->{option_results}->{hostname}) ? md5_hex($self->{option_results}->{hostname}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); - - foreach my $counter (keys %{$json_data}) { - next if ($counter !~ /shm/); - my $value = $json_data->{$counter}->{value}; - $counter =~ s/^([A-Z])+\.//; - $self->{shm}->{$counter} = $value; - } -}; - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 -j 2>&1') - -=item B<--warning-*> - -Warning Threshold for: -records => SHM records, -writes => SHM writes, -flushes => SHM flushes due to overflow, -cont => SHM MTX contention, -cycles => SHM cycles through buffer - -=item B<--critical-*> - -Critical Threshold for: -records => SHM records, -writes => SHM writes, -flushes => SHM flushes due to overflow, -cont => SHM MTX contention, -cycles => SHM cycles through buffer - -=back - -=cut diff --git a/apps/varnish/local/mode/sms.pm b/apps/varnish/local/mode/sms.pm deleted file mode 100644 index 9ca539c9a..000000000 --- a/apps/varnish/local/mode/sms.pm +++ /dev/null @@ -1,260 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::sms; - -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); - -my $maps_counters = { - sms_nreq => { thresholds => { - warning_nreq => { label => 'warning-nreq', exit_value => 'warning' }, - critical_nreq => { label => 'critical-nreq', exit_value => 'critical' }, - }, - output_msg => 'SMS allocator requests: %.2f', - factor => 1, unit => '', - }, - sms_nobj => { thresholds => { - warning_nobj => { label => 'warning-nobj', exit_value => 'warning' }, - critical_nobj => { label => 'critical-nobj', exit_value => 'critical' }, - }, - output_msg => 'SMS outstanding allocations: %.2f', - factor => 1, unit => '', - }, - sms_nbytes => { thresholds => { - warning_nbytes => { label => 'warning-nbytes', exit_value => 'warning' }, - critical_nbytes => { label => 'critical-nbytes', exit_value => 'critical' }, - }, - output_msg => 'SMS outstanding bytes: %.2f', - factor => 1, unit => '', - }, - sms_balloc => { thresholds => { - warning_balloc => { label => 'warning-balloc', exit_value => 'warning' }, - critical_balloc => { label => 'critical-balloc', exit_value => 'critical' }, - }, - output_msg => 'SMS bytes allocated: %.2f', - factor => 1, unit => '', - }, - sms_bfree => { thresholds => { - warning_bfree => { label => 'warning-bfree', exit_value => 'warning' }, - critical_bfree => { label => 'critical-bfree', exit_value => 'critical' }, - }, - output_msg => 'SMS bytes freed: %.2f', - factor => 1, unit => '', - }, -}; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, - }); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - return $self; -}; - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options} . $self->{option_results}->{command_options2}); - #print $stdout; - - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text - - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; - -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 ') - -=item B<--warning-*> - -Warning Threshold for: -nreq => SMS allocator requests, -nobj => SMS outstanding allocations, -nbytes => SMS outstanding bytes, -balloc => SMS bytes allocated, -bfree => SMS bytes freed - -=item B<--critical-*> - -Critical Threshold for: -nreq => SMS allocator requests, -nobj => SMS outstanding allocations, -nbytes => SMS outstanding bytes, -balloc => SMS bytes allocated, -bfree => SMS bytes freed - -=back - -=cut \ No newline at end of file diff --git a/apps/varnish/local/mode/stats.pm b/apps/varnish/local/mode/stats.pm new file mode 100644 index 000000000..3add27c66 --- /dev/null +++ b/apps/varnish/local/mode/stats.pm @@ -0,0 +1,334 @@ +# +# Copyright 2019 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 apps::varnish::local::mode::stats; + +use base qw(centreon::plugins::templates::counter); +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use JSON::XS; + +sub configure_varnish_stats { + my ($self, %options) = @_; + + $self->{varnish_stats} = [ + { entry => 'client_conn', nlabel => 'connections.client.accepted.persecond', display_ok => 1, diff => 1, per_second => 1 }, + { entry => 'client_drop', nlabel => 'connections.client.dropped.persecond', display_ok => 1, diff => 1, per_second => 1 }, + { entry => 'client_req', nlabel => 'connections.client.request.received.persecond', display_ok => 1, diff => 1, per_second => 1 }, + { entry => 'client_drop_late', nlabel => 'connections.client.dropped.late.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'client_req_400', nlabel => 'connections.client.request400.received.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'client_req_411', nlabel => 'connections.client.request411.received.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'client_req_413', nlabel => 'connections.client.request413.received.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'client_req_417', nlabel => 'connections.client.request417.received.persecond', display_ok => 0, diff => 1, per_second => 1 }, + + { entry => 'backend_conn', nlabel => 'backends.connections.success.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'backend_unhealthy', nlabel => 'backends.connections.unhealthy.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'backend_busy', nlabel => 'backends.connections.busy.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'backend_fail', nlabel => 'backends.connections.fail.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'backend_reuse', nlabel => 'backends.connections.reuse.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'backend_recycle', nlabel => 'backends.connections.recycle.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'backend_retry', nlabel => 'backends.connections.retry.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'backend_req', nlabel => 'backends.requests.persecond', display_ok => 0, diff => 1, per_second => 1 }, + + { entry => 'cache_hit', nlabel => 'cache.hit.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'cache_hitpass', nlabel => 'cache.hitpass.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'cache_miss', nlabel => 'cache.miss.persecond', display_ok => 0, diff => 1, per_second => 1 }, + + { entry => 'n_sess_mem', nlabel => 'structure.session.memory.count', display_ok => 0 }, + { entry => 'n_sess', nlabel => 'structure.session.count', display_ok => 0 }, + { entry => 'n_sess', nlabel => 'structure.session.count', display_ok => 0 }, + { entry => 'n_object', nlabel => 'structure.object.count', display_ok => 0 }, + { entry => 'n_vampireobject', nlabel => 'object.unresurrected.count', display_ok => 0 }, + { entry => 'n_objectcore', nlabel => 'structure.objectcore.count', display_ok => 0 }, + { entry => 'n_objecthead', nlabel => 'structure.objecthead.count', display_ok => 0 }, + { entry => 'n_waitinglist', nlabel => 'structure.waitinglist.count', display_ok => 0 }, + { entry => 'n_vbc', nlabel => 'structure.vbc.count', display_ok => 0 }, + { entry => 'n_backend', nlabel => 'backend.count', display_ok => 0 }, + { entry => 'n_expired', nlabel => 'object.expired.count', display_ok => 0 }, + { entry => 'n_lru_nuked', nlabel => 'object.lru.nuked.count', display_ok => 0 }, + { entry => 'n_lru_moved', nlabel => 'object.lru.moved.count', display_ok => 0 }, + + { entry => 'n_objsendfile', nlabel => 'object.sent.file.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'n_objwrite', nlabel => 'object.sent.write.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'n_objoverflow', nlabel => 'object.overflow.workspace.persecond', display_ok => 0, diff => 1, per_second => 1 }, + + { entry => 'shm_records', nlabel => 'shm.records.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'shm_writes', nlabel => 'shm.writes.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'shm_flushes', nlabel => 'shm.flushes.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'shm_cont', nlabel => 'shm.contentions.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'shm_cycles', nlabel => 'shm.cycles.persecond', display_ok => 0, diff => 1, per_second => 1 }, + + { entry => 'sms_nreq', nlabel => 'sms.allocator.requests.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'sms_nobj', nlabel => 'sms.outstanding.allocations.count', display_ok => 0 }, + { entry => 'sms_nbytes', nlabel => 'sms.outstanding.bytes', display_ok => 0, custom_output => $self->can('custom_output_scale_bytes') }, + { entry => 'sms_balloc', nlabel => 'sms.outstanding.allocated.bytes', display_ok => 0, custom_output => $self->can('custom_output_scale_bytes') }, + { entry => 'sms_bfree', nlabel => 'sms.outstanding.freed.bytes', display_ok => 0, custom_output => $self->can('custom_output_scale_bytes') }, + + { entry => 'fetch_head', nlabel => 'fetch.head.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'fetch_length', nlabel => 'fetch.length.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'fetch_chunked', nlabel => 'fetch.chunked.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'fetch_eof', nlabel => 'fetch.eof.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'fetch_bad', nlabel => 'fetch.badheaders.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'fetch_close', nlabel => 'fetch.close.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'fetch_oldhttp', nlabel => 'fetch.oldhttp.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'fetch_zero', nlabel => 'fetch.zero.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'fetch_failed', nlabel => 'fetch.failed.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'fetch_1xx', nlabel => 'fetch.1xx.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'fetch_204', nlabel => 'fetch.204.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'fetch_304', nlabel => 'fetch.304.persecond', display_ok => 0, diff => 1, per_second => 1 }, + + { entry => 'n_ban', nlabel => 'ban.total.active.count', display_ok => 0 }, + { entry => 'n_ban_add', nlabel => 'ban.new.added.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'n_ban_retire', nlabel => 'ban.old.deleted.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'n_ban_obj_test', nlabel => 'ban.object.tested.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'n_ban_re_test', nlabel => 'ban.object.tested.regexp.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'n_ban_dups', nlabel => 'ban.duplicate.removed.persecond', display_ok => 0, diff => 1, per_second => 1 }, + + { entry => 'dir_dns_lookups', nlabel => 'dns.director.lookups.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'dir_dns_failed', nlabel => 'dns.director.lookups.failed.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'dir_dns_hit', nlabel => 'dns.director.lookups.cachehit.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'dir_dns_cache_full', nlabel => 'dns.director.cache.full.persecond', display_ok => 0, diff => 1, per_second => 1 }, + + { entry => 'esi_errors', nlabel => 'esi.parse.errors.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'esi_warnings', nlabel => 'esi.parse.warnings.persecond', display_ok => 0, diff => 1, per_second => 1 }, + + { entry => 'hcb_nolock', nlabel => 'hck.lookups.nolock.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'hcb_lock', nlabel => 'hck.lookups.lock.persecond', display_ok => 0, diff => 1, per_second => 1 }, + { entry => 'hcb_insert', nlabel => 'hck.inserts.persecond', display_ok => 0, diff => 1, per_second => 1 }, + + { entry => 'n_vcl', nlabel => 'vlc.total.count', display_ok => 0, diff => 1 }, + { entry => 'n_vcl_avail', nlabel => 'vlc.available.count', display_ok => 0, diff => 1 }, + { entry => 'n_vcl_discard', nlabel => 'vlc.discarded.count', display_ok => 0, diff => 1 }, + + { entry => 'sess_conn', nlabel => 'sessions.accepted.count', display_ok => 0, diff => 1 }, + { entry => 'sess_drop', nlabel => 'sessions.dropped.count', display_ok => 0, diff => 1 }, + { entry => 'sess_fail', nlabel => 'sessions.failed.count', display_ok => 0, diff => 1 }, + { entry => 'sess_pipe_overflow', nlabel => 'sessions.pipe.overflow.count', display_ok => 0, diff => 1 }, + { entry => 'sess_queued', nlabel => 'sessions.queued.count', display_ok => 0, diff => 1 }, + { entry => 'sess_readahead', nlabel => 'sessions.readahead.count', display_ok => 0, diff => 1 }, + { entry => 'sess_closed', nlabel => 'sessions.closed.count', display_ok => 0, diff => 1 }, + { entry => 'sess_herd', nlabel => 'sessions.herd.count', display_ok => 0, diff => 1 }, + { entry => 'sess_linger', nlabel => 'sessions.linger.count', display_ok => 0, diff => 1 }, + { entry => 'sess_closed', nlabel => 'sessions.closed.count', display_ok => 0, diff => 1 }, + { entry => 'sess_pipeline', nlabel => 'sessions.pipeline.count', display_ok => 0, diff => 1 }, + + { entry => 'threads', nlabel => 'threads.total.count', display_ok => 0 }, + { entry => 'threads_created', nlabel => 'threads.created.count', display_ok => 0, diff => 1 }, + { entry => 'threads_limited', nlabel => 'threads.limited.count', display_ok => 0, diff => 1 }, + { entry => 'threads_destroyed', nlabel => 'threads.destroyed.count', display_ok => 0, diff => 1 }, + { entry => 'threads_failed', nlabel => 'threads.failed.count', display_ok => 0, diff => 1 }, + { entry => 'thread_queue_len', nlabel => 'threads.queue.length.count', display_ok => 0 }, + + { entry => 's_sess', nlabel => 'total.sessions.seen.count', display_ok => 0, diff => 1 }, + { entry => 's_req', nlabel => 'total.requests.count', display_ok => 0, diff => 1 }, + { entry => 's_fetch', nlabel => 'total.backends.fetch.count', display_ok => 0, diff => 1 }, + + { entry => 'n_wrk', nlabel => 'workers.threads.count', display_ok => 0 }, + { entry => 'n_wrk_create', nlabel => 'workers.threads.created.count', display_ok => 0, diff => 1 }, + { entry => 'n_wrk_failed', nlabel => 'workers.threads.failed.count', display_ok => 0, diff => 1 }, + { entry => 'n_wrk_max', nlabel => 'workers.threads.limited.count', display_ok => 0, diff => 1 }, + { entry => 'n_wrk_lqueue', nlabel => 'workers.requests.queue.length.count', display_ok => 0, diff => 1 }, + { entry => 'n_wrk_queued', nlabel => 'workers.requests.queued.count', display_ok => 0, diff => 1 }, + { entry => 'n_wrk_drop', nlabel => 'workers.requests.dropped.count', display_ok => 0, diff => 1 }, + ]; +} + +sub custom_output_scale_bytes { + my ($self, %options) = @_; + + my $label = $self->{label}; + $label =~ s/-/_/g; + my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{$label . '_absolute'}); + my $msg = sprintf('%s: %.2f %s', $self->{result_values}->{$label . '_description_absolute'}, $value, $unit); + return $msg; +} + +sub custom_output_second { + my ($self, %options) = @_; + + my $label = $self->{label}; + $label =~ s/-/_/g; + my $msg = sprintf('%s: %.2f/s', $self->{result_values}->{$label . '_description_absolute'}, $self->{result_values}->{$label . '_per_second'}); + return $msg; +} + +sub custom_output { + my ($self, %options) = @_; + + my $label = $self->{label}; + $label =~ s/-/_/g; + my $msg = sprintf('%s: %s', $self->{result_values}->{$label . '_description_absolute'}, $self->{result_values}->{$label . '_absolute'}); + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->configure_varnish_stats(); + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = []; + foreach (@{$self->{varnish_stats}}) { + my $label = $_->{entry}; + $label =~ s/_/-/g; + push @{$self->{maps_counters}->{global}}, + { label => $label, nlabel => $_->{nlabel}, display_ok => $_->{display_ok}, set => { + key_values => [ { name => $_->{entry}, diff => $_->{diff} }, { name => $_->{entry}. '_description' } ], + closure_custom_output => defined($_->{custom_output}) ? $_->{custom_output} : + (defined($_->{per_second}) ? $self->can('custom_output_second') : $self->can('custom_output')), + per_second => $_->{per_second}, + perfdatas => [ + { label => $_->{entry}, value => $_->{entry} . (defined($_->{per_second}) ? '_per_second' : '_absolute'), + template => defined($_->{per_second}) ? '%.2f' : '%s', + min => 0 }, + ], + } + } + ; + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + 'hostname:s' => { name => 'hostname' }, + 'remote' => { name => 'remote' }, + 'ssh-option:s@' => { name => 'ssh_option' }, + 'ssh-path:s' => { name => 'ssh_path' }, + 'ssh-command:s' => { name => 'ssh_command', default => 'ssh' }, + 'timeout:s' => { name => 'timeout', default => 30 }, + 'sudo' => { name => 'sudo' }, + 'command:s' => { name => 'command', default => 'varnishstat' }, + 'command-path:s' => { name => 'command_path', default => '/usr/bin' }, + 'command-options:s' => { name => 'command_options', default => ' -1 -j 2>&1' }, + }); + + return $self; +} + +sub check_varnish_old { + my ($self, %options) = @_; + + return if (!defined($options{json}->{uptime})); + # "cache_hit": {"value": 56320, "flag": "a", "description": "Cache hits"}, + # "cache_hitpass": {"value": 0, "flag": "a", "description": "Cache hits for pass"}, + foreach (@{$self->{varnish_stats}}) { + next if (!defined($options{json}->{$_->{entry}})); + $self->{global}->{$_->{entry}} = $options{json}->{$_->{entry}}->{value}; + $self->{global}->{$_->{entry} . '_description'} = $options{json}->{$_->{entry}}->{description}; + } +} + +sub check_varnish_new { + my ($self, %options) = @_; + + return if (!defined($options{json}->{'MAIN.uptime'})); + + # "MAIN.cache_hit": {"type": "MAIN", "value": 18437, "flag": "a", "description": "Cache hits"}, + # "MAIN.cache_hitpass": {"type": "MAIN", "value": 3488, "flag": "a", "description": "Cache hits for pass"}, + # "MAIN.cache_miss": {"type": "MAIN", "value": 5782, "flag": "a", "description": "Cache misses"}, + foreach (@{$self->{varnish_stats}}) { + next if (!defined($options{json}->{'MAIN.' . $_->{entry}})); + $self->{global}->{$_->{entry}} = $options{json}->{'MAIN.' . $_->{entry}}->{value}; + $self->{global}->{$_->{entry} . '_description'} = $options{json}->{'MAIN.' . $_->{entry}}->{description}; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my ($stdout) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options} + ); + + $self->{global} = {}; + + my $content; + eval { + $content = JSON::XS->new->utf8->decode($stdout); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + $self->check_varnish_old(json => $content); + $self->check_varnish_new(json => $content); + + $self->{cache_name} = "cache_varnish_" . $self->{mode} . '_' . + (defined($self->{option_results}->{hostname}) ? md5_hex($self->{option_results}->{hostname}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +}; + + +1; + +__END__ + +=head1 MODE + +Check statistics with varnishstat command + +=over 8 + +=item B<--remote> + +If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. + +=item B<--hostname> + +Hostname to query (need --remote). + +=item B<--ssh-option> + +Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). + +=item B<--command> + +Varnishstat Binary Filename (Default: varnishstat) + +=item B<--command-path> + +Directory Path to Varnishstat Binary File (Default: /usr/bin) + +=item B<--command-options> + +Parameter for Binary File (Default: ' -1 -j 2>&1') + +=item B<--warning-[countername]> B<--critical-[countername]> + +Thresholds. Use option --list-counters to see available counters + +=back + +=cut diff --git a/apps/varnish/local/mode/threads.pm b/apps/varnish/local/mode/threads.pm deleted file mode 100644 index 0511382bb..000000000 --- a/apps/varnish/local/mode/threads.pm +++ /dev/null @@ -1,203 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::threads; - -use base qw(centreon::plugins::templates::counter); -use strict; -use warnings; -use Digest::MD5 qw(md5_hex); -use JSON; - -sub set_counters { - my ($self, %options) = @_; - - $self->{maps_counters_type} = [ - { name => 'threads', type => 0, skipped_code => { -10 => 1 } }, - ]; - $self->{maps_counters}->{threads} = [ - { label => 'total', set => { - key_values => [ { name => 'threads' } ], - output_template => 'Total Threads: %d', output_error_template => "Total Threads: %s", - perfdatas => [ - { label => 'total', value => 'threads_absolute', template => '%d', - min => 0 }, - ], - } - }, - { label => 'created', set => { - key_values => [ { name => 'threads_created', diff => 1 } ], - output_template => 'Thread created: %.2f/s', output_error_template => "Thread created: %s", - per_second => 1, - perfdatas => [ - { label => 'created', value => 'threads_created_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'limited', set => { - key_values => [ { name => 'threads_limited', diff => 1 } ], - output_template => 'Thread limited: %.2f/s', output_error_template => "Thread limited: %s", - per_second => 1, - perfdatas => [ - { label => 'limited', value => 'threads_limited_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'destroyed', set => { - key_values => [ { name => 'threads_destroyed', diff => 1 } ], - output_template => 'Thread destroyed: %.2f/s', output_error_template => "Thread destroyed: %s", - per_second => 1, - perfdatas => [ - { label => 'destroyed', value => 'threads_destroyed_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'failed', set => { - key_values => [ { name => 'threads_failed', diff => 1 } ], - output_template => 'Threads fail: %.2f/s', output_error_template => "Threads fail: %s", - per_second => 1, - perfdatas => [ - { label => 'failed', value => 'threads_failed_per_second', template => '%.2f', - min => 0 }, - ], - } - }, - { label => 'queue', set => { - key_values => [ { name => 'thread_queue_len' } ], - output_template => 'Thread queue lenght: %d', output_error_template => "Thread queue lenght: %d", - perfdatas => [ - { label => 'queue_lenght', value => 'thread_queue_len_absolute', template => '%d', - min => 0 }, - ], - } - }, - ], -} - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); - bless $self, $class; - - $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 -j 2>&1' }, - }); - - return $self; -}; - -sub manage_selection { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - -# "MAIN.threads_limited": {"type": "MAIN", "value": 0, "flag": "c", "description": "Threads hit max"}, -# "MAIN.threads_created": {"type": "MAIN", "value": 100, "flag": "c", "description": "Threads created"}, -# "MAIN.threads_destroyed": {"type": "MAIN", "value": 0, "flag": "c", "description": "Threads destroyed"}, -# "MAIN.threads_failed": {"type": "MAIN", "value": 0, "flag": "c", "description": "Thread creation failed"}, -# "MAIN.thread_queue_len": {"type": "MAIN", "value": 0, "flag": "g", "description": "Length of session queue"}, - - my $json_data = decode_json($stdout); - - $self->{cache_name} = "cache_varnish_" . $self->{mode} . '_' . - (defined($self->{option_results}->{hostname}) ? md5_hex($self->{option_results}->{hostname}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); - - foreach my $counter (keys %{$json_data}) { - next if ($counter !~ /^([A-Z])+\.thread.*/); - my $value = $json_data->{$counter}->{value}; - $counter =~ s/^([A-Z])+\.//; - print "$counter ===> $value \n"; - $self->{threads}->{$counter} = $value; - } -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish 4 Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 -j 2>&1') - -=item B<--warning-*> - -Warning Threshold for threads. -Can be: - (created, destroyed, limited, failed) [per sec] - (total, queue lenght) [absolute] - -=item B<--critical-*> - -Warning Threshold for threads. -Can be: - (created, destroyed, limited, failed) [per sec] - (total, queue lenght) [absolute] - -=back - -=cut - diff --git a/apps/varnish/local/mode/totals.pm b/apps/varnish/local/mode/totals.pm deleted file mode 100644 index f3b71141a..000000000 --- a/apps/varnish/local/mode/totals.pm +++ /dev/null @@ -1,287 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::totals; - -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); - -my $maps_counters = { - s_sess => { thresholds => { - warning_sess => { label => 'warning-sess', exit_value => 'warning' }, - critical_sess => { label => 'critical-sess', exit_value => 'critical' }, - }, - output_msg => 'Total Sessions: %.2f', - factor => 1, unit => '', - }, - s_req => { thresholds => { - warning_req => { label => 'warning-req', exit_value => 'warning' }, - critical_req => { label => 'critical-req', exit_value => 'critical' }, - }, - output_msg => 'Total Requests: %.2f', - factor => 1, unit => '', - }, - s_pipe => { thresholds => { - warning_pipe => { label => 'warning-pipe', exit_value => 'warning' }, - critical_pipe => { label => 'critical-pipe', exit_value => 'critical' }, - }, - output_msg => 'Total pipe: %.2f', - factor => 1, unit => '', - }, - s_pass => { thresholds => { - warning_pass => { label => 'warning-pass', exit_value => 'warning' }, - critical_pass => { label => 'critical-pass', exit_value => 'critical' }, - }, - output_msg => 'Total pass: %.2f', - factor => 1, unit => '', - }, - s_fetch => { thresholds => { - warning_fetch => { label => 'warning-fetch', exit_value => 'warning' }, - critical_fetch => { label => 'critical-fetch', exit_value => 'critical' }, - }, - output_msg => 'Total fetch: %.2f', - factor => 1, unit => '', - }, - s_hdrbytes => { thresholds => { - warning_hdrbytes => { label => 'warning-hdrbytes', exit_value => 'warning' }, - critical_hdrbytes => { label => 'critical-hdrbytes', exit_value => 'critical' }, - }, - output_msg => 'Total header bytes: %.2f', - factor => 1, unit => '', - }, - s_bodybytes => { thresholds => { - warning_bodybytes => { label => 'warning-bodybytes', exit_value => 'warning' }, - critical_bodybytes => { label => 'critical-bodybytes', exit_value => 'critical' }, - }, - output_msg => 'Total body bytes: %.2f', - factor => 1, unit => '', - }, - accept_fail => { thresholds => { - warning_fail => { label => 'warning-fail', exit_value => 'warning' }, - critical_fail => { label => 'critical-fail', exit_value => 'critical' }, - }, - output_msg => 'Accept failures: %.2f', - factor => 1, unit => '', - }, -}; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, - }); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - return $self; -}; - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options} . $self->{option_results}->{command_options2}); - #print $stdout; - - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text - - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; - -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 ') - -=item B<--warning-*> - -Warning Threshold for: -sess => Total Sessions, -req => Total Requests, -pipe => Total pipe, -pass => Total pass, -fetch => Total fetch, -hdrbytes => Total header bytes, -bodybytes => Total body bytes, -fail => Accept failures - -=item B<--critical-*> - -Critical Threshold for: -sess => Total Sessions, -req => Total Requests, -pipe => Total pipe, -pass => Total pass, -fetch => Total fetch, -hdrbytes => Total header bytes, -bodybytes => Total body bytes, -fail => Accept failures - -=back - -=cut \ No newline at end of file diff --git a/apps/varnish/local/mode/uptime.pm b/apps/varnish/local/mode/uptime.pm deleted file mode 100644 index 95eb5d684..000000000 --- a/apps/varnish/local/mode/uptime.pm +++ /dev/null @@ -1,222 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::uptime; - -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); - -my $maps_counters = { - uptime => { thresholds => { - warning => { label => 'warning', exit_value => 'warning' }, - critical => { label => 'critical', exit_value => 'critical' }, - }, - output_msg => 'Uptime in sec: %.2f', - factor => 1, unit => '', - }, -}; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, - }); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - return $self; -}; - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options} . $self->{option_results}->{command_options2}); - #print $stdout; - - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text - - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; - -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 ') - -=item B<--warning> - -Warning Threshold for Uptime - -=item B<--critical> - -Critical Threshold for Uptime - -=back - -=cut \ No newline at end of file diff --git a/apps/varnish/local/mode/vcl.pm b/apps/varnish/local/mode/vcl.pm deleted file mode 100644 index e6f305d72..000000000 --- a/apps/varnish/local/mode/vcl.pm +++ /dev/null @@ -1,243 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::vcl; - -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); - -#n_vcl_avail could be max from n_vcl -my $maps_counters = { - n_vcl => { thresholds => { - warning_total => { label => 'warning-total', exit_value => 'warning' }, - critical_total => { label => 'critical-total', exit_value => 'critical' }, - }, - output_msg => 'N vcl total: %.2f', - factor => 1, unit => '', - }, - n_vcl_avail => { thresholds => { - warning_avail => { label => 'warning-avail', exit_value => 'warning' }, - critical_avail => { label => 'critical-avail', exit_value => 'critical' }, - }, - output_msg => 'N vcl available: %.2f', - factor => 1, unit => '', - }, - n_vcl_discard => { thresholds => { - warning_discard => { label => 'warning-discard', exit_value => 'warning' }, - critical_discard => { label => 'critical-discard', exit_value => 'critical' }, - }, - output_msg => 'N vcl discarded: %.2f', - factor => 1, unit => '', - }, -}; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, - }); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - return $self; -}; - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options} . $self->{option_results}->{command_options2}); - #print $stdout; - - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text - - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; - -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 ') - -=item B<--warning-*> - -Warning Threshold for: -total => N vcl total, -avail => N vcl available, -discard => N vcl discarded - -=item B<--critical-*> - -Critical Threshold for: -total => N vcl total, -avail => N vcl available, -discard => N vcl discarded - -=back - -=cut \ No newline at end of file diff --git a/apps/varnish/local/mode/workers.pm b/apps/varnish/local/mode/workers.pm deleted file mode 100644 index 54e45c475..000000000 --- a/apps/varnish/local/mode/workers.pm +++ /dev/null @@ -1,278 +0,0 @@ -# -# Copyright 2019 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 apps::varnish::local::mode::workers; - -use base qw(centreon::plugins::mode); -use centreon::plugins::misc; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); - -my $maps_counters = { - n_wrk => { thresholds => { - warning_workers => { label => 'warning-workers', exit_value => 'warning' }, - critical_workers => { label => 'critical-workers', exit_value => 'critical' }, - }, - output_msg => 'Backend conn. success: %.2f', - factor => 1, unit => '', - }, - n_wrk_create => { thresholds => { - warning_create => { label => 'warning-create', exit_value => 'warning' }, - critical_create => { label => 'critical-create', exit_value => 'critical' }, - }, - output_msg => 'Backend conn. not attempted: %.2f', - factor => 1, unit => '', - }, - n_wrk_failed => { thresholds => { - warning_failed => { label => 'warning-failed', exit_value => 'warning' }, - critical_failed => { label => 'critical-failed', exit_value => 'critical' }, - }, - output_msg => 'Backend conn. too many: %.2f', - factor => 1, unit => '', - }, - n_wrk_max => { thresholds => { - warning_max => { label => 'warning-max', exit_value => 'warning' }, - critical_max => { label => 'critical-max', exit_value => 'critical' }, - }, - output_msg => 'Backend conn. failures: %.2f', - factor => 1, unit => '', - }, - n_wrk_lqueue => { thresholds => { - warning_lqueue => { label => 'warning-lqueue', exit_value => 'warning' }, - critical_lqueue => { label => 'critical-lqueue', exit_value => 'critical' }, - }, - output_msg => 'Backend conn. reuses: %.2f', - factor => 1, unit => '', - }, - n_wrk_queued => { thresholds => { - warning_queued => { label => 'warning-queued', exit_value => 'warning' }, - critical_queued => { label => 'critical-queued', exit_value => 'critical' }, - }, - output_msg => 'Backend conn. was closed: %.2f', - factor => 1, unit => '', - }, - n_wrk_drop => { thresholds => { - warning_drop => { label => 'warning-drop', exit_value => 'warning' }, - critical_drop => { label => 'critical-drop', exit_value => 'critical' }, - }, - output_msg => 'Backend conn. recycles: %.2f', - factor => 1, unit => '', - }, -}; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'varnishstat' }, - "command-path:s" => { name => 'command_path', default => '/usr/bin' }, - "command-options:s" => { name => 'command_options', default => ' -1 ' }, - "command-options2:s" => { name => 'command_options2', default => ' 2>&1' }, - }); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - }; - }; - - $self->{instances_done} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - return $self; -}; - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - }; - }; - }; - $self->{statefile_value}->check_options(%options); -}; - -sub getdata { - my ($self, %options) = @_; - - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options} . $self->{option_results}->{command_options2}); - #print $stdout; - - foreach (split(/\n/, $stdout)) { - #client_conn 7390867 1.00 Client connections - # - Symbolic entry name - # - Value - # - Per-second average over process lifetime, or a period if the value can not be averaged - # - Descriptive text - - if (/^(.\S*)\s*([0-9]*)\s*([0-9.]*)\s(.*)$/i) { - #print "FOUND: " . $1 . "=" . $2 . "\n"; - $self->{result}->{$1} = $2; - }; - }; -}; - -sub run { - my ($self, %options) = @_; - - $self->getdata(); - - $self->{statefile_value}->read(statefile => 'cache_apps_varnish' . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $self->{result}->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - # Calculate - my $delta_time = $self->{result}->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - - foreach (keys %{$maps_counters}) { - #print $_ . "\n"; - $self->{old_cache}->{$_} = $self->{statefile_value}->get(name => '$_'); # Get Data from Cache - $self->{old_cache}->{$_} = 0 if ( $self->{old_cache}->{$_} > $self->{result}->{$_} ); - $self->{outputdata}->{$_} = ($self->{result}->{$_} - $self->{old_cache}->{$_}) / $delta_time; - }; - - # Write Cache if not there - $self->{statefile_value}->write(data => $self->{result}); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{outputdata}->{$_}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - - - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = ""; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{outputdata}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - - $self->{output}->display(); - $self->{output}->exit(); -}; - - -1; - -__END__ - -=head1 MODE - -Check Varnish Cache with varnishstat Command - -=over 8 - -=item B<--remote> - -If you dont run this script locally, if you wanna use it remote, you can run it remotely with 'ssh'. - -=item B<--hostname> - -Hostname to query (need --remote). - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--command> - -Varnishstat Binary Filename (Default: varnishstat) - -=item B<--command-path> - -Directory Path to Varnishstat Binary File (Default: /usr/bin) - -=item B<--command-options> - -Parameter for Binary File (Default: ' -1 ') - -=item B<--warning-*> - -Warning Threshold for: -workers => N worker threads, -create => N worker threads created, -failed => N worker threads not created, -max => N worker threads limited, -lqueue => work request queue length, -queued => N queued work requests, -drop => N dropped work requests - -=item B<--critical-*> - -Critical Threshold for: -workers => N worker threads, -create => N worker threads created, -failed => N worker threads not created, -max => N worker threads limited, -lqueue => work request queue length, -queued => N queued work requests, -drop => N dropped work requests - -=back - -=cut \ No newline at end of file diff --git a/apps/varnish/local/plugin.pm b/apps/varnish/local/plugin.pm index 816aefc3b..aa3563322 100644 --- a/apps/varnish/local/plugin.pm +++ b/apps/varnish/local/plugin.pm @@ -30,27 +30,9 @@ sub new { bless $self, $class; $self->{version} = '0.1'; - %{$self->{modes}} = ( - 'connections' => 'apps::varnish::local::mode::connections', - 'clients' => 'apps::varnish::local::mode::clients', - 'cache' => 'apps::varnish::local::mode::cache', - 'backend' => 'apps::varnish::local::mode::backend', - 'sessions' => 'apps::varnish::local::mode::sessions', - 'fetch' => 'apps::varnish::local::mode::fetch', - 'workers' => 'apps::varnish::local::mode::workers', - 'totals' => 'apps::varnish::local::mode::totals', - 'objects' => 'apps::varnish::local::mode::objects', - 'uptime' => 'apps::varnish::local::mode::uptime', - 'bans' => 'apps::varnish::local::mode::bans', - 'dns' => 'apps::varnish::local::mode::dns', - 'shm' => 'apps::varnish::local::mode::shm', - 'vcl' => 'apps::varnish::local::mode::vcl', - 'n' => 'apps::varnish::local::mode::n', - 'sms' => 'apps::varnish::local::mode::sms', - 'hcb' => 'apps::varnish::local::mode::hcb', - 'esi' => 'apps::varnish::local::mode::esi', - 'threads' => 'apps::varnish::local::mode::threads', - ); + %{$self->{modes}} = ( + 'stats' => 'apps::varnish::local::mode::stats', + ); return $self; } diff --git a/apps/video/zixi/restapi/custom/api.pm b/apps/video/zixi/restapi/custom/api.pm index ced835c5c..416ee7ed6 100644 --- a/apps/video/zixi/restapi/custom/api.pm +++ b/apps/video/zixi/restapi/custom/api.pm @@ -40,23 +40,20 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s@" => { name => 'hostname' }, - "port:s@" => { name => 'port' }, - "proto:s@" => { name => 'proto' }, - "username:s@" => { name => 'username' }, - "password:s@" => { name => 'password' }, - "proxyurl:s@" => { name => 'proxyurl' }, - "timeout:s@" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s@" => { name => 'hostname' }, + "port:s@" => { name => 'port' }, + "proto:s@" => { name => 'proto' }, + "username:s@" => { name => 'username' }, + "password:s@" => { name => 'password' }, + "timeout:s@" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; @@ -100,7 +97,6 @@ sub check_options { $self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : ''; $self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{password}}) : ''; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef; if (!defined($self->{hostname})) { $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); @@ -121,7 +117,6 @@ sub build_options_for_httplib { $self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{port} = $self->{port}; $self->{option_results}->{proto} = $self->{proto}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; $self->{option_results}->{credentials} = 1; $self->{option_results}->{basic} = 1; $self->{option_results}->{username} = $self->{username}; @@ -194,18 +189,10 @@ Zixi username. Zixi password. -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/apps/video/zixi/restapi/mode/broadcasterlicenseusage.pm b/apps/video/zixi/restapi/mode/broadcasterlicenseusage.pm index c1d4eb6d4..90e712a01 100644 --- a/apps/video/zixi/restapi/mode/broadcasterlicenseusage.pm +++ b/apps/video/zixi/restapi/mode/broadcasterlicenseusage.pm @@ -54,19 +54,21 @@ sub custom_usage_perfdata { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); if ($self->{result_values}->{total} =~ /[0-9]/ && $self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total} =~ /[0-9]/ ? $self->{result_values}->{total} : undef); + $self->{output}->perfdata_add( + label => $label, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} =~ /[0-9]/ ? $self->{result_values}->{total} : undef + ); } sub custom_usage_threshold { @@ -79,7 +81,7 @@ sub custom_usage_threshold { $threshold_value = $self->{result_values}->{prct_used}; $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } diff --git a/apps/virtualization/ovirt/custom/api.pm b/apps/virtualization/ovirt/custom/api.pm new file mode 100644 index 000000000..313b5eda8 --- /dev/null +++ b/apps/virtualization/ovirt/custom/api.pm @@ -0,0 +1,329 @@ +# +# Copyright 2019 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 apps::virtualization::ovirt::custom::api; + +use strict; +use warnings; +use DateTime; +use centreon::plugins::http; +use centreon::plugins::statefile; +use JSON::XS; +use URI::Encode; +use Digest::MD5 qw(md5_hex); + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "api-username:s" => { name => 'api_username' }, + "api-password:s" => { name => 'api_password' }, + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "timeout:s" => { name => 'timeout' }, + "reload-cache-time:s" => { name => 'reload_cache_time' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{http} = centreon::plugins::http->new(%options); + $self->{cache} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : ''; + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443; + $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; + $self->{api_username} = (defined($self->{option_results}->{api_username})) ? $self->{option_results}->{api_username} : ''; + $self->{api_password} = (defined($self->{option_results}->{api_password})) ? $self->{option_results}->{api_password} : ''; + $self->{reload_cache_time} = (defined($self->{option_results}->{reload_cache_time})) ? $self->{option_results}->{reload_cache_time} : 180; + + $self->{cache}->check_options(option_results => $self->{option_results}); + + return 0; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{warning_status} = ''; + $self->{option_results}->{critical_status} = ''; + $self->{option_results}->{unknown_status} = '%{http_code} < 200 or %{http_code} > 400'; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->add_header(key => 'Accept', value => 'application/json'); + $self->{http}->add_header(key => 'Content-Type', value => 'application/x-www-form-urlencoded'); + if (defined($self->{access_token})) { + $self->{http}->add_header(key => 'Authorization', value => 'Bearer ' . $self->{access_token}); + } + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub get_access_token { + my ($self, %options) = @_; + + my $has_cache_file = $options{statefile}->read(statefile => 'ovirt_api_' . md5_hex($self->{hostname}) . '_' . md5_hex($self->{api_username})); + my $expires_on = $options{statefile}->get(name => 'expires_on'); + my $access_token = $options{statefile}->get(name => 'access_token'); + + if ($has_cache_file == 0 || !defined($access_token) || (($expires_on - time()) < 10)) { + my $uri = URI::Encode->new({encode_reserved => 1}); + my $encoded_username = $uri->encode($self->{api_username}); + my $encoded_password = $uri->encode($self->{api_password}); + my $post_data = 'grant_type=password' . + '&scope=ovirt-app-api' . + '&username=' . $encoded_username . + '&password=' . $encoded_password; + + $self->settings(); + + my $content = $self->{http}->request( + method => 'POST', + query_form_post => $post_data, + url_path => '/ovirt-engine/sso/oauth/token' + ); + + if (!defined($content) || $content eq '') { + $self->{output}->add_option_msg(short_msg => "Authentification endpoint returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->output_add(long_msg => $content, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + if (defined($decoded->{error_code})) { + $self->{output}->output_add(long_msg => "Error message : " . $decoded->{error}, debug => 1); + $self->{output}->add_option_msg(short_msg => "Authentification endpoint returns error code '" . $decoded->{error_code} . "' (add --debug option for detailed message)"); + $self->{output}->option_exit(); + } + + $access_token = $decoded->{access_token}; + my $datas = { last_timestamp => time(), access_token => $decoded->{access_token}, expires_on => substr($decoded->{exp}, 0, -3) }; + $options{statefile}->write(data => $datas); + } + + return $access_token; +} + +sub request_api { + my ($self, %options) = @_; + + if (!defined($self->{access_token})) { + $self->{access_token} = $self->get_access_token(statefile => $self->{cache}); + } + + $self->settings(); + + $self->{output}->output_add(long_msg => "URL: '" . $self->{proto} . '://' . $self->{hostname} . ':' . $self->{port} . + $options{url_path} . "'", debug => 1); + + my $content = $self->{http}->request(%options); + + if (!defined($content) || $content eq '') { + $self->{output}->add_option_msg(short_msg => "API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->output_add(long_msg => $content, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + if (defined($decoded->{error_code})) { + $self->{output}->output_add(long_msg => "Error message : " . $decoded->{error}, debug => 1); + $self->{output}->add_option_msg(short_msg => "API returns error code '" . $decoded->{error_code} . "' (add --debug option for detailed message)"); + $self->{output}->option_exit(); + } + + return $decoded; +} + +sub list_vms { + my ($self, %options) = @_; + + my $url_path = '/ovirt-engine/api/vms'; + my $response = $self->request_api(method => 'GET', url_path => $url_path); + + return $response->{vm}; +} + +sub list_hosts { + my ($self, %options) = @_; + + my $url_path = '/ovirt-engine/api/hosts'; + my $response = $self->request_api(method => 'GET', url_path => $url_path); + + return $response->{host}; +} + +sub get_host_statistics { + my ($self, %options) = @_; + + my $url_path = '/ovirt-engine/api/hosts/' . $options{id} . '/statistics'; + my $response = $self->request_api(method => 'GET', url_path => $url_path); + + return $response->{statistic}; +} + +sub cache_hosts { + my ($self, %options) = @_; + + $self->{cache_hosts} = centreon::plugins::statefile->new(%options); + $self->{cache_hosts}->check_options(option_results => $self->{option_results}); + my $has_cache_file = $self->{cache_hosts}->read(statefile => 'cache_ovirt_hosts_' . md5_hex($self->{hostname}) . '_' . md5_hex($self->{api_username})); + my $timestamp_cache = $self->{cache_hosts}->get(name => 'last_timestamp'); + my $hosts = $self->{cache_hosts}->get(name => 'hosts'); + if ($has_cache_file == 0 || !defined($timestamp_cache) || ((time() - $timestamp_cache) > (($self->{reload_cache_time}) * 60))) { + $hosts = []; + my $datas = { last_timestamp => time(), hosts => $hosts }; + my $list = $self->list_hosts(); + foreach (@{$list}) { + push @{$hosts}, { id => $_->{id}, name => $_->{name} }; + } + $self->{cache_hosts}->write(data => $datas); + } + + return $hosts; +} + +sub list_clusters { + my ($self, %options) = @_; + + my $url_path = '/ovirt-engine/api/clusters'; + my $response = $self->request_api(method => 'GET', url_path => $url_path); + + return $response->{cluster}; +} + +sub list_datacenters { + my ($self, %options) = @_; + + my $url_path = '/ovirt-engine/api/datacenters'; + my $response = $self->request_api(method => 'GET', url_path => $url_path); + + return $response->{data_center}; +} + +1; + +__END__ + +=head1 NAME + +oVirt Rest API + +=head1 REST API OPTIONS + +oVirt Rest API + +=over 8 + +=item B<--hostname> + +oVirt hostname. + +=item B<--port> + +Port used (Default: 443) + +=item B<--proto> + +Specify https if needed (Default: 'https') + +=item B<--api-username> + +oVirt API username. + +=item B<--api-password> + +oVirt API password. + +=item B<--timeout> + +Set timeout in seconds (Default: 10). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/apps/virtualization/ovirt/mode/cpuhost.pm b/apps/virtualization/ovirt/mode/cpuhost.pm new file mode 100644 index 000000000..197aeb9ed --- /dev/null +++ b/apps/virtualization/ovirt/mode/cpuhost.pm @@ -0,0 +1,139 @@ +# +# Copyright 2019 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 apps::virtualization::ovirt::mode::cpuhost; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'host', type => 1, cb_prefix_output => 'prefix_output', message_multiple => 'All hosts are ok' }, + ]; + + $self->{maps_counters}->{host} = [ + { label => 'cpu-user', nlabel => 'host.cpu.user.utilization.percentage', set => { + key_values => [ { name => 'user' }, { name => 'display' } ], + output_template => 'user: %.2f %%', + perfdatas => [ + { value => 'user_absolute', template => '%.2f', unit => '%', + min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'cpu-system', nlabel => 'host.cpu.system.utilization.percentage', set => { + key_values => [ { name => 'system' }, { name => 'display' } ], + output_template => 'system: %.2f %%', + perfdatas => [ + { value => 'system_absolute', template => '%.2f', unit => '%', + min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Host '" . $options{instance_value}->{display} . "' CPU utilization "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "filter-id:s" => { name => 'filter_id' }, + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{host} = {}; + + if (!defined($self->{cache_hosts})) { + $self->{cache_hosts} = $options{custom}->cache_hosts(); + } + + foreach my $host (@{$self->{cache_hosts}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $host->{name} !~ /$self->{option_results}->{filter_name}/); + next if (defined($self->{option_results}->{filter_id}) && $self->{option_results}->{filter_id} ne '' + && $host->{id} !~ /$self->{option_results}->{filter_id}/); + + my $stats = $options{custom}->get_host_statistics(id => $host->{id}); + + foreach my $stat (@{$stats}) { + next if ($stat->{name} !~ /^cpu\.current\..*/); + + $self->{host}->{$host->{id}}->{display} = $host->{name}; + $self->{host}->{$host->{id}}->{user} = $stat->{values}->{value}[0]->{datum} if ($stat->{name} =~ /^cpu.current.user$/); + $self->{host}->{$host->{id}}->{system} = $stat->{values}->{value}[0]->{datum} if ($stat->{name} =~ /^cpu.current.system$/); + } + } + + if (scalar(keys %{$self->{host}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No hosts found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check host cpu utilization. + +=over 8 + +=item B<--filter-name> + +Filter host name (Can be a regexp). + +=item B<--filter-id> + +Filter host id (Can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'host-cpu-user-utilization-percentage', 'host-cpu-system-utilization-percentage'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'host-cpu-user-utilization-percentage', 'host-cpu-system-utilization-percentage'. + +=back + +=cut diff --git a/apps/virtualization/ovirt/mode/listclusters.pm b/apps/virtualization/ovirt/mode/listclusters.pm new file mode 100644 index 000000000..e32179221 --- /dev/null +++ b/apps/virtualization/ovirt/mode/listclusters.pm @@ -0,0 +1,104 @@ +# +# Copyright 2019 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 apps::virtualization::ovirt::mode::listclusters; + +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' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{clusters} = $options{custom}->list_clusters(); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $cluster (@{$self->{clusters}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $cluster->{name} !~ /$self->{option_results}->{filter_name}/); + + $self->{output}->output_add(long_msg => sprintf("[id = %s][name = %s]", + $cluster->{id}, $cluster->{name})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List clusters:'); + $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 => ['id', 'name']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $cluster (@{$self->{clusters}}) { + $self->{output}->add_disco_entry( + id => $cluster->{id}, + name => $cluster->{name}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List clusters. + +=over 8 + +=item B<--filter-name> + +Filter cluster name (Can be a regexp). + +=back + +=cut diff --git a/apps/virtualization/ovirt/mode/listdatacenters.pm b/apps/virtualization/ovirt/mode/listdatacenters.pm new file mode 100644 index 000000000..9348bac38 --- /dev/null +++ b/apps/virtualization/ovirt/mode/listdatacenters.pm @@ -0,0 +1,104 @@ +# +# Copyright 2019 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 apps::virtualization::ovirt::mode::listdatacenters; + +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' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{datacenters} = $options{custom}->list_datacenters(); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $datacenter (@{$self->{datacenters}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $datacenter->{name} !~ /$self->{option_results}->{filter_name}/); + + $self->{output}->output_add(long_msg => sprintf("[id = %s][name = %s]", + $datacenter->{id}, $datacenter->{name})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List datacenters:'); + $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 => ['id', 'name']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $datacenter (@{$self->{datacenters}}) { + $self->{output}->add_disco_entry( + id => $datacenter->{id}, + name => $datacenter->{name}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List datacenters. + +=over 8 + +=item B<--filter-name> + +Filter datacenter name (Can be a regexp). + +=back + +=cut diff --git a/apps/virtualization/ovirt/mode/listhosts.pm b/apps/virtualization/ovirt/mode/listhosts.pm new file mode 100644 index 000000000..c29b64892 --- /dev/null +++ b/apps/virtualization/ovirt/mode/listhosts.pm @@ -0,0 +1,109 @@ +# +# Copyright 2019 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 apps::virtualization::ovirt::mode::listhosts; + +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' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{hosts} = $options{custom}->list_hosts(); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $host (@{$self->{hosts}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $host->{name} !~ /$self->{option_results}->{filter_name}/); + + $self->{output}->output_add(long_msg => sprintf("[id = %s][name = %s][address = %s][status = %s]", + $host->{id}, + $host->{name}, + $host->{address}, + $host->{status})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List hosts:'); + $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 => ['id', 'name', 'address', 'status']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $host (@{$self->{hosts}}) { + $self->{output}->add_disco_entry( + id => $host->{id}, + name => $host->{name}, + address => $host->{address}, + status => $host->{status}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List hosts. + +=over 8 + +=item B<--filter-name> + +Filter host name (Can be a regexp). + +=back + +=cut diff --git a/apps/virtualization/ovirt/plugin.pm b/apps/virtualization/ovirt/plugin.pm new file mode 100644 index 000000000..46bf7bf54 --- /dev/null +++ b/apps/virtualization/ovirt/plugin.pm @@ -0,0 +1,52 @@ +# +# Copyright 2019 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 apps::virtualization::ovirt::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'cpu-host' => 'apps::virtualization::ovirt::mode::cpuhost', + 'list-clusters' => 'apps::virtualization::ovirt::mode::listclusters', + 'list-datacenters' => 'apps::virtualization::ovirt::mode::listdatacenters', + 'list-hosts' => 'apps::virtualization::ovirt::mode::listhosts', + ); + + $self->{custom_modes}{api} = 'apps::virtualization::ovirt::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check oVirt using API. + +=cut diff --git a/apps/vmware/connector/custom/connector.pm b/apps/vmware/connector/custom/connector.pm index 9dae9e990..0f8d9a5b9 100644 --- a/apps/vmware/connector/custom/connector.pm +++ b/apps/vmware/connector/custom/connector.pm @@ -46,22 +46,21 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "connector-hostname:s@" => { name => 'connector_hostname' }, - "connector-port:s@" => { name => 'connector_port' }, - "vsphere-address:s@" => { name => 'vsphere_address' }, - "vsphere-username:s@" => { name => 'vsphere_username' }, - "vsphere-password:s@" => { name => 'vsphere_password' }, - "container:s@" => { name => 'container' }, - "timeout:s@" => { name => 'timeout' }, - "sampling-period:s@" => { name => 'sampling_period' }, - "time-shift:s@" => { name => 'time_shift' }, - "case-insensitive" => { name => 'case_insensitive' }, - "unknown-connector-status:s" => { name => 'unknown_connector_status' }, - "warning-connector-status:s" => { name => 'warning_connector_status' }, - "critical-connector-status:s" => { name => 'critical_connector_status' }, - }); + $options{options}->add_options(arguments => { + 'connector-hostname:s@' => { name => 'connector_hostname' }, + 'connector-port:s@' => { name => 'connector_port' }, + 'vsphere-address:s@' => { name => 'vsphere_address' }, + 'vsphere-username:s@' => { name => 'vsphere_username' }, + 'vsphere-password:s@' => { name => 'vsphere_password' }, + 'container:s@' => { name => 'container' }, + 'timeout:s@' => { name => 'timeout' }, + 'sampling-period:s@' => { name => 'sampling_period' }, + 'time-shift:s@' => { name => 'time_shift' }, + 'case-insensitive' => { name => 'case_insensitive' }, + 'unknown-connector-status:s' => { name => 'unknown_connector_status' }, + 'warning-connector-status:s' => { name => 'warning_connector_status' }, + 'critical-connector-status:s' => { name => 'critical_connector_status' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'CONNECTOR OPTIONS', once => 1); @@ -122,7 +121,7 @@ sub check_options { $self->{connector_port} = 5700 if ($self->{connector_port} eq ''); $self->{container} = 'default' if ($self->{container} eq ''); if (!defined($self->{connector_hostname}) || $self->{connector_hostname} eq '') { - $self->{output}->add_option_msg(short_msg => "Please set option --connector-hostname."); + $self->{output}->add_option_msg(short_msg => 'Please set option --connector-hostname.'); $self->{output}->option_exit(); } if (defined($self->{timeout}) && $self->{timeout} =~ /^\d+$/ && @@ -162,8 +161,9 @@ sub connector_response { $self->{output}->option_exit(); } - my $json = $1; + my $json = $1; eval { + $self->{output}->output_add(long_msg => $json, debug => 1); $self->{result} = JSON->new->utf8->decode($json); }; if ($@) { @@ -176,11 +176,11 @@ sub connector_response_status { my ($self, %options) = @_; if (!defined($self->{result})) { - $self->{output}->add_option_msg(short_msg => "Cannot get response (timeout received)"); + $self->{output}->add_option_msg(short_msg => 'Cannot get response (timeout received)'); $self->{output}->option_exit(); } if (!defined($self->{result}->{code})) { - $self->{output}->add_option_msg(short_msg => "response format incorrect"); + $self->{output}->add_option_msg(short_msg => 'response format incorrect - need connector vmware version >= 3.x.x'); $self->{output}->option_exit(); } @@ -271,6 +271,7 @@ sub execute { $self->{json_send}->{vsphere_password} = $self->{vsphere_password}; $self->{json_send}->{sampling_period} = $self->{sampling_period}; $self->{json_send}->{time_shift} = $self->{time_shift}; + $self->{json_send}->{case_insensitive} = $self->{case_insensitive}; # Init my $context = zmq_init(); diff --git a/apps/vmware/connector/mode/alarmdatacenter.pm b/apps/vmware/connector/mode/alarmdatacenter.pm index b174880aa..06c3011d9 100644 --- a/apps/vmware/connector/mode/alarmdatacenter.pm +++ b/apps/vmware/connector/mode/alarmdatacenter.pm @@ -86,14 +86,19 @@ sub custom_status_calc { sub custom_dcmetrics_perfdata { my ($self, %options) = @_; - my $extra_label = ''; + my $extra_label; # We do it manually. Because we have only 1 instance in group. - if (scalar(keys %{$self->{instance_mode}->{datacenter}}) > 1) { - $extra_label .= '_' . $self->{result_values}->{name}; + if (scalar(keys %{$self->{instance_mode}->{datacenter}}) > 1 || $self->{output}->use_new_perfdata()) { + $extra_label = $self->{result_values}->{name}; } - $self->{output}->perfdata_add(label => 'alarm_' . $self->{result_values}->{label_ref} . $extra_label, - value => $self->{result_values}->{alarm_value}, - min => 0); + + $self->{output}->perfdata_add( + label => 'alarm_' . $self->{result_values}->{label_ref}, + nlabel => 'datacenter.alarms.' . $self->{result_values}->{label_ref} . '.current.count', + instances => $extra_label, + value => $self->{result_values}->{alarm_value}, + min => 0 + ); } sub custom_dcmetrics_calc { @@ -119,7 +124,7 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'total-alarm-warning', set => { + { label => 'total-alarm-warning', nlabel => 'datacenter.alarms.warning.current.count', set => { key_values => [ { name => 'yellow' } ], output_template => '%s warning alarm(s) found(s)', perfdatas => [ @@ -127,7 +132,7 @@ sub set_counters { ], } }, - { label => 'total-alarm-critical', set => { + { label => 'total-alarm-critical', nlabel => 'datacenter.alarms.critical.current.count', set => { key_values => [ { name => 'red' } ], output_template => '%s critical alarm(s) found(s)', perfdatas => [ @@ -153,6 +158,7 @@ sub set_counters { { label => 'alarm-warning', threshold => 0, set => { key_values => [ { name => 'name' } ], output_template => '', + closure_custom_threshold_check => sub { return 'ok' }, closure_custom_calc => $self->can('custom_dcmetrics_calc'), closure_custom_calc_extra_options => { label_ref => 'warning' }, closure_custom_perfdata => $self->can('custom_dcmetrics_perfdata'), } @@ -160,6 +166,7 @@ sub set_counters { { label => 'alarm-critical', threshold => 0, set => { key_values => [ { name => 'name' } ], output_template => '', + closure_custom_threshold_check => sub { return 'ok' }, closure_custom_calc => $self->can('custom_dcmetrics_calc'), closure_custom_calc_extra_options => { label_ref => 'critical' }, closure_custom_perfdata => $self->can('custom_dcmetrics_perfdata'), } @@ -192,15 +199,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "datacenter:s" => { name => 'datacenter' }, - "filter" => { name => 'filter' }, - "filter-time:s" => { name => 'filter_time', }, - "memory" => { name => 'memory', }, - "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /yellow/i' }, - "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /red/i' }, - }); + $options{options}->add_options(arguments => { + "datacenter:s" => { name => 'datacenter' }, + "filter" => { name => 'filter' }, + "filter-time:s" => { name => 'filter_time', }, + "memory" => { name => 'memory', }, + "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /yellow/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /red/i' }, + }); centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'Date::Parse', error_msg => "Cannot load module 'Date::Parse'."); diff --git a/apps/vmware/connector/mode/alarmhost.pm b/apps/vmware/connector/mode/alarmhost.pm index 7348a999a..6c0491fca 100644 --- a/apps/vmware/connector/mode/alarmhost.pm +++ b/apps/vmware/connector/mode/alarmhost.pm @@ -40,11 +40,11 @@ sub catalog_status_threshold { $label =~ s/-/_/g; if (defined($self->{instance_mode}->{option_results}->{'critical_' . $label}) && $self->{instance_mode}->{option_results}->{'critical_' . $label} ne '' && eval "$self->{instance_mode}->{option_results}->{'critical_' . $label}") { - $self->{instance_mode}->{dc_critical}++; + $self->{instance_mode}->{host_critical}++; $status = 'critical'; } elsif (defined($self->{instance_mode}->{option_results}->{'warning_' . $label}) && $self->{instance_mode}->{option_results}->{'warning_' . $label} ne '' && eval "$self->{instance_mode}->{option_results}->{'warning_' . $label}") { - $self->{instance_mode}->{dc_warning}++; + $self->{instance_mode}->{host_warning}++; $status = 'warning'; } }; @@ -86,21 +86,25 @@ sub custom_status_calc { sub custom_esxhost_perfdata { my ($self, %options) = @_; - my $extra_label = ''; + my $extra_label; # We do it manually. Because we have only 1 instance in group. - if (scalar(keys %{$self->{instance_mode}->{esxhost}}) > 1) { - $extra_label .= '_' . $self->{result_values}->{name}; + if (scalar(keys %{$self->{instance_mode}->{esxhost}}) > 1 || $self->{output}->use_new_perfdata()) { + $extra_label = $self->{result_values}->{name}; } - $self->{output}->perfdata_add(label => 'alarm_' . $self->{result_values}->{label_ref} . $extra_label, - value => $self->{result_values}->{alarm_value}, - min => 0); + $self->{output}->perfdata_add( + label => 'alarm_' . $self->{result_values}->{label_ref}, + nlabel => 'host.alarms.' . $self->{result_values}->{label_ref} . '.current.count', + instances => $extra_label, + value => $self->{result_values}->{alarm_value}, + min => 0 + ); } sub custom_esxhost_calc { my ($self, %options) = @_; $self->{result_values}->{label_ref} = $options{extra_options}->{label_ref}; - $self->{result_values}->{alarm_value} = $self->{instance_mode}->{'dc_' . $options{extra_options}->{label_ref}}; + $self->{result_values}->{alarm_value} = $self->{instance_mode}->{'host_' . $options{extra_options}->{label_ref}}; $self->{result_values}->{name} = $options{new_datas}->{$self->{instance} . '_name'}; return 0; } @@ -119,7 +123,7 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'total-alarm-warning', set => { + { label => 'total-alarm-warning', nlabel => 'host.alarms.warning.current.count', set => { key_values => [ { name => 'yellow' } ], output_template => '%s warning alarm(s) found(s)', perfdatas => [ @@ -127,7 +131,7 @@ sub set_counters { ], } }, - { label => 'total-alarm-critical', set => { + { label => 'total-alarm-critical', nlabel => 'host.alarms.critical.current.count', set => { key_values => [ { name => 'red' } ], output_template => '%s critical alarm(s) found(s)', perfdatas => [ @@ -153,6 +157,7 @@ sub set_counters { { label => 'alarm-warning', threshold => 0, set => { key_values => [ { name => 'name' } ], output_template => '', + closure_custom_threshold_check => sub { return 'ok' }, closure_custom_calc => $self->can('custom_esxhost_calc'), closure_custom_calc_extra_options => { label_ref => 'warning' }, closure_custom_perfdata => $self->can('custom_esxhost_perfdata'), } @@ -160,6 +165,7 @@ sub set_counters { { label => 'alarm-critical', threshold => 0, set => { key_values => [ { name => 'name' } ], output_template => '', + closure_custom_threshold_check => sub { return 'ok' }, closure_custom_calc => $self->can('custom_esxhost_calc'), closure_custom_calc_extra_options => { label_ref => 'critical' }, closure_custom_perfdata => $self->can('custom_esxhost_perfdata'), } @@ -176,8 +182,8 @@ sub prefix_esxhost_output { sub alarm_reset { my ($self, %options) = @_; - $self->{dc_warning} = 0; - $self->{dc_critical} = 0; + $self->{host_warning} = 0; + $self->{host_critical} = 0; } sub esxhost_long_output { diff --git a/apps/vmware/connector/mode/countvmhost.pm b/apps/vmware/connector/mode/countvmhost.pm index 0d1c36b36..b396acab2 100644 --- a/apps/vmware/connector/mode/countvmhost.pm +++ b/apps/vmware/connector/mode/countvmhost.pm @@ -49,7 +49,7 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'total-on', set => { + { label => 'total-on', nlabel => 'host.vm.poweredon.current.count', set => { key_values => [ { name => 'poweredon' }, { name => 'total' } ], output_template => '%s VM(s) poweredon', perfdatas => [ @@ -58,7 +58,7 @@ sub set_counters { ], } }, - { label => 'total-off', set => { + { label => 'total-off', nlabel => 'host.vm.poweredoff.current.count', set => { key_values => [ { name => 'poweredoff' }, { name => 'total' } ], output_template => '%s VM(s) poweredoff', perfdatas => [ @@ -67,7 +67,7 @@ sub set_counters { ], } }, - { label => 'total-suspended', set => { + { label => 'total-suspended', nlabel => 'host.vm.suspended.current.count', set => { key_values => [ { name => 'suspended' }, { name => 'total' } ], output_template => '%s VM(s) suspended', perfdatas => [ @@ -87,7 +87,7 @@ sub set_counters { closure_custom_threshold_check => \&catalog_status_threshold, } }, - { label => 'on', set => { + { label => 'on', nlabel => 'host.vm.poweredon.current.count', set => { key_values => [ { name => 'poweredon' }, { name => 'total' } ], output_template => '%s VM(s) poweredon', perfdatas => [ @@ -96,7 +96,7 @@ sub set_counters { ], } }, - { label => 'off', set => { + { label => 'off', nlabel => 'host.vm.poweredoff.current.count', set => { key_values => [ { name => 'poweredoff' }, { name => 'total' } ], output_template => '%s VM(s) poweredoff', perfdatas => [ @@ -105,7 +105,7 @@ sub set_counters { ], } }, - { label => 'suspended', set => { + { label => 'suspended', nlabel => 'host.vm.suspended.current.count', set => { key_values => [ { name => 'suspended' }, { name => 'total' } ], output_template => '%s VM(s) suspended', perfdatas => [ diff --git a/apps/vmware/connector/mode/cpuhost.pm b/apps/vmware/connector/mode/cpuhost.pm index 86dda6516..8ba9a1834 100644 --- a/apps/vmware/connector/mode/cpuhost.pm +++ b/apps/vmware/connector/mode/cpuhost.pm @@ -65,7 +65,7 @@ sub set_counters { ]; $self->{maps_counters}->{global_cpu} = [ - { label => 'total-cpu', set => { + { label => 'total-cpu', nlabel => 'host.cpu.utilization.percentage', set => { key_values => [ { name => 'cpu_average' } ], output_template => '%s %%', perfdatas => [ @@ -74,7 +74,7 @@ sub set_counters { ], } }, - { label => 'total-cpu-mhz', set => { + { label => 'total-cpu-mhz', nlabel => 'host.cpu.utilization.mhz', set => { key_values => [ { name => 'cpu_average_mhz' }, { name => 'cpu_average_mhz_max' } ], output_template => '%s MHz', perfdatas => [ @@ -86,7 +86,7 @@ sub set_counters { ]; $self->{maps_counters}->{cpu} = [ - { label => 'cpu', set => { + { label => 'cpu', nlabel => 'host.core.cpu.utilization.percentage', set => { key_values => [ { name => 'cpu_usage' }, { name => 'display' } ], output_template => 'usage : %s', perfdatas => [ diff --git a/apps/vmware/connector/mode/cpuvm.pm b/apps/vmware/connector/mode/cpuvm.pm index c3462da50..112722537 100644 --- a/apps/vmware/connector/mode/cpuvm.pm +++ b/apps/vmware/connector/mode/cpuvm.pm @@ -49,7 +49,7 @@ sub set_counters { group => [ { name => 'global', type => 0, skipped_code => { -10 => 1 } }, { name => 'global_cpu', cb_prefix_output => 'prefix_global_cpu_output', type => 0, skipped_code => { -10 => 1 } }, - { name => 'cpu', display_long => 0, cb_prefix_output => 'prefix_cpu_output', message_multiple => 'All CPUs are ok', type => 1, skipped_code => { -10 => 1 } }, + { name => 'cpu', display_long => 0, cb_prefix_output => 'prefix_cpu_output', message_multiple => 'All CPUs are ok', type => 1, skipped_code => { -10 => 1 } }, ] } ]; @@ -66,7 +66,7 @@ sub set_counters { ]; $self->{maps_counters}->{global_cpu} = [ - { label => 'total-cpu', set => { + { label => 'total-cpu', nlabel => 'vm.cpu.utilization.percentage', set => { key_values => [ { name => 'cpu_average' } ], output_template => '%s %%', perfdatas => [ @@ -75,7 +75,7 @@ sub set_counters { ], } }, - { label => 'total-cpu-mhz', set => { + { label => 'total-cpu-mhz', nlabel => 'vm.cpu.utilization.mhz', set => { key_values => [ { name => 'cpu_average_mhz' } ], output_template => '%s MHz', perfdatas => [ @@ -84,7 +84,7 @@ sub set_counters { ], } }, - { label => 'cpu-ready', set => { + { label => 'cpu-ready', nlabel => 'vm.cpu.ready.percentage', set => { key_values => [ { name => 'cpu_ready' } ], output_template => 'ready %s %%', perfdatas => [ @@ -96,7 +96,7 @@ sub set_counters { ]; $self->{maps_counters}->{cpu} = [ - { label => 'cpu', set => { + { label => 'cpu', nlabel => 'vm.core.cpu.utilization.percentage', set => { key_values => [ { name => 'cpu_usage' }, { name => 'display' } ], output_template => 'usage : %s MHz', perfdatas => [ @@ -158,6 +158,7 @@ sub new { "display-description" => { name => 'display_description' }, "filter-description:s" => { name => 'filter_description' }, "filter-os:s" => { name => 'filter_os' }, + "filter-uuid:s" => { name => 'filter_uuid' }, "unknown-status:s" => { name => 'unknown_status', default => '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i' }, "warning-status:s" => { name => 'warning_status', default => '' }, "critical-status:s" => { name => 'critical_status', default => '' }, diff --git a/apps/vmware/connector/mode/datastorecountvm.pm b/apps/vmware/connector/mode/datastorecountvm.pm index f1a650087..64f9fb60f 100644 --- a/apps/vmware/connector/mode/datastorecountvm.pm +++ b/apps/vmware/connector/mode/datastorecountvm.pm @@ -50,7 +50,7 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'total-on', set => { + { label => 'total-on', nlabel => 'datastore.vm.poweredon.current.count', set => { key_values => [ { name => 'poweredon' }, { name => 'total' } ], output_template => '%s VM(s) poweredon', perfdatas => [ @@ -59,7 +59,7 @@ sub set_counters { ], } }, - { label => 'total-off', set => { + { label => 'total-off', nlabel => 'datastore.vm.poweredoff.current.count', set => { key_values => [ { name => 'poweredoff' }, { name => 'total' } ], output_template => '%s VM(s) poweredoff', perfdatas => [ @@ -68,7 +68,7 @@ sub set_counters { ], } }, - { label => 'total-suspended', set => { + { label => 'total-suspended', nlabel => 'datastore.vm.suspended.current.count', set => { key_values => [ { name => 'suspended' }, { name => 'total' } ], output_template => '%s VM(s) suspended', perfdatas => [ @@ -88,7 +88,7 @@ sub set_counters { closure_custom_threshold_check => \&catalog_status_threshold, } }, - { label => 'on', set => { + { label => 'on', nlabel => 'datastore.vm.poweredon.current.count', set => { key_values => [ { name => 'poweredon' }, { name => 'total' } ], output_template => '%s VM(s) poweredon', perfdatas => [ @@ -97,7 +97,7 @@ sub set_counters { ], } }, - { label => 'off', set => { + { label => 'off', nlabel => 'datastore.vm.poweredoff.current.count', set => { key_values => [ { name => 'poweredoff' }, { name => 'total' } ], output_template => '%s VM(s) poweredoff', perfdatas => [ @@ -106,7 +106,7 @@ sub set_counters { ], } }, - { label => 'suspended', set => { + { label => 'suspended', nlabel => 'datastore.vm.suspended.current.count', set => { key_values => [ { name => 'suspended' }, { name => 'total' } ], output_template => '%s VM(s) suspended', perfdatas => [ diff --git a/apps/vmware/connector/mode/datastorehost.pm b/apps/vmware/connector/mode/datastorehost.pm index 35fc6dc91..7b681ee45 100644 --- a/apps/vmware/connector/mode/datastorehost.pm +++ b/apps/vmware/connector/mode/datastorehost.pm @@ -65,7 +65,7 @@ sub set_counters { ]; $self->{maps_counters}->{datastore} = [ - { label => 'read-latency', set => { + { label => 'read-latency', nlabel => 'host.datastore.latency.read.milliseconds', set => { key_values => [ { name => 'read_latency' }, { name => 'display' } ], output_template => 'read : %s ms', perfdatas => [ @@ -74,7 +74,7 @@ sub set_counters { ], } }, - { label => 'write-latency', set => { + { label => 'write-latency', nlabel => 'host.datastore.latency.write.milliseconds', set => { key_values => [ { name => 'write_latency' }, { name => 'display' } ], output_template => 'write : %s ms', perfdatas => [ diff --git a/apps/vmware/connector/mode/datastoreio.pm b/apps/vmware/connector/mode/datastoreio.pm index 4d98d2dd2..4d933a139 100644 --- a/apps/vmware/connector/mode/datastoreio.pm +++ b/apps/vmware/connector/mode/datastoreio.pm @@ -49,23 +49,23 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'total-read', set => { + { label => 'total-read', nlabel => 'datastore.read.usage.bytespersecond', set => { key_values => [ { name => 'read' } ], output_template => 'Total rate of reading data: %s %s/s', - output_change_bytes => 2, + output_change_bytes => 1, perfdatas => [ { label => 'total_read_rate', value => 'read_absolute', template => '%s', unit => 'B/s', min => 0 }, ], } }, - { label => 'total-write', set => { + { label => 'total-write', nlabel => 'datastore.write.usage.bytespersecond', set => { key_values => [ { name => 'write' } ], output_template => 'Total rate of writing data: %s %s/s', - output_change_bytes => 2, + output_change_bytes => 1, perfdatas => [ { label => 'total_write_rate', value => 'write_absolute', template => '%s', - min => 0 }, + unit => 'B/s', min => 0 }, ], } }, @@ -80,23 +80,23 @@ sub set_counters { closure_custom_threshold_check => \&catalog_status_threshold, } }, - { label => 'read', set => { + { label => 'read', nlabel => 'datastore.read.usage.bytespersecond', set => { key_values => [ { name => 'read' } ], output_template => 'rate of reading data: %s %s/s', - output_change_bytes => 2, + output_change_bytes => 1, perfdatas => [ { label => 'read_rate', value => 'read_absolute', template => '%s', unit => 'B/s', min => 0, label_extra_instance => 1 }, ], } }, - { label => 'write', set => { + { label => 'write', nlabel => 'datastore.write.usage.bytespersecond', set => { key_values => [ { name => 'write' } ], output_template => 'rate of writing data: %s %s/s', - output_change_bytes => 2, + output_change_bytes => 1, perfdatas => [ { label => 'write_rate', value => 'write_absolute', template => '%s', - min => 0, label_extra_instance => 1 }, + unit => 'B/s', min => 0, label_extra_instance => 1 }, ], } }, @@ -147,10 +147,10 @@ sub manage_selection { $self->{datastore}->{$ds_name} = { display => $ds_name, accessible => $response->{data}->{$ds_id}->{accessible}, - read => $response->{data}->{$ds_id}->{'datastore.write.average'}, - write => $response->{data}->{$ds_id}->{'datastore.read.average'}, + read => $response->{data}->{$ds_id}->{'datastore.read.average'}, + write => $response->{data}->{$ds_id}->{'datastore.write.average'}, }; - $self->{global}->{read} += $response->{data}->{$ds_id}->{'datastore.write.average'} if (defined($response->{data}->{$ds_id}->{'datastore.write.average'})); + $self->{global}->{read} += $response->{data}->{$ds_id}->{'datastore.read.average'} if (defined($response->{data}->{$ds_id}->{'datastore.read.average'})); $self->{global}->{write} += $response->{data}->{$ds_id}->{'datastore.write.average'} if (defined($response->{data}->{$ds_id}->{'datastore.write.average'})); } } @@ -177,10 +177,6 @@ Datastore name is a regexp. Search in following datacenter(s) (can be a regexp). -=item B<--disconnect-status> - -Status if datastore disconnected (default: 'unknown'). - =item B<--unknown-status> Set warning threshold for status (Default: '%{accessible} !~ /^true|1$/i'). diff --git a/apps/vmware/connector/mode/datastoreiops.pm b/apps/vmware/connector/mode/datastoreiops.pm index 8b8088540..189435553 100644 --- a/apps/vmware/connector/mode/datastoreiops.pm +++ b/apps/vmware/connector/mode/datastoreiops.pm @@ -66,7 +66,7 @@ sub set_counters { ]; $self->{maps_counters}->{global_iops} = [ - { label => 'read', set => { + { label => 'read', nlabel => 'datastore.read.usage.iops', set => { key_values => [ { name => 'read' } ], output_template => '%s read iops', perfdatas => [ @@ -75,7 +75,7 @@ sub set_counters { ], } }, - { label => 'write', set => { + { label => 'write', nlabel => 'datastore.write.usage.iops', set => { key_values => [ { name => 'write' } ], output_template => '%s write iops', perfdatas => [ @@ -87,7 +87,7 @@ sub set_counters { ]; $self->{maps_counters}->{vm} = [ - { label => 'read-vm', set => { + { label => 'read-vm', nlabel => 'datastore.vm.read.usage.iops', set => { key_values => [ { name => 'read' } ], output_template => '%s read iops', perfdatas => [ @@ -96,7 +96,7 @@ sub set_counters { ], } }, - { label => 'write-vm', set => { + { label => 'write-vm', nlabel => 'datastore.vm.write.usage.iops', set => { key_values => [ { name => 'write' } ], output_template => '%s write iops', perfdatas => [ diff --git a/apps/vmware/connector/mode/datastoresnapshot.pm b/apps/vmware/connector/mode/datastoresnapshot.pm index d9d2bb076..f9ffad0b4 100644 --- a/apps/vmware/connector/mode/datastoresnapshot.pm +++ b/apps/vmware/connector/mode/datastoresnapshot.pm @@ -66,10 +66,10 @@ sub set_counters { ]; $self->{maps_counters}->{global_snapshot} = [ - { label => 'total', set => { + { label => 'total', nlabel => 'datastore.snapshots.usage.bytes', set => { key_values => [ { name => 'total' } ], output_template => 'total snapshots [size = %s %s]', - output_change_bytes => 2, + output_change_bytes => 1, perfdatas => [ { label => 'total_size', value => 'total_absolute', template => '%s', unit => 'B', min => 0, label_extra_instance => 1 }, @@ -79,10 +79,10 @@ sub set_counters { ]; $self->{maps_counters}->{files} = [ - { label => 'snapshot', set => { + { label => 'snapshot', nlabel => 'datastore.snapshot.usage.bytes', set => { key_values => [ { name => 'total' } ], output_template => '[size = %s %s]', - output_change_bytes => 2, + output_change_bytes => 1, closure_custom_perfdata => sub { return 0; }, } }, diff --git a/apps/vmware/connector/mode/datastoreusage.pm b/apps/vmware/connector/mode/datastoreusage.pm index ba9d3b02b..adc75e5c0 100644 --- a/apps/vmware/connector/mode/datastoreusage.pm +++ b/apps/vmware/connector/mode/datastoreusage.pm @@ -43,25 +43,28 @@ sub custom_status_calc { sub custom_usage_perfdata { my ($self, %options) = @_; - my $label = 'used'; + my ($label, $nlabel) = ('used', $self->{nlabel}); my $value_perf = $self->{result_values}->{used}; if (defined($self->{instance_mode}->{option_results}->{free})) { - $label = 'free'; + ($label, $nlabel) = ('free', 'datastore.space.free.bytes'); $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + nlabel => $nlabel, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -74,7 +77,7 @@ sub custom_usage_threshold { $threshold_value = $self->{result_values}->{prct_used}; $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -153,7 +156,7 @@ sub set_counters { closure_custom_threshold_check => \&catalog_status_threshold, } }, - { label => 'usage', set => { + { label => 'usage', nlabel => 'datastore.space.usage.bytes', set => { key_values => [ { name => 'display' }, { name => 'free' }, { name => 'total' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_output => $self->can('custom_usage_output'), @@ -161,7 +164,7 @@ sub set_counters { closure_custom_threshold_check => $self->can('custom_usage_threshold'), } }, - { label => 'provisioned', set => { + { label => 'provisioned', nlabel => 'datastore.space.provisioned.bytes', set => { key_values => [ { name => 'display' }, { name => 'uncommitted' }, { name => 'total' }, { name => 'free' } ], closure_custom_calc => $self->can('custom_provisioned_calc'), closure_custom_output => $self->can('custom_provisioned_output'), @@ -278,12 +281,12 @@ Can used special variables like: %{accessible} =item B<--warning-*> Threshold warning. -Can be: 'total', 'snapshot'. +Can be: 'usage', 'provisioned'. =item B<--critical-*> Threshold critical. -Can be: 'total', 'snapshot'. +Can be: 'usage', 'provisioned'. =back diff --git a/apps/vmware/connector/mode/datastorevm.pm b/apps/vmware/connector/mode/datastorevm.pm index 1399d1650..48f3e30bf 100644 --- a/apps/vmware/connector/mode/datastorevm.pm +++ b/apps/vmware/connector/mode/datastorevm.pm @@ -67,7 +67,7 @@ sub set_counters { ]; $self->{maps_counters}->{global_vm} = [ - { label => 'max-total-latency', set => { + { label => 'max-total-latency', nlabel => 'vm.datastore.latency.max.milliseconds', set => { key_values => [ { name => 'total_latency' } ], output_template => 'max total latency is %s ms', perfdatas => [ @@ -79,7 +79,7 @@ sub set_counters { ]; $self->{maps_counters}->{datastore} = [ - { label => 'read', set => { + { label => 'read', nlabel => 'vm.datastore.read.usage.iops', set => { key_values => [ { name => 'read' } ], output_template => '%s read iops', perfdatas => [ @@ -88,7 +88,7 @@ sub set_counters { ], } }, - { label => 'write', set => { + { label => 'write', nlabel => 'vm.datastore.write.usage.iops', set => { key_values => [ { name => 'write' } ], output_template => '%s write iops', perfdatas => [ @@ -143,6 +143,7 @@ sub new { "scope-host:s" => { name => 'scope_host' }, "filter-description:s" => { name => 'filter_description' }, "filter-os:s" => { name => 'filter_os' }, + "filter-uuid:s" => { name => 'filter_uuid' }, "display-description" => { name => 'display_description' }, "datastore-name:s" => { name => 'datastore_name' }, "filter-datastore:s" => { name => 'filter_datastore' }, diff --git a/apps/vmware/connector/mode/devicevm.pm b/apps/vmware/connector/mode/devicevm.pm index 593834141..15f7ef15b 100644 --- a/apps/vmware/connector/mode/devicevm.pm +++ b/apps/vmware/connector/mode/devicevm.pm @@ -57,7 +57,7 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'total-device-connected', set => { + { label => 'total-device-connected', nlabel => 'vm.devices.connected.count', set => { key_values => [ { name => 'device_connected' } ], closure_custom_output => $self->can('custom_device_output'), perfdatas => [ @@ -77,7 +77,7 @@ sub set_counters { closure_custom_threshold_check => \&catalog_status_threshold, } }, - { label => 'device-connected', set => { + { label => 'device-connected', nlabel => 'vm.devices.connected.count', set => { key_values => [ { name => 'device_connected' }, { name => 'display' } ], oclosure_custom_output => $self->can('custom_device_output'), perfdatas => [ @@ -115,6 +115,7 @@ sub new { "scope-host:s" => { name => 'scope_host' }, "filter-description:s" => { name => 'filter_description' }, "filter-os:s" => { name => 'filter_os' }, + "filter-uuid:s" => { name => 'filter_uuid' }, "display-description" => { name => 'display_description' }, "device:s" => { name => 'device' }, "unknown-status:s" => { name => 'unknown_status', default => '%{connection_state} !~ /^connected$/i' }, diff --git a/apps/vmware/connector/mode/discovery.pm b/apps/vmware/connector/mode/discovery.pm new file mode 100644 index 000000000..d61e4b7e4 --- /dev/null +++ b/apps/vmware/connector/mode/discovery.pm @@ -0,0 +1,91 @@ +# +# Copyright 2019 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 apps::vmware::connector::mode::discovery; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use JSON::XS; + +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 => { + "resource-type:s" => { name => 'resource_type' }, + "prettify" => { name => 'prettify' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + + my $response = $options{custom}->execute(params => $self->{option_results}, + command => 'discovery', force_response => 1); + + my $encoded_data; + eval { + if (defined($self->{option_results}->{prettify})) { + $encoded_data = JSON::XS->new->utf8->pretty->encode($response->{data}); + } else { + $encoded_data = JSON::XS->new->utf8->encode($response->{data}); + } + }; + if ($@) { + $encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}'; + } + + $self->{output}->output_add(short_msg => $encoded_data); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1); +} + +1; + +__END__ + +=head1 MODE + +Resources discovery. + +=over 8 + +=item B<--resource-type> + +Choose the type of resources +to discover (Can be: 'esx', 'vm') (Mandatory). + +=item B<--prettify> + +Prettify JSON output. + +=back + +=cut diff --git a/apps/vmware/connector/mode/healthhost.pm b/apps/vmware/connector/mode/healthhost.pm index 4a3c35449..3a1258136 100644 --- a/apps/vmware/connector/mode/healthhost.pm +++ b/apps/vmware/connector/mode/healthhost.pm @@ -43,8 +43,6 @@ sub custom_status_calc { sub custom_summary_output { my ($self, %options) = @_; - use Data::Dumper; - print Data::Dumper::Dumper($self->{result_values}); my $msg; if ($self->{result_values}->{type_absolute} ne '') { $msg = $self->{result_values}->{type_absolute} . " sensor " . $self->{result_values}->{name_absolute} . ": ". $self->{result_values}->{summary_absolute}; @@ -69,7 +67,7 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'total-problems', set => { + { label => 'total-problems', nlabel => 'host.health.problems.current.count', set => { key_values => [ { name => 'total_problems' }, { name => 'total' } ], output_template => '%s total health issue(s) found', perfdatas => [ @@ -98,7 +96,7 @@ sub set_counters { closure_custom_perfdata => sub { return 0; }, } }, - { label => 'problems', set => { + { label => 'problems', nlabel => 'host.health.problems.current.count', set => { key_values => [ { name => 'total_problems' }, { name => 'total' } ], output_template => '%s total health issue(s) found', perfdatas => [ @@ -107,7 +105,7 @@ sub set_counters { ], } }, - { label => 'problems-yellow', set => { + { label => 'problems-yellow', nlabel => 'host.health.yellow.current.count', set => { key_values => [ { name => 'yellow' }, { name => 'total' } ], output_template => '%s yellow health issue(s) found', perfdatas => [ @@ -116,7 +114,7 @@ sub set_counters { ], } }, - { label => 'problems-red', set => { + { label => 'problems-red', nlabel => 'host.health.red.current.count', set => { key_values => [ { name => 'red' }, { name => 'total' } ], output_template => '%s red health issue(s) found', perfdatas => [ diff --git a/apps/vmware/connector/mode/limitvm.pm b/apps/vmware/connector/mode/limitvm.pm index 9cd8439fd..dce27d214 100644 --- a/apps/vmware/connector/mode/limitvm.pm +++ b/apps/vmware/connector/mode/limitvm.pm @@ -55,13 +55,13 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'cpu_alarms', type => 2, cb_long_output => 'cpu_long_output', message_multiple => '0 cpu limit problem(s) detected', format_output => '%s cpu limit problem(s) detected', display_counter_problem => { label => 'cpu_alerts', min => 0 }, + { name => 'cpu_alarms', type => 2, cb_long_output => 'cpu_long_output', message_multiple => '0 cpu limit problem(s) detected', format_output => '%s cpu limit problem(s) detected', display_counter_problem => { label => 'cpu_alerts', nlabel => 'vm.limit.cpu.alerts.count', min => 0 }, group => [ { name => 'cpu_alarm', cb_prefix_output => 'prefix_vm_output', skipped_code => { -11 => 1 } } ] }, - { name => 'memory_alarms', type => 2,cb_long_output => 'memory_long_output', message_multiple => '0 memory limit problem(s) detected', format_output => '%s memory limit problem(s) detected', display_counter_problem => { label => 'memory_alerts', min => 0 }, + { name => 'memory_alarms', type => 2,cb_long_output => 'memory_long_output', message_multiple => '0 memory limit problem(s) detected', format_output => '%s memory limit problem(s) detected', display_counter_problem => { label => 'memory_alerts', nlabel => 'vm.limit.memory.alerts.count', min => 0 }, group => [ { name => 'memory_alarm', cb_prefix_output => 'prefix_vm_output', skipped_code => { -11 => 1 } } ] }, - { name => 'disk_alarms', type => 2, cb_long_output => 'disk_long_output', message_multiple => '0 disk limit problem(s) detected', format_output => '%s disk limit problem(s) detected', display_counter_problem => { label => 'disk_alerts', min => 0 }, + { name => 'disk_alarms', type => 2, cb_long_output => 'disk_long_output', message_multiple => '0 disk limit problem(s) detected', format_output => '%s disk limit problem(s) detected', display_counter_problem => { label => 'disk_alerts', nlabel => 'vm.limit.disk.alerts.count', min => 0 }, group => [ { name => 'disk_alarm', cb_prefix_output => 'prefix_vm_output', skipped_code => { -11 => 1 } } ] }, ]; @@ -139,6 +139,7 @@ sub new { "filter" => { name => 'filter' }, "filter-description:s" => { name => 'filter_description' }, "filter-os:s" => { name => 'filter_os' }, + "filter-uuid:s" => { name => 'filter_uuid' }, "display-description" => { name => 'display_description' }, "check-disk-limit" => { name => 'check_disk_limit' }, "warning-disk-status:s" => { name => 'warning_disk_status', default => '' }, diff --git a/apps/vmware/connector/mode/memoryhost.pm b/apps/vmware/connector/mode/memoryhost.pm index cdde3c709..86f55708b 100644 --- a/apps/vmware/connector/mode/memoryhost.pm +++ b/apps/vmware/connector/mode/memoryhost.pm @@ -43,25 +43,28 @@ sub custom_status_calc { sub custom_usage_perfdata { my ($self, %options) = @_; - my $label = 'used'; + my ($label, $nlabel) = ('used', $self->{nlabel}); my $value_perf = $self->{result_values}->{used}; if (defined($self->{instance_mode}->{option_results}->{free})) { - $label = 'free'; + ($label, $nlabel) = ('free', 'host.memory.free.bytes'); $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + nlabel => $nlabel, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -74,7 +77,7 @@ sub custom_usage_threshold { $threshold_value = $self->{result_values}->{prct_used}; $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -142,7 +145,7 @@ sub set_counters { closure_custom_threshold_check => \&catalog_status_threshold, } }, - { label => 'consumed-memory', set => { + { label => 'consumed-memory', nlabel => 'host.memory.usage.bytes', set => { key_values => [ { name => 'display' }, { name => 'consumed' }, { name => 'total' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_output => $self->can('custom_usage_output'), @@ -150,7 +153,7 @@ sub set_counters { closure_custom_threshold_check => $self->can('custom_usage_threshold'), } }, - { label => 'overhead-memory', set => { + { label => 'overhead-memory', nlabel => 'host.memory.overhead.bytes', set => { key_values => [ { name => 'overhead' }, { name => 'display' } ], closure_custom_output => $self->can('custom_overhead_output'), perfdatas => [ @@ -159,7 +162,7 @@ sub set_counters { ], } }, - { label => 'state-memory', set => { + { label => 'state-memory', nlabel => 'host.memory.state.count', set => { key_values => [ { name => 'mem_state' }, { name => 'mem_state_str' }, { name => 'display' } ], closure_custom_output => $self->can('custom_memstate_output'), perfdatas => [ @@ -190,6 +193,7 @@ sub new { "scope-cluster:s" => { name => 'scope_cluster' }, "units:s" => { name => 'units', default => '%' }, "free" => { name => 'free' }, + "no-memory-state" => { name => 'no_memory_state' }, "unknown-status:s" => { name => 'unknown_status', default => '%{status} !~ /^connected$/i' }, "warning-status:s" => { name => 'warning_status', default => '' }, "critical-status:s" => { name => 'critical_status', default => '' }, diff --git a/apps/vmware/connector/mode/memoryvm.pm b/apps/vmware/connector/mode/memoryvm.pm index d2a0f01ff..7e420228f 100644 --- a/apps/vmware/connector/mode/memoryvm.pm +++ b/apps/vmware/connector/mode/memoryvm.pm @@ -44,25 +44,28 @@ sub custom_status_calc { sub custom_usage_perfdata { my ($self, %options) = @_; - my $label = $self->{label} . '_used'; + my ($label, $nlabel) = ('used', $self->{nlabel}); my $value_perf = $self->{result_values}->{used}; if (defined($self->{instance_mode}->{option_results}->{free})) { - $label = $self->{label} . '_free'; + ($label, $nlabel) = ('free', 'vm.memory.free.bytes'); $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{instance} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + nlabel => $nlabel, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -75,7 +78,7 @@ sub custom_usage_threshold { $threshold_value = $self->{result_values}->{prct_used}; $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -165,7 +168,7 @@ sub set_counters { ]; $self->{maps_counters}->{global_consumed} = [ - { label => 'consumed', set => { + { label => 'consumed', nlabel => 'vm.memory.usage.bytes', set => { key_values => [ { name => 'consumed' }, { name => 'total' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_calc_extra_options => { label_ref => 'consumed' }, closure_custom_output => $self->can('custom_usage_output'), @@ -175,7 +178,7 @@ sub set_counters { }, ]; $self->{maps_counters}->{global_active} = [ - { label => 'active', set => { + { label => 'active', nlabel => 'vm.memory.active.bytes', set => { key_values => [ { name => 'active' }, { name => 'total' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_calc_extra_options => { label_ref => 'active' }, closure_custom_output => $self->can('custom_usage_output'), @@ -185,7 +188,7 @@ sub set_counters { }, ]; $self->{maps_counters}->{global_overhead} = [ - { label => 'overhead', set => { + { label => 'overhead', nlabel => 'vm.memory.overhead.bytes', set => { key_values => [ { name => 'overhead' } ], closure_custom_output => $self->can('custom_overhead_output'), perfdatas => [ @@ -196,7 +199,7 @@ sub set_counters { }, ]; $self->{maps_counters}->{global_vmmemctl} = [ - { label => 'ballooning', set => { + { label => 'ballooning', nlabel => 'vm.memory.ballooning.bytes', set => { key_values => [ { name => 'vmmemctl' } ], closure_custom_output => $self->can('custom_ballooning_output'), perfdatas => [ @@ -207,7 +210,7 @@ sub set_counters { }, ]; $self->{maps_counters}->{global_shared} = [ - { label => 'shared', set => { + { label => 'shared', nlabel => 'vm.memory.shared.bytes', set => { key_values => [ { name => 'shared' } ], closure_custom_output => $self->can('custom_shared_output'), perfdatas => [ @@ -256,6 +259,7 @@ sub new { "scope-host:s" => { name => 'scope_host' }, "filter-description:s" => { name => 'filter_description' }, "filter-os:s" => { name => 'filter_os' }, + "filter-uuid:s" => { name => 'filter_uuid' }, "display-description" => { name => 'display_description' }, "units:s" => { name => 'units', default => '%' }, "free" => { name => 'free' }, diff --git a/apps/vmware/connector/mode/nethost.pm b/apps/vmware/connector/mode/nethost.pm index 6c318da77..d3ba0e983 100644 --- a/apps/vmware/connector/mode/nethost.pm +++ b/apps/vmware/connector/mode/nethost.pm @@ -92,8 +92,11 @@ sub custom_dropped_calc { $self->{result_values}->{dropped} = $options{new_datas}->{$self->{instance} . '_dropped_' . $options{extra_options}->{label_ref}}; $self->{result_values}->{packets} = $options{new_datas}->{$self->{instance} . '_packets_' . $options{extra_options}->{label_ref}}; $self->{result_values}->{label_ref} = $options{extra_options}->{label_ref}; - $self->{result_values}->{dropped_prct} = $self->{result_values}->{dropped} * 100 / $self->{result_values}->{packets}; - + $self->{result_values}->{dropped_prct} = 0; + if ($self->{result_values}->{packets} > 0) { + $self->{result_values}->{dropped_prct} = $self->{result_values}->{dropped} * 100 / $self->{result_values}->{packets}; + } + return 0; } @@ -123,20 +126,20 @@ sub set_counters { ]; $self->{maps_counters}->{global_host} = [ - { label => 'host-traffic-in', set => { + { label => 'host-traffic-in', nlabel => 'host.traffic.in.bitsperseconds', set => { key_values => [ { name => 'traffic_in' } ], output_template => 'host traffic in : %s %s/s', - output_change_bytes => 1, + output_change_bytes => 2, perfdatas => [ { label => 'host_traffic_in', value => 'traffic_in_absolute', template => '%s', unit => 'b/s', min => 0, label_extra_instance => 1 }, ], } }, - { label => 'host-traffic-out', set => { + { label => 'host-traffic-out', nlabel => 'host.traffic.out.bitsperseconds', set => { key_values => [ { name => 'traffic_out' } ], output_template => 'host traffic out : %s %s/s', - output_change_bytes => 1, + output_change_bytes => 2, perfdatas => [ { label => 'host_traffic_out', value => 'traffic_out_absolute', template => '%s', unit => 'b/s', min => 0, label_extra_instance => 1 }, @@ -146,20 +149,20 @@ sub set_counters { ]; $self->{maps_counters}->{vswitch} = [ - { label => 'vswitch-traffic-in', set => { + { label => 'vswitch-traffic-in', nlabel => 'host.vswitch.traffic.in.bitsperseconds', set => { key_values => [ { name => 'traffic_in' } ], output_template => 'traffic in : %s %s/s', - output_change_bytes => 1, + output_change_bytes => 2, perfdatas => [ { label => 'vswitch_traffic_in', value => 'traffic_in_absolute', template => '%s', unit => 'b/s', min => 0, label_extra_instance => 1 }, ], } }, - { label => 'vswitch-traffic-out', set => { + { label => 'vswitch-traffic-out', nlabel => 'host.vswitch.traffic.out.bitsperseconds', set => { key_values => [ { name => 'traffic_out' } ], output_template => 'traffic out : %s %s/s', - output_change_bytes => 1, + output_change_bytes => 2, perfdatas => [ { label => 'vswitch_traffic_out', value => 'traffic_out_absolute', template => '%s', unit => 'b/s', min => 0, label_extra_instance => 1 }, @@ -177,7 +180,7 @@ sub set_counters { closure_custom_threshold_check => \&catalog_status_threshold, } }, - { label => 'link-traffic-in', set => { + { label => 'link-traffic-in', nlabel => 'host.traffic.in.bitsperseconds', set => { key_values => [ { name => 'display' }, { name => 'traffic_in' }, { name => 'speed' } ], closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'in' }, closure_custom_output => $self->can('custom_traffic_output'), @@ -188,7 +191,7 @@ sub set_counters { ], } }, - { label => 'link-traffic-out', set => { + { label => 'link-traffic-out', nlabel => 'host.traffic.out.bitsperseconds', set => { key_values => [ { name => 'display' }, { name => 'traffic_out' }, { name => 'speed' } ], closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'out' }, closure_custom_output => $self->can('custom_traffic_output'), @@ -199,7 +202,7 @@ sub set_counters { ], } }, - { label => 'link-dropped-in', set => { + { label => 'link-dropped-in', nlabel => 'host.packets.in.dropped.percentage', set => { key_values => [ { name => 'display' }, { name => 'packets_in' }, { name => 'dropped_in' } ], closure_custom_calc => $self->can('custom_dropped_calc'), closure_custom_calc_extra_options => { label_ref => 'in' }, closure_custom_output => $self->can('custom_dropped_output'), @@ -210,7 +213,7 @@ sub set_counters { ], } }, - { label => 'link-dropped-out', set => { + { label => 'link-dropped-out', nlabel => 'host.packets.out.dropped.percentage', set => { key_values => [ { name => 'display' }, { name => 'packets_out' }, { name => 'dropped_out' } ], closure_custom_calc => $self->can('custom_dropped_calc'), closure_custom_calc_extra_options => { label_ref => 'out' }, closure_custom_output => $self->can('custom_dropped_output'), @@ -260,11 +263,11 @@ sub new { "filter" => { name => 'filter' }, "scope-datacenter:s" => { name => 'scope_datacenter' }, "scope-cluster:s" => { name => 'scope_cluster' }, - "filter-nic" => { name => 'filter_nic' }, "no-proxyswitch" => { name => 'no_proxyswitch' }, "unknown-status:s" => { name => 'unknown_status', default => '%{status} !~ /^connected$/i' }, "warning-status:s" => { name => 'warning_status', default => '' }, "critical-status:s" => { name => 'critical_status', default => '' }, + "unknown-link-status:s" => { name => 'unknown_link_status', default => '' }, "warning-link-status:s" => { name => 'warning_link_status', default => '' }, "critical-link-status:s" => { name => 'critical_link_status', default => '%{link_status} !~ /up/' }, }); @@ -277,7 +280,7 @@ sub check_options { $self->SUPER::check_options(%options); $self->change_macros(macros => ['unknown_status', 'warning_status', 'critical_status', - 'warning_link_status', 'critical_link_status']); + 'unknown_link_status', 'warning_link_status', 'critical_link_status']); } sub manage_selection { @@ -302,6 +305,8 @@ sub manage_selection { foreach my $pnic_name (sort keys %{$response->{data}->{$host_id}->{pnic}}) { $self->{host}->{$host_name}->{pnic} = {} if (!defined($self->{host}->{$host_name}->{pnic})); + next if (defined($self->{option_results}->{nic_name}) && $self->{option_results}->{nic_name} ne '' && + $pnic_name !~ /$self->{option_results}->{nic_name}/); $self->{host}->{$host_name}->{pnic}->{$pnic_name} = { display => $pnic_name, @@ -371,10 +376,6 @@ Search in following cluster(s) (can be a regexp). ESX nic to check. If not set, we check all nics. -=item B<--filter-nic> - -Nic name is a regexp. - =item B<--unknown-status> Set warning threshold for status (Default: '%{status} !~ /^connected$/i'). @@ -390,15 +391,20 @@ Can used special variables like: %{status} Set critical threshold for status (Default: ''). Can used special variables like: %{status} +=item B<--unknown-link-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{link_status} + =item B<--warning-link-status> Set warning threshold for status (Default: ''). -Can used special variables like: %{status} +Can used special variables like: %{link_status} =item B<--critical-link-status> Set critical threshold for status (Default: '%{link_status} !~ /up/'). -Can used special variables like: %{status} +Can used special variables like: %{link_status} =item B<--warning-*> diff --git a/apps/vmware/connector/mode/snapshotvm.pm b/apps/vmware/connector/mode/snapshotvm.pm index 776384840..460058990 100644 --- a/apps/vmware/connector/mode/snapshotvm.pm +++ b/apps/vmware/connector/mode/snapshotvm.pm @@ -40,6 +40,7 @@ sub new { "scope-host:s" => { name => 'scope_host' }, "filter-description:s" => { name => 'filter_description' }, "filter-os:s" => { name => 'filter_os' }, + "filter-uuid:s" => { name => 'filter_uuid' }, "display-description" => { name => 'display_description' }, "check-consolidation" => { name => 'check_consolidation' }, "nopoweredon-skip" => { name => 'nopoweredon_skip' }, @@ -137,20 +138,26 @@ sub run { } } - $self->{output}->perfdata_add(label => 'num_warning', - value => scalar(keys %{$vm_errors{warning}}), - min => 0); - $self->{output}->perfdata_add(label => 'num_critical', - value => scalar(keys %{$vm_errors{critical}}), - min => 0); + $self->{output}->perfdata_add( + label => 'num_warning', + nlabel => 'vm.snapshots.warning.current.count', + value => scalar(keys %{$vm_errors{warning}}), + min => 0 + ); + $self->{output}->perfdata_add( + label => 'num_critical', + nlabel => 'vm.snapshots.critical.current.count', + value => scalar(keys %{$vm_errors{critical}}), + min => 0 + ); if (scalar(keys %{$vm_errors{warning}}) > 0) { $self->{output}->output_add(severity => 'WARNING', - short_msg => sprintf('Snapshots for VM older than %d days: [%s]', ($self->{warning} / 86400), + short_msg => sprintf('Snapshots for VM older than %d days: [%s]', ($self->{option_results}->{warning} / 86400), join('] [', sort keys %{$vm_errors{warning}}))); } if (scalar(keys %{$vm_errors{critical}}) > 0) { $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf('Snapshots for VM older than %d days: [%s]', ($self->{critical} / 86400), + short_msg => sprintf('Snapshots for VM older than %d days: [%s]', ($self->{option_results}->{critical} / 86400), join('] [', sort keys %{$vm_errors{critical}}))); } if (scalar(keys %vm_consolidate) > 0) { diff --git a/apps/vmware/connector/mode/statconnectors.pm b/apps/vmware/connector/mode/statconnectors.pm index 4646e8de0..dc3f57d7a 100644 --- a/apps/vmware/connector/mode/statconnectors.pm +++ b/apps/vmware/connector/mode/statconnectors.pm @@ -35,7 +35,7 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'total-requests', set => { + { label => 'total-requests', nlabel => 'connector.requests.total.count', set => { key_values => [ { name => 'requests', diff => 1 } ], output_template => 'Total %s requests', perfdatas => [ @@ -47,7 +47,7 @@ sub set_counters { ]; $self->{maps_counters}->{container} = [ - { label => 'requests', set => { + { label => 'requests', nlabel => 'connector.requests.total.count', set => { key_values => [ { name => 'requests', diff => 1 } ], output_template => '%s requests', perfdatas => [ @@ -71,9 +71,9 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); + return $self; } diff --git a/apps/vmware/connector/mode/statusvm.pm b/apps/vmware/connector/mode/statusvm.pm index a7811690e..bce83bdc2 100644 --- a/apps/vmware/connector/mode/statusvm.pm +++ b/apps/vmware/connector/mode/statusvm.pm @@ -107,6 +107,7 @@ sub new { "scope-host:s" => { name => 'scope_host' }, "filter-description:s" => { name => 'filter_description' }, "filter-os:s" => { name => 'filter_os' }, + "filter-uuid:s" => { name => 'filter_uuid' }, "display-description" => { name => 'display_description' }, "unknown-status:s" => { name => 'unknown_status', default => '%{connection_state} !~ /^connected$/i' }, "warning-status:s" => { name => 'warning_status', default => '' }, diff --git a/apps/vmware/connector/mode/swaphost.pm b/apps/vmware/connector/mode/swaphost.pm index e636ffe28..5f7f1c95d 100644 --- a/apps/vmware/connector/mode/swaphost.pm +++ b/apps/vmware/connector/mode/swaphost.pm @@ -56,20 +56,20 @@ sub set_counters { closure_custom_threshold_check => \&catalog_status_threshold, } }, - { label => 'swap-in', set => { + { label => 'swap-in', nlabel => 'host.swap.in.usage.bytespersecond', set => { key_values => [ { name => 'swap_in' }, { name => 'display' } ], output_template => 'Swap In: %s %s/s', - output_change_bytes => 2, + output_change_bytes => 1, perfdatas => [ { label => 'swap_in', value => 'swap_in_absolute', template => '%s', unit => 'B/s', min => 0, label_extra_instance => 1 }, ], } }, - { label => 'swap-out', set => { + { label => 'swap-out', nlabel => 'host.swap.out.usage.bytespersecond', set => { key_values => [ { name => 'swap_out' }, { name => 'display' } ], output_template => 'Swap Out: %s %s/s', - output_change_bytes => 2, + output_change_bytes => 1, perfdatas => [ { label => 'swap_out', value => 'swap_out_absolute', template => '%s', unit => 'B/s', min => 0, label_extra_instance => 1 }, diff --git a/apps/vmware/connector/mode/swapvm.pm b/apps/vmware/connector/mode/swapvm.pm index e560626fa..9a715ecae 100644 --- a/apps/vmware/connector/mode/swapvm.pm +++ b/apps/vmware/connector/mode/swapvm.pm @@ -57,20 +57,20 @@ sub set_counters { closure_custom_threshold_check => \&catalog_status_threshold, } }, - { label => 'swap-in', set => { + { label => 'swap-in', nlabel => 'vm.swap.in.usage.bytespersecond', set => { key_values => [ { name => 'swap_in' }, { name => 'display' } ], output_template => 'Swap In: %s %s/s', - output_change_bytes => 2, + output_change_bytes => 1, perfdatas => [ { label => 'swap_in', value => 'swap_in_absolute', template => '%s', unit => 'B/s', min => 0, label_extra_instance => 1 }, ], } }, - { label => 'swap-out', set => { + { label => 'swap-out', nlabel => 'vm.swap.out.usage.bytespersecond', set => { key_values => [ { name => 'swap_out' }, { name => 'display' } ], output_template => 'Swap Out: %s %s/s', - output_change_bytes => 2, + output_change_bytes => 1, perfdatas => [ { label => 'swap_out', value => 'swap_out_absolute', template => '%s', unit => 'B/s', min => 0, label_extra_instance => 1 }, @@ -106,6 +106,7 @@ sub new { "scope-host:s" => { name => 'scope_host' }, "filter-description:s" => { name => 'filter_description' }, "filter-os:s" => { name => 'filter_os' }, + "filter-uuid:s" => { name => 'filter_uuid' }, "display-description" => { name => 'display_description' }, "unknown-status:s" => { name => 'unknown_status', default => '%{connection_state} !~ /^connected$/i or %{power_state} !~ /^poweredOn$/i' }, "warning-status:s" => { name => 'warning_status', default => '' }, diff --git a/apps/vmware/connector/mode/thinprovisioningvm.pm b/apps/vmware/connector/mode/thinprovisioningvm.pm index 4e50dd9f6..3013a083a 100644 --- a/apps/vmware/connector/mode/thinprovisioningvm.pm +++ b/apps/vmware/connector/mode/thinprovisioningvm.pm @@ -38,7 +38,8 @@ sub new { "scope-cluster:s" => { name => 'scope_cluster' }, "scope-host:s" => { name => 'scope_host' }, "filter-description:s" => { name => 'filter_description' }, - "filter-os:s" => { name => 'filter_os' }, + "filter-os:s" => { name => 'filter_os' }, + "filter-uuid:s" => { name => 'filter_uuid' }, "disconnect-status:s" => { name => 'disconnect_status', default => 'unknown' }, "nopoweredon-skip" => { name => 'nopoweredon_skip' }, "display-description" => { name => 'display_description' }, diff --git a/apps/vmware/connector/mode/timehost.pm b/apps/vmware/connector/mode/timehost.pm index 03337558b..4aa4852f5 100644 --- a/apps/vmware/connector/mode/timehost.pm +++ b/apps/vmware/connector/mode/timehost.pm @@ -65,7 +65,7 @@ sub set_counters { closure_custom_threshold_check => \&catalog_status_threshold, } }, - { label => 'time', set => { + { label => 'time', nlabel => 'host.time.offset.seconds', set => { key_values => [ { name => 'offset' }, { name => 'date' }, { name => 'display' } ], closure_custom_output => $self->can('custom_time_output'), perfdatas => [ diff --git a/apps/vmware/connector/mode/toolsvm.pm b/apps/vmware/connector/mode/toolsvm.pm index 9ff4547a2..35293769a 100644 --- a/apps/vmware/connector/mode/toolsvm.pm +++ b/apps/vmware/connector/mode/toolsvm.pm @@ -39,6 +39,7 @@ sub new { "scope-host:s" => { name => 'scope_host' }, "filter-description:s" => { name => 'filter_description' }, "filter-os:s" => { name => 'filter_os' }, + "filter-uuid:s" => { name => 'filter_uuid' }, "display-description" => { name => 'display_description' }, "disconnect-status:s" => { name => 'disconnect_status', default => 'unknown' }, "tools-notinstalled-status:s" => { name => 'tools_notinstalled_status', default => 'critical' }, @@ -155,15 +156,24 @@ sub run { if ($multiple == 1) { my $total = scalar(keys %not_up2date) + scalar(keys %not_running) + scalar(keys %not_installed); - $self->{output}->perfdata_add(label => 'not_updated', - value => scalar(keys %not_up2date), - min => 0, max => $total); - $self->{output}->perfdata_add(label => 'not_running', - value => scalar(keys %not_running), - min => 0, max => $total); - $self->{output}->perfdata_add(label => 'not_installed', - value => scalar(keys %not_installed), - min => 0, max => $total); + $self->{output}->perfdata_add( + label => 'not_updated', + nlabel => 'vm.tools.notupdated.current.count', + value => scalar(keys %not_up2date), + min => 0, max => $total + ); + $self->{output}->perfdata_add( + label => 'not_running', + nlabel => 'vm.tools.notrunning.current.count', + value => scalar(keys %not_running), + min => 0, max => $total + ); + $self->{output}->perfdata_add( + label => 'not_installed', + nlabel => 'vm.tools.notinstalled.current.count', + value => scalar(keys %not_installed), + min => 0, max => $total + ); } $self->{output}->display(); diff --git a/apps/vmware/connector/mode/uptimehost.pm b/apps/vmware/connector/mode/uptimehost.pm index e0d38d82b..afaedfbf1 100644 --- a/apps/vmware/connector/mode/uptimehost.pm +++ b/apps/vmware/connector/mode/uptimehost.pm @@ -65,7 +65,7 @@ sub set_counters { closure_custom_threshold_check => \&catalog_status_threshold, } }, - { label => 'time', set => { + { label => 'time', nlabel => 'host.uptime.offset.seconds', set => { key_values => [ { name => 'offset' }, { name => 'date' }, { name => 'display' } ], closure_custom_output => $self->can('custom_time_output'), perfdatas => [ diff --git a/apps/vmware/connector/mode/vmoperationcluster.pm b/apps/vmware/connector/mode/vmoperationcluster.pm index 6e1c5c149..05e620968 100644 --- a/apps/vmware/connector/mode/vmoperationcluster.pm +++ b/apps/vmware/connector/mode/vmoperationcluster.pm @@ -34,7 +34,7 @@ sub set_counters { ]; $self->{maps_counters}->{cluster} = [ - { label => 'svmotion', set => { + { label => 'svmotion', nlabel => 'cluster.operations.svmotion.current.count', set => { key_values => [ { name => 'numSVMotion', diff => 1 }, { name => 'display' } ], output_template => 'SVMotion %s', perfdatas => [ @@ -43,7 +43,7 @@ sub set_counters { ], } }, - { label => 'vmotion', set => { + { label => 'vmotion', nlabel => 'cluster.operations.vmotion.current.count', set => { key_values => [ { name => 'numVMotion', diff => 1 }, { name => 'display' } ], output_template => 'VMotion %s', perfdatas => [ @@ -52,7 +52,7 @@ sub set_counters { ], } }, - { label => 'clone', set => { + { label => 'clone', nlabel => 'cluster.operations.clone.current.count', set => { key_values => [ { name => 'numClone', diff => 1 }, { name => 'display' } ], output_template => 'Clone %s', perfdatas => [ diff --git a/apps/vmware/connector/plugin.pm b/apps/vmware/connector/plugin.pm index f0e69e560..00265e891 100644 --- a/apps/vmware/connector/plugin.pm +++ b/apps/vmware/connector/plugin.pm @@ -31,43 +31,44 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'alarm-datacenter' => 'apps::vmware::connector::mode::alarmdatacenter', - 'alarm-host' => 'apps::vmware::connector::mode::alarmhost', - 'countvm-host' => 'apps::vmware::connector::mode::countvmhost', - 'cpu-host' => 'apps::vmware::connector::mode::cpuhost', - 'cpu-vm' => 'apps::vmware::connector::mode::cpuvm', - 'datastore-countvm' => 'apps::vmware::connector::mode::datastorecountvm', - 'datastore-host' => 'apps::vmware::connector::mode::datastorehost', - 'datastore-io' => 'apps::vmware::connector::mode::datastoreio', - 'datastore-iops' => 'apps::vmware::connector::mode::datastoreiops', - 'datastore-snapshot' => 'apps::vmware::connector::mode::datastoresnapshot', - 'datastore-usage' => 'apps::vmware::connector::mode::datastoreusage', - 'datastore-vm' => 'apps::vmware::connector::mode::datastorevm', - 'device-vm' => 'apps::vmware::connector::mode::devicevm', - 'getmap' => 'apps::vmware::connector::mode::getmap', - 'health-host' => 'apps::vmware::connector::mode::healthhost', - 'limit-vm' => 'apps::vmware::connector::mode::limitvm', - 'list-clusters' => 'apps::vmware::connector::mode::listclusters', - 'list-datacenters' => 'apps::vmware::connector::mode::listdatacenters', - 'list-datastores' => 'apps::vmware::connector::mode::listdatastores', - 'list-nichost' => 'apps::vmware::connector::mode::listnichost', - 'maintenance-host' => 'apps::vmware::connector::mode::maintenancehost', - 'memory-host' => 'apps::vmware::connector::mode::memoryhost', - 'memory-vm' => 'apps::vmware::connector::mode::memoryvm', - 'net-host' => 'apps::vmware::connector::mode::nethost', - 'service-host' => 'apps::vmware::connector::mode::servicehost', - 'snapshot-vm' => 'apps::vmware::connector::mode::snapshotvm', - 'stat-connectors' => 'apps::vmware::connector::mode::statconnectors', - 'status-host' => 'apps::vmware::connector::mode::statushost', - 'status-vm' => 'apps::vmware::connector::mode::statusvm', - 'swap-host' => 'apps::vmware::connector::mode::swaphost', - 'swap-vm' => 'apps::vmware::connector::mode::swapvm', - 'thinprovisioning-vm' => 'apps::vmware::connector::mode::thinprovisioningvm', - 'time-host' => 'apps::vmware::connector::mode::timehost', - 'tools-vm' => 'apps::vmware::connector::mode::toolsvm', - 'uptime-host' => 'apps::vmware::connector::mode::uptimehost', - 'vmoperation-cluster' => 'apps::vmware::connector::mode::vmoperationcluster', - ); + 'alarm-datacenter' => 'apps::vmware::connector::mode::alarmdatacenter', + 'alarm-host' => 'apps::vmware::connector::mode::alarmhost', + 'countvm-host' => 'apps::vmware::connector::mode::countvmhost', + 'cpu-host' => 'apps::vmware::connector::mode::cpuhost', + 'cpu-vm' => 'apps::vmware::connector::mode::cpuvm', + 'datastore-countvm' => 'apps::vmware::connector::mode::datastorecountvm', + 'datastore-host' => 'apps::vmware::connector::mode::datastorehost', + 'datastore-io' => 'apps::vmware::connector::mode::datastoreio', + 'datastore-iops' => 'apps::vmware::connector::mode::datastoreiops', + 'datastore-snapshot' => 'apps::vmware::connector::mode::datastoresnapshot', + 'datastore-usage' => 'apps::vmware::connector::mode::datastoreusage', + 'datastore-vm' => 'apps::vmware::connector::mode::datastorevm', + 'device-vm' => 'apps::vmware::connector::mode::devicevm', + 'discovery' => 'apps::vmware::connector::mode::discovery', + 'getmap' => 'apps::vmware::connector::mode::getmap', + 'health-host' => 'apps::vmware::connector::mode::healthhost', + 'limit-vm' => 'apps::vmware::connector::mode::limitvm', + 'list-clusters' => 'apps::vmware::connector::mode::listclusters', + 'list-datacenters' => 'apps::vmware::connector::mode::listdatacenters', + 'list-datastores' => 'apps::vmware::connector::mode::listdatastores', + 'list-nichost' => 'apps::vmware::connector::mode::listnichost', + 'maintenance-host' => 'apps::vmware::connector::mode::maintenancehost', + 'memory-host' => 'apps::vmware::connector::mode::memoryhost', + 'memory-vm' => 'apps::vmware::connector::mode::memoryvm', + 'net-host' => 'apps::vmware::connector::mode::nethost', + 'service-host' => 'apps::vmware::connector::mode::servicehost', + 'snapshot-vm' => 'apps::vmware::connector::mode::snapshotvm', + 'stat-connectors' => 'apps::vmware::connector::mode::statconnectors', + 'status-host' => 'apps::vmware::connector::mode::statushost', + 'status-vm' => 'apps::vmware::connector::mode::statusvm', + 'swap-host' => 'apps::vmware::connector::mode::swaphost', + 'swap-vm' => 'apps::vmware::connector::mode::swapvm', + 'thinprovisioning-vm' => 'apps::vmware::connector::mode::thinprovisioningvm', + 'time-host' => 'apps::vmware::connector::mode::timehost', + 'tools-vm' => 'apps::vmware::connector::mode::toolsvm', + 'uptime-host' => 'apps::vmware::connector::mode::uptimehost', + 'vmoperation-cluster' => 'apps::vmware::connector::mode::vmoperationcluster', + ); $self->{custom_modes}{connector} = 'apps::vmware::connector::custom::connector'; return $self; @@ -79,6 +80,6 @@ __END__ =head1 PLUGIN DESCRIPTION -Check VMWare with centreon-esxd connector. +Check VMWare with centreon-vmware connector. =cut diff --git a/apps/vmware/wsman/mode/components/cim_numericsensor.pm b/apps/vmware/wsman/mode/components/cim_numericsensor.pm index f6c9d1b3c..5afe1e9c1 100644 --- a/apps/vmware/wsman/mode/components/cim_numericsensor.pm +++ b/apps/vmware/wsman/mode/components/cim_numericsensor.pm @@ -43,7 +43,7 @@ sub check { next if ($self->check_filter(section => 'cim_numericsensor', instance => $instance)); my $status = $self->get_status(entry => $_); if (!defined($status)) { - $self->{output}->output_add(long_msg => sprintf("skipping numeric sensor '%s' : no status", $_->{ElementName}), debug => 1); + $self->{output}->output_add(long_msg => sprintf("skipping numeric sensor '%s' : no status", $name), debug => 1); next; } @@ -53,14 +53,14 @@ sub check { $value = $value * 10 ** int($_->{UnitModifier}) if (defined($value) && $value =~ /\d/); $self->{output}->output_add(long_msg => sprintf("Numeric sensor '%s' status is '%s' [instance: %s, current value: %s].", - $_->{ElementName}, $status, + $name, $status, $instance, defined($value) ? $value : '-' )); my $exit = $self->get_severity(section => 'cim_numericsensor', label => 'default', value => $status); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Numeric sensor '%s' status is '%s'", - $_->{ElementName}, $status)); + $name, $status)); } @@ -96,17 +96,21 @@ sub check { if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Numeric sensor '%s' value is %s %s", - $_->{ElementName}, $value, + $name, $value, defined($mapping_units->{$_->{BaseUnits}}) ? $mapping_units->{$_->{BaseUnits}} : '-')); } my $min = defined($_->{MinReadable}) && $_->{MinReadable} =~ /\d/ ? $_->{MinReadable} * 10 ** int($_->{UnitModifier}) : undef; my $max = defined($_->{MaxReadable}) && $_->{MaxReadable} =~ /\d/ ? $_->{MaxReadable} * 10 ** int($_->{UnitModifier}) : undef; - $self->{output}->perfdata_add(label => $instance, unit => $mapping_units->{$_->{BaseUnits}}, - value => $value, - warning => $warn, - critical => $crit, - min => $min, max => $max); + $self->{output}->perfdata_add( + label => $sensor_type, unit => $mapping_units->{$_->{BaseUnits}}, + nlabel => 'hardware.sensor.' . lc($sensor_type) . '.' . lc($mapping_units->{$_->{BaseUnits}}), + instances => $name, + value => $value, + warning => $warn, + critical => $crit, + min => $min, max => $max + ); } } diff --git a/apps/vmware/wsman/mode/components/resources.pm b/apps/vmware/wsman/mode/components/resources.pm index d8572e587..858945d50 100644 --- a/apps/vmware/wsman/mode/components/resources.pm +++ b/apps/vmware/wsman/mode/components/resources.pm @@ -83,32 +83,32 @@ $mapping_OperationalStatus = { $mapping_sensortype = { 0 => 'unknown', 1 => 'other', - 2 => 'temp', # Temperature - 3 => 'volt', # Voltage + 2 => 'temperature', # Temperature + 3 => 'voltage', # Voltage 4 => 'current', # Current 5 => 'tachometer', 6 => 'counter', 7 => 'switch', 8 => 'lock', - 9 => 'hum', # Humidity - 10 => 'smoke_detection', # Smoke Detection + 9 => 'humidity', # Humidity + 10 => 'smokeDetection', # Smoke Detection 11 => 'presence', - 12 => 'air_flow', # Air Flow - 13 => 'power_consumption', # Power Consumption - 14 => 'power_production', # Power Production - 15 => 'pressure_intrusion', # PressureIntrusion + 12 => 'airFlow', # Air Flow + 13 => 'powerConsumption', # Power Consumption + 14 => 'powerProduction', # Power Production + 15 => 'pressureIntrusion', # PressureIntrusion 16 => 'intrusion', }; $mapping_units = { - 0 => '', - 1 => '', - 2 => 'C', # Degrees C - 3 => 'F', # Degrees F - 4 => 'K', # Degrees K - 5 => 'V', # Volts - 6 => 'A', # Amps, - 7 => 'W', # Watts + 0 => 'unknown', + 1 => 'unknown', + 2 => 'celsius', # Degrees C + 3 => 'fahrenheit', # Degrees F + 4 => 'kelvin', # Degrees K + 5 => 'volt', # Volts + 6 => 'ampere', # Amps, + 7 => 'watt', # Watts 8 => 'Joules', 9 => 'Coulombs', 10 => 'VA', @@ -130,11 +130,11 @@ $mapping_units = { 26 => 'Mils', 27 => 'Inches', 28 => 'Feet', - 29 => 'Cubic_Inches', - 30 => 'Cubic_Feet', + 29 => 'CubicInches', + 30 => 'CubicFeet', 31 => 'Meters', - 32 => 'Cubic_Centimeters', - 33 => 'Cubic_Meters', + 32 => 'CubicCentimeters', + 33 => 'CubicMeters', 34 => 'Liters', 35 => 'Fluid_Ounces', 36 => 'Radians', @@ -144,8 +144,8 @@ $mapping_units = { 40 => 'Gravities', 41 => 'Ounces', 42 => 'Pounds', - 43 => 'Foot_Pounds', - 44 => 'Ounce_Inches', + 43 => 'FootPounds', + 44 => 'OunceInches', 45 => 'Gauss', 46 => 'Gilberts', 47 => 'Henries', @@ -160,14 +160,14 @@ $mapping_units = { 56 => 'DbC', 57 => 'Grays', 58 => 'Sieverts', - 59 => 'Color_Temperature_Degrees_K', - 60 => 'b', # bits - 61 => 'B', # Bytes + 59 => 'ColorTemperatureDegreesKelvin', + 60 => 'bits', # bits + 61 => 'bytes', # Bytes 62 => 'Words', 63 => 'DoubleWords', 64 => 'QuadWords', - 65 => '%', # Percentage, + 65 => 'percentage', # Percentage, 66 => 'Pascals', }; -1; \ No newline at end of file +1; diff --git a/apps/voip/3cx/restapi/custom/api.pm b/apps/voip/3cx/restapi/custom/api.pm new file mode 100644 index 000000000..af5642fa8 --- /dev/null +++ b/apps/voip/3cx/restapi/custom/api.pm @@ -0,0 +1,300 @@ +# +# Copyright 2019 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 apps::voip::3cx::restapi::custom::api; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::http; +use centreon::plugins::statefile; +use JSON::XS; +use Digest::MD5 qw(md5_hex); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port'}, + "proto:s" => { name => 'proto' }, + "api-username:s" => { name => 'api_username' }, + "api-password:s" => { name => 'api_password' }, + "timeout:s" => { name => 'timeout', default => 30 }, + }); + } + + $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{http} = centreon::plugins::http->new(%options); + $self->{cache} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : undef; + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443; + $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 30; + $self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef; + $self->{api_username} = (defined($self->{option_results}->{api_username})) ? $self->{option_results}->{api_username} : undef; + $self->{api_password} = (defined($self->{option_results}->{api_password})) ? $self->{option_results}->{api_password} : undef; + + if (!defined($self->{hostname}) || $self->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --hostname option."); + $self->{output}->option_exit(); + } + if (!defined($self->{api_username}) || $self->{api_username} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --api-username option."); + $self->{output}->option_exit(); + } + if (!defined($self->{api_password}) || $self->{api_password} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --api-password option."); + $self->{output}->option_exit(); + } + + $self->{cache}->check_options(option_results => $self->{option_results}); + + return 0; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{hostname}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{ssl_opt} = $self->{ssl_opt}; + $self->{option_results}->{timeout} = $self->{timeout}; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->add_header(key => 'Content-Type', value => 'application/json;charset=UTF-8'); + if (defined($self->{cookie}) && defined($self->{xsrf})) { + $self->{http}->add_header(key => 'Cookie', value => '.AspNetCore.Cookies=' . $self->{cookie}); + $self->{http}->add_header(key => 'X-XSRF-TOKEN', value => $self->{xsrf}); + } + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub authenticate { + my ($self, %options) = @_; + + my $has_cache_file = $options{statefile}->read(statefile => '3cx_api_' . md5_hex($self->{option_results}->{hostname}) . '_' . md5_hex($self->{option_results}->{api_username})); + my $cookie = $options{statefile}->get(name => 'cookie'); + my $xsrf = $options{statefile}->get(name => 'xsrf'); + my $expires_on = $options{statefile}->get(name => 'expires_on'); + + if ($has_cache_file == 0 || !defined($cookie) || !defined($xsrf) || (($expires_on - time()) < 10)) { + my $post_data = '{"Username":"' . $self->{api_username} . '",' . + '"Password":"' . $self->{api_password} . '"}'; + + $self->settings(); + + my $content = $self->{http}->request( + method => 'POST', query_form_post => $post_data, + url_path => '/api/login', + warning_status => '', unknown_status => '', critical_status => '%{http_code} < 200 or %{http_code} >= 300' + ); + + my $header = $self->{http}->get_header(name => 'Set-Cookie'); + if (defined ($header) && $header =~ /(?:^| ).AspNetCore.Cookies=([^;]+);.*/) { + $cookie = $1; + } else { + $self->{output}->output_add(long_msg => $content, debug => 1); + $self->{output}->add_option_msg(short_msg => "Error retrieving cookie"); + $self->{output}->option_exit(); + } + if (defined ($header) && $header =~ /(?:^| )XSRF-TOKEN=([^;]+);.*/) { + $xsrf = $1; + } else { + $self->{output}->output_add(long_msg => $content, debug => 1); + $self->{output}->add_option_msg(short_msg => "Error retrieving xsrf-token"); + $self->{output}->option_exit(); + } + + my $datas = { last_timestamp => time(), cookie => $cookie, xsrf => $xsrf, expires_on => time() + (3600 * 24) }; + $options{statefile}->write(data => $datas); + } + + $self->{cookie} = $cookie; + $self->{xsrf} = $xsrf; +} + +sub request_api { + my ($self, %options) = @_; + + if (!defined($self->{cookie})) { + $self->authenticate(statefile => $self->{cache}); + } + + $self->settings(); + + my $content = $self->{http}->request(%options, + warning_status => '', unknown_status => '', critical_status => '%{http_code} < 200 or %{http_code} >= 300' + ); + + # Some content may be strangely returned, for example : "[{\"Category\":\"provider\",\"Count\":1}]" + if (defined($options{eval_content}) && $options{eval_content} == 1) { + $content = eval "$content"; + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->output_add(long_msg => $content, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + if (!defined($decoded)) { + $self->{output}->output_add(long_msg => $decoded, debug => 1); + $self->{output}->add_option_msg(short_msg => "Error while retrieving data (add --debug option for detailed message)"); + $self->{output}->option_exit(); + } + + return $decoded; +} + +sub internal_single_status { + my ($self, %options) = @_; + + my $status = $self->request_api(method => 'GET', url_path =>'/api/SystemStatus/GetSingleStatus'); + return $status; +} + +sub api_single_status { + my ($self, %options) = @_; + + my $status = $self->internal_single_status(); + return $status->{Health}; +} + +sub internal_system_status { + my ($self, %options) = @_; + + my $status = $self->request_api(method => 'GET', url_path =>'/api/SystemStatus'); + return $status; +} + +sub api_system_status { + my ($self, %options) = @_; + + my $status = $self->internal_system_status(); + return $status; +} + +sub internal_update_checker { + my ($self, %options) = @_; + + my $status = $self->request_api(method => 'GET', url_path =>'/api/UpdateChecker/GetFromParams', eval_content => 1); + return $status; +} + +sub api_update_checker { + my ($self, %options) = @_; + + my $status = $self->internal_update_checker(); + return $status; +} + +1; + +__END__ + +=head1 NAME + +3CX Rest API + +=head1 REST API OPTIONS + +=over 8 + +=item B<--hostname> + +Set hostname or IP of 3CX server. + +=item B<--port> + +Set 3CX Port (Default: '443'). + +=item B<--proto> + +Specify https if needed (Default: 'https'). + +=item B<--api-username> + +Set 3CX Username. + +=item B<--api-password> + +Set 3CX Password. + +=item B<--timeout> + +Threshold for HTTP timeout (Default: '30'). + +=back + +=cut diff --git a/apps/voip/3cx/restapi/mode/system.pm b/apps/voip/3cx/restapi/mode/system.pm new file mode 100644 index 000000000..31a6b7803 --- /dev/null +++ b/apps/voip/3cx/restapi/mode/system.pm @@ -0,0 +1,187 @@ +# +# Copyright 2019 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 apps::voip::3cx::restapi::mode::system; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'health : ' . $self->{result_values}->{health}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{health} = $options{new_datas}->{$self->{instance} . '_health'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'service', type => 1, cb_prefix_output => 'prefix_service_output', message_multiple => 'All services are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'calls-active', nlabel => 'system.calls.active.current', set => { + key_values => [ { name => 'calls_active' } ], + output_template => 'calls active : %s', + perfdatas => [ + { label => 'calls_active', template => '%s', value => 'calls_active_absolute', + min => 0 }, + ], + } + }, + { label => 'extensions-registered', nlabel => 'system.extensions.registered.current', set => { + key_values => [ { name => 'extensions_registered' } ], + output_template => 'extensions registered : %s', + perfdatas => [ + { label => 'extensions_registered', template => '%s', value => 'extensions_registered_absolute', + min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{service} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'health' }, { 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 => \&catalog_status_threshold, + } + }, + ]; +} + +sub prefix_service_output { + my ($self, %options) = @_; + + return "Service '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{health} =~ /false/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => [ + 'warning_status', 'critical_status', 'unknown_status', + ]); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $single = $options{custom}->api_single_status(); + my $system = $options{custom}->api_system_status(); + my $update = $options{custom}->api_update_checker(); + + $self->{service} = {}; + foreach my $item (keys %$single) { + # As of 3CX 15.5 / 16, we have Firewall, Phones, Trunks + $self->{service}->{$item} = { + display => $item, + health => $single->{$item} ? 'true' : 'false', + }; + } + # As per 3CX support, $single->{Trunks} does not trigger if TrunksRegistered != TrunksTotal, + # but only if "trunk is unsupported", so let's workaround + $self->{service}->{HasUnregisteredTrunks} = { + display => 'HasUnregisteredTrunks', + health => ($system->{TrunksRegistered} < $system->{TrunksTotal}) ? 'false' : 'true', + }; + $self->{service}->{HasNotRunningServices} = { + display => 'HasNotRunningServices', + health => $system->{HasNotRunningServices} ? 'false' : 'true', + }; + $self->{service}->{HasUnregisteredSystemExtensions} = { + display => 'HasUnregisteredSystemExtensions', + health => $system->{HasUnregisteredSystemExtensions} ? 'false' : 'true', + }; + $self->{service}->{HasUpdatesAvailable} = { + display => 'HasUpdatesAvailable', + health => scalar(@$update) ? 'false' : 'true', + }; + + $self->{global} = { + calls_active => $system->{CallsActive}, + extensions_registered => $system->{ExtensionsRegistered}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check system health + +=over 8 + +=item B<--unknown-status> + +Set unknown threshold for status. +Can used special variables like: %{health}, %{display} + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{health}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{health} =~ /false/'). +Can used special variables like: %{health}, %{display} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'calls-active', 'extensions-registered'. + +=back + +=cut diff --git a/apps/voip/3cx/restapi/plugin.pm b/apps/voip/3cx/restapi/plugin.pm new file mode 100644 index 000000000..0bf65c482 --- /dev/null +++ b/apps/voip/3cx/restapi/plugin.pm @@ -0,0 +1,56 @@ +# +# Copyright 2019 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 apps::voip::3cx::restapi::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'system' => 'apps::voip::3cx::restapi::mode::system', + ); + + $self->{custom_modes}{api} = 'apps::voip::3cx::restapi::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check 3CX ressources through its HTTPS remote API. + +Requirements: at least 3CX 15.5. + +=over 8 + +=back + +=cut diff --git a/apps/vtom/restapi/custom/api.pm b/apps/vtom/restapi/custom/api.pm index 06a3d3d08..938b13d1f 100644 --- a/apps/vtom/restapi/custom/api.pm +++ b/apps/vtom/restapi/custom/api.pm @@ -40,23 +40,20 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s@" => { name => 'hostname' }, - "port:s@" => { name => 'port' }, - "proto:s@" => { name => 'proto' }, - "username:s@" => { name => 'username' }, - "password:s@" => { name => 'password' }, - "proxyurl:s@" => { name => 'proxyurl' }, - "timeout:s@" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s@" => { name => 'hostname' }, + "port:s@" => { name => 'port' }, + "proto:s@" => { name => 'proto' }, + "username:s@" => { name => 'username' }, + "password:s@" => { name => 'password' }, + "timeout:s@" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; @@ -100,7 +97,6 @@ sub check_options { $self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : ''; $self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{password}}) : ''; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef; if (!defined($self->{hostname})) { $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); @@ -121,7 +117,6 @@ sub build_options_for_httplib { $self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{port} = $self->{port}; $self->{option_results}->{proto} = $self->{proto}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; $self->{option_results}->{credentials} = 1; $self->{option_results}->{basic} = 1; $self->{option_results}->{username} = $self->{username}; @@ -230,24 +225,16 @@ Specify https if needed (Default: 'http') =item B<--username> -Storeonce username. +VTOM username. =item B<--password> -Storeonce password. - -=item B<--proxyurl> - -Proxy URL if any +VTOM password. =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/apps/wsus/local/mode/computersstatus.pm b/apps/wsus/local/mode/computersstatus.pm new file mode 100644 index 000000000..74b3933aa --- /dev/null +++ b/apps/wsus/local/mode/computersstatus.pm @@ -0,0 +1,229 @@ +# +# Copyright 2019 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 apps::wsus::local::mode::computersstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use JSON::XS; +use centreon::common::powershell::wsus::computersstatus; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_output' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'up-to-date', set => { + key_values => [ { name => 'ComputersUpToDateCount' } ], + output_template => 'Up-to-date: %d', + perfdatas => [ + { label => 'computers_up_to_date', value => 'ComputersUpToDateCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + { label => 'needing-updates', set => { + key_values => [ { name => 'ComputerTargetsNeedingUpdatesCount' } ], + output_template => 'Needing Updates: %d', + perfdatas => [ + { label => 'computers_needing_updates', value => 'ComputerTargetsNeedingUpdatesCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + { label => 'with-update-errors', set => { + key_values => [ { name => 'ComputerTargetsWithUpdateErrorsCount' } ], + output_template => 'With Update Errors: %d', + perfdatas => [ + { label => 'computers_with_update_errors', value => 'ComputerTargetsWithUpdateErrorsCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + { label => 'not-contacted', set => { + key_values => [ { name => 'ComputersNotContactedSinceCount' } ], + output_template => 'Not Contacted: %d', + perfdatas => [ + { label => 'computers_not_contacted', value => 'ComputersNotContactedSinceCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + { label => 'unassigned', set => { + key_values => [ { name => 'UnassignedComputersCount' } ], + output_template => 'Unassigned: %s', + perfdatas => [ + { label => 'computers_unassigned', value => 'UnassignedComputersCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Computers "; +} + +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 => { + "timeout:s" => { name => 'timeout', default => 30 }, + "command:s" => { name => 'command', default => 'powershell.exe' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, + "no-ps" => { name => 'no_ps' }, + "ps-exec-only" => { name => 'ps_exec_only' }, + "wsus-server:s" => { name => 'wsus_server', default => 'localhost' }, + "wsus-port:s" => { name => 'wsus_port', default => 8530 }, + "not-updated-since:s" => { name => 'not_updated_since', default => 10 }, + "use-ssl" => { name => 'use_ssl' }, + "filter-counters:s" => { name => 'filter_counters' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $use_ssl = "\$false"; + $use_ssl = "\$true" if (defined($self->{option_results}->{use_ssl})); + + my $ps = centreon::common::powershell::wsus::computersstatus::get_powershell( + no_ps => $self->{option_results}->{no_ps}, + wsus_server => $self->{option_results}->{wsus_server}, + wsus_port => $self->{option_results}->{wsus_port}, + not_updated_since => $self->{option_results}->{not_updated_since}, + use_ssl => $use_ssl + ); + + $self->{option_results}->{command_options} .= " " . $ps; + my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}); + if (defined($self->{option_results}->{ps_exec_only})) { + $self->{output}->output_add(severity => 'OK', + short_msg => $stdout); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode(centreon::plugins::misc::powershell_json_sanitizer(string => $stdout, output => $self->{output})); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + $self->{global} = { %$decoded }; +} + +1; + +__END__ + +=head1 MODE + +Check computers status. + +=over 8 + +=item B<--timeout> + +Set timeout time for command execution (Default: 30 sec) + +=item B<--no-ps> + +Don't encode powershell. To be used with --command and 'type' command. + +=item B<--command> + +Command to get information (Default: 'powershell.exe'). +Can be changed if you have output in a file. To be used with --no-ps option. + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: '-InputFormat none -NoLogo -EncodedCommand'). + +=item B<--ps-exec-only> + +Print powershell output. + +=item B<--wsus-server> + +Set WSUS hostname/IP. + +=item B<--wsus-port> + +Set WSUS port. + +=item B<--not-updated-since> + +Time in minutes to count computers not updated since. + +=item B<--use-ssl> + +Set if WSUS use ssl. + +=item B<--warning-*> + +Warning thresholds. +Can be: 'needing-updates', 'with-update-errors', +'up-to-date', 'not-contacted', 'unassigned' + +=item B<--critical-*> + +Critical thresholds. +Can be: 'needing-updates', 'with-update-errors', +'up-to-date', 'not-contacted', 'unassigned' + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='errors' + +=back + +=cut diff --git a/apps/wsus/local/mode/serverstatistics.pm b/apps/wsus/local/mode/serverstatistics.pm new file mode 100644 index 000000000..11954f076 --- /dev/null +++ b/apps/wsus/local/mode/serverstatistics.pm @@ -0,0 +1,246 @@ +# +# Copyright 2019 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 apps::wsus::local::mode::serverstatistics; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use JSON::XS; +use centreon::common::powershell::wsus::serverstatistics; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'computers', set => { + key_values => [ { name => 'ComputerTargetCount' } ], + output_template => 'Computers: %d', + perfdatas => [ + { label => 'computers', value => 'ComputerTargetCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + { label => 'computer-groups', set => { + key_values => [ { name => 'CustomComputerTargetGroupCount' } ], + output_template => 'Computer Groups: %d', + perfdatas => [ + { label => 'computer_groups', value => 'CustomComputerTargetGroupCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + { label => 'updates', set => { + key_values => [ { name => 'UpdateCount' } ], + output_template => 'Updates: %d', + perfdatas => [ + { label => 'updates', value => 'UpdateCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + { label => 'approved-updates', set => { + key_values => [ { name => 'ApprovedUpdateCount' } ], + output_template => 'Approved Updates: %d', + perfdatas => [ + { label => 'approved_updates', value => 'ApprovedUpdateCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + { label => 'declined-updates', set => { + key_values => [ { name => 'DeclinedUpdateCount' } ], + output_template => 'Declined Updates: %d', + perfdatas => [ + { label => 'declined_updates', value => 'DeclinedUpdateCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + { label => 'not-approved-updates', set => { + key_values => [ { name => 'NotApprovedUpdateCount' } ], + output_template => 'Not Approved Updates: %d', + perfdatas => [ + { label => 'not_approved_updates', value => 'NotApprovedUpdateCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + { label => 'stale-updates', set => { + key_values => [ { name => 'UpdatesWithStaleUpdateApprovalsCount' } ], + output_template => 'Stale Updates: %d', + perfdatas => [ + { label => 'stale_updates', value => 'UpdatesWithStaleUpdateApprovalsCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + { label => 'expired-updates', set => { + key_values => [ { name => 'ExpiredUpdateCount' } ], + output_template => 'Expired Updates: %d', + perfdatas => [ + { label => 'expired_updates', value => 'ExpiredUpdateCount_absolute', + template => '%d', 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 => { + "timeout:s" => { name => 'timeout', default => 30 }, + "command:s" => { name => 'command', default => 'powershell.exe' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, + "no-ps" => { name => 'no_ps' }, + "ps-exec-only" => { name => 'ps_exec_only' }, + "wsus-server:s" => { name => 'wsus_server', default => 'localhost' }, + "wsus-port:s" => { name => 'wsus_port', default => 8530 }, + "use-ssl" => { name => 'use_ssl' }, + "filter-counters:s" => { name => 'filter_counters' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $use_ssl = "\$false"; + $use_ssl = "\$true" if (defined($self->{option_results}->{use_ssl})); + + my $ps = centreon::common::powershell::wsus::serverstatistics::get_powershell( + no_ps => $self->{option_results}->{no_ps}, + wsus_server => $self->{option_results}->{wsus_server}, + wsus_port => $self->{option_results}->{wsus_port}, + use_ssl => $use_ssl + ); + + $self->{option_results}->{command_options} .= " " . $ps; + my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}); + if (defined($self->{option_results}->{ps_exec_only})) { + $self->{output}->output_add(severity => 'OK', + short_msg => $stdout); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode(centreon::plugins::misc::powershell_json_sanitizer(string => $stdout, output => $self->{output})); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + $self->{global} = { %$decoded }; +} + +1; + +__END__ + +=head1 MODE + +Check server statistics. + +=over 8 + +=item B<--timeout> + +Set timeout time for command execution (Default: 30 sec) + +=item B<--no-ps> + +Don't encode powershell. To be used with --command and 'type' command. + +=item B<--command> + +Command to get information (Default: 'powershell.exe'). +Can be changed if you have output in a file. To be used with --no-ps option. + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: '-InputFormat none -NoLogo -EncodedCommand'). + +=item B<--ps-exec-only> + +Print powershell output. + +=item B<--wsus-server> + +Set WSUS hostname/IP (Dafault: localhost). + +=item B<--wsus-port> + +Set WSUS port (Default: 8530). + +=item B<--use-ssl> + +Set if WSUS use ssl. + +=item B<--warning-*> + +Warning thresholds. +Can be: 'computers', 'computer-groups', 'updates', +'approved-updates', 'declined-updates', +'not-approved-updates', 'stale-updates', 'expired-updates' + +=item B<--critical-*> + +Critical thresholds. +Can be: 'computers', 'computer-groups', 'updates', +'approved-updates', 'declined-updates', +'not-approved-updates', 'stale-updates', 'expired-updates' + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='not' + +=back + +=cut diff --git a/apps/wsus/local/mode/synchronisationstatus.pm b/apps/wsus/local/mode/synchronisationstatus.pm new file mode 100644 index 000000000..4e2925fc0 --- /dev/null +++ b/apps/wsus/local/mode/synchronisationstatus.pm @@ -0,0 +1,368 @@ +# +# Copyright 2019 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 apps::wsus::local::mode::synchronisationstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use JSON::XS; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use centreon::common::powershell::wsus::synchronisationstatus; +use DateTime; + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("status is '%s'", $self->{result_values}->{status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_SynchronizationStatus'}; + return 0; +} + +sub custom_last_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("status is '%s'", $self->{result_values}->{status}); + return $msg; +} + +sub custom_last_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_LastSynchronizationResult'}; + return 0; +} + +sub custom_progress_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => 'synchronisation_progress', + value => $self->{result_values}->{progress}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}), + min => 0, max => 100); +} + +sub custom_progress_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{progress}, + threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_progress_output { + my ($self, %options) = @_; + + my $msg = sprintf("Progress: %.2f%% (%d/%d items)", + $self->{result_values}->{progress}, + $self->{result_values}->{processed}, + $self->{result_values}->{total}); + return $msg; +} + +sub custom_progress_calc { + my ($self, %options) = @_; + + $self->{result_values}->{processed} = $options{new_datas}->{$self->{instance} . '_ProcessedItems'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_TotalItems'}; + $self->{result_values}->{progress} = 0; + return 0 if ($self->{result_values}->{total} == 0); + + $self->{result_values}->{progress} = $self->{result_values}->{processed} * 100 / $self->{result_values}->{total}; + + return 0; +} + +sub custom_duration_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => 'last_synchronisation_duration', + value => $self->{result_values}->{duration}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}), + min => 0, unit => 's'); +} + +sub custom_duration_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{duration}, + threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_duration_output { + my ($self, %options) = @_; + + my $msg = sprintf("Duration: %s", centreon::plugins::misc::change_seconds(value => $self->{result_values}->{duration})); + return $msg; +} + +sub custom_duration_calc { + my ($self, %options) = @_; + + my $start_time = $options{new_datas}->{$self->{instance} . '_LastSynchronizationStartTime'}; + my $end_time = $options{new_datas}->{$self->{instance} . '_LastSynchronizationEndTime'}; + + # 2019-03-21T13:00:13 + my $tz = centreon::plugins::misc::set_timezone(name => $self->{option_results}->{timezone}); + $start_time =~ /^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)$/; + my $start_time_dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6, %$tz); + $end_time =~ /^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)$/; + my $end_time_dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6, %$tz); + + $self->{result_values}->{duration} = $end_time_dt->epoch - $start_time_dt->epoch; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'current', type => 0, cb_prefix_output => 'prefix_output_current' }, + { name => 'last', type => 0, cb_prefix_output => 'prefix_output_last' }, + ]; + + $self->{maps_counters}->{current} = [ + { label => 'synchronisation-status', threshold => 0, set => { + key_values => [ { name => 'SynchronizationStatus' } ], + 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 => \&catalog_status_threshold, + } + }, + { label => 'synchronisation-progress', set => { + key_values => [ { name => 'TotalItems' }, { name => 'ProcessedItems' } ], + closure_custom_calc => $self->can('custom_progress_calc'), + closure_custom_output => $self->can('custom_progress_output'), + closure_custom_perfdata => $self->can('custom_progress_perfdata'), + closure_custom_threshold_check => $self->can('custom_progress_threshold'), + } + }, + ]; + $self->{maps_counters}->{last} = [ + { label => 'last-synchronisation-status', threshold => 0, set => { + key_values => [ { name => 'LastSynchronizationResult' } ], + closure_custom_calc => $self->can('custom_last_status_calc'), + closure_custom_output => $self->can('custom_last_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + { label => 'last-synchronisation-duration', set => { + key_values => [ { name => 'LastSynchronizationStartTime' }, { name => 'LastSynchronizationEndTime' } ], + closure_custom_calc => $self->can('custom_duration_calc'), + closure_custom_output => $self->can('custom_duration_output'), + closure_custom_perfdata => $self->can('custom_duration_perfdata'), + closure_custom_threshold_check => $self->can('custom_duration_threshold'), + } + }, + ]; +} + +sub prefix_output_current { + my ($self, %options) = @_; + + return "Current Synchronisation "; +} + +sub prefix_output_last { + my ($self, %options) = @_; + + return "Last Synchronisation "; +} + +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 => { + "timeout:s" => { name => 'timeout', default => 30 }, + "command:s" => { name => 'command', default => 'powershell.exe' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, + "no-ps" => { name => 'no_ps' }, + "ps-exec-only" => { name => 'ps_exec_only' }, + "wsus-server:s" => { name => 'wsus_server', default => 'localhost' }, + "wsus-port:s" => { name => 'wsus_port', default => 8530 }, + "use-ssl" => { name => 'use_ssl' }, + "warning-synchronisation-status:s" => { name => 'warning_synchronisation_status', default => '' }, + "critical-synchronisation-status:s" => { name => 'critical_synchronisation_status', default => '' }, + "warning-last-synchronisation-status:s" => { name => 'warning_last_synchronisation_status', default => '' }, + "critical-last-synchronisation-status:s" => { name => 'critical_last_synchronisation_status', default => '%{status} !~ /Succeeded/' }, + "timezone:s" => { name => 'timezone', default => 'UTC' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_synchronisation_status', 'critical_synchronisation_status', + 'warning_last_synchronisation_status', 'critical_last_synchronisation_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $use_ssl = "\$false"; + $use_ssl = "\$true" if (defined($self->{option_results}->{use_ssl})); + + my $ps = centreon::common::powershell::wsus::synchronisationstatus::get_powershell( + no_ps => $self->{option_results}->{no_ps}, + wsus_server => $self->{option_results}->{wsus_server}, + wsus_port => $self->{option_results}->{wsus_port}, + use_ssl => $use_ssl + ); + + $self->{option_results}->{command_options} .= " " . $ps; + my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}); + if (defined($self->{option_results}->{ps_exec_only})) { + $self->{output}->output_add(severity => 'OK', + short_msg => $stdout); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode(centreon::plugins::misc::powershell_json_sanitizer(string => $stdout, output => $self->{output})); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + $self->{current} = { + SynchronizationStatus => $decoded->{SynchronizationStatus}, + TotalItems => $decoded->{TotalItems}, + ProcessedItems => $decoded->{ProcessedItems}, + }; + $self->{last} = { + LastSynchronizationResult => $decoded->{LastSynchronizationResult}, + LastSynchronizationStartTime => $decoded->{LastSynchronizationStartTime}, + LastSynchronizationEndTime => $decoded->{LastSynchronizationEndTime}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check synchronisation status. + +=over 8 + +=item B<--timeout> + +Set timeout time for command execution (Default: 30 sec) + +=item B<--no-ps> + +Don't encode powershell. To be used with --command and 'type' command. + +=item B<--command> + +Command to get information (Default: 'powershell.exe'). +Can be changed if you have output in a file. To be used with --no-ps option. + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: '-InputFormat none -NoLogo -EncodedCommand'). + +=item B<--ps-exec-only> + +Print powershell output. + +=item B<--wsus-server> + +Set WSUS hostname/IP (Dafault: localhost). + +=item B<--wsus-port> + +Set WSUS port (Default: 8530). + +=item B<--use-ssl> + +Set if WSUS use ssl. + +=item B<--warning-synchronisation-status> + +Set warning threshold for current synchronisation status (Default: '') +Can used special variables like: %{status}. + +=item B<--critical-synchronisation-status> + +Set critical threshold for current synchronisation status (Default: ''). +Can used special variables like: %{status}. + +=item B<--warning-last-synchronisation-status> + +Set warning threshold for current synchronisation status (Default: '') +Can used special variables like: %{status}. + +=item B<--critical-last-synchronisation-status> + +Set critical threshold for current synchronisation status (Default: '%{status} !~ /Succeeded/'). +Can used special variables like: %{status}. + +=item B<--warning-*> + +Warning thresholds. +Can be: 'progress' (%), 'duration' (s). + +=item B<--critical-*> + +Critical thresholds. +Can be: 'progress' (%), 'duration' (s). + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='status' + +=back + +=cut diff --git a/apps/wsus/local/mode/updatesstatus.pm b/apps/wsus/local/mode/updatesstatus.pm new file mode 100644 index 000000000..b765e57aa --- /dev/null +++ b/apps/wsus/local/mode/updatesstatus.pm @@ -0,0 +1,223 @@ +# +# Copyright 2019 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 apps::wsus::local::mode::updatesstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use JSON::XS; +use centreon::common::powershell::wsus::updatesstatus; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_output' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'with-client-errors', set => { + key_values => [ { name => 'UpdatesWithClientErrorsCount' } ], + output_template => 'With Client Errors: %d', + perfdatas => [ + { label => 'updates_with_client_errors', value => 'UpdatesWithClientErrorsCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + { label => 'with-server-errors', set => { + key_values => [ { name => 'UpdatesWithServerErrorsCount' } ], + output_template => 'With Server Errors: %d', + perfdatas => [ + { label => 'updates_with_server_errors', value => 'UpdatesWithServerErrorsCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + { label => 'needing-files', set => { + key_values => [ { name => 'UpdatesNeedingFilesCount' } ], + output_template => 'Needing Files: %d', + perfdatas => [ + { label => 'updates_needing_files_count', value => 'UpdatesNeedingFilesCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + { label => 'needed-by-computers', set => { + key_values => [ { name => 'UpdatesNeededByComputersCount' } ], + output_template => 'Needed By Computers: %d', + perfdatas => [ + { label => 'updates_needed_by_computers', value => 'UpdatesNeededByComputersCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + { label => 'up-to-date', set => { + key_values => [ { name => 'UpdatesUpToDateCount' } ], + output_template => 'Up-to-date: %s', + perfdatas => [ + { label => 'updates_up_to_date', value => 'UpdatesUpToDateCount_absolute', + template => '%d', min => 0 }, + ], + } + }, + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Updates "; +} + +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 => { + "timeout:s" => { name => 'timeout', default => 30 }, + "command:s" => { name => 'command', default => 'powershell.exe' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, + "no-ps" => { name => 'no_ps' }, + "ps-exec-only" => { name => 'ps_exec_only' }, + "wsus-server:s" => { name => 'wsus_server', default => 'localhost' }, + "wsus-port:s" => { name => 'wsus_port', default => 8530 }, + "use-ssl" => { name => 'use_ssl' }, + "filter-counters:s" => { name => 'filter_counters' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $use_ssl = "\$false"; + $use_ssl = "\$true" if (defined($self->{option_results}->{use_ssl})); + + my $ps = centreon::common::powershell::wsus::updatesstatus::get_powershell( + no_ps => $self->{option_results}->{no_ps}, + wsus_server => $self->{option_results}->{wsus_server}, + wsus_port => $self->{option_results}->{wsus_port}, + use_ssl => $use_ssl + ); + + $self->{option_results}->{command_options} .= " " . $ps; + my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}); + if (defined($self->{option_results}->{ps_exec_only})) { + $self->{output}->output_add(severity => 'OK', + short_msg => $stdout); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode(centreon::plugins::misc::powershell_json_sanitizer(string => $stdout, output => $self->{output})); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + $self->{global} = { %$decoded }; +} + +1; + +__END__ + +=head1 MODE + +Check updates status. + +=over 8 + +=item B<--timeout> + +Set timeout time for command execution (Default: 30 sec) + +=item B<--no-ps> + +Don't encode powershell. To be used with --command and 'type' command. + +=item B<--command> + +Command to get information (Default: 'powershell.exe'). +Can be changed if you have output in a file. To be used with --no-ps option. + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: '-InputFormat none -NoLogo -EncodedCommand'). + +=item B<--ps-exec-only> + +Print powershell output. + +=item B<--wsus-server> + +Set WSUS hostname/IP (Dafault: localhost). + +=item B<--wsus-port> + +Set WSUS port (Default: 8530). + +=item B<--use-ssl> + +Set if WSUS use ssl. + +=item B<--warning-*> + +Warning thresholds. +Can be: 'with-client-errors', 'with-server-errors', +'needing-files', 'needed-by-computers', 'up-to-date'. + +=item B<--critical-*> + +Critical thresholds. +Can be: 'with-client-errors', 'with-server-errors', +'needing-files', 'needed-by-computers', 'up-to-date'. + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='errors' + +=back + +=cut diff --git a/apps/wsus/local/plugin.pm b/apps/wsus/local/plugin.pm new file mode 100644 index 000000000..4d179f04a --- /dev/null +++ b/apps/wsus/local/plugin.pm @@ -0,0 +1,51 @@ +# +# Copyright 2019 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 apps::wsus::local::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_simple); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'computers-status' => 'apps::wsus::local::mode::computersstatus', + 'server-statistics' => 'apps::wsus::local::mode::serverstatistics', + 'synchronisation-status' => 'apps::wsus::local::mode::synchronisationstatus', + 'updates-status' => 'apps::wsus::local::mode::updatesstatus', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check WSUS through powershell. + +=cut diff --git a/centreon/common/adic/tape/snmp/mode/components/fan.pm b/centreon/common/adic/tape/snmp/mode/components/fan.pm index 1752c8a1f..f9f3c137e 100644 --- a/centreon/common/adic/tape/snmp/mode/components/fan.pm +++ b/centreon/common/adic/tape/snmp/mode/components/fan.pm @@ -105,13 +105,16 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '%s' is %s rpm", $id, $result->{coolingFanRPM})); } - $self->{output}->perfdata_add(label => 'fan_' . $id, unit => 'rpm', - value => $result->{coolingFanRPM}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $id, + value => $result->{coolingFanRPM}, + warning => $warn, + critical => $crit, + ); } } } -1; \ No newline at end of file +1; diff --git a/centreon/common/adic/tape/snmp/mode/components/temperature.pm b/centreon/common/adic/tape/snmp/mode/components/temperature.pm index 626a9c0c4..6ce02ee87 100644 --- a/centreon/common/adic/tape/snmp/mode/components/temperature.pm +++ b/centreon/common/adic/tape/snmp/mode/components/temperature.pm @@ -105,13 +105,16 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s degree centigrade", $id, $result->{temperatureSensorDegreesCelsius})); } - $self->{output}->perfdata_add(label => 'temp_' . $id, unit => 'C', - value => $result->{temperatureSensorDegreesCelsius}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $id, + value => $result->{temperatureSensorDegreesCelsius}, + warning => $warn, + critical => $crit, + ); } } } -1; \ No newline at end of file +1; diff --git a/centreon/common/airespace/snmp/mode/apchannelinterference.pm b/centreon/common/airespace/snmp/mode/apchannelinterference.pm index c77065ff2..4b76973df 100644 --- a/centreon/common/airespace/snmp/mode/apchannelinterference.pm +++ b/centreon/common/airespace/snmp/mode/apchannelinterference.pm @@ -65,11 +65,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "filter-channel:s" => { name => 'filter_channel' }, - }); + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' }, + 'filter-channel:s' => { name => 'filter_channel' }, + }); return $self; } @@ -82,11 +81,14 @@ sub manage_selection { my ($self, %options) = @_; $self->{ap} = {}; - $self->{results} = $options{snmp}->get_multiple_table(oids => [ { oid => $oid_bsnAPName }, - { oid => $oid_bsnAPIfInterferencePower }, - { oid => $oid_bsnAPIfInterferenceUtilization }, - ], - nothing_quit => 1); + $self->{results} = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oid_bsnAPName }, + { oid => $oid_bsnAPIfInterferencePower }, + { oid => $oid_bsnAPIfInterferenceUtilization }, + ], + nothing_quit => 1 + ); foreach my $oid (keys %{$self->{results}->{$oid_bsnAPName}}) { $oid =~ /^$oid_bsnAPName\.(.*)$/; my $instance_mac = $1; diff --git a/centreon/common/airespace/snmp/mode/apchannelnoise.pm b/centreon/common/airespace/snmp/mode/apchannelnoise.pm index 707205712..71fc8a0bb 100644 --- a/centreon/common/airespace/snmp/mode/apchannelnoise.pm +++ b/centreon/common/airespace/snmp/mode/apchannelnoise.pm @@ -56,11 +56,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "filter-channel:s" => { name => 'filter_channel' }, - }); + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' }, + 'filter-channel:s' => { name => 'filter_channel' }, + }); return $self; } diff --git a/centreon/common/airespace/snmp/mode/apusers.pm b/centreon/common/airespace/snmp/mode/apusers.pm index a671677cb..e1ec5044a 100644 --- a/centreon/common/airespace/snmp/mode/apusers.pm +++ b/centreon/common/airespace/snmp/mode/apusers.pm @@ -169,11 +169,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-ssid:s" => { name => 'filter_ssid' }, - "filter-ap:s" => { name => 'filter_ap' }, - }); + $options{options}->add_options(arguments => { + 'filter-ssid:s' => { name => 'filter_ssid' }, + 'filter-ap:s' => { name => 'filter_ap' }, + }); return $self; } diff --git a/centreon/common/aruba/snmp/mode/apconnections.pm b/centreon/common/aruba/snmp/mode/apconnections.pm index 0835e9f47..3544adb43 100644 --- a/centreon/common/aruba/snmp/mode/apconnections.pm +++ b/centreon/common/aruba/snmp/mode/apconnections.pm @@ -20,62 +20,69 @@ package centreon::common::aruba::snmp::mode::apconnections; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -my $maps_counters = { - ap => { - '000_total-time' => { set => { - key_values => [ { name => 'apTotalTime' }, { name => 'bssid' }, ], - output_template => 'Current total connection time : %.3f s', - perfdatas => [ - { label => 'total_time', value => 'apTotalTime_absolute', template => '%.3f', - min => 0, unit => 's', label_extra_instance => 1, instance_use => 'bssid_absolute' }, - ], - } - }, - '001_inactive-time' => { set => { - key_values => [ { name => 'apInactiveTime' }, { name => 'bssid' }, ], - output_template => 'Current inactive time : %.3f s', - perfdatas => [ - { label => 'inactive_time', value => 'apInactiveTime_absolute', template => '%.3f', - min => 0, unit => 's', label_extra_instance => 1, instance_use => 'bssid_absolute' }, - ], - } - }, - '002_channel-noise' => { set => { - key_values => [ { name => 'apChannelNoise' }, { name => 'bssid' }, ], - output_template => 'Channel noise : %d', - perfdatas => [ - { label => 'channel_noise', value => 'apChannelNoise_absolute', template => '%d', - label_extra_instance => 1, instance_use => 'bssid_absolute' }, - ], - } - }, - '003_snr' => { set => { - key_values => [ { name => 'apSignalToNoiseRatio' }, { name => 'bssid' }, ], - output_template => 'Signal to noise ratio : %d', - perfdatas => [ - { label => 'snr', value => 'apSignalToNoiseRatio_absolute', template => '%d', - label_extra_instance => 1, instance_use => 'bssid_absolute' }, - ], - } - }, +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'ap', type => 1, cb_prefix_output => 'prefix_ap_output', message_multiple => 'All access points are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total', nlabel => 'accesspoints.connected.current.count', set => { + key_values => [ { name => 'total' } ], + output_template => 'Total access points connected : %d', + perfdatas => [ + { label => 'total', value => 'total_absolute', template => '%d', min => 0 }, + ], + } }, - total => { - '000_total' => { set => { - key_values => [ { name => 'total' } ], - output_template => 'AP connected : %d', - perfdatas => [ - { label => 'total', value => 'total_absolute', template => '%d', min => 0 }, - ], - } - }, - } -}; + ]; + + $self->{maps_counters}->{ap} = [ + { label => 'total-time', nlabel => 'accesspoint.time.connection.current.seconds', set => { + key_values => [ { name => 'apTotalTime' }, { name => 'bssid' }, ], + output_template => 'Current total connection time : %.3f s', + perfdatas => [ + { label => 'total_time', value => 'apTotalTime_absolute', template => '%.3f', + min => 0, unit => 's', label_extra_instance => 1, instance_use => 'bssid_absolute' }, + ], + } + }, + { label => 'inactive-time', nlabel => 'accesspoint.time.inactive.current.seconds', set => { + key_values => [ { name => 'apInactiveTime' }, { name => 'bssid' }, ], + output_template => 'Current inactive time : %.3f s', + perfdatas => [ + { label => 'inactive_time', value => 'apInactiveTime_absolute', template => '%.3f', + min => 0, unit => 's', label_extra_instance => 1, instance_use => 'bssid_absolute' }, + ], + } + }, + { label => 'channel-noise', nlabel => 'accesspoint.channel.noise.count', sset => { + key_values => [ { name => 'apChannelNoise' }, { name => 'bssid' }, ], + output_template => 'Channel noise : %d', + perfdatas => [ + { label => 'channel_noise', value => 'apChannelNoise_absolute', template => '%d', + label_extra_instance => 1, instance_use => 'bssid_absolute' }, + ], + } + }, + { label => 'snr', nlabel => 'accesspoint.signal.noise.ratio.dbm', set => { + key_values => [ { name => 'apSignalToNoiseRatio' }, { name => 'bssid' }, ], + output_template => 'Signal to noise ratio : %d', + perfdatas => [ + { label => 'snr', value => 'apSignalToNoiseRatio_absolute', template => '%d', + label_extra_instance => 1, instance_use => 'bssid_absolute' }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; @@ -83,151 +90,21 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-ip-address:s" => { name => 'filter_ip_address' }, - "filter-bssid:s" => { name => 'filter_bssid' }, - "filter-essid:s" => { name => 'filter_essid' }, - "filter-type:s" => { name => 'filter_type', default => 'ap' }, - "skip-total" => { name => 'skip_total' }, - }); + $options{options}->add_options(arguments => { + "filter-ip-address:s" => { name => 'filter_ip_address' }, + "filter-bssid:s" => { name => 'filter_bssid' }, + "filter-essid:s" => { name => 'filter_essid' }, + "filter-type:s" => { name => 'filter_type', default => 'ap' }, + "skip-total" => { name => 'skip_total' }, + }); - foreach my $key (('ap', 'total')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - return $self; } -sub check_options { +sub prefix_ap_output { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('ap', 'total')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } -} -sub check_total { - my ($self, %options) = @_; - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{total}}) { - my $obj = $maps_counters->{total}->{$_}->{obj}; - $obj->set(instance => 'global'); - - my ($value_check) = $obj->execute(values => $self->{global}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(); - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Total $short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "Total $long_msg"); - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{ap}}) == 1) { - $multiple = 0; - } - - if (!defined($self->{option_results}->{skip_total})) { - $self->check_total(); - } - - #### - # By AP - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All AP are ok'); - } - - foreach my $id (sort keys %{$self->{ap}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{ap}}) { - my $obj = $maps_counters->{ap}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{ap}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{ap}->{$_}->{obj}->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "AP [bssid: '$self->{ap}->{$id}->{bssid}', essid: $self->{ap}->{$id}->{apESSID}, ip: $self->{ap}->{$id}->{apIpAddress}] Usage $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "AP [bssid: '$self->{ap}->{$id}->{bssid}', essid: $self->{ap}->{$id}->{apESSID}, ip: $self->{ap}->{$id}->{apIpAddress}] Usage $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "AP [bssid: '$self->{ap}->{$id}->{bssid}', [essid: $self->{ap}->{$id}->{apESSID}, ip: $self->{ap}->{$id}->{apIpAddress}] Usage $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); + return "AP [bssid: '$options{instance_value}->{bssid}', essid: $options{instance_value}->{apESSID}, ip: $options{instance_value}->{apIpAddress}] Usage "; } my %map_role = ( @@ -266,17 +143,19 @@ my $oid_wlsxSwitchTotalNumAccessPoints = '.1.3.6.1.4.1.14823.2.2.1.1.3.1'; sub manage_selection { my ($self, %options) = @_; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_wlsxSwitchTotalNumAccessPoints }, - { oid => $oid_wlsxSwitchRole }, - { oid => $mapping->{apESSID}->{oid} }, - { oid => $mapping2->{apIpAddress}->{oid} }, - { oid => $mapping3->{apType}->{oid} }, - { oid => $oid_wlsxSwitchAccessPointEntry, start => $mapping4->{apTotalTime}->{oid}, end => $mapping4->{apInactiveTime}->{oid} }, - { oid => $oid_wlsxSwitchAccessPointTable, start => $mapping5->{apChannelNoise}->{oid}, end => $mapping5->{apSignalToNoiseRatio}->{oid} }, - ], - , nothing_quit => 1); - my $role = $map_role{$self->{results}->{$oid_wlsxSwitchRole}->{$oid_wlsxSwitchRole . '.0'}}; + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oid_wlsxSwitchTotalNumAccessPoints }, + { oid => $oid_wlsxSwitchRole }, + { oid => $mapping->{apESSID}->{oid} }, + { oid => $mapping2->{apIpAddress}->{oid} }, + { oid => $mapping3->{apType}->{oid} }, + { oid => $oid_wlsxSwitchAccessPointEntry, start => $mapping4->{apTotalTime}->{oid}, end => $mapping4->{apInactiveTime}->{oid} }, + { oid => $oid_wlsxSwitchAccessPointTable, start => $mapping5->{apChannelNoise}->{oid}, end => $mapping5->{apSignalToNoiseRatio}->{oid} }, + ], + nothing_quit => 1 + ); + my $role = $map_role{$snmp_result->{$oid_wlsxSwitchRole}->{$oid_wlsxSwitchRole . '.0'}}; if ($role =~ /standbymaster/) { $self->{output}->output_add(severity => 'OK', short_msg => "Cannot get information. Switch role is '" . $role . "'."); @@ -285,33 +164,33 @@ sub manage_selection { } $self->{ap} = {}; - foreach my $oid (keys %{$self->{results}->{$mapping->{apESSID}->{oid}}}) { + foreach my $oid (keys %{$snmp_result->{$mapping->{apESSID}->{oid}}}) { next if ($oid !~ /^$mapping->{apESSID}->{oid}\.(.*)$/); my $bssid = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{apESSID}->{oid}}, instance => $bssid); - my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{apIpAddress}->{oid}}, instance => $bssid); - my $result3 = $self->{snmp}->map_instance(mapping => $mapping3, results => $self->{results}->{$mapping3->{apType}->{oid}}, instance => $bssid); - my $result4 = $self->{snmp}->map_instance(mapping => $mapping4, results => $self->{results}->{$oid_wlsxSwitchAccessPointEntry}, instance => $bssid); - my $result5 = $self->{snmp}->map_instance(mapping => $mapping5, results => $self->{results}->{$oid_wlsxSwitchAccessPointTable}, instance => $bssid); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result->{$mapping->{apESSID}->{oid}}, instance => $bssid); + my $result2 = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result->{$mapping2->{apIpAddress}->{oid}}, instance => $bssid); + my $result3 = $options{snmp}->map_instance(mapping => $mapping3, results => $snmp_result->{$mapping3->{apType}->{oid}}, instance => $bssid); + my $result4 = $options{snmp}->map_instance(mapping => $mapping4, results => $snmp_result->{$oid_wlsxSwitchAccessPointEntry}, instance => $bssid); + my $result5 = $options{snmp}->map_instance(mapping => $mapping5, results => $snmp_result->{$oid_wlsxSwitchAccessPointTable}, instance => $bssid); if (defined($self->{option_results}->{filter_bssid}) && $self->{option_results}->{filter_bssid} ne '' && $bssid !~ /$self->{option_results}->{filter_bssid}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $bssid . "': no matching filter bssid."); + $self->{output}->output_add(long_msg => "skipping '" . $bssid . "': no matching filter bssid."); next; } if (defined($self->{option_results}->{filter_ip_address}) && $self->{option_results}->{filter_ip_address} ne '' && $result2->{apIpAddress} !~ /$self->{option_results}->{filter_ip_address}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $result2->{apIpAddress} . "': no matching filter ip-address."); + $self->{output}->output_add(long_msg => "skipping '" . $result2->{apIpAddress} . "': no matching filter ip-address."); next; } if (defined($self->{option_results}->{filter_essid}) && $self->{option_results}->{filter_essid} ne '' && $result->{apESSID} !~ /$self->{option_results}->{filter_essid}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $result->{apESSID} . "': no matching filter essid."); + $self->{output}->output_add(long_msg => "skipping '" . $result->{apESSID} . "': no matching filter essid."); next; } if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && $result3->{apType} !~ /$self->{option_results}->{filter_type}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $result->{apType} . "': no matching filter type."); + $self->{output}->output_add(long_msg => "skipping '" . $result->{apType} . "': no matching filter type."); next; } @@ -320,8 +199,8 @@ sub manage_selection { $self->{ap}->{$bssid}->{apTotalTime} *= 0.01 if (defined($self->{ap}->{$bssid}->{apTotalTime})); } - if (defined($self->{results}->{$oid_wlsxSwitchTotalNumAccessPoints}->{$oid_wlsxSwitchTotalNumAccessPoints . '.0'})) { - $self->{global} = { total => $self->{results}->{$oid_wlsxSwitchTotalNumAccessPoints}->{$oid_wlsxSwitchTotalNumAccessPoints . '.0'} }; + if (!defined($self->{option_results}->{skip_total}) && defined($snmp_result->{$oid_wlsxSwitchTotalNumAccessPoints}->{$oid_wlsxSwitchTotalNumAccessPoints . '.0'})) { + $self->{global} = { total => $snmp_result->{$oid_wlsxSwitchTotalNumAccessPoints}->{$oid_wlsxSwitchTotalNumAccessPoints . '.0'} }; } } diff --git a/centreon/common/avaya/snmp/mode/cpu.pm b/centreon/common/avaya/snmp/mode/cpu.pm new file mode 100644 index 000000000..6be4b2111 --- /dev/null +++ b/centreon/common/avaya/snmp/mode/cpu.pm @@ -0,0 +1,120 @@ +# +# Copyright 2019 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 centreon::common::avaya::snmp::mode::cpu; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'cpu', type => 1, cb_prefix_output => 'prefix_cpu_output', message_multiple => 'All CPUs are ok' }, + ]; + + $self->{maps_counters}->{cpu} = [ + { label => 'usage', nlabel => 'cpu.utilization.percentage', set => { + key_values => [ { name => 'cpu' }, { name => 'display' } ], + output_template => 'usage : %s %%', + perfdatas => [ + { label => 'cpu_usage', value => 'cpu_absolute', template => '%s', + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_cpu_output { + my ($self, %options) = @_; + + return "CPU '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +my $map_cpu_monitoring = { 1 => 'disabled', 2 => 'enabled' }; + +my $mapping = { + genCpuUtilizationEnableMonitoring => { oid => '.1.3.6.1.4.1.6889.2.1.11.1.1.1.1.2', map => $map_cpu_monitoring }, + genCpuAverageUtilization => { oid => '.1.3.6.1.4.1.6889.2.1.11.1.1.1.1.5' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_genCpuUtilizationEntry = '.1.3.6.1.4.1.6889.2.1.11.1.1.1.1'; + my $results = $options{snmp}->get_table(oid => $oid_genCpuUtilizationEntry, nothing_quit => 1); + $self->{cpu} = {}; + foreach my $oid (keys %{$results}) { + next if ($oid !~ /^$mapping->{genCpuAverageUtilization}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance); + + if ($result->{genCpuUtilizationEnableMonitoring} eq 'disabled') { + next; + } + + $self->{cpu}->{$instance} = { + display => $instance, + cpu => $result->{genCpuAverageUtilization}, + }; + } + + if (scalar(keys %{$self->{cpu}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No entry found (or cpu monitoring is disabled)."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check CPU usage. + +=over 8 + +=item B<--warning-usage> + +Threshold warning. + +=item B<--critical-usage> + +Threshold critical. + +=back + +=cut diff --git a/centreon/common/avaya/snmp/mode/memory.pm b/centreon/common/avaya/snmp/mode/memory.pm new file mode 100644 index 000000000..acf7cd249 --- /dev/null +++ b/centreon/common/avaya/snmp/mode/memory.pm @@ -0,0 +1,166 @@ +# +# Copyright 2019 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 centreon::common::avaya::snmp::mode::memory; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + nlabel => $self->{nlabel}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + + my $msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 1, cb_prefix_output => 'prefix_memory_output', message_multiple => 'All memory usages are ok' } + ]; + + $self->{maps_counters}->{memory} = [ + { label => 'usage', nlabel => 'memory.usage.bytes', set => { + key_values => [ { name => 'display' }, { name => 'total' }, { name => 'used' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +sub prefix_memory_output { + my ($self, %options) = @_; + + if ($self->{multiple} == 1) { + return "Memory '" . $options{instance_value}->{display} . "' "; + } + return ''; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +my $mapping = { + genMemUtilizationPhyRam => { oid => '.1.3.6.1.4.1.6889.2.1.11.1.2.6.1.2' }, # in Bytes + genMemUtilizationPercentUsed => { oid => '.1.3.6.1.4.1.6889.2.1.11.1.2.6.1.3' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_genMemUtilizationEntry = '.1.3.6.1.4.1.6889.2.1.11.1.2.6.1'; + my $results = $options{snmp}->get_table(oid => $oid_genMemUtilizationEntry, nothing_quit => 1); + $self->{memory} = {}; + foreach my $oid (keys %{$results}) { + next if ($oid !~ /^$mapping->{genMemUtilizationPercentUsed}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance); + + my $total = $result->{genMemUtilizationPhyRam}; + my $used = sprintf('%d', $total * $result->{genMemUtilizationPercentUsed} / 100); + $self->{memory}->{$instance} = { + display => $instance, + used => $used, + total => $total + }; + } + + if (scalar(keys %{$self->{memory}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No entry found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check memory usages. + +=over 8 + +=item B<--warning-usage> + +Threshold warning (in percent). + +=item B<--critical-usage> + +Threshold critical (in percent). + +=back + +=cut diff --git a/centreon/common/bluearc/snmp/mode/components/fan.pm b/centreon/common/bluearc/snmp/mode/components/fan.pm index eff337ab0..8a5e0c083 100644 --- a/centreon/common/bluearc/snmp/mode/components/fan.pm +++ b/centreon/common/bluearc/snmp/mode/components/fan.pm @@ -75,13 +75,17 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Fan '%s' is %s rpm", $instance, $result->{fanSpeedStatus})); } - $self->{output}->perfdata_add(label => 'fan_' . $instance, unit => 'rpm', - value => $result->{fanSpeedStatus}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $instance, + value => $result->{fanSpeedStatus}, + warning => $warn, + critical => $crit, + min => 0, + ); } } } -1; \ No newline at end of file +1; diff --git a/centreon/common/bluearc/snmp/mode/components/temperature.pm b/centreon/common/bluearc/snmp/mode/components/temperature.pm index 2d0041987..4b5e75f53 100644 --- a/centreon/common/bluearc/snmp/mode/components/temperature.pm +++ b/centreon/common/bluearc/snmp/mode/components/temperature.pm @@ -74,13 +74,16 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Temperature '%s' is %s degree centigrade", $instance, $result->{temperatureSensorCReading})); } - $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', - value => $result->{temperatureSensorCReading}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $instance, + value => $result->{temperatureSensorCReading}, + warning => $warn, + critical => $crit, + ); } } } -1; \ No newline at end of file +1; diff --git a/centreon/common/bluearc/snmp/mode/volumeusage.pm b/centreon/common/bluearc/snmp/mode/volumeusage.pm index 252c6a29d..d0c7553e9 100644 --- a/centreon/common/bluearc/snmp/mode/volumeusage.pm +++ b/centreon/common/bluearc/snmp/mode/volumeusage.pm @@ -50,19 +50,21 @@ sub custom_usage_perfdata { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -75,7 +77,7 @@ sub custom_usage_threshold { $threshold_value = $self->{result_values}->{prct_used}; $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -138,14 +140,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /needsChecking/i' }, - "critical-status:s" => { name => 'critical_status', default => '' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /needsChecking/i' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); return $self; } diff --git a/centreon/common/broadcom/fastpath/snmp/mode/components/fan.pm b/centreon/common/broadcom/fastpath/snmp/mode/components/fan.pm index b3fad067b..f770bdec9 100644 --- a/centreon/common/broadcom/fastpath/snmp/mode/components/fan.pm +++ b/centreon/common/broadcom/fastpath/snmp/mode/components/fan.pm @@ -75,11 +75,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '%s' is '%s' rpm", $instance, $result->{boxServicesFanSpeed})); } - $self->{output}->perfdata_add(label => 'fan_' . $instance, unit => 'rpm', - value => $result->{boxServicesFanSpeed}, - warning => $warn, - critical => $crit, min => 0 - ); + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $instance, + value => $result->{boxServicesFanSpeed}, + warning => $warn, + critical => $crit, min => 0 + ); } } diff --git a/centreon/common/broadcom/fastpath/snmp/mode/components/temperature.pm b/centreon/common/broadcom/fastpath/snmp/mode/components/temperature.pm index 48f65fa36..7e847aac9 100644 --- a/centreon/common/broadcom/fastpath/snmp/mode/components/temperature.pm +++ b/centreon/common/broadcom/fastpath/snmp/mode/components/temperature.pm @@ -75,11 +75,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is '%s' rpm", $instance, $result->{boxServicesTempSensorTemperature})); } - $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', - value => $result->{boxServicesTempSensorTemperature}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $instance, + value => $result->{boxServicesTempSensorTemperature}, + warning => $warn, + critical => $crit, + ); } } diff --git a/centreon/common/broadcom/megaraid/snmp/mode/components/temperature.pm b/centreon/common/broadcom/megaraid/snmp/mode/components/temperature.pm index 9939e4fb6..db2696b48 100644 --- a/centreon/common/broadcom/megaraid/snmp/mode/components/temperature.pm +++ b/centreon/common/broadcom/megaraid/snmp/mode/components/temperature.pm @@ -78,11 +78,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is '%s' C", $instance, $result->{enclosureTemperature})); } - $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', - value => $result->{enclosureTemperature}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $instance, + value => $result->{enclosureTemperature}, + warning => $warn, + critical => $crit, + ); } } diff --git a/network/cisco/ironport/snmp/mode/components/fan.pm b/centreon/common/cisco/ironport/snmp/mode/components/fan.pm similarity index 86% rename from network/cisco/ironport/snmp/mode/components/fan.pm rename to centreon/common/cisco/ironport/snmp/mode/components/fan.pm index a2c003cde..8747cf777 100644 --- a/network/cisco/ironport/snmp/mode/components/fan.pm +++ b/centreon/common/cisco/ironport/snmp/mode/components/fan.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::cisco::ironport::snmp::mode::components::fan; +package centreon::common::cisco::ironport::snmp::mode::components::fan; use strict; use warnings; @@ -58,12 +58,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '%s' is '%s' rpm", $result->{fanName}, $result->{fanRPMs})); } - $self->{output}->perfdata_add(label => 'fan_' . $result->{fanName}, unit => 'rpm', - value => $result->{fanRPMs}, - warning => $warn, - critical => $crit, min => 0 - ); + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $result->{fanName}, + value => $result->{fanRPMs}, + warning => $warn, + critical => $crit, min => 0 + ); } } -1; \ No newline at end of file +1; diff --git a/network/cisco/ironport/snmp/mode/components/psu.pm b/centreon/common/cisco/ironport/snmp/mode/components/psu.pm similarity index 97% rename from network/cisco/ironport/snmp/mode/components/psu.pm rename to centreon/common/cisco/ironport/snmp/mode/components/psu.pm index 53be1bf3d..a0dca2bab 100644 --- a/network/cisco/ironport/snmp/mode/components/psu.pm +++ b/centreon/common/cisco/ironport/snmp/mode/components/psu.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::cisco::ironport::snmp::mode::components::psu; +package centreon::common::cisco::ironport::snmp::mode::components::psu; use strict; use warnings; @@ -71,4 +71,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/network/cisco/ironport/snmp/mode/components/raid.pm b/centreon/common/cisco/ironport/snmp/mode/components/raid.pm similarity index 97% rename from network/cisco/ironport/snmp/mode/components/raid.pm rename to centreon/common/cisco/ironport/snmp/mode/components/raid.pm index 663ea7185..afe854d1e 100644 --- a/network/cisco/ironport/snmp/mode/components/raid.pm +++ b/centreon/common/cisco/ironport/snmp/mode/components/raid.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::cisco::ironport::snmp::mode::components::raid; +package centreon::common::cisco::ironport::snmp::mode::components::raid; use strict; use warnings; @@ -66,4 +66,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/network/cisco/ironport/snmp/mode/components/temperature.pm b/centreon/common/cisco/ironport/snmp/mode/components/temperature.pm similarity index 87% rename from network/cisco/ironport/snmp/mode/components/temperature.pm rename to centreon/common/cisco/ironport/snmp/mode/components/temperature.pm index 3acf950e9..03bfbf046 100644 --- a/network/cisco/ironport/snmp/mode/components/temperature.pm +++ b/centreon/common/cisco/ironport/snmp/mode/components/temperature.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::cisco::ironport::snmp::mode::components::temperature; +package centreon::common::cisco::ironport::snmp::mode::components::temperature; use strict; use warnings; @@ -72,12 +72,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s degree centigrade", $result->{temperatureName}, $result->{degreesCelsius})); } - $self->{output}->perfdata_add(label => 'temp_' . $result->{temperatureName}, unit => 'C', - value => $result->{degreesCelsius}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $result->{temperatureName}, + value => $result->{degreesCelsius}, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1; diff --git a/network/cisco/ironport/snmp/mode/cpu.pm b/centreon/common/cisco/ironport/snmp/mode/cpu.pm similarity index 94% rename from network/cisco/ironport/snmp/mode/cpu.pm rename to centreon/common/cisco/ironport/snmp/mode/cpu.pm index 942ccf26c..fc630974e 100644 --- a/network/cisco/ironport/snmp/mode/cpu.pm +++ b/centreon/common/cisco/ironport/snmp/mode/cpu.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::cisco::ironport::snmp::mode::cpu; +package centreon::common::cisco::ironport::snmp::mode::cpu; use base qw(centreon::plugins::templates::counter); @@ -59,9 +59,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } diff --git a/network/cisco/ironport/snmp/mode/hardware.pm b/centreon/common/cisco/ironport/snmp/mode/hardware.pm similarity index 92% rename from network/cisco/ironport/snmp/mode/hardware.pm rename to centreon/common/cisco/ironport/snmp/mode/hardware.pm index 8a1935ca0..e9e853260 100644 --- a/network/cisco/ironport/snmp/mode/hardware.pm +++ b/centreon/common/cisco/ironport/snmp/mode/hardware.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::cisco::ironport::snmp::mode::hardware; +package centreon::common::cisco::ironport::snmp::mode::hardware; use base qw(centreon::plugins::templates::hardware); @@ -47,7 +47,7 @@ sub set_system { ], }; - $self->{components_path} = 'network::cisco::ironport::snmp::mode::components'; + $self->{components_path} = 'centreon::common::cisco::ironport::snmp::mode::components'; $self->{components_module} = ['fan', 'temperature', 'psu', 'raid']; } @@ -64,9 +64,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } @@ -119,4 +118,4 @@ Example: --critical='fan,.*,6000' =back -=cut \ No newline at end of file +=cut diff --git a/network/cisco/ironport/snmp/mode/keysexpire.pm b/centreon/common/cisco/ironport/snmp/mode/keysexpire.pm similarity index 94% rename from network/cisco/ironport/snmp/mode/keysexpire.pm rename to centreon/common/cisco/ironport/snmp/mode/keysexpire.pm index 3a27821c6..8c774331c 100644 --- a/network/cisco/ironport/snmp/mode/keysexpire.pm +++ b/centreon/common/cisco/ironport/snmp/mode/keysexpire.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::cisco::ironport::snmp::mode::keysexpire; +package centreon::common::cisco::ironport::snmp::mode::keysexpire; use base qw(centreon::plugins::templates::counter); @@ -55,9 +55,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } diff --git a/network/cisco/ironport/snmp/mode/memory.pm b/centreon/common/cisco/ironport/snmp/mode/memory.pm similarity index 89% rename from network/cisco/ironport/snmp/mode/memory.pm rename to centreon/common/cisco/ironport/snmp/mode/memory.pm index 4c1987ca4..62448af7a 100644 --- a/network/cisco/ironport/snmp/mode/memory.pm +++ b/centreon/common/cisco/ironport/snmp/mode/memory.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::cisco::ironport::snmp::mode::memory; +package centreon::common::cisco::ironport::snmp::mode::memory; use base qw(centreon::plugins::mode); @@ -31,11 +31,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - }); + $options{options}->add_options(arguments => { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); return $self; } diff --git a/centreon/common/cisco/ironport/snmp/mode/proxyusage.pm b/centreon/common/cisco/ironport/snmp/mode/proxyusage.pm new file mode 100644 index 000000000..4ed2080b9 --- /dev/null +++ b/centreon/common/cisco/ironport/snmp/mode/proxyusage.pm @@ -0,0 +1,239 @@ +# +# Copyright 2019 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 centreon::common::cisco::ironport::snmp::mode::proxyusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub custom_data_calc { + my ($self, %options) = @_; + + my $delta_value = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{hit_ref}} - $options{old_datas}->{$self->{instance} . '_' . $options{extra_options}->{hit_ref}}; + my $delta_total = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{total_ref}} - $options{old_datas}->{$self->{instance} . '_' . $options{extra_options}->{total_ref}}; + + $self->{result_values}->{hits_prct} = 100; + if ($delta_total > 0) { + $self->{result_values}->{hits_prct} = $delta_value * 100 / $delta_total; + } + return 0; +} + + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'global_http', type => 0, cb_prefix_output => 'prefix_http_output', skipped_code => { -10 => 1 } }, + { name => 'global_icp', type => 0, cb_prefix_output => 'prefix_icp_output', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global_http} = [ + { label => 'client-http-hits-rate', nlabel => 'client.http.hits.percentage', set => { + key_values => [ { name => 'cacheClientRequests', diff => 1 }, { name => 'cacheClientHits', diff => 1 } ], + closure_custom_calc => $self->can('custom_data_calc'), + closure_custom_calc_extra_options => { hit_ref => 'cacheClientHits', total_ref => 'cacheClientRequests' }, + output_template => 'client hits rate : %.2f %%', output_use => 'hits_prct', threshold_use => 'hits_prct', + perfdatas => [ + { label => 'client_http_hits_rate', value => 'hits_prct', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'client-http-errors', display_ok => 0, nlabel => 'client.http.errors.count', set => { + key_values => [ { name => 'cacheClientErrors', diff => 1 } ], + output_template => 'client errors : %s', + perfdatas => [ + { label => 'client_http_errors', value => 'cacheClientErrors_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'client-http-traffic-in', display_ok => 0, nlabel => 'client.http.traffic.in.bitspersecond', set => { + key_values => [ { name => 'cacheClientInKb', diff => 1 } ], + output_template => 'client traffic in : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'client_http_traffic_in', value => 'cacheClientInKb_per_second', template => '%s', + min => 0, unit => 'b/s' }, + ], + } + }, + { label => 'client-http-traffic-out', display_ok => 0, nlabel => 'client.http.traffic.out.bitspersecond', set => { + key_values => [ { name => 'cacheClientOutKb', diff => 1 } ], + output_template => 'client traffic Out : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'client_http_traffic_out', value => 'cacheClientOutKb_per_second', template => '%s', + min => 0, unit => 'b/s' }, + ], + } + }, + { label => 'total-con-clients', nlabel => 'client.http.total.connections.count', set => { + key_values => [ { name => 'cacheClientTotalConns' } ], + output_template => 'total number of clients : %s', + perfdatas => [ + { label => 'total_con_clients', value => 'cacheClientTotalConns_absolute', template => '%s', + min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{global_icp} = [ + { label => 'client-icp-hits-rate', nlabel => 'client.icp.hits.percentage', set => { + key_values => [ { name => 'cacheClientICPRequests', diff => 1 }, { name => 'cacheClientICPHits', diff => 1 } ], + closure_custom_calc_extra_options => { hit_ref => 'cacheClientICPHits', total_ref => 'cacheClientICPRequests' }, + closure_custom_calc => $self->can('custom_data_calc'), + output_template => 'client hits rate : %.2f %%', output_use => 'hits_prct', threshold_use => 'hits_prct', + perfdatas => [ + { label => 'client_icp_hits_rate', value => 'hits_prct', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'http-mean-time', nlabel => 'http.response.mean.time.milliseconds', set => { + key_values => [ { name => 'cacheMeanRespTime' } ], + output_template => 'http mean response time : %s ms', + perfdatas => [ + { label => 'http_mean_time', value => 'cacheMeanRespTime_absolute', template => '%s', + min => 0, unit => 'ms' }, + ], + } + }, + { label => 'server-traffic-in', display_ok => 0, nlabel => 'server.traffic.in.bitspersecond', set => { + key_values => [ { name => 'cacheServerInKb', diff => 1 } ], + output_template => 'server traffic in : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'server_traffic_in', value => 'cacheServerInKb_per_second', template => '%s', + min => 0, unit => 'b/s' }, + ], + } + }, + { label => 'server-traffic-out', display_ok => 0, nlabel => 'server.traffic.out.bitspersecond', set => { + key_values => [ { name => 'cacheServerOutKb', diff => 1 } ], + output_template => 'server traffic Out : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'server_traffic_out', value => 'cacheServerOutKb_per_second', template => '%s', + min => 0, unit => 'b/s' }, + ], + } + }, + ]; +} + +sub prefix_http_output { + my ($self, %options) = @_; + + return "http "; +} + +sub prefix_icp_output { + my ($self, %options) = @_; + + return "icp "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my %oids = ( + cacheClientRequests => '.1.3.6.1.4.1.15497.1.2.3.2.2.0', + cacheClientHits => '.1.3.6.1.4.1.15497.1.2.3.2.3.0', + cacheClientErrors => '.1.3.6.1.4.1.15497.1.2.3.2.4.0', + cacheClientInKb => '.1.3.6.1.4.1.15497.1.2.3.2.5.0', + cacheClientOutKb => '.1.3.6.1.4.1.15497.1.2.3.2.6.0', + cacheClientICPRequests => '.1.3.6.1.4.1.15497.1.2.3.2.11.0', + cacheClientICPHits => '.1.3.6.1.4.1.15497.1.2.3.2.12.0', + cacheServerInKb => '.1.3.6.1.4.1.15497.1.2.3.3.5.0', + cacheServerOutKb => '.1.3.6.1.4.1.15497.1.2.3.3.6.0', + cacheClientTotalConns => '.1.3.6.1.4.1.15497.1.2.3.2.8.0', + cacheMeanRespTime => '.1.3.6.1.4.1.15497.1.2.3.6.2.0', + ); + my $snmp_result = $options{snmp}->get_leef(oids => [ + values %oids + ], nothing_quit => 1); + + $self->{global_http} = { + cacheClientRequests => $snmp_result->{$oids{cacheClientRequests}}, + cacheClientHits => $snmp_result->{$oids{cacheClientHits}}, + cacheClientErrors => $snmp_result->{$oids{cacheClientErrors}}, + cacheClientInKb => $snmp_result->{$oids{cacheClientInKb}} * 1024 * 8, + cacheClientOutKb => $snmp_result->{$oids{cacheClientOutKb}} * 1024 * 8, + cacheClientTotalConns => $snmp_result->{$oids{cacheClientTotalConns}}, + }; + $self->{global_icp} = { + cacheClientICPRequests => $snmp_result->{$oids{cacheClientICPRequests}}, + cacheClientICPHits => $snmp_result->{$oids{cacheClientICPHits}}, + }; + $self->{global} = { + cacheMeanRespTime => $snmp_result->{$oids{cacheMeanRespTime}}, + cacheServerInKb => $snmp_result->{$oids{cacheServerInKb}} * 1024 * 8, + cacheServerOutKb => $snmp_result->{$oids{cacheServerOutKb}} * 1024 * 8, + }; + + $self->{cache_name} = "cisco_ironport_" . $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')); +} + +1; + +__END__ + +=head1 MODE + +Check proxy usage (websecurity appliance). + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='http' + +=item B<--warning-*> B<--critical-*> + +Threshold warning. +Can be: 'client-http-hits-rate', 'client-http-errors', 'client-http-traffic-in', +'client-http-traffic-out', 'total-con-clients', 'client-icp-hits-rate', +'server-traffic-in', 'server-traffic-out', 'http-mean-time'. + +=back + +=cut diff --git a/centreon/common/cisco/ironport/xmlapi/mode/systemusage.pm b/centreon/common/cisco/ironport/xmlapi/mode/systemusage.pm new file mode 100644 index 000000000..1a3b8f825 --- /dev/null +++ b/centreon/common/cisco/ironport/xmlapi/mode/systemusage.pm @@ -0,0 +1,328 @@ +# +# Copyright 2019 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 centreon::common::cisco::ironport::xmlapi::mode::systemusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use centreon::plugins::http; +use XML::Simple; +use Digest::MD5 qw(md5_hex); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'system status: ' . $self->{result_values}->{system_status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{system_status} = $options{new_datas}->{$self->{instance} . '_system_status'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'system-status', threshold => 0, set => { + key_values => [ { name => 'system_status' } ], + 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 => \&catalog_status_threshold + } + }, + { label => 'memory', nlabel => 'system.memory.usage.percentage', set => { + key_values => [ { name => 'ram_utilization' } ], + output_template => 'memory usage: %.2f %%', + perfdatas => [ + { value => 'ram_utilization_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + { label => 'cpu-total', nlabel => 'system.cpu.total.utilization.percentage', set => { + key_values => [ { name => 'total_utilization' } ], + output_template => 'total cpu usage: %.2f %%', + perfdatas => [ + { value => 'total_utilization_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + { label => 'diskio', nlabel => 'system.disk.io.usage.percentage', set => { + key_values => [ { name => 'disk_utilization' } ], + output_template => 'disk i/o usage: %.2f %%', + perfdatas => [ + { value => 'disk_utilization_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + { label => 'log', nlabel => 'system.logging.disk.usage.percentage', set => { + key_values => [ { name => 'log_used' } ], + output_template => 'logging disk usage: %.2f %%', + perfdatas => [ + { value => 'log_used_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + { label => 'resource-conservation', nlabel => 'system.resource.conservation.current.count', set => { + key_values => [ { name => 'resource_conservation' } ], + output_template => 'resource conservation mode: %s', + perfdatas => [ + { value => 'resource_conservation_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'connections-in', nlabel => 'system.connections.inbound.current.count', set => { + key_values => [ { name => 'conn_in' } ], + output_template => 'current inbound connections: %s', + perfdatas => [ + { value => 'conn_in_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'connections-out', nlabel => 'system.connections.outbound.current.count', set => { + key_values => [ { name => 'conn_out' } ], + output_template => 'current outbound connections: %s', + perfdatas => [ + { value => 'conn_out_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'queue-active-recipients', nlabel => 'system.queue.recipients.active.current.count', set => { + key_values => [ { name => 'active_recips' } ], + output_template => 'queue active recipients: %s', + perfdatas => [ + { value => 'active_recips_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'messages-quarantine', nlabel => 'system.queue.messages.quarantine.current.count', set => { + key_values => [ { name => 'msgs_in_quarantine' } ], + output_template => 'messages in quarantine: %s', + perfdatas => [ + { value => 'msgs_in_quarantine_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'messages-workqueue', nlabel => 'system.queue.messages.workqueue.current.count', set => { + key_values => [ { name => 'msgs_in_work_queue' } ], + output_template => 'messages in work queue: %s', + perfdatas => [ + { value => 'msgs_in_work_queue_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'messages-received', nlabel => 'system.queue.messages.received.persecond', set => { + key_values => [ { name => 'msgs_received_lifetime', diff => 1 } ], + per_second => 1, + output_template => 'messages received: %.2f/s', + perfdatas => [ + { value => 'msgs_received_lifetime_per_second', template => '%.2f', + unit => '/s', min => 0 }, + ], + } + }, + { label => 'queuedisk', nlabel => 'system.queue.disk.usage.percentage', set => { + key_values => [ { name => 'queuedisk' } ], + output_template => 'queue disk usage: %.2f %%', + perfdatas => [ + { value => 'queuedisk_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + 'hostname:s' => { name => 'hostname' }, + 'port:s' => { name => 'port', }, + 'proto:s' => { name => 'proto', default => 'https' }, + 'urlpath:s' => { name => 'url_path', default => "/xml/status" }, + 'username:s' => { name => 'username' }, + 'password:s' => { name => 'password' }, + 'timeout:s' => { name => 'timeout' }, + 'unknown-http-status:s' => { name => 'unknown_http_status' }, + 'warning-http-status:s' => { name => 'warning_http_status' }, + 'critical-http-status:s' => { name => 'critical_http__status' }, + 'warning-system-status:s' => { name => 'warning_system_status', default => '' }, + 'critical-system-status:s' => { name => 'critical_system_status', default => '%{system_status} !~ /online/i' }, + }); + + $self->{http} = centreon::plugins::http->new(%options); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{hostname}) || $self->{option_results}->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{username}) || $self->{option_results}->{username} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify username option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{password}) || $self->{option_results}->{password} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify password option."); + $self->{output}->option_exit(); + } + + if (!defined($self->{option_results}->{curl_opt})) { + $self->{option_results}->{curl_opt} = ['CURLOPT_SSL_VERIFYPEER => 0']; + } + if (!defined($self->{option_results}->{ssl_opt})) { + $self->{option_results}->{ssl_opt} = ['SSL_verify_mode => SSL_VERIFY_NONE']; + } + + $self->{option_results}->{credentials} = 1; + $self->{http}->set_options(%{$self->{option_results}}); + $self->change_macros(macros => ['warning_system_status', 'critical_system_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + my ($content) = $self->{http}->request( + unknown_status => $self->{option_results}->{unknown_http_status}, + warning_status => $self->{option_results}->{warning_http_status}, + critical_status => $self->{option_results}->{critical_http_status}, + ); + + my $xml_result; + eval { + $xml_result = XMLin($content, + ForceArray => [], + KeyAttr => [], + SuppressEmpty => '' + ); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode xml response: $@"); + $self->{output}->option_exit(); + } + + $self->{global} = { + system_status => $xml_result->{system}->{status}, + }; + foreach (@{$xml_result->{gauges}->{gauge}}) { + $self->{global}->{$_->{name}} = $_->{current}; + } + foreach (@{$xml_result->{counnters}->{counter}}) { + $self->{global}->{$_->{name} . '_lifetime'} = $_->{lifetime}; + } + + $self->{global}->{queuedisk} = $self->{global}->{kbytes_used} * 100 / ($self->{global}->{kbytes_used} + $self->{global}->{kbytes_free}); + $self->{cache_name} = "cisco_ironport_" . $self->{option_results}->{hostname} . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check system usage. + +=over 8 + +=item B<--hostname> + +IP Address or FQDN of the webserver host + +=item B<--port> + +Port used. + +=item B<--proto> + +Protocol used http or https (Default: https) + +=item B<--urlpath> + +Set path to get server-status page in auto mode (Default: '/xml/status') + +=item B<--username> + +Specify username for authentication + +=item B<--password> + +Specify password for authentication + +=item B<--timeout> + +Threshold for HTTP timeout + +=item B<--unknown-http-status> + +Threshold unknown for http response code (Default: '%{http_code} < 200 or %{http_code} >= 300') + +=item B<--warning-http-status> + +Threshold warning for http response code + +=item B<--critical-http-status> + +Threshold critical for http response code + +=item B<--warning-system-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{system_status} + +=item B<--critical-system-status> + +Set critical threshold for status (Default: '%{system_status} !~ /online/i'). +Can used special variables like: %{system_status} + +=item B<--warning-*> B<--critical-*> + +Warning threshold. +Can be: 'memory' (%), 'cpu-total' (%), 'diskio' (%), 'log' (%), 'resource-conservation', +'connections-in', 'connections-out', 'queue-active-recipients', 'messages-quarantine', +'messages-workqueue', 'queuedisk' (%), 'messages-received'. + +=back + +=cut diff --git a/centreon/common/cisco/standard/snmp/mode/components/sensor.pm b/centreon/common/cisco/standard/snmp/mode/components/sensor.pm index 7a4e7653e..8f76eb493 100644 --- a/centreon/common/cisco/standard/snmp/mode/components/sensor.pm +++ b/centreon/common/cisco/standard/snmp/mode/components/sensor.pm @@ -115,7 +115,8 @@ my $oid_entPhysicalDescr = '.1.3.6.1.2.1.47.1.1.1.1.2'; sub load { my ($self) = @_; - push @{$self->{request}}, { oid => $oid_entSensorValueEntry }, { oid => $oid_entSensorThresholdEntry }; + push @{$self->{request}}, { oid => $oid_entSensorValueEntry, end => $mapping->{entSensorStatus}->{oid} }, + { oid => $oid_entSensorThresholdEntry, end => $mapping2->{entSensorThresholdValue}->{oid} }; } sub get_default_warning_threshold { @@ -127,7 +128,7 @@ sub get_default_warning_threshold { my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$oid_entSensorThresholdEntry}, instance => $options{instance} . '.' . $instance); next if ($result->{entSensorThresholdSeverity} ne 'minor'); - + my $value = $result->{entSensorThresholdValue} * (10 ** ($options{result}->{entSensorScale}) * (10 ** -($options{result}->{entSensorPrecision}))); if ($result->{entSensorThresholdRelation} eq 'greaterOrEqual') { $high_th = $value - (1 * (10 ** ($options{result}->{entSensorScale}) * (10 ** -($options{result}->{entSensorPrecision})))); @@ -140,10 +141,14 @@ sub get_default_warning_threshold { } } + # when it's the same value. Means no threshold. + if (defined($low_th) && defined($high_th) && $high_th <= $low_th) { + return ''; + } my $th = ''; $th = centreon::plugins::misc::expand_exponential(value => $low_th) . ':' if (defined($low_th)); $th .= centreon::plugins::misc::expand_exponential(value => $high_th) if (defined($high_th)); - + return $th; } @@ -168,7 +173,11 @@ sub get_default_critical_threshold { $low_th = $value; } } - + + # when it's the same value. Means no threshold. + if (defined($low_th) && defined($high_th) && $high_th <= $low_th) { + return ''; + } my $th = ''; $th = centreon::plugins::misc::expand_exponential(value => $low_th) . ':' if (defined($low_th)); $th .= centreon::plugins::misc::expand_exponential(value => $high_th) if (defined($high_th)); @@ -220,17 +229,25 @@ sub check { $self->{perfdata}->threshold_validate(label => 'critical-' . $component . '-instance-' . $instance, value => $crit_th); $warn = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $component . '-instance-' . $instance); $crit = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $component . '-instance-' . $instance); - $exit2 = $self->{perfdata}->threshold_check(value => $result->{entSensorValue}, threshold => [ { label => 'critical-' . $component . '-instance-' . $instance, exit_litteral => 'critical' }, - { label => 'warning-' . $component . '-instance-' . $instance, exit_litteral => 'warning' } ]); + $exit2 = $self->{perfdata}->threshold_check( + value => $result->{entSensorValue}, + threshold => [ { label => 'critical-' . $component . '-instance-' . $instance, exit_litteral => 'critical' }, + { label => 'warning-' . $component . '-instance-' . $instance, exit_litteral => 'warning' } + ] + ); } if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Sensor '%s/%s' is %s %s", $sensor_descr, $instance, $result->{entSensorValue}, $perfdata_unit{$result->{entSensorType}})); } - $self->{output}->perfdata_add(label => $component . '_' . $sensor_descr, unit => $perfdata_unit{$result->{entSensorType}}, - value => $result->{entSensorValue}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => $component, unit => $perfdata_unit{$result->{entSensorType}}, + nlabel => 'hardware.' . $component, + instances => $sensor_descr, + value => $result->{entSensorValue}, + warning => $warn, + critical => $crit + ); } } diff --git a/centreon/common/cisco/standard/snmp/mode/components/temperature.pm b/centreon/common/cisco/standard/snmp/mode/components/temperature.pm index 97ca2dd55..d11131280 100644 --- a/centreon/common/cisco/standard/snmp/mode/components/temperature.pm +++ b/centreon/common/cisco/standard/snmp/mode/components/temperature.pm @@ -87,11 +87,15 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Temperature '%s' is %s degree centigrade", $result->{ciscoEnvMonTemperatureStatusDescr}, $result->{ciscoEnvMonTemperatureStatusValue})); } - $self->{output}->perfdata_add(label => "temp_" . $result->{ciscoEnvMonTemperatureStatusDescr}, unit => 'C', - value => $result->{ciscoEnvMonTemperatureStatusValue}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "temp", unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $result->{ciscoEnvMonTemperatureStatusDescr}, + value => $result->{ciscoEnvMonTemperatureStatusValue}, + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/centreon/common/cisco/standard/snmp/mode/components/voltage.pm b/centreon/common/cisco/standard/snmp/mode/components/voltage.pm index b782b4615..16d3fa907 100644 --- a/centreon/common/cisco/standard/snmp/mode/components/voltage.pm +++ b/centreon/common/cisco/standard/snmp/mode/components/voltage.pm @@ -88,11 +88,15 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Voltage '%s' is %.3f V", $result->{ciscoEnvMonVoltageStatusDescr}, $result->{ciscoEnvMonVoltageStatusValue})); } - $self->{output}->perfdata_add(label => "voltage_" . $result->{ciscoEnvMonVoltageStatusDescr}, unit => 'V', - value => sprintf("%.3f", $result->{ciscoEnvMonVoltageStatusValue}), - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "voltage", unit => 'V', + nlabel => 'hardware.voltage.volt', + instances => $result->{ciscoEnvMonVoltageStatusDescr}, + value => sprintf("%.3f", $result->{ciscoEnvMonVoltageStatusValue}), + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/centreon/common/cisco/standard/snmp/mode/cpu.pm b/centreon/common/cisco/standard/snmp/mode/cpu.pm index 676481cae..0ac880512 100644 --- a/centreon/common/cisco/standard/snmp/mode/cpu.pm +++ b/centreon/common/cisco/standard/snmp/mode/cpu.pm @@ -20,147 +20,174 @@ package centreon::common::cisco::standard::snmp::mode::cpu; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'cpu_avg', type => 0, cb_prefix_output => 'prefix_cpu_avg_output', message_separator => ' ', skipped_code => { -10 => 1 } }, + { name => 'cpu_core', type => 1, cb_prefix_output => 'prefix_cpu_core_output', message_separator => ' ', message_multiple => 'All core cpu are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{cpu_avg} = [ + { label => 'average-5s', nlabel => 'cpu.utilization.5s.percentage', set => { + key_values => [ { name => 'average_5s' } ], + output_template => '%.2f %% (5s)', + perfdatas => [ + { label => 'total_cpu_5s_avg', value => 'average_5s_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'average-1m', nlabel => 'cpu.utilization.1m.percentage', set => { + key_values => [ { name => 'average_1m' } ], + output_template => '%.2f %% (1m)', + perfdatas => [ + { label => 'total_cpu_1m_avg', value => 'average_1m_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'average-5m', nlabel => 'cpu.utilization.5m.percentage', set => { + key_values => [ { name => 'average_5m' } ], + output_template => '%.2f %% (5m)', + perfdatas => [ + { label => 'total_cpu_5m_avg', value => 'average_5m_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; + + $self->{maps_counters}->{cpu_core} = [ + { label => 'core-5s', nlabel => 'core.cpu.utilization.5s.percentage', set => { + key_values => [ { name => 'cpu_5s' }, { name => 'display' } ], + output_template => '%.2f %% (5s)', + perfdatas => [ + { label => 'cpu_5s', value => 'cpu_5s_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'core-1m', nlabel => 'core.cpu.utilization.1m.percentage', set => { + key_values => [ { name => 'cpu_1m' }, { name => 'display' } ], + output_template => '%.2f %% (1m)', + perfdatas => [ + { label => 'cpu_1m', value => 'cpu_1m_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'core-5m', nlabel => 'core.cpu.utilization.5m.percentage', set => { + key_values => [ { name => 'cpu_5m' }, { name => 'display' } ], + output_template => '%.2f %% (5m)', + perfdatas => [ + { label => 'cpu_5m', value => 'cpu_5m_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_cpu_avg_output { + my ($self, %options) = @_; + + return $self->{cpu_avg}->{count} . " CPU(s) average usage is "; +} + +sub prefix_cpu_core_output { + my ($self, %options) = @_; + + return "CPU '" . $options{instance_value}->{display} . "' usage "; +} + 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:s" => { name => 'warning', default => '' }, - "critical:s" => { name => 'critical', default => '' }, - }); + $options{options}->add_options(arguments => { + 'check-order:s' => { name => 'check_order', default => 'process,old_sys,system_ext' }, + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - ($self->{warn5s}, $self->{warn1m}, $self->{warn5m}) = split /,/, $self->{option_results}->{warning}; - ($self->{crit5s}, $self->{crit1m}, $self->{crit5m}) = split /,/, $self->{option_results}->{critical}; - - if (($self->{perfdata}->threshold_validate(label => 'warn5s', value => $self->{warn5s})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning (5sec) threshold '" . $self->{warn5s} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'warn1m', value => $self->{warn1m})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning (1min) threshold '" . $self->{warn1m} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'warn5m', value => $self->{warn5m})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning (5min) threshold '" . $self->{warn5m} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'crit5s', value => $self->{crit5s})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical (5sec) threshold '" . $self->{crit5s} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'crit1m', value => $self->{crit1m})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical (1min) threshold '" . $self->{crit1m} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'crit5m', value => $self->{crit5m})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical (5min) threshold '" . $self->{crit5m} . "'."); - $self->{output}->option_exit(); - } -} - sub check_nexus_cpu { my ($self, %options) = @_; - if (!defined($self->{results}->{$options{oid}}->{$options{oid} . '.0'})) { - return 0; - } - - my $cpu = $self->{results}->{$options{oid}}->{$options{oid} . '.0'}; - my $exit = $self->{perfdata}->threshold_check(value => $cpu, - threshold => [ { label => 'crit5m', exit_litteral => 'critical' }, { label => 'warn5m', exit_litteral => 'warning' } ]); - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("CPU Usage : %s %%", $cpu)); - $self->{output}->perfdata_add(label => "cpu", unit => '%', - value => $cpu, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn5m'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit5m'), - min => 0, max => 100); - return 1; + return if (!defined($options{snmp_result}->{$options{oid} . '.0'})); + + my $instance = 0; + $self->{cpu_core}->{$instance} = { + display => $instance, + cpu_5m => $options{snmp_result}->{$options{oid} . '.0'}, + }; + + $self->{checked_cpu} = 1; } sub check_table_cpu { my ($self, %options) = @_; - my $checked = 0; + return if ($self->{checked_cpu} == 1); + my $instances = {}; - foreach my $oid (keys %{$self->{results}->{$options{entry}}}) { + foreach my $oid (keys %{$options{snmp_result}}) { $oid =~ /\.([0-9]+)$/; next if (defined($instances->{$1})); $instances->{$1} = 1; my $instance = $1; - my $cpu5sec = defined($self->{results}->{$options{entry}}->{$options{sec5} . '.' . $instance}) ? sprintf("%.2f", $self->{results}->{$options{entry}}->{$options{sec5} . '.' . $instance}) : undef; - my $cpu1min = defined($self->{results}->{$options{entry}}->{$options{min1} . '.' . $instance}) ? sprintf("%.2f", $self->{results}->{$options{entry}}->{$options{min1} . '.' . $instance}) : undef; - my $cpu5min = defined($self->{results}->{$options{entry}}->{$options{min5} . '.' . $instance}) ? sprintf("%.2f", $self->{results}->{$options{entry}}->{$options{min5} . '.' . $instance}) : undef; + my $cpu5sec = defined($options{snmp_result}->{$options{sec5} . '.' . $instance}) ? $options{snmp_result}->{$options{sec5} . '.' . $instance} : undef; + my $cpu1min = defined($options{snmp_result}->{$options{min1} . '.' . $instance}) ? $options{snmp_result}->{$options{min1} . '.' . $instance} : undef; + my $cpu5min = defined($options{snmp_result}->{$options{min5} . '.' . $instance}) ? $options{snmp_result}->{$options{min5} . '.' . $instance} : undef; + # Case that it's maybe other CPU oid in table for datas. next if (!defined($cpu5sec) && !defined($cpu1min) && !defined($cpu5min)); - - $checked = 1; - my @exits; - push @exits, $self->{perfdata}->threshold_check(value => $cpu5sec, - threshold => [ { label => 'crit5s', exit_litteral => 'critical' }, { label => 'warn5s', exit_litteral => 'warning' } ]) if (defined($cpu5sec)); - push @exits, $self->{perfdata}->threshold_check(value => $cpu1min, - threshold => [ { label => 'crit1m', exit_litteral => 'critical' }, { label => 'warn1m', exit_litteral => 'warning' } ]) if (defined($cpu1min)); - push @exits, $self->{perfdata}->threshold_check(value => $cpu5min, - threshold => [ { label => 'crit5m', exit_litteral => 'critical' }, { label => 'warn5m', exit_litteral => 'warning' } ]) if (defined($cpu5min)); - my $exit = $self->{output}->get_most_critical(status => \@exits); - - $self->{output}->output_add(long_msg => sprintf("CPU '%s': %s (5sec), %s (1min), %s (5min)", $instance, - defined($cpu5sec) ? $cpu5sec . '%' : 'not defined', - defined($cpu1min) ? $cpu1min . '%' : 'not defined', - defined($cpu5min) ? $cpu5min . '%' : 'not defined')); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("CPU '%s': %s (5sec), %s (1min), %s (5min)", $instance, - defined($cpu5sec) ? $cpu5sec . '%' : 'not defined', - defined($cpu1min) ? $cpu1min . '%' : 'not defined', - defined($cpu5min) ? $cpu5min . '%' : 'not defined')); - } - - if (defined($cpu5sec)) { - $self->{output}->perfdata_add(label => "cpu_" . $instance . "_5s", unit => '%', - value => $cpu5sec, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn5s'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit5s'), - min => 0, max => 100); - } - if (defined($cpu1min)) { - $self->{output}->perfdata_add(label => "cpu_" . $instance . "_1m", unit => '%', - value => $cpu1min, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn1m'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit1m'), - min => 0, max => 100); - } - if (defined($cpu5min)) { - $self->{output}->perfdata_add(label => "cpu_" . $instance . "_5m", unit => '%', - value => $cpu5min, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn5m'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit5m'), - min => 0, max => 100); - } - } - - return $checked; + + $self->{checked_cpu} = 1; + $self->{cpu_core}->{$instance} = { + display => $instance, + cpu_5s => $cpu5sec, + cpu_1m => $cpu1min, + cpu_5m => $cpu5min, + }; + } } -sub run { +sub check_cpu_average { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; + + my $count = scalar(keys %{$self->{cpu_core}}); + my ($avg_5s, $avg_1m, $avg_5m); + foreach (values %{$self->{cpu_core}}) { + $avg_5s = defined($avg_5s) ? $avg_5s + $_->{cpu_5s} : $_->{cpu_5s} + if (defined($_->{cpu_5s})); + $avg_1m = defined($avg_1m) ? $avg_1m + $_->{cpu_1m} : $_->{cpu_1m} + if (defined($_->{cpu_1m})); + $avg_5m = defined($avg_5m) ? $avg_5m + $_->{cpu_5m} : $_->{cpu_5m} + if (defined($_->{cpu_5m})); + } + + $self->{cpu_avg} = { + average_5s => defined($avg_5s) ? $avg_5s / $count : undef, + average_1m => defined($avg_1m) ? $avg_1m / $count : undef, + average_5m => defined($avg_5m) ? $avg_5m / $count : undef, + count => $count, + }; +} + +sub check_cpu_process { + my ($self, %options) = @_; + + return if ($self->{checked_cpu} == 1); # Cisco IOS Software releases later to 12.0(3)T and prior to 12.2(3.5) my $oid_cpmCPUTotalEntry = '.1.3.6.1.4.1.9.9.109.1.1.1.1'; @@ -171,39 +198,66 @@ sub run { my $oid_cpmCPUTotal5minRev = '.1.3.6.1.4.1.9.9.109.1.1.1.1.8'; my $oid_cpmCPUTotal1minRev = '.1.3.6.1.4.1.9.9.109.1.1.1.1.7'; my $oid_cpmCPUTotal5secRev = '.1.3.6.1.4.1.9.9.109.1.1.1.1.6'; + + my $snmp_result = $self->{snmp}->get_table( + oid => $oid_cpmCPUTotalEntry, start => $oid_cpmCPUTotal5sec, end => $oid_cpmCPUTotal5minRev + ); + $self->check_table_cpu(snmp_result => $snmp_result, sec5 => $oid_cpmCPUTotal5secRev, min1 => $oid_cpmCPUTotal1minRev, min5 => $oid_cpmCPUTotal5minRev); + $self->check_table_cpu(snmp_result => $snmp_result, sec5 => $oid_cpmCPUTotal5sec, min1 => $oid_cpmCPUTotal1min, min5 => $oid_cpmCPUTotal5min); +} + +sub check_cpu_old_sys { + my ($self, %options) = @_; + + return if ($self->{checked_cpu} == 1); + # Cisco IOS Software releases prior to 12.0(3)T my $oid_lcpu = '.1.3.6.1.4.1.9.2.1'; my $oid_busyPer = '.1.3.6.1.4.1.9.2.1.56'; # .0 in reality my $oid_avgBusy1 = '.1.3.6.1.4.1.9.2.1.57'; # .0 in reality my $oid_avgBusy5 = '.1.3.6.1.4.1.9.2.1.58'; # .0 in reality + + my $snmp_result = $self->{snmp}->get_table( + oid => $oid_lcpu, start => $oid_busyPer, end => $oid_avgBusy5 + ); + $self->check_table_cpu(snmp_result => $snmp_result, sec5 => $oid_busyPer, min1 => $oid_avgBusy1, min5 => $oid_avgBusy5); +} + +sub check_cpu_system_ext { + my ($self, %options) = @_; + + return if ($self->{checked_cpu} == 1); + # Cisco Nexus my $oid_cseSysCPUUtilization = '.1.3.6.1.4.1.9.9.305.1.1.1'; # .0 in reality + my $snmp_result = $self->{snmp}->get_table( + oid => $oid_cseSysCPUUtilization + ); + + $self->check_nexus_cpu(snmp_result => $snmp_result, oid => $oid_cseSysCPUUtilization); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{cpu_avg} = {}; + $self->{cpu_core} = {}; + $self->{checked_cpu} = 0; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_cpmCPUTotalEntry, - start => $oid_cpmCPUTotal5sec, end => $oid_cpmCPUTotal5minRev - }, - { oid => $oid_lcpu, - start => $oid_busyPer, end => $oid_avgBusy5 }, - { oid => $oid_cseSysCPUUtilization }, - ], - nothing_quit => 1); - - $self->{output}->output_add(severity => 'OK', - short_msg => 'All CPUs are ok.'); - - if (!$self->check_table_cpu(entry => $oid_cpmCPUTotalEntry, sec5 => $oid_cpmCPUTotal5secRev, min1 => $oid_cpmCPUTotal1minRev, min5 => $oid_cpmCPUTotal5minRev) - && !$self->check_table_cpu(entry => $oid_cpmCPUTotalEntry, sec5 => $oid_cpmCPUTotal5sec, min1 => $oid_cpmCPUTotal1min, min5 => $oid_cpmCPUTotal5min) - && !$self->check_table_cpu(entry => $oid_lcpu, sec5 => $oid_busyPer, min1 => $oid_avgBusy1, min5 => $oid_avgBusy5) - ) { - if (!$self->check_nexus_cpu(oid => $oid_cseSysCPUUtilization)) { - $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("Cannot find CPU informations.")); + foreach (split /,/, $self->{option_results}->{check_order}) { + my $method = $self->can('check_cpu_' . $_); + if ($method) { + $self->$method(); } } - - $self->{output}->display(); - $self->{output}->exit(); + + if ($self->{checked_cpu} == 0) { + $self->{output}->add_option_msg(short_msg => "Cannot find CPU informations"); + $self->{output}->option_exit(); + } + + $self->check_cpu_average(); } 1; @@ -216,15 +270,15 @@ Check cpu usage (CISCO-PROCESS-MIB and CISCO-SYSTEM-EXT-MIB). =over 8 -=item B<--warning> +=item B<--check-order> -Threshold warning in percent (5s,1min,5min). -Used 5min threshold when you have only 'cpu' metric. +Check cpu in standard cisco mib. If you have some issue (wrong cpu information in a specific mib), you can change the order +(Default: 'process,old_sys,system_ext'). -=item B<--critical> +=item B<--warning-*> B<--critical-*> -Threshold critical in percent (5s,1min,5min). -Used 5min threshold when you have only 'cpu' metric. +Thresholds. +Can be: 'core-5s', 'core-1m', 'core-5m', 'average-5s', 'average-1m', 'average-5m'. =back diff --git a/centreon/common/cisco/standard/snmp/mode/interfaces.pm b/centreon/common/cisco/standard/snmp/mode/interfaces.pm new file mode 100644 index 000000000..7c4c5dd8f --- /dev/null +++ b/centreon/common/cisco/standard/snmp/mode/interfaces.pm @@ -0,0 +1,225 @@ +# +# Copyright 2019 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 centreon::common::cisco::standard::snmp::mode::interfaces; + +use base qw(snmp_standard::mode::interfaces); + +use strict; +use warnings; + +sub set_oids_errors { + my ($self, %options) = @_; + + $self->{oid_ifInDiscards} = '.1.3.6.1.2.1.2.2.1.13'; + $self->{oid_ifInErrors} = '.1.3.6.1.2.1.2.2.1.14'; + $self->{oid_ifOutDiscards} = '.1.3.6.1.2.1.2.2.1.19'; + $self->{oid_ifOutErrors} = '.1.3.6.1.2.1.2.2.1.20'; + $self->{oid_ifInCrc} = '.1.3.6.1.4.1.9.2.2.1.1.12'; +} + +sub set_counters_errors { + my ($self, %options) = @_; + + $self->SUPER::set_counters_errors(%options); + + push @{$self->{maps_counters}->{int}}, + { label => 'in-crc', filter => 'add_errors', nlabel => 'interface.packets.in.crc.count', set => { + key_values => [ { name => 'incrc', diff => 1 }, { name => 'total_in_packets', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], + closure_custom_calc => $self->can('custom_errors_calc'), closure_custom_calc_extra_options => { label_ref1 => 'in', label_ref2 => 'crc' }, + closure_custom_output => $self->can('custom_errors_output'), output_error_template => 'Packets In Crc : %s', + closure_custom_perfdata => $self->can('custom_errors_perfdata'), + closure_custom_threshold_check => $self->can('custom_errors_threshold'), + } + }, + ; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + return $self; +} + +sub load_errors { + my ($self, %options) = @_; + + $self->set_oids_errors(); + $self->{snmp}->load( + oids => [ + $self->{oid_ifInDiscards}, $self->{oid_ifInErrors}, + $self->{oid_ifOutDiscards}, $self->{oid_ifOutErrors}, + $self->{oid_ifInCrc} + ], + instances => $self->{array_interface_selected} + ); +} + +sub add_result_errors { + my ($self, %options) = @_; + + $self->{int}->{$options{instance}}->{indiscard} = $self->{results}->{$self->{oid_ifInDiscards} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{inerror} = $self->{results}->{$self->{oid_ifInErrors} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{outdiscard} = $self->{results}->{$self->{oid_ifOutDiscards} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{outerror} = $self->{results}->{$self->{oid_ifOutErrors} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{incrc} = $self->{results}->{$self->{oid_ifInCrc} . '.' . $options{instance}}; +} + +1; + +__END__ + +=head1 MODE + +Check interfaces. + +=over 8 + +=item B<--add-global> + +Check global port statistics (By default if no --add-* option is set). + +=item B<--add-status> + +Check interface status. + +=item B<--add-duplex-status> + +Check duplex status (with --warning-status and --critical-status). + +=item B<--add-traffic> + +Check interface traffic. + +=item B<--add-errors> + +Check interface errors. + +=item B<--add-cast> + +Check interface cast. + +=item B<--add-speed> + +Check interface speed. + +=item B<--add-volume> + +Check interface data volume between two checks (not supposed to be graphed, useful for BI reporting). + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). +Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down', +'in-traffic', 'out-traffic', 'in-crc', 'in-error', 'in-discard', 'out-error', 'out-discard', +'in-ucast' (%), 'in-bcast' (%), 'in-mcast' (%), 'out-ucast' (%), 'out-bcast' (%), 'out-mcast' (%), +'speed' (b/s). + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down', +'in-traffic', 'out-traffic', 'in-crc', 'in-error', 'in-discard', 'out-error', 'out-discard', +'in-ucast' (%), 'in-bcast' (%), 'in-mcast' (%), 'out-ucast' (%), 'out-bcast' (%), 'out-mcast' (%), +'speed' (b/s). + +=item B<--units-traffic> + +Units of thresholds for the traffic (Default: '%') ('%', 'b/s'). + +=item B<--units-errors> + +Units of thresholds for errors/discards (Default: '%') ('%', 'absolute'). + +=item B<--nagvis-perfdata> + +Display traffic perfdata to be compatible with nagvis widget. + +=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<--no-skipped-counters> + +Don't skip counters when no change. + +=item B<--force-counters32> + +Force to use 32 bits counters (even in snmp v2c and v3). Should be used when 64 bits counters are buggy. + +=item B<--reload-cache-time> + +Time in minutes before reloading cache file (default: 180). + +=item B<--oid-filter> + +Choose OID used to filter interface (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). + +=item B<--oid-display> + +Choose OID used to display interface (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). + +=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/centreon/common/cisco/standard/snmp/mode/ipsectunnel.pm b/centreon/common/cisco/standard/snmp/mode/ipsectunnel.pm index 97f76ebbe..284f57958 100644 --- a/centreon/common/cisco/standard/snmp/mode/ipsectunnel.pm +++ b/centreon/common/cisco/standard/snmp/mode/ipsectunnel.pm @@ -27,8 +27,6 @@ use warnings; use Digest::MD5 qw(md5_hex); use Socket; -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -99,26 +97,24 @@ sub set_counters { sub custom_traffic_perfdata { my ($self, %options) = @_; + + my $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}); + my $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}); - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - - my $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}); - my $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}); - - $self->{output}->perfdata_add(label => 'traffic_' . lc($self->{result_values}->{label}) . $extra_label, unit => 'b/s', - value => sprintf("%.2f", $self->{result_values}->{traffic_per_seconds}), - warning => $warning, - critical => $critical, - min => 0); + $self->{output}->perfdata_add( + label => 'traffic_' . lc($self->{result_values}->{label}), unit => 'b/s', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{traffic_per_seconds}), + warning => $warning, + critical => $critical, + min => 0 + ); } sub custom_traffic_threshold { my ($self, %options) = @_; - my $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' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_per_seconds}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -165,25 +161,23 @@ sub custom_traffic_calc { sub custom_drop_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } + my $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}); + my $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}); - my $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}); - my $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}); - - $self->{output}->perfdata_add(label => 'drop_' . lc($self->{result_values}->{label}) . $extra_label, unit => 'pkts/s', - value => sprintf("%.2f", $self->{result_values}->{pkts_per_seconds}), - warning => $warning, - critical => $critical, - min => 0); + $self->{output}->perfdata_add( + label => 'drop_' . lc($self->{result_values}->{label}), unit => 'pkts/s', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{pkts_per_seconds}), + warning => $warning, + critical => $critical, + min => 0 + ); } sub custom_drop_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{pkts_per_seconds}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{pkts_per_seconds}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -229,12 +223,11 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "filter-sa:s" => { name => 'filter_sa' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "filter-sa:s" => { name => 'filter_sa' }, + }); + return $self; } diff --git a/centreon/common/cisco/standard/snmp/mode/memory.pm b/centreon/common/cisco/standard/snmp/mode/memory.pm index 44931194d..db8381a4b 100644 --- a/centreon/common/cisco/standard/snmp/mode/memory.pm +++ b/centreon/common/cisco/standard/snmp/mode/memory.pm @@ -20,159 +20,299 @@ package centreon::common::cisco::standard::snmp::mode::memory; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my ($label, $nlabel, $unit, $total) = ('used', $self->{nlabel}, '%', 100); + my $value_perf = $self->{result_values}->{prct_used}; + my %total_options = (); + if ($self->{result_values}->{total} != -1) { + $nlabel = 'memory.usage.bytes'; + $unit = 'B'; + $total = $self->{result_values}->{total}; + $total_options{total} = $self->{result_values}->{total}; + $total_options{cast_int} = 1; + $value_perf = $self->{result_values}->{used}; + } + + $self->{output}->perfdata_add( + label => $label, unit => $unit, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + nlabel => $nlabel, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $total + ); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + return $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my $msg; + if ($self->{result_values}->{total} != -1) { + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + $msg = sprintf("Usage Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + } else { + $msg = sprintf("Usage : %.2f %%", $self->{result_values}->{prct_used}); + } + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{prct_used} = $options{new_datas}->{$self->{instance} . '_prct_used'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + if ($self->{result_values}->{total} != -1) { + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + } + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 1, cb_prefix_output => 'prefix_memory_output', message_multiple => 'All memories are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{memory} = [ + { label => 'usage', nlabel => 'memory.usage.percentage', set => { + key_values => [ { name => 'display' }, { name => 'used' }, { name => 'total' }, { name => 'prct_used' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +sub prefix_memory_output { + my ($self, %options) = @_; + + return "Memory '" . $options{instance_value}->{display} . "' "; +} + 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:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "filter-pool:s" => { name => 'filter_pool' }, - }); + $options{options}->add_options(arguments => { + 'filter-pool:s' => { name => 'filter_pool' }, + 'check-order:s' => { name => 'check_order', default => 'enhanced_pool,pool,process,system_ext' }, + }); return $self; } -sub check_options { +my $mapping_memory_pool = { + ciscoMemoryPoolName => { oid => '.1.3.6.1.4.1.9.9.48.1.1.1.2' }, + ciscoMemoryPoolUsed => { oid => '.1.3.6.1.4.1.9.9.48.1.1.1.5' }, # in B + ciscoMemoryPoolFree => { oid => '.1.3.6.1.4.1.9.9.48.1.1.1.6' }, # in B +}; +my $oid_ciscoMemoryPoolEntry = '.1.3.6.1.4.1.9.9.48.1.1.1'; + +sub check_memory_pool { my ($self, %options) = @_; - $self->SUPER::init(%options); + + return if ($self->{checked_memory} == 1); - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } -} - -sub check_table_memory { - my ($self, %options) = @_; - - my $checked = 0; - foreach my $oid (keys %{$self->{results}->{$options{entry}}}) { - next if ($oid !~ /^$options{poolName}/); - $oid =~ /\.([0-9]+)$/; + my $snmp_result = $self->{snmp}->get_table( + oid => $oid_ciscoMemoryPoolEntry, + start => $mapping_memory_pool->{ciscoMemoryPoolName}->{oid}, end => $mapping_memory_pool->{ciscoMemoryPoolFree}->{oid} + ); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping_memory_pool->{ciscoMemoryPoolName}->{oid}\.(.*)$/); my $instance = $1; - my $memory_name = $self->{results}->{$options{entry}}->{$oid}; - my $memory_used = $self->{results}->{$options{entry}}->{$options{poolUsed} . '.' . $instance}; - my $memory_free = $self->{results}->{$options{entry}}->{$options{poolFree} . '.' . $instance}; - - next if ($memory_name eq ''); + my $result = $self->{snmp}->map_instance(mapping => $mapping_memory_pool, results => $snmp_result, instance => $instance); + + $self->{checked_memory} = 1; if (defined($self->{option_results}->{filter_pool}) && $self->{option_results}->{filter_pool} ne '' && - $memory_name !~ /$self->{option_results}->{filter_pool}/) { - $self->{output}->output_add(long_msg => "Skipping pool '" . $memory_name . "'."); + $result->{ciscoMemoryPoolName} !~ /$self->{option_results}->{filter_pool}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{ciscoMemoryPoolName} . "': no matching filter.", debug => 1); next; } - $checked = 1; - - my $total_size = $memory_used + $memory_free; - my $prct_used = $memory_used * 100 / $total_size; - my $prct_free = 100 - $prct_used; - - my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $total_size); - my ($used_value, $used_unit) = $self->{perfdata}->change_bytes(value => $memory_used); - my ($free_value, $free_unit) = $self->{perfdata}->change_bytes(value => $memory_free); - - $self->{output}->output_add(long_msg => sprintf("Memory '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $memory_name, - $total_value . " " . $total_unit, - $used_value . " " . $used_unit, $prct_used, - $free_value . " " . $free_unit, $prct_free)); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Memory '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $memory_name, - $total_value . " " . $total_unit, - $used_value . " " . $used_unit, $prct_used, - $free_value . " " . $free_unit, $prct_free)); - } - - $self->{output}->perfdata_add(label => "used_" . $memory_name, unit => 'B', - value => $memory_used, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size), - min => 0, max => $total_size); + $self->{memory}->{$instance} = { + display => $result->{ciscoMemoryPoolName}, + total => $result->{ciscoMemoryPoolFree} + $result->{ciscoMemoryPoolUsed}, + used => $result->{ciscoMemoryPoolUsed}, + prct_used => -1, + }; } - - return $checked; } -sub check_percent_memory { +my $oid_cseSysMemoryUtilization = '.1.3.6.1.4.1.9.9.305.1.1.2'; + +sub check_memory_system_ext { + my ($self, %options) = @_; + + return if ($self->{checked_memory} == 1); + + my $snmp_result = $self->{snmp}->get_table( + oid => $oid_cseSysMemoryUtilization, + ); + + foreach my $oid (keys %{$snmp_result}) { + my $used = $snmp_result->{$oid}; + next if ($used eq ''); + my $display = 'system'; + + $self->{checked_memory} = 1; + if (defined($self->{option_results}->{filter_pool}) && $self->{option_results}->{filter_pool} ne '' && + $display !~ /$self->{option_results}->{filter_pool}/) { + $self->{output}->output_add(long_msg => "skipping '" . $display . "': no matching filter.", debug => 1); + next; + } + + $self->{memory}->{system} = { + display => 'system', + total => -1, + used => -1, + prct_used => $used, + }; + } +} + +my $mapping_enh_memory_pool = { + cempMemPoolName => { oid => '.1.3.6.1.4.1.9.9.221.1.1.1.1.3' }, + cempMemPoolUsed => { oid => '.1.3.6.1.4.1.9.9.221.1.1.1.1.7' }, # in B + cempMemPoolFree => { oid => '.1.3.6.1.4.1.9.9.221.1.1.1.1.8' }, # in B + cempMemPoolHCUsed => { oid => '.1.3.6.1.4.1.9.9.221.1.1.1.1.18' }, # in B + cempMemPoolHCFree => { oid => '.1.3.6.1.4.1.9.9.221.1.1.1.1.20' }, # in B +}; + +sub check_memory_enhanced_pool { my ($self, %options) = @_; - my $checked = 0; - foreach my $oid (keys %{$self->{results}->{$options{entry}}}) { - next if ($oid !~ /^$options{memUsage}/); - $oid =~ /\.([0-9]+)$/; + return if ($self->{checked_memory} == 1); + + my $oids = [ + { oid => $mapping_enh_memory_pool->{cempMemPoolName}->{oid} }, + { oid => $mapping_enh_memory_pool->{cempMemPoolUsed}->{oid} }, + { oid => $mapping_enh_memory_pool->{cempMemPoolFree}->{oid} }, + ]; + if (!$self->{snmp}->is_snmpv1()) { + push @{$oids}, { oid => $mapping_enh_memory_pool->{cempMemPoolHCUsed}->{oid} }, + { oid => $mapping_enh_memory_pool->{cempMemPoolHCFree}->{oid} }; + } + my $snmp_result = $self->{snmp}->get_multiple_table( + oids => $oids, + return_type => 1 + ); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping_enh_memory_pool->{cempMemPoolName}->{oid}\.(.*)$/); my $instance = $1; - my $memory_usage = $self->{results}->{$options{entry}}->{$oid}; + my $result = $self->{snmp}->map_instance(mapping => $mapping_enh_memory_pool, results => $snmp_result, instance => $instance); - next if ($memory_usage eq ''); - - $checked = 1; - - my $exit = $self->{perfdata}->threshold_check(value => $memory_usage, - threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Memory used : %.2f%%", $memory_usage)); + $self->{checked_memory} = 1; + if (defined($self->{option_results}->{filter_pool}) && $self->{option_results}->{filter_pool} ne '' && + $result->{cempMemPoolName} !~ /$self->{option_results}->{filter_pool}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{cempMemPoolName} . "': no matching filter.", debug => 1); + next; } - $self->{output}->perfdata_add(label => "utilization", - value => $memory_usage, - unit => "%", - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0, max => 100); + my $used = defined($result->{cempMemPoolHCUsed}) ? $result->{cempMemPoolHCUsed} : $result->{cempMemPoolUsed}; + my $free = defined($result->{cempMemPoolHCFree}) ? $result->{cempMemPoolHCFree} : $result->{cempMemPoolFree}; + $self->{memory}->{$instance} = { + display => $result->{cempMemPoolName}, + total => $used + $free, + used => $used, + prct_used => -1, + }; } - - return $checked; } -sub run { +my $mapping_memory_process = { + cpmCPUMemoryUsed => { oid => '.1.3.6.1.4.1.9.9.109.1.1.1.1.12' }, # in KB + cpmCPUMemoryFree => { oid => '.1.3.6.1.4.1.9.9.109.1.1.1.1.13' }, # in KB + cpmCPUMemoryUsedOvrflw => { oid => '.1.3.6.1.4.1.9.9.109.1.1.1.1.16' }, # in KB + cpmCPUMemoryFreeOvrflw => { oid => '.1.3.6.1.4.1.9.9.109.1.1.1.1.18' }, # in KB +}; + +sub check_memory_process { my ($self, %options) = @_; + + return if ($self->{checked_memory} == 1); + + my $oid_cpmCPUTotalEntry = '.1.3.6.1.4.1.9.9.109.1.1.1.1'; + my $snmp_result = $self->{snmp}->get_table( + oid => $oid_cpmCPUTotalEntry, + start => $mapping_memory_process->{cpmCPUMemoryUsed}->{oid}, + end => $mapping_memory_process->{cpmCPUMemoryFreeOvrflw}->{oid}, + ); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping_memory_process->{cpmCPUMemoryUsed}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping_memory_process, results => $snmp_result, instance => $instance); + + $self->{checked_memory} = 1; + + my $used = ( + defined($result->{cpmCPUMemoryUsedOvrflw}) ? + ($result->{cpmCPUMemoryUsedOvrflw} << 32) + ($result->{cpmCPUMemoryUsed}) : + $result->{cpmCPUMemoryUsed} + ) * 1024; + my $free = ( + defined($result->{cpmCPUMemoryFreeOvrflw}) ? + ($result->{cpmCPUMemoryFreeOvrflw} << 32) + ($result->{cpmCPUMemoryFree}) : + $result->{cpmCPUMemoryFree} + ) * 1024; + $self->{memory}->{$instance} = { + display => $instance, + total => $used + $free, + used => $used, + prct_used => -1, + }; + } +} + +sub manage_selection { + my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; + $self->{checked_memory} = 0; + $self->{memory} = {}; - my $oid_ciscoMemoryPoolEntry = '.1.3.6.1.4.1.9.9.48.1.1.1'; - my $oid_ciscoMemoryPoolName = '.1.3.6.1.4.1.9.9.48.1.1.1.2'; - my $oid_ciscoMemoryPoolUsed = '.1.3.6.1.4.1.9.9.48.1.1.1.5'; # in B - my $oid_ciscoMemoryPoolFree = '.1.3.6.1.4.1.9.9.48.1.1.1.6'; # in B - - # OIDs for Nexus - my $oid_cseSysMemoryEntry = '.1.3.6.1.4.1.9.9.305.1.1'; - my $oid_cseSysMemoryUtilization = '.1.3.6.1.4.1.9.9.305.1.1.2'; - - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_ciscoMemoryPoolEntry, - start => $oid_ciscoMemoryPoolName, end => $oid_ciscoMemoryPoolFree - }, - { oid => $oid_cseSysMemoryEntry, - start => $oid_cseSysMemoryUtilization, end => $oid_cseSysMemoryUtilization }], - nothing_quit => 1); - - $self->{output}->output_add(severity => 'OK', - short_msg => 'Memory is ok.'); - - if (!$self->check_table_memory(entry => $oid_ciscoMemoryPoolEntry, poolName => $oid_ciscoMemoryPoolName, poolUsed => $oid_ciscoMemoryPoolUsed, poolFree => $oid_ciscoMemoryPoolFree) - && !$self->check_percent_memory(entry => $oid_cseSysMemoryEntry, memUsage => $oid_cseSysMemoryUtilization) - ) { - $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("Cannot find Memory informations.")); + foreach (split /,/, $self->{option_results}->{check_order}) { + my $method = $self->can('check_memory_' . $_); + if ($method) { + $self->$method(); + } } - $self->{output}->display(); - $self->{output}->exit(); - + if ($self->{checked_memory} == 0) { + $self->{output}->add_option_msg(short_msg => "Cannot find memory informations"); + $self->{output}->option_exit(); + } } 1; @@ -181,15 +321,15 @@ __END__ =head1 MODE -Check memory usage (CISCO-MEMORY-POOL-MIB and CISCO-SYSTEM-EXT-MIB). +Check memory usage (CISCO-MEMORY-POOL-MIB, CISCO-ENHANCED-MEMPOOL-MIB, CISCO-PROCESS-MIB, CISCO-SYSTEM-EXT-MIB). =over 8 -=item B<--warning> +=item B<--warning-usage> Threshold warning in percent. -=item B<--critical> +=item B<--critical-usage> Threshold critical in percent. @@ -197,6 +337,11 @@ Threshold critical in percent. Filter pool to check (can use regexp). +=item B<--check-order> + +Check memory in standard cisco mib. If you have some issue (wrong memory information in a specific mib), you can change the order +(Default: 'enhanced_pool,pool,process,system_ext'). + =back =cut diff --git a/centreon/common/cisco/standard/snmp/mode/memoryflash.pm b/centreon/common/cisco/standard/snmp/mode/memoryflash.pm index c5c9f3c9c..adc1690da 100644 --- a/centreon/common/cisco/standard/snmp/mode/memoryflash.pm +++ b/centreon/common/cisco/standard/snmp/mode/memoryflash.pm @@ -20,41 +20,29 @@ package centreon::common::cisco::standard::snmp::mode::memoryflash; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; - -my $maps_counters = { - '000_usage' => { set => { - key_values => [ { name => 'display' }, { name => 'free' }, { name => 'total' } ], - closure_custom_calc => \&custom_usage_calc, - closure_custom_output => \&custom_usage_output, - closure_custom_perfdata => \&custom_usage_perfdata, - closure_custom_threshold_check => \&custom_usage_threshold, - } - }, -}; sub custom_usage_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + nlabel => $self->{nlabel}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -84,102 +72,43 @@ sub custom_usage_calc { return 0; } + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 1, cb_prefix_output => 'prefix_memory_output', message_multiple => 'All memory flash partitions are ok' } + ]; + + $self->{maps_counters}->{memory} = [ + { label => 'usage', nlabel => 'memory.flash.usage.bytes', set => { + key_values => [ { name => 'display' }, { name => 'free' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + 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' }, - }); - - foreach (sort keys %{$maps_counters}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$_}->{threshold}) || $maps_counters->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); + return $self; } -sub check_options { +sub prefix_memory_output { my ($self, %options) = @_; - $self->SUPER::init(%options); - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{memory_selected}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All memory flash partitions are ok'); - } - - foreach my $id (sort keys %{$self->{memory_selected}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - my $obj = $maps_counters->{$_}->{obj}; - - $obj->set(instance => $id); - my ($value_check) = $obj->execute(values => $self->{memory_selected}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Partition '" . $self->{memory_selected}->{$id}->{display} . "' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Partition '" . $self->{memory_selected}->{$id}->{display} . "' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Partition '" . $self->{memory_selected}->{$id}->{display} . "' $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); + return "Partition '" . $options{instance_value}->{display} . "' "; } my $mapping = { @@ -193,18 +122,20 @@ my $mapping = { sub manage_selection { my ($self, %options) = @_; - $self->{memory_selected} = {}; my $ciscoFlashPartitionEntry = '.1.3.6.1.4.1.9.9.10.1.1.4.1.1'; - $self->{results} = $self->{snmp}->get_table(oid => $ciscoFlashPartitionEntry, - nothing_quit => 1); - - foreach my $oid (keys %{$self->{results}}) { + my $snmp_result = $options{snmp}->get_table( + oid => $ciscoFlashPartitionEntry, + nothing_quit => 1 + ); + + $self->{memory} = {}; + foreach my $oid (keys %$snmp_result) { next if ($oid !~ /^$mapping->{ciscoFlashPartitionSize}->{oid}\.(.*)/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); + 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->{ciscoFlashPartitionName} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $result->{ciscoFlashPartitionName} . "': no matching filter.", debug => 1); + $self->{output}->output_add(long_msg => "skipping '" . $result->{ciscoFlashPartitionName} . "': no matching filter.", debug => 1); next; } @@ -217,12 +148,14 @@ sub manage_selection { $free = $result->{ciscoFlashPartitionFreeSpaceExtended}; } - $self->{memory_selected}->{$instance} = { display => $result->{ciscoFlashPartitionName}, - free => $free, total => $total }; + $self->{memory}->{$instance} = { + display => $result->{ciscoFlashPartitionName}, + free => $free, total => $total + }; } - if (scalar(keys %{$self->{memory_selected}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No entry found."); + if (scalar(keys %{$self->{memory}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No flash memory found."); $self->{output}->option_exit(); } } diff --git a/centreon/common/cisco/standard/snmp/mode/qosusage.pm b/centreon/common/cisco/standard/snmp/mode/qosusage.pm index fdc026d2f..aa2d85318 100644 --- a/centreon/common/cisco/standard/snmp/mode/qosusage.pm +++ b/centreon/common/cisco/standard/snmp/mode/qosusage.pm @@ -26,8 +26,6 @@ use strict; use warnings; use Digest::MD5 qw(md5_hex); -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -107,35 +105,33 @@ sub set_counters { 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}->{total})) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1); - $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, 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}); + if ($self->{instance_mode}->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{total})) { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1); + } elsif ($self->{instance_mode}->{option_results}->{units_traffic} eq 'b/s') { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}); } - $self->{output}->perfdata_add(label => 'icmap_traffic' . $extra_label, unit => 'b/s', - value => sprintf("%.2f", $self->{result_values}->{traffic_per_seconds}), - warning => $warning, - critical => $critical, - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'icmap_traffic', unit => 'b/s', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{traffic_per_seconds}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{total} + ); } sub custom_traffic_threshold { my ($self, %options) = @_; my $exit = 'ok'; - if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{total})) { - $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' } ]); + if ($self->{instance_mode}->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{total})) { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); + } elsif ($self->{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->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } return $exit; } @@ -184,14 +180,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-source:s" => { name => 'filter_source' }, - "oid-filter:s" => { name => 'oid_filter', default => 'ifname' }, - "oid-display:s" => { name => 'oid_display', default => 'ifname' }, - "units-traffic:s" => { name => 'units_traffic', default => '%' }, - }); - + $options{options}->add_options(arguments => { + "filter-source:s" => { name => 'filter_source' }, + "oid-filter:s" => { name => 'oid_filter', default => 'ifname' }, + "oid-display:s" => { name => 'oid_display', default => 'ifname' }, + "units-traffic:s" => { name => 'units_traffic', default => '%' }, + }); + return $self; } @@ -205,7 +200,6 @@ sub check_options { 'ifname' => '.1.3.6.1.2.1.31.1.1.1.1', }; $self->check_oids_label(); - $instance_mode = $self; } sub check_oids_label { diff --git a/centreon/common/dell/fastpath/snmp/mode/components/fan.pm b/centreon/common/dell/fastpath/snmp/mode/components/fan.pm index 30c4eb226..a2fbbdfbc 100644 --- a/centreon/common/dell/fastpath/snmp/mode/components/fan.pm +++ b/centreon/common/dell/fastpath/snmp/mode/components/fan.pm @@ -79,11 +79,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '%s' is '%s' rpm", $instance, $result->{boxServicesFanSpeed})); } - $self->{output}->perfdata_add(label => 'fan_' . $instance, unit => 'rpm', - value => $result->{boxServicesFanSpeed}, - warning => $warn, - critical => $crit, min => 0 - ); + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $instance, + value => $result->{boxServicesFanSpeed}, + warning => $warn, + critical => $crit, min => 0 + ); } } diff --git a/centreon/common/dell/fastpath/snmp/mode/components/temperature.pm b/centreon/common/dell/fastpath/snmp/mode/components/temperature.pm index 9c8b73c98..2fd177907 100644 --- a/centreon/common/dell/fastpath/snmp/mode/components/temperature.pm +++ b/centreon/common/dell/fastpath/snmp/mode/components/temperature.pm @@ -87,11 +87,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is '%s' C", $instance, $result->{boxServicesTempSensorTemperature})); } - $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', - value => $result->{boxServicesTempSensorTemperature}, - warning => $warn, - critical => $crit, min => 0 - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $instance, + value => $result->{boxServicesTempSensorTemperature}, + warning => $warn, + critical => $crit, min => 0 + ); } } diff --git a/centreon/common/emc/navisphere/mode/controller.pm b/centreon/common/emc/navisphere/mode/controller.pm index df35206ef..641854ec2 100644 --- a/centreon/common/emc/navisphere/mode/controller.pm +++ b/centreon/common/emc/navisphere/mode/controller.pm @@ -20,57 +20,11 @@ package centreon::common::emc::navisphere::mode::controller; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); -use centreon::plugins::values; - -my $maps_counters = { - 'read-iops' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'read', diff => 1 }, - ], - per_second => 1, - output_template => 'Read IOPs : %.2f', - perfdatas => [ - { value => 'read_per_second', template => '%.2f', - unit => 'iops', min => 0 }, - ], - } - }, - 'write-iops' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'write', diff => 1 }, - ], - per_second => 1, - output_template => 'Write IOPs : %.2f', - perfdatas => [ - { value => 'write_per_second', template => '%.2f', - unit => 'iops', min => 0 }, - ], - } - }, - 'busy' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'idle_ticks', diff => 1 }, - { name => 'busy_ticks', diff => 1 }, - ], - closure_custom_calc => \&custom_busy_calc, - output_template => 'Busy : %.2f %%', - output_use => 'busy_prct', threshold_use => 'busy_prct', - perfdatas => [ - { value => 'busy_prct', template => '%.2f', - unit => '%', min => 0, max => 100 }, - ], - } - }, -}; sub custom_busy_calc { my ($self, %options) = @_; @@ -87,106 +41,79 @@ sub custom_busy_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', skipped_code => { -2 => 1, -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'read-iops', nlabel => 'controller.io.read.usage.iops', set => { + key_values => [ { name => 'read', diff => 1 } ], + per_second => 1, + output_template => 'Read IOPs : %.2f', + perfdatas => [ + { value => 'read_per_second', template => '%.2f', + unit => 'iops', min => 0 }, + ], + } + }, + { label => 'write-iops', nlabel => 'controller.io.write.usage.iops', set => { + key_values => [ { name => 'write', diff => 1 } ], + per_second => 1, + output_template => 'Write IOPs : %.2f', + perfdatas => [ + { value => 'write_per_second', template => '%.2f', + unit => 'iops', min => 0 }, + ], + } + }, + { label => 'busy', nlabel => 'controller.busy.usage.percentage', set => { + key_values => [ { name => 'idle_ticks', diff => 1 }, { name => 'busy_ticks', diff => 1 } ], + closure_custom_calc => $self->can('custom_busy_calc'), + output_template => 'Busy : %.2f %%', + output_use => 'busy_prct', threshold_use => 'busy_prct', + perfdatas => [ + { value => 'busy_prct', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + ]; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Global Controller "; +} + sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - - foreach (keys %{$maps_counters}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - my $clariion = $options{custom}; - - $self->{response} = $clariion->execute_command(cmd => 'getcontrol -cbt -busy -write -read -idle'); - - $self->manage_selection(); - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "cache_clariion_" . $clariion->{hostname} . '_' . $self->{mode}); - $self->{new_datas}->{last_timestamp} = time(); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => 'gcontrol'); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{gcontrol}, - new_datas => $self->{new_datas}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{$_}->{obj}->perfdata(); - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Global Controller $short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "Global Controller $long_msg"); - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; + + my $response = $options{custom}->execute_command(cmd => 'getcontrol -cbt -busy -write -read -idle'); + + $self->{global} = {}; + $self->{global}->{read} = $response =~ /^Total Reads:\s*(\d+)/msi ? $1 : undef; + $self->{global}->{write} = $response =~ /^Total Writes:\s*(\d+)/msi ? $1 : undef;; + $self->{global}->{idle_ticks} = $response =~ /^Controller idle ticks:\s*(\d+)/msi ? $1 : undef; + $self->{global}->{busy_ticks} = $response =~ /^Controller busy ticks:\s*(\d+)/msi ? $1 : undef; - $self->{gcontrol} = {}; - $self->{gcontrol}->{read} = $self->{response} =~ /^Total Reads:\s*(\d+)/msi ? $1 : undef; - $self->{gcontrol}->{write} = $self->{response} =~ /^Total Writes:\s*(\d+)/msi ? $1 : undef;; - $self->{gcontrol}->{idle_ticks} = $self->{response} =~ /^Controller idle ticks:\s*(\d+)/msi ? $1 : undef; - $self->{gcontrol}->{busy_ticks} = $self->{response} =~ /^Controller busy ticks:\s*(\d+)/msi ? $1 : undef; + $self->{cache_name} = "cache_clariion_" . $options{custom}->{hostname} . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; diff --git a/centreon/common/emc/navisphere/mode/disk.pm b/centreon/common/emc/navisphere/mode/disk.pm index ac0530ba7..074a448c8 100644 --- a/centreon/common/emc/navisphere/mode/disk.pm +++ b/centreon/common/emc/navisphere/mode/disk.pm @@ -27,8 +27,6 @@ use warnings; use centreon::plugins::misc; use Digest::MD5 qw(md5_hex); -my $instance_mode; - my @states = ( ['^enabled$' , 'OK'], ['^binding$' , 'OK'], @@ -170,22 +168,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-raidgroupid:s" => { name => 'filter_raidgroupid', }, - "filter-disk:s" => { name => 'filter_disk', }, - }); + $options{options}->add_options(arguments => { + "filter-raidgroupid:s" => { name => 'filter_raidgroupid', }, + "filter-disk:s" => { name => 'filter_disk', }, + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/centreon/common/force10/snmp/mode/components/temperature.pm b/centreon/common/force10/snmp/mode/components/temperature.pm index 1d5f30ef5..bee81aa1e 100644 --- a/centreon/common/force10/snmp/mode/components/temperature.pm +++ b/centreon/common/force10/snmp/mode/components/temperature.pm @@ -65,12 +65,16 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s C", $instance, $result->{Temp})); } - $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', - value => $result->{Temp}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $instance, + value => $result->{Temp}, + warning => $warn, + critical => $crit + ); } } } -1; \ No newline at end of file +1; diff --git a/centreon/common/force10/snmp/mode/cpu.pm b/centreon/common/force10/snmp/mode/cpu.pm index 7e63a2f87..224199af3 100644 --- a/centreon/common/force10/snmp/mode/cpu.pm +++ b/centreon/common/force10/snmp/mode/cpu.pm @@ -20,157 +20,65 @@ package centreon::common::force10::snmp::mode::cpu; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -my $instance_mode; - -my $maps_counters = { - cpu => { - '000_5s' => { - set => { +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'cpu', type => 1, cb_prefix_output => 'prefix_cpu_output', message_multiple => 'All CPU usages are ok' } + ]; + + $self->{maps_counters}->{cpu} = [ + { label => '5s', nlabel => 'cpu.utilization.5s.percentage', set => { key_values => [ { name => 'usage_5s' }, { name => 'display' } ], output_template => '%s %% (5sec)', output_error_template => "%s (5sec)", perfdatas => [ { label => 'cpu_5s', value => 'usage_5s_absolute', template => '%d', unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '001_1m' => { - set => { + { label => '1m', nlabel => 'cpu.utilization.1m.percentage', set => { key_values => [ { name => 'usage_1m' }, { name => 'display' } ], output_template => '%s %% (1m)', output_error_template => "%s (1min)", perfdatas => [ { label => 'cpu_1m', value => 'usage_1m_absolute', template => '%d', unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '002_5m' => { - set => { + { label => '5m', nlabel => 'cpu.utilization.5m.percentage', set => { key_values => [ { name => 'usage_5m' }, { name => 'display' } ], output_template => '%s %% (5min)', output_error_template => "%s (5min)", perfdatas => [ { label => 'cpu_5m', value => 'usage_5m_absolute', template => '%d', unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - } -}; + ]; +} 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 => - { - }); - - foreach my $key (('cpu')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - + $options{options}->add_options(arguments => { + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('cpu')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - $instance_mode = $self; -} - -sub run_instances { +sub prefix_cpu_output { my ($self, %options) = @_; - my $multiple = 1; - if (scalar(keys %{$self->{cpu}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All CPU usages are ok'); - } - - foreach my $id (sort keys %{$self->{cpu}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{cpu}}) { - my $obj = $maps_counters->{cpu}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{cpu}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(level => 1, extra_instance => $multiple); - } - - my $prefix = "CPU Usage "; - if ($multiple == 1) { - $prefix = sprintf("CPU '%s' Usage ", $self->{cpu}->{$id}->{display}); - } - $self->{output}->output_add(long_msg => "${prefix}$long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "${prefix}$short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "${prefix}$long_msg"); - } - } -} - -sub run { - my ($self, %options) = @_; - - $self->manage_selection(%options); - $self->run_instances(); - - $self->{output}->display(); - $self->{output}->exit(); + return "CPU '" . $options{instance_value}->{display} . "' Usage "; } my $mapping = { @@ -195,20 +103,24 @@ sub manage_selection { my ($self, %options) = @_; my $oids = { sseries => '.1.3.6.1.4.1.6027.3.10.1.2.9.1', mseries => '.1.3.6.1.4.1.6027.3.19.1.2.8.1', zseries => '.1.3.6.1.4.1.6027.3.25.1.2.3.1' }; - my $results = $options{snmp}->get_multiple_table(oids => [ { oid => $oids->{sseries} }, { oid => $oids->{mseries} }, { oid => $oids->{zseries} } ], - nothing_quit => 1); + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ { oid => $oids->{sseries} }, { oid => $oids->{mseries} }, { oid => $oids->{zseries} } ], + nothing_quit => 1 + ); + $self->{cpu} = {}; foreach my $name (keys %{$oids}) { - foreach my $oid (keys %{$results->{$oids->{$name}}}) { + foreach my $oid (keys %{$snmp_result->{$oids->{$name}}}) { next if ($oid !~ /^$mapping->{$name}->{Util5Min}->{oid}\.(.*)/); my $instance = $1; - my $result = $options{snmp}->map_instance(mapping => $mapping->{$name}, results => $results->{$oids->{$name}}, instance => $instance); + my $result = $options{snmp}->map_instance(mapping => $mapping->{$name}, results => $snmp_result->{$oids->{$name}}, instance => $instance); - $self->{cpu}->{$instance} = { display => $instance, - usage_5s => $result->{Util5Sec}, - usage_1m => $result->{Util1Min}, - usage_5m => $result->{Util5Min}, - }; + $self->{cpu}->{$instance} = { + display => $instance, + usage_5s => $result->{Util5Sec}, + usage_1m => $result->{Util1Min}, + usage_5m => $result->{Util5Min}, + }; } } diff --git a/centreon/common/force10/snmp/mode/memory.pm b/centreon/common/force10/snmp/mode/memory.pm index b139050e9..a13cdcf7f 100644 --- a/centreon/common/force10/snmp/mode/memory.pm +++ b/centreon/common/force10/snmp/mode/memory.pm @@ -20,139 +20,49 @@ package centreon::common::force10::snmp::mode::memory; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -my $instance_mode; - -my $maps_counters = { - mem => { - '000_usage' => { - set => { +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 1, cb_prefix_output => 'prefix_memory_output', message_multiple => 'All memory usages are ok' } + ]; + + $self->{maps_counters}->{memory} = [ + { label => 'usage', nlabel => 'memory.usage.percentage', set => { key_values => [ { name => 'usage' }, { name => 'display' } ], output_template => '%s %%', output_error_template => "%s", perfdatas => [ { label => 'used', value => 'usage_absolute', template => '%d', unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - } -}; + ]; +} + +sub prefix_memory_output { + my ($self, %options) = @_; + + return "Memory '" . $options{instance_value}->{display} . "' Usage "; +} 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 => - { - }); - - foreach my $key (('mem')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - + $options{options}->add_options(arguments => { + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('mem')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - $instance_mode = $self; -} - -sub run_instances { - my ($self, %options) = @_; - - my $multiple = 1; - if (scalar(keys %{$self->{mem}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All memory usages are ok'); - } - - foreach my $id (sort keys %{$self->{mem}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{mem}}) { - my $obj = $maps_counters->{mem}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{mem}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(level => 1, extra_instance => $multiple); - } - - my $prefix = "Memory Usage "; - if ($multiple == 1) { - $prefix = sprintf("Memory '%s' Usage ", $self->{mem}->{$id}->{display}); - } - $self->{output}->output_add(long_msg => "${prefix}$long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "${prefix}$short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "${prefix}$long_msg"); - } - } -} - -sub run { - my ($self, %options) = @_; - - $self->manage_selection(%options); - $self->run_instances(); - - $self->{output}->display(); - $self->{output}->exit(); -} - my $mapping = { sseries => { MemUsageUtil => { oid => '.1.3.6.1.4.1.6027.3.10.1.2.9.1.5' }, @@ -169,22 +79,26 @@ sub manage_selection { my ($self, %options) = @_; my $oids = { sseries => '.1.3.6.1.4.1.6027.3.10.1.2.9.1', mseries => '.1.3.6.1.4.1.6027.3.19.1.2.8.1', zseries => '.1.3.6.1.4.1.6027.3.25.1.2.3.1' }; - my $results = $options{snmp}->get_multiple_table(oids => [ { oid => $oids->{sseries} }, { oid => $oids->{mseries} }, { oid => $oids->{zseries} } ], - nothing_quit => 1); - $self->{mem} = {}; + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ { oid => $oids->{sseries} }, { oid => $oids->{mseries} }, { oid => $oids->{zseries} } ], + nothing_quit => 1 + ); + + $self->{memory} = {}; foreach my $name (keys %{$oids}) { - foreach my $oid (keys %{$results->{$oids->{$name}}}) { + foreach my $oid (keys %{$snmp_result->{$oids->{$name}}}) { next if ($oid !~ /^$mapping->{$name}->{MemUsageUtil}->{oid}\.(.*)/); my $instance = $1; - my $result = $options{snmp}->map_instance(mapping => $mapping->{$name}, results => $results->{$oids->{$name}}, instance => $instance); + my $result = $options{snmp}->map_instance(mapping => $mapping->{$name}, results => $snmp_result->{$oids->{$name}}, instance => $instance); - $self->{mem}->{$instance} = { display => $instance, - usage => $result->{MemUsageUtil}, - }; + $self->{memory}->{$instance} = { + display => $instance, + usage => $result->{MemUsageUtil}, + }; } } - if (scalar(keys %{$self->{mem}}) <= 0) { + if (scalar(keys %{$self->{memory}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No entry found."); $self->{output}->option_exit(); } diff --git a/centreon/common/fortinet/fortigate/mode/apusage.pm b/centreon/common/fortinet/fortigate/mode/apusage.pm new file mode 100644 index 000000000..16725dd75 --- /dev/null +++ b/centreon/common/fortinet/fortigate/mode/apusage.pm @@ -0,0 +1,268 @@ +# +# Copyright 2019 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 centreon::common::fortinet::fortigate::mode::apusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use Digest::MD5 qw(md5_hex); + +sub custom_status_output { + my ($self, %options) = @_; + my $msg = 'status : ' . $self->{result_values}->{status} . ' [admin: ' . $self->{result_values}->{admin} . ']'; + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{admin} = $options{new_datas}->{$self->{instance} . '_admin'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'ap', type => 1, cb_prefix_output => 'prefix_ap_output', message_multiple => 'All access points are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{ap} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'admin' }, { 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 => \&catalog_status_threshold, + } + }, + { label => 'in-traffic', set => { + key_values => [ { name => 'in', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'traffic in : %s %s/s', + perfdatas => [ + { label => 'traffic_in', value => 'in_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'out-traffic', set => { + key_values => [ { name => 'out', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'traffic out : %s %s/s', + perfdatas => [ + { label => 'traffic_out', value => 'out_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'clients', set => { + key_values => [ { name => 'clients' }, { name => 'display' } ], + output_template => 'current client connections : %s', + perfdatas => [ + { label => 'clients', value => 'clients_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'cpu', set => { + key_values => [ { name => 'cpu' }, { name => 'display' } ], + output_template => 'cpu usage : %.2f %%', + perfdatas => [ + { label => 'cpu', value => 'cpu_absolute', template => '%.2f', + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'memory', set => { + key_values => [ { name => 'memory' }, { name => 'display' } ], + output_template => 'memory usage : %.2f %%', + perfdatas => [ + { label => 'memory', value => 'memory_absolute', template => '%.2f', + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_ap_output { + my ($self, %options) = @_; + + return "Access point '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{admin} eq "enable" and %{status} !~ /online/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['unknown_status', 'warning_status', 'critical_status']); +} + +my %map_ap_admin = ( + 0 => 'other', 1 => 'discovered', 2 => 'disable', 3 => 'enable', +); + +my %map_ap_connect_status = ( + 0 => 'other', 1 => 'offLine', 2 => 'onLine', 3 => 'downloadingImage', 4 => 'connectedImage', +); + +my $mapping = { + fgWcWtpConfigWtpAdmin => { oid => '.1.3.6.1.4.1.12356.101.14.4.3.1.2', map => \%map_ap_admin }, + fgWcWtpConfigWtpName => { oid => '.1.3.6.1.4.1.12356.101.14.4.3.1.3' }, +}; + +my $mapping2 = { + fgWcWtpSessionConnectionState => { oid => '.1.3.6.1.4.1.12356.101.14.4.4.1.7', map => \%map_ap_connect_status }, + fgWcWtpSessionWtpStationCount => { oid => '.1.3.6.1.4.1.12356.101.14.4.4.1.17'}, + fgWcWtpSessionWtpByteRxCount => { oid => '.1.3.6.1.4.1.12356.101.14.4.4.1.18' }, + fgWcWtpSessionWtpByteTxCount => { oid => '.1.3.6.1.4.1.12356.101.14.4.4.1.19' }, + fgWcWtpSessionWtpCpuUsage => { oid => '.1.3.6.1.4.1.12356.101.14.4.4.1.20' }, + fgWcWtpSessionWtpMemoryUsage => { oid => '.1.3.6.1.4.1.12356.101.14.4.4.1.21' }, +}; +my $oid_fgWcWtpConfigEntry = '.1.3.6.1.4.1.12356.101.14.4.3.1'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table( + oid => $oid_fgWcWtpConfigEntry, + start => $mapping->{fgWcWtpConfigWtpAdmin}->{oid}, + end => $mapping->{fgWcWtpConfigWtpName}->{oid}, + nothing_quit => 1 + ); + + $self->{ap} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{fgWcWtpConfigWtpName}->{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->{fgWcWtpConfigWtpName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping access point '" . $result->{fgWcWtpConfigWtpName} . "'.", debug => 1); + next; + } + + $self->{ap}->{$instance} = { + display => $result->{fgWcWtpConfigWtpName}, + admin => $result->{fgWcWtpConfigWtpAdmin}, + status => 'n/a', + }; + } + + if (scalar(keys %{$self->{ap}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No access point found."); + $self->{output}->option_exit(); + } + + $options{snmp}->load( + oids => [ + $mapping2->{fgWcWtpSessionConnectionState}->{oid}, $mapping2->{fgWcWtpSessionWtpStationCount}->{oid}, + $mapping2->{fgWcWtpSessionWtpByteRxCount}->{oid}, $mapping2->{fgWcWtpSessionWtpByteTxCount}->{oid}, + $mapping2->{fgWcWtpSessionWtpCpuUsage}->{oid}, $mapping2->{fgWcWtpSessionWtpMemoryUsage}->{oid}, + ], + instances => [keys %{$self->{ap}}], + instance_regexp => '^(.*)$' + ); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{ap}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result, instance => $_); + + $self->{ap}->{$_}->{status} = $result->{fgWcWtpSessionConnectionState}; + $self->{ap}->{$_}->{in} = defined($result->{fgWcWtpSessionWtpByteRxCount}) ? ($result->{fgWcWtpSessionWtpByteRxCount} * 8) : undef; + $self->{ap}->{$_}->{out} = defined($result->{fgWcWtpSessionWtpByteTxCount}) ? ($result->{fgWcWtpSessionWtpByteTxCount} * 8) : undef; + $self->{ap}->{$_}->{clients} = $result->{fgWcWtpSessionWtpStationCount}; + $self->{ap}->{$_}->{cpu} = $result->{fgWcWtpSessionWtpCpuUsage}; + $self->{ap}->{$_}->{memory} = $result->{fgWcWtpSessionWtpMemoryUsage}; + } + + $self->{cache_name} = "fortigate_" . $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')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check access point usage. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'in-traffic', 'out-traffic', 'cpu' (%), 'memory' (%), +'clients'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'in-traffic', 'out-traffic', 'cpu' (%), 'memory' (%), +'clients'. + +=item B<--filter-name> + +Filter by access point name (can be a regexp). + +=item B<--unknown-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{admin}, %{status}, %{display} + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{admin}, %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{admin} eq "enable" and %{status} !~ /online/i''). +Can used special variables like: %{admin}, %{status}, %{display} + +=back + +=cut diff --git a/centreon/common/fortinet/fortigate/mode/clusterstatus.pm b/centreon/common/fortinet/fortigate/mode/clusterstatus.pm index 868e88870..3fb5a7bf9 100644 --- a/centreon/common/fortinet/fortigate/mode/clusterstatus.pm +++ b/centreon/common/fortinet/fortigate/mode/clusterstatus.pm @@ -90,6 +90,15 @@ sub set_counters { { name => 'nodes', type => 1, cb_prefix_output => 'prefix_status_output', message_multiple => 'All cluster nodes status are ok' }, ]; $self->{maps_counters}->{global} = [ + { label => 'total-nodes', display_ok => 0, set => { + key_values => [ { name => 'total_nodes' } ], + output_template => 'Total nodes: %d', + perfdatas => [ + { label => 'total_nodes', value => 'total_nodes_absolute', template => '%d', + min => 0 }, + ], + } + }, { label => 'synchronized', set => { key_values => [ { name => 'synchronized' } ], output_template => 'Synchronized: %d', @@ -182,7 +191,7 @@ sub manage_selection { $self->{results} = $options{snmp}->get_table(oid => $oid_fgHaStatsEntry, nothing_quit => 1); - $self->{global} = { synchronized => 0, not_synchronized => 0 }; + $self->{global} = { synchronized => 0, not_synchronized => 0, total_nodes => 0 }; foreach my $oid (keys %{$self->{results}}) { next if ($oid !~ /^$mapping->{fgHaStatsSerial}->{oid}\.(.*)$/); @@ -198,6 +207,7 @@ sub manage_selection { }; $result->{fgHaStatsSyncStatus} =~ s/ /_/; $self->{global}->{$result->{fgHaStatsSyncStatus}}++; + $self->{global}->{total_nodes}++; } if (scalar(keys %{$self->{nodes}}) <= 0) { @@ -219,12 +229,12 @@ Check cluster status (FORTINET-FORTIGATE-MIB). =item B<--warning-*> Set warning thresholds. -Can be: 'synchronized', 'not-synchronized' +Can be: 'total-nodes', 'synchronized', 'not-synchronized'. =item B<--critical-*> Set critical thresholds. -Can be: 'synchronized', 'not-synchronized' +Can be: 'total-nodes', 'synchronized', 'not-synchronized'. =item B<--warning-status> diff --git a/centreon/common/fortinet/fortigate/mode/ipsstats.pm b/centreon/common/fortinet/fortigate/mode/ipsstats.pm index 2dc39d621..70dfccbe5 100644 --- a/centreon/common/fortinet/fortigate/mode/ipsstats.pm +++ b/centreon/common/fortinet/fortigate/mode/ipsstats.pm @@ -20,207 +20,123 @@ package centreon::common::fortinet::fortigate::mode::ipsstats; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); -my $maps_counters = { - '000_intrusions-detected' => { set => { - key_values => [ { name => 'fgIpsIntrusionsDetected', diff => 1 }, { name => 'display' } ], - output_template => 'Intrusions detected : %s', - perfdatas => [ - { label => 'intrusions_detected', value => 'fgIpsIntrusionsDetected_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '001_intrusions-blocked' => { set => { - key_values => [ { name => 'fgIpsIntrusionsBlocked', diff => 1 }, { name => 'display' } ], - output_template => 'Intrusions blocked : %s', - perfdatas => [ - { label => 'intrusions_blocked', value => 'fgIpsIntrusionsBlocked_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '002_crit-sev-detections' => { set => { - key_values => [ { name => 'fgIpsCritSevDetections', diff => 1 }, { name => 'display' } ], - output_template => 'Critical severity intrusions detected : %s', - perfdatas => [ - { label => 'crit_sev_detections', value => 'fgIpsCritSevDetections_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '003_high-sev-detections' => { set => { - key_values => [ { name => 'fgIpsHighSevDetections', diff => 1 }, { name => 'display' } ], - output_template => 'High severity intrusions detected : %s', - perfdatas => [ - { label => 'high_sev_detections', value => 'fgIpsHighSevDetections_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '004_med-sev-detections' => { set => { - key_values => [ { name => 'fgIpsMedSevDetections', diff => 1 }, { name => 'display' } ], - output_template => 'Medium severity intrusions detected : %s', - perfdatas => [ - { label => 'med_sev_detections', value => 'fgIpsMedSevDetections_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '005_low-sev-detections' => { set => { - key_values => [ { name => 'fgIpsLowSevDetections', diff => 1 }, { name => 'display' } ], - output_template => 'Low severity intrusions detected : %s', - perfdatas => [ - { label => 'low_sev_detections', value => 'fgIpsLowSevDetections_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '006_info-sev-detections' => { set => { - key_values => [ { name => 'fgIpsInfoSevDetections', diff => 1 }, { name => 'display' } ], - output_template => 'Informational severity intrusions detected : %s', - perfdatas => [ - { label => 'info_sev_detections', value => 'fgIpsInfoSevDetections_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '007_signature-detections' => { set => { - key_values => [ { name => 'fgIpsSignatureDetections', diff => 1 }, { name => 'display' } ], - output_template => 'Signature intrusions detected : %s', - perfdatas => [ - { label => 'signature_detection', value => 'fgIpsSignatureDetections_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '008_anomaly-detections' => { set => { - key_values => [ { name => 'fgIpsAnomalyDetections', diff => 1 }, { name => 'display' } ], - output_template => 'Anomaly intrusions detected : %s', - perfdatas => [ - { label => 'anomaly_detections', value => 'fgIpsAnomalyDetections_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'domain', type => 1, cb_prefix_output => 'prefix_domain_output', message_multiple => 'All IPS domain statistics are ok' } + ]; + + $self->{maps_counters}->{domain} = [ + { label => 'intrusions-detected', nlabel => 'domain.intrusions.detected.count', set => { + key_values => [ { name => 'fgIpsIntrusionsDetected', diff => 1 }, { name => 'display' } ], + output_template => 'Intrusions detected : %s', + perfdatas => [ + { label => 'intrusions_detected', value => 'fgIpsIntrusionsDetected_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'intrusions-blocked', nlabel => 'domain.intrusions.blocked.count', set => { + key_values => [ { name => 'fgIpsIntrusionsBlocked', diff => 1 }, { name => 'display' } ], + output_template => 'Intrusions blocked : %s', + perfdatas => [ + { label => 'intrusions_blocked', value => 'fgIpsIntrusionsBlocked_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'crit-sev-detections', nlabel => 'domain.intrusions.detected.critical.severity.count', set => { + key_values => [ { name => 'fgIpsCritSevDetections', diff => 1 }, { name => 'display' } ], + output_template => 'Critical severity intrusions detected : %s', + perfdatas => [ + { label => 'crit_sev_detections', value => 'fgIpsCritSevDetections_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'high-sev-detections', nlabel => 'domain.intrusions.detected.high.severity.count', set => { + key_values => [ { name => 'fgIpsHighSevDetections', diff => 1 }, { name => 'display' } ], + output_template => 'High severity intrusions detected : %s', + perfdatas => [ + { label => 'high_sev_detections', value => 'fgIpsHighSevDetections_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'med-sev-detections', nlabel => 'domain.intrusions.detected.medium.severity.count', set => { + key_values => [ { name => 'fgIpsMedSevDetections', diff => 1 }, { name => 'display' } ], + output_template => 'Medium severity intrusions detected : %s', + perfdatas => [ + { label => 'med_sev_detections', value => 'fgIpsMedSevDetections_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'low-sev-detections', nlabel => 'domain.intrusions.detected.low.severity.count', set => { + key_values => [ { name => 'fgIpsLowSevDetections', diff => 1 }, { name => 'display' } ], + output_template => 'Low severity intrusions detected : %s', + perfdatas => [ + { label => 'low_sev_detections', value => 'fgIpsLowSevDetections_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'info-sev-detections', nlabel => 'domain.intrusions.detected.info.severity.count', set => { + key_values => [ { name => 'fgIpsInfoSevDetections', diff => 1 }, { name => 'display' } ], + output_template => 'Informational severity intrusions detected : %s', + perfdatas => [ + { label => 'info_sev_detections', value => 'fgIpsInfoSevDetections_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'signature-detections', nlabel => 'domain.intrusions.detected.signature.count', set => { + key_values => [ { name => 'fgIpsSignatureDetections', diff => 1 }, { name => 'display' } ], + output_template => 'Signature intrusions detected : %s', + perfdatas => [ + { label => 'signature_detection', value => 'fgIpsSignatureDetections_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'anomaly-detections', nlabel => 'domain.intrusions.detected.anomaly.count', set => { + key_values => [ { name => 'fgIpsAnomalyDetections', diff => 1 }, { name => 'display' } ], + output_template => 'Anomaly intrusions detected : %s', + perfdatas => [ + { label => 'anomaly_detections', value => 'fgIpsAnomalyDetections_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_domain_output { + my ($self, %options) = @_; + + return "Domain '" . $options{instance_value}->{display} . "' "; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); - foreach (keys %{$maps_counters}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$_}->{threshold}) || $maps_counters->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$_}->{obj} = centreon::plugins::values->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{domain_selected}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All IPS domain statistics are ok'); - } - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "fortinet_fortigate_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('.*'))); - $self->{new_datas}->{last_timestamp} = time(); - - foreach my $id (sort keys %{$self->{domain_selected}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => $id); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{domain_selected}->{$id}, - new_datas => $self->{new_datas}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{$_}->{obj}->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Domain '" . $self->{domain_selected}->{$id}->{display} . "' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Domain '" . $self->{domain_selected}->{$id}->{display} . "' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Domain '" . $self->{domain_selected}->{$id}->{display} . "' $long_msg"); - } - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - my $mapping = { fgIpsIntrusionsDetected => { oid => '.1.3.6.1.4.1.12356.101.9.2.1.1.1' }, fgIpsIntrusionsBlocked => { oid => '.1.3.6.1.4.1.12356.101.9.2.1.1.2' }, @@ -238,32 +154,39 @@ my $oid_fgVdEntName = '.1.3.6.1.4.1.12356.101.3.2.1.1.2'; sub manage_selection { my ($self, %options) = @_; - $self->{domain_selected} = {}; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_fgVdEntName}, - { oid => $oid_fgIpsStatsEntry}, - ], - nothing_quit => 1); - foreach my $oid (keys %{$self->{results}->{$oid_fgVdEntName}}) { + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oid_fgVdEntName}, + { oid => $oid_fgIpsStatsEntry}, + ], + nothing_quit => 1 + ); + + $self->{domain} = {}; + foreach my $oid (keys %{$snmp_result->{$oid_fgVdEntName}}) { next if ($oid !~ /^$oid_fgVdEntName\.(.*)/); my $instance = $1; if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $self->{results}->{$oid_fgVdEntName}->{$oid} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $self->{results}->{$oid_fgVdEntName}->{$oid} . "': no matching filter."); + $snmp_result->{$oid_fgVdEntName}->{$oid} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $snmp_result->{$oid_fgVdEntName}->{$oid} . "': no matching filter."); next; } - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_fgIpsStatsEntry}, instance => $instance); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result->{$oid_fgIpsStatsEntry}, instance => $instance); - $self->{domain_selected}->{$instance} = $result; - $self->{domain_selected}->{$instance}->{display} = $self->{results}->{$oid_fgVdEntName}->{$oid}; + $self->{domain}->{$instance} = $result; + $self->{domain}->{$instance}->{display} = $snmp_result->{$oid_fgVdEntName}->{$oid}; } - if (scalar(keys %{$self->{domain_selected}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No entry found."); + if (scalar(keys %{$self->{domain}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No domain found."); $self->{output}->option_exit(); } + + $self->{cache_name} = "fortinet_fortigate_" . $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')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); } 1; diff --git a/centreon/common/fortinet/fortigate/mode/vdomcpu.pm b/centreon/common/fortinet/fortigate/mode/vdomcpu.pm index 3afb668a7..b664cde2f 100644 --- a/centreon/common/fortinet/fortigate/mode/vdomcpu.pm +++ b/centreon/common/fortinet/fortigate/mode/vdomcpu.pm @@ -89,7 +89,7 @@ sub manage_selection { if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $result->{fgVdEntName} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter name.", debug => 1); + $self->{output}->output_add(long_msg => "skipping '" . $result->{fgVdEntName} . "': no matching filter name.", debug => 1); next; } diff --git a/centreon/common/fortinet/fortigate/mode/vdommemory.pm b/centreon/common/fortinet/fortigate/mode/vdommemory.pm index e2d00a028..89d03ad6c 100644 --- a/centreon/common/fortinet/fortigate/mode/vdommemory.pm +++ b/centreon/common/fortinet/fortigate/mode/vdommemory.pm @@ -89,7 +89,7 @@ sub manage_selection { if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $result->{fgVdEntName} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter name.", debug => 1); + $self->{output}->output_add(long_msg => "skipping '" . $result->{fgVdEntName} . "': no matching filter name.", debug => 1); next; } diff --git a/centreon/common/fortinet/fortigate/mode/vdomsession.pm b/centreon/common/fortinet/fortigate/mode/vdomsession.pm index 1195459f8..b3d9acfa2 100644 --- a/centreon/common/fortinet/fortigate/mode/vdomsession.pm +++ b/centreon/common/fortinet/fortigate/mode/vdomsession.pm @@ -99,7 +99,7 @@ sub manage_selection { if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $result->{fgVdEntName} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter name.", debug => 1); + $self->{output}->output_add(long_msg => "skipping '" . $result->{fgVdEntName} . "': no matching filter name.", debug => 1); next; } diff --git a/centreon/common/fortinet/fortigate/mode/vdomstate.pm b/centreon/common/fortinet/fortigate/mode/vdomstate.pm index e38cf3bf8..7f9b775d9 100644 --- a/centreon/common/fortinet/fortigate/mode/vdomstate.pm +++ b/centreon/common/fortinet/fortigate/mode/vdomstate.pm @@ -120,7 +120,7 @@ sub manage_selection { if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $result->{fgVdEntName} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter name.", debug => 1); + $self->{output}->output_add(long_msg => "skipping '" . $result->{fgVdEntName} . "': no matching filter name.", debug => 1); next; } diff --git a/centreon/common/h3c/snmp/mode/components/sensor.pm b/centreon/common/h3c/snmp/mode/components/sensor.pm index 4e6c379c0..39c4c3850 100644 --- a/centreon/common/h3c/snmp/mode/components/sensor.pm +++ b/centreon/common/h3c/snmp/mode/components/sensor.pm @@ -97,12 +97,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature sensor '%s' is %s degree centigrade", $name, $result2->{EntityExtTemperature})); } - $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', - value => $result2->{EntityExtTemperature}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.sensor.temperature.celsius', + instances => $instance, + value => $result2->{EntityExtTemperature}, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1; diff --git a/centreon/common/h3c/snmp/mode/cpu.pm b/centreon/common/h3c/snmp/mode/cpu.pm index ab44a38f3..d10c70663 100644 --- a/centreon/common/h3c/snmp/mode/cpu.pm +++ b/centreon/common/h3c/snmp/mode/cpu.pm @@ -20,32 +20,37 @@ package centreon::common::h3c::snmp::mode::cpu; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; use centreon::plugins::statefile; -my $oid_entPhysicalEntry = '.1.3.6.1.2.1.47.1.1.1.1'; -my $oid_entPhysicalDescr = '.1.3.6.1.2.1.47.1.1.1.1.2'; -my $oid_entPhysicalContainedIn = '.1.3.6.1.2.1.47.1.1.1.1.4'; -my $oid_entPhysicalClass = '.1.3.6.1.2.1.47.1.1.1.1.5'; -my $oid_entPhysicalName = '.1.3.6.1.2.1.47.1.1.1.1.7'; - -my $maps_counters = { - cpu => { - '000_usage' => { set => { - key_values => [ { name => 'EntityExtCpuUsage' }, { name => 'num' }, ], - output_template => ' : %.2f %%', - perfdatas => [ - { label => 'cpu', value => 'EntityExtCpuUsage_absolute', template => '%.2f', - min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'num_absolute' }, - ], - } - }, +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'cpu', type => 1, cb_prefix_output => 'prefix_cpu_output', message_multiple => 'All CPU usages are ok' } + ]; + + $self->{maps_counters}->{cpu} = [ + { label => 'usage', nlabel => 'cpu.utilization.percentage', set => { + key_values => [ { name => 'EntityExtCpuUsage' }, { name => 'num' }, ], + output_template => ' : %.2f %%', + perfdatas => [ + { label => 'cpu', value => 'EntityExtCpuUsage_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'num_absolute' }, + ], + } }, -}; + ]; +} + +sub prefix_cpu_output { + my ($self, %options) = @_; + + return "CPU '" . $options{instance_value}->{num} . "' Usage "; +} sub new { my ($class, %options) = @_; @@ -53,106 +58,27 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "reload-cache-time:s" => { name => 'reload_cache_time', default => 180 }, - "display-entity-name" => { name => 'display_entity_name' }, - }); + $options{options}->add_options(arguments => { + "reload-cache-time:s" => { name => 'reload_cache_time', default => 180 }, + "display-entity-name" => { name => 'display_entity_name' }, + }); - foreach my $key (('cpu')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - $self->{statefile_cache} = centreon::plugins::statefile->new(%options); - return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('cpu')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } + $self->SUPER::check_options(%options); $self->{statefile_cache}->check_options(%options); } -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{cpu}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All CPU usages are ok'); - } - - foreach my $id (sort keys %{$self->{cpu}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{cpu}}) { - my $obj = $maps_counters->{cpu}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{cpu}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{cpu}->{$_}->{obj}->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "CPU '" . $self->{cpu}->{$id}->{num} . "' Usage $long_msg [entity = '" . $self->{cpu}->{$id}->{name} . "']"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "CPU '" . $self->{cpu}->{$id}->{num} . "' Usage $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "CPU '" . $self->{cpu}->{$id}->{num} . "' Usage $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} +my $oid_entPhysicalEntry = '.1.3.6.1.2.1.47.1.1.1.1'; +my $oid_entPhysicalDescr = '.1.3.6.1.2.1.47.1.1.1.1.2'; +my $oid_entPhysicalContainedIn = '.1.3.6.1.2.1.47.1.1.1.1.4'; +my $oid_entPhysicalClass = '.1.3.6.1.2.1.47.1.1.1.1.5'; +my $oid_entPhysicalName = '.1.3.6.1.2.1.47.1.1.1.1.7'; sub check_cache { my ($self, %options) = @_; @@ -203,7 +129,8 @@ sub get_long_name { sub manage_selection { my ($self, %options) = @_; - + + $self->{snmp} = $options{snmp}; my $oid_h3cEntityExtCpuUsage = '.1.3.6.1.4.1.2011.10.2.6.1.1.1.1.6'; my $oid_hh3cEntityExtCpuUsage = '.1.3.6.1.4.1.25506.2.6.1.1.1.1.6'; $self->{snmp_request} = [ diff --git a/centreon/common/h3c/snmp/mode/memory.pm b/centreon/common/h3c/snmp/mode/memory.pm index cc0ce1b30..c605ff525 100644 --- a/centreon/common/h3c/snmp/mode/memory.pm +++ b/centreon/common/h3c/snmp/mode/memory.pm @@ -20,59 +20,42 @@ package centreon::common::h3c::snmp::mode::memory; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; use centreon::plugins::statefile; -my $oid_entPhysicalEntry = '.1.3.6.1.2.1.47.1.1.1.1'; -my $oid_entPhysicalDescr = '.1.3.6.1.2.1.47.1.1.1.1.2'; -my $oid_entPhysicalContainedIn = '.1.3.6.1.2.1.47.1.1.1.1.4'; -my $oid_entPhysicalClass = '.1.3.6.1.2.1.47.1.1.1.1.5'; -my $oid_entPhysicalName = '.1.3.6.1.2.1.47.1.1.1.1.7'; - -my $maps_counters = { - '000_usage' => { set => { - key_values => [ - { name => 'display' }, { name => 'used_prct' }, { name => 'total' }, - ], - closure_custom_calc => \&custom_usage_calc, - closure_custom_output => \&custom_usage_output, - closure_custom_perfdata => \&custom_usage_perfdata, - closure_custom_threshold_check => \&custom_usage_threshold, - } - }, -}; - sub custom_usage_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - + if ($self->{result_values}->{total} == 4294967295) { - $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => '%', - value => $self->{result_values}->{prct_used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}), - min => 0, max => 100); + $self->{output}->perfdata_add( + label => 'used', unit => '%', + nlabel => 'memory.usage.percentage', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{prct_used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0, max => 100 + ); } else { - $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', - value => int($self->{result_values}->{used}), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + nlabel => $self->{nlabel}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => int($self->{result_values}->{used}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } } sub custom_usage_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -108,108 +91,58 @@ sub custom_usage_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 1, cb_prefix_output => 'prefix_memory_output', message_multiple => 'All memory usages are ok' } + ]; + + $self->{maps_counters}->{memory} = [ + { label => 'usage', nlabel => 'memory.usage.bytes', set => { + key_values => [ { name => 'display' }, { name => 'used_prct' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +sub prefix_memory_output { + my ($self, %options) = @_; + + return "Memory '" . $options{instance_value}->{display} . "' "; +} + 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 => - { - "reload-cache-time:s" => { name => 'reload_cache_time', default => 180 }, - "display-entity-name" => { name => 'display_entity_name' }, - }); - - foreach (keys %{$maps_counters}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$_}->{threshold}) || $maps_counters->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - + $options{options}->add_options(arguments => { + "reload-cache-time:s" => { name => 'reload_cache_time', default => 180 }, + "display-entity-name" => { name => 'display_entity_name' }, + }); + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); - return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->SUPER::check_options(%options); - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - $self->{statefile_cache}->check_options(%options); } -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{memory_selected}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All memory usages are ok'); - } - - foreach my $id (sort keys %{$self->{memory_selected}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => $id); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{memory_selected}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{$_}->{obj}->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Memory '" . $self->{memory_selected}->{$id}->{display} . "' $long_msg [entity = '" . $self->{memory_selected}->{$id}->{name} . "']"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Memory '" . $self->{memory_selected}->{$id}->{display} . "' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Memory '" . $self->{memory_selected}->{$id}->{display} . "' $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} - +my $oid_entPhysicalEntry = '.1.3.6.1.2.1.47.1.1.1.1'; +my $oid_entPhysicalDescr = '.1.3.6.1.2.1.47.1.1.1.1.2'; +my $oid_entPhysicalContainedIn = '.1.3.6.1.2.1.47.1.1.1.1.4'; +my $oid_entPhysicalClass = '.1.3.6.1.2.1.47.1.1.1.1.5'; +my $oid_entPhysicalName = '.1.3.6.1.2.1.47.1.1.1.1.7'; sub check_cache { my ($self, %options) = @_; @@ -261,6 +194,7 @@ sub get_long_name { sub manage_selection { my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; my $oid_h3cEntityExtStateEntry = '.1.3.6.1.4.1.2011.10.2.6.1.1.1.1'; my $oid_hh3cEntityExtStateEntry = '.1.3.6.1.4.1.25506.2.6.1.1.1.1'; my $oid_hh3cEntityExtMemUsage = '.1.3.6.1.4.1.25506.2.6.1.1.1.1.8'; @@ -291,7 +225,7 @@ sub manage_selection { EntityExtMemSize => { oid => $self->{branch} . '.10' }, }; - $self->{memory_selected} = {}; + $self->{memory} = {}; foreach my $oid (keys %{$self->{results}->{$self->{branch} . '.8'}}) { next if ($oid !~ /^$self->{branch}\.8\.(\d+)/); my $instance = $1; @@ -304,12 +238,15 @@ sub manage_selection { if (defined($self->{option_results}->{display_entity_name})) { $name = $self->get_long_name(instance => $instance); } - $self->{memory_selected}->{$instance} = { display => $instance, name => $name, - used_prct => $result->{EntityExtMemUsage}, total => $result2->{EntityExtMemSize}}; + $self->{memory}->{$instance} = { + display => $instance, name => $name, + used_prct => $result->{EntityExtMemUsage}, + total => $result2->{EntityExtMemSize} + }; } } - if (scalar(keys %{$self->{memory_selected}}) <= 0) { + if (scalar(keys %{$self->{memory}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No entry found."); $self->{output}->option_exit(); } diff --git a/centreon/common/jvm/mode/memory.pm b/centreon/common/jvm/mode/memory.pm index f2343a518..5b5591cce 100644 --- a/centreon/common/jvm/mode/memory.pm +++ b/centreon/common/jvm/mode/memory.pm @@ -55,17 +55,15 @@ sub set_counters { ]; } -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $use_th = 1; - $use_th = 0 if ($instance_mode->{option_results}->{units} eq '%' && $self->{result_values}->{max} <= 0); + $use_th = 0 if ($self->{instance_mode}->{option_results}->{units} eq '%' && $self->{result_values}->{max} <= 0); my $value_perf = $self->{result_values}->{used}; my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%' && $self->{result_values}->{max} > 0) { + if ($self->{instance_mode}->{option_results}->{units} eq '%' && $self->{result_values}->{max} > 0) { $total_options{total} = $self->{result_values}->{max}; $total_options{cast_int} = 1; } @@ -81,10 +79,10 @@ sub custom_usage_threshold { my ($self, %options) = @_; # Cannot use percent without total - return 'ok' if ($self->{result_values}->{max} <= 0 && $instance_mode->{option_results}->{units} eq '%'); + return 'ok' if ($self->{result_values}->{max} <= 0 && $self->{instance_mode}->{option_results}->{units} eq '%'); my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); @@ -130,18 +128,11 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "units:s" => { name => 'units', default => '%' }, - }); - return $self; -} + $options{options}->add_options(arguments => { + "units:s" => { name => 'units', default => '%' }, + }); -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; + return $self; } sub manage_selection { diff --git a/centreon/common/jvm/mode/memorydetailed.pm b/centreon/common/jvm/mode/memorydetailed.pm index 3581ce832..a97977c25 100644 --- a/centreon/common/jvm/mode/memorydetailed.pm +++ b/centreon/common/jvm/mode/memorydetailed.pm @@ -44,8 +44,6 @@ my %mapping_memory = ( 'Tenured Gen' => 'tenured', ); -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -101,11 +99,11 @@ sub custom_usage_perfdata { my ($self, %options) = @_; my $use_th = 1; - $use_th = 0 if ($instance_mode->{option_results}->{units} eq '%' && $self->{result_values}->{max} <= 0); + $use_th = 0 if ($self->{instance_mode}->{option_results}->{units} eq '%' && $self->{result_values}->{max} <= 0); my $value_perf = $self->{result_values}->{used}; my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%' && $self->{result_values}->{max} > 0) { + if ($self->{instance_mode}->{option_results}->{units} eq '%' && $self->{result_values}->{max} > 0) { $total_options{total} = $self->{result_values}->{max}; $total_options{cast_int} = 1; } @@ -121,10 +119,10 @@ sub custom_usage_threshold { my ($self, %options) = @_; # Cannot use percent without total - return 'ok' if ($self->{result_values}->{max} <= 0 && $instance_mode->{option_results}->{units} eq '%'); + return 'ok' if ($self->{result_values}->{max} <= 0 && $self->{instance_mode}->{option_results}->{units} eq '%'); my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); @@ -177,18 +175,11 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "units:s" => { name => 'units', default => '%' }, - }); - return $self; -} + $options{options}->add_options(arguments => { + "units:s" => { name => 'units', default => '%' }, + }); -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; + return $self; } sub manage_selection { diff --git a/centreon/common/powershell/exchange/2010/imapmailbox.pm b/centreon/common/powershell/exchange/2010/imapmailbox.pm index bcdcd9e64..92b494f30 100644 --- a/centreon/common/powershell/exchange/2010/imapmailbox.pm +++ b/centreon/common/powershell/exchange/2010/imapmailbox.pm @@ -120,4 +120,4 @@ __END__ Method to check Exchange 2010 imap on a specific mailbox. -=cut \ No newline at end of file +=cut diff --git a/centreon/common/powershell/exchange/2010/outlookwebservices.pm b/centreon/common/powershell/exchange/2010/outlookwebservices.pm index 47bd736ce..336e0c03f 100644 --- a/centreon/common/powershell/exchange/2010/outlookwebservices.pm +++ b/centreon/common/powershell/exchange/2010/outlookwebservices.pm @@ -36,8 +36,23 @@ sub get_powershell { $ps .= ' try { - $ErrorActionPreference = "Stop" + $ErrorActionPreference = "Stop" +'; + if (defined($options{password}) && $options{password} ne '') { + $ps .= ' + $username = "' . $options{mailbox} . '" + $password = "' . $options{password} . '" + $secstr = New-Object -TypeName System.Security.SecureString + $password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)} + $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr + $results = Test-OutlookWebServices -WarningAction:SilentlyContinue -MailboxCredential $cred +'; + } else { + $ps .= ' $results = Test-OutlookWebServices -WarningAction:SilentlyContinue -Identity "' . $options{mailbox} . '" +'; + } + $ps .= ' } catch { Write-Host $Error[0].Exception exit 1 @@ -107,4 +122,4 @@ __END__ Method to check Exchange 2010 outlook autodiscovery webservices. -=cut \ No newline at end of file +=cut diff --git a/centreon/common/powershell/exchange/2010/queues.pm b/centreon/common/powershell/exchange/2010/queues.pm index a1485d898..b663ed2d9 100644 --- a/centreon/common/powershell/exchange/2010/queues.pm +++ b/centreon/common/powershell/exchange/2010/queues.pm @@ -44,7 +44,7 @@ try { } Foreach ($result in $results) { - Write-Host "[identity=" $result.Identity "][deliverytype=" $result.DeliveryType "][status=" $result.Status "][isvalid=" $result.IsValid "][messagecount=" $result.MessageCount "][[error=" $result.LastError "]]" + Write-Host "[identity=" $result.Identity "][nexthopdomain=" $result.NextHopDomain "][deliverytype=" $result.DeliveryType "][status=" $result.Status "][isvalid=" $result.IsValid "][messagecount=" $result.MessageCount "][[error=" $result.LastError "]]" } exit 0 '; @@ -57,7 +57,7 @@ sub check { # options: stdout # Following output: - #[identity= ][deliverytype= SmtpRelayWithinAdSite][status= Active ][isvalid= Yes][messagecount= 1 ][[error=...]] + #[identity= ][nexthopdomain= xxxx][deliverytype= SmtpRelayWithinAdSite][status= Active ][isvalid= Yes][messagecount= 1 ][[error=...]] $self->{output}->output_add(severity => 'OK', short_msg => "All Queues are ok."); @@ -65,11 +65,11 @@ sub check { $self->{output}->output_add(long_msg => $options{stdout}); $self->{perfdatas_queues} = {}; - while ($options{stdout} =~ /\[identity=(.*?)\]\[deliverytype=(.*?)\]\[status=(.*?)\]\[isvalid=(.*?)\]\[messagecount=(.*?)\]\[\[error=(.*?)\]\]/msg) { + while ($options{stdout} =~ /\[identity=(.*?)\]\[nexthopdomain=(.*?)\]\[deliverytype=(.*?)\]\[status=(.*?)\]\[isvalid=(.*?)\]\[messagecount=(.*?)\]\[\[error=(.*?)\]\]/msg) { $self->{data} = {}; - ($self->{data}->{identity}, $self->{data}->{deliverytype}, $self->{data}->{status}, $self->{data}->{isvalid}, $self->{data}->{messagecount}, $self->{data}->{error}) = + ($self->{data}->{identity}, $self->{data}->{nexthopdomain}, $self->{data}->{deliverytype}, $self->{data}->{status}, $self->{data}->{isvalid}, $self->{data}->{messagecount}, $self->{data}->{error}) = ($self->{output}->to_utf8($1), centreon::plugins::misc::trim($2), - centreon::plugins::misc::trim($3), centreon::plugins::misc::trim($4), centreon::plugins::misc::trim($5), centreon::plugins::misc::trim($6)); + centreon::plugins::misc::trim($3), centreon::plugins::misc::trim($4), centreon::plugins::misc::trim($5), centreon::plugins::misc::trim($6), centreon::plugins::misc::trim($7)); $checked++; @@ -92,7 +92,7 @@ sub check { if (!$self->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $status, short_msg => sprintf("Queue '%s' status is '%s' [last error: %s]", - $self->{data}->{identity}, $self->{data}->{status}, $self->{data}->{error})); + $self->{data}->{nexthopdomain}, $self->{data}->{status}, $self->{data}->{error})); } if ($self->{data}->{messagecount} =~ /^(\d+)/) { @@ -125,4 +125,4 @@ __END__ Method to check Exchange 2010 queues. -=cut \ No newline at end of file +=cut diff --git a/centreon/common/powershell/functions.pm b/centreon/common/powershell/functions.pm new file mode 100644 index 000000000..be383e0eb --- /dev/null +++ b/centreon/common/powershell/functions.pm @@ -0,0 +1,122 @@ +# +# Copyright 2019 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 centreon::common::powershell::functions; + +use strict; +use warnings; + +sub escape_jsonstring { + my (%options) = @_; + + my $ps = q{ +function Escape-JSONString($str) { + if ($str -eq $null) {return ""} + $str = $str.ToString().Replace('"','\"').Replace('\','\\').Replace("`n",'\n').Replace("`r",'\r').Replace("`t",'\t') + return $str; +} +}; + + return $ps; +} + +sub convert_to_json { + my (%options) = @_; + + my $ps = q{ +function ConvertTo-JSON-20($maxDepth = 4,$forceArray = $false) { + begin { + $data = @() + } + process{ + $data += $_ + } + + end{ + if ($data.length -eq 1 -and $forceArray -eq $false) { + $value = $data[0] + } else { + $value = $data + } + + if ($value -eq $null) { + return "null" + } + + $dataType = $value.GetType().Name + + switch -regex ($dataType) { + 'String' { + return "`"{0}`"" -f (Escape-JSONString $value ) + } + '(System\.)?DateTime' {return "`"{0:yyyy-MM-dd}T{0:HH:mm:ss}`"" -f $value} + 'Int32|Double' {return "$value"} + 'Boolean' {return "$value".ToLower()} + '(System\.)?Object\[\]' { # array + + if ($maxDepth -le 0){return "`"$value`""} + + $jsonResult = '' + foreach($elem in $value){ + #if ($elem -eq $null) {continue} + if ($jsonResult.Length -gt 0) {$jsonResult +=','} + $jsonResult += ($elem | ConvertTo-JSON-20 -maxDepth ($maxDepth -1)) + } + return "[" + $jsonResult + "]" + } + '(System\.)?Hashtable' { # hashtable + $jsonResult = '' + foreach($key in $value.Keys){ + if ($jsonResult.Length -gt 0) {$jsonResult +=','} + $jsonResult += +@" +"{0}":{1} +"@ -f $key , ($value[$key] | ConvertTo-JSON-20 -maxDepth ($maxDepth -1) ) + } + return "{" + $jsonResult + "}" + } + default { #object + if ($maxDepth -le 0){return "`"{0}`"" -f (Escape-JSONString $value)} + + return "{" + + (($value | Get-Member -MemberType *property | % { +@" +"{0}":{1} +"@ -f $_.Name , ($value.($_.Name) | ConvertTo-JSON-20 -maxDepth ($maxDepth -1) ) + + }) -join ',') + "}" + } + } + } +} +}; + + return $ps; +} + +1; + +__END__ + +=head1 DESCRIPTION + +Powershell common functions. + +=cut diff --git a/centreon/common/powershell/sccm/databasereplicationstatus.pm b/centreon/common/powershell/sccm/databasereplicationstatus.pm new file mode 100644 index 000000000..5f830cb97 --- /dev/null +++ b/centreon/common/powershell/sccm/databasereplicationstatus.pm @@ -0,0 +1,97 @@ +# +# Copyright 2019 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 centreon::common::powershell::sccm::databasereplicationstatus; + +use strict; +use warnings; +use centreon::common::powershell::functions; + +sub get_powershell { + my (%options) = @_; + my $no_ps = (defined($options{no_ps})) ? 1 : 0; + + return '' if ($no_ps == 1); + + my $ps = ' +$culture = new-object "System.Globalization.CultureInfo" "en-us" +[System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture +'; + + $ps .= centreon::common::powershell::functions::escape_jsonstring(%options); + $ps .= centreon::common::powershell::functions::convert_to_json(%options); + + $ps .= ' +$ProgressPreference = "SilentlyContinue" + +Try { + $ErrorActionPreference = "Stop" + + $modulePath = ${env:SMS_ADMIN_UI_PATH} + $modulePath = $modulePath.Substring(0, $modulePath.lastIndexOf("\")) + $module = $modulePath + "\ConfigurationManager.psd1" + Import-Module $module + + New-PSDrive -Name SCCMDrive -PSProvider "AdminUI.PS.Provider\CMSite" -Root $env:COMPUTERNAME -Description "SCCM Site" | Out-Null + CD "SCCMDrive:\" + + $CMObject = Get-CMDatabaseReplicationStatus + + CD "C:\" + Remove-PSDrive -Name SCCMDrive + + $returnObject = New-Object -TypeName PSObject + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "LinkStatus" -Value $CMObject.LinkStatus + + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "Site1" -Value $CMObject.Site1 + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "SiteName1" -Value $CMObject.SiteName1 + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "SiteType1" -Value $CMObject.SiteType1 + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "Site1Status" -Value $CMObject.Site1Status + + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "Site2" -Value $CMObject.Site2 + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "SiteName2" -Value $CMObject.SiteName2 + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "SiteType2" -Value $CMObject.SiteType2 + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "Site2Status" -Value $CMObject.Site2Status + + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "Site1ToSite2GlobalState" -Value $CMObject.Site1ToSite2GlobalState + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "Site1ToSite2GlobalSyncTime" -Value $CMObject.Site1ToSite2GlobalSyncTime + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "Site2ToSite1GlobalState" -Value $CMObject.Site2ToSite1GlobalState + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "Site2ToSite1GlobalSyncTime" -Value $CMObject.Site2ToSite1GlobalSyncTime + + $returnObject | ConvertTo-JSON-20 +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +exit 0 +'; + return centreon::plugins::misc::powershell_encoded($ps); +} + +1; + +__END__ + +=head1 DESCRIPTION + +Method to get SCCM database replication informations. + +=cut diff --git a/centreon/common/powershell/sccm/sitestatus.pm b/centreon/common/powershell/sccm/sitestatus.pm new file mode 100644 index 000000000..5c28564c8 --- /dev/null +++ b/centreon/common/powershell/sccm/sitestatus.pm @@ -0,0 +1,92 @@ +# +# Copyright 2019 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 centreon::common::powershell::sccm::sitestatus; + +use strict; +use warnings; +use centreon::common::powershell::functions; + +sub get_powershell { + my (%options) = @_; + my $no_ps = (defined($options{no_ps})) ? 1 : 0; + + return '' if ($no_ps == 1); + + my $ps = ' +$culture = new-object "System.Globalization.CultureInfo" "en-us" +[System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture +'; + + $ps .= centreon::common::powershell::functions::escape_jsonstring(%options); + $ps .= centreon::common::powershell::functions::convert_to_json(%options); + + $ps .= ' +$ProgressPreference = "SilentlyContinue" + +Try { + $ErrorActionPreference = "Stop" + + $modulePath = ${env:SMS_ADMIN_UI_PATH} + $modulePath = $modulePath.Substring(0, $modulePath.lastIndexOf("\")) + $module = $modulePath + "\ConfigurationManager.psd1" + Import-Module $module + + New-PSDrive -Name SCCMDrive -PSProvider "AdminUI.PS.Provider\CMSite" -Root $env:COMPUTERNAME -Description "SCCM Site" | Out-Null + CD "SCCMDrive:\" + + $CMObject = Get-CMSite + + CD "C:\" + Remove-PSDrive -Name SCCMDrive + + $returnArray = @() + + Foreach ($site in $CMObject) { + $returnObject = New-Object -TypeName PSObject + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "SiteCode" -Value $site.SiteCode + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "SiteName" -Value $site.SiteName + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "Type" -Value $site.Type + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "Mode" -Value $site.Mode + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "Status" -Value $site.Status + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "SecondarySiteCMUpdateStatus" -Value $site.SecondarySiteCMUpdateStatus + $returnArray += $returnObject + } + + $returnArray | ConvertTo-JSON-20 +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +exit 0 +'; + return centreon::plugins::misc::powershell_encoded($ps); +} + +1; + +__END__ + +=head1 DESCRIPTION + +Method to get SCCM database replication informations. + +=cut diff --git a/centreon/common/powershell/wsus/computersstatus.pm b/centreon/common/powershell/wsus/computersstatus.pm new file mode 100644 index 000000000..d1a972c42 --- /dev/null +++ b/centreon/common/powershell/wsus/computersstatus.pm @@ -0,0 +1,97 @@ +# +# Copyright 2019 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 centreon::common::powershell::wsus::computersstatus; + +use strict; +use warnings; +use centreon::common::powershell::functions; + +sub get_powershell { + my (%options) = @_; + my $no_ps = (defined($options{no_ps})) ? 1 : 0; + + return '' if ($no_ps == 1); + + my $ps = ' +$culture = new-object "System.Globalization.CultureInfo" "en-us" +[System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture +'; + + $ps .= centreon::common::powershell::functions::escape_jsonstring(%options); + $ps .= centreon::common::powershell::functions::convert_to_json(%options); + + $ps .= ' +$wsusServer = "' . $options{wsus_server} . '" +$useSsl = ' . $options{use_ssl} . ' +$wsusPort = ' . $options{wsus_port} . ' +$notUpdatedSince = ' . $options{not_updated_since} . ' + +Try { + [void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +$ProgressPreference = "SilentlyContinue" + +Try { + $ErrorActionPreference = "Stop" + + $wsusObject = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusServer, $useSsl, $wsusPort) + + $wsusStatus = $wsusObject.GetStatus() + + $notUpdatedSinceTimespan = new-object TimeSpan($notUpdatedSince, 0, 0, 0) + $computersNotContactedSinceCount = $wsusObject.GetComputersNotContactedSinceCount([DateTime]::UtcNow.Subtract($notUpdatedSinceTimespan)) + + $computerTargetScope = new-object Microsoft.UpdateServices.Administration.ComputerTargetScope + $unassignedComputersCount = $wsusObject.GetComputerTargetGroup([Microsoft.UpdateServices.Administration.ComputerTargetGroupId]::UnassignedComputers).GetComputerTargets().Count + + $returnObject = New-Object -TypeName PSObject + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ComputerTargetsNeedingUpdatesCount" -Value $wsusStatus.ComputerTargetsNeedingUpdatesCount + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ComputerTargetsWithUpdateErrorsCount" -Value $wsusStatus.ComputerTargetsWithUpdateErrorsCount + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ComputersUpToDateCount" -Value $wsusStatus.ComputersUpToDateCount + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ComputersNotContactedSinceCount" -Value $computersNotContactedSinceCount + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UnassignedComputersCount" -Value $unassignedComputersCount + + $jsonString = $returnObject | ConvertTo-JSON-20 + Write-Host $jsonString +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +exit 0 +'; + + return centreon::plugins::misc::powershell_encoded($ps); +} + +1; + +__END__ + +=head1 DESCRIPTION + +Method to get WSUS computers informations. + +=cut diff --git a/centreon/common/powershell/wsus/serverstatistics.pm b/centreon/common/powershell/wsus/serverstatistics.pm new file mode 100644 index 000000000..a28f1d7b9 --- /dev/null +++ b/centreon/common/powershell/wsus/serverstatistics.pm @@ -0,0 +1,93 @@ +# +# Copyright 2019 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 centreon::common::powershell::wsus::serverstatistics; + +use strict; +use warnings; +use centreon::common::powershell::functions; + +sub get_powershell { + my (%options) = @_; + my $no_ps = (defined($options{no_ps})) ? 1 : 0; + + return '' if ($no_ps == 1); + + my $ps = ' +$culture = new-object "System.Globalization.CultureInfo" "en-us" +[System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture +'; + + $ps .= centreon::common::powershell::functions::escape_jsonstring(%options); + $ps .= centreon::common::powershell::functions::convert_to_json(%options); + + $ps .= ' +$wsusServer = "' . $options{wsus_server} . '" +$useSsl = ' . $options{use_ssl} . ' +$wsusPort = ' . $options{wsus_port} . ' + +Try { + [void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +$ProgressPreference = "SilentlyContinue" + +Try { + $ErrorActionPreference = "Stop" + + $wsusObject = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusServer, $useSsl, $wsusPort) + + $wsusStatus = $wsusObject.GetStatus() + + $returnObject = New-Object -TypeName PSObject + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ComputerTargetCount" -Value $wsusStatus.ComputerTargetCount + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "CustomComputerTargetGroupCount" -Value $wsusStatus.CustomComputerTargetGroupCount + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UpdateCount" -Value $wsusStatus.UpdateCount + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ApprovedUpdateCount" -Value $wsusStatus.ApprovedUpdateCount + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "DeclinedUpdateCount" -Value $wsusStatus.DeclinedUpdateCount + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "NotApprovedUpdateCount" -Value $wsusStatus.NotApprovedUpdateCount + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UpdatesWithStaleUpdateApprovalsCount" -Value $wsusStatus.UpdatesWithStaleUpdateApprovalsCount + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ExpiredUpdateCount" -Value $wsusStatus.ExpiredUpdateCount + + $jsonString = $returnObject | ConvertTo-JSON-20 + Write-Host $jsonString +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +exit 0 +'; + + return centreon::plugins::misc::powershell_encoded($ps); +} + +1; + +__END__ + +=head1 DESCRIPTION + +Method to get WSUS server statistics. + +=cut diff --git a/centreon/common/powershell/wsus/synchronisationstatus.pm b/centreon/common/powershell/wsus/synchronisationstatus.pm new file mode 100644 index 000000000..ef88e710c --- /dev/null +++ b/centreon/common/powershell/wsus/synchronisationstatus.pm @@ -0,0 +1,93 @@ +# +# Copyright 2019 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 centreon::common::powershell::wsus::synchronisationstatus; + +use strict; +use warnings; +use centreon::common::powershell::functions; + +sub get_powershell { + my (%options) = @_; + my $no_ps = (defined($options{no_ps})) ? 1 : 0; + + return '' if ($no_ps == 1); + + my $ps = ' +$culture = new-object "System.Globalization.CultureInfo" "en-us" +[System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture +'; + + $ps .= centreon::common::powershell::functions::escape_jsonstring(%options); + $ps .= centreon::common::powershell::functions::convert_to_json(%options); + + $ps .= ' +$wsusServer = "' . $options{wsus_server} . '" +$useSsl = ' . $options{use_ssl} . ' +$wsusPort = ' . $options{wsus_port} . ' + +Try { + [void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +$ProgressPreference = "SilentlyContinue" + +Try { + $ErrorActionPreference = "Stop" + + $wsusObject = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusServer, $useSsl, $wsusPort) + + $syncStatus = $wsusObject.GetSubscription().GetSynchronizationStatus() + $syncProgress = $wsusObject.GetSubscription().GetSynchronizationProgress() + $lastSync = $wsusObject.GetSubscription().GetLastSynchronizationInfo() + + $returnObject = New-Object -TypeName PSObject + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "SynchronizationStatus" -Value $syncStatus.ToString() + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "TotalItems" -Value $syncProgress.TotalItems + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ProcessedItems" -Value $syncProgress.ProcessedItems + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "LastSynchronizationResult" -Value $lastSync.Result.ToString() + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "LastSynchronizationStartTime" -Value $lastSync.StartTime + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "LastSynchronizationEndTime" -Value $lastSync.EndTime + + $jsonString = $returnObject | ConvertTo-JSON-20 + Write-Host $jsonString +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +exit 0 +'; + + return centreon::plugins::misc::powershell_encoded($ps); +} + +1; + +__END__ + +=head1 DESCRIPTION + +Method to get WSUS synchronisation informations. + +=cut diff --git a/centreon/common/powershell/wsus/updatesstatus.pm b/centreon/common/powershell/wsus/updatesstatus.pm new file mode 100644 index 000000000..f808c2f2b --- /dev/null +++ b/centreon/common/powershell/wsus/updatesstatus.pm @@ -0,0 +1,90 @@ +# +# Copyright 2019 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 centreon::common::powershell::wsus::updatesstatus; + +use strict; +use warnings; +use centreon::common::powershell::functions; + +sub get_powershell { + my (%options) = @_; + my $no_ps = (defined($options{no_ps})) ? 1 : 0; + + return '' if ($no_ps == 1); + + my $ps = ' +$culture = new-object "System.Globalization.CultureInfo" "en-us" +[System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture +'; + + $ps .= centreon::common::powershell::functions::escape_jsonstring(%options); + $ps .= centreon::common::powershell::functions::convert_to_json(%options); + + $ps .= ' +$wsusServer = "' . $options{wsus_server} . '" +$useSsl = ' . $options{use_ssl} . ' +$wsusPort = ' . $options{wsus_port} . ' + +Try { + [void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +$ProgressPreference = "SilentlyContinue" + +Try { + $ErrorActionPreference = "Stop" + + $wsusObject = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusServer, $useSsl, $wsusPort) + + $wsusStatus = $wsusObject.GetStatus() + + $returnObject = New-Object -TypeName PSObject + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UpdatesWithClientErrorsCount" -Value $wsusStatus.UpdatesWithClientErrorsCount + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UpdatesWithServerErrorsCount" -Value $wsusStatus.UpdatesWithServerErrorsCount + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UpdatesNeedingFilesCount" -Value $wsusStatus.UpdatesNeedingFilesCount + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UpdatesNeededByComputersCount" -Value $wsusStatus.UpdatesNeededByComputersCount + Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UpdatesUpToDateCount" -Value $wsusStatus.UpdatesUpToDateCount + + $jsonString = $returnObject | ConvertTo-JSON-20 + Write-Host $jsonString +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +exit 0 +'; + + return centreon::plugins::misc::powershell_encoded($ps); +} + +1; + +__END__ + +=head1 DESCRIPTION + +Method to get WSUS updates informations. + +=cut diff --git a/centreon/common/protocols/ldap/lib/ldap.pm b/centreon/common/protocols/ldap/lib/ldap.pm new file mode 100644 index 000000000..3c850b893 --- /dev/null +++ b/centreon/common/protocols/ldap/lib/ldap.pm @@ -0,0 +1,112 @@ +# +# Copyright 2019 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 centreon::common::protocols::ldap::lib::ldap; + +use strict; +use warnings; +use Net::LDAP; + +sub quit { + my (%options) = @_; + + if (defined($options{ldap_handle})) { + $options{ldap_handle}->unbind(); + } +} + +sub search { + my (%options) = @_; + my %ldap_search_options = (); + + $ldap_search_options{base} = $options{search_base}; + $ldap_search_options{filter} = $options{search_filter}; + my $attrs; + foreach my $option (@{$options{ldap_search_options}}) { + next if ($option !~ /^\s*(.+?)\s*=(.+)$/); + if ($1 eq 'attrs') { + $attrs = [] if (!defined($attrs)); + push @$attrs, $2; + } else { + $ldap_search_options{$1} = $2; + } + } + $ldap_search_options{attrs} = $attrs if (defined($attrs)); + my $search_result = $options{ldap_handle}->search(%ldap_search_options); + if ($search_result->code) { + return ($search_result, 1, 'Search operation error: ' . $search_result->error); + } + + return ($search_result, 0); +} + +sub connect { + my (%options) = @_; + my %ldap_connect_options = (); + my %ldap_bind_options = (); + + $ldap_connect_options{timeout} = $options{timeout} if (defined($options{timeout})); + foreach my $option (@{$options{ldap_connect_options}}) { + next if ($option !~ /^(.+?)=(.+)$/); + $ldap_connect_options{$1} = $2; + } + + my $ldap_handle = Net::LDAP->new($options{hostname}, %ldap_connect_options); + + if (!defined($ldap_handle)) { + return (undef, 1, 'Unable to connect to LDAP: ' . $@); + } + + # TLS Process + if (defined($options{use_tls})) { + my %ldap_starttls_options = (); + + foreach my $option (@{$options{ldap_starttls_options}}) { + next if ($option !~ /^(.+?)=(.+)$/); + $ldap_starttls_options{$1} = $2; + } + + my $tls_result = $ldap_handle->start_tls(%ldap_starttls_options); + if ($tls_result->code) { + return ($ldap_handle, 1, 'Start TLS operation error: ' . $tls_result->error); + } + } + + # Bind process + my $username; + if (defined($options{username}) && $options{username} ne '') { + $ldap_bind_options{password} = $options{password}; + $username = $options{username}; + } + + foreach my $option (@{$options{ldap_bind_options}}) { + next if ($option !~ /^(.+?)=(.+)$/); + $ldap_bind_options{$1} = $2; + } + + my $bind_result = $ldap_handle->bind($username, %ldap_bind_options); + if ($bind_result->code) { + return ($ldap_handle, 1, 'Bind operation error: ' . $bind_result->error); + } + + return ($ldap_handle, 0); +} + +1; diff --git a/centreon/common/protocols/sql/mode/connectiontime.pm b/centreon/common/protocols/sql/mode/connectiontime.pm index 517226cc2..c16758939 100644 --- a/centreon/common/protocols/sql/mode/connectiontime.pm +++ b/centreon/common/protocols/sql/mode/connectiontime.pm @@ -33,11 +33,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - }); + $options{options}->add_options(arguments => { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); return $self; } @@ -63,7 +62,8 @@ sub run { my $now = Time::HiRes::time(); my ($exit, $msg_error) = $self->{sql}->connect(dontquit => 1); - my $now2 = Time::HiRes::time(); + my $now2 = Time::HiRes::time(); + $self->{sql}->disconnect(); if ($exit == -1) { $self->{output}->output_add(severity => 'CRITICAL', diff --git a/centreon/common/protocols/sql/mode/sql.pm b/centreon/common/protocols/sql/mode/sql.pm index 80964fc5b..1a562124c 100644 --- a/centreon/common/protocols/sql/mode/sql.pm +++ b/centreon/common/protocols/sql/mode/sql.pm @@ -31,17 +31,16 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "sql-statement:s" => { name => 'sql_statement', }, - "format:s" => { name => 'format', default => 'SQL statement result : %i.'}, - "perfdata-unit:s" => { name => 'perfdata_unit', default => ''}, - "perfdata-name:s" => { name => 'perfdata_name', default => 'value'}, - "perfdata-min:s" => { name => 'perfdata_min', default => ''}, - "perfdata-max:s" => { name => 'perfdata_max', default => ''}, - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - }); + $options{options}->add_options(arguments => { + "sql-statement:s" => { name => 'sql_statement', }, + "format:s" => { name => 'format', default => 'SQL statement result : %i.'}, + "perfdata-unit:s" => { name => 'perfdata_unit', default => ''}, + "perfdata-name:s" => { name => 'perfdata_name', default => 'value'}, + "perfdata-min:s" => { name => 'perfdata_min', default => ''}, + "perfdata-max:s" => { name => 'perfdata_max', default => ''}, + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); return $self; } @@ -70,7 +69,6 @@ sub check_options { sub run { my ($self, %options) = @_; - # $options{sql} = sqlmode object $self->{sql} = $options{sql}; my $query = $self->{option_results}->{sql_statement}; @@ -78,6 +76,7 @@ sub run { $self->{sql}->connect(); $self->{sql}->query(query => $query); my $value = $self->{sql}->fetchrow_array(); + $self->{sql}->disconnect(); my $exit_code = $self->{perfdata}->threshold_check(value => $value, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{output}->output_add(severity => $exit_code, diff --git a/centreon/common/protocols/sql/mode/sqlstring.pm b/centreon/common/protocols/sql/mode/sqlstring.pm index ac0a04b29..d673a2414 100644 --- a/centreon/common/protocols/sql/mode/sqlstring.pm +++ b/centreon/common/protocols/sql/mode/sqlstring.pm @@ -106,17 +106,18 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "sql-statement:s" => { name => 'sql_statement' }, - "key-column:s" => { name => 'key_column' }, - "value-column:s" => { name => 'value_column' }, - "warning-string:s" => { name => 'warning_string', default => '' }, - "critical-string:s" => { name => 'critical_string', default => '' }, - "printf-format:s" => { name => 'printf_format' }, - "printf-value:s" => { name => 'printf_value' }, - "dual-table" => { name => 'dual_table' }, - }); + $options{options}->add_options(arguments => { + "sql-statement:s" => { name => 'sql_statement' }, + "key-column:s" => { name => 'key_column' }, + "value-column:s" => { name => 'value_column' }, + "warning-string:s" => { name => 'warning_string', default => '' }, + "critical-string:s" => { name => 'critical_string', default => '' }, + "printf-format:s" => { name => 'printf_format' }, + "printf-value:s" => { name => 'printf_value' }, + "dual-table" => { name => 'dual_table' }, + "empty-sql-string:s" => { name => 'empty_sql_string', default => 'No row returned or --key-column/--value-column do not correctly match selected field' }, + }); + return $self; } @@ -124,12 +125,12 @@ sub check_options { my ($self, %options) = @_; $self->SUPER::check_options(%options); - if (!defined($self->{instance_mode}->{option_results}->{sql_statement}) || $self->{instance_mode}->{option_results}->{sql_statement} eq '') { - $self->{instance_mode}->{output}->add_option_msg(short_msg => "Need to specify '--sql-statement' option."); - $self->{instance_mode}->{output}->option_exit(); + if (!defined($self->{option_results}->{sql_statement}) || $self->{option_results}->{sql_statement} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify '--sql-statement' option."); + $self->{output}->option_exit(); } - $self->{instance_mode}->change_macros(macros => ['warning_string', 'critical_string']); + $self->change_macros(macros => ['warning_string', 'critical_string']); } sub manage_selection { @@ -158,8 +159,9 @@ sub manage_selection { } } + $self->{sql}->disconnect(); if (scalar(keys %{$self->{rows}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No row returned or --key-column/--value-column do not correctly match selected field"); + $self->{output}->add_option_msg(short_msg => $self->{option_results}->{empty_sql_string}); $self->{output}->option_exit(); } @@ -211,6 +213,11 @@ Set critical condition (if statement syntax) for status evaluation. Set this option to ensure compatibility with dual table and Oracle. +=item B<--empty-sql-string> + +Set this option to change the output message when the sql statement result is empty. +(Default: 'No row returned or --key-column/--value-column do not correctly match selected field') + =back =cut diff --git a/network/riverbed/steelhead/snmp/mode/bwoptimization.pm b/centreon/common/riverbed/steelhead/snmp/mode/bwoptimization.pm similarity index 65% rename from network/riverbed/steelhead/snmp/mode/bwoptimization.pm rename to centreon/common/riverbed/steelhead/snmp/mode/bwoptimization.pm index c5e22d8ac..dca33d757 100644 --- a/network/riverbed/steelhead/snmp/mode/bwoptimization.pm +++ b/centreon/common/riverbed/steelhead/snmp/mode/bwoptimization.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::riverbed::steelhead::snmp::mode::bwoptimization; +package centreon::common::riverbed::steelhead::snmp::mode::bwoptimization; use base qw(centreon::plugins::templates::counter); @@ -37,7 +37,7 @@ sub set_counters { { label => 'wan2lan-lan', set => { key_values => [ { name => 'bwHCAggInLan', diff => 1 } ], output_template => 'Wan2Lan on Lan: %s %s/s', - output_change_bytes => 1, + output_change_bytes => 1, per_second => 1, perfdatas => [ { label => 'wan2lan_lan', value => 'bwHCAggInLan_absolute', template => '%s', min => 0, unit => 'B/s' }, @@ -47,7 +47,7 @@ sub set_counters { { label => 'wan2lan-wan', set => { key_values => [ { name => 'bwHCAggInWan', diff => 1 } ], output_template => 'Wan2Lan on Wan: %s %s/s', - output_change_bytes => 1, + output_change_bytes => 1, per_second => 1, perfdatas => [ { label => 'wan2lan_wan', value => 'bwHCAggInWan_absolute', template => '%s', min => 0, unit => 'B/s' }, @@ -57,7 +57,7 @@ sub set_counters { { label => 'lan2wan-lan', set => { key_values => [ { name => 'bwHCAggOutLan', diff => 1 } ], output_template => 'Lan2Wan on Lan: %s %s/s', - output_change_bytes => 1, + output_change_bytes => 1, per_second => 1, perfdatas => [ { label => 'lan2wan_lan', value => 'bwHCAggOutLan_absolute', template => '%s', min => 0, unit => 'B/s' }, @@ -67,7 +67,7 @@ sub set_counters { { label => 'lan2wan-wan', set => { key_values => [ { name => 'bwHCAggOutWan', diff => 1 } ], output_template => 'Lan2Wan on Wan: %s %s/s', - output_change_bytes => 1, + output_change_bytes => 1, per_second => 1, perfdatas => [ { label => 'lan2wan_wan', value => 'bwHCAggOutWan_absolute', template => '%s', min => 0, unit => 'B/s' }, @@ -80,7 +80,7 @@ sub set_counters { sub prefix_output { my ($self, %options) = @_; - return "Optimized: "; + return "Optimized "; } sub new { @@ -96,41 +96,51 @@ sub new { return $self; } +my $mappings = { + common => { + bwHCAggInLan => { oid => '.1.3.6.1.4.1.17163.1.1.5.6.1.1' }, + bwHCAggInWan => { oid => '.1.3.6.1.4.1.17163.1.1.5.6.1.2' }, + bwHCAggOutLan => { oid => '.1.3.6.1.4.1.17163.1.1.5.6.1.3' }, + bwHCAggOutWan => { oid => '.1.3.6.1.4.1.17163.1.1.5.6.1.4' }, + }, + ex => { + bwHCAggInLan => { oid => '.1.3.6.1.4.1.17163.1.51.5.6.1.1' }, + bwHCAggInWan => { oid => '.1.3.6.1.4.1.17163.1.51.5.6.1.2' }, + bwHCAggOutLan => { oid => '.1.3.6.1.4.1.17163.1.51.5.6.1.3' }, + bwHCAggOutWan => { oid => '.1.3.6.1.4.1.17163.1.51.5.6.1.4' }, + }, +}; + +my $oids = { + common => '.1.3.6.1.4.1.17163.1.1.5.6.1', + ex => '.1.3.6.1.4.1.17163.1.51.5.6.1', +}; + sub manage_selection { my ($self, %options) = @_; - # STEELHEAD-MIB - my $oids = { - bwHCAggInLan => '.1.3.6.1.4.1.17163.1.1.5.6.1.1.0', - bwHCAggInWan => '.1.3.6.1.4.1.17163.1.1.5.6.1.2.0', - bwHCAggOutLan => '.1.3.6.1.4.1.17163.1.1.5.6.1.3.0', - bwHCAggOutWan => '.1.3.6.1.4.1.17163.1.1.5.6.1.4.0', - }; + my $results = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oids->{common}, + start => $mappings->{common}->{bwHCAggInLan}->{oid}, + end => $mappings->{common}->{bwHCAggOutWan}->{oid} }, + { oid => $oids->{ex}, + start => $mappings->{ex}->{bwHCAggInLan}->{oid}, + end => $mappings->{ex}->{bwHCAggOutWan}->{oid} } + ] + ); - # STEELHEAD-EX-MIB - my $oids_ex = { - bwHCAggInLan => '.1.3.6.1.4.1.17163.1.51.5.6.1.1.0', - bwHCAggInWan => '.1.3.6.1.4.1.17163.1.51.5.6.1.2.0', - bwHCAggOutLan => '.1.3.6.1.4.1.17163.1.51.5.6.1.3.0', - bwHCAggOutWan => '.1.3.6.1.4.1.17163.1.51.5.6.1.4.0', - }; + foreach my $equipment (keys %{$oids}) { + next if (!%{$results->{$oids->{$equipment}}}); - my $result = $options{snmp}->get_leef(oids => [ values %{$oids}, values %{$oids_ex} ], nothing_quit => 1); + my $result = $options{snmp}->map_instance(mapping => $mappings->{$equipment}, + results => $results->{$oids->{$equipment}}, instance => 0); - $self->{cache_name} = "riverbed_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . - '_' . $self->{mode} . '_' . md5_hex('all'); - - $self->{global} = {}; - - if (defined($result->{$oids->{bwHCAggInLan}})) { - foreach (keys %{$oids}) { - $self->{global}->{$_} = $result->{$oids->{$_}}; - } - } else { - foreach (keys %{$oids_ex}) { - $self->{global}->{$_} = $result->{$oids_ex->{$_}}; - } + $self->{global} = { %$result }; } + + $self->{cache_name} = "riverbed_steelhead_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . + '_' . $self->{mode} . '_' . md5_hex('all'); } 1; diff --git a/network/riverbed/steelhead/snmp/mode/bwpassthrough.pm b/centreon/common/riverbed/steelhead/snmp/mode/bwpassthrough.pm similarity index 59% rename from network/riverbed/steelhead/snmp/mode/bwpassthrough.pm rename to centreon/common/riverbed/steelhead/snmp/mode/bwpassthrough.pm index 9596bf760..f75625dba 100644 --- a/network/riverbed/steelhead/snmp/mode/bwpassthrough.pm +++ b/centreon/common/riverbed/steelhead/snmp/mode/bwpassthrough.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::riverbed::steelhead::snmp::mode::bwpassthrough; +package centreon::common::riverbed::steelhead::snmp::mode::bwpassthrough; use base qw(centreon::plugins::templates::counter); @@ -37,20 +37,20 @@ sub set_counters { { label => 'traffic-in', set => { key_values => [ { name => 'bwPassThroughIn', diff => 1 } ], output_template => 'Traffic In (Wan2Lan): %s %s/s', - output_change_bytes => 1, + output_change_bytes => 1, per_second => 1, perfdatas => [ { label => 'traffic_in', value => 'bwPassThroughIn_absolute', - template => '%s', min => 0, unit => 'B/s' }, + template => '%s', min => 0, unit => 'B/s' }, ], } }, { label => 'traffic-out', set => { key_values => [ { name => 'bwPassThroughOut', diff => 1 } ], output_template => 'Traffic Out (Lan2Wan): %s %s/s', - output_change_bytes => 1, + output_change_bytes => 1, per_second => 1, perfdatas => [ { label => 'traffic_out', value => 'bwPassThroughOut_absolute', - template => '%s', min => 0, unit => 'B/s' }, + template => '%s', min => 0, unit => 'B/s' }, ], } }, @@ -60,18 +60,33 @@ sub set_counters { sub prefix_output { my ($self, %options) = @_; - return "Passthrough: "; + return "Passthrough "; } +my $mappings = { + common => { + bwPassThroughIn => { oid => '.1.3.6.1.4.1.17163.1.1.5.3.3.1' }, + bwPassThroughOut => { oid => '.1.3.6.1.4.1.17163.1.1.5.3.3.2' }, + }, + ex => { + bwPassThroughIn => { oid => '.1.3.6.1.4.1.17163.1.51.5.3.3.1' }, + bwPassThroughOut => { oid => '.1.3.6.1.4.1.17163.1.51.5.3.3.2' }, + }, +}; + +my $oids = { + common => '.1.3.6.1.4.1.17163.1.1.5.3.3', + ex => '.1.3.6.1.4.1.17163.1.51.5.3.3', +}; + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '0.1'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } @@ -79,34 +94,28 @@ sub new { sub manage_selection { my ($self, %options) = @_; - # STEELHEAD-MIB - my $oids = { - bwPassThroughIn => '.1.3.6.1.4.1.17163.1.1.5.3.3.1.0', - bwPassThroughOut => '.1.3.6.1.4.1.17163.1.1.5.3.3.2.0', - }; + my $results = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oids->{common}, + start => $mappings->{common}->{bwPassThroughIn}->{oid}, + end => $mappings->{common}->{bwPassThroughOut}->{oid} }, + { oid => $oids->{ex}, + start => $mappings->{ex}->{bwPassThroughIn}->{oid}, + end => $mappings->{ex}->{bwPassThroughOut}->{oid} } + ] + ); - # STEELHEAD-EX-MIB - my $oids_ex = { - bwPassThroughIn => '.1.3.6.1.4.1.17163.1.51.5.3.3.1.0', - bwPassThroughOut => '.1.3.6.1.4.1.17163.1.51.5.3.3.2.0', - }; + foreach my $equipment (keys %{$oids}) { + next if (!%{$results->{$oids->{$equipment}}}); - my $result = $options{snmp}->get_leef(oids => [ values %{$oids}, values %{$oids_ex} ], nothing_quit => 1); + my $result = $options{snmp}->map_instance(mapping => $mappings->{$equipment}, + results => $results->{$oids->{$equipment}}, instance => 0); - $self->{cache_name} = "riverbed_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . - '_' . $self->{mode} . '_' . md5_hex('all'); - - $self->{global} = {}; - - if (defined($result->{$oids->{bwPassThroughIn}})) { - foreach (keys %{$oids}) { - $self->{global}->{$_} = $result->{$oids->{$_}}; - } - } else { - foreach (keys %{$oids_ex}) { - $self->{global}->{$_} = $result->{$oids_ex->{$_}}; - } + $self->{global} = { %$result }; } + + $self->{cache_name} = "riverbed_steelhead_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . + '_' . $self->{mode} . '_' . md5_hex('all'); } 1; diff --git a/network/riverbed/steelhead/snmp/mode/connections.pm b/centreon/common/riverbed/steelhead/snmp/mode/connections.pm similarity index 68% rename from network/riverbed/steelhead/snmp/mode/connections.pm rename to centreon/common/riverbed/steelhead/snmp/mode/connections.pm index 8e7440b26..d380b764f 100644 --- a/network/riverbed/steelhead/snmp/mode/connections.pm +++ b/centreon/common/riverbed/steelhead/snmp/mode/connections.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::riverbed::steelhead::snmp::mode::connections; +package centreon::common::riverbed::steelhead::snmp::mode::connections; use base qw(centreon::plugins::templates::counter); @@ -104,49 +104,58 @@ sub new { bless $self, $class; $self->{version} = '0.1'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } +my $mappings = { + common => { + optimizedConnections => { oid => '.1.3.6.1.4.1.17163.1.1.5.2.1' }, + passthroughConnections => { oid => '.1.3.6.1.4.1.17163.1.1.5.2.2' }, + halfOpenedConnections => { oid => '.1.3.6.1.4.1.17163.1.1.5.2.3' }, + halfClosedConnections => { oid => '.1.3.6.1.4.1.17163.1.1.5.2.4' }, + establishedConnections => { oid => '.1.3.6.1.4.1.17163.1.1.5.2.5' }, + activeConnections => { oid => '.1.3.6.1.4.1.17163.1.1.5.2.6' }, + totalConnections => { oid => '.1.3.6.1.4.1.17163.1.1.5.2.7' }, + }, + ex => { + optimizedConnections => { oid => '.1.3.6.1.4.1.17163.1.51.5.2.1' }, + passthroughConnections => { oid => '.1.3.6.1.4.1.17163.1.51.5.2.2' }, + halfOpenedConnections => { oid => '.1.3.6.1.4.1.17163.1.51.5.2.3' }, + halfClosedConnections => { oid => '.1.3.6.1.4.1.17163.1.51.5.2.4' }, + establishedConnections => { oid => '.1.3.6.1.4.1.17163.1.51.5.2.5' }, + activeConnections => { oid => '.1.3.6.1.4.1.17163.1.51.5.2.6' }, + totalConnections => { oid => '.1.3.6.1.4.1.17163.1.51.5.2.7' }, + }, +}; + +my $oids = { + common => '.1.3.6.1.4.1.17163.1.1.5.2', + ex => '.1.3.6.1.4.1.17163.1.51.5.2', +}; + sub manage_selection { my ($self, %options) = @_; - # STEELHEAD-MIB - my $oids = { - optimizedConnections => '.1.3.6.1.4.1.17163.1.1.5.2.1.0', - passthroughConnections => '.1.3.6.1.4.1.17163.1.1.5.2.2.0', - halfOpenedConnections => '.1.3.6.1.4.1.17163.1.1.5.2.3.0', - halfClosedConnections => '.1.3.6.1.4.1.17163.1.1.5.2.4.0', - establishedConnections => '.1.3.6.1.4.1.17163.1.1.5.2.5.0', - activeConnections => '.1.3.6.1.4.1.17163.1.1.5.2.6.0', - totalConnections => '.1.3.6.1.4.1.17163.1.1.5.2.7.0', - }; + my $results = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oids->{common}, + start => $mappings->{common}->{optimizedConnections}->{oid}, + end => $mappings->{common}->{totalConnections}->{oid} }, + { oid => $oids->{ex}, + start => $mappings->{ex}->{optimizedConnections}->{oid}, + end => $mappings->{ex}->{totalConnections}->{oid} } + ] + ); - # STEELHEAD-EX-MIB - my $oids_ex = { - optimizedConnections => '.1.3.6.1.4.1.17163.1.51.5.2.1.0', - passthroughConnections => '.1.3.6.1.4.1.17163.1.51.5.2.2.0', - halfOpenedConnections => '.1.3.6.1.4.1.17163.1.51.5.2.3.0', - halfClosedConnections => '.1.3.6.1.4.1.17163.1.51.5.2.4.0', - establishedConnections => '.1.3.6.1.4.1.17163.1.51.5.2.5.0', - activeConnections => '.1.3.6.1.4.1.17163.1.51.5.2.6.0', - totalConnections => '.1.3.6.1.4.1.17163.1.51.5.2.7.0', - }; + foreach my $equipment (keys %{$oids}) { + next if (!%{$results->{$oids->{$equipment}}}); - my $snmp_result = $options{snmp}->get_leef(oids => [ values %{$oids}, values %{$oids_ex} ], nothing_quit => 1); - - $self->{global} = {}; - - if (defined($snmp_result->{$oids->{optimizedConnections}})) { - foreach (keys %{$oids}) { - $self->{global}->{$_} = $snmp_result->{$oids->{$_}}; - } - } else { - foreach (keys %{$oids_ex}) { - $self->{global}->{$_} = $snmp_result->{$oids_ex->{$_}}; - } + my $result = $options{snmp}->map_instance(mapping => $mappings->{$equipment}, + results => $results->{$oids->{$equipment}}, instance => 0); + + $self->{global} = { %$result }; } } diff --git a/centreon/common/riverbed/steelhead/snmp/mode/diskutilization.pm b/centreon/common/riverbed/steelhead/snmp/mode/diskutilization.pm new file mode 100644 index 000000000..d25e5da2d --- /dev/null +++ b/centreon/common/riverbed/steelhead/snmp/mode/diskutilization.pm @@ -0,0 +1,154 @@ +# +# Copyright 2019 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 centreon::common::riverbed::steelhead::snmp::mode::diskutilization; + +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 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'usage', set => { + key_values => [ { name => 'dsAveDiskUtilization' } ], + output_template => 'Datastore Usage: %.2f%%', + perfdatas => [ + { label => 'used', value => 'dsAveDiskUtilization_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'hits', set => { + key_values => [ { name => 'dsHitsTotal', diff => 1 } ], + per_second => 1, + output_template => 'Hits: %s/s', + perfdatas => [ + { label => 'hits', value => 'dsHitsTotal_per_second', template => '%.2f', + min => 0, unit => 'hits/s' }, + ], + } + }, + { label => 'misses', set => { + key_values => [ { name => 'dsMissTotal', diff => 1 } ], + per_second => 1, + output_template => 'Misses: %s/s', + perfdatas => [ + { label => 'misses', value => 'dsMissTotal_per_second', template => '%.2f', + min => 0, unit => 'misses/s' }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '0.1'; + $options{options}->add_options(arguments =>{ + }); + return $self; +} + +my $mappings = { + common => { + dsHitsTotal => { oid => '.1.3.6.1.4.1.17163.1.1.5.4.1' }, + dsMissTotal => { oid => '.1.3.6.1.4.1.17163.1.1.5.4.2' }, + dsCostPerSegment => { oid => '.1.3.6.1.4.1.17163.1.1.5.4.3' }, + dsAveDiskUtilization => { oid => '.1.3.6.1.4.1.17163.1.1.5.4.4' }, + }, + ex => { + dsHitsTotal => { oid => '.1.3.6.1.4.1.17163.1.51.5.4.1' }, + dsMissTotal => { oid => '.1.3.6.1.4.1.17163.1.51.5.4.2' }, + dsCostPerSegment => { oid => '.1.3.6.1.4.1.17163.1.51.5.4.3' }, + dsAveDiskUtilization => { oid => '.1.3.6.1.4.1.17163.1.51.5.4.4' }, + }, +}; + +my $oids = { + common => '.1.3.6.1.4.1.17163.1.1.5.4', + ex => '.1.3.6.1.4.1.17163.1.51.5.4', +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oids->{common}, + start => $mappings->{common}->{dsHitsTotal}->{oid}, + end => $mappings->{common}->{dsAveDiskUtilization}->{oid} }, + { oid => $oids->{ex}, + start => $mappings->{ex}->{dsHitsTotal}->{oid}, + end => $mappings->{ex}->{dsAveDiskUtilization}->{oid} } + ] + ); + + foreach my $equipment (keys %{$oids}) { + next if (!%{$results->{$oids->{$equipment}}}); + + my $result = $options{snmp}->map_instance(mapping => $mappings->{$equipment}, + results => $results->{$oids->{$equipment}}, instance => 0); + + $self->{global} = { + dsHitsTotal => $result->{dsHitsTotal}, + dsMissTotal => $result->{dsMissTotal}, + dsAveDiskUtilization => $result->{dsAveDiskUtilization}, + }; + } + + $self->{cache_name} = "riverbed_steelhead_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . + '_' . $self->{mode} . '_' . md5_hex('all'); +} + +1; + +__END__ + +=head1 MODE + +Check disk utilization : usage, hits and misses. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'usage' (%), 'hits' (/s), 'misses' (/s). + + +=item B<--critical-usage> + +Threshold critical. +Can be: 'usage' (%), 'hits' (/s), 'misses' (/s). + +=back + +=cut diff --git a/centreon/common/riverbed/steelhead/snmp/mode/loadaverage.pm b/centreon/common/riverbed/steelhead/snmp/mode/loadaverage.pm new file mode 100644 index 000000000..6d8819a49 --- /dev/null +++ b/centreon/common/riverbed/steelhead/snmp/mode/loadaverage.pm @@ -0,0 +1,187 @@ +# +# Copyright 2019 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. +# + +# +# Copyright 2019 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 centreon::common::riverbed::steelhead::snmp::mode::loadaverage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'average', nlabel => 'cpu.usage.percentage', set => { + key_values => [ { name => 'cpuUtil1' } ], + output_template => 'CPU Average: %.2f%%', + perfdatas => [ + { label => 'total_cpu_avg', value => 'cpuUtil1_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => '1min', nlabel => 'cpu.1m.usage.percentage', set => { + key_values => [ { name => 'cpuLoad1' } ], + output_template => 'Load 1 min: %.2f', + perfdatas => [ + { label => 'load1', value => 'cpuLoad1_absolute', template => '%.2f', + min => 0 }, + ], + } + }, + { label => '5min', nlabel => 'cpu.5m.usage.percentage', set => { + key_values => [ { name => 'cpuLoad5' } ], + output_template => 'Load 5 min: %.2f', + perfdatas => [ + { label => 'load5', value => 'cpuLoad5_absolute', template => '%.2f', + min => 0 }, + ], + } + }, + { label => '15min', nlabel => 'cpu.15m.usage.percentage', set => { + key_values => [ { name => 'cpuLoad15' } ], + output_template => 'Load 15 min: %.2f', + perfdatas => [ + { label => 'load15', value => 'cpuLoad15_absolute', template => '%.2f', + min => 0 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + $options{options}->add_options(arguments =>{ + }); + return $self; +} + +my $mappings = { + common => { + cpuLoad1 => { oid => '.1.3.6.1.4.1.17163.1.1.5.1.1' }, + cpuLoad5 => { oid => '.1.3.6.1.4.1.17163.1.1.5.1.2' }, + cpuLoad15 => { oid => '.1.3.6.1.4.1.17163.1.1.5.1.3' }, + cpuUtil1 => { oid => '.1.3.6.1.4.1.17163.1.1.5.1.4' }, + }, + ex => { + cpuLoad1 => { oid => '.1.3.6.1.4.1.17163.1.51.5.1.1' }, + cpuLoad5 => { oid => '.1.3.6.1.4.1.17163.1.51.5.1.2' }, + cpuLoad15 => { oid => '.1.3.6.1.4.1.17163.1.51.5.1.3' }, + cpuUtil1 => { oid => '.1.3.6.1.4.1.17163.1.51.5.1.4' }, + }, + interceptor => { + cpuLoad1 => { oid => '.1.3.6.1.4.1.17163.1.3.5.1.1' }, + cpuLoad5 => { oid => '.1.3.6.1.4.1.17163.1.3.5.1.2' }, + cpuLoad15 => { oid => '.1.3.6.1.4.1.17163.1.3.5.1.3' }, + cpuUtil1 => { oid => '.1.3.6.1.4.1.17163.1.3.5.1.4' }, + }, +}; + +my $oids = { + common => '.1.3.6.1.4.1.17163.1.1.5.1', + ex => '.1.3.6.1.4.1.17163.1.51.5.1', + interceptor => '.1.3.6.1.4.1.17163.1.3.5.1', +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oids->{common}, + start => $mappings->{common}->{cpuLoad1}->{oid}, + end => $mappings->{common}->{cpuUtil1}->{oid} }, + { oid => $oids->{ex}, + start => $mappings->{ex}->{cpuLoad1}->{oid}, + end => $mappings->{ex}->{cpuUtil1}->{oid} }, + { oid => $oids->{interceptor}, + start => $mappings->{interceptor}->{cpuLoad1}->{oid}, + end => $mappings->{interceptor}->{cpuUtil1}->{oid} } + ] + ); + + foreach my $equipment (keys %{$oids}) { + next if (!%{$results->{$oids->{$equipment}}}); + + my $result = $options{snmp}->map_instance(mapping => $mappings->{$equipment}, + results => $results->{$oids->{$equipment}}, instance => 0); + + $self->{global} = { + cpuLoad1 => $result->{cpuLoad1} / 100, + cpuLoad5 => $result->{cpuLoad5} / 100, + cpuLoad15 => $result->{cpuLoad15} / 100, + cpuUtil1 => $result->{cpuUtil1}, + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check system load average. + +=over 8 + +=item B<--warning-*> + +Warning thresholds +Can be --warning-(average|1m|5m|15m) + +=item B<--critical-*> + +Critical thresholds +Can be --critical-(average|1m|5m|15m) + +=back + +=cut diff --git a/centreon/common/riverbed/steelhead/snmp/mode/status.pm b/centreon/common/riverbed/steelhead/snmp/mode/status.pm new file mode 100644 index 000000000..91e01dac6 --- /dev/null +++ b/centreon/common/riverbed/steelhead/snmp/mode/status.pm @@ -0,0 +1,186 @@ +# +# Copyright 2019 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 centreon::common::riverbed::steelhead::snmp::mode::status; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("Health is '%s', Status is '%s'", + $self->{result_values}->{health}, + $self->{result_values}->{status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{health} = $options{new_datas}->{$self->{instance} . '_health'}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_serviceStatus'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_status_output' }, + ]; + $self->{maps_counters}->{global} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'health' }, { name => 'serviceStatus' } ], + 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 => \&catalog_status_threshold, + } + }, + { label => 'uptime', set => { + key_values => [ { name => 'serviceUptime' }, { name => 'serviceUptime_human' } ], + output_template => 'Uptime: %s', output_use => 'serviceUptime_human_absolute', + perfdatas => [ + { label => 'uptime', value => 'serviceUptime_absolute', template => '%d', + min => 0, unit => 's' }, + ], + } + }, + ]; +} + +sub prefix_status_output { + my ($self, %options) = @_; + + return "Optimization Service "; +} + +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 => '%{health} !~ /Healthy/ || %{status} !~ /running/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +my $mappings = { + common => { + health => { oid => '.1.3.6.1.4.1.17163.1.1.2.2' }, + serviceStatus => { oid => '.1.3.6.1.4.1.17163.1.1.2.3' }, + serviceUptime => { oid => '.1.3.6.1.4.1.17163.1.1.2.4' }, + }, + ex => { + health => { oid => '.1.3.6.1.4.1.17163.1.51.2.2' }, + serviceStatus => { oid => '.1.3.6.1.4.1.17163.1.51.2.3' }, + serviceUptime => { oid => '.1.3.6.1.4.1.17163.1.51.2.4' }, + }, + interceptor => { + health => { oid => '.1.3.6.1.4.1.17163.1.3.2.2' }, + serviceStatus => { oid => '.1.3.6.1.4.1.17163.1.3.2.3' }, + serviceUptime => { oid => '.1.3.6.1.4.1.17163.1.3.2.4' }, + }, +}; + +my $oids = { + common => '.1.3.6.1.4.1.17163.1.1.2', + ex => '.1.3.6.1.4.1.17163.1.51.2', + interceptor => '.1.3.6.1.4.1.17163.1.3.2', +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oids->{common}, + start => $mappings->{common}->{health}->{oid}, + end => $mappings->{common}->{serviceUptime}->{oid} }, + { oid => $oids->{ex}, + start => $mappings->{ex}->{health}->{oid}, + end => $mappings->{ex}->{serviceUptime}->{oid} }, + { oid => $oids->{interceptor}, + start => $mappings->{interceptor}->{health}->{oid}, + end => $mappings->{interceptor}->{serviceUptime}->{oid} } + ] + ); + + foreach my $equipment (keys %{$oids}) { + next if (!%{$results->{$oids->{$equipment}}}); + + my $result = $options{snmp}->map_instance(mapping => $mappings->{$equipment}, + results => $results->{$oids->{$equipment}}, instance => 0); + + $self->{global} = { + health => $result->{health}, + serviceStatus => $result->{serviceStatus}, + serviceUptime => $result->{serviceUptime} / 100, + serviceUptime_human => centreon::plugins::misc::change_seconds(value => $result->{serviceUptime} / 100), + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check the current status of the optimization service. + +=over 8 + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{health}, %{status} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{health} !~ /Healthy/ || %{status} !~ /running/'). +Can used special variables like: %{health}, %{status} + +=item B<--warning-uptime> + +Warning thresholds in seconds. + +=item B<--critical-uptime> + +Critical thresholds in seconds. + +=back + +=cut diff --git a/centreon/common/riverbed/steelhead/snmp/mode/temperature.pm b/centreon/common/riverbed/steelhead/snmp/mode/temperature.pm new file mode 100644 index 000000000..abbd060e7 --- /dev/null +++ b/centreon/common/riverbed/steelhead/snmp/mode/temperature.pm @@ -0,0 +1,120 @@ +# +# Copyright 2019 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 centreon::common::riverbed::steelhead::snmp::mode::temperature; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'temperature', set => { + key_values => [ { name => 'systemTemperature' } ], + output_template => 'Temperature: %.2f C', + perfdatas => [ + { label => 'temperature', value => 'systemTemperature_absolute', template => '%.2f', + min => 0, unit => 'C' }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + $options{options}->add_options(arguments =>{ + }); + return $self; +} + +my $mappings = { + common => { + systemTemperature => { oid => '.1.3.6.1.4.1.17163.1.1.2.9' }, + }, + ex => { + systemTemperature => { oid => '.1.3.6.1.4.1.17163.1.51.2.9' }, + }, +}; + +my $oids = { + common => '.1.3.6.1.4.1.17163.1.1.2.9', + ex => '.1.3.6.1.4.1.17163.1.51.2.9', +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oids->{common}, + start => $mappings->{common}->{systemTemperature}->{oid}, + end => $mappings->{common}->{systemTemperature}->{oid} }, + { oid => $oids->{ex}, + start => $mappings->{ex}->{systemTemperature}->{oid}, + end => $mappings->{ex}->{systemTemperature}->{oid} } + ] + ); + + foreach my $equipment (keys %{$oids}) { + next if (!%{$results->{$oids->{$equipment}}}); + + my $result = $options{snmp}->map_instance(mapping => $mappings->{$equipment}, + results => $results->{$oids->{$equipment}}, instance => 0); + + $self->{global} = { + systemTemperature => $result->{systemTemperature}, + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check the temperature of the system in Celcius (STEELHEAD-MIB and STEELHEAD-EX-MIB). + +=over 8 + +=item B<--warning-temperature> + +Threshold warning for temperature in Celsius. + +=item B<--critical-temperature> + +Threshold critical for temperature in Celsius. + +=back + +=cut diff --git a/centreon/common/smcli/custom/custom.pm b/centreon/common/smcli/custom/custom.pm index 02ccd7fc3..ce584fd9f 100644 --- a/centreon/common/smcli/custom/custom.pm +++ b/centreon/common/smcli/custom/custom.pm @@ -43,19 +43,18 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "smcli-command:s" => { name => 'smcli_command', default => 'SMcli' }, - "smcli-path:s" => { name => 'smcli_path', }, - "sudo:s" => { name => 'sudo', }, - "extra-options:s@" => { name => 'extra_options' }, - "special-arg:s@" => { name => 'special_arg' }, - "hostname:s@" => { name => 'hostname' }, - "hostname2:s@" => { name => 'hostname2' }, - "password:s@" => { name => 'password' }, - "timeout:s@" => { name => 'timeout' }, - "show-output:s" => { name => 'show_output' }, - }); + $options{options}->add_options(arguments => { + "smcli-command:s" => { name => 'smcli_command', default => 'SMcli' }, + "smcli-path:s" => { name => 'smcli_path', }, + "sudo:s" => { name => 'sudo', }, + "extra-options:s@" => { name => 'extra_options' }, + "special-arg:s@" => { name => 'special_arg' }, + "hostname:s@" => { name => 'hostname' }, + "hostname2:s@" => { name => 'hostname2' }, + "password:s@" => { name => 'password' }, + "timeout:s@" => { name => 'timeout' }, + "show-output:s" => { name => 'show_output' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'SMCLI OPTIONS', once => 1); @@ -84,15 +83,25 @@ sub set_defaults { # Manage default value foreach (keys %{$options{default}}) { if ($_ eq $self->{mode}) { - for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { - foreach my $opt (keys %{$options{default}->{$_}[$i]}) { - if (!defined($self->{option_results}->{$opt}[$i])) { - $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + if (ref($options{default}->{$_}) eq 'ARRAY') { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + + if (ref($options{default}->{$_}) eq 'HASH') { + foreach my $opt (keys %{$options{default}->{$_}}) { + if (!defined($self->{option_results}->{$opt})) { + $self->{option_results}->{$opt} = $options{default}->{$_}->{$opt}; } } } } - } + } } sub build_command { diff --git a/centreon/common/smcli/mode/healthstatus.pm b/centreon/common/smcli/mode/healthstatus.pm index f54cec81f..344b8a48e 100644 --- a/centreon/common/smcli/mode/healthstatus.pm +++ b/centreon/common/smcli/mode/healthstatus.pm @@ -31,10 +31,9 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "storage-command:s" => { name => 'storage_command', }, - }); + $options{options}->add_options(arguments => { + "storage-command:s" => { name => 'storage_command', }, + }); return $self; } diff --git a/centreon/common/sun/snmp/mode/components/entity.pm b/centreon/common/sun/snmp/mode/components/entity.pm index cc3cd4b9f..2d1cb47e0 100644 --- a/centreon/common/sun/snmp/mode/components/entity.pm +++ b/centreon/common/sun/snmp/mode/components/entity.pm @@ -39,13 +39,13 @@ my %map_sensor_type = (1 => 'other', 7 => 'counter', 8 => 'switch', 9 => 'lock', 10 => 'humidity', 11 => 'smokeDetection', 12 => 'presence', 13 => 'airFlow'); my %mapping_units = ( - 1 => '', 2 => '', - 3 => 'C', # Degrees C - 4 => 'F', # Degrees F - 5 => 'K', # Degrees K - 6 => 'V', # Volts - 7 => 'A', # Amps, - 8 => 'W', # Watts + 1 => 'unknown', 2 => 'unknown', + 3 => 'celsius', + 4 => 'fahrenheit', + 5 => 'kelvin', + 6 => 'volt', + 7 => 'ampere', + 8 => 'watt', 9 => 'Joules', 10 => 'Coulombs', 11 => 'VA', 12 => 'Nits', 13 => 'Lumens', 14 => 'Lux', 15 => 'Candelas', 16 => 'kPa', 17 => 'PSI', 18 => 'Newtons', @@ -54,20 +54,20 @@ my %mapping_units = ( 22 => 'Seconds', 23 => 'Minutes', 24 => 'Hours', 25 => 'Days', 26 => 'Weeks', 27 => 'Mils', 28 => 'Inches', 29 => 'Feet', 30 => 'Cubic_Inches', - 31 => 'Cubic_Feet', 32 => 'Meters', 33 => 'Cubic_Centimeters', - 34 => 'Cubic_Meters', 35 => 'Liters', 36 => 'Fluid_Ounces', + 31 => 'CubicFeet', 32 => 'Meters', 33 => 'CubicCentimeters', + 34 => 'CubicMeters', 35 => 'Liters', 36 => 'FluidOunces', 37 => 'Radians', 38 => 'Steradians', 39 => 'Revolutions', 40 => 'Cycles', 41 => 'Gravities', 42 => 'Ounces', - 43 => 'Pounds', 44 => 'Foot_Pounds', 45 => 'Ounce_Inches', + 43 => 'Pounds', 44 => 'FootPounds', 45 => 'OunceInches', 46 => 'Gauss', 47 => 'Gilberts', 48 => 'Henries', 49 => 'Farads', 50 => 'Ohms', 51 => 'Siemens', 52 => 'Moles', 53 => 'Becquerels', 54 => 'PPM', 55 => 'Decibels', 56 => 'DbA', 57 => 'DbC', - 58 => 'Grays', 59 => 'Sieverts', 60 => 'Color_Temperature_Degrees_K', - 61 => 'b', # bits - 62 => 'B', # Bytes + 58 => 'Grays', 59 => 'Sieverts', 60 => 'ColorTemperatureDegreesKelvin', + 61 => 'bits', + 62 => 'bytes', 63 => 'Words', 64 => 'DoubleWords', 65 => 'QuadWords', - 66 => '%', # Percentage, + 66 => 'percentage', 67 => 'Pascals', ); @@ -130,12 +130,15 @@ sub check { short_msg => sprintf("%s '%s' is '%s' %s", $result->{sunPlatSensorType}, $result->{entPhysicalName}, $result->{sunPlatNumericSensorCurrent}, $result->{sunPlatNumericSensorBaseUnits})); } - $self->{output}->perfdata_add(label => $result->{sunPlatSensorType} . '_' . $result->{entPhysicalName},, unit => $result->{sunPlatNumericSensorBaseUnits}, - value => $result->{sunPlatNumericSensorCurrent}, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => $result->{sunPlatSensorType}, unit => $result->{sunPlatNumericSensorBaseUnits}, + nlabel => 'hardware.entity.' . $result->{sunPlatSensorType} . '.' . lc($result->{sunPlatNumericSensorBaseUnits}), + instances => $result->{entPhysicalName}, + value => $result->{sunPlatNumericSensorCurrent}, + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/centreon/common/violin/snmp/mode/components/temperature.pm b/centreon/common/violin/snmp/mode/components/temperature.pm index c55409c10..4ef31563e 100644 --- a/centreon/common/violin/snmp/mode/components/temperature.pm +++ b/centreon/common/violin/snmp/mode/components/temperature.pm @@ -52,10 +52,14 @@ sub temperature { $self->{output}->output_add(long_msg => sprintf("Temperature '%s' is %s degree centigrade.", $instance, $temperature)); my ($exit, $warn, $crit) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $temperature); - $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', - value => $temperature, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $instance, + value => $temperature, + warning => $warn, + critical => $crit + ); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s degree centigrade", $instance, $temperature)); diff --git a/centreon/plugins/backend/http/curl.pm b/centreon/plugins/backend/http/curl.pm new file mode 100644 index 000000000..215395cae --- /dev/null +++ b/centreon/plugins/backend/http/curl.pm @@ -0,0 +1,460 @@ +# +# Copyright 2019 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 centreon::plugins::backend::http::curl; + +use strict; +use warnings; +use URI; +use centreon::plugins::misc; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{noptions}) || $options{noptions} != 1) { + $options{options}->add_options(arguments => { + "curl-opt:s@" => { name => 'curl_opt' }, + }); + $options{options}->add_help(package => __PACKAGE__, sections => 'BACKEND CURL OPTIONS', once => 1); + } + + $self->{output} = $options{output}; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'Net::Curl::Easy', + error_msg => "Cannot load module 'Net::Curl::Easy'."); + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'centreon::plugins::backend::http::curlconstants', + error_msg => "Cannot load module 'centreon::plugins::backend::http::curlconstants'."); + $self->{constant_cb} = \¢reon::plugins::backend::http::curlconstants::get_constant_value; + + foreach (('unknown_status', 'warning_status', 'critical_status')) { + if (defined($options{request}->{$_})) { + $options{request}->{$_} =~ s/%\{http_code\}/\$self->{response_code}/g; + } + } + + if (!defined($options{request}->{curl_opt})) { + $options{request}->{curl_opt} = []; + } +} + +my $http_code_explained = { + 100 => 'Continue', + 101 => 'Switching Protocols', + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 306 => '(Unused)', + 307 => 'Temporary Redirect', + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested Range Not Satisfiable', + 417 => 'Expectation Failed', + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported', +}; + +sub cb_debug { + my ($easy, $type, $data, $uservar) = @_; + + my $msg = ''; + if ($type == $uservar->{constant_cb}->(name => 'CURLINFO_TEXT')) { + $msg = sprintf("== Info: %s", $data); + } + if ($type == $uservar->{constant_cb}->(name => 'CURLINFO_HEADER_OUT')) { + $msg = sprintf("=> Send header: %s", $data); + } + if ($type == $uservar->{constant_cb}->(name => 'CURLINFO_DATA_OUT')) { + $msg = sprintf("=> Send data: %s", $data); + } + if ($type == $uservar->{constant_cb}->(name => 'CURLINFO_SSL_DATA_OUT')) { + $msg = sprintf("=> Send SSL data: %s", $data); + } + if ($type == $uservar->{constant_cb}->(name => 'CURLINFO_HEADER_IN')) { + $msg = sprintf("=> Recv header: %s", $data); + } + if ($type == $uservar->{constant_cb}->(name => 'CURLINFO_DATA_IN')) { + $msg = sprintf("=> Recv data: %s", $data); + } + if ($type == $uservar->{constant_cb}->(name => 'CURLINFO_SSL_DATA_IN')) { + $msg = sprintf("=> Recv SSL data: %s", $data); + } + + $uservar->{output}->output_add(long_msg => $msg, debug => 1); + return 0; +} + +sub curl_setopt { + my ($self, %options) = @_; + + eval { + $self->{curl_easy}->setopt($options{option}, $options{parameter}); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "curl setopt error: '" . $@ . "'."); + $self->{output}->option_exit(); + } +} + +sub set_method { + my ($self, %options) = @_; + + if ($options{request}->{method} eq 'GET') { + return ; + } + + if ($options{content_type_forced} == 1) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_POSTFIELDS'), parameter => $options{request}->{query_form_post}) + if (defined($options{request}->{query_form_post}) && $options{request}->{query_form_post} ne ''); + } elsif (defined($options{request}->{post_params})) { + my $uri_post = URI->new(); + $uri_post->query_form($options{request}->{post_params}); + push @{$options{headers}}, 'Content-Type: application/x-www-form-urlencoded'; + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_POSTFIELDS'), parameter => $uri_post->query); + } + + if ($options{request}->{method} eq 'POST') { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_POST'), parameter => 1); + } + if ($options{request}->{method} eq 'PUT') { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_CUSTOMREQUEST'), parameter => $options{request}->{method}); + } + if ($options{request}->{method} eq 'DELETE') { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_CUSTOMREQUEST'), parameter => $options{request}->{method}); + } +} + +sub set_auth { + my ($self, %options) = @_; + + if (defined($options{request}->{credentials})) { + if (defined($options{request}->{basic})) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HTTPAUTH'), parameter => $self->{constant_cb}->(name => 'CURLAUTH_BASIC')); + } elsif (defined($options{request}->{ntlmv2})) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HTTPAUTH'), parameter => $self->{constant_cb}->(name => 'CURLAUTH_NTLM')); + } else { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HTTPAUTH'), parameter => $self->{constant_cb}->(name => 'CURLAUTH_ANY')); + } + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_USERPWD'), parameter => $options{request}->{username} . ':' . $options{request}->{password}); + } + + if (defined($options{request}->{cert_file}) && $options{request}->{cert_file} ne '') { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_SSLCERT'), parameter => $options{request}->{cert_file}); + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_SSLKEY'), parameter => $options{request}->{key_file}); + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_KEYPASSWD'), parameter => $options{request}->{cert_pwd}); + } + + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_SSLCERTTYPE'), parameter => "PEM"); + if (defined($options{request}->{cert_pkcs12})) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_SSLCERTTYPE'), parameter => "P12"); + } +} + +sub set_proxy { + my ($self, %options) = @_; + + if (defined($options{request}->{proxyurl}) && $options{request}->{proxyurl} ne '') { + if ($options{request}->{proxyurl} =~ /^(?:http|https):\/\/(.*?):(.*?)@/) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_PROXYUSERNAME'), parameter => $1); + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_PROXYPASSWORD'), parameter => $2); + $options{request}->{proxyurl} =~ s/\/\/$1:$2@//; + } + + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_PROXY'), parameter => $options{request}->{proxyurl}); + } + + if (defined($options{request}->{proxypac}) && $options{request}->{proxypac} ne '') { + $self->{output}->add_option_msg(short_msg => 'Unsupported proxypac option'); + $self->{output}->option_exit(); + } +} + +sub set_extra_curl_opt { + my ($self, %options) = @_; + + my $fields = { key => '', value => '' }; + foreach (@{$options{request}->{curl_opt}}) { + ($fields->{key}, $fields->{value}) = split /=>/; + foreach my $label ('key', 'value') { + $fields->{$label} = centreon::plugins::misc::trim($fields->{$label}); + if ($fields->{$label} =~ /^CURLOPT|CURL/) { + $fields->{$label} = $self->{constant_cb}->(name => $fields->{$label}); + } + } + + $self->curl_setopt(option => $fields->{key}, parameter => $fields->{value}); + } +} + +sub cb_get_header { + my ($easy, $header, $uservar) = @_; + + $header =~ s/[\r\n]//g; + if ($header =~ /^[\r\n]*$/) { + $uservar->{nheaders}++; + } else { + $uservar->{response_headers}->[$uservar->{nheaders}] = {} + if (!defined($uservar->{response_headers}->[$uservar->{nheaders}])); + if ($header =~ /^(\S(?:.*?))\s*:\s*(.*)/) { + my $header_name = lc($1); + $uservar->{response_headers}->[$uservar->{nheaders}]->{$header_name} = [] + if (!defined($uservar->{response_headers}->[$uservar->{nheaders}]->{$header_name})); + push @{$uservar->{response_headers}->[$uservar->{nheaders}]->{$header_name}}, $2; + } else { + $uservar->{response_headers}->[$uservar->{nheaders}]->{response_line} = $header; + } + } + + return length($_[1]); +} + +sub request { + my ($self, %options) = @_; + + $self->{curl_easy} = Net::Curl::Easy->new(); + + if ($self->{output}->is_debug()) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_DEBUGFUNCTION'), parameter => \&cb_debug); + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_DEBUGDATA'), parameter => $self); + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_VERBOSE'), parameter => 1); + } + + if (defined($options{request}->{timeout})) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_TIMEOUT'), parameter => $options{request}->{timeout}); + } + if (defined($options{request}->{cookies_file})) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_COOKIEFILE'), parameter => $options{request}->{cookies_file}); + } + + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_FOLLOWLOCATION'), parameter => 1); + if (defined($options{request}->{no_follow})) { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_FOLLOWLOCATION'), parameter => 0); + } + + my $url; + if (defined($options{request}->{full_url})) { + $url = $options{request}->{full_url}; + } elsif (defined($options{request}->{port}) && $options{request}->{port} =~ /^[0-9]+$/) { + $url = $options{request}->{proto}. "://" . $options{request}->{hostname} . ':' . $options{request}->{port} . $options{request}->{url_path}; + } else { + $url = $options{request}->{proto}. "://" . $options{request}->{hostname} . $options{request}->{url_path}; + } + + if (defined($options{request}->{http_peer_addr}) && $options{request}->{http_peer_addr} ne '') { + $url =~ /^(?:http|https):\/\/(.*?)(\/|\:|$)/; + $self->{curl_easy}->pushopt($self->{constant_cb}->(name => 'CURLOPT_RESOLVE'), + [$1 . ':' . $options{request}->{port_force} . ':' . $options{request}->{http_peer_addr}]); + } + + my $uri = URI->new($url); + if (defined($options{request}->{get_params})) { + $uri->query_form($options{request}->{get_params}); + } + + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_URL'), parameter => $uri); + + my $headers = []; + my $content_type_forced = 0; + foreach my $key (keys %{$options{request}->{headers}}) { + push @$headers, $key . ':' . $options{request}->{headers}->{$key}; + if ($key =~ /content-type/i) { + $content_type_forced = 1; + } + } + + $self->set_method(%options, content_type_forced => $content_type_forced, headers => $headers); + + if (scalar(@$headers) > 0) { + $self->{curl_easy}->pushopt($self->{constant_cb}->(name => 'CURLOPT_HTTPHEADER'), $headers); + } + + if (defined($options{request}->{cacert_file}) && $options{request}->{cacert_file} ne '') { + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_CAINFO'), parameter => $options{request}->{cacert_file}); + } + + $self->set_auth(%options); + $self->set_proxy(%options); + $self->set_extra_curl_opt(%options); + + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_FILE'), parameter => \$self->{response_body}); + $self->{nheaders} = 0; + $self->{response_headers} = [{}]; + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HEADERDATA'), parameter => $self); + $self->curl_setopt(option => $self->{constant_cb}->(name => 'CURLOPT_HEADERFUNCTION'), parameter => \&cb_get_header); + + eval { + $self->{curl_easy}->perform(); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => 'curl perform error : ' . $@); + $self->{output}->option_exit(); + } + + $self->{response_code} = $self->{curl_easy}->getinfo($self->{constant_cb}->(name => 'CURLINFO_RESPONSE_CODE')); + + # Check response + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($options{request}->{critical_status}) && $options{request}->{critical_status} ne '' && + eval "$options{request}->{critical_status}") { + $status = 'critical'; + } elsif (defined($options{request}->{warning_status}) && $options{request}->{warning_status} ne '' && + eval "$options{request}->{warning_status}") { + $status = 'warning'; + } elsif (defined($options{request}->{unknown_status}) && $options{request}->{unknown_status} ne '' && + eval "$options{request}->{unknown_status}") { + $status = 'unknown'; + } + }; + if (defined($message)) { + $self->{output}->add_option_msg(short_msg => 'filter status issue: ' . $message); + $self->{output}->option_exit(); + } + + if (!$self->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { + my $short_msg = $self->{response_code} . ' ' . + (defined($http_code_explained->{$self->{response_code}}) ? $http_code_explained->{$self->{response_code}} : 'unknown'); + + $self->{output}->output_add(severity => $status, + short_msg => $short_msg); + $self->{output}->display(); + $self->{output}->exit(); + } + + return $self->{response_body}; +} + +sub get_headers { + my ($self, %options) = @_; + + my $headers = ''; + foreach (keys %{$self->{response_headers}->[$options{nheader}]}) { + next if (/response_line/); + foreach my $value (@{$self->{response_headers}->[$options{nheader}]->{$_}}) { + $headers .= "$_: " . $value . "\n"; + } + } + + return $headers; +} + +sub get_first_header { + my ($self, %options) = @_; + + if (!defined($options{name})) { + return $self->get_headers(nheader => 0); + } + + return undef + if (!defined($self->{response_headers}->[0]->{ lc($options{name}) })); + return wantarray ? @{$self->{response_headers}->[0]->{ lc($options{name}) }} : $self->{response_headers}->[0]->{ lc($options{name}) }->[0]; +} + +sub get_header { + my ($self, %options) = @_; + + if (!defined($options{name})) { + return $self->get_headers(nheader => -1); + } + + return undef + if (!defined($self->{response_headers}->[-1]->{ lc($options{name}) })); + return wantarray ? @{$self->{response_headers}->[-1]->{ lc($options{name}) }} : $self->{response_headers}->[-1]->{ lc($options{name}) }->[0]; +} + +sub get_code { + my ($self, %options) = @_; + + return $self->{response_code}; +} + +sub get_message { + my ($self, %options) = @_; + + return $http_code_explained->{$self->{response_code}}; +} + +1; + +__END__ + +=head1 NAME + +HTTP Curl backend layer. + +=head1 SYNOPSIS + +HTTP Curl backend layer. + +=head1 BACKEND CURL OPTIONS + +=over 8 + +=item B<--curl-opt> + +Set CURL Options (--curl-opt="CURLOPT_SSL_VERIFYPEER => 0" --curl-opt="CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_1" ). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon/plugins/backend/http/curlconstants.pm b/centreon/plugins/backend/http/curlconstants.pm new file mode 100644 index 000000000..6c30d01f2 --- /dev/null +++ b/centreon/plugins/backend/http/curlconstants.pm @@ -0,0 +1,33 @@ +# +# Copyright 2019 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 centreon::plugins::backend::http::curlconstants; + +use strict; +use warnings; +use Net::Curl::Easy qw(:constants); + +sub get_constant_value { + my (%options) = @_; + + return eval $options{name}; +} + +1; diff --git a/centreon/plugins/backend/http/lwp.pm b/centreon/plugins/backend/http/lwp.pm new file mode 100644 index 000000000..fc2a4447b --- /dev/null +++ b/centreon/plugins/backend/http/lwp.pm @@ -0,0 +1,336 @@ +# +# Copyright 2019 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 centreon::plugins::backend::http::lwp; + +use strict; +use warnings; +use centreon::plugins::backend::http::useragent; +use URI; +use IO::Socket::SSL; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{noptions}) || $options{noptions} != 1) { + $options{options}->add_options(arguments => { + "ssl:s" => { name => 'ssl' }, + "ssl-opt:s@" => { name => 'ssl_opt' }, + }); + $options{options}->add_help(package => __PACKAGE__, sections => 'BACKEND LWP OPTIONS', once => 1); + } + + $self->{output} = $options{output}; + $self->{ua} = undef; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + + foreach (('unknown_status', 'warning_status', 'critical_status')) { + if (defined($options{request}->{$_})) { + $options{request}->{$_} =~ s/%\{http_code\}/\$self->{response}->code/g; + } + } + + $self->{ssl_context} = ''; + if (!defined($options{request}->{ssl_opt})) { + $options{request}->{ssl_opt} = []; + } + if (defined($options{request}->{ssl}) && $options{request}->{ssl} ne '') { + push @{$options{request}->{ssl_opt}}, 'SSL_version => ' . $options{request}->{ssl}; + } + if (defined($options{request}->{cert_file}) && !defined($options{request}->{cert_pkcs12})) { + push @{$options{request}->{ssl_opt}}, 'SSL_use_cert => 1'; + push @{$options{request}->{ssl_opt}}, 'SSL_cert_file => "' . $options{request}->{cert_file} . '"'; + push @{$options{request}->{ssl_opt}}, 'SSL_key_file => "' . $options{request}->{key_file} . '"' + if (defined($options{request}->{key_file})); + push @{$options{request}->{ssl_opt}}, 'SSL_ca_file => "' . $options{request}->{cacert_file} . '"' + if (defined($options{request}->{cacert_file})); + } + my $append = ''; + foreach (@{$options{request}->{ssl_opt}}) { + if ($_ ne '') { + $self->{ssl_context} .= $append . $_; + $append = ', '; + } + } +} + +sub set_proxy { + my ($self, %options) = @_; + + if (defined($options{request}->{proxypac}) && $options{request}->{proxypac} ne '') { + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'HTTP::ProxyPAC', + error_msg => "Cannot load module 'HTTP::ProxyPAC'."); + my ($pac, $pac_uri); + eval { + if ($options{request}->{proxypac} =~ /^(http|https):\/\//) { + $pac_uri = URI->new($options{request}->{proxypac}); + $pac = HTTP::ProxyPAC->new($pac_uri); + } else { + $pac = HTTP::ProxyPAC->new($options{request}->{proxypac}); + } + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => 'issue to load proxypac: ' . $@); + $self->{output}->option_exit(); + } + my $res = $pac->find_proxy($options{url}); + if (defined($res->direct) && $res->direct != 1) { + my $proxy_uri = URI->new($res->proxy); + $proxy_uri->userinfo($pac_uri->userinfo) if (defined($pac_uri->userinfo)); + $self->{ua}->proxy(['http', 'https'], $proxy_uri->as_string); + } + } + if (defined($options{request}->{proxyurl}) && $options{request}->{proxyurl} ne '') { + $self->{ua}->proxy(['http', 'https'], $options{request}->{proxyurl}); + } +} + +sub request { + my ($self, %options) = @_; + + my $request_options = $options{request}; + if (!defined($self->{ua})) { + $self->{ua} = centreon::plugins::backend::http::useragent->new( + keep_alive => 1, protocols_allowed => ['http', 'https'], timeout => $request_options->{timeout}, + credentials => $request_options->{credentials}, username => $request_options->{username}, password => $request_options->{password}); + if (defined($request_options->{cookies_file})) { + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'HTTP::Cookies', + error_msg => "Cannot load module 'HTTP::Cookies'."); + $self->{ua}->cookie_jar(HTTP::Cookies->new(file => $request_options->{cookies_file}, + autosave => 1)); + } + } + + if ($self->{output}->is_debug()) { + $self->{ua}->add_handler("request_send", sub { + my ($response, $ua, $handler) = @_; + + $self->{output}->output_add(long_msg => "======> request send", debug => 1); + $self->{output}->output_add(long_msg => $response->as_string, debug => 1); + return ; + }); + $self->{ua}->add_handler("response_done", sub { + my ($response, $ua, $handler) = @_; + + $self->{output}->output_add(long_msg => "======> response done", debug => 1); + $self->{output}->output_add(long_msg => $response->as_string, debug => 1); + return ; + }); + } + + if (defined($request_options->{no_follow})) { + $self->{ua}->requests_redirectable(undef); + } else { + $self->{ua}->requests_redirectable([ 'GET', 'HEAD', 'POST' ]); + } + if (defined($request_options->{http_peer_addr})) { + push @LWP::Protocol::http::EXTRA_SOCK_OPTS, PeerAddr => $request_options->{http_peer_addr}; + } + + my ($req, $url); + if (defined($request_options->{full_url})) { + $url = $request_options->{full_url}; + } elsif (defined($request_options->{port}) && $request_options->{port} =~ /^[0-9]+$/) { + $url = $request_options->{proto}. "://" . $request_options->{hostname} . ':' . $request_options->{port} . $request_options->{url_path}; + } else { + $url = $request_options->{proto}. "://" . $request_options->{hostname} . $request_options->{url_path}; + } + + my $uri = URI->new($url); + if (defined($request_options->{get_params})) { + $uri->query_form($request_options->{get_params}); + } + $req = HTTP::Request->new($request_options->{method}, $uri); + + my $content_type_forced; + foreach my $key (keys %{$request_options->{headers}}) { + if ($key !~ /content-type/i) { + $req->header($key => $request_options->{headers}->{$key}); + } else { + $content_type_forced = $request_options->{headers}->{$key}; + } + } + + if ($request_options->{method} eq 'POST') { + if (defined($content_type_forced)) { + $req->content_type($content_type_forced); + $req->content($request_options->{query_form_post}); + } else { + my $uri_post = URI->new(); + if (defined($request_options->{post_params})) { + $uri_post->query_form($request_options->{post_params}); + } + $req->content_type('application/x-www-form-urlencoded'); + $req->content($uri_post->query); + } + } + + if (defined($request_options->{credentials}) && defined($request_options->{ntlmv2})) { + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'Authen::NTLM', + error_msg => "Cannot load module 'Authen::NTLM'."); + Authen::NTLM::ntlmv2(1); + } + + if (defined($request_options->{credentials}) && defined($request_options->{basic})) { + $req->authorization_basic($request_options->{username}, $request_options->{password}); + } + + $self->set_proxy(request => $request_options, url => $url); + + if (defined($request_options->{cert_pkcs12}) && $request_options->{cert_file} ne '' && $request_options->{cert_pwd} ne '') { + eval "use Net::SSL"; die $@ if $@; + $ENV{HTTPS_PKCS12_FILE} = $request_options->{cert_file}; + $ENV{HTTPS_PKCS12_PASSWORD} = $request_options->{cert_pwd}; + } + + if (defined($self->{ssl_context}) && $self->{ssl_context} ne '') { + my $context = new IO::Socket::SSL::SSL_Context(eval $self->{ssl_context}); + IO::Socket::SSL::set_default_context($context); + } + + $self->{response} = $self->{ua}->request($req); + + # Check response + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($request_options->{critical_status}) && $request_options->{critical_status} ne '' && + eval "$request_options->{critical_status}") { + $status = 'critical'; + } elsif (defined($request_options->{warning_status}) && $request_options->{warning_status} ne '' && + eval "$request_options->{warning_status}") { + $status = 'warning'; + } elsif (defined($request_options->{unknown_status}) && $request_options->{unknown_status} ne '' && + eval "$request_options->{unknown_status}") { + $status = 'unknown'; + } + }; + if (defined($message)) { + $self->{output}->add_option_msg(short_msg => 'filter status issue: ' . $message); + $self->{output}->option_exit(); + } + + if (!$self->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { + my $short_msg = $self->{response}->status_line; + if ($short_msg =~ /^401/) { + $short_msg .= ' (' . $1 . ' authentication expected)' if (defined($self->{response}->www_authenticate) && + $self->{response}->www_authenticate =~ /(\S+)/); + } + + $self->{output}->output_add(long_msg => $self->{response}->content, debug => 1); + $self->{output}->output_add(severity => $status, + short_msg => $short_msg); + $self->{output}->display(); + $self->{output}->exit(); + } + + $self->{headers} = $self->{response}->headers(); + return $self->{response}->content; +} + +sub get_headers { + my ($self, %options) = @_; + + my $headers = ''; + foreach ($options{response}->header_field_names()) { + $headers .= "$_: " . $options{response}->header($_) . "\n"; + } + + return $headers; +} + +sub get_first_header { + my ($self, %options) = @_; + + my @redirects = $self->{response}->redirects(); + if (!defined($options{name})) { + return $self->get_headers(response => defined($redirects[0]) ? $redirects[0] : $self->{response}); + } + + return + defined($redirects[0]) ? + $redirects[0]->headers()->header($options{name}) : + $self->{headers}->header($options{name}) + ; +} + +sub get_header { + my ($self, %options) = @_; + + if (!defined($options{name})) { + return $self->get_headers(response => $self->{response}); + } + return $self->{headers}->header($options{name}); +} + +sub get_code { + my ($self, %options) = @_; + + return $self->{response}->code(); +} + +sub get_message { + my ($self, %options) = @_; + + return $self->{response}->message(); +} + +1; + +__END__ + +=head1 NAME + +HTTP LWP backend layer. + +=head1 SYNOPSIS + +HTTP LWP backend layer. + +=head1 BACKEND LWP OPTIONS + +=over 8 + +=item B<--ssl-opt> + +Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). + +=item B<--ssl> + +Set SSL version (--ssl=TLSv1). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon/plugins/useragent.pm b/centreon/plugins/backend/http/useragent.pm similarity index 89% rename from centreon/plugins/useragent.pm rename to centreon/plugins/backend/http/useragent.pm index 5eca396e9..f9a9b419f 100644 --- a/centreon/plugins/useragent.pm +++ b/centreon/plugins/backend/http/useragent.pm @@ -1,5 +1,5 @@ # -# Copyright 2017 Centreon (http://www.centreon.com/) +# Copyright 2019 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -18,7 +18,7 @@ # limitations under the License. # -package centreon::plugins::useragent; +package centreon::plugins::backend::http::useragent; use strict; use warnings; @@ -30,7 +30,7 @@ sub new { bless $self, $class; $self = LWP::UserAgent::new(@_); - $self->agent("centreon::plugins::useragent"); + $self->agent("centreon::plugins::backend::http::useragent"); $self->{credentials} = $options{credentials} if defined($options{credentials}); $self->{username} = $options{username} if defined($options{username}); diff --git a/centreon/plugins/dbi.pm b/centreon/plugins/dbi.pm index e981a93e1..690aa318b 100644 --- a/centreon/plugins/dbi.pm +++ b/centreon/plugins/dbi.pm @@ -46,13 +46,13 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { "datasource:s@" => { name => 'data_source' }, - "username:s@" => { name => 'username' }, - "password:s@" => { name => 'password' }, - "connect-options:s@" => { name => 'connect_options' }, - "sql-errors-exit:s" => { name => 'sql_errors_exit', default => 'unknown' }, - "timeout:i" => { name => 'timeout' }, + $options{options}->add_options(arguments => { + 'datasource:s@' => { name => 'data_source' }, + 'username:s@' => { name => 'username' }, + 'password:s@' => { name => 'password' }, + 'connect-options:s@' => { name => 'connect_options' }, + 'sql-errors-exit:s' => { name => 'sql_errors_exit', default => 'unknown' }, + 'timeout:i' => { name => 'timeout' }, }); } $options{options}->add_help(package => __PACKAGE__, sections => 'DBI OPTIONS', once => 1); @@ -93,8 +93,9 @@ sub class_handle_ALRM { sub handle_ALRM { my $self = shift; + $self->disconnect(); $self->{output}->output_add(severity => $self->{sql_errors_exit}, - short_msg => "Timeout"); + short_msg => 'Timeout'); $self->{output}->display(); $self->{output}->exit(); } @@ -145,7 +146,7 @@ sub check_options { } if (!defined($self->{data_source}) || $self->{data_source} eq '') { - $self->{output}->add_option_msg(short_msg => "Need to specify data_source arguments."); + $self->{output}->add_option_msg(short_msg => 'Need to specify data_source arguments.'); $self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit}); } if (defined($self->{connect_options}) && $self->{connect_options} ne '') { @@ -196,6 +197,15 @@ sub set_version { $self->{version} = $self->{instance}->get_info(18); # SQL_DBMS_VER } + +sub disconnect { + my ($self) = @_; + + if (defined($self->{instance})) { + $self->{statement_handle} = undef; + $self->{instance}->disconnect(); + } +} sub connect { my ($self, %options) = @_; @@ -213,12 +223,12 @@ sub connect { "DBI:". $self->{data_source}, $self->{username}, $self->{password}, - { "RaiseError" => 0, "PrintError" => 0, "AutoCommit" => 1, %{$self->{connect_options_hash}} } + { RaiseError => 0, PrintError => 0, AutoCommit => 1, %{$self->{connect_options_hash}} } ); alarm(0) if (defined($self->{timeout})); if (!defined($self->{instance})) { - my $err_msg = sprintf("Cannot connect: %s", defined($DBI::errstr) ? $DBI::errstr : "(no error string)"); + my $err_msg = sprintf('Cannot connect: %s', defined($DBI::errstr) ? $DBI::errstr : '(no error string)'); if ($dontquit == 0) { $self->{output}->add_option_msg(short_msg => $err_msg); $self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit}); @@ -267,14 +277,16 @@ sub query { $self->{statement_handle} = $self->{instance}->prepare($options{query}); if (!defined($self->{statement_handle})) { return 1 if ($continue_error == 1); - $self->{output}->add_option_msg(short_msg => "Cannot execute query: " . $self->{instance}->errstr); + $self->{output}->add_option_msg(short_msg => 'Cannot execute query: ' . $self->{instance}->errstr); + $self->disconnect(); $self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit}); } my $rv = $self->{statement_handle}->execute; if (!$rv) { return 1 if ($continue_error == 1); - $self->{output}->add_option_msg(short_msg => "Cannot execute query: " . $self->{statement_handle}->errstr); + $self->{output}->add_option_msg(short_msg => 'Cannot execute query: ' . $self->{statement_handle}->errstr); + $self->disconnect(); $self->{output}->option_exit(exit_litteral => $self->{sql_errors_exit}); } diff --git a/centreon/plugins/http.pm b/centreon/plugins/http.pm index 113d12b74..ad0f86f1b 100644 --- a/centreon/plugins/http.pm +++ b/centreon/plugins/http.pm @@ -22,18 +22,31 @@ package centreon::plugins::http; use strict; use warnings; -use centreon::plugins::useragent; -use HTTP::Cookies; -use URI; -use IO::Socket::SSL; sub new { my ($class, %options) = @_; my $self = {}; bless $self, $class; + if (!defined($options{noptions}) || $options{noptions} != 1) { + $options{options}->add_options(arguments => { + "http-peer-addr:s" => { name => 'http_peer_addr' }, + "proxyurl:s" => { name => 'proxyurl' }, + "proxypac:s" => { name => 'proxypac' }, + "http-backend:s" => { name => 'http_backend', default => 'lwp' }, + }); + $options{options}->add_help(package => __PACKAGE__, sections => 'HTTP GLOBAL OPTIONS'); + } + + centreon::plugins::misc::mymodule_load(output => $options{output}, module => 'centreon::plugins::backend::http::lwp', + error_msg => "Cannot load module 'centreon::plugins::backend::http::lwp'."); + $self->{backend_lwp} = centreon::plugins::backend::http::lwp->new(%options); + + centreon::plugins::misc::mymodule_load(output => $options{output}, module => 'centreon::plugins::backend::http::curl', + error_msg => "Cannot load module 'centreon::plugins::backend::http::curl'."); + $self->{backend_curl} = centreon::plugins::backend::http::curl->new(%options); + $self->{output} = $options{output}; - $self->{ua} = undef; $self->{options} = { proto => 'http', url_path => '/', @@ -43,6 +56,7 @@ sub new { warning_status => undef, critical_status => undef, }; + $self->{add_headers} = {}; return $self; } @@ -65,6 +79,14 @@ sub add_header { sub check_options { my ($self, %options) = @_; + $options{request}->{http_backend} = 'lwp' + if (!defined($options{request}->{http_backend}) || $options{request}->{http_backend} eq ''); + $self->{http_backend} = $options{request}->{http_backend}; + if ($self->{http_backend} !~ /^\s*lwp|curl\s*$/i) { + $self->{output}->add_option_msg(short_msg => "Unsupported http backend specified '" . $self->{http_backend} . "'."); + $self->{output}->option_exit(); + } + if (($options{request}->{proto} ne 'http') && ($options{request}->{proto} ne 'https')) { $self->{output}->add_option_msg(short_msg => "Unsupported protocol specified '" . $self->{option_results}->{proto} . "'."); $self->{output}->option_exit(); @@ -77,12 +99,12 @@ sub check_options { $self->{output}->add_option_msg(short_msg => "You need to set --username= and --password= options when --credentials is used"); $self->{output}->option_exit(); } - if ((defined($options{request}->{pkcs12})) && (!defined($options{request}->{cert_file}) && !defined($options{request}->{cert_pwd}))) { + if ((defined($options{request}->{cert_pkcs12})) && (!defined($options{request}->{cert_file}) && !defined($options{request}->{cert_pwd}))) { $self->{output}->add_option_msg(short_msg => "You need to set --cert-file= and --cert-pwd= options when --pkcs12 is used"); $self->{output}->option_exit(); } - $options{request}->{port} = $self->get_port_request(); + $options{request}->{port_force} = $self->get_port(); $options{request}->{headers} = {}; if (defined($options{request}->{header})) { @@ -98,52 +120,25 @@ sub check_options { foreach my $method (('get', 'post')) { if (defined($options{request}->{$method . '_param'})) { - $self->{$method . '_params'} = {}; + $options{request}->{$method . '_params'} = {}; foreach (@{$options{request}->{$method . '_param'}}) { if (/^([^=]+)={0,1}(.*)$/) { my $key = $1; my $value = defined($2) ? $2 : 1; - if (defined($self->{$method . '_params'}->{$key})) { - if (ref($self->{$method . '_params'}->{$key}) ne 'ARRAY') { - $self->{$method . '_params'}->{$key} = [ $self->{$method . '_params'}->{$key} ]; + if (defined($options{request}->{$method . '_params'}->{$key})) { + if (ref($options{request}->{$method . '_params'}->{$key}) ne 'ARRAY') { + $options{request}->{$method . '_params'}->{$key} = [ $options{request}->{$method . '_params'}->{$key} ]; } - push @{$self->{$method . '_params'}->{$key}}, $value; + push @{$options{request}->{$method . '_params'}->{$key}}, $value; } else { - $self->{$method . '_params'}->{$key} = $value; + $options{request}->{$method . '_params'}->{$key} = $value; } } } } } - - foreach (('unknown_status', 'warning_status', 'critical_status')) { - if (defined($options{request}->{$_})) { - $options{request}->{$_} =~ s/%\{http_code\}/\$response->code/g; - } - } - - $self->{ssl_context} = ''; - if (!defined($options{request}->{ssl_opt})) { - $options{request}->{ssl_opt} = []; - } - if (defined($options{request}->{ssl}) && $options{request}->{ssl} ne '') { - push @{$options{request}->{ssl_opt}}, 'SSL_version => ' . $options{request}->{ssl}; - } - if (defined($options{request}->{cert_file}) && !defined($options{request}->{cert_pkcs12})) { - push @{$options{request}->{ssl_opt}}, 'SSL_use_cert => 1'; - push @{$options{request}->{ssl_opt}}, 'SSL_cert_file => "' . $options{request}->{cert_file} . '"'; - push @{$options{request}->{ssl_opt}}, 'SSL_key_file => "' . $options{request}->{key_file} . '"' - if (defined($options{request}->{key_file})); - push @{$options{request}->{ssl_opt}}, 'SSL_ca_file => "' . $options{request}->{cacert_file} . '"' - if (defined($options{request}->{cacert_file})); - } - my $append = ''; - foreach (@{$options{request}->{ssl_opt}}) { - if ($_ ne '') { - $self->{ssl_context} .= $append . $_; - $append = ', '; - } - } + + $self->{'backend_' . $self->{http_backend}}->check_options(%options); } sub get_port { @@ -170,37 +165,6 @@ sub get_port_request { return $port; } -sub set_proxy { - my ($self, %options) = @_; - - if (defined($options{request}->{proxypac}) && $options{request}->{proxypac} ne '') { - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'HTTP::ProxyPAC', - error_msg => "Cannot load module 'HTTP::ProxyPAC'."); - my ($pac, $pac_uri); - eval { - if ($options{request}->{proxypac} =~ /^(http|https):\/\//) { - $pac_uri = URI->new($options{request}->{proxypac}); - $pac = HTTP::ProxyPAC->new($pac_uri); - } else { - $pac = HTTP::ProxyPAC->new($options{request}->{proxypac}); - } - }; - if ($@) { - $self->{output}->add_option_msg(short_msg => 'issue to load proxypac: ' . $@); - $self->{output}->option_exit(); - } - my $res = $pac->find_proxy($options{url}); - if (defined($res->direct) && $res->direct != 1) { - my $proxy_uri = URI->new($res->proxy); - $proxy_uri->userinfo($pac_uri->userinfo) if (defined($pac_uri->userinfo)); - $self->{ua}->proxy(['http', 'https'], $proxy_uri->as_string); - } - } - if (defined($options{request}->{proxyurl}) && $options{request}->{proxyurl} ne '') { - $self->{ua}->proxy(['http', 'https'], $options{request}->{proxyurl}); - } -} - sub request { my ($self, %options) = @_; @@ -210,140 +174,70 @@ sub request { } $self->check_options(request => $request_options); - if (!defined($self->{ua})) { - $self->{ua} = centreon::plugins::useragent->new(keep_alive => 1, protocols_allowed => ['http', 'https'], timeout => $request_options->{timeout}, - credentials => $request_options->{credentials}, username => $request_options->{username}, password => $request_options->{password}); - if (defined($request_options->{cookies_file})) { - $self->{ua}->cookie_jar(HTTP::Cookies->new(file => $request_options->{cookies_file}, - autosave => 1)); - } - } - if (defined($request_options->{no_follow})) { - $self->{ua}->requests_redirectable(undef); - } else { - $self->{ua}->requests_redirectable([ 'GET', 'HEAD', 'POST' ]); - } - if (defined($request_options->{http_peer_addr})) { - push @LWP::Protocol::http::EXTRA_SOCK_OPTS, PeerAddr => $request_options->{http_peer_addr}; - } + return $self->{'backend_' . $self->{http_backend}}->request(request => $request_options); +} - my ($response, $content); - my ($req, $url); - if (defined($request_options->{full_url})) { - $url = $request_options->{full_url}; - } elsif (defined($request_options->{port}) && $request_options->{port} =~ /^[0-9]+$/) { - $url = $request_options->{proto}. "://" . $request_options->{hostname} . ':' . $request_options->{port} . $request_options->{url_path}; - } else { - $url = $request_options->{proto}. "://" . $request_options->{hostname} . $request_options->{url_path}; - } +sub get_first_header { + my ($self, %options) = @_; - my $uri = URI->new($url); - if (defined($self->{get_params})) { - $uri->query_form($self->{get_params}); - } - $req = HTTP::Request->new($request_options->{method}, $uri); - - my $content_type_forced; - foreach my $key (keys %{$request_options->{headers}}) { - if ($key !~ /content-type/i) { - $req->header($key => $request_options->{headers}->{$key}); - } else { - $content_type_forced = $request_options->{headers}->{$key}; - } - } - - if ($request_options->{method} eq 'POST') { - if (defined($content_type_forced)) { - $req->content_type($content_type_forced); - $req->content($request_options->{query_form_post}); - } else { - my $uri_post = URI->new(); - if (defined($self->{post_params})) { - $uri_post->query_form($self->{post_params}); - } - $req->content_type('application/x-www-form-urlencoded'); - $req->content($uri_post->query); - } - } - - if (defined($request_options->{credentials}) && defined($request_options->{ntlmv2})) { - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'Authen::NTLM', - error_msg => "Cannot load module 'Authen::NTLM'."); - Authen::NTLM::ntlmv2(1); - } - - if (defined($request_options->{credentials}) && defined($request_options->{basic})) { - $req->authorization_basic($request_options->{username}, $request_options->{password}); - } - - $self->set_proxy(request => $request_options, url => $url); - - if (defined($request_options->{cert_pkcs12}) && $request_options->{cert_file} ne '' && $request_options->{cert_pwd} ne '') { - eval "use Net::SSL"; die $@ if $@; - $ENV{HTTPS_PKCS12_FILE} = $request_options->{cert_file}; - $ENV{HTTPS_PKCS12_PASSWORD} = $request_options->{cert_pwd}; - } - - if (defined($self->{ssl_context}) && $self->{ssl_context} ne '') { - my $context = new IO::Socket::SSL::SSL_Context(eval $self->{ssl_context}); - IO::Socket::SSL::set_default_context($context); - } - - $response = $self->{ua}->request($req); - - # Check response - my $status = 'ok'; - my $message; - - eval { - local $SIG{__WARN__} = sub { $message = $_[0]; }; - local $SIG{__DIE__} = sub { $message = $_[0]; }; - - if (defined($request_options->{critical_status}) && $request_options->{critical_status} ne '' && - eval "$request_options->{critical_status}") { - $status = 'critical'; - } elsif (defined($request_options->{warning_status}) && $request_options->{warning_status} ne '' && - eval "$request_options->{warning_status}") { - $status = 'warning'; - } elsif (defined($request_options->{unknown_status}) && $request_options->{unknown_status} ne '' && - eval "$request_options->{unknown_status}") { - $status = 'unknown'; - } - }; - if (defined($message)) { - $self->{output}->add_option_msg(short_msg => 'filter status issue: ' . $message); - $self->{output}->option_exit(); - } - - if (!$self->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { - my $short_msg = $response->status_line; - if ($short_msg =~ /^401/) { - my ($authenticate) = $response->www_authenticate =~ /(\S+)/; - $short_msg .= ' (' . $authenticate . ' authentication expected)'; - } - - $self->{output}->output_add(long_msg => $response->content, debug => 1); - $self->{output}->output_add(severity => $status, - short_msg => $short_msg); - $self->{output}->display(); - $self->{output}->exit(); - } - - $self->{headers} = $response->headers(); - $self->{response} = $response; - return $response->content; + return $self->{'backend_' . $self->{http_backend}}->get_first_header(%options); } sub get_header { my ($self, %options) = @_; - return $self->{headers}; + return $self->{'backend_' . $self->{http_backend}}->get_header(%options); } -sub get_response { +sub get_code { my ($self, %options) = @_; - return $self->{response}; + return $self->{'backend_' . $self->{http_backend}}->get_code(); +} + +sub get_message { + my ($self, %options) = @_; + + return $self->{'backend_' . $self->{http_backend}}->get_message(); } 1; + +__END__ + +=head1 NAME + +HTTP abstraction layer. + +=head1 SYNOPSIS + +HTTP abstraction layer for lwp and curl backends + +=head1 HTTP GLOBAL OPTIONS + +=over 8 + +=item B<--http-peer-addr> + +Set the address you want to connect (Useful if hostname is only a vhost. no ip resolve) + +=item B<--proxyurl> + +Proxy URL + +=item B<--proxypac> + +Proxy pac file (can be an url or local file) + +=item B<--http-backend> + +Set the backend used (Default: 'lwp') +For curl: --http-backend=curl + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon/plugins/misc.pm b/centreon/plugins/misc.pm index 24bcafe11..ca8b22cef 100644 --- a/centreon/plugins/misc.pm +++ b/centreon/plugins/misc.pm @@ -51,23 +51,22 @@ sub windows_execute { $| = 1; pipe FROM_CHILD, TO_PARENT or do { - $options{output}->output_add(severity => 'UNKNOWN', - short_msg => "Internal error: can't create pipe from child to parent: $!"); - $options{output}->display(); - $options{output}->exit(); + $options{output}->add_option_msg(short_msg => "Internal error: can't create pipe from child to parent: $!"); + $options{output}->option_exit(); }; my $job = Win32::Job->new; + my $stderr = 'NUL'; + $stderr = \*TO_PARENT if ($options{output}->is_debug()); if (!($pid = $job->spawn(undef, $cmd, - { stdout => \*TO_PARENT, - stderr => \*TO_PARENT }))) { - $options{output}->output_add(severity => 'UNKNOWN', - short_msg => "Internal error: execution issue: $^E"); - $options{output}->display(); - $options{output}->exit(); + { stdin => 'NUL', + stdout => \*TO_PARENT, + stderr => $stderr }))) { + $options{output}->add_option_msg(short_msg => "Internal error: execution issue: $^E"); + $options{output}->option_exit(); } close TO_PARENT; - my $ein = ""; + my $ein = ''; vec($ein, fileno(FROM_CHILD), 1) = 1; $job->watch( sub { @@ -97,10 +96,8 @@ sub windows_execute { close FROM_CHILD; if ($ended == 0) { - $options{output}->output_add(severity => 'UNKNOWN', - short_msg => "Command too long to execute (timeout)..."); - $options{output}->display(); - $options{output}->exit(); + $options{output}->add_option_msg(short_msg => 'Command too long to execute (timeout)...'); + $options{output}->option_exit(); } chomp $stdout; @@ -110,10 +107,8 @@ sub windows_execute { if ($result->{$pid}->{exitcode} != 0) { $stdout =~ s/\n/ - /g; - $options{output}->output_add(severity => 'UNKNOWN', - short_msg => "Command error: $stdout"); - $options{output}->display(); - $options{output}->exit(); + $options{output}->add_option_msg(short_msg => "Command error: $stdout"); + $options{output}->option_exit(); } return ($stdout, $result->{$pid}->{exitcode}); @@ -124,6 +119,11 @@ sub unix_execute { my $cmd = ''; my $args = []; my ($lerror, $stdout, $exit_code); + + my $redirect_stderr = 1; + $redirect_stderr = $options{redirect_stderr} if (defined($options{redirect_stderr})); + my $wait_exit = 1; + $wait_exit = $options{wait_exit} if (defined($options{wait_exit})); # Build command line # Can choose which command is done remotely (can filter and use local file) @@ -152,21 +152,21 @@ sub unix_execute { $sub_cmd .= $options{command_options} if (defined($options{command_options})); # On some equipment. Cannot get a pseudo terminal if (defined($options{ssh_pipe}) && $options{ssh_pipe} == 1) { - $cmd = "echo '" . $sub_cmd . "' | " . $cmd . ' ' . join(" ", @$args); + $cmd = "echo '" . $sub_cmd . "' | " . $cmd . ' ' . join(' ', @$args); ($lerror, $stdout, $exit_code) = backtick( - command => $cmd, - timeout => $options{options}->{timeout}, - wait_exit => 1, - redirect_stderr => 1 - ); + command => $cmd, + timeout => $options{options}->{timeout}, + wait_exit => $wait_exit, + redirect_stderr => $redirect_stderr + ); } else { ($lerror, $stdout, $exit_code) = backtick( - command => $cmd, - arguments => [@$args, $sub_cmd], - timeout => $options{options}->{timeout}, - wait_exit => 1, - redirect_stderr => 1 - ); + command => $cmd, + arguments => [@$args, $sub_cmd], + timeout => $options{options}->{timeout}, + wait_exit => $wait_exit, + redirect_stderr => $redirect_stderr + ); } } else { $cmd = 'sudo ' if (defined($options{sudo})); @@ -175,11 +175,11 @@ sub unix_execute { $cmd .= $options{command_options} if (defined($options{command_options})); ($lerror, $stdout, $exit_code) = backtick( - command => $cmd, - timeout => $options{options}->{timeout}, - wait_exit => 1, - redirect_stderr => 1 - ); + command => $cmd, + timeout => $options{options}->{timeout}, + wait_exit => $wait_exit, + redirect_stderr => $redirect_stderr + ); } if (defined($options{options}->{show_output}) && @@ -190,10 +190,8 @@ sub unix_execute { $stdout =~ s/\r//g; if ($lerror <= -1000) { - $options{output}->output_add(severity => 'UNKNOWN', - short_msg => $stdout); - $options{output}->display(); - $options{output}->exit(); + $options{output}->add_option_msg(short_msg => $stdout); + $options{output}->option_exit(); } if (defined($options{no_quit}) && $options{no_quit} == 1) { @@ -202,10 +200,8 @@ sub unix_execute { if ($exit_code != 0 && (!defined($options{no_errors}) || !defined($options{no_errors}->{$exit_code}))) { $stdout =~ s/\n/ - /g; - $options{output}->output_add(severity => 'UNKNOWN', - short_msg => "Command error: $stdout"); - $options{output}->display(); - $options{output}->exit(); + $options{output}->add_option_msg(short_msg => "Command error: $stdout"); + $options{output}->option_exit(); } return $stdout; @@ -214,7 +210,7 @@ sub unix_execute { sub mymodule_load { my (%options) = @_; my $file; - ($file = ($options{module} =~ /\.pm$/ ? $options{module} : $options{module} . ".pm")) =~ s{::}{/}g; + ($file = ($options{module} =~ /\.pm$/ ? $options{module} : $options{module} . '.pm')) =~ s{::}{/}g; eval { local $SIG{__DIE__} = 'IGNORE'; @@ -278,7 +274,7 @@ sub backtick { } alarm(0); - return (-1000, "Command too long to execute (timeout)...", -1); + return (-1000, 'Command too long to execute (timeout)...', -1); } else { if ($arg{wait_exit} == 1) { # We're waiting the exit code @@ -295,7 +291,7 @@ sub backtick { setpgrp( 0, 0 ); if ($arg{redirect_stderr} == 1) { - open STDERR, ">&STDOUT"; + open STDERR, '>&STDOUT'; } if (scalar(@{$arg{arguments}}) <= 0) { exec($arg{command}); @@ -324,7 +320,7 @@ sub powershell_encoded { require Encode; require MIME::Base64; - my $bytes = Encode::encode("utf16LE", $value); + my $bytes = Encode::encode('utf16LE', $value); my $script = MIME::Base64::encode_base64($bytes, "\n"); $script =~ s/\n//g; return $script; @@ -339,6 +335,18 @@ sub powershell_escape { return $value; } +sub powershell_json_sanitizer { + my (%options) = @_; + + centreon::plugins::misc::mymodule_load(output => $options{output}, module => 'JSON::XS', + error_msg => "Cannot load module 'JSON::XS'."); + foreach my $line (split /\n/, $options{string}) { + eval { JSON::XS->new->utf8->decode($line) }; + return $line if (!$@); + } + return -1; +} + sub minimal_version { my ($version_src, $version_dst) = @_; @@ -366,13 +374,13 @@ sub change_seconds { my %options = @_; my ($str, $str_append) = ('', ''); my $periods = [ - { unit => 'y', value => 31556926 }, - { unit => 'M', value => 2629743 }, - { unit => 'w', value => 604800 }, - { unit => 'd', value => 86400 }, - { unit => 'h', value => 3600 }, - { unit => 'm', value => 60 }, - { unit => 's', value => 1 }, + { unit => 'y', value => 31556926 }, + { unit => 'M', value => 2629743 }, + { unit => 'w', value => 604800 }, + { unit => 'd', value => 86400 }, + { unit => 'h', value => 3600 }, + { unit => 'm', value => 60 }, + { unit => 's', value => 1 }, ]; my %values = ('y' => 1, 'M' => 2, 'w' => 3, 'd' => 4, 'h' => 5, 'm' => 6, 's' => 7); @@ -451,15 +459,29 @@ sub parse_threshold { my (%options) = @_; my $perf = trim($options{threshold}); - my $perf_result = { arobase => 0, infinite_neg => 0, infinite_pos => 0, start => "", end => "" }; + my $perf_result = { arobase => 0, infinite_neg => 0, infinite_pos => 0, start => '', end => '' }; my $global_status = 1; - if ($perf =~ /^(\@?)((?:~|(?:\+|-)?\d+(?:[\.,]\d+)?|):)?((?:\+|-)?\d+(?:[\.,]\d+)?)?$/) { + if ($perf =~ /^(\@?)((?:~|(?:\+|-)?\d+(?:[\.,]\d+)?(?:[KMGTPE][bB])?|):)?((?:\+|-)?\d+(?:[\.,]\d+)?(?:[KMGTPE][bB])?)?$/) { $perf_result->{start} = $2 if (defined($2)); $perf_result->{end} = $3 if (defined($3)); $perf_result->{arobase} = 1 if (defined($1) && $1 eq '@'); $perf_result->{start} =~ s/[\+:]//g; $perf_result->{end} =~ s/\+//; + if ($perf_result->{start} =~ s/([KMGTPE])([bB])//) { + $perf_result->{start} = scale_bytesbit( + value => $perf_result->{start}, + src_unit => $2, dst_unit => $2, + src_quantity => $1, dst_quantity => '', + ); + } + if ($perf_result->{end} =~ s/([KMGTPE])([bB])//) { + $perf_result->{end} = scale_bytesbit( + value => $perf_result->{end}, + src_unit => $2, dst_unit => $2, + src_quantity => $1, dst_quantity => '', + ); + } if ($perf_result->{end} eq '') { $perf_result->{end} = 1e500; $perf_result->{infinite_pos} = 1; @@ -482,10 +504,10 @@ sub parse_threshold { sub get_threshold_litteral { my (%options) = @_; - my $perf_output = ($options{arobase} == 1 ? "@" : "") . - (($options{infinite_neg} == 0) ? $options{start} : "~") . - ":" . - (($options{infinite_pos} == 0) ? $options{end} : ""); + my $perf_output = ($options{arobase} == 1 ? '@' : '') . + (($options{infinite_neg} == 0) ? $options{start} : '~') . + ':' . + (($options{infinite_pos} == 0) ? $options{end} : ''); return $perf_output; } diff --git a/centreon/plugins/mode.pm b/centreon/plugins/mode.pm index e95bd6556..739f6b8a8 100644 --- a/centreon/plugins/mode.pm +++ b/centreon/plugins/mode.pm @@ -30,8 +30,11 @@ sub new { bless $self, $class; $self->{perfdata} = centreon::plugins::perfdata->new(output => $options{output}); + %{$self->{option_results}} = (); $self->{output} = $options{output}; + $self->{output}->use_new_perfdata(value => 1) + if (defined($options{force_new_perfdata}) && $options{force_new_perfdata} == 1); $self->{mode} = $options{mode}; $self->{version} = undef; diff --git a/centreon/plugins/nrpe.pm b/centreon/plugins/nrpe.pm new file mode 100644 index 000000000..033a44001 --- /dev/null +++ b/centreon/plugins/nrpe.pm @@ -0,0 +1,418 @@ +# +# Copyright 2019 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 centreon::plugins::nrpe; + +use strict; +use warnings; +use Convert::Binary::C; +use Digest::CRC 'crc32'; +use IO::Socket; +use IO::Socket::INET6; +use IO::Socket::SSL; +use Socket qw(SOCK_STREAM AF_INET6 AF_INET); + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class NRPE: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class NRPE: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "nrpe-version:s" => { name => 'nrpe_version', default => 2 }, + "nrpe-port:s" => { name => 'nrpe_port', default => 5666 }, + "nrpe-payload:s" => { name => 'nrpe_payload', default => 1024 }, + "nrpe-bindaddr:s" => { name => 'nrpe_bindaddr' }, + "nrpe-use-ipv4" => { name => 'nrpe_use_ipv4' }, + "nrpe-use-ipv6" => { name => 'nrpe_use_ipv6' }, + "nrpe-timeout:s" => { name => 'nrpe_timeout', default => 10 }, + "ssl-opt:s@" => { name => 'ssl_opt' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'NRPE CLASS OPTIONS'); + + $self->{output} = $options{output}; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + + $options{option_results}->{nrpe_version} =~ s/^v//; + if ($options{option_results}->{nrpe_version} !~ /2|3/) { + $self->{output}->add_option_msg(short_msg => "Unknown NRPE version."); + $self->{output}->option_exit(); + } + $self->{nrpe_version} = $options{option_results}->{nrpe_version}; + $self->{nrpe_payload} = $options{option_results}->{nrpe_payload}; + + %{$self->{nrpe_params}} = ( + PeerHost => $options{option_results}->{hostname}, + PeerPort => $options{option_results}->{nrpe_port}, + Timeout => $options{option_results}->{nrpe_timeout}, + ); + if ($options{option_results}->{bindaddr}) { + $self->{nrpe_params}->{LocalAddr} = $options{option_results}->{nrpe_bindaddr}; + } + if ($options{option_results}->{nrpe_use_ipv4}) { + $self->{nrpe_params}->{Domain} = AF_INET; + } elsif ($options{option_results}->{nrpe_use_ipv6}) { + $self->{nrpe_params}->{Domain} = AF_INET6; + } + + foreach (@{$options{option_results}->{ssl_opt}}) { + if ($_ ne '' && $_ =~ /(.*)\s*=>\s*(.*)/) { + $self->{ssl_context}->{$1} = $2; + } + } +} + +sub create_socket { + my ($self, %options) = @_; + + my $socket; + + if (defined($self->{ssl_context}) && $self->{ssl_context} ne '') { + IO::Socket::SSL::set_ctx_defaults(%{$self->{ssl_context}}); + $socket = IO::Socket::SSL->new(%{$self->{nrpe_params}}); + if (!$socket) { + $self->{output}->add_option_msg(short_msg => "Failed to establish SSL connection: $!, ssl_error=$SSL_ERROR"); + $self->{output}->option_exit(); + } + } else { + $socket = IO::Socket::INET6->new(Proto => 'tcp', Type => SOCK_STREAM, %{$self->{nrpe_params}}); + if (!$socket) { + $self->{output}->add_option_msg(short_msg => "Failed to create socket: $!"); + $self->{output}->option_exit(); + } + } + + return $socket; +} + +sub assemble { + my ($self, %options) = @_; + + $self->{c} = Convert::Binary::C->new(ByteOrder => 'BigEndian', Alignment => 0); + + my $packed; + if ($options{version} eq 2) { + $packed = $self->assemble_v2(%options); + } else { + $packed = $self->assemble_v3(%options); + } + return $packed; +} + +sub assemble_v3 { + my ($self, %options) = @_; + + my $buffer = $options{check}; + my $len = length($buffer); + + # In order for crc32 calculation to be correct we need to pad the buffer with \0 + # It seems that the buffer must be in multiples of 1024 so to achive this we use + # some integer arithmetic to find the next multiple of 1024 that can hold our message + my $pack_len; + { + use integer; + $pack_len = (($len / 1024) * 1024) + 1024; + } + $buffer = pack("Z$pack_len", $buffer); + $len = length($buffer) + 1; + + my $unpacked; + $unpacked->{alignment} = 0; + $unpacked->{buffer_length} = $len; + $unpacked->{buffer} = $buffer; + $unpacked->{crc32_value} = "\x00\x00\x00\x00"; + $unpacked->{packet_type} = $options{type} // 1; + $unpacked->{packet_version} = 3; + $unpacked->{result_code} = $options{result_code} // 2324; + + $self->{c}->parse(<{c}->tag('Packet.buffer', Format => 'String'); + my $packed = $self->{c}->pack('Packet', $unpacked); + + $unpacked->{crc32_value} = crc32($packed); + $packed = $self->{c}->pack('Packet', $unpacked); + return $packed; +} + +sub assemble_v2 { + my ($self, %options) = @_; + + my $len = $options{payload}; + + my $unpacked; + $unpacked->{buffer} = $options{check}; + $unpacked->{crc32_value} = "\x00\x00\x00\x00"; + $unpacked->{packet_type} = $options{type} // 1; + $unpacked->{packet_version} = 2; + $unpacked->{result_code} = $options{result_code} // 2324; + + $self->{c}->parse(<{c}->tag('Packet.buffer', Format => 'String'); + my $packed = $self->{c}->pack('Packet', $unpacked); + + $unpacked->{crc32_value} = crc32($packed); + $packed = $self->{c}->pack('Packet', $unpacked); + return $packed; +} + +sub validate { + my ($self, $packet) = @_; + + my $unpacked = $self->disassemble($packet, 1); + if (!$unpacked->{packet_version}) { + # If version is missing this is probably not an NRPE Packet. + return undef; + } + my $checksum = $unpacked->{crc32_value}; + $unpacked->{crc32_value} = "\x00\x00\x00\x00"; + my $packed = $self->assemble( + %{ + { + check => $unpacked->{buffer}, + version => $unpacked->{packet_version}, + type => $unpacked->{packet_type}, + result_code => $unpacked->{result_code} + } + } + ); + if (crc32($packed) != $checksum) { + return undef; + } else { + return 1; + } +} + +sub disassemble { + my ($self, $packet, $novalidate) = @_; + + if (!$packet) { + $self->{output}->add_option_msg(short_msg => "Could not disassemble packet."); + $self->{output}->option_exit(); + } + unless ($novalidate) { + unless ($self->validate($packet)) { + $self->{output}->add_option_msg(short_msg => "Packet had invalid CRC32."); + $self->{output}->option_exit(); + } + } + + my $version = unpack("n", $packet); + if (!defined($version) || $version eq '') { + $self->{output}->add_option_msg(short_msg => "Could not disassemble packet."); + $self->{output}->option_exit(); + } + + my $unpacked = {}; + if ($version eq 2) { + $unpacked = $self->disassemble_v2($packet); + } else { + $unpacked = $self->disassemble_v3($packet); + } + + return $unpacked; +} + +sub disassemble_v3 { + my ($self, $packet) = @_; + + my @arr = unpack("n2 N n2 N Z*", $packet); + my $unpacked = {}; + $unpacked->{packet_version} = $arr[0]; + $unpacked->{packet_type} = $arr[1]; + $unpacked->{crc32_value} = $arr[2]; + $unpacked->{result_code} = $arr[3]; + $unpacked->{alignment} = $arr[4]; + $unpacked->{buffer_length} = $arr[5]; + $unpacked->{buffer} = $arr[6]; + return $unpacked; +} + +sub disassemble_v2 { + my ($self, $packet) = @_; + + my @arr = unpack("n2 N n Z*", $packet); + my $unpacked = {}; + $unpacked->{packet_version} = $arr[0]; + $unpacked->{packet_type} = $arr[1]; + $unpacked->{crc32_value} = $arr[2]; + $unpacked->{result_code} = $arr[3]; + $unpacked->{buffer} = $arr[4]; + return $unpacked; +} + +sub request { + my ($self, %options) = @_; + + my $check; + if (!defined($options{arg}) || scalar @{$options{arg}} == 0) { + $check = $options{check}; + } else { + $check = join('!', $options{check}, @{$options{arg}}); + } + + my $socket = $self->create_socket(%options); + + my $assembled = $self->assemble( + type => 1, + check => $check, + version => $self->{nrpe_version}, + payload => $self->{nrpe_payload} + ); + + my $response; + print $socket $assembled; + while (<$socket>) { + $response .= $_; + } + close($socket); + + if (!defined($response) || $response eq '') { + $self->{output}->add_option_msg(short_msg => "No response from remote host."); + $self->{output}->option_exit(); + } + + my $response_packet = $self->disassemble($response, 1); + if (!defined($response_packet->{packet_version}) || $response_packet->{packet_version} != $self->{nrpe_version}) { + $self->{output}->add_option_msg(short_msg => "Bad response from remote host."); + $self->{output}->option_exit(); + } + + return $response_packet; +} + +sub set_nrpe_connect_params { + my ($self, %options) = @_; + + foreach (keys %options) { + $self->{nrpe_params}->{$_} = $options{$_}; + } +} + +sub set_nrpe_params { + my ($self, %options) = @_; + + foreach (keys %options) { + $self->{$_} = $options{$_}; + } +} + +sub get_hostname { + my ($self) = @_; + + my $host = $self->{nrpe_params}->{PeerHost}; + $host =~ s/.*://; + return $host; +} + +sub get_port { + my ($self) = @_; + + return $self->{nrpe_params}->{PeerPort}; +} + +1; + +__END__ + +=head1 NAME + +NRPE global + +=head1 SYNOPSIS + +NRPE class + +=head1 NRPE CLASS OPTIONS + +=over 8 + +=item B<--nrpe-version> + +Version: 2 for NRPE v2 (Default), 3 for NRPE v3. + +=item B<--nrpe-port> + +Port (Default: 5666). + +=item B<--nrpe-payload> + +Buffer payload (For v2 only) (Default: 1024). + +=item B<--nrpe-bindaddr> + +Bind to local address. + +=item B<--nrpe-use-ipv4> + +Use IPv4 only + +=item B<--nrpe-use-ipv6> + +Use IPv6 only + +=item B<--nrpe-timeout> + +Timeout in secondes (Default: 10). + +=item B<--ssl-opt> + +Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => 0" +--ssl-opt="SSL_cipher_list => ALL"). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon/plugins/options.pm b/centreon/plugins/options.pm index b158d9801..ba22d1650 100644 --- a/centreon/plugins/options.pm +++ b/centreon/plugins/options.pm @@ -46,6 +46,7 @@ sub new { Getopt::Long::Configure('no_auto_abbrev'); } else { require centreon::plugins::alternative::Getopt; + $centreon::plugins::alternative::Getopt::warn_message = 0; centreon::plugins::alternative::Getopt->import(); } @@ -114,11 +115,17 @@ sub add_options { # $options{arguments} = ref to hash table with string and name to store (example: { 'mode:s' => { name => 'mode', default => 'defaultvalue' ) foreach (keys %{$options{arguments}}) { + if (defined($options{arguments}->{$_}->{redirect})) { + $self->{options}->{$_} = \$self->{options_stored}->{$options{arguments}->{$_}->{redirect}}; + next; + } + if (defined($options{arguments}->{$_}->{default})) { $self->{options_stored}->{$options{arguments}->{$_}->{name}} = $options{arguments}->{$_}->{default}; } else { $self->{options_stored}->{$options{arguments}->{$_}->{name}} = undef; } + $self->{options}->{$_} = \$self->{options_stored}->{$options{arguments}->{$_}->{name}}; } } diff --git a/centreon/plugins/output.pm b/centreon/plugins/output.pm index 509e3b597..2795d08da 100644 --- a/centreon/plugins/output.pm +++ b/centreon/plugins/output.pm @@ -20,9 +20,9 @@ package centreon::plugins::output; -use centreon::plugins::misc; use strict; use warnings; +use centreon::plugins::misc; sub new { my ($class, %options) = @_; @@ -33,23 +33,28 @@ sub new { exit 3; } - $options{options}->add_options(arguments => - { - "explode-perfdata-max:s@" => { name => 'explode_perfdata_max' }, - "range-perfdata:s" => { name => 'range_perfdata' }, - "filter-perfdata:s" => { name => 'filter_perfdata' }, - "change-perfdata:s@" => { name => 'change_perfdata' }, - "extend-perfdata:s@" => { name => 'extend_perfdata' }, - "filter-uom:s" => { name => 'filter_uom' }, - "verbose" => { name => 'verbose' }, - "debug" => { name => 'debug' }, - "opt-exit:s" => { name => 'opt_exit', default => 'unknown' }, - "output-xml" => { name => 'output_xml' }, - "output-json" => { name => 'output_json' }, - "output-file:s" => { name => 'output_file' }, - "disco-format" => { name => 'disco_format' }, - "disco-show" => { name => 'disco_show' }, - }); + $options{options}->add_options(arguments => { + 'explode-perfdata-max:s@' => { name => 'explode_perfdata_max' }, + 'range-perfdata:s' => { name => 'range_perfdata' }, + 'filter-perfdata:s' => { name => 'filter_perfdata' }, + 'change-perfdata:s@' => { name => 'change_perfdata' }, + 'extend-perfdata:s@' => { name => 'extend_perfdata' }, + 'extend-perfdata-group:s@'=> { name => 'extend_perfdata_group' }, + 'change-short-output:s@' => { name => 'change_short_output' }, + 'use-new-perfdata' => { name => 'use_new_perfdata' }, + 'filter-uom:s' => { name => 'filter_uom' }, + 'verbose' => { name => 'verbose' }, + 'debug' => { name => 'debug' }, + 'opt-exit:s' => { name => 'opt_exit', default => 'unknown' }, + 'output-xml' => { name => 'output_xml' }, + 'output-json' => { name => 'output_json' }, + 'output-openmetrics' => { name => 'output_openmetrics' }, + 'output-file:s' => { name => 'output_file' }, + 'disco-format' => { name => 'disco_format' }, + 'disco-show' => { name => 'disco_show' }, + 'float-precision:s' => { name => 'float_precision', default => 8 }, + }); + %{$self->{option_results}} = (); $self->{option_msg} = []; @@ -125,6 +130,7 @@ sub check_options { } $self->load_perfdata_extend_args(); + $self->{option_results}->{use_new_perfdata} = 1 if (defined($self->{option_results}->{output_openmetrics})); } sub add_option_msg { @@ -150,12 +156,12 @@ sub set_status { sub output_add { my ($self, %params) = @_; my %args = ( - severity => 'OK', - separator => ' - ', - debug => 0, - short_msg => undef, - long_msg => undef, - ); + severity => 'OK', + separator => ' - ', + debug => 0, + short_msg => undef, + long_msg => undef, + ); my $options = {%args, %params}; if (defined($options->{short_msg})) { @@ -178,11 +184,27 @@ sub output_add { sub perfdata_add { my ($self, %options) = @_; - my $perfdata = {label => '', value => '', unit => '', warning => '', critical => '', min => '', max => ''}; + my $perfdata = { + label => '', value => '', unit => '', warning => '', critical => '', min => '', max => '' + }; foreach (keys %options) { next if (!defined($options{$_})); $perfdata->{$_} = $options{$_}; } + + if (defined($self->{option_results}->{use_new_perfdata}) && defined($options{nlabel})) { + $perfdata->{label} = $options{nlabel}; + } + if (defined($options{instances})) { + $options{instances} = [$options{instances}] if (!ref($options{instances})); + my ($external_instance_separator, $internal_instance_separator) = ('#', '~'); + if (defined($self->{option_results}->{use_new_perfdata})) { + $perfdata->{label} = join('~', @{$options{instances}}) . '#' . $perfdata->{label}; + } else { + $perfdata->{label} .= '_' . join('_', @{$options{instances}}); + } + } + $perfdata->{label} =~ s/'/''/g; push @{$self->{perfdatas}}, $perfdata; } @@ -206,14 +228,15 @@ sub output_json { my ($self, %options) = @_; my $force_ignore_perfdata = (defined($options{force_ignore_perfdata}) && $options{force_ignore_perfdata} == 1) ? 1 : 0; my $force_long_output = (defined($options{force_long_output}) && $options{force_long_output} == 1) ? 1 : 0; - my $json_content = {plugin => { - name => $self->{plugin}, - mode => $self->{mode}, - exit => $options{exit_litteral}, - outputs => [], - perfdatas => [] - } - }; + my $json_content = { + plugin => { + name => $self->{plugin}, + mode => $self->{mode}, + exit => $options{exit_litteral}, + outputs => [], + perfdatas => [] + } + }; foreach my $code_litteral (keys %{$self->{global_short_outputs}}) { foreach (@{$self->{global_short_outputs}->{$code_litteral}}) { @@ -221,19 +244,19 @@ sub output_json { my $lcode_litteral = ($code_litteral eq 'UNQUALIFIED_YET' ? uc($options{exit_litteral}) : $code_litteral); push @{$json_content->{plugin}->{outputs}}, { - type => 1, - msg => ($options{nolabel} == 0 ? ($lcode_litteral . ': ') : '') . $_, - exit => $lcode_litteral - }; + type => 1, + msg => ($options{nolabel} == 0 ? ($lcode_litteral . ': ') : '') . $_, + exit => $lcode_litteral + }; } } if (defined($self->{option_results}->{verbose}) || $force_long_output == 1) { foreach (@{$self->{global_long_output}}) { push @{$json_content->{plugin}->{outputs}}, { - type => 2, - msg => $_, - }; + type => 2, + msg => $_, + }; } } @@ -252,8 +275,8 @@ sub output_json { } push @{$json_content->{plugin}->{perfdatas}}, { - %values - }; + %values + }; } } @@ -269,17 +292,17 @@ sub output_xml { my $root = $self->{xml_output}->createElement('plugin'); $self->{xml_output}->setDocumentElement($root); - $child_plugin_name = $self->{xml_output}->createElement("name"); + $child_plugin_name = $self->{xml_output}->createElement('name'); $child_plugin_name->appendText($self->{plugin}); - $child_plugin_mode = $self->{xml_output}->createElement("mode"); + $child_plugin_mode = $self->{xml_output}->createElement('mode'); $child_plugin_mode->appendText($self->{mode}); - $child_plugin_exit = $self->{xml_output}->createElement("exit"); + $child_plugin_exit = $self->{xml_output}->createElement('exit'); $child_plugin_exit->appendText($options{exit_litteral}); - $child_plugin_output = $self->{xml_output}->createElement("outputs"); - $child_plugin_perfdata = $self->{xml_output}->createElement("perfdatas"); + $child_plugin_output = $self->{xml_output}->createElement('outputs'); + $child_plugin_perfdata = $self->{xml_output}->createElement('perfdatas'); $root->addChild($child_plugin_name); $root->addChild($child_plugin_mode); @@ -292,15 +315,15 @@ sub output_xml { my ($child_output, $child_type, $child_msg, $child_exit); my $lcode_litteral = ($code_litteral eq 'UNQUALIFIED_YET' ? uc($options{exit_litteral}) : $code_litteral); - $child_output = $self->{xml_output}->createElement("output"); + $child_output = $self->{xml_output}->createElement('output'); $child_plugin_output->addChild($child_output); - $child_type = $self->{xml_output}->createElement("type"); + $child_type = $self->{xml_output}->createElement('type'); $child_type->appendText(1); # short - $child_msg = $self->{xml_output}->createElement("msg"); + $child_msg = $self->{xml_output}->createElement('msg'); $child_msg->appendText(($options{nolabel} == 0 ? ($lcode_litteral . ': ') : '') . $_); - $child_exit = $self->{xml_output}->createElement("exit"); + $child_exit = $self->{xml_output}->createElement('exit'); $child_exit->appendText($lcode_litteral); $child_output->addChild($child_type); @@ -313,13 +336,13 @@ sub output_xml { foreach (@{$self->{global_long_output}}) { my ($child_output, $child_type, $child_msg); - $child_output = $self->{xml_output}->createElement("output"); + $child_output = $self->{xml_output}->createElement('output'); $child_plugin_output->addChild($child_output); - $child_type = $self->{xml_output}->createElement("type"); + $child_type = $self->{xml_output}->createElement('type'); $child_type->appendText(2); # long - $child_msg = $self->{xml_output}->createElement("msg"); + $child_msg = $self->{xml_output}->createElement('msg'); $child_msg->appendText($_); $child_output->addChild($child_type); @@ -335,7 +358,7 @@ sub output_xml { $self->range_perfdata(ranges => [\$perf->{warning}, \$perf->{critical}]); my ($child_perfdata); - $child_perfdata = $self->{xml_output}->createElement("perfdata"); + $child_perfdata = $self->{xml_output}->createElement('perfdata'); $child_plugin_perfdata->addChild($child_perfdata); foreach my $key (keys %$perf) { $perf->{$key} = '' if (defined($self->{option_results}->{filter_uom}) && $key eq 'unit' && @@ -350,15 +373,36 @@ sub output_xml { print $self->{xml_output}->toString(1); } -sub output_txt { +sub output_openmetrics { my ($self, %options) = @_; - my $force_ignore_perfdata = (defined($options{force_ignore_perfdata}) && $options{force_ignore_perfdata} == 1) ? 1 : 0; - my $force_long_output = (defined($options{force_long_output}) && $options{force_long_output} == 1) ? 1 : 0; - if (defined($self->{global_short_concat_outputs}->{UNQUALIFIED_YET})) { - $self->output_add(severity => uc($options{exit_litteral}), short_msg => $self->{global_short_concat_outputs}->{UNQUALIFIED_YET}); + $self->change_perfdata(); + foreach my $perf (@{$self->{perfdatas}}) { + next if (defined($self->{option_results}->{filter_perfdata}) && + $perf->{label} !~ /$self->{option_results}->{filter_perfdata}/); + $perf->{unit} = '' if (defined($self->{option_results}->{filter_uom}) && + $perf->{unit} !~ /$self->{option_results}->{filter_uom}/); + $self->range_perfdata(ranges => [\$perf->{warning}, \$perf->{critical}]); + my $label = $perf->{label}; + my $instance; + if ($label =~ /^(.*?)#(.*)$/) { + ($perf->{instance}, $label) = ($1, $2); + } + my ($bucket, $append) = ('{plugin="' . $self->{plugin} . '",mode="' . $self->{mode} . '"', ''); + foreach ('unit', 'warning', 'critical', 'min', 'max', 'instance') { + if (defined($perf->{$_}) && $perf->{$_} ne '') { + $bucket .= ',' . $_ . '="' . $perf->{$_} . '"'; + } + } + $bucket .= '}'; + + print $label . $bucket . ' ' . $perf->{value} . "\n"; } +} +sub output_txt_short_display { + my ($self, %options) = @_; + if (defined($self->{global_short_concat_outputs}->{CRITICAL})) { print (($options{nolabel} == 0 ? 'CRITICAL: ' : '') . $self->{global_short_concat_outputs}->{CRITICAL} . " "); } @@ -371,11 +415,49 @@ sub output_txt { if (uc($options{exit_litteral}) eq 'OK') { print (($options{nolabel} == 0 ? 'OK: ' : '') . (defined($self->{global_short_concat_outputs}->{OK}) ? $self->{global_short_concat_outputs}->{OK} : '') . " "); } +} + +sub output_txt_short { + my ($self, %options) = @_; + + if (!defined($self->{option_results}->{change_short_output})) { + $self->output_txt_short_display(%options); + return ; + } + + my $stdout = ''; + { + local *STDOUT; + open STDOUT, '>', \$stdout; + $self->output_txt_short_display(%options); + } + + foreach (@{$self->{option_results}->{change_short_output}}) { + my ($pattern, $replace, $modifier) = split /~/; + next if (!defined($pattern)); + $replace = '' if (!defined($replace)); + $modifier = '' if (!defined($modifier)); + eval "\$stdout =~ s{$pattern}{$replace}$modifier"; + } + + print $stdout; +} + +sub output_txt { + my ($self, %options) = @_; + my $force_ignore_perfdata = (defined($options{force_ignore_perfdata}) && $options{force_ignore_perfdata} == 1) ? 1 : 0; + my $force_long_output = (defined($options{force_long_output}) && $options{force_long_output} == 1) ? 1 : 0; + + if (defined($self->{global_short_concat_outputs}->{UNQUALIFIED_YET})) { + $self->output_add(severity => uc($options{exit_litteral}), short_msg => $self->{global_short_concat_outputs}->{UNQUALIFIED_YET}); + } + + $self->output_txt_short(%options); if ($force_ignore_perfdata == 1) { print "\n"; } else { - print "|"; + print '|'; $self->change_perfdata(); foreach my $perf (@{$self->{perfdatas}}) { next if (defined($self->{option_results}->{filter_perfdata}) && @@ -383,7 +465,7 @@ sub output_txt { $perf->{unit} = '' if (defined($self->{option_results}->{filter_uom}) && $perf->{unit} !~ /$self->{option_results}->{filter_uom}/); $self->range_perfdata(ranges => [\$perf->{warning}, \$perf->{critical}]); - print " '" . $perf->{label} . "'=" . $perf->{value} . $perf->{unit} . ";" . $perf->{warning} . ";" . $perf->{critical} . ";" . $perf->{min} . ";" . $perf->{max}; + print " '" . $perf->{label} . "'=" . $perf->{value} . $perf->{unit} . ';' . $perf->{warning} . ';' . $perf->{critical} . ';' . $perf->{min} . ';' . $perf->{max}; } print "\n"; } @@ -425,11 +507,16 @@ sub display { force_ignore_perfdata => $force_ignore_perfdata, force_long_output => $force_long_output); return ; } - } + } elsif (defined($self->{option_results}->{output_openmetrics})) { + $self->output_openmetrics(); + return ; + } - $self->output_txt(exit_litteral => $self->get_litteral_status(), - nolabel => $nolabel, - force_ignore_perfdata => $force_ignore_perfdata, force_long_output => $force_long_output); + $self->output_txt( + exit_litteral => $self->get_litteral_status(), + nolabel => $nolabel, + force_ignore_perfdata => $force_ignore_perfdata, force_long_output => $force_long_output + ); } sub die_exit { @@ -478,7 +565,7 @@ sub option_exit { $self->output_json(exit_litteral => $exit_litteral, nolabel => $nolabel, force_ignore_perfdata => 1, force_long_output => 1); $self->exit(exit_litteral => $exit_litteral); } - } + } $self->output_txt(exit_litteral => $exit_litteral, nolabel => $nolabel, force_ignore_perfdata => 1, force_long_output => 1); $self->exit(exit_litteral => $exit_litteral); @@ -642,7 +729,7 @@ sub display_disco_show { $self->{xml_output}->setDocumentElement($root); foreach (@{$self->{disco_entries}}) { - my $child = $self->{xml_output}->createElement("label"); + my $child = $self->{xml_output}->createElement('label'); foreach my $key (keys %$_) { $child->setAttribute($key, $_->{$key}); } @@ -669,8 +756,6 @@ sub to_utf8 { my ($self, $value) = @_; if ($self->{encode_utf8_import} == 0) { - - # Some Perl version dont have the following module (like Perl 5.6.x) if (centreon::plugins::misc::mymodule_load(no_quit => 1, module => 'Encode', error_msg => "Cannot load module 'Encode'.")) { @@ -727,6 +812,26 @@ sub is_debug { return 0; } +sub use_new_perfdata { + my ($self, %options) = @_; + + $self->{option_results}->{use_new_perfdata} = $options{value} + if (defined($options{value})); + if (defined($self->{option_results}->{use_new_perfdata})) { + return 1; + } + return 0; +} + +sub get_instance_perfdata_separator { + my ($self) = @_; + + if (defined($self->{option_results}->{use_new_perfdata})) { + return '~'; + } + return '_'; +} + sub parse_pfdata_scale { my ($self, %options) = @_; @@ -761,6 +866,43 @@ sub parse_pfdata_math { return (0, $args); } +sub parse_group_pfdata { + my ($self, %options) = @_; + + $options{args} =~ s/^\s+//; + $options{args} =~ s/\s+$//; + my $args = { pattern_pf => $options{args} }; + return $args; +} + +sub parse_pfdata_min { + my ($self, %options) = @_; + + my $args = $self->parse_group_pfdata(%options); + return (0, $args); +} + +sub parse_pfdata_max { + my ($self, %options) = @_; + + my $args = $self->parse_group_pfdata(%options); + return (0, $args); +} + +sub parse_pfdata_average { + my ($self, %options) = @_; + + my $args = $self->parse_group_pfdata(%options); + return (0, $args); +} + +sub parse_pfdata_sum { + my ($self, %options) = @_; + + my $args = $self->parse_group_pfdata(%options); + return (0, $args); +} + sub apply_pfdata_scale { my ($self, %options) = @_; @@ -781,7 +923,7 @@ sub apply_pfdata_scale { src_quantity => $src_quantity, src_unit => $src_unit, dst_quantity => defined($dst_unit) ? $dst_quantity : $options{args}->{quantity}, dst_unit => defined($dst_unit) ? $dst_unit : $options{args}->{unit}); - ${$options{perf}}->{max} = sprintf("%.2f", $value); + ${$options{perf}}->{max} = sprintf('%.2f', $value); } foreach my $threshold ('warning', 'critical') { @@ -837,7 +979,7 @@ sub apply_pfdata_percent { return if (!defined(${$options{perf}}->{max}) || ${$options{perf}}->{max} eq ''); - ${$options{perf}}->{value} = sprintf("%.2f", ${$options{perf}}->{value} * 100 / ${$options{perf}}->{max}); + ${$options{perf}}->{value} = sprintf('%.2f', ${$options{perf}}->{value} * 100 / ${$options{perf}}->{max}); ${$options{perf}}->{unit} = '%'; foreach my $threshold ('warning', 'critical') { next if (${$options{perf}}->{$threshold} eq ''); @@ -845,10 +987,10 @@ sub apply_pfdata_percent { next if ($status == 0); if ($result->{start} ne '' && $result->{infinite_neg} == 0) { - $result->{start} = sprintf("%.2f", $result->{start} * 100 / ${$options{perf}}->{max}); + $result->{start} = sprintf('%.2f', $result->{start} * 100 / ${$options{perf}}->{max}); } if ($result->{end} ne '' && $result->{infinite_pos} == 0) { - $result->{end} = sprintf("%.2f", $result->{end} * 100 / ${$options{perf}}->{max}); + $result->{end} = sprintf('%.2f', $result->{end} * 100 / ${$options{perf}}->{max}); } ${$options{perf}}->{$threshold} = centreon::plugins::misc::get_threshold_litteral(%$result); @@ -885,13 +1027,85 @@ sub apply_pfdata_math { ${$options{perf}}->{$threshold} = centreon::plugins::misc::get_threshold_litteral(%$result); } - ${$options{perf}}->{max} = 100; + ${$options{perf}}->{max} = 100; +} + +sub apply_pfdata_min { + my ($self, %options) = @_; + + my $pattern_pf; + eval "\$pattern_pf = \"$options{args}->{pattern_pf}\""; + my $min; + for (my $i = 0; $i < scalar(@{$self->{perfdatas}}); $i++) { + next if ($self->{perfdatas}->[$i]->{label} !~ /$pattern_pf/); + next if ($self->{perfdatas}->[$i]->{value} !~ /\d+/); + $min = $self->{perfdatas}->[$i]->{value} + if (!defined($min) || $min > $self->{perfdatas}->[$i]->{value}); + } + + ${$options{perf}}->{value} = $min + if (defined($min)); +} + +sub apply_pfdata_max { + my ($self, %options) = @_; + + my $pattern_pf; + eval "\$pattern_pf = \"$options{args}->{pattern_pf}\""; + my $max; + for (my $i = 0; $i < scalar(@{$self->{perfdatas}}); $i++) { + next if ($self->{perfdatas}->[$i]->{label} !~ /$pattern_pf/); + next if ($self->{perfdatas}->[$i]->{value} !~ /\d+/); + $max = $self->{perfdatas}->[$i]->{value} + if (!defined($max) || $max < $self->{perfdatas}->[$i]->{value}); + } + + ${$options{perf}}->{value} = $max + if (defined($max)); +} + +sub apply_pfdata_sum { + my ($self, %options) = @_; + + my $pattern_pf; + eval "\$pattern_pf = \"$options{args}->{pattern_pf}\""; + my ($sum, $num) = (0, 0); + for (my $i = 0; $i < scalar(@{$self->{perfdatas}}); $i++) { + next if ($self->{perfdatas}->[$i]->{label} !~ /$pattern_pf/); + next if ($self->{perfdatas}->[$i]->{value} !~ /\d+/); + $sum += $self->{perfdatas}->[$i]->{value}; + $num++; + } + + ${$options{perf}}->{value} = $sum + if ($num > 0); +} + +sub apply_pfdata_average { + my ($self, %options) = @_; + + my $pattern_pf; + eval "\$pattern_pf = \"$options{args}->{pattern_pf}\""; + my ($sum, $num) = (0, 0); + for (my $i = 0; $i < scalar(@{$self->{perfdatas}}); $i++) { + next if ($self->{perfdatas}->[$i]->{label} !~ /$pattern_pf/); + next if ($self->{perfdatas}->[$i]->{value} !~ /\d+/); + $sum += $self->{perfdatas}->[$i]->{value}; + $num++; + } + + ${$options{perf}}->{value} = sprintf("%.2f", ($sum / $num)) + if ($num > 0); } sub load_perfdata_extend_args { my ($self, %options) = @_; - - foreach ([$self->{option_results}->{change_perfdata}, 1], [$self->{option_results}->{extend_perfdata}, 2]) { + + foreach ( + [$self->{option_results}->{change_perfdata}, 1], + [$self->{option_results}->{extend_perfdata}, 2], + [$self->{option_results}->{extend_perfdata_group}, 3], + ) { next if (!defined($_->[0])); foreach my $arg (@{$_->[0]}) { $self->parse_perfdata_extend_args(arg => $arg, type => $_->[1]); @@ -902,20 +1116,23 @@ sub load_perfdata_extend_args { sub parse_perfdata_extend_args { my ($self, %options) = @_; - # --extend-perfdata=searchlabel,newlabel,method[,newuom] - my ($pfdata_match, $pfdata_substitute, $method, $uom_substitute) = split /,/, $options{arg}; - return if (!defined($pfdata_match) || $pfdata_match eq ''); + # --extend-perfdata=searchlabel,newlabel,method[,[newuom],[min],[max]] + my ($pfdata_match, $pfdata_substitute, $method, $uom_sub, $min_sub, $max_sub) = + split /,/, $options{arg}; + return if ((!defined($pfdata_match) || $pfdata_match eq '') && $options{type} != 3); $self->{pfdata_extends} = [] if (!defined($self->{pfdata_extends})); my $pfdata_extends = { pfdata_match => defined($pfdata_match) && $pfdata_match ne '' ? $pfdata_match : undef, pfdata_substitute => defined($pfdata_substitute) && $pfdata_substitute ne '' ? $pfdata_substitute : undef, - uom_substitute => defined($uom_substitute) && $uom_substitute ne '' ? $uom_substitute : undef, + uom_sub => defined($uom_sub) && $uom_sub ne '' ? $uom_sub : undef, + min_sub => defined($min_sub) && $min_sub ne '' ? $min_sub : undef, + max_sub => defined($max_sub) && $max_sub ne '' ? $max_sub : undef, type => $options{type} }; if (defined($method) && $method ne '') { - if ($method !~ /^\s*(invert|percent|scale|math)\s*\(\s*(.*?)\s*\)\s*$/) { + if ($method !~ /^\s*(invert|percent|scale|math|min|max|average|sum)\s*\(\s*(.*?)\s*\)\s*$/) { $self->output_add(long_msg => "method in argument '$options{arg}' is unknown", debug => 1); return ; } @@ -930,7 +1147,7 @@ sub parse_perfdata_extend_args { } } } - + push @{$self->{pfdata_extends}}, $pfdata_extends; } @@ -959,10 +1176,35 @@ sub apply_perfdata_extend { foreach my $extend (@{$self->{pfdata_extends}}) { my $new_pfdata = []; + # Manage special case when type group and pfdata_match empty + if ($extend->{type} == 3 && (!defined($extend->{pfdata_match}) || $extend->{pfdata_match} eq '')) { + next if (!defined($extend->{pfdata_substitute}) || $extend->{pfdata_substitute} eq ''); + my $new_perf = { + label => $extend->{pfdata_substitute}, value => '', + unit => defined($extend->{uom_sub}) ? $extend->{uom_sub} : '', + warning => '', critical => '', + min => defined($extend->{min_sub}) ? $extend->{min_sub} : '', + max => defined($extend->{max_sub}) ? $extend->{max_sub} : '' + }; + + if (defined($extend->{method_name})) { + my $func = $self->can('apply_pfdata_' . $extend->{method_name}); + $func->($self, perf => \$new_perf, args => $extend->{method_args}); + } + + if (length($new_perf->{value})) { + push @{$self->{perfdatas}}, $new_perf; + } + next; + } + for (my $i = 0; $i < scalar(@{$self->{perfdatas}}); $i++) { next if ($self->{perfdatas}->[$i]->{label} !~ /$extend->{pfdata_match}/); my $new_perf = { %{$self->{perfdatas}->[$i]} }; + if ($extend->{type} == 3) { + $new_perf = { label => $self->{perfdatas}->[$i]->{label}, value => '', unit => '', warning => '', critical => '', min => '', max => '' }; + } if (defined($extend->{pfdata_substitute})) { eval "\$new_perf->{label} =~ s{$extend->{pfdata_match}}{$extend->{pfdata_substitute}}"; @@ -973,17 +1215,17 @@ sub apply_perfdata_extend { $func->($self, perf => \$new_perf, args => $extend->{method_args}); } - if (defined($extend->{uom_substitute})) { - $new_perf->{unit} = $extend->{uom_substitute}; - } - + $new_perf->{unit} = $extend->{uom_sub} if (defined($extend->{uom_sub})); + $new_perf->{min} = $extend->{min_sub} if (defined($extend->{min_sub})); + $new_perf->{max} = $extend->{max_sub} if (defined($extend->{max_sub})); + if ($extend->{type} == 1) { $self->{perfdatas}->[$i] = $new_perf; } else { - push @$new_pfdata, $new_perf; + push @$new_pfdata, $new_perf if (length($new_perf->{value})); } } - + push @{$self->{perfdatas}}, @$new_pfdata; } } @@ -1031,7 +1273,7 @@ Put max perfdata (if it exist) in a specific perfdata =item B<--change-perfdata> B<--extend-perfdata> Change or extend perfdata. -Syntax: --extend-perfdata=searchlabel,newlabel,target[,newuom] +Syntax: --extend-perfdata=searchlabel,newlabel,target[,[newuom],[min],[max]] Common examples: @@ -1049,6 +1291,25 @@ Change traffic values in percent: --change-perfdata=traffic_in,,percent() =back +=item B<--extend-perfdata-group> + +Extend perfdata from multiple perfdatas (methods in target are: min, max, average, sum) +Syntax: --extend-perfdata-group=searchlabel,newlabel,target[,newuom] + +Common examples: + +=over 4 + +Sum wrong packets from all interfaces (with interface need --units-errors=absolute): --extend-perfdata-group=',packets_wrong,sum(packets_(discard|error)_(in|out))' + +Sum traffic by interface: --extend-perfdata-group='traffic_in_(.*),traffic_$1,sum(traffic_(in|out)_$1)' + +=back + +=item B<--change-short-output> + +Change short output display. --change-short-output=pattern~replace~modifier + =item B<--range-perfdata> Change perfdata range thresholds display: @@ -1060,15 +1321,21 @@ Filter UOM that match the regexp. =item B<--opt-exit> -Exit code for an option error, usage (default: unknown). +Optional exit code for an execution error (i.e. wrong option provided, +SSH connection refused, timeout, etc) +(Default: unknown). =item B<--output-xml> -Display output in XML Format. +Display output in XML format. =item B<--output-json> -Display output in JSON Format. +Display output in JSON format. + +=item B<--output-openmetrics> + +Display metrics in OpenMetrics format. =item B<--output-file> @@ -1082,6 +1349,10 @@ Display discovery arguments (if the mode manages it). Display discovery values (if the mode manages it). +=item B<--float-precision> + +Set the float precision for thresholds (Default: 8). + =head1 DESCRIPTION B. diff --git a/centreon/plugins/passwordmgr/teampass.pm b/centreon/plugins/passwordmgr/teampass.pm index 147026913..a9a798b93 100644 --- a/centreon/plugins/passwordmgr/teampass.pm +++ b/centreon/plugins/passwordmgr/teampass.pm @@ -56,7 +56,7 @@ sub new { $options{options}->add_help(package => __PACKAGE__, sections => 'TEAMPASS OPTIONS'); $self->{output} = $options{output}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options, noptions => 1); $JSON::Path::Safe = 0; return $self; diff --git a/centreon/plugins/perfdata.pm b/centreon/plugins/perfdata.pm index 23475a597..88ac83e21 100644 --- a/centreon/plugins/perfdata.pm +++ b/centreon/plugins/perfdata.pm @@ -32,6 +32,8 @@ sub new { $self->{output} = $options{output}; # Typical Nagios Perfdata 'with ~ @ ..' $self->{threshold_label} = {}; + $self->{float_precision} = defined($self->{output}->{option_results}->{float_precision}) && $self->{output}->{option_results}->{float_precision} =~ /\d+/ ? + int($self->{output}->{option_results}->{float_precision}) : 8; return $self; } @@ -64,10 +66,10 @@ sub get_perfdata_for_output { $perf_value{start} = int($perf_value{start}) if ($perf_value{infinite_neg} == 0 && defined($options{cast_int}) && $options{cast_int} == 1); $perf_value{end} = int($perf_value{end}) if ($perf_value{infinite_pos} == 0 && defined($options{cast_int}) && $options{cast_int} == 1); - my $perf_output = ($perf_value{arobase} == 1 ? "@" : "") . - (($perf_value{infinite_neg} == 0) ? $perf_value{start} : "~") . - ":" . - (($perf_value{infinite_pos} == 0) ? $perf_value{end} : ""); + my $perf_output = ($perf_value{arobase} == 1 ? '@' : '') . + (($perf_value{infinite_neg} == 0) ? $perf_value{start} : '~') . + ':' . + (($perf_value{infinite_pos} == 0) ? $perf_value{end} : ''); return $perf_output; } @@ -86,6 +88,17 @@ sub threshold_validate { ($status, my $result_perf) = centreon::plugins::misc::parse_threshold(threshold => $options{value}); $self->{threshold_label}->{$options{label}} = { %{$self->{threshold_label}->{$options{label}}}, %$result_perf }; + + $self->{threshold_label}->{$options{label}}->{start_precision} = $self->{threshold_label}->{$options{label}}->{start}; + if ($self->{threshold_label}->{$options{label}}->{start} =~ /[.,]/) { + $self->{threshold_label}->{$options{label}}->{start_precision} = sprintf("%.$self->{output}->{option_results}->{float_precision}f", $self->{threshold_label}->{$options{label}}->{start}); + } + + $self->{threshold_label}->{$options{label}}->{end_precision} = $self->{threshold_label}->{$options{label}}->{end}; + if ($self->{threshold_label}->{$options{label}}->{end} =~ /[.,]/) { + $self->{threshold_label}->{$options{label}}->{end_precision} = sprintf("%.$self->{output}->{option_results}->{float_precision}f", $self->{threshold_label}->{$options{label}}->{end}); + } + return $status; } @@ -94,12 +107,16 @@ sub threshold_check { # Can check multiple threshold. First match: out. Order is important # options{value}: value to compare # options{threshold}: ref to an array (example: [ {label => 'warning', exit_litteral => 'warning' }, {label => 'critical', exit_litteral => 'critical'} ] + if ($options{value} =~ /[.,]/) { + $options{value} = sprintf("%.$self->{output}->{option_results}->{float_precision}f", $options{value}); + } + foreach (@{$options{threshold}}) { next if (!defined($self->{threshold_label}->{$_->{label}})); next if (!defined($self->{threshold_label}->{$_->{label}}->{value}) || $self->{threshold_label}->{$_->{label}}->{value} eq ''); - if ($self->{threshold_label}->{$_->{label}}->{arobase} == 0 && ($options{value} < $self->{threshold_label}->{$_->{label}}->{start} || $options{value} > $self->{threshold_label}->{$_->{label}}->{end})) { + if ($self->{threshold_label}->{$_->{label}}->{arobase} == 0 && ($options{value} < $self->{threshold_label}->{$_->{label}}->{start_precision} || $options{value} > $self->{threshold_label}->{$_->{label}}->{end_precision})) { return $_->{exit_litteral}; - } elsif ($self->{threshold_label}->{$_->{label}}->{arobase} == 1 && ($options{value} >= $self->{threshold_label}->{$_->{label}}->{start} && $options{value} <= $self->{threshold_label}->{$_->{label}}->{end})) { + } elsif ($self->{threshold_label}->{$_->{label}}->{arobase} == 1 && ($options{value} >= $self->{threshold_label}->{$_->{label}}->{start_precision} && $options{value} <= $self->{threshold_label}->{$_->{label}}->{end_precision})) { return $_->{exit_litteral}; } } @@ -117,17 +134,23 @@ sub trim { sub change_bytes { my ($self, %options) = @_; + + my $value = $options{value}; my $divide = defined($options{network}) ? 1000 : 1024; my @units = ('K', 'M', 'G', 'T'); my $unit = ''; + my $sign = ''; + + $sign = '-' if ($value != abs($value)); + $value = abs($value); for (my $i = 0; $i < scalar(@units); $i++) { - last if (($options{value} / $divide) < 1); + last if (($value / $divide) < 1); $unit = $units[$i]; - $options{value} = $options{value} / $divide; + $value = $value / $divide; } - return (sprintf("%.2f", $options{value}), $unit . (defined($options{network}) ? 'b' : 'B')); + return (sprintf('%.2f', $sign . $value), $unit . (defined($options{network}) ? 'b' : 'B')); } 1; diff --git a/centreon/plugins/script.pm b/centreon/plugins/script.pm index bbf43ee46..a38689806 100644 --- a/centreon/plugins/script.pm +++ b/centreon/plugins/script.pm @@ -99,15 +99,15 @@ sub get_plugin { $self->{options}->set_output(output => $self->{output}); $self->{options}->add_options(arguments => { - 'plugin:s' => { name => 'plugin' }, - 'list-plugin' => { name => 'list_plugin' }, - 'help' => { name => 'help' }, - 'ignore-warn-msg' => { name => 'ignore_warn_msg' }, - 'version' => { name => 'version' }, - 'runas:s' => { name => 'runas' }, - 'environment:s%' => { name => 'environment' }, - 'convert-args:s' => { name => 'convert_args' }, - } ); + 'plugin:s' => { name => 'plugin' }, + 'list-plugin' => { name => 'list_plugin' }, + 'help' => { name => 'help' }, + 'ignore-warn-msg' => { name => 'ignore_warn_msg' }, + 'version' => { name => 'version' }, + 'runas:s' => { name => 'runas' }, + 'environment:s%' => { name => 'environment' }, + 'convert-args:s' => { name => 'convert_args' }, + }); $self->{options}->parse_options(); @@ -120,7 +120,6 @@ sub get_plugin { $self->{ignore_warn_msg} = $self->{options}->get_option(argument => 'ignore_warn_msg' ); $self->{convert_args} = $self->{options}->get_option(argument => 'convert_args' ); - $self->{output}->mode(name => $self->{mode}); $self->{output}->plugin(name => $self->{plugin}); $self->{output}->check_options(option_results => $self->{options}->get_options()); @@ -147,13 +146,13 @@ sub display_local_help { open STDOUT, '>', \$stdout; if ($alternative_fatpacker == 0) { - pod2usage(-exitval => "NOEXIT", -input => pod_where({-inc => 1}, __PACKAGE__)); + pod2usage(-exitval => 'NOEXIT', -input => pod_where({-inc => 1}, __PACKAGE__)); } else { - my $pp = __PACKAGE__ . ".pm"; + my $pp = __PACKAGE__ . '.pm'; $pp =~ s{::}{/}g; my $content_class = $INC{$pp}->{$pp}; open my $str_fh, '<', \$content_class; - pod2usage(-exitval => "NOEXIT", -input => $str_fh); + pod2usage(-exitval => 'NOEXIT', -input => $str_fh); close $str_fh; } } @@ -166,7 +165,7 @@ sub check_directory { opendir(my $dh, $directory) || return ; while (my $filename = readdir $dh) { - $self->check_directory($directory . "/" . $filename) if ($filename !~ /^\./ && -d $directory . "/" . $filename); + $self->check_directory($directory . '/' . $filename) if ($filename !~ /^\./ && -d $directory . '/' . $filename); if ($filename eq 'plugin.pm') { my $stdout = ''; @@ -203,7 +202,7 @@ sub check_plugin_option { my ($self) = @_; if (defined($self->{version})) { - $self->{output}->add_option_msg(short_msg => "Global Version: " . $global_version); + $self->{output}->add_option_msg(short_msg => 'Global Version: ' . $global_version); $self->{output}->option_exit(nolabel => 1); } @@ -232,7 +231,7 @@ sub display_list_plugin { foreach my $key (@$integrated_plugins) { # Need to load it to get the description centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $key, - error_msg => "Cannot load module --plugin."); + error_msg => 'Cannot load module --plugin.'); my $name = $key; $name =~ s/\.pm//g; @@ -245,7 +244,7 @@ sub display_list_plugin { open STDOUT, '>', \$stdout; my $content_class = $INC{$key}->{$key}; open my $str_fh, '<', \$content_class; - pod2usage(-exitval => "NOEXIT", -input => $str_fh, -verbose => 99, -sections => "PLUGIN DESCRIPTION"); + pod2usage(-exitval => 'NOEXIT', -input => $str_fh, -verbose => 99, -sections => 'PLUGIN DESCRIPTION'); close $str_fh; $self->{output}->add_option_msg(long_msg => $stdout); } @@ -303,15 +302,16 @@ sub check_relaunch { if ($need_restart == 1) { if (scalar(@args) <= 0) { - unshift @args, @ARGV, "--plugin=" . $self->{plugin} + unshift @args, @ARGV, '--plugin=' . $self->{plugin} } my ($lerror, $stdout, $exit_code) = centreon::plugins::misc::backtick( - command => $cmd, - arguments => [@args], - timeout => 30, - wait_exit => 1 - ); + command => $cmd, + arguments => [@args], + timeout => 30, + wait_exit => 1 + ); + if ($exit_code <= -1000) { if ($exit_code == -1000) { $self->{output}->output_add(severity => 'UNKNOWN', @@ -352,7 +352,7 @@ sub run { (undef, $self->{plugin}) = centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{plugin}, - error_msg => "Cannot load module --plugin."); + error_msg => 'Cannot load module --plugin.'); my $plugin = $self->{plugin}->new(options => $self->{options}, output => $self->{output}); $plugin->init(help => $self->{help}, version => $self->{version}); diff --git a/centreon/plugins/script_custom.pm b/centreon/plugins/script_custom.pm index 9bc01b669..5ea3251b4 100644 --- a/centreon/plugins/script_custom.pm +++ b/centreon/plugins/script_custom.pm @@ -35,16 +35,16 @@ sub new { $self->{output} = $options{output}; $self->{options}->add_options( - arguments => { - 'mode:s' => { name => 'mode_name' }, - 'dyn-mode:s' => { name => 'dynmode_name' }, - 'list-mode' => { name => 'list_mode' }, - 'custommode:s' => { name => 'custommode_name' }, - 'list-custommode' => { name => 'list_custommode' }, - 'multiple' => { name => 'multiple' }, - 'sanity-options' => { name => 'sanity_options' }, # keep it for 6 month before remove it - } - ); + arguments => { + 'mode:s' => { name => 'mode_name' }, + 'dyn-mode:s' => { name => 'dynmode_name' }, + 'list-mode' => { name => 'list_mode' }, + 'custommode:s' => { name => 'custommode_name' }, + 'list-custommode' => { name => 'list_custommode' }, + 'multiple' => { name => 'multiple' }, + 'sanity-options' => { name => 'sanity_options' }, # keep it for 6 month before remove it + } + ); $self->{version} = '1.0'; %{$self->{modes}} = (); %{$self->{custom_modes}} = (); @@ -62,6 +62,7 @@ sub new { $self->{options}->add_help(package => $options{package}, sections => 'PLUGIN DESCRIPTION'); $self->{options}->add_help(package => __PACKAGE__, sections => 'GLOBAL OPTIONS'); + $self->{output}->mode(name => $self->{mode_name}); return $self; } diff --git a/centreon/plugins/script_simple.pm b/centreon/plugins/script_simple.pm index 5f2e1f749..569d03e4a 100644 --- a/centreon/plugins/script_simple.pm +++ b/centreon/plugins/script_simple.pm @@ -34,14 +34,14 @@ sub new { $self->{output} = $options{output}; $self->{options}->add_options( - arguments => { - 'mode:s' => { name => 'mode_name' }, - 'dyn-mode:s' => { name => 'dynmode_name' }, - 'list-mode' => { name => 'list_mode' }, - 'mode-version:s' => { name => 'mode_version' }, - 'sanity-options' => { name => 'sanity_options' }, # keep it for 6 month before remove it - } - ); + arguments => { + 'mode:s' => { name => 'mode_name' }, + 'dyn-mode:s' => { name => 'dynmode_name' }, + 'list-mode' => { name => 'list_mode' }, + 'mode-version:s' => { name => 'mode_version' }, + 'sanity-options' => { name => 'sanity_options' }, # keep it for 6 month before remove it + } + ); $self->{version} = '1.0'; %{$self->{modes}} = (); $self->{default} = undef; @@ -55,6 +55,7 @@ sub new { $self->{options}->add_help(package => $options{package}, sections => 'PLUGIN DESCRIPTION'); $self->{options}->add_help(package => __PACKAGE__, sections => 'GLOBAL OPTIONS'); + $self->{output}->mode(name => $self->{mode_name}); return $self; } diff --git a/centreon/plugins/script_snmp.pm b/centreon/plugins/script_snmp.pm index 08b1cb0ba..fc7378dd9 100644 --- a/centreon/plugins/script_snmp.pm +++ b/centreon/plugins/script_snmp.pm @@ -36,15 +36,15 @@ sub new { $self->{output} = $options{output}; $self->{options}->add_options( - arguments => { - 'mode:s' => { name => 'mode_name' }, - 'dyn-mode:s' => { name => 'dynmode_name' }, - 'list-mode' => { name => 'list_mode' }, - 'mode-version:s' => { name => 'mode_version' }, - 'sanity-options' => { name => 'sanity_options' }, # keep it for 6 month before remove it - 'pass-manager:s' => { name => 'pass_manager' }, - } - ); + arguments => { + 'mode:s' => { name => 'mode_name' }, + 'dyn-mode:s' => { name => 'dynmode_name' }, + 'list-mode' => { name => 'list_mode' }, + 'mode-version:s' => { name => 'mode_version' }, + 'sanity-options' => { name => 'sanity_options' }, # keep it for 6 month before remove it + 'pass-manager:s' => { name => 'pass_manager' }, + } + ); $self->{version} = '1.0'; %{$self->{modes}} = (); $self->{default} = undef; @@ -58,6 +58,7 @@ sub new { $self->{options}->add_help(package => $options{package}, sections => 'PLUGIN DESCRIPTION'); $self->{options}->add_help(package => __PACKAGE__, sections => 'GLOBAL OPTIONS'); + $self->{output}->mode(name => $self->{mode_name}); return $self; } @@ -87,7 +88,6 @@ sub init { # SNMP $self->{snmp} = centreon::plugins::snmp->new(options => $self->{options}, output => $self->{output}); - # Load mode if (defined($self->{mode_name}) && $self->{mode_name} ne '') { $self->is_mode(mode => $self->{mode_name}); @@ -126,7 +126,7 @@ sub init { $self->{pass_mgr}->manage_options(option_results => $self->{option_results}) if (defined($self->{pass_mgr})); $self->{snmp}->check_options(option_results => $self->{option_results}); - $self->{mode}->check_options(option_results => $self->{option_results}, default => $self->{default}); + $self->{mode}->check_options(option_results => $self->{option_results}, default => $self->{default}, snmp => $self->{snmp}); } sub load_password_mgr { diff --git a/centreon/plugins/script_sql.pm b/centreon/plugins/script_sql.pm index 1caf73052..4f782f927 100644 --- a/centreon/plugins/script_sql.pm +++ b/centreon/plugins/script_sql.pm @@ -35,17 +35,17 @@ sub new { $self->{output} = $options{output}; $self->{options}->add_options( - arguments => { - 'mode:s' => { name => 'mode_name' }, - 'dyn-mode:s' => { name => 'dynmode_name' }, - 'list-mode' => { name => 'list_mode' }, - 'mode-version:s' => { name => 'mode_version' }, - 'sqlmode:s' => { name => 'sqlmode_name', default => 'dbi' }, - 'list-sqlmode' => { name => 'list_sqlmode' }, - 'multiple' => { name => 'multiple' }, - 'sanity-options' => { name => 'sanity_options' }, # keep it for 6 month before remove it - } - ); + arguments => { + 'mode:s' => { name => 'mode_name' }, + 'dyn-mode:s' => { name => 'dynmode_name' }, + 'list-mode' => { name => 'list_mode' }, + 'mode-version:s' => { name => 'mode_version' }, + 'sqlmode:s' => { name => 'sqlmode_name', default => 'dbi' }, + 'list-sqlmode' => { name => 'list_sqlmode' }, + 'multiple' => { name => 'multiple' }, + 'sanity-options' => { name => 'sanity_options' }, # keep it for 6 month before remove it + } + ); $self->{version} = '1.0'; %{$self->{modes}} = (); %{$self->{sql_modes}} = ('dbi' => 'centreon::plugins::dbi'); @@ -63,6 +63,7 @@ sub new { $self->{options}->add_help(package => $options{package}, sections => 'PLUGIN DESCRIPTION'); $self->{options}->add_help(package => __PACKAGE__, sections => 'GLOBAL OPTIONS'); + $self->{output}->mode(name => $self->{mode_name}); return $self; } diff --git a/centreon/plugins/script_wsman.pm b/centreon/plugins/script_wsman.pm index 7f8e672ec..493429677 100644 --- a/centreon/plugins/script_wsman.pm +++ b/centreon/plugins/script_wsman.pm @@ -36,14 +36,14 @@ sub new { $self->{output} = $options{output}; $self->{options}->add_options( - arguments => { - 'mode:s' => { name => 'mode_name' }, - 'dyn-mode:s' => { name => 'dynmode_name' }, - 'list-mode' => { name => 'list_mode' }, - 'mode-version:s' => { name => 'mode_version' }, - 'sanity-options' => { name => 'sanity_options' }, # keep it for 6 month before remove it - } - ); + arguments => { + 'mode:s' => { name => 'mode_name' }, + 'dyn-mode:s' => { name => 'dynmode_name' }, + 'list-mode' => { name => 'list_mode' }, + 'mode-version:s' => { name => 'mode_version' }, + 'sanity-options' => { name => 'sanity_options' }, # keep it for 6 month before remove it + } + ); $self->{version} = '1.0'; %{$self->{modes}} = (); $self->{default} = undef; @@ -57,6 +57,7 @@ sub new { $self->{options}->add_help(package => $options{package}, sections => 'PLUGIN DESCRIPTION'); $self->{options}->add_help(package => __PACKAGE__, sections => 'GLOBAL OPTIONS'); + $self->{output}->mode(name => $self->{mode_name}); return $self; } diff --git a/centreon/plugins/snmp.pm b/centreon/plugins/snmp.pm index f1b839e2c..ab4b352ca 100644 --- a/centreon/plugins/snmp.pm +++ b/centreon/plugins/snmp.pm @@ -43,28 +43,30 @@ sub new { $options{output}->option_exit(); } - $options{options}->add_options(arguments => - { "hostname|host:s" => { name => 'host' }, - "snmp-community:s" => { name => 'snmp_community', default => 'public' }, - "snmp-version:s" => { name => 'snmp_version', default => 1 }, - "snmp-port:s" => { name => 'snmp_port', default => 161 }, - "snmp-timeout:s" => { name => 'snmp_timeout', default => 1 }, - "snmp-retries:s" => { name => 'snmp_retries', default => 5 }, - "maxrepetitions:s" => { name => 'maxrepetitions', default => 50 }, - "subsetleef:s" => { name => 'subsetleef', default => 50 }, - "subsettable:s" => { name => 'subsettable', default => 100 }, - "snmp-autoreduce:s" => { name => 'snmp_autoreduce' }, - "snmp-force-getnext" => { name => 'snmp_force_getnext' }, - "snmp-username:s" => { name => 'snmp_security_name' }, - "authpassphrase:s" => { name => 'snmp_auth_passphrase' }, - "authprotocol:s" => { name => 'snmp_auth_protocol' }, - "privpassphrase:s" => { name => 'snmp_priv_passphrase' }, - "privprotocol:s" => { name => 'snmp_priv_protocol' }, - "contextname:s" => { name => 'snmp_context_name' }, - "contextengineid:s" => { name => 'snmp_context_engine_id' }, - "securityengineid:s" => { name => 'snmp_security_engine_id' }, - "snmp-errors-exit:s" => { name => 'snmp_errors_exit', default => 'unknown' }, - }); + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "hostname|host:s" => { name => 'host' }, + "snmp-community:s" => { name => 'snmp_community', default => 'public' }, + "snmp-version:s" => { name => 'snmp_version', default => 1 }, + "snmp-port:s" => { name => 'snmp_port', default => 161 }, + "snmp-timeout:s" => { name => 'snmp_timeout', default => 1 }, + "snmp-retries:s" => { name => 'snmp_retries', default => 5 }, + "maxrepetitions:s" => { name => 'maxrepetitions', default => 50 }, + "subsetleef:s" => { name => 'subsetleef', default => 50 }, + "subsettable:s" => { name => 'subsettable', default => 100 }, + "snmp-autoreduce:s" => { name => 'snmp_autoreduce' }, + "snmp-force-getnext" => { name => 'snmp_force_getnext' }, + "snmp-username:s" => { name => 'snmp_security_name' }, + "authpassphrase:s" => { name => 'snmp_auth_passphrase' }, + "authprotocol:s" => { name => 'snmp_auth_protocol' }, + "privpassphrase:s" => { name => 'snmp_priv_passphrase' }, + "privprotocol:s" => { name => 'snmp_priv_protocol' }, + "contextname:s" => { name => 'snmp_context_name' }, + "contextengineid:s" => { name => 'snmp_context_engine_id' }, + "securityengineid:s" => { name => 'snmp_security_engine_id' }, + "snmp-errors-exit:s" => { name => 'snmp_errors_exit', default => 'unknown' }, + }); + } $options{options}->add_help(package => __PACKAGE__, sections => 'SNMP OPTIONS'); ##### @@ -311,7 +313,8 @@ sub get_leef { next; } - if ($self->{snmp_autoreduce} == 1 && ($self->{session}->{ErrorNum} == 1 || $self->{session}->{ErrorNum} == -24)) { + if ($self->{snmp_autoreduce} == 1 && + ($self->{session}->{ErrorNum} == 1 || $self->{session}->{ErrorNum} == 5 || $self->{session}->{ErrorNum} == -24)) { next if ($self->autoreduce_leef(current => $entry) == 0); } my $msg = 'SNMP GET Request : ' . $self->{session}->{ErrorStr}; @@ -326,7 +329,8 @@ sub get_leef { # Some equipments gives a partial response and no error. # We look the last value if it's empty or not - if ((scalar(@$vb) != scalar(@{$entry})) || (scalar(@{@$vb[-1]}) < 3)) { + # In snmpv1 we have the retryNoSuch + if (((scalar(@$vb) != scalar(@{$entry})) || (scalar(@{@$vb[-1]}) < 3)) && !$self->is_snmpv1()) { next if ($self->{snmp_autoreduce} == 1 && $self->autoreduce_leef(current => $entry) == 0); if ($dont_quit == 0) { $self->{output}->add_option_msg(short_msg => "SNMP partial response. Please try --snmp-autoreduce option"); @@ -459,7 +463,8 @@ sub get_multiple_table { next; } - if ($self->{snmp_autoreduce} == 1 && ($self->{session}->{ErrorNum} == 1 || $self->{session}->{ErrorNum} == -24)) { + if ($self->{snmp_autoreduce} == 1 && + ($self->{session}->{ErrorNum} == 1 || $self->{session}->{ErrorNum} == 5 || $self->{session}->{ErrorNum} == -24)) { next if ($self->autoreduce_multiple_table(repeat_count => \$repeat_count) == 0); } @@ -604,7 +609,8 @@ sub get_table { # We are at the end with snmpv1. We quit. last; } - if ($self->{snmp_autoreduce} == 1 && ($self->{session}->{ErrorNum} == 1 || $self->{session}->{ErrorNum} == -24)) { + if ($self->{snmp_autoreduce} == 1 && + ($self->{session}->{ErrorNum} == 1 || $self->{session}->{ErrorNum} == 5 || $self->{session}->{ErrorNum} == -24)) { next if ($self->autoreduce_table(repeat_count => \$repeat_count) == 0); } @@ -780,43 +786,47 @@ sub check_options { } - if (!defined($options{option_results}->{snmp_security_name})) { + if (!defined($options{option_results}->{snmp_security_name}) || $options{option_results}->{snmp_security_name} eq '') { $self->{output}->add_option_msg(short_msg => "Missing parameter Security Name."); $self->{output}->option_exit(); } # unauthenticated and unencrypted - if (!defined($options{option_results}->{snmp_auth_passphrase}) && !defined($options{option_results}->{snmp_priv_passphrase})) { - $self->{snmp_params}->{SecLevel} = 'noAuthNoPriv'; - return ; - } - - if (defined($options{option_results}->{snmp_auth_passphrase}) && !defined($options{option_results}->{snmp_auth_protocol})) { - $self->{output}->add_option_msg(short_msg => "Missing parameter authenticate protocol."); - $self->{output}->option_exit(); - } - $options{option_results}->{snmp_auth_protocol} = uc($options{option_results}->{snmp_auth_protocol}); - if ($options{option_results}->{snmp_auth_protocol} ne "MD5" && $options{option_results}->{snmp_auth_protocol} ne "SHA") { - $self->{output}->add_option_msg(short_msg => "Wrong authentication protocol. Must be MD5 or SHA."); - $self->{output}->option_exit(); - } - - $self->{snmp_params}->{SecLevel} = 'authNoPriv'; - $self->{snmp_params}->{AuthProto} = $options{option_results}->{snmp_auth_protocol}; - $self->{snmp_params}->{AuthPass} = $options{option_results}->{snmp_auth_passphrase}; - - if (defined($options{option_results}->{snmp_priv_passphrase}) && !defined($options{option_results}->{snmp_priv_protocol})) { - $self->{output}->add_option_msg(short_msg => "Missing parameter privacy protocol."); - $self->{output}->option_exit(); - } + $self->{snmp_params}->{SecLevel} = 'noAuthNoPriv'; - if (defined($options{option_results}->{snmp_priv_protocol})) { + my $user_activate = 0; + if (defined($options{option_results}->{snmp_auth_passphrase}) && $options{option_results}->{snmp_auth_passphrase} ne '') { + if (!defined($options{option_results}->{snmp_auth_protocol})) { + $self->{output}->add_option_msg(short_msg => "Missing parameter authenticate protocol."); + $self->{output}->option_exit(); + } + $options{option_results}->{snmp_auth_protocol} = uc($options{option_results}->{snmp_auth_protocol}); + if ($options{option_results}->{snmp_auth_protocol} ne "MD5" && $options{option_results}->{snmp_auth_protocol} ne "SHA") { + $self->{output}->add_option_msg(short_msg => "Wrong authentication protocol. Must be MD5 or SHA."); + $self->{output}->option_exit(); + } + + $self->{snmp_params}->{SecLevel} = 'authNoPriv'; + $self->{snmp_params}->{AuthProto} = $options{option_results}->{snmp_auth_protocol}; + $self->{snmp_params}->{AuthPass} = $options{option_results}->{snmp_auth_passphrase}; + $user_activate = 1; + } + + if (defined($options{option_results}->{snmp_priv_passphrase}) && $options{option_results}->{snmp_priv_passphrase} ne '') { + if (!defined($options{option_results}->{snmp_priv_protocol})) { + $self->{output}->add_option_msg(short_msg => "Missing parameter privacy protocol."); + $self->{output}->option_exit(); + } + $options{option_results}->{snmp_priv_protocol} = uc($options{option_results}->{snmp_priv_protocol}); if ($options{option_results}->{snmp_priv_protocol} ne 'DES' && $options{option_results}->{snmp_priv_protocol} ne 'AES') { $self->{output}->add_option_msg(short_msg => "Wrong privacy protocol. Must be DES or AES."); $self->{output}->option_exit(); } - + if ($user_activate == 0) { + $self->{output}->add_option_msg(short_msg => "Cannot use snmp v3 privacy option without snmp v3 authentification options."); + $self->{output}->option_exit(); + } $self->{snmp_params}->{SecLevel} = 'authPriv'; $self->{snmp_params}->{PrivPass} = $options{option_results}->{snmp_priv_passphrase}; $self->{snmp_params}->{PrivProto} = $options{option_results}->{snmp_priv_protocol}; @@ -824,6 +834,22 @@ sub check_options { } } +sub set_snmp_connect_params { + my ($self, %options) = @_; + + foreach (keys %options) { + $self->{snmp_params}->{$_} = $options{$_}; + } +} + +sub set_snmp_params { + my ($self, %options) = @_; + + foreach (keys %options) { + $self->{$_} = $options{$_}; + } +} + sub set_error { my ($self, %options) = @_; # $options{error_msg} = string error diff --git a/centreon/plugins/templates/catalog_functions.pm b/centreon/plugins/templates/catalog_functions.pm index be4b19fe7..9e0cf76ab 100644 --- a/centreon/plugins/templates/catalog_functions.pm +++ b/centreon/plugins/templates/catalog_functions.pm @@ -25,7 +25,7 @@ use warnings; use Exporter; our @ISA = qw(Exporter); -our @EXPORT_OK = qw(catalog_status_threshold); +our @EXPORT_OK = qw(catalog_status_threshold catalog_status_calc); sub catalog_status_threshold { my ($self, %options) = @_; @@ -38,7 +38,10 @@ sub catalog_status_threshold { my $label = $self->{label}; $label =~ s/-/_/g; - if (defined($self->{instance_mode}->{option_results}->{'critical_' . $label}) && $self->{instance_mode}->{option_results}->{'critical_' . $label} ne '' && + if (defined($self->{instance_mode}->{option_results}->{ok_status}) && $self->{instance_mode}->{option_results}->{ok_status} ne '' && + eval "$self->{instance_mode}->{option_results}->{ok_status}") { + $status = 'ok'; + } elsif (defined($self->{instance_mode}->{option_results}->{'critical_' . $label}) && $self->{instance_mode}->{option_results}->{'critical_' . $label} ne '' && eval "$self->{instance_mode}->{option_results}->{'critical_' . $label}") { $status = 'critical'; } elsif (defined($self->{instance_mode}->{option_results}->{'warning_' . $label}) && $self->{instance_mode}->{option_results}->{'warning_' . $label} ne '' && @@ -56,6 +59,16 @@ sub catalog_status_threshold { return $status; } +sub catalog_status_calc { + my ($self, %options) = @_; + + foreach (keys %{$options{new_datas}}) { + if (/^$self->{instance}_(.*)/) { + $self->{result_values}->{$1} = $options{new_datas}->{$_}; + } + } +} + 1; __END__ diff --git a/centreon/plugins/templates/counter.pm b/centreon/plugins/templates/counter.pm index 44196ce7d..d6bbd2113 100644 --- a/centreon/plugins/templates/counter.pm +++ b/centreon/plugins/templates/counter.pm @@ -27,6 +27,11 @@ use warnings; use centreon::plugins::values; use centreon::plugins::misc; +my $sort_subs = { + num => sub { $a <=> $b }, + cmp => sub { $a cmp $b }, +}; + sub set_counters { my ($self, %options) = @_; @@ -61,6 +66,16 @@ sub set_counters { #}; } +sub get_callback { + my ($self, %options) = @_; + + if (defined($options{method_name})) { + return $self->can($options{method_name}); + } + + return undef; +} + sub call_object_callback { my ($self, %options) = @_; @@ -74,17 +89,41 @@ sub call_object_callback { return undef; } +sub get_threshold_prefix { + my ($self, %options) = @_; + + my $prefix = ''; + END_LOOP: foreach (@{$self->{maps_counters_type}}) { + if ($_->{name} eq $options{name}) { + $prefix = 'instance-' if ($_->{type} == 1); + last; + } + + if ($_->{type} == 3) { + foreach (@{$_->{group}}) { + if ($_->{name} eq $options{name}) { + $prefix = 'instance-' if ($_->{type} == 0); + $prefix = 'subinstance-' if ($_->{type} == 1); + last END_LOOP; + } + } + } + } + + return $prefix; +} + 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-counters:s" => { name => 'filter_counters' }, - "list-counters" => { name => 'list_counters' }, - }); + $options{options}->add_options(arguments => { + 'filter-counters:s' => { name => 'filter_counters' }, + 'display-ok-counters:s' => { name => 'display_ok_counters' }, + 'list-counters' => { name => 'list_counters' }, + }); $self->{statefile_value} = undef; if (defined($options{statefile}) && $options{statefile}) { centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'centreon::plugins::statefile', @@ -93,23 +132,40 @@ sub new { } $self->{maps_counters} = {} if (!defined($self->{maps_counters})); - $self->set_counters(); + $self->set_counters(%options); foreach my $key (keys %{$self->{maps_counters}}) { foreach (@{$self->{maps_counters}->{$key}}) { + my $label = $_->{label}; + my $thlabel = $label; + if ($self->{output}->use_new_perfdata() && defined($_->{nlabel})) { + $label = $_->{nlabel}; + $thlabel = $self->get_threshold_prefix(name => $key) . $label; + } + $thlabel =~ s/\./-/g; + if (!defined($_->{threshold}) || $_->{threshold} != 0) { $options{options}->add_options(arguments => { - 'warning-' . $_->{label} . ':s' => { name => 'warning-' . $_->{label} }, - 'critical-' . $_->{label} . ':s' => { name => 'critical-' . $_->{label} }, - }); + 'warning-' . $thlabel . ':s' => { name => 'warning-' . $thlabel }, + 'critical-' . $thlabel . ':s' => { name => 'critical-' . $thlabel }, + }); + + if (defined($_->{nlabel})) { + $options{options}->add_options(arguments => { + 'warning-' . $_->{label} . ':s' => { name => 'warning-' . $_->{label}, redirect => 'warning-' . $thlabel }, + 'critical-' . $_->{label} . ':s' => { name => 'critical-' . $_->{label}, redirect => 'critical-' . $thlabel }, + }); + } } - $_->{obj} = centreon::plugins::values->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $_->{label}); + $_->{obj} = centreon::plugins::values->new( + statefile => $self->{statefile_value}, + output => $self->{output}, perfdata => $self->{perfdata}, + label => $_->{label}, nlabel => $_->{nlabel}, thlabel => $thlabel, + ); $_->{obj}->set(%{$_->{set}}); } } - + return $self; } @@ -174,9 +230,13 @@ sub run_global { push @exits, $exit2; my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = $message_separator; - + if (!defined($_->{display_ok}) || $_->{display_ok} != 0 || + (defined($self->{option_results}->{display_ok_counters}) && $self->{option_results}->{display_ok_counters} ne '' && + $_->{label} =~ /$self->{option_results}->{display_ok_counters}/)) { + $long_msg .= $long_msg_append . $output; + $long_msg_append = $message_separator; + } + if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { $short_msg .= $short_msg_append . $output; $short_msg_append = $message_separator; @@ -223,6 +283,7 @@ sub run_instances { my ($self, %options) = @_; return undef if (defined($options{config}->{cb_init}) && $self->call_object_callback(method_name => $options{config}->{cb_init}) == 1); + my $cb_init_counters = $self->get_callback(method_name => $options{config}->{cb_init_counters}); my $display_status_lo = defined($options{display_status_long_output}) && $options{display_status_long_output} == 1 ? 1 : 0; my $resume = defined($options{resume}) && $options{resume} == 1 ? 1 : 0; my $no_message_multiple = 1; @@ -236,15 +297,19 @@ sub run_instances { my $message_separator = defined($options{config}->{message_separator}) ? $options{config}->{message_separator}: ', '; - foreach my $id (sort keys %{$self->{$options{config}->{name}}}) { + my $sort_method = 'cmp'; + $sort_method = $options{config}->{sort_method} + if (defined($options{config}->{sort_method})); + foreach my $id (sort { $sort_subs->{$sort_method}->() } keys %{$self->{$options{config}->{name}}}) { my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); my @exits = (); foreach (@{$self->{maps_counters}->{$options{config}->{name}}}) { my $obj = $_->{obj}; - + next if (defined($self->{option_results}->{filter_counters}) && $self->{option_results}->{filter_counters} ne '' && $_->{label} !~ /$self->{option_results}->{filter_counters}/); - + next if ($cb_init_counters && $self->$cb_init_counters(%$_) == 1); + $no_message_multiple = 0; $obj->set(instance => $id); @@ -260,8 +325,12 @@ sub run_instances { push @exits, $exit2; my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = $message_separator; + if (!defined($_->{display_ok}) || $_->{display_ok} != 0 || + (defined($self->{option_results}->{display_ok_counters}) && $self->{option_results}->{display_ok_counters} ne '' && + $_->{label} =~ /$self->{option_results}->{display_ok_counters}/)) { + $long_msg .= $long_msg_append . $output; + $long_msg_append = $message_separator; + } if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { $self->{lproblems}++; @@ -362,9 +431,13 @@ sub run_group { } if (defined($options{config}->{display_counter_problem})) { - $self->{output}->perfdata_add(label => $options{config}->{display_counter_problem}->{label}, unit => $options{config}->{display_counter_problem}->{unit}, - value => $total_problems, - min => $options{config}->{display_counter_problem}->{min}, max => $options{config}->{display_counter_problem}->{max}); + $self->{output}->perfdata_add( + label => $options{config}->{display_counter_problem}->{label}, + nlabel => $options{config}->{display_counter_problem}->{nlabel}, + unit => $options{config}->{display_counter_problem}->{unit}, + value => $total_problems, + min => $options{config}->{display_counter_problem}->{min}, max => $options{config}->{display_counter_problem}->{max} + ); } } @@ -382,9 +455,11 @@ sub run_multiple_instances { } my $message_separator = defined($options{config}->{message_separator}) ? - $options{config}->{message_separator}: ', '; - - foreach my $id (sort keys %{$self->{$options{config}->{name}}}) { + $options{config}->{message_separator} : ', '; + my $sort_method = 'cmp'; + $sort_method = $options{config}->{sort_method} + if (defined($options{config}->{sort_method})); + foreach my $id (sort { $sort_subs->{$sort_method}->() } keys %{$self->{$options{config}->{name}}}) { my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); my @exits = (); foreach (@{$self->{maps_counters}->{$options{config}->{name}}}) { @@ -395,7 +470,7 @@ sub run_multiple_instances { my $instance = $id; if ($multiple_parent == 1 && $multiple == 1) { - $instance = $options{instance_parent} . "_" . $id; + $instance = $options{instance_parent} . ($self->{output}->get_instance_perfdata_separator()) . $id; } elsif ($multiple_parent == 1 && $multiple == 0) { $instance = $options{instance_parent}; } diff --git a/centreon/plugins/templates/hardware.pm b/centreon/plugins/templates/hardware.pm index b5341683a..2e20ea1e0 100644 --- a/centreon/plugins/templates/hardware.pm +++ b/centreon/plugins/templates/hardware.pm @@ -80,17 +80,18 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, + 'component:s' => { name => 'component', default => '.*' }, + 'no-component:s' => { name => 'no_component' }, + 'threshold-overload:s@' => { name => 'threshold_overload' }, + 'add-name-instance' => { name => 'add_name_instance' }, }); $self->{performance} = (defined($options{no_performance}) && $options{no_performance} == 1) ? 0 : 1; if ($self->{performance} == 1) { $options{options}->add_options(arguments => { - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + 'warning:s@' => { name => 'warning' }, + 'critical:s@' => { name => 'critical' }, }); } @@ -98,15 +99,15 @@ sub new { 0 : 1; if ($self->{filter_exclude} == 1) { $options{options}->add_options(arguments => { - "exclude:s" => { name => 'exclude' }, - "filter:s@" => { name => 'filter' }, + 'exclude:s' => { name => 'exclude' }, + 'filter:s@' => { name => 'filter' }, }); } $self->{absent} = (defined($options{no_absent}) && $options{no_absent} == 1) ? 0 : 1; if ($self->{absent} == 1) { $options{options}->add_options(arguments => { - "absent-problem:s@" => { name => 'absent_problem' }, + 'absent-problem:s@' => { name => 'absent_problem' }, }); } @@ -291,10 +292,13 @@ sub display { $self->{components}->{$comp}->{total}, $comp)); } - $self->{output}->perfdata_add(label => 'count_' . $comp, - value => $self->{components}->{$comp}->{total}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'count_' . $comp, + nlabel => 'hardware.' . $comp . '.count', + value => $self->{components}->{$comp}->{total}, + warning => $warn, + critical => $crit + ); push @{$exits}, $exit; } @@ -307,7 +311,7 @@ sub display { $exit = $self->{output}->get_most_critical(status => $exits) if (scalar(@{$exits}) > 0); if ($self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(short_msg => sprintf("All %s components are ok [%s].", + $self->{output}->output_add(short_msg => sprintf('All %s components are ok [%s].', $total_components, $display_by_component) ); @@ -351,22 +355,23 @@ sub check_filter { if (defined($options{instance})) { if ($self->{option_results}->{exclude} =~ /(^|\s|,)${options{section}}[^,]*#\Q$options{instance}\E#/) { $self->{components}->{$options{section}}->{skip}++; - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); + $self->{output}->output_add(long_msg => sprintf("skipping $options{section} section $options{instance} instance.")); return 1; } } elsif (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)$options{section}(\s|,|$)/) { - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); + $self->{output}->output_add(long_msg => sprintf("skipping $options{section} section.")); return 1; } } - + + $options{instance} .= '#' . $options{name} if (defined($self->{option_results}->{add_name_instance}) && defined($options{name})); foreach (@{$self->{filter}}) { if ($options{section} =~ /$_->{filter}/) { if (!defined($options{instance}) && !defined($_->{instance})) { - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); + $self->{output}->output_add(long_msg => sprintf("skipping $options{section} section.")); return 1; } elsif (defined($options{instance}) && $options{instance} =~ /$_->{instance}/) { - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); + $self->{output}->output_add(long_msg => sprintf("skipping $options{section} section $options{instance} instance.")); return 1; } } @@ -377,7 +382,8 @@ sub check_filter { sub absent_problem { my ($self, %options) = @_; - + + $options{instance} .= '#' . $options{name} if (defined($self->{option_results}->{add_name_instance}) && defined($options{name})); foreach (@{$self->{absent_problem}}) { if ($options{section} =~ /$_->{filter}/) { if (!defined($_->{instance}) || $options{instance} =~ /$_->{instance}/) { @@ -413,7 +419,8 @@ sub get_severity_numeric { my $status = 'OK'; # default my $thresholds = { warning => undef, critical => undef }; my $checked = 0; - + + $options{instance} .= '#' . $options{name} if (defined($self->{option_results}->{add_name_instance}) && defined($options{name})); if (defined($self->{numeric_threshold}->{$options{section}})) { my $exits = []; foreach (@{$self->{numeric_threshold}->{$options{section}}}) { diff --git a/centreon/plugins/values.pm b/centreon/plugins/values.pm index 418cffb43..ecb947677 100644 --- a/centreon/plugins/values.pm +++ b/centreon/plugins/values.pm @@ -35,6 +35,8 @@ sub new { $self->{output} = $options{output}; $self->{perfdata} = $options{perfdata}; $self->{label} = $options{label}; + $self->{nlabel} = $options{nlabel}; + $self->{thlabel} = defined($options{thlabel}) ? $options{thlabel} : $self->{label}; $self->{perfdatas} = []; @@ -61,8 +63,8 @@ sub new { sub init { my ($self, %options) = @_; - my $warn = defined($self->{threshold_warn}) ? $self->{threshold_warn} : 'warning-' . $self->{label}; - my $crit = defined($self->{threshold_crit}) ? $self->{threshold_crit} : 'critical-' . $self->{label}; + my $warn = defined($self->{threshold_warn}) ? $self->{threshold_warn} : 'warning-' . $self->{thlabel}; + my $crit = defined($self->{threshold_crit}) ? $self->{threshold_crit} : 'critical-' . $self->{thlabel}; if (($self->{perfdata}->threshold_validate(label => $warn, value => $options{option_results}->{$warn})) == 0) { $self->{output}->add_option_msg(short_msg => "Wrong $warn threshold '" . $options{option_results}->{$warn} . "'."); @@ -88,7 +90,7 @@ sub calc { # manage only one value ;) foreach my $value (@{$self->{key_values}}) { if (defined($value->{diff}) && $value->{diff} == 1) { - if ($self->{per_second} == 1) { + if (defined($self->{per_second}) && $self->{per_second} == 1) { $self->{result_values}->{$value->{name} . '_per_second'} = ($options{new_datas}->{$self->{instance} . '_' . $value->{name}} - $options{old_datas}->{$self->{instance} . '_' . $value->{name}}) / $options{delta_time}; } $self->{result_values}->{$value->{name} . '_absolute'} = $options{new_datas}->{$self->{instance} . '_' . $value->{name}} - $options{old_datas}->{$self->{instance} . '_' . $value->{name}}; @@ -108,15 +110,15 @@ sub threshold_check { return &{$self->{closure_custom_threshold_check}}($self, %options); } - my $warn = defined($self->{threshold_warn}) ? $self->{threshold_warn} : 'warning-' . $self->{label}; - my $crit = defined($self->{threshold_crit}) ? $self->{threshold_crit} : 'critical-' . $self->{label}; + my $warn = defined($self->{threshold_warn}) ? $self->{threshold_warn} : 'warning-' . $self->{thlabel}; + my $crit = defined($self->{threshold_crit}) ? $self->{threshold_crit} : 'critical-' . $self->{thlabel}; my $first = ${${$self->{key_values}}[0]}{name}; my $value; if (!defined($self->{threshold_use})) { $value = $self->{result_values}->{$first . '_absolute'}; - if ($self->{per_second} == 1) { + if (defined($self->{per_second}) && $self->{per_second} == 1) { $value = $self->{result_values}->{$first . '_per_second'}; } } else { @@ -160,6 +162,16 @@ sub output { return sprintf($self->{output_template}, $value, $unit); } +sub use_instances { + my ($self, %options) = @_; + + if (!defined($options{extra_instance}) || $options{extra_instance} != 0 || $self->{output}->use_new_perfdata()) { + return 1; + } + + return 0; +} + sub perfdata { my ($self, %options) = @_; @@ -167,8 +179,8 @@ sub perfdata { return &{$self->{closure_custom_perfdata}}($self, %options); } - my $warn = defined($self->{threshold_warn}) ? $self->{threshold_warn} : 'warning-' . $self->{label}; - my $crit = defined($self->{threshold_crit}) ? $self->{threshold_crit} : 'critical-' . $self->{label}; + my $warn = defined($self->{threshold_warn}) ? $self->{threshold_warn} : 'warning-' . $self->{thlabel}; + my $crit = defined($self->{threshold_crit}) ? $self->{threshold_crit} : 'critical-' . $self->{thlabel}; foreach my $perf (@{$self->{perfdatas}}) { my ($label, $extra_label, $min, $max, $th_total) = ($self->{label}, ''); @@ -187,21 +199,30 @@ sub perfdata { $th_total = ($perf->{threshold_total} =~ /[^0-9]/) ? $self->{result_values}->{$perf->{threshold_total}} : $perf->{threshold_total}; } - if (defined($perf->{label_extra_instance}) && $perf->{label_extra_instance} == 1 && - (!defined($options{extra_instance}) || $options{extra_instance} != 0)) { - + my $instances; + if (defined($perf->{label_extra_instance}) && $perf->{label_extra_instance} == 1) { + my $instance = ''; if (defined($perf->{instance_use})) { - $extra_label .= '_' . $self->{result_values}->{$perf->{instance_use}}; + $instance = $self->{result_values}->{$perf->{instance_use}}; } else { - $extra_label .= '_' . $self->{instance}; + $instance = $self->{instance}; + } + + if (!defined($options{extra_instance}) || $options{extra_instance} != 0 || $self->{output}->use_new_perfdata()) { + $instances = $instance; } } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => $perf->{unit}, - value => $cast_int == 1 ? int($self->{result_values}->{$perf->{value}}) : sprintf($template, $self->{result_values}->{$perf->{value}}), - warning => $self->{perfdata}->get_perfdata_for_output(label => $warn, total => $th_total, cast_int => $cast_int), - critical => $self->{perfdata}->get_perfdata_for_output(label => $crit, total => $th_total, cast_int => $cast_int), - min => $min, max => $max); + $self->{output}->perfdata_add( + label => $label, + instances => $instances, + nlabel => $self->{nlabel}, + unit => $perf->{unit}, + value => $cast_int == 1 ? int($self->{result_values}->{$perf->{value}}) : sprintf($template, $self->{result_values}->{$perf->{value}}), + warning => $self->{perfdata}->get_perfdata_for_output(label => $warn, total => $th_total, cast_int => $cast_int), + critical => $self->{perfdata}->get_perfdata_for_output(label => $crit, total => $th_total, cast_int => $cast_int), + min => $min, max => $max + ); } } @@ -260,7 +281,7 @@ sub execute { return -1; } - if ($self->{per_second} == 1) { + if (defined($self->{per_second}) && $self->{per_second} == 1) { if (!defined($self->{last_timestamp})) { $self->{last_timestamp} = $self->{statefile}->get(name => 'last_timestamp'); } @@ -271,7 +292,7 @@ sub execute { } my $delta_time; - if ($self->{per_second} == 1) { + if (defined($self->{per_second}) && $self->{per_second} == 1) { $delta_time = $options{new_datas}->{last_timestamp} - $self->{last_timestamp}; if ($delta_time <= 0) { $delta_time = 1; diff --git a/centreon_plugins.pl b/centreon_plugins.pl old mode 100644 new mode 100755 diff --git a/changelog b/changelog index ac33c3965..a6b1bf094 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,111 @@ +2019-XX-XX Quentin Garnier + * Plugin added: Cisco ACI APIC Rest API + * Plugin added: OpenLDAP + * Plugin added: SCCM + * Plugin added: Cisco ESA XML API + * Plugin added: MongoDB + * Plugin added: Ovirt Rest API + * Plugin added: Keepalived SNMP + * Plugin added: Openweathermap Rest API + * Plugin added: 3CX Rest API + * Plugin added: Atto FiberBridge SNMP + * Plugin added: Buffalo TeraStation SNMP + * Mode added: [oracle] 'librarycacheusage' + * Mode added: [oracle] 'dictionarycacheusage' + * Mode added: [oracle] 'redologusage' + * Enhancement: [haproxy/snmp] manage oss mib (#1475) + * Enhancement: [oracle] Fix segfault with last DBD::Oracle + * Break: [pdu/apc] modes refactoring + * Break: [pdu/eaton] modes refactoring + * Break: [apps/lmsensors] modes refactoring + * Break: [cisco/standard] 'cpu', 'memory' refactoring + * Break: [3par/ssh] modes refactoring + +2019-04-12 Quentin Garnier + * Plugin added: Google Cloud Platform Compute Engine API + * Plugin added: Prometheus NGINX Ingress Controller + * Plugin added: Bind9 Web + * Plugin added: Rudder Rest API + * Plugin added: Kubernetes API + * Plugin added: Protocol TFTP + * Plugin added: Rad Airmux SNMP + * Plugin added: Alvarion Breezeaccess SNMP + * Plugin added: Riverbed Interceptor SNMP + * Plugin added: WSUS + * Plugin added: Sahipro + * Mode added: [linux/local] 'ntp' + * Mode added: [macafee/webgateway] 'versions' + * Mode added: [ups/apc] 'input-lines' + * Mode added: [oracle] 'password-expiration' + * Mode added: [fortigate] 'ap-usage' + * Mode added: [centreon/local] 'bam-services' + * Mode added: [linux/local] 'discovery' + * Mode added: [aws] 'discovery' + * Mode added: [azure] 'discovery' + * Mode added: [vmware] 'discovery' + * Enhancement: [core] add float-precision option + * Enhancement: [core] add --extend-perfdata-group option + * Enhancement: [core/http] add curl backend support + * Enhancement: [core/http] add debug for lwp backend + * Enhancement: [oracle] add servicename support + * Enhancement: [snmp_standard] 'storage' (#1042) + * Enhancement: [snmp_standard] 'interfaces' (#712) + * Enhancement: [snmp_standard] 'list-interfaces' (#713) + * Enhancement: [f5/bigip] 'list-virtualservers' (#1252) + * Enhancement: [linux/local] 'traffic' 'packet-errors' (#916) + * Enhancement: [protocols/http] 'expected-content' + * Enhancement: [linux/local] 'process' (#1438) + * Enhancement: [cisco/snmp] 'interfaces' (#454) + * Enhancement: [hwgste/snmp] 'sensors' (#585) + * Enhancement: [azure] better apis responses handling + * Fix: Ctrl+F "Fix" on commits page + * Break: [dell/equallogic] modes refactoring + * Break: [snmp_standard] mode memory refactoring changes thresholds + +2019-02-21 Quentin Garnier + * Plugin added: Microsoft Azure Recovery and Backup + * Plugin added: Microsoft Azure ExpressRoute + * Plugin added: Microsoft Azure VPN Gateway + * Plugin added: Microsoft Azure Virtual Network + * Plugin added: Microsoft Azure SQL Server and Database + * Plugin added: Squid SNMP + * Plugin added: Informix Database SNMP + * Plugin added: Lenovo XCC SNMP + * Plugin added: Peplink Pepwave SNMP + * Plugin added: Centreon MAP JMX (>= 18.10) + * Plugin added: Adder AIM SNMP + * Plugin added: Kafka JMX + * Plugin added: Cassandra JMX + * Plugin added: Office 365 Teams + * Plugin added: Office 365 Skype for Business + * Plugin added: Skype 2015 MSSQL + * Plugin added: HP Standard SNMP + * Plugin added: Mac OS SNMP + * Mode added: [snmp_standard] 'listspanningtrees' + * Mode added: [quantum dxi] 'dedupvtl' + * Mode added: [protocols/snmp] 'response-time' + * Enhancement: [vmware/connector] compatibility with VMware connector 3.x with enhancement + * Enhancement: [azure] many improvements in Azure plugins (tags, dates format) + * Enhancement: [office] change metrics behaviour, more global + * Enhancement: [core] add password management system + * Enhancement: [core/template] add catalog template method + * Enhancement: [core/template] enhance counter type 3 + * Enhancement: [core/snmp] change snmpv3 management parameters + * Enhancement: [core/exec] change exit behaviour in case of failure + * Enhancement: [protocols/http] refacto expected-content mode, add possibility to extract data + * Enhancement: [database/oracle] add sqlpluscmd connection method + * Enhancement: [snmp_standard] spanningtree mode + * Enhancement: [centreon/sql] pollerdelay mode + * Enhancement: [mssql] 'failed-jobs' (#1365) + * Enhancement: [snmp_standard] 'interfaces' (#553) + * Enhancement: [prometheus/api] add headers handling + * Enhancement: [centreon/sql] add filter for broker stats + * Fix: [fortinet/fortigate] enhance cluster status mode + * Fix: [core/http] fix get-param option (#1355) + * Fix: [ilo xmlapi] fix nic management (#1358 #1213) + * Break: [informix/sql] change informix sql plugin path + * Break: [vmware/connector] several options changement + 2019-01-11 Colin Gagnaire * Plugin added: Office 365 (PR #1288) * Plugin added: IBM Cloud SoftLayer (PR #1224, #1226, #1241, #1273) diff --git a/cloud/aws/cloudfront/mode/requests.pm b/cloud/aws/cloudfront/mode/requests.pm index 3265d6ea0..b6c6d9a8d 100644 --- a/cloud/aws/cloudfront/mode/requests.pm +++ b/cloud/aws/cloudfront/mode/requests.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -48,7 +46,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'critical' }, { label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'warning' } ]); return $exit; @@ -61,8 +59,8 @@ sub custom_metric_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'requests/s' : 'requests', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'requests/s' : 'requests', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -72,7 +70,7 @@ sub custom_metric_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); $msg = $self->{result_values}->{metric} . ": " . $value . "requests/s"; } else { @@ -111,12 +109,11 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "id:s@" => { name => 'id' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "id:s@" => { name => 'id' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -148,9 +145,7 @@ sub check_options { } } - push @{$self->{aws_metrics}}, 'Requests'; - - $instance_mode = $self; + push @{$self->{aws_metrics}}, 'Requests'; } sub manage_selection { diff --git a/cloud/aws/cloudfront/mode/throughput.pm b/cloud/aws/cloudfront/mode/throughput.pm index d2cafe947..1f4725127 100644 --- a/cloud/aws/cloudfront/mode/throughput.pm +++ b/cloud/aws/cloudfront/mode/throughput.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -48,7 +46,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'critical' }, { label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'warning' } ]); return $exit; @@ -61,8 +59,8 @@ sub custom_metric_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'B/s' : 'B', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -72,7 +70,7 @@ sub custom_metric_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); $msg = $self->{result_values}->{metric} . ": " . $value . $unit . "/s"; } else { @@ -111,13 +109,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "id:s@" => { name => 'id' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "id:s@" => { name => 'id' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -155,8 +152,6 @@ sub check_options { push @{$self->{aws_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/aws/cloudwatch/mode/discovery.pm b/cloud/aws/cloudwatch/mode/discovery.pm new file mode 100644 index 000000000..1a37729ab --- /dev/null +++ b/cloud/aws/cloudwatch/mode/discovery.pm @@ -0,0 +1,254 @@ +# +# Copyright 2019 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 cloud::aws::cloudwatch::mode::discovery; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use JSON::XS; + +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 => { + "service:s@" => { name => 'service' }, + "prettify" => { name => 'prettify' }, + }); + + $self->{services} = { + VPC => $self->can('discover_vpc'), + EC2 => $self->can('discover_ec2'), + RDS => $self->can('discover_rds'), + ELB => $self->can('discover_elb'), + VPN => $self->can('discover_vpn'), + }; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{service}) || $self->{option_results}->{service} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --service option."); + $self->{output}->option_exit(); + } +} + +sub discover_vpc { + my (%options) = @_; + + my @disco_data; + + my $vpcs = $options{custom}->discovery(region => $options{region}, + service => 'ec2', command => 'describe-vpcs'); + foreach my $vpc (@{$vpcs->{Vpcs}}) { + next if (!defined($vpc->{VpcId})); + my %vpc; + $vpc{type} = "vpc"; + $vpc{id} = $vpc->{VpcId}; + $vpc{state} = $vpc->{State}; + $vpc{cidr} = $vpc->{CidrBlock}; + foreach my $tag (@{$vpc->{Tags}}) { + if ($tag->{Key} eq "Name" && defined($tag->{Value})) { + $vpc{name} = $tag->{Value}; + } + push @{$vpc{tags}}, { key => $tag->{Key}, value => $tag->{Value} }; + } + push @disco_data, \%vpc; + } + return @disco_data; +} + +sub discover_ec2 { + my (%options) = @_; + + my @disco_data; + my %asgs; + + my $instances = $options{custom}->discovery(region => $options{region}, + service => 'ec2', command => 'describe-instances'); + foreach my $reservation (@{$instances->{Reservations}}) { + foreach my $instance (@{$reservation->{Instances}}) { + next if (!defined($instance->{InstanceId})); + my %asg; + $asg{type} = "asg"; + my %ec2; + $ec2{type} = "ec2"; + $ec2{id} = $instance->{InstanceId}; + $ec2{state} = $instance->{State}->{Name}; + $ec2{key_name} = $instance->{KeyName}; + $ec2{private_ip} = $instance->{PrivateIpAddress}; + $ec2{private_dns_name} = $instance->{PrivateDnsName}; + $ec2{public_dns_name} = $instance->{PublicDnsName}; + $ec2{instance_type} = $instance->{InstanceType}; + $ec2{vpc_id} = $instance->{VpcId}; + foreach my $tag (@{$instance->{Tags}}) { + if ($tag->{Key} eq "aws:autoscaling:groupName" && defined($tag->{Value})) { + $ec2{asg} = $tag->{Value}; + next if (defined($asgs{$tag->{Value}})); + $asg{name} = $tag->{Value}; + $asgs{$tag->{Value}} = 1; + } + if ($tag->{Key} eq "Name" && defined($tag->{Value})) { + $ec2{name} = $tag->{Value}; + } + push @{$ec2{tags}}, { key => $tag->{Key}, value => $tag->{Value} }; + } + push @disco_data, \%ec2; + push @disco_data, \%asg if (defined($asg{name}) && $asg{name} ne ''); + } + } + return @disco_data; +} + +sub discover_rds { + my (%options) = @_; + + my @disco_data; + + my $db_instances = $options{custom}->discovery(region => $options{region}, + service => 'rds', command => 'describe-db-instances'); + foreach my $db_instance (@{$db_instances->{DBInstances}}) { + next if (!defined($db_instance->{DbiResourceId})); + my %rds; + $rds{type} = "rds"; + $rds{id} = $db_instance->{DbiResourceId}; + $rds{name} = $db_instance->{DBInstanceIdentifier}; + $rds{status} = $db_instance->{DBInstanceStatus}; + $rds{storage_type} = $db_instance->{StorageType}; + $rds{instance_class} = $db_instance->{DBInstanceClass}; + $rds{availability_zone} = $db_instance->{AvailabilityZone}; + $rds{vpc_id} = $db_instance->{DBSubnetGroup}->{VpcId}; + push @disco_data, \%rds; + } + return @disco_data; +} + +sub discover_elb { + my (%options) = @_; + + my @disco_data; + + my $load_balancers = $options{custom}->discovery(region => $options{region}, + service => 'elb', command => 'describe-load-balancers'); + foreach my $load_balancer (@{$load_balancers->{LoadBalancerDescriptions}}) { + next if (!defined($load_balancer->{LoadBalancerName})); + my %elb; + $elb{type} = "elb"; + $elb{name} = $load_balancer->{LoadBalancerName}; + $elb{dns_name} = $load_balancer->{DNSName}; + $elb{availability_zones} = $load_balancer->{AvailabilityZones}; + $elb{vpc_id} = $load_balancer->{VPCId}; + push @disco_data, \%elb; + } + return @disco_data; +} + +sub discover_vpn { + my (%options) = @_; + + my @disco_data; + + my $vpns = $options{custom}->discovery(region => $options{region}, + service => 'ec2', command => 'describe-vpn-connections'); + foreach my $connection (@{$vpns->{VpnConnections}}) { + next if (!defined($connection->{VpnConnectionId})); + my %vpn; + $vpn{type} = "vpn"; + $vpn{id} = $connection->{VpnConnectionId}; + $vpn{connection_type} = $connection->{Type}; + $vpn{state} = $connection->{State}; + $vpn{category} = $connection->{Category}; + foreach my $tag (@{$connection->{Tags}}) { + if ($tag->{Key} eq "Name" && defined($tag->{Value})) { + $vpn{name} = $tag->{Value}; + } + push @{$vpn{tags}}, { key => $tag->{Key}, value => $tag->{Value} }; + } + push @disco_data, \%vpn; + } + return @disco_data; +} + +sub run { + my ($self, %options) = @_; + + my @disco_data; + my $disco_stats; + + $disco_stats->{start_time} = time(); + + foreach my $service (@{$self->{option_results}->{service}}) { + push @disco_data, $self->{services}->{uc($service)}->(custom => $options{custom}, + region => $self->{option_results}->{region}) if (defined($self->{services}->{uc($service)})); + } + + $disco_stats->{end_time} = time(); + $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; + $disco_stats->{discovered_items} = @disco_data; + $disco_stats->{results} = \@disco_data; + + my $encoded_data; + eval { + if (defined($self->{option_results}->{prettify})) { + $encoded_data = JSON::XS->new->utf8->pretty->encode($disco_stats); + } else { + $encoded_data = JSON::XS->new->utf8->encode($disco_stats); + } + }; + if ($@) { + $encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}'; + } + + $self->{output}->output_add(short_msg => $encoded_data); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Resources discovery. + +=over 8 + +=item B<--service> + +Choose the service from which discover +resources (Can be: 'VPC', 'EC2', 'RDS', +'ELB', 'VPN') (Mandatory). + +=item B<--prettify> + +Prettify JSON output. + +=back + +=cut diff --git a/cloud/aws/cloudwatch/plugin.pm b/cloud/aws/cloudwatch/plugin.pm index 630e8141d..1efbb1b21 100644 --- a/cloud/aws/cloudwatch/plugin.pm +++ b/cloud/aws/cloudwatch/plugin.pm @@ -31,9 +31,10 @@ sub new { $self->{version} = '0.1'; %{ $self->{modes} } = ( - 'get-alarms' => 'cloud::aws::cloudwatch::mode::getalarms', - 'get-metrics' => 'cloud::aws::cloudwatch::mode::getmetrics', - 'list-metrics' => 'cloud::aws::cloudwatch::mode::listmetrics', + 'discovery' => 'cloud::aws::cloudwatch::mode::discovery', + 'get-alarms' => 'cloud::aws::cloudwatch::mode::getalarms', + 'get-metrics' => 'cloud::aws::cloudwatch::mode::getmetrics', + 'list-metrics' => 'cloud::aws::cloudwatch::mode::listmetrics', ); $self->{custom_modes}{paws} = 'cloud::aws::custom::paws'; diff --git a/cloud/aws/custom/awscli.pm b/cloud/aws/custom/awscli.pm index 1d5ec9f50..c86e59b4f 100644 --- a/cloud/aws/custom/awscli.pm +++ b/cloud/aws/custom/awscli.pm @@ -40,23 +40,22 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "aws-secret-key:s" => { name => 'aws_secret_key' }, - "aws-access-key:s" => { name => 'aws_access_key' }, - "endpoint-url:s" => { name => 'endpoint_url' }, - "region:s" => { name => 'region' }, - "timeframe:s" => { name => 'timeframe' }, - "period:s" => { name => 'period' }, - "statistic:s@" => { name => 'statistic' }, - "zeroed" => { name => 'zeroed' }, - "timeout:s" => { name => 'timeout', default => 50 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'aws' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '' }, - "proxyurl:s" => { name => 'proxyurl' }, - }); + $options{options}->add_options(arguments => { + "aws-secret-key:s" => { name => 'aws_secret_key' }, + "aws-access-key:s" => { name => 'aws_access_key' }, + "endpoint-url:s" => { name => 'endpoint_url' }, + "region:s" => { name => 'region' }, + "timeframe:s" => { name => 'timeframe' }, + "period:s" => { name => 'period' }, + "statistic:s@" => { name => 'statistic' }, + "zeroed" => { name => 'zeroed' }, + "timeout:s" => { name => 'timeout', default => 50 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'aws' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '' }, + "proxyurl:s" => { name => 'proxyurl' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'AWSCLI OPTIONS', once => 1); @@ -122,6 +121,35 @@ sub check_options { return 0; } +sub execute { + my ($self, %options) = @_; + + $self->{output}->output_add(long_msg => "Command line: '" . $self->{option_results}->{command} . " " . $options{cmd_options} . "'", debug => 1); + + my ($response) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $options{cmd_options}, + redirect_stderr => 0 + ); + + my $raw_results; + + eval { + $raw_results = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->output_add(long_msg => $response, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + + return $raw_results; +} + sub cloudwatch_get_metrics_set_cmd { my ($self, %options) = @_; @@ -146,86 +174,79 @@ sub cloudwatch_get_metrics { my $end_time = DateTime->now->iso8601; foreach my $metric_name (@{$options{metrics}}) { - my $cmd_options = $self->cloudwatch_get_metrics_set_cmd(%options, metric_name => $metric_name, start_time => $start_time, end_time => $end_time); - my ($response) = centreon::plugins::misc::execute( - output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $cmd_options); + my $cmd_options = $self->cloudwatch_get_metrics_set_cmd(%options, metric_name => $metric_name, + start_time => $start_time, end_time => $end_time); + my $raw_results = $self->execute(cmd_options => $cmd_options); - my $metric_result; - eval { - $metric_result = JSON::XS->new->utf8->decode($response); - }; - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); - $self->{output}->option_exit(); - } - - $metric_results->{$metric_result->{Label}} = { points => 0 }; - foreach my $point (@{$metric_result->{Datapoints}}) { + $metric_results->{$raw_results->{Label}} = { points => 0 }; + foreach my $point (@{$raw_results->{Datapoints}}) { if (defined($point->{Average})) { - $metric_results->{$metric_result->{Label}}->{average} = 0 if (!defined($metric_results->{$metric_result->{Label}}->{average})); - $metric_results->{$metric_result->{Label}}->{average} += $point->{Average}; + $metric_results->{$raw_results->{Label}}->{average} = 0 if (!defined($metric_results->{$raw_results->{Label}}->{average})); + $metric_results->{$raw_results->{Label}}->{average} += $point->{Average}; } if (defined($point->{Minimum})) { - $metric_results->{$metric_result->{Label}}->{minimum} = $point->{Minimum} - if (!defined($metric_results->{$metric_result->{Label}}->{minimum}) || $point->{Minimum} < $metric_results->{$metric_result->{Label}}->{minimum}); + $metric_results->{$raw_results->{Label}}->{minimum} = $point->{Minimum} + if (!defined($metric_results->{$raw_results->{Label}}->{minimum}) || $point->{Minimum} < $metric_results->{$raw_results->{Label}}->{minimum}); } if (defined($point->{Maximum})) { - $metric_results->{$metric_result->{Label}}->{maximum} = $point->{Maximum} - if (!defined($metric_results->{$metric_result->{Label}}->{maximum}) || $point->{Maximum} > $metric_results->{$metric_result->{Label}}->{maximum}); + $metric_results->{$raw_results->{Label}}->{maximum} = $point->{Maximum} + if (!defined($metric_results->{$raw_results->{Label}}->{maximum}) || $point->{Maximum} > $metric_results->{$raw_results->{Label}}->{maximum}); } if (defined($point->{Sum})) { - $metric_results->{$metric_result->{Label}}->{sum} = 0 if (!defined($metric_results->{$metric_result->{Label}}->{sum})); - $metric_results->{$metric_result->{Label}}->{sum} += $point->{Sum}; + $metric_results->{$raw_results->{Label}}->{sum} = 0 if (!defined($metric_results->{$raw_results->{Label}}->{sum})); + $metric_results->{$raw_results->{Label}}->{sum} += $point->{Sum}; } - $metric_results->{$metric_result->{Label}}->{points}++; + $metric_results->{$raw_results->{Label}}->{points}++; } - if (defined($metric_results->{$metric_result->{Label}}->{average})) { - $metric_results->{$metric_result->{Label}}->{average} /= $metric_results->{$metric_result->{Label}}->{points}; + if (defined($metric_results->{$raw_results->{Label}}->{average})) { + $metric_results->{$raw_results->{Label}}->{average} /= $metric_results->{$raw_results->{Label}}->{points}; } } return $metric_results; } +sub discovery_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + my $cmd_options = $options{service} . " " . $options{command} . " --region $options{region} --output json"; + $cmd_options .= " --endpoint-url $self->{endpoint_url}" if (defined($self->{endpoint_url}) && $self->{endpoint_url} ne ''); + + return $cmd_options; +} + +sub discovery { + my ($self, %options) = @_; + + my $cmd_options = $self->discovery_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return $raw_results; +} + sub cloudwatch_get_alarms_set_cmd { my ($self, %options) = @_; return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + my $cmd_options = "cloudwatch describe-alarms --region $options{region} --output json"; $cmd_options .= " --endpoint-url $self->{endpoint_url}" if (defined($self->{endpoint_url}) && $self->{endpoint_url} ne ''); + return $cmd_options; } sub cloudwatch_get_alarms { my ($self, %options) = @_; - + my $cmd_options = $self->cloudwatch_get_alarms_set_cmd(%options); - my ($response) = centreon::plugins::misc::execute( - output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $cmd_options - ); - my $alarm_result; - eval { - $alarm_result = JSON::XS->new->utf8->decode($response); - }; - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); - $self->{output}->option_exit(); - } + my $raw_results = $self->execute(cmd_options => $cmd_options); my $alarm_results = []; - foreach my $alarm (@{$alarm_result->{MetricAlarms}}) { + foreach my $alarm (@{$raw_results->{MetricAlarms}}) { push @$alarm_results, { AlarmName => $alarm->{AlarmName}, StateValue => $alarm->{StateValue}, @@ -241,71 +262,47 @@ sub cloudwatch_list_metrics_set_cmd { my ($self, %options) = @_; return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + my $cmd_options = "cloudwatch list-metrics --region $options{region} --output json"; $cmd_options .= " --namespace $options{namespace}" if defined($options{namespace}); $cmd_options .= " --metric-name $options{metric}" if defined($options{metric}); $cmd_options .= " --endpoint-url $self->{endpoint_url}" if (defined($self->{endpoint_url}) && $self->{endpoint_url} ne ''); + return $cmd_options; } sub cloudwatch_list_metrics { my ($self, %options) = @_; - + my $cmd_options = $self->cloudwatch_list_metrics_set_cmd(%options); - my ($response) = centreon::plugins::misc::execute( - output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $cmd_options - ); - my $list_metrics; - eval { - $list_metrics = JSON::XS->new->utf8->decode($response); - }; - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); - $self->{output}->option_exit(); - } + my $raw_results = $self->execute(cmd_options => $cmd_options); - return $list_metrics->{Metrics}; + return $raw_results->{Metrics}; } sub ec2_get_instances_status_set_cmd { my ($self, %options) = @_; return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + my $cmd_options = "ec2 describe-instance-status --include-all-instances --no-dry-run --region $options{region} --output json"; $cmd_options .= " --endpoint-url $self->{endpoint_url}" if (defined($self->{endpoint_url}) && $self->{endpoint_url} ne ''); + return $cmd_options; } sub ec2_get_instances_status { my ($self, %options) = @_; - + my $cmd_options = $self->ec2_get_instances_status_set_cmd(%options); - my ($response) = centreon::plugins::misc::execute( - output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $cmd_options - ); - my $list_instances; - eval { - $list_instances = JSON::XS->new->utf8->decode($response); - }; - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); - $self->{output}->option_exit(); - } + my $raw_results = $self->execute(cmd_options => $cmd_options); my $instance_results = {}; - foreach (@{$list_instances->{InstanceStatuses}}) { - $instance_results->{$_->{InstanceId}} = { state => $_->{InstanceState}->{Name}, - status => => $_->{InstanceStatus}->{Status} }; + foreach (@{$raw_results->{InstanceStatuses}}) { + $instance_results->{$_->{InstanceId}} = { + state => $_->{InstanceState}->{Name}, + status => => $_->{InstanceStatus}->{Status} + }; } return $instance_results; @@ -315,34 +312,21 @@ sub ec2_list_resources_set_cmd { my ($self, %options) = @_; return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + my $cmd_options = "ec2 describe-instances --no-dry-run --region $options{region} --output json"; $cmd_options .= " --endpoint-url $self->{endpoint_url}" if (defined($self->{endpoint_url}) && $self->{endpoint_url} ne ''); + return $cmd_options; } sub ec2_list_resources { my ($self, %options) = @_; - + my $cmd_options = $self->ec2_list_resources_set_cmd(%options); - my ($response) = centreon::plugins::misc::execute( - output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $cmd_options - ); - my $list_instances; - eval { - $list_instances = JSON::XS->new->utf8->decode($response); - }; - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); - $self->{output}->option_exit(); - } + my $raw_results = $self->execute(cmd_options => $cmd_options); my $resource_results = []; - foreach my $reservation (@{$list_instances->{Reservations}}) { + foreach my $reservation (@{$raw_results->{Reservations}}) { foreach my $instance (@{$reservation->{Instances}}) { my @instance_tags; foreach my $tag (@{$instance->{Tags}}) { @@ -376,8 +360,10 @@ sub asg_get_resources_set_cmd { my ($self, %options) = @_; return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + my $cmd_options = "autoscaling describe-auto-scaling-groups --region $options{region} --output json"; $cmd_options .= " --endpoint-url $self->{endpoint_url}" if (defined($self->{endpoint_url}) && $self->{endpoint_url} ne ''); + return $cmd_options; } @@ -385,59 +371,30 @@ sub asg_get_resources { my ($self, %options) = @_; my $cmd_options = $self->asg_get_resources_set_cmd(%options); - my ($response) = centreon::plugins::misc::execute( - output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $cmd_options - ); - - my $autoscaling_groups; - eval { - $autoscaling_groups = JSON::XS->new->utf8->decode($response); - }; - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); - $self->{output}->option_exit(); - } - - return \@{$autoscaling_groups->{AutoScalingGroups}}; + my $raw_results = $self->execute(cmd_options => $cmd_options); + + return \@{$raw_results->{AutoScalingGroups}}; } sub rds_get_instances_status_set_cmd { my ($self, %options) = @_; return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + my $cmd_options = "rds describe-db-instances --region $options{region} --output json"; $cmd_options .= " --endpoint-url $self->{endpoint_url}" if (defined($self->{endpoint_url}) && $self->{endpoint_url} ne ''); + return $cmd_options; } sub rds_get_instances_status { my ($self, %options) = @_; - + my $cmd_options = $self->rds_get_instances_status_set_cmd(%options); - my ($response) = centreon::plugins::misc::execute( - output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $cmd_options - ); - my $list_instances; - eval { - $list_instances = JSON::XS->new->utf8->decode($response); - }; - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); - $self->{output}->option_exit(); - } + my $raw_results = $self->execute(cmd_options => $cmd_options); my $instance_results = {}; - foreach (@{$list_instances->{DBInstances}}) { + foreach (@{$raw_results->{DBInstances}}) { $instance_results->{$_->{DBInstanceIdentifier}} = { state => $_->{DBInstanceStatus} }; } @@ -448,34 +405,21 @@ sub rds_list_instances_set_cmd { my ($self, %options) = @_; return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + my $cmd_options = "rds describe-db-instances --region $options{region} --output json"; $cmd_options .= " --endpoint-url $self->{endpoint_url}" if (defined($self->{endpoint_url}) && $self->{endpoint_url} ne ''); + return $cmd_options; } sub rds_list_instances { my ($self, %options) = @_; - - my $cmd_options = $self->rds_get_instances_status_set_cmd(%options); - my ($response) = centreon::plugins::misc::execute( - output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $cmd_options - ); - my $list_instances; - eval { - $list_instances = JSON::XS->new->utf8->decode($response); - }; - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); - $self->{output}->option_exit(); - } + + my $cmd_options = $self->rds_list_instances_set_cmd(%options); + my $raw_results = $self->execute(cmd_options => $cmd_options); my $instance_results = []; - foreach my $instance (@{$list_instances->{DBInstances}}) { + foreach my $instance (@{$raw_results->{DBInstances}}) { push @{$instance_results}, { Name => $instance->{DBInstanceIdentifier}, AvailabilityZone => $instance->{AvailabilityZone}, @@ -492,34 +436,21 @@ sub rds_list_clusters_set_cmd { my ($self, %options) = @_; return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + my $cmd_options = "rds describe-db-clusters --region $options{region} --output json"; $cmd_options .= " --endpoint-url $self->{endpoint_url}" if (defined($self->{endpoint_url}) && $self->{endpoint_url} ne ''); + return $cmd_options; } sub rds_list_clusters { my ($self, %options) = @_; - + my $cmd_options = $self->rds_list_clusters_set_cmd(%options); - my ($response) = centreon::plugins::misc::execute( - output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $cmd_options - ); - my $list_clusters; - eval { - $list_clusters = JSON::XS->new->utf8->decode($response); - }; - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); - $self->{output}->option_exit(); - } + my $raw_results = $self->execute(cmd_options => $cmd_options); my $cluster_results = []; - foreach my $cluster (@{$list_clusters->{DBClusters}}) { + foreach my $cluster (@{$raw_results->{DBClusters}}) { push @{$cluster_results}, { Name => $cluster->{DBClusterIdentifier}, DatabaseName => $cluster->{DatabaseName}, diff --git a/cloud/aws/custom/paws.pm b/cloud/aws/custom/paws.pm index d17fb5e6e..731200450 100644 --- a/cloud/aws/custom/paws.pm +++ b/cloud/aws/custom/paws.pm @@ -40,16 +40,15 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "aws-secret-key:s" => { name => 'aws_secret_key' }, - "aws-access-key:s" => { name => 'aws_access_key' }, - "region:s" => { name => 'region' }, - "timeframe:s" => { name => 'timeframe' }, - "period:s" => { name => 'period' }, - "statistic:s@" => { name => 'statistic' }, - "zeroed" => { name => 'zeroed' }, - }); + $options{options}->add_options(arguments => { + "aws-secret-key:s" => { name => 'aws_secret_key' }, + "aws-access-key:s" => { name => 'aws_access_key' }, + "region:s" => { name => 'region' }, + "timeframe:s" => { name => 'timeframe' }, + "period:s" => { name => 'period' }, + "statistic:s@" => { name => 'statistic' }, + "zeroed" => { name => 'zeroed' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'PAWS OPTIONS', once => 1); diff --git a/cloud/aws/ec2/mode/diskio.pm b/cloud/aws/ec2/mode/diskio.pm index f0943a37f..d4f9cc715 100644 --- a/cloud/aws/ec2/mode/diskio.pm +++ b/cloud/aws/ec2/mode/diskio.pm @@ -30,8 +30,6 @@ my %map_type = ( "asg" => "AutoScalingGroupName", ); -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -53,7 +51,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'critical' }, { label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'warning' } ]); return $exit; @@ -66,8 +64,8 @@ sub custom_usage_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'B/s' : 'B', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -77,7 +75,7 @@ sub custom_usage_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); $msg = $self->{result_values}->{metric} . ": " . $value . $unit . "/s"; } else { @@ -94,8 +92,8 @@ sub custom_ops_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'ops/s' : 'ops', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'ops/s' : 'ops', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -106,7 +104,7 @@ sub custom_ops_output { my $msg =""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { $msg = sprintf("%s: %.2f ops/s", $self->{result_values}->{metric}, $self->{result_values}->{value_per_sec}); } else { $msg = sprintf("%s: %.2f ops", $self->{result_values}->{metric}, $self->{result_values}->{value}); @@ -156,14 +154,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "type:s" => { name => 'type' }, - "name:s@" => { name => 'name' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "type:s" => { name => 'type' }, + "name:s@" => { name => 'name' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -211,8 +208,6 @@ sub check_options { push @{$self->{aws_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/aws/ec2/mode/listinstances.pm b/cloud/aws/ec2/mode/listinstances.pm index b1ba67fd1..83b211ae5 100644 --- a/cloud/aws/ec2/mode/listinstances.pm +++ b/cloud/aws/ec2/mode/listinstances.pm @@ -31,9 +31,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } @@ -55,7 +54,7 @@ sub run { $self->manage_selection(%options); foreach (@{$self->{instances}}) { next if ($_->{Type} !~ m/instance/); - $self->{output}->output_add(long_msg => sprintf("[Name = %s][AvailabilityZone = %s][InstanceType = %s][State = %s][Tags = %s]", + $self->{output}->output_add(long_msg => sprintf("[Id = %s][AvailabilityZone = %s][InstanceType = %s][State = %s][Tags = %s]", $_->{Name}, $_->{AvailabilityZone}, $_->{InstanceType}, $_->{State}, $_->{Tags})); } @@ -68,7 +67,7 @@ sub run { sub disco_format { my ($self, %options) = @_; - $self->{output}->add_disco_format(elements => ['name', 'availabilityzone', 'instancetype', 'state', 'tags']); + $self->{output}->add_disco_format(elements => ['id', 'availabilityzone', 'instancetype', 'state', 'tags']); } sub disco_show { @@ -78,7 +77,7 @@ sub disco_show { foreach (@{$self->{instances}}) { next if ($_->{Type} !~ m/instance/); $self->{output}->add_disco_entry( - name => $_->{Name}, + id => $_->{Name}, availabilityzone => $_->{AvailabilityZone}, instancetype => $_->{InstanceType}, state => $_->{State}, diff --git a/cloud/aws/ec2/mode/network.pm b/cloud/aws/ec2/mode/network.pm index 2cd07660a..137be8a6f 100644 --- a/cloud/aws/ec2/mode/network.pm +++ b/cloud/aws/ec2/mode/network.pm @@ -30,8 +30,6 @@ my %map_type = ( "asg" => "AutoScalingGroupName", ); -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -53,7 +51,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'critical' }, { label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'warning' } ]); return $exit; @@ -66,8 +64,8 @@ sub custom_traffic_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'B/s' : 'B', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -77,7 +75,7 @@ sub custom_traffic_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); $msg = $self->{result_values}->{metric} . ": " . $value . $unit . "/s"; } else { @@ -94,8 +92,8 @@ sub custom_packets_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'packets/s' : 'packets', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'packets/s' : 'packets', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -106,7 +104,7 @@ sub custom_packets_output { my $msg =""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { $msg = sprintf("%s: %.2f packets/s", $self->{result_values}->{metric}, $self->{result_values}->{value_per_sec}); } else { $msg = sprintf("%s: %.2f packets", $self->{result_values}->{metric}, $self->{result_values}->{value}); @@ -156,14 +154,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "type:s" => { name => 'type' }, - "name:s@" => { name => 'name' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "type:s" => { name => 'type' }, + "name:s@" => { name => 'name' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -211,8 +208,6 @@ sub check_options { push @{$self->{aws_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/aws/elasticache/mode/commandsmemcached.pm b/cloud/aws/elasticache/mode/commandsmemcached.pm index 15b222cb7..ed2874035 100644 --- a/cloud/aws/elasticache/mode/commandsmemcached.pm +++ b/cloud/aws/elasticache/mode/commandsmemcached.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -53,7 +51,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'critical' }, { label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'warning' } ]); return $exit; @@ -66,8 +64,8 @@ sub custom_metric_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'cmd/s' : 'cmd', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'cmd/s' : 'cmd', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -77,7 +75,7 @@ sub custom_metric_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { $msg = sprintf("%s: %.2f cmd/s", $self->{result_values}->{metric}, $self->{result_values}->{value_per_sec}); } else { $msg = sprintf("%s: %.2f cmd", $self->{result_values}->{metric}, $self->{result_values}->{value}); @@ -114,14 +112,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "name:s@" => { name => 'name' }, - "node-id:s" => { name => 'node_id' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "name:s@" => { name => 'name' }, + "node-id:s" => { name => 'node_id' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -159,8 +156,6 @@ sub check_options { push @{$self->{aws_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/aws/elasticache/mode/commandsredis.pm b/cloud/aws/elasticache/mode/commandsredis.pm index fcead2ccf..db911534d 100644 --- a/cloud/aws/elasticache/mode/commandsredis.pm +++ b/cloud/aws/elasticache/mode/commandsredis.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -53,7 +51,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'critical' }, { label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'warning' } ]); return $exit; @@ -66,8 +64,8 @@ sub custom_metric_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'cmd/s' : 'cmd', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'cmd/s' : 'cmd', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -77,7 +75,7 @@ sub custom_metric_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { $msg = sprintf("%s: %.2f cmd/s", $self->{result_values}->{metric}, $self->{result_values}->{value_per_sec}); } else { $msg = sprintf("%s: %.2f cmd", $self->{result_values}->{metric}, $self->{result_values}->{value}); @@ -115,14 +113,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "name:s@" => { name => 'name' }, - "node-id:s" => { name => 'node_id' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "name:s@" => { name => 'name' }, + "node-id:s" => { name => 'node_id' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -161,8 +158,6 @@ sub check_options { push @{$self->{aws_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/aws/elasticache/mode/connections.pm b/cloud/aws/elasticache/mode/connections.pm index 2befae9af..cd5e25952 100644 --- a/cloud/aws/elasticache/mode/connections.pm +++ b/cloud/aws/elasticache/mode/connections.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -53,7 +51,7 @@ sub custom_connection_calc { sub custom_connection_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'critical' }, { label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'warning' } ]); return $exit; @@ -66,8 +64,8 @@ sub custom_connection_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'conn/s' : 'conn', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'conn/s' : 'conn', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -77,7 +75,7 @@ sub custom_connection_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { $msg = sprintf("%s: %.2f connections/s", $self->{result_values}->{metric}, $self->{result_values}->{value_per_sec}); } else { $msg = sprintf("%s: %.2f connections", $self->{result_values}->{metric}, $self->{result_values}->{value}); @@ -126,14 +124,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "name:s@" => { name => 'name' }, - "node-id:s" => { name => 'node_id' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "name:s@" => { name => 'name' }, + "node-id:s" => { name => 'node_id' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -171,8 +168,6 @@ sub check_options { push @{$self->{aws_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/aws/elasticache/mode/evictions.pm b/cloud/aws/elasticache/mode/evictions.pm index f14c5acf5..5ad1059a2 100644 --- a/cloud/aws/elasticache/mode/evictions.pm +++ b/cloud/aws/elasticache/mode/evictions.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -53,7 +51,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'critical' }, { label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'warning' } ]); return $exit; @@ -66,8 +64,8 @@ sub custom_metric_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'evictions/s' : 'evictions', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'evictions/s' : 'evictions', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -77,7 +75,7 @@ sub custom_metric_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { $msg = sprintf("%s: %.2f evictions/s", $self->{result_values}->{metric}, $self->{result_values}->{value_per_sec}); } else { $msg = sprintf("%s: %.2f evictions", $self->{result_values}->{metric}, $self->{result_values}->{value}); @@ -114,14 +112,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "name:s@" => { name => 'name' }, - "node-id:s" => { name => 'node_id' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "name:s@" => { name => 'name' }, + "node-id:s" => { name => 'node_id' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -159,8 +156,6 @@ sub check_options { push @{$self->{aws_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/aws/elasticache/mode/items.pm b/cloud/aws/elasticache/mode/items.pm index 14ae15a73..f0b462826 100644 --- a/cloud/aws/elasticache/mode/items.pm +++ b/cloud/aws/elasticache/mode/items.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -53,7 +51,7 @@ sub custom_item_calc { sub custom_item_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'critical' }, { label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'warning' } ]); return $exit; @@ -66,8 +64,8 @@ sub custom_item_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'items/s' : 'items', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'items/s' : 'items', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -77,7 +75,7 @@ sub custom_item_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { $msg = sprintf("%s: %.2f items/s", $self->{result_values}->{metric}, $self->{result_values}->{value_per_sec}); } else { $msg = sprintf("%s: %.2f items", $self->{result_values}->{metric}, $self->{result_values}->{value}); @@ -126,14 +124,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "name:s@" => { name => 'name' }, - "node-id:s" => { name => 'node_id' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "name:s@" => { name => 'name' }, + "node-id:s" => { name => 'node_id' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -171,8 +168,6 @@ sub check_options { push @{$self->{aws_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/aws/elasticache/mode/network.pm b/cloud/aws/elasticache/mode/network.pm index 11244535c..dfd419388 100644 --- a/cloud/aws/elasticache/mode/network.pm +++ b/cloud/aws/elasticache/mode/network.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -53,7 +51,7 @@ sub custom_traffic_calc { sub custom_traffic_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'critical' }, { label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'warning' } ]); return $exit; @@ -66,8 +64,8 @@ sub custom_traffic_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'B/s' : 'B', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -77,7 +75,7 @@ sub custom_traffic_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); $msg = $self->{result_values}->{metric} . ": " . $value . $unit . "/s"; } else { @@ -116,14 +114,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "name:s@" => { name => 'name' }, - "node-id:s" => { name => 'node_id' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "name:s@" => { name => 'name' }, + "node-id:s" => { name => 'node_id' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -161,8 +158,6 @@ sub check_options { push @{$self->{aws_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/aws/elasticache/mode/replication.pm b/cloud/aws/elasticache/mode/replication.pm index 09da1f070..6044271f1 100644 --- a/cloud/aws/elasticache/mode/replication.pm +++ b/cloud/aws/elasticache/mode/replication.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -53,7 +51,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'critical' }, { label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'warning' } ]); return $exit; @@ -66,8 +64,8 @@ sub custom_metric_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'B/s' : 'B', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -77,7 +75,7 @@ sub custom_metric_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); $msg = $self->{result_values}->{metric} . ": " . $value . $unit . "/s"; } else { @@ -128,14 +126,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "name:s@" => { name => 'name' }, - "node-id:s" => { name => 'node_id' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "name:s@" => { name => 'name' }, + "node-id:s" => { name => 'node_id' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -173,8 +170,6 @@ sub check_options { push @{$self->{aws_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/aws/elasticache/mode/requestsmemcached.pm b/cloud/aws/elasticache/mode/requestsmemcached.pm index 19725adff..69c3f70dc 100644 --- a/cloud/aws/elasticache/mode/requestsmemcached.pm +++ b/cloud/aws/elasticache/mode/requestsmemcached.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -53,7 +51,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'critical' }, { label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'warning' } ]); return $exit; @@ -66,8 +64,8 @@ sub custom_metric_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'req/s' : 'req', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'req/s' : 'req', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -77,7 +75,7 @@ sub custom_metric_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { $msg = sprintf("%s: %.2f requests/s", $self->{result_values}->{metric}, $self->{result_values}->{value_per_sec}); } else { $msg = sprintf("%s: %.2f requests", $self->{result_values}->{metric}, $self->{result_values}->{value}); @@ -115,14 +113,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "name:s@" => { name => 'name' }, - "node-id:s" => { name => 'node_id' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "name:s@" => { name => 'name' }, + "node-id:s" => { name => 'node_id' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -161,8 +158,6 @@ sub check_options { push @{$self->{aws_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/aws/elasticache/mode/requestsredis.pm b/cloud/aws/elasticache/mode/requestsredis.pm index 7c2b2efa6..8cc576b86 100644 --- a/cloud/aws/elasticache/mode/requestsredis.pm +++ b/cloud/aws/elasticache/mode/requestsredis.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -53,7 +51,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'critical' }, { label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'warning' } ]); return $exit; @@ -66,8 +64,8 @@ sub custom_metric_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'req/s' : 'req', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'req/s' : 'req', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -77,7 +75,7 @@ sub custom_metric_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { $msg = sprintf("%s: %.2f requests/s", $self->{result_values}->{metric}, $self->{result_values}->{value_per_sec}); } else { $msg = sprintf("%s: %.2f requests", $self->{result_values}->{metric}, $self->{result_values}->{value}); @@ -114,14 +112,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "name:s@" => { name => 'name' }, - "node-id:s" => { name => 'node_id' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "name:s@" => { name => 'name' }, + "node-id:s" => { name => 'node_id' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -159,8 +156,6 @@ sub check_options { push @{$self->{aws_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/aws/rds/mode/volume.pm b/cloud/aws/rds/mode/volume.pm index c52dba4c5..ec49ac64c 100644 --- a/cloud/aws/rds/mode/volume.pm +++ b/cloud/aws/rds/mode/volume.pm @@ -29,9 +29,6 @@ my %map_type = ( "cluster" => "DbClusterIdentifier", ); - -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -53,7 +50,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'critical' }, { label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat}), exit_litteral => 'warning' } ]); return $exit; @@ -66,8 +63,8 @@ sub custom_ops_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => lc($self->{result_values}->{metric}) . "_" . lc($self->{result_values}->{stat}) . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'ops/s' : 'ops', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'ops/s' : 'ops', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{metric}) . "-" . lc($self->{result_values}->{stat})), ); @@ -78,7 +75,7 @@ sub custom_ops_output { my $msg =""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { $msg = sprintf("%s: %.2f ops/s", $self->{result_values}->{metric}, $self->{result_values}->{value_per_sec}); } else { $msg = sprintf("%s: %.2f ops", $self->{result_values}->{metric}, $self->{result_values}->{value}); @@ -129,14 +126,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "type:s" => { name => 'type', default => 'cluster' }, - "name:s@" => { name => 'name' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "type:s" => { name => 'type', default => 'cluster' }, + "name:s@" => { name => 'name' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -184,8 +180,6 @@ sub check_options { push @{$self->{aws_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/azure/compute/virtualmachine/mode/diskio.pm b/cloud/azure/compute/virtualmachine/mode/diskio.pm index 815d8a9d7..0a1f54b36 100644 --- a/cloud/azure/compute/virtualmachine/mode/diskio.pm +++ b/cloud/azure/compute/virtualmachine/mode/diskio.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -50,7 +48,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ]); return $exit; @@ -63,8 +61,8 @@ sub custom_usage_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'B/s' : 'B', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), min => 0 @@ -75,7 +73,7 @@ sub custom_usage_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit . "/s"; } else { @@ -161,14 +159,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "resource:s@" => { name => 'resource' }, - "resource-group:s" => { name => 'resource_group' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -204,8 +201,6 @@ sub check_options { push @{$self->{az_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/azure/compute/virtualmachine/mode/network.pm b/cloud/azure/compute/virtualmachine/mode/network.pm index 8b7a546aa..e5b4710f1 100644 --- a/cloud/azure/compute/virtualmachine/mode/network.pm +++ b/cloud/azure/compute/virtualmachine/mode/network.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -50,7 +48,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ]); return $exit; @@ -63,8 +61,8 @@ sub custom_traffic_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'B/s' : 'B', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), min => 0 @@ -75,7 +73,7 @@ sub custom_traffic_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit . "/s"; } else { @@ -120,14 +118,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "resource:s@" => { name => 'resource' }, - "resource-group:s" => { name => 'resource_group' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -162,8 +159,6 @@ sub check_options { push @{$self->{az_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/azure/custom/api.pm b/cloud/azure/custom/api.pm index 1de936339..c1710fd45 100644 --- a/cloud/azure/custom/api.pm +++ b/cloud/azure/custom/api.pm @@ -44,27 +44,25 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "subscription:s" => { name => 'subscription' }, - "tenant:s" => { name => 'tenant' }, - "client-id:s" => { name => 'client_id' }, - "client-secret:s" => { name => 'client_secret' }, - "login-endpoint:s" => { name => 'login_endpoint' }, - "management-endpoint:s" => { name => 'management_endpoint' }, - "timeframe:s" => { name => 'timeframe' }, - "interval:s" => { name => 'interval' }, - "aggregation:s@" => { name => 'aggregation' }, - "zeroed" => { name => 'zeroed' }, - "timeout:s" => { name => 'timeout' }, - "proxyurl:s" => { name => 'proxyurl' }, - }); + $options{options}->add_options(arguments => { + "subscription:s" => { name => 'subscription' }, + "tenant:s" => { name => 'tenant' }, + "client-id:s" => { name => 'client_id' }, + "client-secret:s" => { name => 'client_secret' }, + "login-endpoint:s" => { name => 'login_endpoint' }, + "management-endpoint:s" => { name => 'management_endpoint' }, + "timeframe:s" => { name => 'timeframe' }, + "interval:s" => { name => 'interval' }, + "aggregation:s@" => { name => 'aggregation' }, + "zeroed" => { name => 'zeroed' }, + "timeout:s" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); $self->{cache} = centreon::plugins::statefile->new(%options); return $self; @@ -105,8 +103,6 @@ sub check_options { } $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? $self->{option_results}->{proxyurl} : undef; - $self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef; $self->{timeframe} = (defined($self->{option_results}->{timeframe})) ? $self->{option_results}->{timeframe} : undef; $self->{step} = (defined($self->{option_results}->{step})) ? $self->{option_results}->{step} : undef; $self->{subscription} = (defined($self->{option_results}->{subscription})) ? $self->{option_results}->{subscription} : undef; @@ -147,8 +143,6 @@ sub build_options_for_httplib { my ($self, %options) = @_; $self->{option_results}->{timeout} = $self->{timeout}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; - $self->{option_results}->{ssl_opt} = $self->{ssl_opt}; $self->{option_results}->{warning_status} = ''; $self->{option_results}->{critical_status} = ''; $self->{option_results}->{unknown_status} = '%{http_code} < 200 or %{http_code} >= 500'; @@ -187,18 +181,23 @@ sub get_access_token { full_url => $self->{login_endpoint} . '/' . $self->{tenant} . '/oauth2/token', hostname => ''); + if (!defined($content) || $content eq '' || $self->{http}->get_header(name => 'content-length') == 0) { + $self->{output}->add_option_msg(short_msg => "Login endpoint API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + my $decoded; eval { $decoded = JSON::XS->new->utf8->decode($content); }; if ($@) { $self->{output}->output_add(long_msg => $content, debug => 1); - $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); $self->{output}->option_exit(); } if (defined($decoded->{error})) { $self->{output}->output_add(long_msg => "Error message : " . $decoded->{error_description}, debug => 1); - $self->{output}->add_option_msg(short_msg => "Login endpoint API return error code '" . $decoded->{error} . "' (add --debug option for detailed message)"); + $self->{output}->add_option_msg(short_msg => "Login endpoint API returns error code '" . $decoded->{error} . "' (add --debug option for detailed message)"); $self->{output}->option_exit(); } @@ -223,18 +222,28 @@ sub request_api { my $content = $self->{http}->request(%options); + if (!defined($content) || $content eq '' || $self->{http}->get_header(name => 'content-length') == 0) { + $self->{output}->add_option_msg(short_msg => "Management endpoint API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + my $decoded; eval { $decoded = JSON::XS->new->utf8->decode($content); }; if ($@) { $self->{output}->output_add(long_msg => $content, debug => 1); - $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); $self->{output}->option_exit(); } if (defined($decoded->{error})) { $self->{output}->output_add(long_msg => "Error message : " . $decoded->{error}->{message}, debug => 1); - $self->{output}->add_option_msg(short_msg => "Management endpoint API return error code '" . $decoded->{error}->{code} . "' (add --debug option for detailed message)"); + $self->{output}->add_option_msg(short_msg => "Management endpoint API returns error code '" . $decoded->{error}->{code} . "' (add --debug option for detailed message)"); + $self->{output}->option_exit(); + } + if (defined($decoded->{code})) { + $self->{output}->output_add(long_msg => "Message : " . $decoded->{message}, debug => 1); + $self->{output}->add_option_msg(short_msg => "Management endpoint API returns code '" . $decoded->{code} . "' (add --debug option for detailed message)"); $self->{output}->option_exit(); } @@ -246,15 +255,15 @@ sub convert_duration { my $duration; if ($options{time_string} =~ /^P.*S$/) { - centreon::plugins::misc::mymodule_load(module => 'DateTime::Format::Duration::ISO8601', - error_msg => "Cannot load module 'DateTime::Format::Duration::ISO8601'."); + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'DateTime::Format::Duration::ISO8601', + error_msg => "Cannot load module 'DateTime::Format::Duration::ISO8601'."); my $format = DateTime::Format::Duration::ISO8601->new; my $d = $format->parse_duration($options{time_string}); $duration = $d->minutes * 60 + $d->seconds; } elsif ($options{time_string} =~ /^(\d+):(\d+):(\d+)\.\d+$/) { - centreon::plugins::misc::mymodule_load(module => 'DateTime::Duration', - error_msg => "Cannot load module 'DateTime::Format::Duration'."); + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'DateTime::Duration', + error_msg => "Cannot load module 'DateTime::Format::Duration'."); my $d = DateTime::Duration->new(hours => $1, minutes => $2, seconds => $3); $duration = $d->minutes * 60 + $d->seconds; @@ -651,10 +660,6 @@ does not return value when not defined. Set timeout in seconds (Default: 10). -=item B<--proxyurl> - -Proxy URL if any - =back =head1 DESCRIPTION diff --git a/cloud/azure/custom/azcli.pm b/cloud/azure/custom/azcli.pm index 4bd4f70ff..6e5af2429 100644 --- a/cloud/azure/custom/azcli.pm +++ b/cloud/azure/custom/azcli.pm @@ -40,23 +40,22 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "subscription:s" => { name => 'subscription' }, - "tenant:s" => { name => 'tenant' }, - "client-id:s" => { name => 'client_id' }, - "client-secret:s" => { name => 'client_secret' }, - "timeframe:s" => { name => 'timeframe' }, - "interval:s" => { name => 'interval' }, - "aggregation:s@" => { name => 'aggregation' }, - "zeroed" => { name => 'zeroed' }, - "timeout:s" => { name => 'timeout', default => 50 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'az' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '' }, - "proxyurl:s" => { name => 'proxyurl' }, - }); + $options{options}->add_options(arguments => { + "subscription:s" => { name => 'subscription' }, + "tenant:s" => { name => 'tenant' }, + "client-id:s" => { name => 'client_id' }, + "client-secret:s" => { name => 'client_secret' }, + "timeframe:s" => { name => 'timeframe' }, + "interval:s" => { name => 'interval' }, + "aggregation:s@" => { name => 'aggregation' }, + "zeroed" => { name => 'zeroed' }, + "timeout:s" => { name => 'timeout', default => 50 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'az' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '' }, + "proxyurl:s" => { name => 'proxyurl' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'AZCLI OPTIONS', once => 1); @@ -129,7 +128,8 @@ sub execute { $raw_results = JSON::XS->new->utf8->decode($response); }; if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->output_add(long_msg => $response, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); $self->{output}->option_exit(); } @@ -141,15 +141,15 @@ sub convert_duration { my $duration; if ($options{time_string} =~ /^P.*S$/) { - centreon::plugins::misc::mymodule_load(module => 'DateTime::Format::Duration::ISO8601', - error_msg => "Cannot load module 'DateTime::Format::Duration::ISO8601'."); + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'DateTime::Format::Duration::ISO8601', + error_msg => "Cannot load module 'DateTime::Format::Duration::ISO8601'."); my $format = DateTime::Format::Duration::ISO8601->new; my $d = $format->parse_duration($options{time_string}); $duration = $d->minutes * 60 + $d->seconds; } elsif ($options{time_string} =~ /^(\d+):(\d+):(\d+)\.\d+$/) { - centreon::plugins::misc::mymodule_load(module => 'DateTime::Duration', - error_msg => "Cannot load module 'DateTime::Format::Duration'."); + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'DateTime::Duration', + error_msg => "Cannot load module 'DateTime::Format::Duration'."); my $d = DateTime::Duration->new(hours => $1, minutes => $2, seconds => $3); $duration = $d->minutes * 60 + $d->seconds; diff --git a/cloud/azure/management/monitor/mode/discovery.pm b/cloud/azure/management/monitor/mode/discovery.pm index c575f1531..7a2a0d5fa 100644 --- a/cloud/azure/management/monitor/mode/discovery.pm +++ b/cloud/azure/management/monitor/mode/discovery.pm @@ -32,13 +32,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "namespace:s" => { name => 'namespace' }, - "type:s" => { name => 'type' }, - "resource-group:s" => { name => 'resource_group' }, - "location:s" => { name => 'location' }, - }); + $options{options}->add_options(arguments => { + "namespace:s" => { name => 'namespace' }, + "type:s" => { name => 'type' }, + "resource-group:s" => { name => 'resource_group' }, + "location:s" => { name => 'location' }, + "prettify" => { name => 'prettify' }, + }); return $self; } @@ -88,7 +88,11 @@ sub run { my $encoded_data; eval { - $encoded_data = encode_json($disco_stats); + if (defined($self->{option_results}->{prettify})) { + $encoded_data = JSON::XS->new->utf8->pretty->encode($disco_stats); + } else { + $encoded_data = JSON::XS->new->utf8->encode($disco_stats); + } }; if ($@) { $encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}'; @@ -109,6 +113,26 @@ Resources discovery. =over 8 +=item B<--namespace> + +Specify resources namespace. + +=item B<--type> + +Specify resources type. + +=item B<--resource-group> + +Specify resources resource group. + +=item B<--location> + +Specify resources location. + +=item B<--prettify> + +Prettify JSON output. + =back =cut diff --git a/cloud/azure/management/monitor/mode/getmetrics.pm b/cloud/azure/management/monitor/mode/getmetrics.pm index ce199760e..2a77be569 100644 --- a/cloud/azure/management/monitor/mode/getmetrics.pm +++ b/cloud/azure/management/monitor/mode/getmetrics.pm @@ -149,7 +149,7 @@ sub check_options { sub manage_selection { my ($self, %options) = @_; - my ($results, $raw_results, $command_line) = $options{custom}->azure_get_metrics( + my ($results, $raw_results) = $options{custom}->azure_get_metrics( resource => $self->{az_resource}, resource_group => $self->{az_resource_group}, resource_type => $self->{az_resource_type}, @@ -175,7 +175,6 @@ sub manage_selection { } } - $self->{output}->output_add(long_msg => sprintf("Command line: %s", $command_line), debug => 1); $self->{output}->output_add(long_msg => sprintf("Raw data:\n%s", Dumper($raw_results)), debug => 1); } diff --git a/cloud/azure/network/expressroute/mode/traffic.pm b/cloud/azure/network/expressroute/mode/traffic.pm index 2127effa1..cc1120864 100644 --- a/cloud/azure/network/expressroute/mode/traffic.pm +++ b/cloud/azure/network/expressroute/mode/traffic.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_traffic_output { my ($self, %options) = @_; @@ -113,13 +111,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "resource:s@" => { name => 'resource' }, - "resource-group:s" => { name => 'resource_group' }, - "filter-metric:s" => { name => 'filter_metric' }, - }); - + $options{options}->add_options(arguments => { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "filter-metric:s" => { name => 'filter_metric' }, + }); + return $self; } @@ -154,8 +151,6 @@ sub check_options { push @{$self->{az_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/azure/network/networkinterface/mode/traffic.pm b/cloud/azure/network/networkinterface/mode/traffic.pm index 4b4c7abf5..5aefe45be 100644 --- a/cloud/azure/network/networkinterface/mode/traffic.pm +++ b/cloud/azure/network/networkinterface/mode/traffic.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -50,7 +48,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ]); return $exit; @@ -63,8 +61,8 @@ sub custom_traffic_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'B/s' : 'B', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), min => 0 @@ -75,7 +73,7 @@ sub custom_traffic_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit . "/s"; } else { @@ -92,8 +90,8 @@ sub custom_packets_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'packets/s' : 'packets', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'packets/s' : 'packets', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), min => 0 @@ -104,7 +102,7 @@ sub custom_packets_output { my ($self, %options) = @_; my $msg =""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { $msg = sprintf("%s: %.2f packets/s", $self->{result_values}->{metric_name}, $self->{result_values}->{value_per_sec}); } else { $msg = sprintf("%s: %.2f packets", $self->{result_values}->{metric_name}, $self->{result_values}->{value}); @@ -165,14 +163,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "resource:s@" => { name => 'resource' }, - "resource-group:s" => { name => 'resource_group' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -207,8 +204,6 @@ sub check_options { push @{$self->{az_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/azure/network/vpngateway/mode/sitetraffic.pm b/cloud/azure/network/vpngateway/mode/sitetraffic.pm index ab7f40ff4..eef5df12a 100644 --- a/cloud/azure/network/vpngateway/mode/sitetraffic.pm +++ b/cloud/azure/network/vpngateway/mode/sitetraffic.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -133,13 +131,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "resource:s@" => { name => 'resource' }, - "resource-group:s" => { name => 'resource_group' }, - "filter-metric:s" => { name => 'filter_metric' }, - }); - + $options{options}->add_options(arguments => { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "filter-metric:s" => { name => 'filter_metric' }, + }); + return $self; } @@ -174,8 +171,6 @@ sub check_options { push @{$self->{az_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/azure/network/vpngateway/mode/tunneltraffic.pm b/cloud/azure/network/vpngateway/mode/tunneltraffic.pm index 954a44861..fc76e74ef 100644 --- a/cloud/azure/network/vpngateway/mode/tunneltraffic.pm +++ b/cloud/azure/network/vpngateway/mode/tunneltraffic.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -51,7 +49,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ]); return $exit; @@ -64,8 +62,8 @@ sub custom_traffic_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'B/s' : 'B', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), min => 0 @@ -76,7 +74,7 @@ sub custom_traffic_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit . "/s"; } else { @@ -93,8 +91,8 @@ sub custom_packets_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'packets/s' : 'packets', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'packets/s' : 'packets', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), min => 0 @@ -105,7 +103,7 @@ sub custom_packets_output { my ($self, %options) = @_; my $msg =""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { $msg = sprintf("%s: %.2f packets/s", $self->{result_values}->{metric_name}, $self->{result_values}->{value_per_sec}); } else { $msg = sprintf("%s: %.2f packets", $self->{result_values}->{metric_name}, $self->{result_values}->{value}); @@ -166,14 +164,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "resource:s@" => { name => 'resource' }, - "resource-group:s" => { name => 'resource_group' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -209,8 +206,6 @@ sub check_options { push @{$self->{az_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/azure/storage/storageaccount/mode/transactionscount.pm b/cloud/azure/storage/storageaccount/mode/transactionscount.pm index 6967d4228..9c6f3b22d 100644 --- a/cloud/azure/storage/storageaccount/mode/transactionscount.pm +++ b/cloud/azure/storage/storageaccount/mode/transactionscount.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -55,7 +53,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ]); return $exit; @@ -68,8 +66,8 @@ sub custom_usage_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'transactions/s' : 'transactions', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'transactions/s' : 'transactions', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), min => 0 @@ -80,7 +78,7 @@ sub custom_usage_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { $msg = sprintf("%s: %.2f transactions/s", $self->{result_values}->{metric_name}, $self->{result_values}->{value_per_sec}); } else { $msg = sprintf("%s: %.2f transactions", $self->{result_values}->{metric_name}, $self->{result_values}->{value}); @@ -120,14 +118,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "resource:s@" => { name => 'resource' }, - "resource-group:s" => { name => 'resource_group' }, - "resource-namespace:s" => { name => 'resource_namespace' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-namespace:s" => { name => 'resource_namespace' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -160,8 +157,6 @@ sub check_options { foreach my $metric ('Transactions') { push @{$self->{az_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/azure/storage/storageaccount/mode/transactionslatency.pm b/cloud/azure/storage/storageaccount/mode/transactionslatency.pm index b502c312a..f43e289f6 100644 --- a/cloud/azure/storage/storageaccount/mode/transactionslatency.pm +++ b/cloud/azure/storage/storageaccount/mode/transactionslatency.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -68,14 +66,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "resource:s@" => { name => 'resource' }, - "resource-group:s" => { name => 'resource_group' }, - "resource-namespace:s" => { name => 'resource_namespace' }, - "filter-metric:s" => { name => 'filter_metric' }, - }); - + $options{options}->add_options(arguments => { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-namespace:s" => { name => 'resource_namespace' }, + "filter-metric:s" => { name => 'filter_metric' }, + }); + return $self; } @@ -111,8 +108,6 @@ sub check_options { push @{$self->{az_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/azure/storage/storageaccount/mode/transactionsthroughput.pm b/cloud/azure/storage/storageaccount/mode/transactionsthroughput.pm index 7b30d52d1..5738d5fa9 100644 --- a/cloud/azure/storage/storageaccount/mode/transactionsthroughput.pm +++ b/cloud/azure/storage/storageaccount/mode/transactionsthroughput.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub prefix_metric_output { my ($self, %options) = @_; @@ -55,7 +53,7 @@ sub custom_metric_calc { sub custom_metric_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + my $exit = $self->{perfdata}->threshold_check(value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ]); return $exit; @@ -68,8 +66,8 @@ sub custom_usage_perfdata { $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); $self->{output}->perfdata_add(label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, - unit => defined($instance_mode->{option_results}->{per_sec}) ? 'B/s' : 'B', - value => sprintf("%.2f", defined($instance_mode->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), min => 0 @@ -80,7 +78,7 @@ sub custom_usage_output { my ($self, %options) = @_; my $msg = ""; - if (defined($instance_mode->{option_results}->{per_sec})) { + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); $msg = $self->{result_values}->{metric_name} . ": " . $value . ' ' . $unit . "/s"; } else { @@ -122,15 +120,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "resource:s@" => { name => 'resource' }, - "resource-group:s" => { name => 'resource_group' }, - "resource-namespace:s" => { name => 'resource_namespace' }, - "filter-metric:s" => { name => 'filter_metric' }, - "per-sec" => { name => 'per_sec' }, - }); - + $options{options}->add_options(arguments => { + "resource:s@" => { name => 'resource' }, + "resource-group:s" => { name => 'resource_group' }, + "resource-namespace:s" => { name => 'resource_namespace' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + return $self; } @@ -166,8 +163,6 @@ sub check_options { push @{$self->{az_metrics}}, $metric; } - - $instance_mode = $self; } sub manage_selection { diff --git a/cloud/cadvisor/restapi/custom/api.pm b/cloud/cadvisor/restapi/custom/api.pm index dd905656b..7d5c37a21 100644 --- a/cloud/cadvisor/restapi/custom/api.pm +++ b/cloud/cadvisor/restapi/custom/api.pm @@ -42,29 +42,27 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s@" => { name => 'hostname' }, - "port:s" => { name => 'port', default => 8080 }, - "proto:s" => { name => 'proto', default => 'http' }, - "path:s" => { name => 'path', default => '/containers/docker/' }, - "credentials" => { name => 'credentials' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "proxypac:s" => { name => 'proxypac' }, - "timeout:s" => { name => 'timeout', default => 10 }, - "ssl:s" => { name => 'ssl' }, - "cert-file:s" => { name => 'cert_file' }, - "key-file:s" => { name => 'key_file' }, - "cacert-file:s" => { name => 'cacert_file' }, - "cert-pwd:s" => { name => 'cert_pwd' }, - "cert-pkcs12" => { name => 'cert_pkcs12' }, - "api-version:s" => { name => 'api_version', default => 'v1.3' }, - }); + $options{options}->add_options(arguments => { + "hostname:s@" => { name => 'hostname' }, + "port:s" => { name => 'port', default => 8080 }, + "proto:s" => { name => 'proto', default => 'http' }, + "path:s" => { name => 'path', default => '/containers/docker/' }, + "credentials" => { name => 'credentials' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout', default => 10 }, + "cert-file:s" => { name => 'cert_file' }, + "key-file:s" => { name => 'key_file' }, + "cacert-file:s" => { name => 'cacert_file' }, + "cert-pwd:s" => { name => 'cert_pwd' }, + "cert-pkcs12" => { name => 'cert_pkcs12' }, + "api-version:s" => { name => 'api_version', default => 'v1.3' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + $self->{http} = centreon::plugins::http->new(%options); + $self->{output} = $options{output}; $self->{mode} = $options{mode}; @@ -105,14 +103,15 @@ sub check_options { $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); $self->{output}->option_exit(); } - $self->{http} = {}; + + $self->{node_names} = []; foreach my $node_name (@{$self->{hostname}}) { if ($node_name ne '') { - $self->{http}->{$node_name} = centreon::plugins::http->new(output => $self->{output}); - $self->{option_results}->{hostname} = $node_name; - $self->{http}->{$node_name}->set_options(%{$self->{option_results}}); + push @{$self->{node_names}}, $node_name; } } + + $self->{http}->set_options(%{$self->{option_results}}); return 0; } @@ -132,7 +131,8 @@ sub get_port { sub internal_api_list_nodes { my ($self, %options) = @_; - my $response = $self->{http}->{$options{node_name}}->request( + my $response = $self->{http}->request( + hostname => $options{node_name}, url_path => '/api/' . $self->{option_results}->{api_version} . $self->{option_results}->{path}, unknown_status => '', critical_status => '', warning_status => ''); my $nodes; @@ -153,7 +153,8 @@ sub internal_api_list_nodes { sub internal_api_info { my ($self, %options) = @_; - my $response = $self->{http}->{$options{node_name}}->request( + my $response = $self->{http}->request( + hostname => $options{node_name}, url_path => '/api/' . $self->{option_results}->{api_version} . '/machine/', unknown_status => '', critical_status => '', warning_status => ''); my $nodes; @@ -172,7 +173,8 @@ sub internal_api_info { sub internal_api_list_containers { my ($self, %options) = @_; - my $response = $self->{http}->{$options{node_name}}->request( + my $response = $self->{http}->request( + hostname => $options{node_name}, url_path => '/api/' . $self->{option_results}->{api_version} . $self->{option_results}->{path}, unknown_status => '', critical_status => '', warning_status => ''); my $containers = []; @@ -187,7 +189,8 @@ sub internal_api_list_containers { } foreach my $container (@{$containers_ids->{subcontainers}}) { my $json_response = JSON::XS->new->utf8->decode( - $self->{http}->{$options{node_name}}->request( + $self->{http}->request( + hostname => $options{node_name}, url_path => '/api/' . $self->{option_results}->{api_version} . '/containers/' . $container->{name} ) ); @@ -204,7 +207,8 @@ sub internal_api_list_containers { sub internal_api_get_machine_stats { my ($self, %options) = @_; - my $response = $self->{http}->{$options{node_name}}->request( + my $response = $self->{http}->request( + hostname => $options{node_name}, url_path => '/api/' . $self->{option_results}->{api_version} . '/machine', unknown_status => '', critical_status => '', warning_status => ''); my $machine_stats; @@ -225,7 +229,8 @@ sub internal_api_get_machine_stats { sub internal_api_get_container_stats { my ($self, %options) = @_; - my $response = $self->{http}->{$options{node_name}}->request( + my $response = $self->{http}->request( + hostname => $options{node_name}, url_path => '/api/' . $self->{option_results}->{api_version} . $self->{option_results}->{path} . '/' . $options{container_id}, unknown_status => '', critical_status => '', warning_status => ''); my $container_stats; @@ -248,7 +253,7 @@ sub api_list_containers { my ($self, %options) = @_; my $containers = {}; - foreach my $node_name (keys %{$self->{http}}) { + foreach my $node_name (@{$self->{node_names}}) { my $list_containers = $self->internal_api_list_containers(node_name => $node_name); foreach my $container (@$list_containers) { $containers->{$container->{id}} = { @@ -265,7 +270,7 @@ sub api_get_machine_stats { my ($self, %options) = @_; my $machine_stats = {}; - foreach my $node_name (keys %{$self->{http}}) { + foreach my $node_name (@{$self->{node_names}}) { $machine_stats->{$node_name} = $self->internal_api_get_machine_stats(node_name => $node_name); } return $machine_stats; @@ -275,7 +280,7 @@ sub api_list_nodes { my ($self, %options) = @_; my $nodes = {}; - foreach my $node_name (keys %{$self->{http}}) { + foreach my $node_name (@{$self->{node_names}}) { my $info_node = $self->internal_api_info(node_name => $node_name); my $list_nodes = $self->internal_api_list_nodes(node_name => $node_name); $nodes->{$node_name} = { nodes => [], @@ -367,22 +372,10 @@ Specify username for basic authentification (Mandatory if --credentials is speci Specify password for basic authentification (Mandatory if --credentials is specidied) -=item B<--proxyurl> - -Proxy URL - -=item B<--proxypac> - -Proxy pac file (can be an url or local file) - =item B<--timeout> Threshold for HTTP timeout (Default: 10) -=item B<--ssl> - -Specify SSL version (example : 'sslv3', 'tlsv1'...) - =item B<--cert-file> Specify certificate to send to the webserver diff --git a/cloud/cadvisor/restapi/mode/containerusage.pm b/cloud/cadvisor/restapi/mode/containerusage.pm index 8882cc8d2..b6dd83bbe 100644 --- a/cloud/cadvisor/restapi/mode/containerusage.pm +++ b/cloud/cadvisor/restapi/mode/containerusage.pm @@ -27,8 +27,6 @@ use warnings; use Digest::MD5 qw(md5_hex); use DateTime; -my $instance_mode; - sub custom_memory_output { my ($self, %options) = @_; my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{memory_total_absolute}); @@ -136,15 +134,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "container-id:s" => { name => 'container_id' }, - "container-name:s" => { name => 'container_name' }, - "filter-name:s" => { name => 'filter_name' }, - "use-name" => { name => 'use_name' }, - "warning-container-status:s" => { name => 'warning_container_status', default => '' }, - "critical-container-status:s" => { name => 'critical_container_status', default => '' }, - }); + $options{options}->add_options(arguments => { + "container-id:s" => { name => 'container_id' }, + "container-name:s" => { name => 'container_name' }, + "filter-name:s" => { name => 'filter_name' }, + "use-name" => { name => 'use_name' }, + "warning-container-status:s" => { name => 'warning_container_status', default => '' }, + "critical-container-status:s" => { name => 'critical_container_status', default => '' }, + }); return $self; } @@ -153,8 +150,7 @@ sub check_options { my ($self, %options) = @_; $self->SUPER::check_options(%options); - $instance_mode = $self; - $self->change_macros(); + $self->change_macros(macros => ['warning_container_status', 'critical_container_status']); } sub prefix_containers_output { @@ -162,16 +158,6 @@ sub prefix_containers_output { return "Container '" . $options{instance_value}->{display} . "' "; } -sub change_macros { - my ($self, %options) = @_; - - foreach (('warning_container_status', 'critical_container_status')) { - if (defined($self->{option_results}->{$_})) { - $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; - } - } -} - sub manage_selection { my ($self, %options) = @_; diff --git a/cloud/cadvisor/restapi/mode/traffic.pm b/cloud/cadvisor/restapi/mode/traffic.pm index f05b3c9c4..3682cfd35 100644 --- a/cloud/cadvisor/restapi/mode/traffic.pm +++ b/cloud/cadvisor/restapi/mode/traffic.pm @@ -27,8 +27,6 @@ use warnings; use Digest::MD5 qw(md5_hex); use DateTime; -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -66,13 +64,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "container-id:s" => { name => 'container_id' }, - "container-name:s" => { name => 'container_name' }, - "filter-name:s" => { name => 'filter_name' }, - "use-name" => { name => 'use_name' }, - }); + $options{options}->add_options(arguments => { + "container-id:s" => { name => 'container_id' }, + "container-name:s" => { name => 'container_name' }, + "filter-name:s" => { name => 'filter_name' }, + "use-name" => { name => 'use_name' }, + }); return $self; } diff --git a/cloud/cloudfoundry/restapi/custom/api.pm b/cloud/cloudfoundry/restapi/custom/api.pm index b8d48103e..4602c4e83 100644 --- a/cloud/cloudfoundry/restapi/custom/api.pm +++ b/cloud/cloudfoundry/restapi/custom/api.pm @@ -41,26 +41,23 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port' }, - "proto:s" => { name => 'proto' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "api-path:s" => { name => 'api_path' }, - "api-username:s" => { name => 'api_username' }, - "api-password:s" => { name => 'api_password' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + "api-path:s" => { name => 'api_path' }, + "api-username:s" => { name => 'api_username' }, + "api-password:s" => { name => 'api_password' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; @@ -97,8 +94,6 @@ sub check_options { $self->{username} = (defined($self->{option_results}->{username})) ? $self->{option_results}->{username} : 'cf'; $self->{password} = (defined($self->{option_results}->{password})) ? $self->{option_results}->{password} : ''; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? $self->{option_results}->{proxyurl} : undef; - $self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef; $self->{api_path} = (defined($self->{option_results}->{api_path})) ? $self->{option_results}->{api_path} : '/v2'; $self->{api_username} = (defined($self->{option_results}->{api_username})) ? $self->{option_results}->{api_username} : undef; $self->{api_password} = (defined($self->{option_results}->{api_password})) ? $self->{option_results}->{api_password} : undef; @@ -128,8 +123,6 @@ sub build_options_for_httplib { $self->{option_results}->{username} = $self->{username}; $self->{option_results}->{password} = $self->{password}; $self->{option_results}->{timeout} = $self->{timeout}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; - $self->{option_results}->{ssl_opt} = $self->{ssl_opt}; $self->{option_results}->{warning_status} = ''; $self->{option_results}->{critical_status} = ''; } @@ -151,7 +144,6 @@ sub request_api { my $content = $self->{http}->request(method => $options{method}, url_path => $self->{api_path} . $options{url_path}, query_form_post => $options{query_form_post}, critical_status => '', warning_status => '', unknown_status => ''); - my $response = $self->{http}->get_response(); my $decoded; eval { $decoded = decode_json($content); @@ -161,7 +153,7 @@ sub request_api { $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); $self->{output}->option_exit(); } - if ($response->code() != 200) { + if ($self->{http}->get_code() != 200) { $self->{output}->add_option_msg(short_msg => "Error code: " . $decoded->{error_code} . ". Description: " . $decoded->{description}); $self->{output}->option_exit(); } @@ -319,19 +311,10 @@ Authorization endpoint username (Default: 'cf') Authorization endpoint password (Default: '') -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (Examples: --ssl-opt="SSL_version => TLSv1" ---ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/cloud/cloudfoundry/restapi/mode/instancesstate.pm b/cloud/cloudfoundry/restapi/mode/instancesstate.pm index efad7fa68..af61e9073 100644 --- a/cloud/cloudfoundry/restapi/mode/instancesstate.pm +++ b/cloud/cloudfoundry/restapi/mode/instancesstate.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_app_state_threshold { my ($self, %options) = @_; my $status = 'ok'; @@ -36,11 +34,11 @@ sub custom_app_state_threshold { local $SIG{__WARN__} = sub { $message = $_[0]; }; local $SIG{__DIE__} = sub { $message = $_[0]; }; - if (defined($instance_mode->{option_results}->{critical_app_state}) && $instance_mode->{option_results}->{critical_app_state} ne '' && - eval "$instance_mode->{option_results}->{critical_app_state}") { + if (defined($self->{instance_mode}->{option_results}->{critical_app_state}) && $self->{instance_mode}->{option_results}->{critical_app_state} ne '' && + eval "$self->{instance_mode}->{option_results}->{critical_app_state}") { $status = 'critical'; - } elsif (defined($instance_mode->{option_results}->{warning_app_state}) && $instance_mode->{option_results}->{warning_app_state} ne '' && - eval "$instance_mode->{option_results}->{warning_app_state}") { + } elsif (defined($self->{instance_mode}->{option_results}->{warning_app_state}) && $self->{instance_mode}->{option_results}->{warning_app_state} ne '' && + eval "$self->{instance_mode}->{option_results}->{warning_app_state}") { $status = 'warning'; } }; @@ -77,11 +75,11 @@ sub custom_inst_state_threshold { local $SIG{__WARN__} = sub { $message = $_[0]; }; local $SIG{__DIE__} = sub { $message = $_[0]; }; - if (defined($instance_mode->{option_results}->{critical_instance_state}) && $instance_mode->{option_results}->{critical_instance_state} ne '' && - eval "$instance_mode->{option_results}->{critical_instance_state}") { + if (defined($self->{instance_mode}->{option_results}->{critical_instance_state}) && $self->{instance_mode}->{option_results}->{critical_instance_state} ne '' && + eval "$self->{instance_mode}->{option_results}->{critical_instance_state}") { $status = 'critical'; - } elsif (defined($instance_mode->{option_results}->{warning_instance_state}) && $instance_mode->{option_results}->{warning_instance_state} ne '' && - eval "$instance_mode->{option_results}->{warning_instance_state}") { + } elsif (defined($self->{instance_mode}->{option_results}->{warning_instance_state}) && $self->{instance_mode}->{option_results}->{warning_instance_state} ne '' && + eval "$self->{instance_mode}->{option_results}->{warning_instance_state}") { $status = 'warning'; } }; @@ -182,15 +180,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "app-guid:s" => { name => 'app_guid' }, - "warning-app-state:s" => { name => 'warning_app_state' }, - "critical-app-state:s" => { name => 'critical_app_state', default => '%{state} !~ /STARTED/i' }, - "warning-instance-state:s" => { name => 'warning_instance_state' }, - "critical-instance-state:s" => { name => 'critical_instance_state', default => '%{state} !~ /RUNNING/i' }, - }); - + $options{options}->add_options(arguments => { + "app-guid:s" => { name => 'app_guid' }, + "warning-app-state:s" => { name => 'warning_app_state' }, + "critical-app-state:s" => { name => 'critical_app_state', default => '%{state} !~ /STARTED/i' }, + "warning-instance-state:s" => { name => 'warning_instance_state' }, + "critical-instance-state:s" => { name => 'critical_instance_state', default => '%{state} !~ /RUNNING/i' }, + }); + return $self; } @@ -203,7 +200,6 @@ sub check_options { $self->{output}->option_exit(); } - $instance_mode = $self; $self->change_macros(macros => ['warning_app_state', 'critical_app_state', 'warning_instance_state', 'critical_instance_state']); } diff --git a/cloud/docker/restapi/custom/api.pm b/cloud/docker/restapi/custom/api.pm index 9f802a3a5..b277b94bd 100644 --- a/cloud/docker/restapi/custom/api.pm +++ b/cloud/docker/restapi/custom/api.pm @@ -42,33 +42,30 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s@" => { name => 'hostname' }, - "port:s" => { name => 'port', default => 8080 }, - "proto:s" => { name => 'proto' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "proxypac:s" => { name => 'proxypac' }, - "timeout:s" => { name => 'timeout', default => 10 }, - "ssl:s" => { name => 'ssl' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "cert-file:s" => { name => 'cert_file' }, - "key-file:s" => { name => 'key_file' }, - "cacert-file:s" => { name => 'cacert_file' }, - "cert-pwd:s" => { name => 'cert_pwd' }, - "cert-pkcs12" => { name => 'cert_pkcs12' }, - "api-display" => { name => 'api_display' }, - "api-write-file:s" => { name => 'api_write_file' }, - "api-read-file:s" => { name => 'api_read_file' }, - "reload-cache-time:s" => { name => 'reload_cache_time', default => 300 }, - }); + $options{options}->add_options(arguments => { + "hostname:s@" => { name => 'hostname' }, + "port:s" => { name => 'port', default => 8080 }, + "proto:s" => { name => 'proto' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout', default => 10 }, + "cert-file:s" => { name => 'cert_file' }, + "key-file:s" => { name => 'key_file' }, + "cacert-file:s" => { name => 'cacert_file' }, + "cert-pwd:s" => { name => 'cert_pwd' }, + "cert-pkcs12" => { name => 'cert_pkcs12' }, + "api-display" => { name => 'api_display' }, + "api-write-file:s" => { name => 'api_write_file' }, + "api-read-file:s" => { name => 'api_read_file' }, + "reload-cache-time:s" => { name => 'reload_cache_time', default => 300 }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + $self->{http} = centreon::plugins::http->new(%options); + $self->{output} = $options{output}; $self->{mode} = $options{mode}; @@ -111,14 +108,15 @@ sub check_options { $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); $self->{output}->option_exit(); } - $self->{http} = {}; + + $self->{node_names} = []; foreach my $node_name (@{$self->{hostname}}) { if ($node_name ne '') { - $self->{http}->{$node_name} = centreon::plugins::http->new(output => $self->{output}); - $self->{option_results}->{hostname} = $node_name; - $self->{http}->{$node_name}->set_options(%{$self->{option_results}}); + push @{$self->{node_names}}, $node_name; } } + + $self->{http}->set_options(%{$self->{option_results}}); return 0; } @@ -195,7 +193,7 @@ sub cache_containers { $containers = {}; my $datas = { last_timestamp => time(), containers => $containers }; - foreach my $node_name (keys %{$self->{http}}) { + foreach my $node_name (@{$self->{node_names}}) { my $list_containers = $self->internal_api_list_containers(node_name => $node_name); foreach my $container (@$list_containers) { $containers->{$container->{Id}} = { @@ -214,7 +212,8 @@ sub cache_containers { sub internal_api_list_nodes { my ($self, %options) = @_; - my $response = $self->{http}->{$options{node_name}}->request( + my $response = $self->{http}->request( + hostname => $options{node_name}, url_path => '/nodes', unknown_status => '', critical_status => '', warning_status => ''); my $nodes; @@ -235,7 +234,8 @@ sub internal_api_list_nodes { sub internal_api_info { my ($self, %options) = @_; - my $response = $self->{http}->{$options{node_name}}->request( + my $response = $self->{http}->request( + hostname => $options{node_name}, url_path => '/info', unknown_status => '', critical_status => '', warning_status => ''); my $nodes; @@ -254,7 +254,8 @@ sub internal_api_info { sub internal_api_list_containers { my ($self, %options) = @_; - my $response = $self->{http}->{$options{node_name}}->request( + my $response = $self->{http}->request( + hostname => $options{node_name}, url_path => '/containers/json?all=true', unknown_status => '', critical_status => '', warning_status => ''); my $containers; @@ -273,7 +274,8 @@ sub internal_api_list_containers { sub internal_api_get_container_stats { my ($self, %options) = @_; - my $response = $self->{http}->{$options{node_name}}->request( + my $response = $self->{http}->request( + hostname => $options{node_name}, url_path => '/containers/' . $options{container_id} . '/stats?stream=false', unknown_status => '', critical_status => '', warning_status => ''); my $container_stats; @@ -293,7 +295,7 @@ sub api_list_containers { my ($self, %options) = @_; my $containers = {}; - foreach my $node_name (keys %{$self->{http}}) { + foreach my $node_name (@{$self->{node_names}}) { my $list_containers = $self->internal_api_list_containers(node_name => $node_name); foreach my $container (@$list_containers) { $containers->{$container->{Id}} = { @@ -311,7 +313,7 @@ sub api_list_nodes { my ($self, %options) = @_; my $nodes = {}; - foreach my $node_name (keys %{$self->{http}}) { + foreach my $node_name (@{$self->{node_names}}) { my $info_node = $self->internal_api_info(node_name => $node_name); my $list_nodes = $self->internal_api_list_nodes(node_name => $node_name); $nodes->{$node_name} = { nodes => [], @@ -410,22 +412,10 @@ Specify this option if you access server-status page over hidden basic authentic (Use with --credentials) -=item B<--proxyurl> - -Proxy URL - -=item B<--proxypac> - -Proxy pac file (can be an url or local file) - =item B<--timeout> Threshold for HTTP timeout (Default: 10) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--cert-file> Specify certificate to send to the webserver diff --git a/cloud/google/gcp/compute/computeengine/mode/cpu.pm b/cloud/google/gcp/compute/computeengine/mode/cpu.pm new file mode 100644 index 000000000..ddec5ae43 --- /dev/null +++ b/cloud/google/gcp/compute/computeengine/mode/cpu.pm @@ -0,0 +1,242 @@ +# +# Copyright 2019 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 cloud::google::gcp::compute::computeengine::mode::cpu; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use cloud::google::gcp::custom::misc; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Instance '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub custom_metric_calc { + my ($self, %options) = @_; + + $self->{result_values}->{stat} = $options{new_datas}->{$self->{instance} . '_stat'}; + $self->{result_values}->{metric} = $options{extra_options}->{metric}; + $self->{result_values}->{metric_name} = $options{extra_options}->{metric_name}; + $self->{result_values}->{metric_label} = $options{extra_options}->{metric_label}; + $self->{result_values}->{metric_perf} = $options{extra_options}->{metric_perf}; + $self->{result_values}->{value} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{metric} . '_' . $self->{result_values}->{stat}} * 100; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_metric_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check( + value => $self->{result_values}->{value}, + threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ] + ); + return $exit; +} + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + + $self->{output}->perfdata_add( + label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, + unit => '%', + value => sprintf("%.2f", $self->{result_values}->{value}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + min => 0, max => 100 + ); +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my $msg = sprintf("%s: %.2f%%", $self->{result_values}->{metric_name}, $self->{result_values}->{value}); + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', + message_multiple => "All CPU metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('minimum', 'maximum', 'average', 'total') { + foreach my $metric ('instance/cpu/utilization') { + my $metric_label = cloud::google::gcp::custom::misc::format_metric_label(metric => $metric, remove => 'instance/'); + my $metric_perf = cloud::google::gcp::custom::misc::format_metric_perf(metric => $metric, remove => 'instance/'); + my $metric_name = cloud::google::gcp::custom::misc::format_metric_name(metric => $metric, remove => 'instance/'); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + closure_custom_calc => $self->can('custom_metric_calc'), + closure_custom_calc_extra_options => { metric_perf => $metric_perf, + metric_label => $metric_label, metric_name => $metric_name, metric => $metric }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_metric_threshold'), + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + foreach my $metric ('instance/cpu/reserved_cores') { + my $metric_label = cloud::google::gcp::custom::misc::format_metric_label(metric => $metric, remove => 'instance/'); + my $metric_perf = cloud::google::gcp::custom::misc::format_metric_perf(metric => $metric, remove => 'instance/'); + my $metric_name = cloud::google::gcp::custom::misc::format_metric_name(metric => $metric, remove => 'instance/'); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric . '_' . $aggregation }, { name => 'display' }, { name => 'stat' } ], + output_template => $metric_name . ': %.2f', + perfdatas => [ + { label => $metric_perf . '_' . $aggregation, value => $metric . '_' . $aggregation . '_absolute', + template => '%.2f', unit => '', label_extra_instance => 1, instance_use => 'display_absolute', + min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +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 => { + "instance:s@" => { name => 'instance' }, + "filter-metric:s" => { name => 'filter_metric' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{instance})) { + $self->{output}->add_option_msg(short_msg => "Need to specify --instance ."); + $self->{output}->option_exit(); + } + + $self->{gcp_instance} = $self->{option_results}->{instance}; + $self->{gcp_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{gcp_aggregations} = ['average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{gcp_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{gcp_aggregations}}, $stat; + } + } + } + + foreach my $metric ('instance/cpu/utilization', 'instance/cpu/reserved_cores') { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + + push @{$self->{gcp_metrics}}, $metric; + } + + $self->{gcp_api} = "compute.googleapis.com"; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $metric_results; + foreach my $instance (@{$self->{gcp_instance}}) { + foreach my $metric (@{$self->{gcp_metrics}}) { + ($metric_results, undef) = $options{custom}->gcp_get_metrics( + instance => $instance, + metric => $metric, + api => $self->{gcp_api}, + aggregations => $self->{gcp_aggregations}, + timeframe => $self->{gcp_timeframe}, + ); + + foreach my $aggregation (@{$self->{gcp_aggregations}}) { + next if (!defined($metric_results->{$metric}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$instance . "_" . lc($aggregation)}->{display} = $metric_results->{labels}->{instance_name}; + $self->{metric}->{$instance . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$instance . "_" . lc($aggregation)}->{$metric . "_" . lc($aggregation)} = defined($metric_results->{$metric}->{lc($aggregation)}) ? $metric_results->{$metric}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check Compute Engine instances CPU metrics. + +Example: + +perl centreon_plugins.pl --plugin=cloud::google::gcp::compute::computeengine::plugin --custommode=api --mode=cpu +--instance=mycomputeinstance --filter-metric='utilization' --aggregation='average' +--critical-cpu-utilization-average='10' --verbose + +Default aggregation: 'average' / All aggregations are valid. + +=over 8 + +=item B<--instance> + +Set instance name (Required). + +=item B<--filter-metric> + +Filter metrics (Can be: 'instance/cpu/utilization', +'instance/cpu/reserved_cores') (Can be a regexp). + +=item B<--warning-$metric$-$aggregation$> + +Thresholds warning ($metric$ can be: 'cpu-utilization', +'cpu-reserved-cores', $aggregation$ can be: 'minimum', +'maximum', 'average', 'total'). + +=item B<--critical-$metric$-$aggregation$> + +Thresholds critical ($metric$ can be: 'cpu-utilization', +'cpu-reserved-cores', $aggregation$ can be: 'minimum', +'maximum', 'average', 'total'). + +=back + +=cut diff --git a/cloud/google/gcp/compute/computeengine/mode/diskio.pm b/cloud/google/gcp/compute/computeengine/mode/diskio.pm new file mode 100644 index 000000000..d583b3175 --- /dev/null +++ b/cloud/google/gcp/compute/computeengine/mode/diskio.pm @@ -0,0 +1,297 @@ +# +# Copyright 2019 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 cloud::google::gcp::compute::computeengine::mode::diskio; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use cloud::google::gcp::custom::misc; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Instance '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub custom_metric_calc { + my ($self, %options) = @_; + + $self->{result_values}->{stat} = $options{new_datas}->{$self->{instance} . '_stat'}; + $self->{result_values}->{metric_perf} = $options{extra_options}->{metric_perf}; + $self->{result_values}->{metric_label} = $options{extra_options}->{metric_label}; + $self->{result_values}->{metric_name} = $options{extra_options}->{metric_name}; + $self->{result_values}->{metric} = $options{extra_options}->{metric}; + $self->{result_values}->{timeframe} = $options{new_datas}->{$self->{instance} . '_timeframe'}; + $self->{result_values}->{value} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{metric} . '_' . $self->{result_values}->{stat}}; + $self->{result_values}->{value_per_sec} = $self->{result_values}->{value} / $self->{result_values}->{timeframe}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check( + value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ] + ); + return $exit; +} + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + + $self->{output}->perfdata_add( + label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%d", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + min => 0 + ); +} + +sub custom_usage_output { + my ($self, %options) = @_; + my $msg = ""; + + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { + my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); + $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit . "/s"; + } else { + my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value}); + $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit; + } + return $msg; +} + +sub custom_ops_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check( + value => $self->{result_values}->{value}, + threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ] + ); + return $exit; +} + +sub custom_ops_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + + $self->{output}->perfdata_add( + label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, + unit => 'ops/s', + value => sprintf("%.2f", $self->{result_values}->{value}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + min => 0 + ); +} + +sub custom_ops_output { + my ($self, %options) = @_; + + my $msg = sprintf("%s: %.2f ops/s", $self->{result_values}->{metric_name}, $self->{result_values}->{value}); + + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', message_multiple => "All disk metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('minimum', 'maximum', 'average', 'total') { + foreach my $metric ('instance/disk/read_bytes_count', 'instance/disk/throttled_read_bytes_count', + 'instance/disk/write_bytes_count', 'instance/disk/throttled_write_bytes_count') { + my $metric_label = cloud::google::gcp::custom::misc::format_metric_label(metric => $metric, remove => 'instance/'); + my $metric_perf = cloud::google::gcp::custom::misc::format_metric_perf(metric => $metric, remove => 'instance/'); + my $metric_name = cloud::google::gcp::custom::misc::format_metric_name(metric => $metric, remove => 'instance/'); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric . '_' . $aggregation }, { name => 'display' }, + { name => 'stat' }, { name => 'timeframe' } ], + closure_custom_calc => $self->can('custom_metric_calc'), + closure_custom_calc_extra_options => { metric_perf => $metric_perf, + metric_label => $metric_label, metric_name => $metric_name, metric => $metric }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + foreach my $metric ('instance/disk/read_ops_count', 'instance/disk/write_ops_count') { + my $metric_label = cloud::google::gcp::custom::misc::format_metric_label(metric => $metric, remove => 'instance/'); + my $metric_perf = cloud::google::gcp::custom::misc::format_metric_perf(metric => $metric, remove => 'instance/'); + my $metric_name = cloud::google::gcp::custom::misc::format_metric_name(metric => $metric, remove => 'instance/'); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric . '_' . $aggregation }, { name => 'display' }, + { name => 'stat' }, { name => 'timeframe' } ], + closure_custom_calc => $self->can('custom_metric_calc'), + closure_custom_calc_extra_options => { metric_perf => $metric_perf, + metric_label => $metric_label, metric_name => $metric_name, metric => $metric }, + closure_custom_output => $self->can('custom_ops_output'), + closure_custom_perfdata => $self->can('custom_ops_perfdata'), + closure_custom_threshold_check => $self->can('custom_ops_threshold'), + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +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 => { + "instance:s@" => { name => 'instance' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{instance})) { + $self->{output}->add_option_msg(short_msg => "Need to specify --instance ."); + $self->{output}->option_exit(); + } + + $self->{gcp_instance} = $self->{option_results}->{instance}; + $self->{gcp_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{gcp_aggregations} = ['average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{gcp_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{gcp_aggregations}}, $stat; + } + } + } + + foreach my $metric ('instance/disk/read_bytes_count', 'instance/disk/throttled_read_bytes_count', + 'instance/disk/write_bytes_count', 'instance/disk/throttled_write_bytes_count', + 'instance/disk/read_ops_count', 'instance/disk/write_ops_count') { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + + push @{$self->{gcp_metrics}}, $metric; + } + + $self->{gcp_api} = "compute.googleapis.com"; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $metric_results; + foreach my $instance (@{$self->{gcp_instance}}) { + foreach my $metric (@{$self->{gcp_metrics}}) { + ($metric_results, undef) = $options{custom}->gcp_get_metrics( + instance => $instance, + metric => $metric, + api => $self->{gcp_api}, + aggregations => $self->{gcp_aggregations}, + timeframe => $self->{gcp_timeframe}, + ); + + foreach my $aggregation (@{$self->{gcp_aggregations}}) { + next if (!defined($metric_results->{$metric}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$instance . "_" . lc($aggregation)}->{display} = $metric_results->{labels}->{instance_name}; + $self->{metric}->{$instance . "_" . lc($aggregation)}->{timeframe} = $self->{gcp_timeframe}; + $self->{metric}->{$instance . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$instance . "_" . lc($aggregation)}->{$metric . "_" . lc($aggregation)} = defined($metric_results->{$metric}->{lc($aggregation)}) ? $metric_results->{$metric}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check Compute Engine instances disk IO metrics. + +Example: + +perl centreon_plugins.pl --plugin=cloud::google::gcp::compute::computeengine::plugin --custommode=api --mode=diskio +--instance=mycomputeinstance --filter-metric='throttled' --aggregation='average' +--critical-disk-throttled-write-bytes-count-average='10' --verbose + +Default aggregation: 'average' / All aggregations are valid. + +=over 8 + +=item B<--instance> + +Set instance name (Required). + +=item B<--filter-metric> + +Filter metrics (Can be: 'instance/disk/read_bytes_count', 'instance/disk/throttled_read_bytes_count', +'instance/disk/write_bytes_count', 'instance/disk/throttled_write_bytes_count', +'instance/disk/read_ops_count', 'instance/disk/write_ops_count') (Can be a regexp). + +=item B<--warning-$metric$-$aggregation$> + +Thresholds warning ($metric$ can be: 'disk-read-bytes-count', 'disk-throttled-read-bytes-count', +'disk-write-bytes-count', 'disk-throttled-write-bytes-count','disk-read-ops-count', +'disk-write-ops-count', $aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--critical-$metric$-$aggregation$> + +Thresholds critical ($metric$ can be: 'disk-read-bytes-count', 'disk-throttled-read-bytes-count', +'disk-write-bytes-count', 'disk-throttled-write-bytes-count','disk-read-ops-count', +'disk-write-ops-count', $aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--per-sec> + +Change the data to be unit/sec. + +=back + +=cut diff --git a/cloud/google/gcp/compute/computeengine/mode/network.pm b/cloud/google/gcp/compute/computeengine/mode/network.pm new file mode 100644 index 000000000..9f2fefef6 --- /dev/null +++ b/cloud/google/gcp/compute/computeengine/mode/network.pm @@ -0,0 +1,289 @@ +# +# Copyright 2019 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 cloud::google::gcp::compute::computeengine::mode::network; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use cloud::google::gcp::custom::misc; + +sub prefix_metric_output { + my ($self, %options) = @_; + + return "Instance '" . $options{instance_value}->{display} . "' " . $options{instance_value}->{stat} . " "; +} + +sub custom_metric_calc { + my ($self, %options) = @_; + + $self->{result_values}->{stat} = $options{new_datas}->{$self->{instance} . '_stat'}; + $self->{result_values}->{metric_perf} = $options{extra_options}->{metric_perf}; + $self->{result_values}->{metric_label} = $options{extra_options}->{metric_label}; + $self->{result_values}->{metric_name} = $options{extra_options}->{metric_name}; + $self->{result_values}->{metric} = $options{extra_options}->{metric}; + $self->{result_values}->{timeframe} = $options{new_datas}->{$self->{instance} . '_timeframe'}; + $self->{result_values}->{value} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{metric} . '_' . $self->{result_values}->{stat}}; + $self->{result_values}->{value_per_sec} = $self->{result_values}->{value} / $self->{result_values}->{timeframe}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_metric_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check( + value => defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}, + threshold => [ { label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}, exit_litteral => 'warning' } ] + ); + return $exit; +} + +sub custom_traffic_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + + $self->{output}->perfdata_add( + label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'B/s' : 'B', + value => sprintf("%d", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + min => 0 + ); +} + +sub custom_traffic_output { + my ($self, %options) = @_; + my $msg = ""; + + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { + my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value_per_sec}); + $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit . "/s"; + } else { + my ($value, $unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{value}); + $msg = $self->{result_values}->{metric_name} . ": " . $value . $unit; + } + return $msg; +} + +sub custom_packet_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + + $self->{output}->perfdata_add( + label => $self->{result_values}->{metric_perf} . "_" . $self->{result_values}->{stat} . $extra_label, + unit => defined($self->{instance_mode}->{option_results}->{per_sec}) ? 'packet/s' : 'packet', + value => sprintf("%.2f", defined($self->{instance_mode}->{option_results}->{per_sec}) ? $self->{result_values}->{value_per_sec} : $self->{result_values}->{value}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{metric_label} . "-" . $self->{result_values}->{stat}), + min => 0 + ); +} + +sub custom_packet_output { + my ($self, %options) = @_; + my $msg = ""; + + if (defined($self->{instance_mode}->{option_results}->{per_sec})) { + $msg = sprintf("%s: %.2f packets/s", $self->{result_values}->{metric_name}, $self->{result_values}->{value_per_sec}); + } else { + $msg = sprintf("%s: %.2f packets", $self->{result_values}->{metric_name}, $self->{result_values}->{value}); + } + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metric', type => 1, cb_prefix_output => 'prefix_metric_output', + message_multiple => "All network metrics are ok", skipped_code => { -10 => 1 } }, + ]; + + foreach my $aggregation ('minimum', 'maximum', 'average', 'total') { + foreach my $metric ('instance/network/received_bytes_count', 'instance/network/sent_bytes_count') { + my $metric_label = cloud::google::gcp::custom::misc::format_metric_label(metric => $metric, remove => 'instance/'); + my $metric_perf = cloud::google::gcp::custom::misc::format_metric_perf(metric => $metric, remove => 'instance/'); + my $metric_name = cloud::google::gcp::custom::misc::format_metric_name(metric => $metric, remove => 'instance/'); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric . '_' . $aggregation }, { name => 'display' }, + { name => 'stat' }, { name => 'timeframe' } ], + closure_custom_calc => $self->can('custom_metric_calc'), + closure_custom_calc_extra_options => { metric_perf => $metric_perf, + metric_label => $metric_label, metric_name => $metric_name, metric => $metric }, + closure_custom_output => $self->can('custom_traffic_output'), + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_metric_threshold'), + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + foreach my $metric ('instance/network/received_packets_count', 'instance/network/sent_packets_count') { + my $metric_label = cloud::google::gcp::custom::misc::format_metric_label(metric => $metric, remove => 'instance/'); + my $metric_perf = cloud::google::gcp::custom::misc::format_metric_perf(metric => $metric, remove => 'instance/'); + my $metric_name = cloud::google::gcp::custom::misc::format_metric_name(metric => $metric, remove => 'instance/'); + my $entry = { label => $metric_label . '-' . $aggregation, set => { + key_values => [ { name => $metric . '_' . $aggregation }, { name => 'display' }, + { name => 'stat' }, { name => 'timeframe' } ], + closure_custom_calc => $self->can('custom_metric_calc'), + closure_custom_calc_extra_options => { metric_perf => $metric_perf, + metric_label => $metric_label, metric_name => $metric_name, metric => $metric }, + closure_custom_output => $self->can('custom_packet_output'), + closure_custom_perfdata => $self->can('custom_packet_perfdata'), + closure_custom_threshold_check => $self->can('custom_metric_threshold'), + } + }; + push @{$self->{maps_counters}->{metric}}, $entry; + } + } +} + +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 => { + "instance:s@" => { name => 'instance' }, + "filter-metric:s" => { name => 'filter_metric' }, + "per-sec" => { name => 'per_sec' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{instance})) { + $self->{output}->add_option_msg(short_msg => "Need to specify --instance ."); + $self->{output}->option_exit(); + } + + $self->{gcp_instance} = $self->{option_results}->{instance}; + $self->{gcp_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 900; + $self->{gcp_aggregations} = ['average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{gcp_aggregations} = []; + foreach my $stat (@{$self->{option_results}->{aggregation}}) { + if ($stat ne '') { + push @{$self->{gcp_aggregations}}, $stat; + } + } + } + + foreach my $metric ('instance/network/received_bytes_count', 'instance/network/sent_bytes_count', + 'instance/network/received_packets_count', 'instance/network/sent_packets_count') { + next if (defined($self->{option_results}->{filter_metric}) && $self->{option_results}->{filter_metric} ne '' + && $metric !~ /$self->{option_results}->{filter_metric}/); + + push @{$self->{gcp_metrics}}, $metric; + } + + $self->{gcp_api} = "compute.googleapis.com"; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $metric_results; + foreach my $instance (@{$self->{gcp_instance}}) { + foreach my $metric (@{$self->{gcp_metrics}}) { + ($metric_results, undef) = $options{custom}->gcp_get_metrics( + instance => $instance, + metric => $metric, + api => $self->{gcp_api}, + aggregations => $self->{gcp_aggregations}, + timeframe => $self->{gcp_timeframe}, + ); + + foreach my $aggregation (@{$self->{gcp_aggregations}}) { + next if (!defined($metric_results->{$metric}->{lc($aggregation)}) && !defined($self->{option_results}->{zeroed})); + + $self->{metric}->{$instance . "_" . lc($aggregation)}->{display} = $metric_results->{labels}->{instance_name}; + $self->{metric}->{$instance . "_" . lc($aggregation)}->{timeframe} = $self->{gcp_timeframe}; + $self->{metric}->{$instance . "_" . lc($aggregation)}->{stat} = lc($aggregation); + $self->{metric}->{$instance . "_" . lc($aggregation)}->{$metric . "_" . lc($aggregation)} = defined($metric_results->{$metric}->{lc($aggregation)}) ? $metric_results->{$metric}->{lc($aggregation)} : 0; + } + } + } + + if (scalar(keys %{$self->{metric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No metrics. Check your options or use --zeroed option to set 0 on undefined values'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check Compute Engine instances network metrics. + +Example: + +perl centreon_plugins.pl --plugin=cloud::google::gcp::compute::computeengine::plugin --custommode=api --mode=network +--instance=mycomputeinstance --filter-metric='bytes' --aggregation='average' +--critical-network-received-bytes-count-average='10' --verbose + +Default aggregation: 'average' / All aggregations are valid. + +=over 8 + +=item B<--instance> + +Set instance name (Required). + +=item B<--filter-metric> + +Filter metrics (Can be: 'instance/network/received_bytes_count', +'instance/network/sent_bytes_count', 'instance/network/received_packets_count', +'instance/network/sent_packets_count') (Can be a regexp). + +=item B<--warning-$metric$-$aggregation$> + +Thresholds warning ($metric$ can be: 'network-received-bytes-count', 'network-sent-bytes-count', +'network-received-packets-count','network-sent-packets-count', +$aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--critical-$metric$-$aggregation$> + +Thresholds critical ($metric$ can be: 'network-received-bytes-count', 'network-sent-bytes-count', +'network-received-packets-count','network-sent-packets-count', +$aggregation$ can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--per-sec> + +Change the data to be unit/sec. + +=back + +=cut diff --git a/cloud/google/gcp/compute/computeengine/plugin.pm b/cloud/google/gcp/compute/computeengine/plugin.pm new file mode 100644 index 000000000..79ee41944 --- /dev/null +++ b/cloud/google/gcp/compute/computeengine/plugin.pm @@ -0,0 +1,51 @@ +# +# Copyright 2019 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 cloud::google::gcp::compute::computeengine::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ( $class, %options ) = @_; + my $self = $class->SUPER::new( package => __PACKAGE__, %options ); + bless $self, $class; + + $self->{version} = '0.1'; + %{ $self->{modes} } = ( + 'cpu' => 'cloud::google::gcp::compute::computeengine::mode::cpu', + 'diskio' => 'cloud::google::gcp::compute::computeengine::mode::diskio', + 'network' => 'cloud::google::gcp::compute::computeengine::mode::network', + ); + + $self->{custom_modes}{api} = 'cloud::google::gcp::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Google Cloud Platform Compute Engine. + +=cut diff --git a/cloud/google/gcp/custom/api.pm b/cloud/google/gcp/custom/api.pm new file mode 100644 index 000000000..3f3cf7abe --- /dev/null +++ b/cloud/google/gcp/custom/api.pm @@ -0,0 +1,405 @@ +# +# Copyright 2019 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 cloud::google::gcp::custom::api; + +use strict; +use warnings; +use DateTime; +use centreon::plugins::http; +use centreon::plugins::statefile; +use JSON::XS; +use URI::Encode; +use Digest::MD5 qw(md5_hex); +use JSON::WebToken; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "key-file:s" => { name => 'key_file' }, + "authorization-endpoint:s" => { name => 'authorization_endpoint' }, + "monitoring-endpoint:s" => { name => 'monitoring_endpoint' }, + "scope-endpoint:s" => { name => 'scope_endpoint' }, + "timeframe:s" => { name => 'timeframe' }, + "interval:s" => { name => 'interval' }, + "aggregation:s@" => { name => 'aggregation' }, + "zeroed" => { name => 'zeroed' }, + "timeout:s" => { name => 'timeout' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{http} = centreon::plugins::http->new(%options); + $self->{cache} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + if (defined($self->{option_results}->{aggregation})) { + foreach my $aggregation (@{$self->{option_results}->{aggregation}}) { + if ($aggregation !~ /average|maximum|minimum|total/i) { + $self->{output}->add_option_msg(short_msg => "Aggregation '" . $aggregation . "' is not handled"); + $self->{output}->option_exit(); + } + } + } + + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; + $self->{timeframe} = (defined($self->{option_results}->{timeframe})) ? $self->{option_results}->{timeframe} : undef; + $self->{step} = (defined($self->{option_results}->{step})) ? $self->{option_results}->{step} : undef; + $self->{key_file} = (defined($self->{option_results}->{key_file})) ? $self->{option_results}->{key_file} : undef; + $self->{authorization_endpoint} = (defined($self->{option_results}->{authorization_endpoint})) ? + $self->{option_results}->{authorization_endpoint} : 'https://www.googleapis.com/oauth2/v4/token'; + $self->{monitoring_endpoint} = (defined($self->{option_results}->{monitoring_endpoint})) ? + $self->{option_results}->{monitoring_endpoint} : 'https://monitoring.googleapis.com/v3'; + $self->{scope_endpoint} = (defined($self->{option_results}->{scope_endpoint})) ? + $self->{option_results}->{scope_endpoint} : 'https://www.googleapis.com/auth/cloud-platform'; + + if (!defined($self->{key_file}) || $self->{key_file} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --key-file option."); + $self->{output}->option_exit(); + } + + $self->{cache}->check_options(option_results => $self->{option_results}); + + return 0; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{warning_status} = ''; + $self->{option_results}->{critical_status} = ''; + $self->{option_results}->{unknown_status} = ''; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->add_header(key => 'Accept', value => 'application/json'); + $self->{http}->add_header(key => 'Content-Type', value => 'application/x-www-form-urlencoded'); + if (defined($self->{access_token})) { + $self->{http}->add_header(key => 'Authorization', value => 'Bearer ' . $self->{access_token}); + } + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub get_access_token { + my ($self, %options) = @_; + + my $has_cache_file = $options{statefile}->read(statefile => 'gcp_api_' . md5_hex($self->{key_file})); + my $expires_on = $options{statefile}->get(name => 'expires_on'); + my $access_token = $options{statefile}->get(name => 'access_token'); + + if ($has_cache_file == 0 || !defined($access_token) || (($expires_on - time()) < 10)) { + local $/ = undef; + if (!open(FILE, "<", $self->{key_file})) { + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot read file '%s': %s", $self->{key_file}, $!)); + $self->{output}->display(); + $self->{output}->exit(); + } + my $key_file = ; + close FILE; + + my $iat = time(); + my $exp = $iat + 3600; + + my $decoded_key_file; + eval { + $decoded_key_file = JSON::XS->new->utf8->decode($key_file); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode key file"); + $self->{output}->option_exit(); + } + + my $jwt = JSON::WebToken->encode({ + iss => $decoded_key_file->{client_email}, + scope => $self->{scope_endpoint}, + aud => $self->{authorization_endpoint}, + exp => $exp, + iat => $iat, + }, $decoded_key_file->{private_key}, 'RS256'); + + my $post_data = 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=' . $jwt; + + $self->settings(); + + my $content = $self->{http}->request(method => 'POST', query_form_post => $post_data, + full_url => $self->{authorization_endpoint}, + hostname => ''); + + if (!defined($content) || $content eq '') { + $self->{output}->add_option_msg(short_msg => "Authorization endpoint API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->output_add(long_msg => $content, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode json response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + if (defined($decoded->{error})) { + $self->{output}->output_add(long_msg => "Error message : " . $decoded->{error_description}, debug => 1); + $self->{output}->add_option_msg(short_msg => "Authorization endpoint API return error code '" . $decoded->{error} . "' (add --debug option for detailed message)"); + $self->{output}->option_exit(); + } + + $access_token = $decoded->{access_token}; + my $datas = { last_timestamp => time(), access_token => $decoded->{access_token}, expires_on => $exp }; + $options{statefile}->write(data => $datas); + } + + return $access_token; +} + +sub get_project_id { + my ($self, %options) = @_; + + local $/ = undef; + if (!open(FILE, "<", $self->{key_file})) { + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot read file '%s': %s", $self->{key_file}, $!)); + $self->{output}->display(); + $self->{output}->exit(); + } + my $key_file = ; + close FILE; + + my $decoded_key_file; + eval { + $decoded_key_file = JSON::XS->new->utf8->decode($key_file); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode key file"); + $self->{output}->option_exit(); + } + + return $decoded_key_file->{project_id}; +} + +sub request_api { + my ($self, %options) = @_; + + if (!defined($self->{access_token})) { + $self->{access_token} = $self->get_access_token(statefile => $self->{cache}); + } + + $self->settings(); + + $self->{output}->output_add(long_msg => "URL: '" . $options{full_url} . "'", debug => 1); + + my $content = $self->{http}->request(%options); + + if (!defined($content) || $content eq '') { + $self->{output}->add_option_msg(short_msg => "Monitoring endpoint API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->output_add(long_msg => $content, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + if (defined($decoded->{error})) { + $self->{output}->output_add(long_msg => "Error message : " . $decoded->{error}->{message}, debug => 1); + $self->{output}->add_option_msg(short_msg => "Monitoring endpoint API return error code '" . $decoded->{error}->{code} . "' (add --debug option for detailed message)"); + $self->{output}->option_exit(); + } + + return $decoded; +} + +sub gcp_get_metrics_set_url { + my ($self, %options) = @_; + + my $uri = URI::Encode->new({encode_reserved => 1}); + my $encoded_filter = $uri->encode('metric.type = "' . $options{api} . '/' . $options{metric} . '"'); + $encoded_filter .= $uri->encode(' AND metric.labels.instance_name = starts_with(' . $options{instance} . ')'); + $encoded_filter .= ' AND ' . $uri->encode(join(' AND ', @{$options{extra_filters}})) if (defined($options{extra_filters}) && $options{extra_filters} ne ''); + my $encoded_start_time = $uri->encode($options{start_time}); + my $encoded_end_time = $uri->encode($options{end_time}); + my $project_id = $self->get_project_id(); + + my $url = $self->{monitoring_endpoint} . "/projects/" . $project_id . "/timeSeries/?filter=" . $encoded_filter . + "&interval.startTime=" . $encoded_start_time . "&interval.endTime=" . $encoded_end_time; + + return $url; +} + +sub gcp_get_metrics { + my ($self, %options) = @_; + + my $results = {}; + my $start_time = DateTime->now->subtract(seconds => $options{timeframe})->iso8601.'.000000Z'; + my $end_time = DateTime->now->iso8601.'.000000Z'; + + my $full_url = $self->gcp_get_metrics_set_url(%options, start_time => $start_time, end_time => $end_time); + my $response = $self->request_api(method => 'GET', full_url => $full_url, hostname => ''); + + my %aggregations = map {$_ => 1} @{$options{aggregations}}; + + foreach my $timeserie (@{$response->{timeSeries}}) { + my $metric_name = lc($timeserie->{metric}->{type}); + $metric_name =~ s/$options{api}\///; + + $results->{$metric_name} = { points => 0 }; + foreach my $point (@{$timeserie->{points}}) { + if (defined($point->{value})) { + my $value = $point->{value}->{lc($timeserie->{valueType}) . 'Value'}; + if (defined($aggregations{average})) { + $results->{$metric_name}->{average} = 0 if (!defined($results->{$metric_name}->{average})); + $results->{$metric_name}->{average} += $value; + $results->{$metric_name}->{points}++; + } + if (defined($aggregations{minimum})) { + $results->{$metric_name}->{minimum} = $value + if (!defined($results->{$metric_name}->{minimum}) || $value < $results->{$metric_name}->{minimum}); + } + if (defined($aggregations{maximum})) { + $results->{$metric_name}->{maximum} = $value + if (!defined($results->{$metric_name}->{maximum}) || $value > $results->{$metric_name}->{maximum}); + } + if (defined($aggregations{total})) { + $results->{$metric_name}->{total} = 0 if (!defined($results->{$metric_name}->{total})); + $results->{$metric_name}->{total} += $value; + $results->{$metric_name}->{points}++; + } + } + } + if (defined($results->{$metric_name}->{average})) { + $results->{$metric_name}->{average} /= $results->{$metric_name}->{points}; + } + $results->{resource} = $timeserie->{resource}; + $results->{labels} = $timeserie->{metric}->{labels}; + } + + return $results, $response; +} + +1; + +__END__ + +=head1 NAME + +Google Cloud Platform Rest API + +=head1 REST API OPTIONS + +Google Cloud Platform Rest API + +To connect to the GCP Rest API, you need to create an API key. + +Follow the 'How-to guide' in https://cloud.google.com/video-intelligence/docs/common/auth + +=over 8 + +=item B<--key-file> + +Set GCP key file path. + +=item B<--authorization-endpoint> + +Set GCP authorization endpoint URL (Default: 'https://www.googleapis.com/oauth2/v4/token') + +=item B<--monitoring-endpoint> + +Set GCP monitoring endpoint URL (Default: 'https://monitoring.googleapis.com/v3') + +=item B<--scope-endpoint> + +Set GCP scope endpoint URL (Default: 'https://www.googleapis.com/auth/monitoring.read') + +=item B<--timeframe> + +Set timeframe in seconds (i.e. 3600 to check last hour). + +=item B<--aggregation> + +Set monitor aggregation (Can be multiple, Can be: 'minimum', 'maximum', 'average', 'total'). + +=item B<--zeroed> + +Set metrics value to 0 if none. Usefull when Stackdriver +does not return value when not defined. + +=item B<--timeout> + +Set timeout in seconds (Default: 10). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/cloud/google/gcp/custom/misc.pm b/cloud/google/gcp/custom/misc.pm new file mode 100644 index 000000000..6b93aaab4 --- /dev/null +++ b/cloud/google/gcp/custom/misc.pm @@ -0,0 +1,62 @@ +# +# Copyright 2019 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 cloud::google::gcp::custom::misc; + +use strict; +use warnings; + +sub format_metric_label { + my (%options) = @_; + + my $metric = $options{metric}; + $metric =~ s/$options{remove}// if (defined($options{remove}) && $options{remove} ne ''); + $metric = lc($metric); + $metric =~ s/(\/)|(_)/-/g; + + return $metric; +} + +sub format_metric_perf { + my (%options) = @_; + + my $metric = $options{metric}; + $metric =~ s/$options{remove}// if (defined($options{remove}) && $options{remove} ne ''); + $metric = lc($metric); + $metric =~ s/\//_/g; + + return $metric; +} + +sub format_metric_name { + my (%options) = @_; + + my $metric = $options{metric}; + $metric =~ s/$options{remove}// if (defined($options{remove}) && $options{remove} ne ''); + $metric =~ s/(\/)|(_)/ /g; + $metric =~ s/(\w+)/\u$1/g; + + return $metric; +} + +1; + +__END__ + diff --git a/cloud/google/gcp/management/stackdriver/mode/getmetrics.pm b/cloud/google/gcp/management/stackdriver/mode/getmetrics.pm new file mode 100644 index 000000000..8a9e0ce1d --- /dev/null +++ b/cloud/google/gcp/management/stackdriver/mode/getmetrics.pm @@ -0,0 +1,220 @@ +# +# Copyright 2019 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 cloud::google::gcp::management::stackdriver::mode::getmetrics; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Data::Dumper; + +sub custom_metric_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + label => $self->{result_values}->{perf_label}, + value => $self->{result_values}->{value}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-metric'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-metric'), + ); +} + +sub custom_metric_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check( + value => $self->{result_values}->{value}, + threshold => [ { label => 'critical-metric', exit_litteral => 'critical' }, + { label => 'warning-metric', exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_metric_output { + my ($self, %options) = @_; + + my $msg = "Metric '" . $self->{result_values}->{label} . "' of resource '" . $self->{result_values}->{display} . "' value is " . $self->{result_values}->{value}; + return $msg; +} + +sub custom_metric_calc { + my ($self, %options) = @_; + + $self->{result_values}->{value} = $options{new_datas}->{$self->{instance} . '_value'}; + $self->{result_values}->{label} = $options{new_datas}->{$self->{instance} . '_label'}; + $self->{result_values}->{aggregation} = $options{new_datas}->{$self->{instance} . '_aggregation'}; + $self->{result_values}->{perf_label} = $options{new_datas}->{$self->{instance} . '_perf_label'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metrics', type => 0 }, + ]; + + $self->{maps_counters}->{metrics} = [ + { label => 'metric', set => { + key_values => [ { name => 'value' }, { name => 'label' }, { name => 'aggregation' }, + { name => 'perf_label' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_metric_calc'), + closure_custom_output => $self->can('custom_metric_output'), + closure_custom_perfdata => $self->can('custom_metric_perfdata'), + closure_custom_threshold_check => $self->can('custom_metric_threshold'), + } + } + ]; +} + +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 => { + "instance:s" => { name => 'instance' }, + "metric:s" => { name => 'metric' }, + "api:s" => { name => 'api' }, + "extra-filter:s@" => { name => 'extra_filter' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{instance})) { + $self->{output}->add_option_msg(short_msg => "Need to specify --instance ."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{metric})) { + $self->{output}->add_option_msg(short_msg => "Need to specify --metric ."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{api})) { + $self->{output}->add_option_msg(short_msg => "Need to specify --api ."); + $self->{output}->option_exit(); + } + + $self->{gcp_instance} = $self->{option_results}->{instance}; + $self->{gcp_metric} = $self->{option_results}->{metric}; + $self->{gcp_api} = $self->{option_results}->{api}; + $self->{gcp_timeframe} = defined($self->{option_results}->{timeframe}) ? $self->{option_results}->{timeframe} : 600; + + if (defined($self->{option_results}->{extra_filter})) { + $self->{gcp_extra_filters} = []; + foreach my $extra_filter (@{$self->{option_results}->{extra_filter}}) { + if ($extra_filter ne '') { + push @{$self->{gcp_extra_filters}}, $extra_filter; + } + } + } + + $self->{gcp_aggregation} = ['average']; + if (defined($self->{option_results}->{aggregation})) { + $self->{gcp_aggregation} = []; + foreach my $aggregation (@{$self->{option_results}->{aggregation}}) { + if ($aggregation ne '') { + push @{$self->{gcp_aggregation}}, lc($aggregation); + } + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my ($results, $raw_results) = $options{custom}->gcp_get_metrics( + instance => $self->{gcp_instance}, + metric => $self->{gcp_metric}, + api => $self->{gcp_api}, + extra_filters => $self->{gcp_extra_filters}, + aggregations => $self->{gcp_aggregation}, + timeframe => $self->{gcp_timeframe}, + ); + + $self->{metrics} = {}; + foreach my $label (keys %{$results}) { + foreach my $aggregation (('minimum', 'maximum', 'average', 'total')) { + next if (!defined($results->{$label}->{$aggregation})); + + $self->{metrics} = { + display => $self->{gcp_instance}, + label => $label, + aggregation => $aggregation, + value => $results->{$label}->{$aggregation}, + perf_label => $label . '_' . $aggregation, + }; + } + } + + $self->{output}->output_add(long_msg => sprintf("Raw data:\n%s", Dumper($raw_results)), debug => 1); +} + +1; + +__END__ + +=head1 MODE + +Check GCP metrics. + +Example: + +perl centreon_plugins.pl --plugin=cloud::google::gcp::management::stackdriver::plugin --custommode=api --mode=get-metrics +--api='compute.googleapis.com' --metric='instance/cpu/utilization' --instance=mycomputeinstance --aggregation=average +-timeframe=600 --warning-metric= --critical-metric= + +=over 8 + +=item B<--api> + +Set GCP API (Required). + +=item B<--metric> + +Set stackdriver metric (Required). + +=item B<--instance> + +Set instance name (Required). + +=item B<--warning-metric> + +Threshold warning. + +=item B<--critical-metric> + +Threshold critical. + +=item B<--extra-filter> + +Set extra filters (Can be multiple). + +Example: --extra-filter='metric.labels.mylabel = "LABELBLEUE"' + +=back + +=cut diff --git a/cloud/google/gcp/management/stackdriver/plugin.pm b/cloud/google/gcp/management/stackdriver/plugin.pm new file mode 100644 index 000000000..d64d077ac --- /dev/null +++ b/cloud/google/gcp/management/stackdriver/plugin.pm @@ -0,0 +1,50 @@ +# +# Copyright 2019 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 cloud::google::gcp::management::stackdriver::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'get-metrics' => 'cloud::google::gcp::management::stackdriver::mode::getmetrics', + ); + + $self->{custom_modes}{api} = 'cloud::google::gcp::custom::api'; + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Google Cloud Plateform Stackdriver service using API. + +=cut diff --git a/cloud/ibm/softlayer/custom/xmlapi.pm b/cloud/ibm/softlayer/custom/xmlapi.pm index 713dd00b5..4546eb555 100644 --- a/cloud/ibm/softlayer/custom/xmlapi.pm +++ b/cloud/ibm/softlayer/custom/xmlapi.pm @@ -40,24 +40,21 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "url-path:s" => { name => 'url_path' }, - "port:s" => { name => 'port' }, - "proto:s" => { name => 'proto' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "api-username:s" => { name => 'api_username' }, - "api-key:s" => { name => 'api_key' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "url-path:s" => { name => 'url_path' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "timeout:s" => { name => 'timeout' }, + "api-username:s" => { name => 'api_username' }, + "api-key:s" => { name => 'api_key' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'XMLAPI OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -92,8 +89,6 @@ sub check_options { $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; $self->{url_path} = (defined($self->{option_results}->{url_path})) ? $self->{option_results}->{url_path} : '/soap/v3'; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? $self->{option_results}->{proxyurl} : undef; - $self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef; if (!defined($self->{option_results}->{api_username}) || $self->{option_results}->{api_username} eq '') { $self->{output}->add_option_msg(short_msg => "Need to specify --api-username option."); @@ -114,7 +109,6 @@ sub build_options_for_httplib { $self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{port} = $self->{port}; $self->{option_results}->{proto} = $self->{proto}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; $self->{option_results}->{warning_status} = ''; $self->{option_results}->{critical_status} = ''; } @@ -238,18 +232,10 @@ Set API username Set API Key -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/cloud/kubernetes/custom/api.pm b/cloud/kubernetes/custom/api.pm new file mode 100644 index 000000000..0bb2d7f96 --- /dev/null +++ b/cloud/kubernetes/custom/api.pm @@ -0,0 +1,285 @@ +# +# Copyright 2019 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 cloud::kubernetes::custom::api; + +use strict; +use warnings; +use centreon::plugins::http; +use DateTime; +use JSON::XS; +use URI::Encode; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "token:s" => { name => 'token' }, + "timeout:s" => { name => 'timeout' }, + "config-file:s" => { name => 'config_file' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{http} = centreon::plugins::http->new(%options); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : undef; + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443; + $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; + $self->{token} = (defined($self->{option_results}->{token})) ? $self->{option_results}->{token} : ''; + + if (!defined($self->{hostname}) || $self->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --hostname option."); + $self->{output}->option_exit(); + } + if (!defined($self->{token}) || $self->{token} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --token option."); + $self->{output}->option_exit(); + } + + return 0; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{warning_status} = ''; + $self->{option_results}->{critical_status} = ''; + $self->{option_results}->{unknown_status} = ''; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->add_header(key => 'Accept', value => 'application/json'); + if (defined($self->{token})) { + $self->{http}->add_header(key => 'Authorization', value => 'Bearer ' . $self->{token}); + } + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub request_api { + my ($self, %options) = @_; + + $self->settings; + + $self->{output}->output_add(long_msg => "URL: '" . $self->{proto} . '://' . $self->{hostname} . + ':' . $self->{port} . $options{url_path} . "'", debug => 1); + + my $response = $self->{http}->request(url_path => $options{url_path}); + + if ($self->{http}->get_code() != 200) { + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->output_add(long_msg => $response, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $response"); + $self->{output}->option_exit(); + } + if (defined($decoded->{code})) { + $self->{output}->output_add(long_msg => "Error message: " . $decoded->{message}, debug => 1); + $self->{output}->add_option_msg(short_msg => "API return error code '" . $decoded->{code} . "' (add --debug option for detailed message)"); + $self->{output}->option_exit(); + } else { + $self->{output}->output_add(long_msg => "Error message: " . $decoded, debug => 1); + $self->{output}->add_option_msg(short_msg => "API return error code '" . $self->{http}->get_code() . "' (add --debug option for detailed message)"); + $self->{output}->option_exit(); + } + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->output_add(long_msg => $response, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $response"); + $self->{output}->option_exit(); + } + + return $decoded; +} + +sub kubernetes_list_daemonsets { + my ($self, %options) = @_; + + my $response = $self->request_api(method => 'GET', url_path => '/apis/apps/v1/daemonsets'); + + return $response; +} + +sub kubernetes_list_deployments { + my ($self, %options) = @_; + + my $response = $self->request_api(method => 'GET', url_path => '/apis/apps/v1/deployments'); + + return $response; +} + +sub kubernetes_list_ingresses { + my ($self, %options) = @_; + + my $response = $self->request_api(method => 'GET', url_path => '/apis/extensions/v1beta1/ingresses'); + + return $response; +} + +sub kubernetes_list_namespaces { + my ($self, %options) = @_; + + my $response = $self->request_api(method => 'GET', url_path => '/api/v1/namespaces'); + + return $response; +} + +sub kubernetes_list_nodes { + my ($self, %options) = @_; + + my $response = $self->request_api(method => 'GET', url_path => '/api/v1/nodes'); + + return $response; +} + +sub kubernetes_list_replicasets { + my ($self, %options) = @_; + + my $response = $self->request_api(method => 'GET', url_path => '/apis/apps/v1/replicasets'); + + return $response; +} + +sub kubernetes_list_services { + my ($self, %options) = @_; + + my $response = $self->request_api(method => 'GET', url_path => '/apis/v1/services'); + + return $response; +} + +sub kubernetes_list_statefulsets { + my ($self, %options) = @_; + + my $response = $self->request_api(method => 'GET', url_path => '/apis/apps/v1/statefulsets'); + + return $response; +} + +sub kubernetes_list_pods { + my ($self, %options) = @_; + + my $response = $self->request_api(method => 'GET', url_path => '/api/v1/pods'); + + return $response; +} + +1; + +__END__ + +=head1 NAME + +Kubernetes Rest API + +=head1 SYNOPSIS + +Kubernetes Rest API custom mode + +=head1 REST API OPTIONS + +Kubernetes Rest API + +=over 8 + +=item B<--hostname> + +Kubernetes API hostname. + +=item B<--port> + +API port (Default: 443) + +=item B<--proto> + +Specify https if needed (Default: 'https') + +=item B<--timeout> + +Set HTTP timeout + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/cloud/kubernetes/custom/kubectl.pm b/cloud/kubernetes/custom/kubectl.pm new file mode 100644 index 000000000..c9f1ee1aa --- /dev/null +++ b/cloud/kubernetes/custom/kubectl.pm @@ -0,0 +1,254 @@ +# +# Copyright 2019 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 cloud::kubernetes::custom::kubectl; + +use strict; +use warnings; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "token:s" => { name => 'token' }, + "timeout:s" => { name => 'timeout', default => 10 }, + "config-file:s" => { name => 'config_file' }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'kubectl' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'CLI OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + $self->{config_file} = (defined($self->{option_results}->{config_file})) ? $self->{option_results}->{config_file} : ''; + + if (!defined($self->{config_file}) || $self->{config_file} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --config-file option."); + $self->{output}->option_exit(); + } + + return 0; +} + +sub execute { + my ($self, %options) = @_; + + $self->{output}->output_add(long_msg => "Command line: '" . $self->{option_results}->{command} . " " . $options{cmd_options} . "'", debug => 1); + + my ($response, $exit_code) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $options{cmd_options}, + no_quit => 1 + ); + + if ($exit_code != 0) { + $self->{output}->output_add(long_msg => "Error message: " . $response, debug => 1); + $self->{output}->add_option_msg(short_msg => "CLI return error code '" . $exit_code . "' (add --debug option for detailed message)"); + $self->{output}->option_exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->output_add(long_msg => $response, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + + return $decoded; +} + +sub kubernetes_list_daemonsets { + my ($self, %options) = @_; + + my $response = $self->execute(cmd_options => 'get daemonsets --all-namespaces --output=json --kubeconfig ' . $self->{config_file}); + + return $response; +} + +sub kubernetes_list_deployments { + my ($self, %options) = @_; + + my $response = $self->execute(cmd_options => 'get deployments --all-namespaces --output=json --kubeconfig ' . $self->{config_file}); + + return $response; +} + +sub kubernetes_list_ingresses { + my ($self, %options) = @_; + + my $response = $self->execute(cmd_options => 'get ingresses --all-namespaces --output=json --kubeconfig ' . $self->{config_file}); + + return $response; +} + +sub kubernetes_list_namespaces { + my ($self, %options) = @_; + + my $response = $self->execute(cmd_options => 'get namespaces --all-namespaces --output=json --kubeconfig ' . $self->{config_file}); + + return $response; +} + +sub kubernetes_list_nodes { + my ($self, %options) = @_; + + my $response = $self->execute(cmd_options => 'get nodes --all-namespaces --output=json --kubeconfig ' . $self->{config_file}); + + return $response; +} + +sub kubernetes_list_replicasets { + my ($self, %options) = @_; + + my $response = $self->execute(cmd_options => 'get replicasets --all-namespaces --output=json --kubeconfig ' . $self->{config_file}); + + return $response; +} + +sub kubernetes_list_services { + my ($self, %options) = @_; + + my $response = $self->execute(cmd_options => 'get services --all-namespaces --output=json --kubeconfig ' . $self->{config_file}); + + return $response; +} + +sub kubernetes_list_statefulsets { + my ($self, %options) = @_; + + my $response = $self->execute(cmd_options => 'get statefulsets --all-namespaces --output=json --kubeconfig ' . $self->{config_file}); + + return $response; +} + +sub kubernetes_list_pods { + my ($self, %options) = @_; + + my $response = $self->execute(cmd_options => 'get pods --all-namespaces --output=json --kubeconfig ' . $self->{config_file}); + + return $response; +} + +1; + +__END__ + +=head1 NAME + +Kubernetes CLI (kubectl) + +=head1 SYNOPSIS + +Kubernetes CLI (kubectl) custom mode + +=head1 CLI OPTIONS + +Kubernetes CLI (kubectl) + +=over 8 + +=item B<--config-file> + +Kubernetes configuration file path +(Example: --config-file='/root/.kube/config'). + +=item B<--timeout> + +Set timeout in seconds (Default: 10). + +=item B<--sudo> + +Use 'sudo' to execute the command. + +=item B<--command> + +Command to get information (Default: 'kubectl'). +Can be changed if you have output in a file. + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: none). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/cloud/kubernetes/mode/daemonsetstatus.pm b/cloud/kubernetes/mode/daemonsetstatus.pm new file mode 100644 index 000000000..051928133 --- /dev/null +++ b/cloud/kubernetes/mode/daemonsetstatus.pm @@ -0,0 +1,215 @@ +# +# Copyright 2019 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 cloud::kubernetes::mode::daemonsetstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + label => 'desired', + nlabel => 'daemonset.pods.desired.count', + value => $self->{result_values}->{desired}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'current', + nlabel => 'daemonset.pods.current.count', + value => $self->{result_values}->{current}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'available', + nlabel => 'daemonset.pods.available.count', + value => $self->{result_values}->{available}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'up_to_date', + nlabel => 'daemonset.pods.uptodate.count', + value => $self->{result_values}->{up_to_date}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'ready', + nlabel => 'daemonset.pods.ready.count', + value => $self->{result_values}->{ready}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'misscheduled', + nlabel => 'daemonset.pods.misscheduled.count', + value => $self->{result_values}->{misscheduled}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); +} + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf("Pods Desired: %s, Current: %s, Available: %s, Up-to-date: %s, Ready: %s, Misscheduled: %s", + $self->{result_values}->{desired}, + $self->{result_values}->{current}, + $self->{result_values}->{available}, + $self->{result_values}->{up_to_date}, + $self->{result_values}->{ready}, + $self->{result_values}->{misscheduled}); +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{desired} = $options{new_datas}->{$self->{instance} . '_desired'}; + $self->{result_values}->{current} = $options{new_datas}->{$self->{instance} . '_current'}; + $self->{result_values}->{available} = $options{new_datas}->{$self->{instance} . '_available'}; + $self->{result_values}->{up_to_date} = $options{new_datas}->{$self->{instance} . '_up_to_date'}; + $self->{result_values}->{ready} = $options{new_datas}->{$self->{instance} . '_ready'}; + $self->{result_values}->{misscheduled} = $options{new_datas}->{$self->{instance} . '_misscheduled'}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'daemonsets', type => 1, cb_prefix_output => 'prefix_daemonset_output', + message_multiple => 'All daemonsets status are ok', skipped_code => { -11 => 1 } }, + ]; + + $self->{maps_counters}->{daemonsets} = [ + { label => 'status', set => { + key_values => [ { name => 'desired' }, { name => 'current' }, { name => 'up_to_date' }, + { name => 'available' }, { name => 'ready' }, { name => 'misscheduled' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => $self->can('custom_status_perfdata'), + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + ]; +} + +sub prefix_daemonset_output { + my ($self, %options) = @_; + + return "Daemonset '" . $options{instance_value}->{display} . "' "; +} + +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' }, + "filter-namespace:s" => { name => 'filter_namespace' }, + "warning-status:s" => { name => 'warning_status', default => '%{up_to_date} < %{desired}' }, + "critical-status:s" => { name => 'critical_status', default => '%{available} < %{desired}' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{daemonsets} = {}; + + my $results = $options{custom}->kubernetes_list_daemonsets(); + + foreach my $daemonset (@{$results->{items}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $daemonset->{metadata}->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $daemonset->{metadata}->{name} . "': no matching filter name.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_namespace}) && $self->{option_results}->{filter_namespace} ne '' && + $daemonset->{metadata}->{namespace} !~ /$self->{option_results}->{filter_namespace}/) { + $self->{output}->output_add(long_msg => "skipping '" . $daemonset->{metadata}->{namespace} . "': no matching filter namespace.", debug => 1); + next; + } + + $self->{daemonsets}->{$daemonset->{metadata}->{uid}} = { + display => $daemonset->{metadata}->{name}, + namespace => $daemonset->{metadata}->{namespace}, + desired => $daemonset->{status}->{desiredNumberScheduled}, + current => $daemonset->{status}->{currentNumberScheduled}, + up_to_date => $daemonset->{status}->{updatedNumberScheduled}, + available => $daemonset->{status}->{numberAvailable}, + ready => $daemonset->{status}->{numberReady}, + misscheduled => $daemonset->{status}->{numberMisscheduled}, + } + } + + if (scalar(keys %{$self->{daemonsets}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No daemonsets found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check daemonset status. + +=over 8 + +=item B<--filter-name> + +Filter daemonset name (can be a regexp). + +=item B<--filter-namespace> + +Filter daemonset namespace (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{up_to_date} < %{desired}') +Can used special variables like: %{display}, %{desired}, %{current}, +%{available}, %{unavailable}, %{up_to_date}, %{ready}, %{misscheduled} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{available} < %{desired}'). +Can used special variables like: %{display}, %{desired}, %{current}, +%{available}, %{unavailable}, %{up_to_date}, %{ready}, %{misscheduled} + +=back + +=cut diff --git a/cloud/kubernetes/mode/deploymentstatus.pm b/cloud/kubernetes/mode/deploymentstatus.pm new file mode 100644 index 000000000..215e8a418 --- /dev/null +++ b/cloud/kubernetes/mode/deploymentstatus.pm @@ -0,0 +1,206 @@ +# +# Copyright 2019 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 cloud::kubernetes::mode::deploymentstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + label => 'desired', + nlabel => 'deployment.replicas.desired.count', + value => $self->{result_values}->{desired}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'current', + nlabel => 'deployment.replicas.current.count', + value => $self->{result_values}->{current}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'available', + nlabel => 'deployment.replicas.available.count', + value => $self->{result_values}->{available}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'ready', + nlabel => 'deployment.replicas.ready.count', + value => $self->{result_values}->{ready}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'up_to_date', + nlabel => 'deployment.replicas.uptodate.count', + value => $self->{result_values}->{up_to_date}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); +} + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf("Replicas Desired: %s, Current: %s, Available: %s, Ready: %s, Up-to-date: %s", + $self->{result_values}->{desired}, + $self->{result_values}->{current}, + $self->{result_values}->{available}, + $self->{result_values}->{ready}, + $self->{result_values}->{up_to_date}); +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{desired} = $options{new_datas}->{$self->{instance} . '_desired'}; + $self->{result_values}->{current} = $options{new_datas}->{$self->{instance} . '_current'}; + $self->{result_values}->{available} = $options{new_datas}->{$self->{instance} . '_available'}; + $self->{result_values}->{ready} = $options{new_datas}->{$self->{instance} . '_ready'}; + $self->{result_values}->{up_to_date} = $options{new_datas}->{$self->{instance} . '_up_to_date'}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'deployments', type => 1, cb_prefix_output => 'prefix_deployment_output', + message_multiple => 'All deployments status are ok', skipped_code => { -11 => 1 } }, + ]; + + $self->{maps_counters}->{deployments} = [ + { label => 'status', set => { + key_values => [ { name => 'desired' }, { name => 'current' }, { name => 'up_to_date' }, + { name => 'available' }, { name => 'ready' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => $self->can('custom_status_perfdata'), + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + ]; +} + +sub prefix_deployment_output { + my ($self, %options) = @_; + + return "Deployment '" . $options{instance_value}->{display} . "' "; +} + +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' }, + "filter-namespace:s" => { name => 'filter_namespace' }, + "warning-status:s" => { name => 'warning_status', default => '%{up_to_date} < %{desired}' }, + "critical-status:s" => { name => 'critical_status', default => '%{available} < %{desired}' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{deployments} = {}; + + my $results = $options{custom}->kubernetes_list_deployments(); + + foreach my $deployment (@{$results->{items}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $deployment->{metadata}->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $deployment->{metadata}->{name} . "': no matching filter name.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_namespace}) && $self->{option_results}->{filter_namespace} ne '' && + $deployment->{metadata}->{namespace} !~ /$self->{option_results}->{filter_namespace}/) { + $self->{output}->output_add(long_msg => "skipping '" . $deployment->{metadata}->{namespace} . "': no matching filter namespace.", debug => 1); + next; + } + + $self->{deployments}->{$deployment->{metadata}->{uid}} = { + display => $deployment->{metadata}->{name}, + namespace => $deployment->{metadata}->{namespace}, + desired => $deployment->{spec}->{replicas}, + current => $deployment->{status}->{replicas}, + ready => $deployment->{status}->{readyReplicas}, + up_to_date => $deployment->{status}->{updatedReplicas}, + available => $deployment->{status}->{availableReplicas}, + } + } + + if (scalar(keys %{$self->{deployments}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No deployments found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check deployment status. + +=over 8 + +=item B<--filter-name> + +Filter deployment name (can be a regexp). + +=item B<--filter-namespace> + +Filter deployment namespace (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{up_to_date} < %{desired}') +Can used special variables like: %{display}, %{desired}, %{current}, +%{available}, %{unavailable}, %{up_to_date} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{available} < %{desired}'). +Can used special variables like: %{display}, %{desired}, %{current}, +%{available}, %{unavailable}, %{up_to_date} + +=back + +=cut diff --git a/cloud/kubernetes/mode/listdaemonsets.pm b/cloud/kubernetes/mode/listdaemonsets.pm new file mode 100644 index 000000000..511c3edcf --- /dev/null +++ b/cloud/kubernetes/mode/listdaemonsets.pm @@ -0,0 +1,128 @@ +# +# Copyright 2019 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 cloud::kubernetes::mode::listdaemonsets; + +use base qw(centreon::plugins::templates::counter); + +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' }, + "filter-namespace:s" => { name => 'filter_namespace' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->kubernetes_list_daemonsets(); + + foreach my $daemonset (@{$results->{items}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $daemonset->{metadata}->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $daemonset->{metadata}->{name} . "': no matching filter name.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_namespace}) && $self->{option_results}->{filter_namespace} ne '' && + $daemonset->{metadata}->{namespace} !~ /$self->{option_results}->{filter_namespace}/) { + $self->{output}->output_add(long_msg => "skipping '" . $daemonset->{metadata}->{namespace} . "': no matching filter namespace.", debug => 1); + next; + } + + $self->{daemonsets}->{$daemonset->{metadata}->{uid}} = { + uid => $daemonset->{metadata}->{uid}, + name => $daemonset->{metadata}->{name}, + namespace => $daemonset->{metadata}->{namespace}, + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $daemonset (sort keys %{$self->{daemonsets}}) { + $self->{output}->output_add(long_msg => sprintf("[uid = %s] [name = %s] [namespace = %s]", + $self->{daemonsets}->{$daemonset}->{uid}, + $self->{daemonsets}->{$daemonset}->{name}, + $self->{daemonsets}->{$daemonset}->{namespace})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List daemonsets:'); + $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 => ['uid', 'name', 'namespace']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $daemonset (sort keys %{$self->{daemonsets}}) { + $self->{output}->add_disco_entry( + uid => $self->{daemonsets}->{$daemonset}->{uid}, + name => $self->{daemonsets}->{$daemonset}->{name}, + namespace => $self->{daemonsets}->{$daemonset}->{namespace}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List daemonsets. + +=over 8 + +=item B<--filter-name> + +Filter daemonset name (can be a regexp). + +=item B<--filter-namespace> + +Filter daemonset namespace (can be a regexp). + +=back + +=cut diff --git a/cloud/kubernetes/mode/listdeployments.pm b/cloud/kubernetes/mode/listdeployments.pm new file mode 100644 index 000000000..624b4decf --- /dev/null +++ b/cloud/kubernetes/mode/listdeployments.pm @@ -0,0 +1,128 @@ +# +# Copyright 2019 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 cloud::kubernetes::mode::listdeployments; + +use base qw(centreon::plugins::templates::counter); + +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' }, + "filter-namespace:s" => { name => 'filter_namespace' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->kubernetes_list_deployments(); + + foreach my $deployment (@{$results->{items}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $deployment->{metadata}->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $deployment->{metadata}->{name} . "': no matching filter name.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_namespace}) && $self->{option_results}->{filter_namespace} ne '' && + $deployment->{metadata}->{namespace} !~ /$self->{option_results}->{filter_namespace}/) { + $self->{output}->output_add(long_msg => "skipping '" . $deployment->{metadata}->{namespace} . "': no matching filter namespace.", debug => 1); + next; + } + + $self->{deployments}->{$deployment->{metadata}->{uid}} = { + uid => $deployment->{metadata}->{uid}, + name => $deployment->{metadata}->{name}, + namespace => $deployment->{metadata}->{namespace}, + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $deployment (sort keys %{$self->{deployments}}) { + $self->{output}->output_add(long_msg => sprintf("[uid = %s] [name = %s] [namespace = %s]", + $self->{deployments}->{$deployment}->{uid}, + $self->{deployments}->{$deployment}->{name}, + $self->{deployments}->{$deployment}->{namespace})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List deployments:'); + $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 => ['uid', 'name', 'namespace']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $deployment (sort keys %{$self->{deployments}}) { + $self->{output}->add_disco_entry( + uid => $self->{deployments}->{$deployment}->{uid}, + name => $self->{deployments}->{$deployment}->{name}, + namespace => $self->{deployments}->{$deployment}->{namespace}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List deployments. + +=over 8 + +=item B<--filter-name> + +Filter deployment name (can be a regexp). + +=item B<--filter-namespace> + +Filter deployment namespace (can be a regexp). + +=back + +=cut diff --git a/cloud/kubernetes/mode/listingresses.pm b/cloud/kubernetes/mode/listingresses.pm new file mode 100644 index 000000000..8fb703cdc --- /dev/null +++ b/cloud/kubernetes/mode/listingresses.pm @@ -0,0 +1,128 @@ +# +# Copyright 2019 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 cloud::kubernetes::mode::listingresses; + +use base qw(centreon::plugins::templates::counter); + +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' }, + "filter-namespace:s" => { name => 'filter_namespace' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->kubernetes_list_ingresses(); + + foreach my $ingress (@{$results->{items}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $ingress->{metadata}->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $ingress->{metadata}->{name} . "': no matching filter name.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_namespace}) && $self->{option_results}->{filter_namespace} ne '' && + $ingress->{metadata}->{namespace} !~ /$self->{option_results}->{filter_namespace}/) { + $self->{output}->output_add(long_msg => "skipping '" . $ingress->{metadata}->{namespace} . "': no matching filter namespace.", debug => 1); + next; + } + + $self->{ingresses}->{$ingress->{metadata}->{uid}} = { + uid => $ingress->{metadata}->{uid}, + name => $ingress->{metadata}->{name}, + namespace => $ingress->{metadata}->{namespace}, + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $ingress (sort keys %{$self->{ingresses}}) { + $self->{output}->output_add(long_msg => sprintf("[uid = %s] [name = %s] [namespace = %s]", + $self->{ingresses}->{$ingress}->{uid}, + $self->{ingresses}->{$ingress}->{name}, + $self->{ingresses}->{$ingress}->{namespace})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List ingresses:'); + $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 => ['uid', 'name', 'namespace']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $ingress (sort keys %{$self->{ingresses}}) { + $self->{output}->add_disco_entry( + uid => $self->{ingresses}->{$ingress}->{uid}, + name => $self->{ingresses}->{$ingress}->{name}, + namespace => $self->{ingresses}->{$ingress}->{namespace}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List ingresses. + +=over 8 + +=item B<--filter-name> + +Filter ingress name (can be a regexp). + +=item B<--filter-namespace> + +Filter ingress namespace (can be a regexp). + +=back + +=cut diff --git a/cloud/kubernetes/mode/listnamespaces.pm b/cloud/kubernetes/mode/listnamespaces.pm new file mode 100644 index 000000000..8abbc8655 --- /dev/null +++ b/cloud/kubernetes/mode/listnamespaces.pm @@ -0,0 +1,115 @@ +# +# Copyright 2019 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 cloud::kubernetes::mode::listnamespaces; + +use base qw(centreon::plugins::templates::counter); + +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' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->kubernetes_list_namespaces(); + + foreach my $namespace (@{$results->{items}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $namespace->{metadata}->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $namespace->{metadata}->{name} . "': no matching filter name.", debug => 1); + next; + } + + $self->{namespaces}->{$namespace->{metadata}->{uid}} = { + uid => $namespace->{metadata}->{uid}, + name => $namespace->{metadata}->{name}, + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $namespace (sort keys %{$self->{namespaces}}) { + $self->{output}->output_add(long_msg => sprintf("[uid = %s] [name = %s]", + $self->{namespaces}->{$namespace}->{uid}, + $self->{namespaces}->{$namespace}->{name})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List namespaces:'); + $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 => ['uid', 'name']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $namespace (sort keys %{$self->{namespaces}}) { + $self->{output}->add_disco_entry( + uid => $self->{namespaces}->{$namespace}->{uid}, + name => $self->{namespaces}->{$namespace}->{name}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List namespaces. + +=over 8 + +=item B<--filter-name> + +Filter namespace name (can be a regexp). + +=back + +=cut diff --git a/cloud/kubernetes/mode/listnodes.pm b/cloud/kubernetes/mode/listnodes.pm new file mode 100644 index 000000000..706c7a774 --- /dev/null +++ b/cloud/kubernetes/mode/listnodes.pm @@ -0,0 +1,115 @@ +# +# Copyright 2019 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 cloud::kubernetes::mode::listnodes; + +use base qw(centreon::plugins::templates::counter); + +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' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->kubernetes_list_nodes(); + + foreach my $node (@{$results->{items}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $node->{metadata}->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{metadata}->{name} . "': no matching filter name.", debug => 1); + next; + } + + $self->{nodes}->{$node->{metadata}->{uid}} = { + uid => $node->{metadata}->{uid}, + name => $node->{metadata}->{name}, + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $node (sort keys %{$self->{nodes}}) { + $self->{output}->output_add(long_msg => sprintf("[uid = %s] [name = %s]", + $self->{nodes}->{$node}->{uid}, + $self->{nodes}->{$node}->{name})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List nodes:'); + $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 => ['uid', 'name']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $node (sort keys %{$self->{nodes}}) { + $self->{output}->add_disco_entry( + uid => $self->{nodes}->{$node}->{uid}, + name => $self->{nodes}->{$node}->{name}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List nodes. + +=over 8 + +=item B<--filter-name> + +Filter node name (can be a regexp). + +=back + +=cut diff --git a/cloud/kubernetes/mode/listpods.pm b/cloud/kubernetes/mode/listpods.pm new file mode 100644 index 000000000..b71b8441b --- /dev/null +++ b/cloud/kubernetes/mode/listpods.pm @@ -0,0 +1,137 @@ +# +# Copyright 2019 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 cloud::kubernetes::mode::listpods; + +use base qw(centreon::plugins::templates::counter); + +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' }, + "filter-namespace:s" => { name => 'filter_namespace' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->kubernetes_list_pods(); + + foreach my $pod (@{$results->{items}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $pod->{metadata}->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $pod->{metadata}->{name} . "': no matching filter name.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_namespace}) && $self->{option_results}->{filter_namespace} ne '' && + $pod->{metadata}->{namespace} !~ /$self->{option_results}->{filter_namespace}/) { + $self->{output}->output_add(long_msg => "skipping '" . $pod->{metadata}->{namespace} . "': no matching filter namespace.", debug => 1); + next; + } + + $self->{pods}->{$pod->{metadata}->{uid}} = { + uid => $pod->{metadata}->{uid}, + name => $pod->{metadata}->{name}, + namespace => $pod->{metadata}->{namespace}, + node => $pod->{spec}->{nodeName}, + status => $pod->{status}->{phase}, + ip => $pod->{status}->{podIP}, + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $pod (sort keys %{$self->{pods}}) { + $self->{output}->output_add(long_msg => sprintf("[uid = %s] [name = %s] [namespace = %s] [node = %s] [status = %s] [ip = %s]", + $self->{pods}->{$pod}->{uid}, + $self->{pods}->{$pod}->{name}, + $self->{pods}->{$pod}->{namespace}, + $self->{pods}->{$pod}->{node}, + $self->{pods}->{$pod}->{status}, + $self->{pods}->{$pod}->{ip})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List pods:'); + $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 => ['uid', 'name', 'namespace', 'node', 'status', 'ip']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $pod (sort keys %{$self->{pods}}) { + $self->{output}->add_disco_entry( + uid => $self->{pods}->{$pod}->{uid}, + name => $self->{pods}->{$pod}->{name}, + namespace => $self->{pods}->{$pod}->{namespace}, + namespace => $self->{pods}->{$pod}->{node}, + namespace => $self->{pods}->{$pod}->{status}, + namespace => $self->{pods}->{$pod}->{ip}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List pods. + +=over 8 + +=item B<--filter-name> + +Filter pod name (can be a regexp). + +=item B<--filter-namespace> + +Filter pod namespace (can be a regexp). + +=back + +=cut diff --git a/cloud/kubernetes/mode/listreplicasets.pm b/cloud/kubernetes/mode/listreplicasets.pm new file mode 100644 index 000000000..245423882 --- /dev/null +++ b/cloud/kubernetes/mode/listreplicasets.pm @@ -0,0 +1,128 @@ +# +# Copyright 2019 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 cloud::kubernetes::mode::listreplicasets; + +use base qw(centreon::plugins::templates::counter); + +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' }, + "filter-namespace:s" => { name => 'filter_namespace' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->kubernetes_list_replicasets(); + + foreach my $replicaset (@{$results->{items}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $replicaset->{metadata}->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $replicaset->{metadata}->{name} . "': no matching filter name.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_namespace}) && $self->{option_results}->{filter_namespace} ne '' && + $replicaset->{metadata}->{namespace} !~ /$self->{option_results}->{filter_namespace}/) { + $self->{output}->output_add(long_msg => "skipping '" . $replicaset->{metadata}->{namespace} . "': no matching filter namespace.", debug => 1); + next; + } + + $self->{replicasets}->{$replicaset->{metadata}->{uid}} = { + uid => $replicaset->{metadata}->{uid}, + name => $replicaset->{metadata}->{name}, + namespace => $replicaset->{metadata}->{namespace}, + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $replicaset (sort keys %{$self->{replicasets}}) { + $self->{output}->output_add(long_msg => sprintf("[uid = %s] [name = %s] [namespace = %s]", + $self->{replicasets}->{$replicaset}->{uid}, + $self->{replicasets}->{$replicaset}->{name}, + $self->{replicasets}->{$replicaset}->{namespace})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List replicasets:'); + $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 => ['uid', 'name', 'namespace']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $replicaset (sort keys %{$self->{replicasets}}) { + $self->{output}->add_disco_entry( + uid => $self->{replicasets}->{$replicaset}->{uid}, + name => $self->{replicasets}->{$replicaset}->{name}, + namespace => $self->{replicasets}->{$replicaset}->{namespace}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List replicasets. + +=over 8 + +=item B<--filter-name> + +Filter replicaset name (can be a regexp). + +=item B<--filter-namespace> + +Filter replicaset namespace (can be a regexp). + +=back + +=cut diff --git a/cloud/kubernetes/mode/listservices.pm b/cloud/kubernetes/mode/listservices.pm new file mode 100644 index 000000000..7477795c1 --- /dev/null +++ b/cloud/kubernetes/mode/listservices.pm @@ -0,0 +1,128 @@ +# +# Copyright 2019 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 cloud::kubernetes::mode::listservices; + +use base qw(centreon::plugins::templates::counter); + +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' }, + "filter-namespace:s" => { name => 'filter_namespace' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->kubernetes_list_services(); + + foreach my $service (@{$results->{items}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $service->{metadata}->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $service->{metadata}->{name} . "': no matching filter name.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_namespace}) && $self->{option_results}->{filter_namespace} ne '' && + $service->{metadata}->{namespace} !~ /$self->{option_results}->{filter_namespace}/) { + $self->{output}->output_add(long_msg => "skipping '" . $service->{metadata}->{namespace} . "': no matching filter namespace.", debug => 1); + next; + } + + $self->{services}->{$service->{metadata}->{uid}} = { + uid => $service->{metadata}->{uid}, + name => $service->{metadata}->{name}, + namespace => $service->{metadata}->{namespace}, + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $service (sort keys %{$self->{services}}) { + $self->{output}->output_add(long_msg => sprintf("[uid = %s] [name = %s] [namespace = %s]", + $self->{services}->{$service}->{uid}, + $self->{services}->{$service}->{name}, + $self->{services}->{$service}->{namespace})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List services:'); + $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 => ['uid', 'name', 'namespace']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $service (sort keys %{$self->{services}}) { + $self->{output}->add_disco_entry( + uid => $self->{services}->{$service}->{uid}, + name => $self->{services}->{$service}->{name}, + namespace => $self->{services}->{$service}->{namespace}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List services. + +=over 8 + +=item B<--filter-name> + +Filter service name (can be a regexp). + +=item B<--filter-namespace> + +Filter service namespace (can be a regexp). + +=back + +=cut diff --git a/cloud/kubernetes/mode/liststatefulsets.pm b/cloud/kubernetes/mode/liststatefulsets.pm new file mode 100644 index 000000000..b993c7483 --- /dev/null +++ b/cloud/kubernetes/mode/liststatefulsets.pm @@ -0,0 +1,128 @@ +# +# Copyright 2019 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 cloud::kubernetes::mode::liststatefulsets; + +use base qw(centreon::plugins::templates::counter); + +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' }, + "filter-namespace:s" => { name => 'filter_namespace' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->kubernetes_list_statefulsets(); + + foreach my $statefulset (@{$results->{items}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $statefulset->{metadata}->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $statefulset->{metadata}->{name} . "': no matching filter name.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_namespace}) && $self->{option_results}->{filter_namespace} ne '' && + $statefulset->{metadata}->{namespace} !~ /$self->{option_results}->{filter_namespace}/) { + $self->{output}->output_add(long_msg => "skipping '" . $statefulset->{metadata}->{namespace} . "': no matching filter namespace.", debug => 1); + next; + } + + $self->{statefulsets}->{$statefulset->{metadata}->{uid}} = { + uid => $statefulset->{metadata}->{uid}, + name => $statefulset->{metadata}->{name}, + namespace => $statefulset->{metadata}->{namespace}, + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $statefulset (sort keys %{$self->{statefulsets}}) { + $self->{output}->output_add(long_msg => sprintf("[uid = %s] [name = %s] [namespace = %s]", + $self->{statefulsets}->{$statefulset}->{uid}, + $self->{statefulsets}->{$statefulset}->{name}, + $self->{statefulsets}->{$statefulset}->{namespace})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List statefulsets:'); + $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 => ['uid', 'name', 'namespace']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $statefulset (sort keys %{$self->{statefulsets}}) { + $self->{output}->add_disco_entry( + uid => $self->{statefulsets}->{$statefulset}->{uid}, + name => $self->{statefulsets}->{$statefulset}->{name}, + namespace => $self->{statefulsets}->{$statefulset}->{namespace}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List statefulsets. + +=over 8 + +=item B<--filter-name> + +Filter statefulset name (can be a regexp). + +=item B<--filter-namespace> + +Filter statefulset namespace (can be a regexp). + +=back + +=cut diff --git a/cloud/kubernetes/mode/nodeusage.pm b/cloud/kubernetes/mode/nodeusage.pm new file mode 100644 index 000000000..39c578e84 --- /dev/null +++ b/cloud/kubernetes/mode/nodeusage.pm @@ -0,0 +1,200 @@ +# +# Copyright 2019 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 cloud::kubernetes::mode::nodeusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $label = 'allocated_pods'; + my $value_perf = $self->{result_values}->{allocated}; + + my %total_options = (); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { + $total_options{total} = $self->{result_values}->{allocatable}; + $total_options{cast_int} = 1; + } + + $self->{output}->perfdata_add( + label => $label, + nlabel => 'pods.allocated.count', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{allocatable}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my ($exit, $threshold_value); + $threshold_value = $self->{result_values}->{allocated}; + if ($self->{instance_mode}->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_allocated}; + } + $exit = $self->{perfdata}->threshold_check( + value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ] + ); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my $msg = sprintf("Pods Capacity: %s, Allocatable: %s, Allocated: %s (%.2f%%)", + $self->{result_values}->{capacity}, + $self->{result_values}->{allocatable}, + $self->{result_values}->{allocated}, + $self->{result_values}->{prct_allocated}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{capacity} = $options{new_datas}->{$self->{instance} . '_capacity'}; + $self->{result_values}->{allocatable} = $options{new_datas}->{$self->{instance} . '_allocatable'}; + $self->{result_values}->{allocated} = $options{new_datas}->{$self->{instance} . '_allocated'}; + $self->{result_values}->{prct_allocated} = ($self->{result_values}->{allocatable} > 0) ? $self->{result_values}->{allocated} * 100 / $self->{result_values}->{allocatable} : 0; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'nodes', type => 1, cb_prefix_output => 'prefix_node_output', + message_multiple => 'All nodes usage are ok', skipped_code => { -11 => 1 } }, + ]; + + $self->{maps_counters}->{nodes} = [ + { label => 'allocated-pods', set => { + key_values => [ { name => 'capacity' }, { name => 'allocatable' }, { name => 'allocated' }, + { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +sub prefix_node_output { + my ($self, %options) = @_; + + return "Node '" . $options{instance_value}->{display} . "' "; +} + +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' }, + "units:s" => { name => 'units', default => '%' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{nodes} = {}; + + my $nodes = $options{custom}->kubernetes_list_nodes(); + + foreach my $node (@{$nodes->{items}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $node->{metadata}->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $node->{metadata}->{name} . "': no matching filter name.", debug => 1); + next; + } + + $self->{nodes}->{$node->{metadata}->{name}} = { + display => $node->{metadata}->{name}, + capacity => $node->{status}->{capacity}->{pods}, + allocatable => $node->{status}->{allocatable}->{pods}, + } + } + + if (scalar(keys %{$self->{nodes}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No nodes found."); + $self->{output}->option_exit(); + } + + my $pods = $options{custom}->kubernetes_list_pods(); + + foreach my $pod (@{$pods->{items}}) { + next if (defined($pod->{spec}->{nodeName}) && !defined($self->{nodes}->{$pod->{spec}->{nodeName}})); + $self->{nodes}->{$pod->{spec}->{nodeName}}->{allocated}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check node usage. + +=over 8 + +=item B<--filter-name> + +Filter node name (can be a regexp). + +=item B<--warning-allocated-pods> + +Threshold warning for pods allocation. + +=item B<--critical-allocated-pods> + +Threshold critical for pods allocation. + +=item B<--units> + +Units of thresholds (Default: '%') (Can be '%' or absolute). + +=back + +=cut diff --git a/cloud/kubernetes/mode/podstatus.pm b/cloud/kubernetes/mode/podstatus.pm new file mode 100644 index 000000000..d3046e0df --- /dev/null +++ b/cloud/kubernetes/mode/podstatus.pm @@ -0,0 +1,353 @@ +# +# Copyright 2019 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 cloud::kubernetes::mode::podstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_pod_status_output { + my ($self, %options) = @_; + + return sprintf("Status is '%s'", + $self->{result_values}->{status}); +} + +sub custom_pod_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + + return 0; +} + +sub custom_container_status_output { + my ($self, %options) = @_; + + return sprintf("Status is '%s', State is '%s'", + $self->{result_values}->{status}, + $self->{result_values}->{state}); +} + +sub custom_container_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{state} = ($options{new_datas}->{$self->{instance} . '_state'} == 1) ? "ready" : "not ready"; + + return 0; +} + +sub custom_ready_perfdata { + my ($self, %options) = @_; + + my $value_perf = $self->{result_values}->{ready}; + my %total_options = (); + if ($self->{result_values}->{total} > 0 && $self->{instance_mode}->{option_results}->{units} eq '%') { + $total_options{total} = $self->{result_values}->{total}; + $total_options{cast_int} = 1; + } + + $self->{output}->perfdata_add( + label => 'containers_ready', + nlabel => 'containers.ready.count', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $total_options{total}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); +} + +sub custom_ready_threshold { + my ($self, %options) = @_; + + my ($exit, $threshold_value); + $threshold_value = $self->{result_values}->{ready}; + if ($self->{instance_mode}->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_ready}; + } + $exit = $self->{perfdata}->threshold_check( + value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ] + ); + return $exit; +} + +sub custom_ready_output { + my ($self, %options) = @_; + + my $msg = sprintf("Containers Ready: %s/%s (%.2f%%)", + $self->{result_values}->{ready}, + $self->{result_values}->{total}, + $self->{result_values}->{prct_ready}); + + return $msg; +} + +sub custom_ready_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{ready} = $options{new_datas}->{$self->{instance} . '_containers_ready'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_containers_total'}; + return 0 if ($self->{result_values}->{total} == 0); + + $self->{result_values}->{prct_ready} = $self->{result_values}->{ready} * 100 / $self->{result_values}->{total}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'pods', type => 3, cb_prefix_output => 'prefix_pod_output', cb_long_output => 'long_output', + message_multiple => 'All pods status are ok', indent_long_output => ' ', + group => [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'containers', display_long => 1, cb_prefix_output => 'prefix_container_output', + message_multiple => 'All containers status are ok', type => 1, skipped_code => { -10 => 1 } }, + ] + } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'containers-ready', set => { + key_values => [ { name => 'containers_total' }, { name => 'containers_ready' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_ready_calc'), + closure_custom_output => $self->can('custom_ready_output'), + closure_custom_perfdata => $self->can('custom_ready_perfdata'), + closure_custom_threshold_check => $self->can('custom_ready_threshold'), + } + }, + { label => 'pod-status', set => { + key_values => [ { name => 'status' } ], + closure_custom_calc => $self->can('custom_pod_status_calc'), + closure_custom_output => $self->can('custom_pod_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + { label => 'total-restarts-count', nlabel => 'restarts.total.count', set => { + key_values => [ { name => 'restarts_total' }, { name => 'display' } ], + output_template => 'Restarts: %d', + perfdatas => [ + { label => 'restarts_count', value => 'restarts_total_absolute', template => '%d', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; + $self->{maps_counters}->{containers} = [ + { label => 'container-status', set => { + key_values => [ { name => 'status' }, { name => 'state' } ], + closure_custom_calc => $self->can('custom_container_status_calc'), + closure_custom_output => $self->can('custom_container_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + { label => 'restarts-count', nlabel => 'containers.restarts.count', set => { + key_values => [ { name => 'restarts' }, { name => 'perf' } ], + output_template => 'Restarts: %d', + perfdatas => [ + { label => 'restarts_count', value => 'restarts_absolute', template => '%d', + min => 0, label_extra_instance => 1, instance_use => 'perf_absolute' }, + ], + } + }, + ]; +} + +sub prefix_pod_output { + my ($self, %options) = @_; + + return "Pod '" . $options{instance_value}->{display} . "' "; +} + +sub prefix_container_output { + my ($self, %options) = @_; + + return "Container '" . $options{instance_value}->{display} . "' "; +} + +sub long_output { + my ($self, %options) = @_; + + return "Checking pod '" . $options{instance_value}->{display} . "'"; +} + +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' }, + "filter-namespace:s" => { name => 'filter_namespace' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "warning-pod-status:s" => { name => 'warning_pod_status', default => '' }, + "critical-pod-status:s" => { name => 'critical_pod_status', default => '%{status} !~ /running/i' }, + "warning-container-status:s" => { name => 'warning_container_status', default => '' }, + "critical-container-status:s" => { name => 'critical_container_status', default => '%{status} !~ /running/i || %{state} !~ /^ready$/' }, + "units:s" => { name => 'units', default => '%' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->{extra_filter} = {}; + foreach my $filter (@{$self->{option_results}->{extra_filter}}) { + next if ($filter !~ /(.*)=(.*)/); + $self->{extra_filter}->{$1} = $2; + } + + $self->change_macros(macros => ['warning_pod_status', 'critical_pod_status', + 'warning_container_status', 'critical_container_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{pods} = {}; + + my $results = $options{custom}->kubernetes_list_pods(); + + foreach my $pod (@{$results->{items}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $pod->{metadata}->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $pod->{metadata}->{name} . "': no matching filter name.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_namespace}) && $self->{option_results}->{filter_namespace} ne '' && + $pod->{metadata}->{namespace} !~ /$self->{option_results}->{filter_namespace}/) { + $self->{output}->output_add(long_msg => "skipping '" . $pod->{metadata}->{name} . "': no matching filter namespace.", debug => 1); + next; + } + my $next = 0; + foreach my $label (keys %{$self->{extra_filter}}) { + if (!defined($pod->{metadata}->{labels}->{$label}) || $pod->{metadata}->{labels}->{$label} !~ /$self->{extra_filter}->{$label}/) { + $self->{output}->output_add(long_msg => "skipping '" . $pod->{metadata}->{name} . "': no matching extra filter.", debug => 1); + $next = 1; + last; + } + } + next if ($next == 1); + + $self->{pods}->{$pod->{metadata}->{uid}}->{display} = $pod->{metadata}->{name}; + $self->{pods}->{$pod->{metadata}->{uid}}->{global} = { + display => $pod->{metadata}->{name}, + status => $pod->{status}->{phase}, + containers_total => scalar(@{$pod->{status}->{containerStatuses}}), + containers_ready => 0, + restarts_total => 0, + }; + + foreach my $container (@{$pod->{status}->{containerStatuses}}) { + $self->{pods}->{$pod->{metadata}->{uid}}->{containers}->{$container->{name}} = { + display => $container->{name}, + status => keys %{$container->{state}}, + state => $container->{ready}, + restarts => $container->{restartCount}, + perf => $pod->{metadata}->{name} . '_' . $container->{name}, + }; + $self->{pods}->{$pod->{metadata}->{uid}}->{global}->{containers_ready}++ if ($container->{ready}); + $self->{pods}->{$pod->{metadata}->{uid}}->{global}->{restarts_total} += $container->{restartCount}; + } + } + + if (scalar(keys %{$self->{pods}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No pods found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check pod status. + +=over 8 + +=item B<--filter-name> + +Filter pod name (can be a regexp). + +=item B<--filter-namespace> + +Filter pod namespace (can be a regexp). + +=item B<--extra-filter> + +Add an extra filter based on labels (Can be multiple) + +Example : --extra-filter='app=mynewapp' + +=item B<--warning-pod-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=item B<--critical-pod-status> + +Set critical threshold for status (Default: '%{status} !~ /running/i'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-container-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=item B<--critical-container-status> + +Set critical threshold for status (Default: '%{status} !~ /running/i || %{state} !~ /^ready$/'). +Can used special variables like: %{status}, %{state}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'containers-ready', 'total-restarts-count' (count), 'restarts-count' (count). + +=item B<--critical-*> + +Threshold critical. +Can be: 'containers-ready', 'total-restarts-count' (count), 'restarts-count' (count). + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'count'). + +=back + +=cut diff --git a/cloud/kubernetes/plugin.pm b/cloud/kubernetes/plugin.pm new file mode 100644 index 000000000..f1d7afca0 --- /dev/null +++ b/cloud/kubernetes/plugin.pm @@ -0,0 +1,68 @@ +# +# Copyright 2019 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 cloud::kubernetes::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'daemonset-status' => 'cloud::kubernetes::mode::daemonsetstatus', + 'deployment-status' => 'cloud::kubernetes::mode::deploymentstatus', + 'list-daemonsets' => 'cloud::kubernetes::mode::listdaemonsets', + 'list-deployments' => 'cloud::kubernetes::mode::listdeployments', + 'list-ingresses' => 'cloud::kubernetes::mode::listingresses', + 'list-namespaces' => 'cloud::kubernetes::mode::listnamespaces', + 'list-nodes' => 'cloud::kubernetes::mode::listnodes', + 'list-pods' => 'cloud::kubernetes::mode::listpods', + 'list-replicasets' => 'cloud::kubernetes::mode::listreplicasets', + 'list-services' => 'cloud::kubernetes::mode::listservices', + 'list-statefulsets' => 'cloud::kubernetes::mode::liststatefulsets', + 'node-usage' => 'cloud::kubernetes::mode::nodeusage', + 'pod-status' => 'cloud::kubernetes::mode::podstatus', + ); + + $self->{custom_modes}{api} = 'cloud::kubernetes::custom::api'; + $self->{custom_modes}{kubectl} = 'cloud::kubernetes::custom::kubectl'; + return $self; +} + +sub init { + my ( $self, %options ) = @_; + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Kubernetes cluster using CLI (kubectl) or RestAPI. + +=cut diff --git a/cloud/microsoft/office365/custom/graphapi.pm b/cloud/microsoft/office365/custom/graphapi.pm index 7c920a484..8849d7995 100644 --- a/cloud/microsoft/office365/custom/graphapi.pm +++ b/cloud/microsoft/office365/custom/graphapi.pm @@ -46,22 +46,20 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "tenant:s" => { name => 'tenant' }, - "client-id:s" => { name => 'client_id' }, - "client-secret:s" => { name => 'client_secret' }, - "login-endpoint:s" => { name => 'login_endpoint' }, - "graph-endpoint:s" => { name => 'graph_endpoint' }, - "timeout:s" => { name => 'timeout' }, - "proxyurl:s" => { name => 'proxyurl' }, - }); + $options{options}->add_options(arguments => { + "tenant:s" => { name => 'tenant' }, + "client-id:s" => { name => 'client_id' }, + "client-secret:s" => { name => 'client_secret' }, + "login-endpoint:s" => { name => 'login_endpoint' }, + "graph-endpoint:s" => { name => 'graph_endpoint' }, + "timeout:s" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); $self->{cache} = centreon::plugins::statefile->new(%options); return $self; @@ -98,8 +96,6 @@ sub check_options { $self->{login_endpoint} = (defined($self->{option_results}->{login_endpoint})) ? $self->{option_results}->{login_endpoint} : 'https://login.microsoftonline.com'; $self->{graph_endpoint} = (defined($self->{option_results}->{graph_endpoint})) ? $self->{option_results}->{graph_endpoint} : 'https://graph.microsoft.com'; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? $self->{option_results}->{proxyurl} : undef; - $self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef; if (!defined($self->{tenant}) || $self->{tenant} eq '') { $self->{output}->add_option_msg(short_msg => "Need to specify --tenant option."); @@ -123,8 +119,6 @@ sub build_options_for_httplib { my ($self, %options) = @_; $self->{option_results}->{timeout} = $self->{timeout}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; - $self->{option_results}->{ssl_opt} = $self->{ssl_opt}; $self->{option_results}->{warning_status} = ''; $self->{option_results}->{critical_status} = ''; $self->{option_results}->{unknown_status} = ''; @@ -186,7 +180,7 @@ sub get_access_token { return $access_token; } -sub request_api_json { +sub request_api_json { #so lame for now my ($self, %options) = @_; if (!defined($self->{access_token})) { @@ -195,26 +189,39 @@ sub request_api_json { $self->settings(); - $self->{output}->output_add(long_msg => "URL: '" . $options{full_url} . "'", debug => 1); + my @results; + my %local_options = %options; - my $content = $self->{http}->request(%options); - - my $decoded; - eval { - $decoded = JSON::XS->new->utf8->decode($content); - }; - if ($@) { - $self->{output}->output_add(long_msg => $content, debug => 1); - $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); - $self->{output}->option_exit(); - } - if (defined($decoded->{error})) { - $self->{output}->output_add(long_msg => "Error message : " . $decoded->{error}->{message}, debug => 1); - $self->{output}->add_option_msg(short_msg => "Graph endpoint API return error code '" . $decoded->{error}->{code} . "' (add --debug option for detailed message)"); - $self->{output}->option_exit(); + while (1) { + $self->{output}->output_add(long_msg => "URL: '" . $local_options{full_url} . "'", debug => 1); + + my $content = $self->{http}->request(%local_options); + + if ($self->{http}->get_code() == 429) { + last; + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->output_add(long_msg => $content, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + if (defined($decoded->{error})) { + $self->{output}->output_add(long_msg => "Error message : " . $decoded->{error}->{message}, debug => 1); + $self->{output}->add_option_msg(short_msg => "Graph endpoint API return error code '" . $decoded->{error}->{code} . "' (add --debug option for detailed message)"); + $self->{output}->option_exit(); + } + push @results, @{$decoded->{value}}; + + last if (!defined($decoded->{'@odata.nextLink'})); + $local_options{full_url} = $decoded->{'@odata.nextLink'}; } - return $decoded; + return @results; } sub request_api_csv { @@ -229,9 +236,8 @@ sub request_api_csv { $self->{output}->output_add(long_msg => "URL: '" . $options{full_url} . "'", debug => 1); my $content = $self->{http}->request(%options); - my $response = $self->{http}->get_response(); - if ($response->code() != 200) { + if ($self->{http}->get_code() != 200) { my $decoded; eval { $decoded = JSON::XS->new->utf8->decode($content); @@ -396,6 +402,40 @@ sub office_get_teams_device_usage { return $response; } +sub office_get_skype_activity_set_url { + my ($self, %options) = @_; + + my $url = $self->{graph_endpoint} . "/v1.0/reports/getSkypeForBusinessActivityUserDetail(period='D7')"; + + return $url; +} + +sub office_get_skype_activity { + my ($self, %options) = @_; + + my $full_url = $self->office_get_skype_activity_set_url(%options); + my $response = $self->request_api_csv(method => 'GET', full_url => $full_url, hostname => ''); + + return $response; +} + +sub office_get_skype_device_usage_set_url { + my ($self, %options) = @_; + + my $url = $self->{graph_endpoint} . "/v1.0/reports/getSkypeForBusinessDeviceUsageUserDetail(period='D7')"; + + return $url; +} + +sub office_get_skype_device_usage { + my ($self, %options) = @_; + + my $full_url = $self->office_get_skype_device_usage_set_url(%options); + my $response = $self->request_api_csv(method => 'GET', full_url => $full_url, hostname => ''); + + return $response; +} + 1; __END__ @@ -440,10 +480,6 @@ Set Office 365 graph endpoint URL (Default: 'https://graph.microsoft.com') Set timeout in seconds (Default: 10). -=item B<--proxyurl> - -Proxy URL if any - =back =head1 DESCRIPTION diff --git a/cloud/microsoft/office365/custom/managementapi.pm b/cloud/microsoft/office365/custom/managementapi.pm index 083fc2bb7..01d2433e1 100644 --- a/cloud/microsoft/office365/custom/managementapi.pm +++ b/cloud/microsoft/office365/custom/managementapi.pm @@ -44,22 +44,20 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "tenant:s" => { name => 'tenant' }, - "client-id:s" => { name => 'client_id' }, - "client-secret:s" => { name => 'client_secret' }, - "login-endpoint:s" => { name => 'login_endpoint' }, - "management-endpoint:s" => { name => 'management_endpoint' }, - "timeout:s" => { name => 'timeout' }, - "proxyurl:s" => { name => 'proxyurl' }, - }); + $options{options}->add_options(arguments => { + "tenant:s" => { name => 'tenant' }, + "client-id:s" => { name => 'client_id' }, + "client-secret:s" => { name => 'client_secret' }, + "login-endpoint:s" => { name => 'login_endpoint' }, + "management-endpoint:s" => { name => 'management_endpoint' }, + "timeout:s" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); $self->{cache} = centreon::plugins::statefile->new(%options); return $self; @@ -96,8 +94,6 @@ sub check_options { $self->{login_endpoint} = (defined($self->{option_results}->{login_endpoint})) ? $self->{option_results}->{login_endpoint} : 'https://login.windows.net'; $self->{management_endpoint} = (defined($self->{option_results}->{management_endpoint})) ? $self->{option_results}->{management_endpoint} : 'https://manage.office.com'; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? $self->{option_results}->{proxyurl} : undef; - $self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef; if (!defined($self->{tenant}) || $self->{tenant} eq '') { $self->{output}->add_option_msg(short_msg => "Need to specify --tenant option."); @@ -121,8 +117,6 @@ sub build_options_for_httplib { my ($self, %options) = @_; $self->{option_results}->{timeout} = $self->{timeout}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; - $self->{option_results}->{ssl_opt} = $self->{ssl_opt}; $self->{option_results}->{warning_status} = ''; $self->{option_results}->{critical_status} = ''; $self->{option_results}->{unknown_status} = ''; @@ -291,10 +285,6 @@ Set Office 365 management endpoint URL (Default: 'https://manage.office.com') Set timeout in seconds (Default: 10). -=item B<--proxyurl> - -Proxy URL if any - =back =head1 DESCRIPTION diff --git a/cloud/microsoft/office365/exchange/mode/emailactivity.pm b/cloud/microsoft/office365/exchange/mode/emailactivity.pm index b6cd08ec3..ac703fb99 100644 --- a/cloud/microsoft/office365/exchange/mode/emailactivity.pm +++ b/cloud/microsoft/office365/exchange/mode/emailactivity.pm @@ -25,13 +25,11 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_active_perfdata { my ($self, %options) = @_; my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } @@ -47,7 +45,7 @@ sub custom_active_threshold { my ($self, %options) = @_; my $threshold_value = $self->{result_values}->{active}; - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_active}; } my $exit = $self->{perfdata}->threshold_check(value => $threshold_value, @@ -176,23 +174,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-mailbox:s" => { name => 'filter_mailbox' }, - "units:s" => { name => 'units', default => '%' }, - "filter-counters:s" => { name => 'filter_counters', default => 'active|total' }, - }); + $options{options}->add_options(arguments => { + "filter-mailbox:s" => { name => 'filter_mailbox' }, + "units:s" => { name => 'units', default => '%' }, + "filter-counters:s" => { name => 'filter_counters', default => 'active|total' }, + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/cloud/microsoft/office365/exchange/mode/mailboxusage.pm b/cloud/microsoft/office365/exchange/mode/mailboxusage.pm index ef2991be5..7f7fe4e0b 100644 --- a/cloud/microsoft/office365/exchange/mode/mailboxusage.pm +++ b/cloud/microsoft/office365/exchange/mode/mailboxusage.pm @@ -25,13 +25,11 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_active_perfdata { my ($self, %options) = @_; my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } @@ -47,7 +45,7 @@ sub custom_active_threshold { my ($self, %options) = @_; my $threshold_value = $self->{result_values}->{active}; - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_active}; } my $exit = $self->{perfdata}->threshold_check(value => $threshold_value, @@ -100,11 +98,11 @@ sub custom_status_threshold { 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}") { + if (defined($self->{instance_mode}->{option_results}->{critical_status}) && $self->{instance_mode}->{option_results}->{critical_status} ne '' && + eval "$self->{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}") { + } elsif (defined($self->{instance_mode}->{option_results}->{warning_status}) && $self->{instance_mode}->{option_results}->{warning_status} ne '' && + eval "$self->{instance_mode}->{option_results}->{warning_status}") { $status = 'warning'; } }; @@ -223,34 +221,22 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-mailbox:s" => { name => 'filter_mailbox' }, - "warning-status:s" => { name => 'warning_status', default => '%{used} > %{issue_warning_quota}' }, - "critical-status:s" => { name => 'critical_status', default => '%{used} > %{prohibit_send_quota}' }, - "units:s" => { name => 'units', default => '%' }, - "filter-counters:s" => { name => 'filter_counters', default => 'active|total' }, - }); - + $options{options}->add_options(arguments => { + "filter-mailbox:s" => { name => 'filter_mailbox' }, + "warning-status:s" => { name => 'warning_status', default => '%{used} > %{issue_warning_quota}' }, + "critical-status:s" => { name => 'critical_status', default => '%{used} > %{prohibit_send_quota}' }, + "units:s" => { name => 'units', default => '%' }, + "filter-counters:s" => { name => 'filter_counters', default => 'active|total' }, + }); + return $self; } -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; - } - } -} - sub check_options { my ($self, %options) = @_; $self->SUPER::check_options(%options); - $instance_mode = $self; - $self->change_macros(); + $self->change_macros(macros => ['warning_status', 'critical_status']); } sub manage_selection { diff --git a/cloud/microsoft/office365/management/mode/servicestatus.pm b/cloud/microsoft/office365/management/mode/servicestatus.pm index ec59e172f..729456c36 100644 --- a/cloud/microsoft/office365/management/mode/servicestatus.pm +++ b/cloud/microsoft/office365/management/mode/servicestatus.pm @@ -102,13 +102,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-service-name:s" => { name => 'filter_service_name' }, - "filter-feature-name:s" => { name => 'filter_feature_name' }, - "warning-status:s" => { name => 'warning_status' }, - "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /Normal/i' }, - }); + $options{options}->add_options(arguments => { + "filter-service-name:s" => { name => 'filter_service_name' }, + "filter-feature-name:s" => { name => 'filter_feature_name' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /Normal|Service Restored/i' }, + }); return $self; } @@ -176,7 +175,7 @@ Can used special variables like: %{service_name}, %{feature_name}, %{status} =item B<--critical-status> -Set critical threshold for status (Default: '%{status} !~ /Normal/i'). +Set critical threshold for status (Default: '%{status} !~ /Normal|Service Restored/i'). Can used special variables like: %{service_name}, %{feature_name}, %{status} =back diff --git a/cloud/microsoft/office365/onedrive/mode/usage.pm b/cloud/microsoft/office365/onedrive/mode/usage.pm index 23aafa0f8..a32af5c53 100644 --- a/cloud/microsoft/office365/onedrive/mode/usage.pm +++ b/cloud/microsoft/office365/onedrive/mode/usage.pm @@ -25,13 +25,11 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_active_perfdata { my ($self, %options) = @_; my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } @@ -47,7 +45,7 @@ sub custom_active_threshold { my ($self, %options) = @_; my $threshold_value = $self->{result_values}->{active}; - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_active}; } my $exit = $self->{perfdata}->threshold_check(value => $threshold_value, @@ -98,10 +96,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, @@ -250,23 +248,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-url:s" => { name => 'filter_url' }, - "filter-owner:s" => { name => 'filter_owner' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - "filter-counters:s" => { name => 'filter_counters', default => 'active-sites|total' }, - }); - - return $self; -} + $options{options}->add_options(arguments => { + "filter-url:s" => { name => 'filter_url' }, + "filter-owner:s" => { name => 'filter_owner' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "filter-counters:s" => { name => 'filter_counters', default => 'active-sites|total' }, + }); -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; + return $self; } sub manage_selection { diff --git a/cloud/microsoft/office365/sharepoint/mode/siteusage.pm b/cloud/microsoft/office365/sharepoint/mode/siteusage.pm index ad2ed1489..d11533150 100644 --- a/cloud/microsoft/office365/sharepoint/mode/siteusage.pm +++ b/cloud/microsoft/office365/sharepoint/mode/siteusage.pm @@ -25,13 +25,11 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_active_perfdata { my ($self, %options) = @_; my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } @@ -47,7 +45,7 @@ sub custom_active_threshold { my ($self, %options) = @_; my $threshold_value = $self->{result_values}->{active}; - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_active}; } my $exit = $self->{perfdata}->threshold_check(value => $threshold_value, @@ -98,10 +96,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, @@ -286,23 +284,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-url:s" => { name => 'filter_url' }, - "filter-id:s" => { name => 'filter_id' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - "filter-counters:s" => { name => 'filter_counters', default => 'active-sites|total' }, - }); - - return $self; -} + $options{options}->add_options(arguments => { + "filter-url:s" => { name => 'filter_url' }, + "filter-id:s" => { name => 'filter_id' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "filter-counters:s" => { name => 'filter_counters', default => 'active-sites|total' }, + }); -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; + return $self; } sub manage_selection { diff --git a/cloud/microsoft/office365/sharepoint/mode/usersactivity.pm b/cloud/microsoft/office365/sharepoint/mode/usersactivity.pm index e248fd0f1..a4e0eeb53 100644 --- a/cloud/microsoft/office365/sharepoint/mode/usersactivity.pm +++ b/cloud/microsoft/office365/sharepoint/mode/usersactivity.pm @@ -25,13 +25,11 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_active_perfdata { my ($self, %options) = @_; my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } @@ -47,7 +45,7 @@ sub custom_active_threshold { my ($self, %options) = @_; my $threshold_value = $self->{result_values}->{active}; - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_active}; } my $exit = $self->{perfdata}->threshold_check(value => $threshold_value, @@ -212,23 +210,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-user:s" => { name => 'filter_user' }, - "units:s" => { name => 'units', default => '%' }, - "filter-counters:s" => { name => 'filter_counters', default => 'active|total' }, - }); - + $options{options}->add_options(arguments => { + "filter-user:s" => { name => 'filter_user' }, + "units:s" => { name => 'units', default => '%' }, + "filter-counters:s" => { name => 'filter_counters', default => 'active|total' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/cloud/microsoft/office365/skype/mode/devicesusage.pm b/cloud/microsoft/office365/skype/mode/devicesusage.pm new file mode 100644 index 000000000..6c740b8ab --- /dev/null +++ b/cloud/microsoft/office365/skype/mode/devicesusage.pm @@ -0,0 +1,244 @@ +# +# Copyright 2019 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 cloud::microsoft::office365::skype::mode::devicesusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_active_perfdata { + my ($self, %options) = @_; + + my %total_options = (); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { + $total_options{total} = $self->{result_values}->{total}; + $total_options{cast_int} = 1; + } + + $self->{output}->perfdata_add(label => 'active_users', + value => $self->{result_values}->{active}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), + unit => 'users', min => 0, max => $self->{result_values}->{total}); +} + +sub custom_active_threshold { + my ($self, %options) = @_; + + my $threshold_value = $self->{result_values}->{active}; + if ($self->{instance_mode}->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_active}; + } + my $exit = $self->{perfdata}->threshold_check(value => $threshold_value, + threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + return $exit; + +} + +sub custom_active_output { + my ($self, %options) = @_; + + my $msg = sprintf("Active users on %s : %d/%d (%.2f%%)", + $self->{result_values}->{report_date}, + $self->{result_values}->{active}, + $self->{result_values}->{total}, + $self->{result_values}->{prct_active}); + return $msg; +} + +sub custom_active_calc { + my ($self, %options) = @_; + + $self->{result_values}->{active} = $options{new_datas}->{$self->{instance} . '_active'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{report_date} = $options{new_datas}->{$self->{instance} . '_report_date'}; + $self->{result_values}->{prct_active} = ($self->{result_values}->{total} != 0) ? $self->{result_values}->{active} * 100 / $self->{result_values}->{total} : 0; + + return 0; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Users count by device type : "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'active', type => 0 }, + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + ]; + + $self->{maps_counters}->{active} = [ + { label => 'active-users', set => { + key_values => [ { name => 'active' }, { name => 'total' }, { name => 'report_date' } ], + closure_custom_calc => $self->can('custom_active_calc'), + closure_custom_output => $self->can('custom_active_output'), + closure_custom_threshold_check => $self->can('custom_active_threshold'), + closure_custom_perfdata => $self->can('custom_active_perfdata') + } + }, + ]; + $self->{maps_counters}->{global} = [ + { label => 'windows', set => { + key_values => [ { name => 'windows' } ], + output_template => 'Windows: %d', + perfdatas => [ + { label => 'windows', value => 'windows_absolute', template => '%d', + min => 0 }, + ], + } + }, + { label => 'ipad', set => { + key_values => [ { name => 'ipad' } ], + output_template => 'iPad: %d', + perfdatas => [ + { label => 'ipad', value => 'ipad_absolute', template => '%d', + min => 0 }, + ], + } + }, + { label => 'iphone', set => { + key_values => [ { name => 'iphone' } ], + output_template => 'iPhone: %d', + perfdatas => [ + { label => 'iphone', value => 'iphone_absolute', template => '%d', + min => 0 }, + ], + } + }, + { label => 'android-phone', set => { + key_values => [ { name => 'android_phone' } ], + output_template => 'Android Phone: %d', + perfdatas => [ + { label => 'android_phone', value => 'android_phone_absolute', template => '%d', + min => 0 }, + ], + } + }, + { label => 'windows-phone', set => { + key_values => [ { name => 'windows_phone' } ], + output_template => 'Windows Phone: %d', + perfdatas => [ + { label => 'windows_phone', value => 'windows_phone_absolute', template => '%d', + 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 => { + "filter-user:s" => { name => 'filter_user' }, + "units:s" => { name => 'units', default => '%' }, + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{active} = { active => 0, total => 0, report_date => '' }; + $self->{global} = { windows => 0, ipad => 0, iphone => 0, android_phone => 0, windows_phone => 0 }; + + my $results = $options{custom}->office_get_skype_device_usage(); + + foreach my $user (@{$results}) { + $self->{active}->{report_date} = $user->{'Report Refresh Date'} if ($self->{active}->{report_date} eq ''); + + if (defined($self->{option_results}->{filter_user}) && $self->{option_results}->{filter_user} ne '' && + $user->{'User Principal Name'} !~ /$self->{option_results}->{filter_user}/) { + $self->{output}->output_add(long_msg => "skipping '" . $user->{'User Principal Name'} . "': no matching filter name.", debug => 1); + next; + } + + $self->{active}->{total}++; + + if (!defined($user->{'Last Activity Date'}) || $user->{'Last Activity Date'} eq '' || + ($user->{'Last Activity Date'} ne $user->{'Report Refresh Date'})) { + $self->{output}->output_add(long_msg => "skipping '" . $user->{'User Principal Name'} . "': no activity.", debug => 1); + next; + } + + $self->{active}->{active}++; + + $self->{global}->{windows}++ if ($user->{'Used Windows'} =~ /Yes/); + $self->{global}->{ipad}++ if ($user->{'Used iPad'} =~ /Yes/); + $self->{global}->{iphone}++ if ($user->{'Used iPhone'} =~ /Yes/); + $self->{global}->{android_phone}++ if ($user->{'Used Android Phone'} =~ /Yes/); + $self->{global}->{windows_phone}++ if ($user->{'Used Windows Phone'} =~ /Yes/); + } +} + +1; + +__END__ + +=head1 MODE + +Check devices usage (reporting period over the last 7 days). + +(See link for details about metrics : +https://docs.microsoft.com/en-us/office365/admin/activity-reports/microsoft-teams-device-usage?view=o365-worldwide) + +=over 8 + +=item B<--filter-user> + +Filter users. + +=item B<--warning-*> + +Threshold warning. +Can be: 'active-users', 'windows' (count), 'ipad' (count), +'iphone' (count), 'android-phone' (count), +'windows-phone' (count). + +=item B<--critical-*> + +Threshold critical. +Can be: 'active-users', 'windows' (count), 'ipad' (count), +'iphone' (count), 'android-phone' (count), +'windows-phone' (count). + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example to hide per user counters: --filter-counters='windows' + +=item B<--units> + +Unit of thresholds (Default: '%') ('%', 'count'). + +=back + +=cut diff --git a/cloud/microsoft/office365/skype/mode/usersactivity.pm b/cloud/microsoft/office365/skype/mode/usersactivity.pm new file mode 100644 index 000000000..64650efdb --- /dev/null +++ b/cloud/microsoft/office365/skype/mode/usersactivity.pm @@ -0,0 +1,270 @@ +# +# Copyright 2019 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 cloud::microsoft::office365::skype::mode::usersactivity; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_active_perfdata { + my ($self, %options) = @_; + + my %total_options = (); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { + $total_options{total} = $self->{result_values}->{total}; + $total_options{cast_int} = 1; + } + + $self->{output}->perfdata_add(label => 'active_users', + value => $self->{result_values}->{active}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), + unit => 'users', min => 0, max => $self->{result_values}->{total}); +} + +sub custom_active_threshold { + my ($self, %options) = @_; + + my $threshold_value = $self->{result_values}->{active}; + if ($self->{instance_mode}->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_active}; + } + my $exit = $self->{perfdata}->threshold_check(value => $threshold_value, + threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + return $exit; + +} + +sub custom_active_output { + my ($self, %options) = @_; + + my $msg = sprintf("Active users on %s : %d/%d (%.2f%%)", + $self->{result_values}->{report_date}, + $self->{result_values}->{active}, + $self->{result_values}->{total}, + $self->{result_values}->{prct_active}); + return $msg; +} + +sub custom_active_calc { + my ($self, %options) = @_; + + $self->{result_values}->{active} = $options{new_datas}->{$self->{instance} . '_active'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{report_date} = $options{new_datas}->{$self->{instance} . '_report_date'}; + $self->{result_values}->{prct_active} = ($self->{result_values}->{total} != 0) ? $self->{result_values}->{active} * 100 / $self->{result_values}->{total} : 0; + + return 0; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Total "; +} + +sub prefix_user_output { + my ($self, %options) = @_; + + return "User '" . $options{instance_value}->{name} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'active', type => 0 }, + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'users', type => 1, cb_prefix_output => 'prefix_user_output', message_multiple => 'All users activity are ok' }, + ]; + + $self->{maps_counters}->{active} = [ + { label => 'active-users', set => { + key_values => [ { name => 'active' }, { name => 'total' }, { name => 'report_date' } ], + closure_custom_calc => $self->can('custom_active_calc'), + closure_custom_output => $self->can('custom_active_output'), + closure_custom_threshold_check => $self->can('custom_active_threshold'), + closure_custom_perfdata => $self->can('custom_active_perfdata') + } + }, + ]; + $self->{maps_counters}->{global} = [ + { label => 'total-peer-to-peer-sessions', set => { + key_values => [ { name => 'peer_to_peer_sessions' } ], + output_template => 'Peer-to-peer Sessions Count: %d', + perfdatas => [ + { label => 'total_peer_to_peer_sessions', value => 'peer_to_peer_sessions_absolute', template => '%d', + min => 0 }, + ], + } + }, + { label => 'total-organized-conference', set => { + key_values => [ { name => 'organized_conference' } ], + output_template => 'Organized Conference Count: %d', + perfdatas => [ + { label => 'total_organized_conference', value => 'organized_conference_absolute', template => '%d', + min => 0 }, + ], + } + }, + { label => 'total-participated-conference', set => { + key_values => [ { name => 'participated_conference' } ], + output_template => 'Participated Conference Count: %d', + perfdatas => [ + { label => 'total_participated_conference', value => 'participated_conference_absolute', template => '%d', + min => 0 }, + ], + } + }, + ]; + $self->{maps_counters}->{users} = [ + { label => 'peer-to-peer-sessions', set => { + key_values => [ { name => 'peer_to_peer_sessions' }, { name => 'name' } ], + output_template => 'Peer-to-peer Sessions Count: %d', + perfdatas => [ + { label => 'peer_to_peer_sessions', value => 'peer_to_peer_sessions_absolute', template => '%d', + min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + { label => 'organized-conference', set => { + key_values => [ { name => 'organized_conference' }, { name => 'name' } ], + output_template => 'Organized Conference Count: %d', + perfdatas => [ + { label => 'organized_conference', value => 'organized_conference_absolute', template => '%d', + min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + { label => 'participated-conference', set => { + key_values => [ { name => 'participated_conference' }, { name => 'name' } ], + output_template => 'Participated Conference Count: %d', + perfdatas => [ + { label => 'participated_conference', value => 'participated_conference_absolute', template => '%d', + min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + ]; +} + +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-user:s" => { name => 'filter_user' }, + "units:s" => { name => 'units', default => '%' }, + "filter-counters:s" => { name => 'filter_counters', default => 'active|total' }, + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{active} = { active => 0, total => 0, report_date => '' }; + $self->{global} = { peer_to_peer_sessions => 0, organized_conference => 0, participated_conference => 0 }; + $self->{users} = {}; + + my $results = $options{custom}->office_get_skype_activity(); + + foreach my $user (@{$results}) { + $self->{active}->{report_date} = $user->{'Report Refresh Date'} if ($self->{active}->{report_date} eq ''); + + if (defined($self->{option_results}->{filter_user}) && $self->{option_results}->{filter_user} ne '' && + $user->{'User Principal Name'} !~ /$self->{option_results}->{filter_user}/) { + $self->{output}->output_add(long_msg => "skipping '" . $user->{'User Principal Name'} . "': no matching filter name.", debug => 1); + next; + } + + $self->{active}->{total}++; + + if (!defined($user->{'Last Activity Date'}) || $user->{'Last Activity Date'} eq '' || + ($user->{'Last Activity Date'} ne $user->{'Report Refresh Date'})) { + $self->{output}->output_add(long_msg => "skipping '" . $user->{'User Principal Name'} . "': no activity.", debug => 1); + next; + } + + $self->{active}->{active}++; + + $self->{global}->{peer_to_peer_sessions} += $user->{'Total Peer-to-peer Session Count'}; + $self->{global}->{organized_conference} += $user->{'Total Organized Conference Count'}; + $self->{global}->{participated_conference} += $user->{'Total Participated Conference Count'}; + + $self->{users}->{$user->{'User Principal Name'}}->{name} = $user->{'User Principal Name'}; + $self->{users}->{$user->{'User Principal Name'}}->{peer_to_peer_sessions} = $user->{'Total Peer-to-peer Session Count'}; + $self->{users}->{$user->{'User Principal Name'}}->{organized_conference} = $user->{'Total Organized Conference Count'}; + $self->{users}->{$user->{'User Principal Name'}}->{participated_conference} = $user->{'Total Participated Conference Count'}; + } +} + +1; + +__END__ + +=head1 MODE + +Check users activity (reporting period over the last 7 days). + +(See link for details about metrics : +https://docs.microsoft.com/en-us/SkypeForBusiness/skype-for-business-online-reporting/activity-report) + +=over 8 + +=item B<--filter-user> + +Filter users. + +=item B<--warning-*> + +Threshold warning. +Can be: 'active-users', 'total-peer-to-peer-sessions' (count), +'total-organized-conference' (count), 'total-participated-conference' (count), +'peer-to-peer-sessions' (count), 'organized-conference' (count), +'participated-conference' (count). + +=item B<--critical-*> + +Threshold critical. +Can be: 'active-users', 'total-peer-to-peer-sessions' (count), +'total-organized-conference' (count), 'total-participated-conference' (count), +'peer-to-peer-sessions' (count), 'organized-conference' (count), +'participated-conference' (count). + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example to hide per user counters: --filter-counters='total' +(Default: 'active|total') + +=item B<--units> + +Unit of thresholds (Default: '%') ('%', 'count'). + +=back + +=cut diff --git a/cloud/microsoft/office365/skype/plugin.pm b/cloud/microsoft/office365/skype/plugin.pm new file mode 100644 index 000000000..865d51d1f --- /dev/null +++ b/cloud/microsoft/office365/skype/plugin.pm @@ -0,0 +1,50 @@ +# +# Copyright 2019 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 cloud::microsoft::office365::skype::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ( $class, %options ) = @_; + my $self = $class->SUPER::new( package => __PACKAGE__, %options ); + bless $self, $class; + + $self->{version} = '0.1'; + %{ $self->{modes} } = ( + 'devices-usage' => 'cloud::microsoft::office365::skype::mode::devicesusage', + 'users-activity' => 'cloud::microsoft::office365::skype::mode::usersactivity', + ); + + $self->{custom_modes}{graphapi} = 'cloud::microsoft::office365::custom::graphapi'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Microsoft Office 365 Skype for Business. + +=cut diff --git a/cloud/microsoft/office365/teams/mode/devicesusage.pm b/cloud/microsoft/office365/teams/mode/devicesusage.pm index c8832fe22..48e0607e6 100644 --- a/cloud/microsoft/office365/teams/mode/devicesusage.pm +++ b/cloud/microsoft/office365/teams/mode/devicesusage.pm @@ -25,13 +25,11 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_active_perfdata { my ($self, %options) = @_; my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } @@ -47,7 +45,7 @@ sub custom_active_threshold { my ($self, %options) = @_; my $threshold_value = $self->{result_values}->{active}; - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_active}; } my $exit = $self->{perfdata}->threshold_check(value => $threshold_value, @@ -167,23 +165,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-user:s" => { name => 'filter_user' }, - "units:s" => { name => 'units', default => '%' }, - "filter-counters:s" => { name => 'filter_counters' }, - }); - + $options{options}->add_options(arguments => { + "filter-user:s" => { name => 'filter_user' }, + "units:s" => { name => 'units', default => '%' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/cloud/microsoft/office365/teams/mode/usersactivity.pm b/cloud/microsoft/office365/teams/mode/usersactivity.pm index 108d783f3..0b88f4706 100644 --- a/cloud/microsoft/office365/teams/mode/usersactivity.pm +++ b/cloud/microsoft/office365/teams/mode/usersactivity.pm @@ -25,13 +25,11 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_active_perfdata { my ($self, %options) = @_; my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } @@ -47,7 +45,7 @@ sub custom_active_threshold { my ($self, %options) = @_; my $threshold_value = $self->{result_values}->{active}; - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_active}; } my $exit = $self->{perfdata}->threshold_check(value => $threshold_value, @@ -194,23 +192,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-user:s" => { name => 'filter_user' }, - "units:s" => { name => 'units', default => '%' }, - "filter-counters:s" => { name => 'filter_counters', default => 'active|total' }, - }); - + $options{options}->add_options(arguments => { + "filter-user:s" => { name => 'filter_user' }, + "units:s" => { name => 'units', default => '%' }, + "filter-counters:s" => { name => 'filter_counters', default => 'active|total' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/cloud/nutanix/snmp/mode/containerusage.pm b/cloud/nutanix/snmp/mode/containerusage.pm index a1dff4208..891819d53 100644 --- a/cloud/nutanix/snmp/mode/containerusage.pm +++ b/cloud/nutanix/snmp/mode/containerusage.pm @@ -26,21 +26,19 @@ use strict; use warnings; use centreon::plugins::misc; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } my $extra_label = ''; $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } @@ -57,10 +55,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); return $exit; @@ -135,23 +133,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub prefix_container_output { my ($self, %options) = @_; diff --git a/cloud/nutanix/snmp/mode/hypervisorusage.pm b/cloud/nutanix/snmp/mode/hypervisorusage.pm index 48c4d3f5a..6098d99cd 100644 --- a/cloud/nutanix/snmp/mode/hypervisorusage.pm +++ b/cloud/nutanix/snmp/mode/hypervisorusage.pm @@ -26,8 +26,6 @@ use strict; use warnings; use centreon::plugins::misc; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; @@ -140,21 +138,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub prefix_hypervisor_output { my ($self, %options) = @_; diff --git a/cloud/nutanix/snmp/mode/storagepoolusage.pm b/cloud/nutanix/snmp/mode/storagepoolusage.pm index 0ae95ff76..67fd531d1 100644 --- a/cloud/nutanix/snmp/mode/storagepoolusage.pm +++ b/cloud/nutanix/snmp/mode/storagepoolusage.pm @@ -26,21 +26,19 @@ use strict; use warnings; use centreon::plugins::misc; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } my $extra_label = ''; $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } @@ -57,10 +55,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); return $exit; @@ -135,23 +133,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub prefix_sp_output { my ($self, %options) = @_; diff --git a/cloud/nutanix/snmp/mode/vmusage.pm b/cloud/nutanix/snmp/mode/vmusage.pm index 10216e024..76ca43f3b 100644 --- a/cloud/nutanix/snmp/mode/vmusage.pm +++ b/cloud/nutanix/snmp/mode/vmusage.pm @@ -27,8 +27,6 @@ use warnings; use centreon::plugins::misc; use Digest::MD5 qw(md5_hex); -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -102,21 +100,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub prefix_vm_output { my ($self, %options) = @_; diff --git a/cloud/ovh/restapi/custom/api.pm b/cloud/ovh/restapi/custom/api.pm index 2af49918b..30abc293e 100644 --- a/cloud/ovh/restapi/custom/api.pm +++ b/cloud/ovh/restapi/custom/api.pm @@ -46,22 +46,19 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "ovh-type:s@" => { name => 'ovh_type' }, - "ovh-application-key:s@" => { name => 'ovh_application_key' }, - "ovh-application-secret:s@" => { name => 'ovh_application_secret' }, - "ovh-consumer-key:s@" => { name => 'ovh_consumer_key' }, - "proxyurl:s@" => { name => 'proxyurl' }, - "timeout:s@" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "ovh-type:s@" => { name => 'ovh_type' }, + "ovh-application-key:s@" => { name => 'ovh_application_key' }, + "ovh-application-secret:s@" => { name => 'ovh_application_secret' }, + "ovh-consumer-key:s@" => { name => 'ovh_consumer_key' }, + "timeout:s@" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; @@ -102,7 +99,6 @@ sub check_options { $self->{ovh_application_secret} = (defined($self->{option_results}->{ovh_application_secret})) ? shift(@{$self->{option_results}->{ovh_application_secret}}) : undef; $self->{ovh_consumer_key} = (defined($self->{option_results}->{ovh_consumer_key})) ? shift(@{$self->{option_results}->{ovh_consumer_key}}) : undef; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef; if (!defined($self->{ovh_application_key})) { $self->{output}->add_option_msg(short_msg => "Need to specify --ovh-application-key option."); @@ -129,7 +125,6 @@ sub build_options_for_httplib { my ($self, %options) = @_; $self->{option_results}->{timeout} = $self->{timeout}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; } sub settings { @@ -188,8 +183,7 @@ sub get { my $response = $self->{http}->request(full_url => $map_ovh_type{uc($self->{ovh_type})} . $options{path}, hostname => '', critical_status => '', warning_status => ''); - my $headers = $self->{http}->get_header(); - my $client_warning = $headers->header('Client-Warning'); + my ($client_warning) = $self->{http}->get_header(name => 'Client-Warning'); if (defined($client_warning) && $client_warning eq 'Internal response') { $self->{output}->add_option_msg(short_msg => "Internal LWP::UserAgent error: $response"); $self->{output}->option_exit(); @@ -243,18 +237,10 @@ OVH API applicationSecret OVH API consumerKey -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/cloud/ovh/restapi/mode/quotausage.pm b/cloud/ovh/restapi/mode/quotausage.pm index bf9248fb4..f6a6ef8ae 100644 --- a/cloud/ovh/restapi/mode/quotausage.pm +++ b/cloud/ovh/restapi/mode/quotausage.pm @@ -26,21 +26,19 @@ use strict; use warnings; use centreon::plugins::misc; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } my $extra_label = ''; $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } @@ -57,10 +55,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); return $exit; @@ -117,23 +115,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-service:s" => { name => 'filter_service' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); - + $options{options}->add_options(arguments => { + "filter-service:s" => { name => 'filter_service' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub prefix_services_output { my ($self, %options) = @_; diff --git a/cloud/prometheus/direct/kubernetes/mode/containerstatus.pm b/cloud/prometheus/direct/kubernetes/mode/containerstatus.pm index e33818ae4..ac5a6e3ed 100644 --- a/cloud/prometheus/direct/kubernetes/mode/containerstatus.pm +++ b/cloud/prometheus/direct/kubernetes/mode/containerstatus.pm @@ -68,7 +68,7 @@ sub set_counters { closure_custom_threshold_check => \&catalog_status_threshold, } }, - { label => 'restarts-count', set => { + { label => 'restarts-count', nlabel => 'containers.restarts.count', set => { key_values => [ { name => 'restarts' }, { name => 'perf' } ], output_template => 'Restarts count : %d', perfdatas => [ @@ -92,16 +92,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "container:s" => { name => 'container', default => 'container=~".*"' }, - "pod:s" => { name => 'pod', default => 'pod=~".*"' }, - "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /running/ || %{state} !~ /ready/' }, - "extra-filter:s@" => { name => 'extra_filter' }, - "metric-overload:s@" => { name => 'metric_overload' }, - "filter-counters:s" => { name => 'filter_counters' }, - }); + $options{options}->add_options(arguments => { + "container:s" => { name => 'container', default => 'container=~".*"' }, + "pod:s" => { name => 'pod', default => 'pod=~".*"' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /running/ || %{state} !~ /ready/' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); return $self; } @@ -146,34 +144,38 @@ sub manage_selection { $self->{containers} = {}; - my $results = $options{custom}->query(queries => [ 'label_replace({__name__=~"' . $self->{metrics}->{ready} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}, "__name__", "ready", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{running} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}, "__name__", "running", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{terminated} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}, "__name__", "terminated", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{terminated_reason} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}, "__name__", "terminated_reason", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{waiting} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}, "__name__", "waiting", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{waiting_reason} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}, "__name__", "waiting_reason", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{restarts} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}, "__name__", "restarts", "", "")' ]); + my $results = $options{custom}->query( + queries => [ + 'label_replace({__name__=~"' . $self->{metrics}->{ready} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}, "__name__", "ready", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{running} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}, "__name__", "running", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{terminated} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}, "__name__", "terminated", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{terminated_reason} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}, "__name__", "terminated_reason", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{waiting} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}, "__name__", "waiting", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{waiting_reason} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}, "__name__", "waiting_reason", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{restarts} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}, "__name__", "restarts", "", "")' + ] + ); foreach my $result (@{$results}) { next if (!defined($result->{metric}->{$self->{labels}->{pod}}) || !defined($result->{metric}->{$self->{labels}->{container}})); diff --git a/cloud/prometheus/direct/kubernetes/mode/daemonsetstatus.pm b/cloud/prometheus/direct/kubernetes/mode/daemonsetstatus.pm index bd3c20c44..097dbc039 100644 --- a/cloud/prometheus/direct/kubernetes/mode/daemonsetstatus.pm +++ b/cloud/prometheus/direct/kubernetes/mode/daemonsetstatus.pm @@ -28,26 +28,49 @@ use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold) sub custom_status_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - - $self->{output}->perfdata_add(label => 'desired' . $extra_label, - value => $self->{result_values}->{desired}); - $self->{output}->perfdata_add(label => 'current' . $extra_label, - value => $self->{result_values}->{current}); - $self->{output}->perfdata_add(label => 'available' . $extra_label, - value => $self->{result_values}->{available}); - $self->{output}->perfdata_add(label => 'unavailable' . $extra_label, - value => $self->{result_values}->{unavailable}); - $self->{output}->perfdata_add(label => 'up_to_date' . $extra_label, - value => $self->{result_values}->{up_to_date}); - $self->{output}->perfdata_add(label => 'ready' . $extra_label, - value => $self->{result_values}->{ready}); - $self->{output}->perfdata_add(label => 'misscheduled' . $extra_label, - value => $self->{result_values}->{misscheduled}); + + $self->{output}->perfdata_add( + label => 'desired', + nlabel => 'daemonset.nodes.desired.count', + value => $self->{result_values}->{desired}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'current', + nlabel => 'daemonset.nodes.current.count', + value => $self->{result_values}->{current}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'available', + nlabel => 'daemonset.nodes.available.count', + value => $self->{result_values}->{available}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'unavailable', + nlabel => 'daemonset.nodes.unavailable.count', + value => $self->{result_values}->{unavailable}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'up_to_date', + nlabel => 'daemonset.nodes.uptodate.count', + value => $self->{result_values}->{up_to_date}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'ready', + nlabel => 'daemonset.nodes.ready.count', + value => $self->{result_values}->{ready}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'misscheduled', + nlabel => 'daemonset.nodes.misscheduled.count', + value => $self->{result_values}->{misscheduled}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); } sub custom_status_output { @@ -112,14 +135,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "daemonset:s" => { name => 'daemonset', default => 'daemonset=~".*"' }, - "warning-status:s" => { name => 'warning_status', default => '%{up_to_date} < %{desired}' }, - "critical-status:s" => { name => 'critical_status', default => '%{available} < %{desired}' }, - "extra-filter:s@" => { name => 'extra_filter' }, - "metric-overload:s@" => { name => 'metric_overload' }, - }); + $options{options}->add_options(arguments => { + "daemonset:s" => { name => 'daemonset', default => 'daemonset=~".*"' }, + "warning-status:s" => { name => 'warning_status', default => '%{up_to_date} < %{desired}' }, + "critical-status:s" => { name => 'critical_status', default => '%{available} < %{desired}' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); return $self; } @@ -164,27 +186,31 @@ sub manage_selection { $self->{daemonsets} = {}; - my $results = $options{custom}->query(queries => [ 'label_replace({__name__=~"' . $self->{metrics}->{desired} . '",' . - $self->{option_results}->{daemonset} . - $self->{extra_filter} . '}, "__name__", "desired", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{current} . '",' . - $self->{option_results}->{daemonset} . - $self->{extra_filter} . '}, "__name__", "current", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{available} . '",' . - $self->{option_results}->{daemonset} . - $self->{extra_filter} . '}, "__name__", "available", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{unavailable} . '",' . - $self->{option_results}->{daemonset} . - $self->{extra_filter} . '}, "__name__", "unavailable", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{up_to_date} . '",' . - $self->{option_results}->{daemonset} . - $self->{extra_filter} . '}, "__name__", "up_to_date", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{ready} . '",' . - $self->{option_results}->{daemonset} . - $self->{extra_filter} . '}, "__name__", "ready", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{misscheduled} . '",' . - $self->{option_results}->{daemonset} . - $self->{extra_filter} . '}, "__name__", "misscheduled", "", "")' ]); + my $results = $options{custom}->query( + queries => [ + 'label_replace({__name__=~"' . $self->{metrics}->{desired} . '",' . + $self->{option_results}->{daemonset} . + $self->{extra_filter} . '}, "__name__", "desired", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{current} . '",' . + $self->{option_results}->{daemonset} . + $self->{extra_filter} . '}, "__name__", "current", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{available} . '",' . + $self->{option_results}->{daemonset} . + $self->{extra_filter} . '}, "__name__", "available", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{unavailable} . '",' . + $self->{option_results}->{daemonset} . + $self->{extra_filter} . '}, "__name__", "unavailable", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{up_to_date} . '",' . + $self->{option_results}->{daemonset} . + $self->{extra_filter} . '}, "__name__", "up_to_date", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{ready} . '",' . + $self->{option_results}->{daemonset} . + $self->{extra_filter} . '}, "__name__", "ready", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{misscheduled} . '",' . + $self->{option_results}->{daemonset} . + $self->{extra_filter} . '}, "__name__", "misscheduled", "", "")' + ] + ); foreach my $result (@{$results}) { $self->{daemonsets}->{$result->{metric}->{$self->{labels}->{daemonset}}}->{display} = $result->{metric}->{$self->{labels}->{daemonset}}; diff --git a/cloud/prometheus/direct/kubernetes/mode/deploymentstatus.pm b/cloud/prometheus/direct/kubernetes/mode/deploymentstatus.pm index 27b17c37a..014f26375 100644 --- a/cloud/prometheus/direct/kubernetes/mode/deploymentstatus.pm +++ b/cloud/prometheus/direct/kubernetes/mode/deploymentstatus.pm @@ -29,21 +29,36 @@ use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold) sub custom_status_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - - $self->{output}->perfdata_add(label => 'desired' . $extra_label, - value => $self->{result_values}->{desired}); - $self->{output}->perfdata_add(label => 'current' . $extra_label, - value => $self->{result_values}->{current}); - $self->{output}->perfdata_add(label => 'available' . $extra_label, - value => $self->{result_values}->{available}); - $self->{output}->perfdata_add(label => 'unavailable' . $extra_label, - value => $self->{result_values}->{unavailable}); - $self->{output}->perfdata_add(label => 'up_to_date' . $extra_label, - value => $self->{result_values}->{up_to_date}); + $self->{output}->perfdata_add( + label => 'desired', + nlabel => 'deployment.replicas.desired.count', + value => $self->{result_values}->{desired}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'current', + nlabel => 'deployment.replicas.current.count', + value => $self->{result_values}->{current}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'available', + nlabel => 'deployment.replicas.available.count', + value => $self->{result_values}->{available}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'unavailable', + nlabel => 'deployment.replicas.unavailable.count', + value => $self->{result_values}->{unavailable}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); + $self->{output}->perfdata_add( + label => 'up_to_date', + nlabel => 'deployment.replicas.uptodate.count', + value => $self->{result_values}->{up_to_date}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); } sub custom_status_output { @@ -103,14 +118,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "deployment:s" => { name => 'deployment', default => 'deployment=~".*"' }, - "warning-status:s" => { name => 'warning_status', default => '%{up_to_date} < %{desired}' }, - "critical-status:s" => { name => 'critical_status', default => '%{available} < %{desired}' }, - "extra-filter:s@" => { name => 'extra_filter' }, - "metric-overload:s@" => { name => 'metric_overload' }, - }); + $options{options}->add_options(arguments => { + "deployment:s" => { name => 'deployment', default => 'deployment=~".*"' }, + "warning-status:s" => { name => 'warning_status', default => '%{up_to_date} < %{desired}' }, + "critical-status:s" => { name => 'critical_status', default => '%{available} < %{desired}' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); return $self; } @@ -153,21 +167,25 @@ sub manage_selection { $self->{deployments} = {}; - my $results = $options{custom}->query(queries => [ 'label_replace({__name__=~"' . $self->{metrics}->{desired} . '",' . - $self->{option_results}->{deployment} . - $self->{extra_filter} . '}, "__name__", "desired", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{current} . '",' . - $self->{option_results}->{deployment} . - $self->{extra_filter} . '}, "__name__", "current", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{available} . '",' . - $self->{option_results}->{deployment} . - $self->{extra_filter} . '}, "__name__", "available", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{unavailable} . '",' . - $self->{option_results}->{deployment} . - $self->{extra_filter} . '}, "__name__", "unavailable", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{up_to_date} . '",' . - $self->{option_results}->{deployment} . - $self->{extra_filter} . '}, "__name__", "up_to_date", "", "")' ]); + my $results = $options{custom}->query( + queries => [ + 'label_replace({__name__=~"' . $self->{metrics}->{desired} . '",' . + $self->{option_results}->{deployment} . + $self->{extra_filter} . '}, "__name__", "desired", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{current} . '",' . + $self->{option_results}->{deployment} . + $self->{extra_filter} . '}, "__name__", "current", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{available} . '",' . + $self->{option_results}->{deployment} . + $self->{extra_filter} . '}, "__name__", "available", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{unavailable} . '",' . + $self->{option_results}->{deployment} . + $self->{extra_filter} . '}, "__name__", "unavailable", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{up_to_date} . '",' . + $self->{option_results}->{deployment} . + $self->{extra_filter} . '}, "__name__", "up_to_date", "", "")' + ] + ); foreach my $result (@{$results}) { $self->{deployments}->{$result->{metric}->{$self->{labels}->{deployment}}}->{display} = $result->{metric}->{$self->{labels}->{deployment}}; diff --git a/cloud/prometheus/direct/kubernetes/mode/namespacestatus.pm b/cloud/prometheus/direct/kubernetes/mode/namespacestatus.pm index def61001d..a156c7fad 100644 --- a/cloud/prometheus/direct/kubernetes/mode/namespacestatus.pm +++ b/cloud/prometheus/direct/kubernetes/mode/namespacestatus.pm @@ -46,11 +46,12 @@ sub set_counters { $self->{maps_counters_type} = [ { name => 'global', type => 0, cb_init => 'skip_global', cb_prefix_output => 'prefix_global_output' }, - { name => 'namespaces', type => 1, cb_prefix_output => 'prefix_namespace_output', message_multiple => 'All namespaces status are ok', skipped_code => { -11 => 1 } }, + { name => 'namespaces', type => 1, cb_prefix_output => 'prefix_namespace_output', + message_multiple => 'All namespaces status are ok', skipped_code => { -11 => 1 } }, ]; $self->{maps_counters}->{global} = [ - { label => 'active', set => { + { label => 'active', nlabel => 'namespaces.active.count', set => { key_values => [ { name => 'active' } ], output_template => 'Active : %d', perfdatas => [ @@ -59,7 +60,7 @@ sub set_counters { ], } }, - { label => 'terminating', set => { + { label => 'terminating', nlabel => 'namespaces.terminating.count', set => { key_values => [ { name => 'terminating' } ], output_template => 'Terminating : %d', perfdatas => [ @@ -105,15 +106,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "namespace:s" => { name => 'namespace', default => 'namespace=~".*"' }, - "phase:s" => { name => 'phase', default => 'phase=~".*"' }, - "warning-status:s" => { name => 'warning_status' }, - "critical-status:s" => { name => 'critical_status', default => '%{phase} !~ /Active/' }, - "extra-filter:s@" => { name => 'extra_filter' }, - "metric-overload:s@" => { name => 'metric_overload' }, - }); + $options{options}->add_options(arguments => { + "namespace:s" => { name => 'namespace', default => 'namespace=~".*"' }, + "phase:s" => { name => 'phase', default => 'phase=~".*"' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status', default => '%{phase} !~ /Active/' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); return $self; } @@ -153,9 +153,13 @@ sub manage_selection { $self->{global} = { active => 0, terminating => 0 }; $self->{namespaces} = {}; - my $results = $options{custom}->query(queries => [ '{__name__=~"' . $self->{metrics}->{status} . '",' . - $self->{option_results}->{namespace} . - $self->{extra_filter} . '}' ]); + my $results = $options{custom}->query( + queries => [ + '{__name__=~"' . $self->{metrics}->{status} . '",' . + $self->{option_results}->{namespace} . + $self->{extra_filter} . '}' + ] + ); foreach my $result (@{$results}) { $self->{namespaces}->{$result->{metric}->{$self->{labels}->{namespace}}}->{display} = $result->{metric}->{$self->{labels}->{namespace}}; diff --git a/cloud/prometheus/direct/kubernetes/mode/nodestatus.pm b/cloud/prometheus/direct/kubernetes/mode/nodestatus.pm index 974b2379f..46e580ac5 100644 --- a/cloud/prometheus/direct/kubernetes/mode/nodestatus.pm +++ b/cloud/prometheus/direct/kubernetes/mode/nodestatus.pm @@ -49,19 +49,22 @@ sub custom_usage_perfdata { my $label = 'allocated_pods'; my $value_perf = $self->{result_values}->{allocated}; - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); if ($self->{instance_mode}->{option_results}->{units} eq '%') { - $total_options{total} = $self->{result_values}->{capacity}; + $total_options{total} = $self->{result_values}->{allocatable}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{capacity}); + $self->{output}->perfdata_add( + label => $label, + nlabel => 'pods.allocated.count', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{allocatable}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); } sub custom_usage_threshold { @@ -72,16 +75,21 @@ sub custom_usage_threshold { if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_allocated}; } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, - { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check( + value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ] + ); return $exit; } sub custom_usage_output { my ($self, %options) = @_; - my $msg = sprintf("Pods Allocation Capacity : %s, Allocated : %s (%.2f%%)", - $self->{result_values}->{capacity}, $self->{result_values}->{allocated}, $self->{result_values}->{prct_allocated}); + my $msg = sprintf("Pods Capacity: %s, Allocatable: %s, Allocated: %s (%.2f%%)", + $self->{result_values}->{capacity}, + $self->{result_values}->{allocatable}, + $self->{result_values}->{allocated}, + $self->{result_values}->{prct_allocated}); return $msg; } @@ -91,19 +99,18 @@ sub custom_usage_calc { $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; $self->{result_values}->{capacity} = $options{new_datas}->{$self->{instance} . '_capacity'}; $self->{result_values}->{allocatable} = $options{new_datas}->{$self->{instance} . '_allocatable'}; - $self->{result_values}->{allocated} = $self->{result_values}->{capacity} - $self->{result_values}->{allocatable}; - $self->{result_values}->{prct_allocated} = ($self->{result_values}->{capacity} > 0) ? $self->{result_values}->{allocated} * 100 / $self->{result_values}->{capacity} : 0; + $self->{result_values}->{allocated} = $options{new_datas}->{$self->{instance} . '_allocated'}; + $self->{result_values}->{prct_allocated} = ($self->{result_values}->{allocatable} > 0) ? $self->{result_values}->{allocated} * 100 / $self->{result_values}->{allocatable} : 0; return 0; } - sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'nodes', type => 1, cb_prefix_output => 'prefix_node_output', message_multiple => 'All nodes status are ok', - message_separator => ' - ', skipped_code => { -11 => 1 } }, + { name => 'nodes', type => 1, cb_prefix_output => 'prefix_node_output', + message_multiple => 'All nodes status are ok', message_separator => ' - ', skipped_code => { -11 => 1 } }, ]; $self->{maps_counters}->{nodes} = [ @@ -116,7 +123,8 @@ sub set_counters { } }, { label => 'allocated-pods', set => { - key_values => [ { name => 'capacity' }, { name => 'allocatable' }, { name => 'display' } ], + key_values => [ { name => 'capacity' }, { name => 'allocatable' }, { name => 'allocated' }, + { name => 'display' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_output => $self->can('custom_usage_output'), closure_custom_perfdata => $self->can('custom_usage_perfdata'), @@ -138,15 +146,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "node:s" => { name => 'node', default => 'node=~".*"' }, - "warning-status:s" => { name => 'warning_status' }, - "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /Ready/ || %{schedulable} =~ /false/' }, - "extra-filter:s@" => { name => 'extra_filter' }, - "metric-overload:s@" => { name => 'metric_overload' }, - "units:s" => { name => 'units', default => '' }, - }); + $options{options}->add_options(arguments => { + "node:s" => { name => 'node', default => 'node=~".*"' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /Ready/ || %{schedulable} =~ /false/' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "metric-overload:s@" => { name => 'metric_overload' }, + "units:s" => { name => 'units', default => '' }, + }); return $self; } @@ -160,6 +167,7 @@ sub check_options { 'unschedulable' => '^kube_node_spec_unschedulable$', 'capacity' => '^kube_node_status_capacity_pods$', 'allocatable' => '^kube_node_status_allocatable_pods$', + 'allocated' => '^kubelet_running_pod_count$', }; foreach my $metric (@{$self->{option_results}->{metric_overload}}) { next if ($metric !~ /(.*),(.*)/); @@ -188,19 +196,26 @@ sub manage_selection { $self->{nodes} = {}; - my $results = $options{custom}->query(queries => [ 'label_replace({__name__=~"' . $self->{metrics}->{status} . '",' . - $self->{option_results}->{node} . ',' . - 'status="true"' . - $self->{extra_filter} . '}, "__name__", "status", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{unschedulable} . '",' . - $self->{option_results}->{node} . - $self->{extra_filter} . '}, "__name__", "unschedulable", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{capacity} . '",' . - $self->{option_results}->{node} . - $self->{extra_filter} . '}, "__name__", "capacity", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{allocatable} . '",' . - $self->{option_results}->{node} . - $self->{extra_filter} . '}, "__name__", "allocatable", "", "")' ]); + my $results = $options{custom}->query( + queries => [ + 'label_replace({__name__=~"' . $self->{metrics}->{status} . '",' . + $self->{option_results}->{node} . ',' . + 'status="true"' . + $self->{extra_filter} . '}, "__name__", "status", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{unschedulable} . '",' . + $self->{option_results}->{node} . + $self->{extra_filter} . '}, "__name__", "unschedulable", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{capacity} . '",' . + $self->{option_results}->{node} . + $self->{extra_filter} . '}, "__name__", "capacity", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{allocatable} . '",' . + $self->{option_results}->{node} . + $self->{extra_filter} . '}, "__name__", "allocatable", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{allocated} . '",' . + $self->{option_results}->{node} . + $self->{extra_filter} . '}, "__name__", "allocated", "", "")' + ] + ); foreach my $result (@{$results}) { $self->{nodes}->{$result->{metric}->{$self->{labels}->{node}}}->{display} = $result->{metric}->{$self->{labels}->{node}}; @@ -268,6 +283,7 @@ Default : - unschedulable: ^kube_node_spec_unschedulable$ - capacity: ^kube_node_status_capacity_pods$ - allocatable: ^kube_node_status_allocatable_pods$ + - allocated: ^kubelet_running_pod_count$ =item B<--filter-counters> diff --git a/cloud/prometheus/direct/nginxingresscontroller/mode/connections.pm b/cloud/prometheus/direct/nginxingresscontroller/mode/connections.pm new file mode 100644 index 000000000..344675232 --- /dev/null +++ b/cloud/prometheus/direct/nginxingresscontroller/mode/connections.pm @@ -0,0 +1,198 @@ +# +# Copyright 2019 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 cloud::prometheus::direct::nginxingresscontroller::mode::connections; + +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, cb_prefix_output => 'prefix_containers_output' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'reading', nlabel => 'connections.reading.count', set => { + key_values => [ { name => 'reading' } ], + output_template => 'Reading: %d', + perfdatas => [ + { label => 'reading', value => 'reading_absolute', template => '%d', + min => 0, unit => 'connections' }, + ], + } + }, + { label => 'waiting', nlabel => 'connections.waiting.count', set => { + key_values => [ { name => 'waiting' } ], + output_template => 'Waiting: %d', + perfdatas => [ + { label => 'waiting', value => 'waiting_absolute', template => '%d', + min => 0, unit => 'connections' }, + ], + } + }, + { label => 'writing', nlabel => 'connections.writing.count', set => { + key_values => [ { name => 'writing' } ], + output_template => 'Writing: %d', + perfdatas => [ + { label => 'writing', value => 'writing_absolute', template => '%d', + min => 0, unit => 'connections' }, + ], + } + }, + { label => 'active', nlabel => 'connections.active.count', set => { + key_values => [ { name => 'active' } ], + output_template => 'Active: %d', + perfdatas => [ + { label => 'active', value => 'active_absolute', template => '%d', + min => 0, unit => 'connections' }, + ], + } + }, + { label => 'accepted', nlabel => 'connections.accepted.persecond', set => { + key_values => [ { name => 'accepted', diff => 1 } ], + output_template => 'Accepted: %.2f/s', + per_second => 1, + perfdatas => [ + { label => 'accepted', value => 'accepted_per_second', template => '%.2f', + min => 0, unit => 'connections/s' }, + ], + } + }, + { label => 'handled', nlabel => 'connections.handled.persecond', set => { + key_values => [ { name => 'handled', diff => 1 } ], + output_template => 'Handled: %.2f/s', + per_second => 1, + perfdatas => [ + { label => 'handled', value => 'handled_per_second', template => '%.2f', + min => 0, unit => 'connections/s' }, + ], + } + }, + ]; +} + +sub prefix_containers_output { + my ($self, %options) = @_; + + return "Connections "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "extra-filter:s@" => { name => 'extra_filter' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->{metrics} = { + 'connections' => '^nginx_ingress_controller_nginx_process_connections$', + 'connections_total' => '^nginx_ingress_controller_nginx_process_connections_total$', + }; + foreach my $metric (@{$self->{option_results}->{metric_overload}}) { + next if ($metric !~ /(.*),(.*)/); + $self->{metrics}->{$1} = $2 if (defined($self->{metrics}->{$1})); + } + + $self->{extra_filter} = ''; + foreach my $filter (@{$self->{option_results}->{extra_filter}}) { + $self->{extra_filter} .= ',' . $filter; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{cache_name} = "prometheus_nginxingresscontroller_" . md5_hex($options{custom}->get_connection_info()) . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + $self->{global} = {}; + + my $results = $options{custom}->query( + queries => [ + 'label_replace({__name__=~"' . $self->{metrics}->{connections} . '",' . + $self->{extra_filter} . '}, "__name__", "connections", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{connections_total} . '",' . + $self->{extra_filter} . '}, "__name__", "connections_total", "", "")' + ] + ); + + foreach my $result (@{$results}) { + $self->{global}->{$result->{metric}->{state}} = ${$result->{value}}[1]; + } +} + +1; + +__END__ + +=head1 MODE + +Check connections number. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'reading', 'waiting', 'writing', 'active', +'accepted', 'handled'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'reading', 'waiting', 'writing', 'active', +'accepted', 'handled'. + +=item B<--extra-filter> + +Add a PromQL filter (Can be multiple) + +Example : --extra-filter='name=~".*pretty.*"' + +=item B<--metric-overload> + +Overload default metrics name (Can be multiple) + +Example : --metric-overload='metric,^my_metric_name$' + +Default : + + - connections: ^nginx_ingress_controller_nginx_process_connections$ + - connections_total: ^nginx_ingress_controller_nginx_process_connections_total$ + +=back + +=cut diff --git a/cloud/prometheus/direct/nginxingresscontroller/mode/requests.pm b/cloud/prometheus/direct/nginxingresscontroller/mode/requests.pm new file mode 100644 index 000000000..ac6814de8 --- /dev/null +++ b/cloud/prometheus/direct/nginxingresscontroller/mode/requests.pm @@ -0,0 +1,207 @@ +# +# Copyright 2019 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 cloud::prometheus::direct::nginxingresscontroller::mode::requests; + +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 }, + { name => 'namespaces', type => 1, cb_prefix_output => 'prefix_namespaces_output', + message_multiple => 'All namespaces request metrics are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'requests', nlabel => 'requests.total.persecond', set => { + key_values => [ { name => 'requests', diff => 1 } ], + output_template => 'Requests: %.2f/s', + per_second => 1, + perfdatas => [ + { label => 'requests', value => 'requests_per_second', template => '%.2f', + min => 0, unit => 'requests/s' }, + ], + } + }, + ]; + $self->{maps_counters}->{namespaces} = [ + { label => 'requests-2xx', nlabel => 'namespace.requests.2xx.persecond', set => { + key_values => [ { name => 'requests_2xx', diff => 1 } ], + output_template => 'Requests 2xx: %.2f/s', + per_second => 1, + perfdatas => [ + { label => 'requests_2xx', value => 'requests_2xx_per_second', template => '%.2f', unit => 'requests/s', + min => 0, label_extra_instance => 1 }, + ], + } + }, + { label => 'requests-3xx', nlabel => 'namespace.requests.2xx.persecond', set => { + key_values => [ { name => 'requests_3xx', diff => 1 } ], + output_template => 'Requests 3xx: %.2f/s', + per_second => 1, + perfdatas => [ + { label => 'requests_3xx', value => 'requests_3xx_per_second', template => '%.2f', unit => 'requests/s', + min => 0, label_extra_instance => 1 }, + ], + } + }, + { label => 'requests-4xx', nlabel => 'namespace.requests.4xx.persecond', set => { + key_values => [ { name => 'requests_4xx', diff => 1 } ], + output_template => 'Requests 4xx: %.2f/s', + per_second => 1, + perfdatas => [ + { label => 'requests_4xx', value => 'requests_4xx_per_second', template => '%.2f', unit => 'requests/s', + min => 0, label_extra_instance => 1 }, + ], + } + }, + { label => 'requests-5xx', nlabel => 'namespace.requests.5xx.persecond', set => { + key_values => [ { name => 'requests_5xx', diff => 1 } ], + output_template => 'Requests 5xx: %.2f/s', + per_second => 1, + perfdatas => [ + { label => 'requests_5xx', value => 'requests_5xx_per_second', template => '%.2f', unit => 'requests/s', + min => 0, label_extra_instance => 1 }, + ], + } + }, + ]; +} + +sub prefix_namespaces_output { + my ($self, %options) = @_; + + return "Namespace '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "extra-filter:s@" => { name => 'extra_filter' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->{metrics} = { + 'requests_total' => '^nginx_ingress_controller_nginx_process_requests_total$', + 'requests' => '^nginx_ingress_controller_requests$', + }; + foreach my $metric (@{$self->{option_results}->{metric_overload}}) { + next if ($metric !~ /(.*),(.*)/); + $self->{metrics}->{$1} = $2 if (defined($self->{metrics}->{$1})); + } + + $self->{extra_filter} = ''; + foreach my $filter (@{$self->{option_results}->{extra_filter}}) { + $self->{extra_filter} .= ',' . $filter; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{cache_name} = "prometheus_nginxingresscontroller_" . md5_hex($options{custom}->get_connection_info()) . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + $self->{global} = {}; + + my $results = $options{custom}->query( + queries => [ + 'label_replace({__name__=~"' . $self->{metrics}->{requests_total} . '",' . + $self->{extra_filter} . '}, "__name__", "requests_total", "", "")' + ] + ); + + foreach my $result (@{$results}) { + $self->{global}->{requests} = ${$result->{value}}[1]; + } + + $self->{namespaces} = {}; + + $results = $options{custom}->query(queries => [ 'label_replace({__name__=~"' . $self->{metrics}->{requests} . '",' . + $self->{extra_filter} . '}, "__name__", "requests", "", "")' ]); + + foreach my $result (@{$results}) { + $self->{namespaces}->{$result->{metric}->{exported_namespace}}->{display} = $result->{metric}->{exported_namespace}; + $self->{namespaces}->{$result->{metric}->{exported_namespace}}->{requests_2xx} += ${$result->{value}}[1] if ($result->{metric}->{status} =~ /^2/); + $self->{namespaces}->{$result->{metric}->{exported_namespace}}->{requests_3xx} += ${$result->{value}}[1] if ($result->{metric}->{status} =~ /^3/); + $self->{namespaces}->{$result->{metric}->{exported_namespace}}->{requests_4xx} += ${$result->{value}}[1] if ($result->{metric}->{status} =~ /^4/); + $self->{namespaces}->{$result->{metric}->{exported_namespace}}->{requests_5xx} += ${$result->{value}}[1] if ($result->{metric}->{status} =~ /^5/); + } +} + +1; + +__END__ + +=head1 MODE + +Check requests number. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'requests', 'requests-2xx', 'requests-3xx', +'requests-4xx', 'requests-5xx'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'requests', 'requests-2xx', 'requests-3xx', +'requests-4xx', 'requests-5xx'. + +=item B<--extra-filter> + +Add a PromQL filter (Can be multiple) + +Example : --extra-filter='name=~".*pretty.*"' + +=item B<--metric-overload> + +Overload default metrics name (Can be multiple) + +Example : --metric-overload='metric,^my_metric_name$' + +Default : + + - requests_total: ^nginx_ingress_controller_nginx_process_requests_total$ + - requests: ^nginx_ingress_controller_requests$ + +=back + +=cut diff --git a/cloud/prometheus/direct/nginxingresscontroller/plugin.pm b/cloud/prometheus/direct/nginxingresscontroller/plugin.pm new file mode 100644 index 000000000..c65565c3d --- /dev/null +++ b/cloud/prometheus/direct/nginxingresscontroller/plugin.pm @@ -0,0 +1,56 @@ +# +# Copyright 2019 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 cloud::prometheus::direct::nginxingresscontroller::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'connections' => 'cloud::prometheus::direct::nginxingresscontroller::mode::connections', + 'requests' => 'cloud::prometheus::direct::nginxingresscontroller::mode::requests', + ); + + $self->{custom_modes}{api} = 'cloud::prometheus::restapi::custom::api'; + return $self; +} + +sub init { + my ( $self, %options ) = @_; + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Nginx Ingress Controller metrics through Prometheus server. + +=cut diff --git a/cloud/prometheus/exporters/cadvisor/mode/cpu.pm b/cloud/prometheus/exporters/cadvisor/mode/cpu.pm index 36a3ebbbc..517ca82e5 100644 --- a/cloud/prometheus/exporters/cadvisor/mode/cpu.pm +++ b/cloud/prometheus/exporters/cadvisor/mode/cpu.pm @@ -34,7 +34,7 @@ sub set_counters { ]; $self->{maps_counters}->{containers} = [ - { label => 'usage', set => { + { label => 'usage', nlabel => 'container.cpu.utilization.percentage', set => { key_values => [ { name => 'usage' }, { name => 'container' }, { name => 'pod' }, { name => 'perf' } ], output_template => 'Usage: %.2f %%', perfdatas => [ @@ -44,7 +44,7 @@ sub set_counters { ], } }, - { label => 'throttled', set => { + { label => 'throttled', nlabel => 'container.cpu.throttled.percentage', set => { key_values => [ { name => 'throttled' }, { name => 'container' }, { name => 'pod' }, { name => 'perf' } ], output_template => 'Throttled: %.2f %%', perfdatas => [ @@ -69,15 +69,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "cpu-attribute:s" => { name => 'cpu_attribute', default => 'cpu="total"' }, - "container:s" => { name => 'container', default => 'container_name!~".*POD.*"' }, - "pod:s" => { name => 'pod', default => 'pod_name=~".*"' }, - "extra-filter:s@" => { name => 'extra_filter' }, - "metric-overload:s@" => { name => 'metric_overload' }, - "filter-counters:s" => { name => 'filter_counters' }, - }); + $options{options}->add_options(arguments => { + "cpu-attribute:s" => { name => 'cpu_attribute', default => 'cpu="total"' }, + "container:s" => { name => 'container', default => 'container_name!~".*POD.*"' }, + "pod:s" => { name => 'pod', default => 'pod_name=~".*"' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); return $self; } @@ -118,16 +116,21 @@ sub manage_selection { $self->{containers} = {}; - my $results = $options{custom}->query_range(queries => [ 'label_replace((irate({__name__=~"' . $self->{metrics}->{usage} . '",' . - $self->{option_results}->{cpu_attribute} . ',' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}[' . $self->{prom_step} . '])) * 100, "__name__", "usage", "", "")', - 'label_replace((irate({__name__=~"' . $self->{metrics}->{throttled} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}[' . $self->{prom_step} . '])) * 100, "__name__", "throttled", "", "")' ], - timeframe => $self->{prom_timeframe}, step => $self->{prom_step}); + my $results = $options{custom}->query_range( + queries => [ + 'label_replace((irate({__name__=~"' . $self->{metrics}->{usage} . '",' . + $self->{option_results}->{cpu_attribute} . ',' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}[' . $self->{prom_step} . '])) * 100, "__name__", "usage", "", "")', + 'label_replace((irate({__name__=~"' . $self->{metrics}->{throttled} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}[' . $self->{prom_step} . '])) * 100, "__name__", "throttled", "", "")' + ], + timeframe => $self->{prom_timeframe}, + step => $self->{prom_step} + ); foreach my $result (@{$results}) { next if (!defined($result->{metric}->{$self->{labels}->{pod}}) || !defined($result->{metric}->{$self->{labels}->{container}})); diff --git a/cloud/prometheus/exporters/cadvisor/mode/load.pm b/cloud/prometheus/exporters/cadvisor/mode/load.pm index dc61230cf..522860d75 100644 --- a/cloud/prometheus/exporters/cadvisor/mode/load.pm +++ b/cloud/prometheus/exporters/cadvisor/mode/load.pm @@ -29,11 +29,12 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'containers', type => 1, cb_prefix_output => 'prefix_containers_output', message_multiple => 'All containers load are ok' }, + { name => 'containers', type => 1, cb_prefix_output => 'prefix_containers_output', + message_multiple => 'All containers load are ok' }, ]; $self->{maps_counters}->{containers} = [ - { label => 'load', set => { + { label => 'load', nlabel => 'container.load.count', set => { key_values => [ { name => 'load' }, { name => 'container' }, { name => 'pod' }, { name => 'perf' } ], output_template => 'Load: %.2f', output_change_bytes => 1, @@ -58,13 +59,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "container:s" => { name => 'container', default => 'container_name!~".*POD.*"' }, - "pod:s" => { name => 'pod', default => 'pod_name=~".*"' }, - "extra-filter:s@" => { name => 'extra_filter' }, - "metric-overload:s@" => { name => 'metric_overload' }, - }); + $options{options}->add_options(arguments => { + "container:s" => { name => 'container', default => 'container_name!~".*POD.*"' }, + "pod:s" => { name => 'pod', default => 'pod_name=~".*"' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); return $self; } @@ -74,7 +74,7 @@ sub check_options { $self->SUPER::check_options(%options); $self->{metrics} = { - 'load' => '^container_cpu_load_average_10s$', + 'load' => '^container_cpu_load_average_10s$', }; foreach my $metric (@{$self->{option_results}->{metric_overload}}) { next if ($metric !~ /(.*),(.*)/); @@ -104,11 +104,16 @@ sub manage_selection { $self->{containers} = {}; - my $results = $options{custom}->query_range(queries => [ 'label_replace({__name__=~"' . $self->{metrics}->{load} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}, "__name__", "load", "", "")' ], - timeframe => $self->{prom_timeframe}, step => $self->{prom_step}); + my $results = $options{custom}->query_range( + queries => [ + 'label_replace({__name__=~"' . $self->{metrics}->{load} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}, "__name__", "load", "", "")' + ], + timeframe => $self->{prom_timeframe}, + step => $self->{prom_step} + ); foreach my $result (@{$results}) { next if (!defined($result->{metric}->{$self->{labels}->{pod}}) || !defined($result->{metric}->{$self->{labels}->{container}})); diff --git a/cloud/prometheus/exporters/cadvisor/mode/memory.pm b/cloud/prometheus/exporters/cadvisor/mode/memory.pm index 37db624a6..a51e6e5bf 100644 --- a/cloud/prometheus/exporters/cadvisor/mode/memory.pm +++ b/cloud/prometheus/exporters/cadvisor/mode/memory.pm @@ -25,39 +25,41 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = $self->{result_values}->{perfdata}; my $value_perf = $self->{result_values}->{used}; - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{perf} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($self->{result_values}->{total} > 0 && $instance_mode->{option_results}->{units} eq '%') { + if ($self->{result_values}->{total} > 0 && $self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{label}, %total_options), - min => 0, max => $total_options{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + nlabel => 'memory.' . $label . '.bytes', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); } sub custom_usage_threshold { my ($self, %options) = @_; - return 'ok' if ($self->{result_values}->{total} <= 0 && $instance_mode->{option_results}->{units} eq '%'); + return 'ok' if ($self->{result_values}->{total} <= 0 && $self->{instance_mode}->{option_results}->{units} eq '%'); my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{result_values}->{label}, exit_litteral => 'critical' }, - { label => 'warning-'. $self->{result_values}->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, + threshold => [ { label => 'critical-' . $self->{result_values}->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{result_values}->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -99,7 +101,8 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'containers', type => 1, cb_prefix_output => 'prefix_containers_output', message_multiple => 'All containers memory usage are ok' }, + { name => 'containers', type => 1, cb_prefix_output => 'prefix_containers_output', + message_multiple => 'All containers memory usage are ok' }, ]; $self->{maps_counters}->{containers} = [ @@ -123,7 +126,7 @@ sub set_counters { closure_custom_threshold_check => $self->can('custom_usage_threshold'), } }, - { label => 'cache', set => { + { label => 'cache', nlabel => 'cache.usage.bytes', set => { key_values => [ { name => 'cache' }, { name => 'container' }, { name => 'pod' }, { name => 'perf' } ], output_template => 'Cache: %.2f %s', output_change_bytes => 1, @@ -133,7 +136,7 @@ sub set_counters { ], } }, - { label => 'rss', set => { + { label => 'rss', nlabel => 'rss.usage.bytes', set => { key_values => [ { name => 'rss' }, { name => 'container' }, { name => 'pod' }, { name => 'perf' } ], output_template => 'Rss: %.2f %s', output_change_bytes => 1, @@ -143,7 +146,7 @@ sub set_counters { ], } }, - { label => 'swap', set => { + { label => 'swap', nlabel => 'swap.usage.bytes', set => { key_values => [ { name => 'swap' }, { name => 'container' }, { name => 'pod' }, { name => 'perf' } ], output_template => 'Swap: %.2f %s', output_change_bytes => 1, @@ -168,16 +171,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "container:s" => { name => 'container', default => 'container_name!~".*POD.*"' }, - "pod:s" => { name => 'pod', default => 'pod_name=~".*"' }, - "extra-filter:s@" => { name => 'extra_filter' }, - "units:s" => { name => 'units', default => '%' }, - "metric-overload:s@" => { name => 'metric_overload' }, - "filter-counters:s" => { name => 'filter_counters' }, - }); - + $options{options}->add_options(arguments => { + "container:s" => { name => 'container', default => 'container_name!~".*POD.*"' }, + "pod:s" => { name => 'pod', default => 'pod_name=~".*"' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "units:s" => { name => 'units', default => '%' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); + return $self; } @@ -210,9 +211,7 @@ sub check_options { $self->{extra_filter} = ''; foreach my $filter (@{$self->{option_results}->{extra_filter}}) { $self->{extra_filter} .= ',' . $filter; - } - - $instance_mode = $self; + } } sub manage_selection { @@ -220,30 +219,34 @@ sub manage_selection { $self->{containers} = {}; - my $results = $options{custom}->query(queries => [ 'label_replace({__name__=~"' . $self->{metrics}->{usage} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}, "__name__", "usage", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{limits} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}, "__name__", "limits", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{working} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}, "__name__", "working", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{cache} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}, "__name__", "cache", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{rss} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}, "__name__", "rss", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{swap} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . - $self->{extra_filter} . '}, "__name__", "swap", "", "")' ]); + my $results = $options{custom}->query( + queries => [ + 'label_replace({__name__=~"' . $self->{metrics}->{usage} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}, "__name__", "usage", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{limits} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}, "__name__", "limits", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{working} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}, "__name__", "working", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{cache} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}, "__name__", "cache", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{rss} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}, "__name__", "rss", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{swap} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . + $self->{extra_filter} . '}, "__name__", "swap", "", "")' + ] + ); foreach my $result (@{$results}) { next if (!defined($result->{metric}->{$self->{labels}->{pod}}) || !defined($result->{metric}->{$self->{labels}->{container}})); diff --git a/cloud/prometheus/exporters/cadvisor/mode/storage.pm b/cloud/prometheus/exporters/cadvisor/mode/storage.pm index 8262ce412..da298a175 100644 --- a/cloud/prometheus/exporters/cadvisor/mode/storage.pm +++ b/cloud/prometheus/exporters/cadvisor/mode/storage.pm @@ -25,30 +25,31 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{label} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + nlabel => 'storage.space.usage.bytes', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); } sub custom_usage_threshold { @@ -56,12 +57,14 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -115,7 +118,7 @@ sub set_counters { $self->{maps_counters}->{storage} = [ { label => 'usage', set => { - key_values => [ { name => 'used' }, { name => 'limit' }, { name => 'container' }, { name => 'pod' } ], + key_values => [ { name => 'used' }, { name => 'limit' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_output => $self->can('custom_usage_output'), closure_custom_perfdata => $self->can('custom_usage_perfdata'), @@ -128,7 +131,7 @@ sub set_counters { sub prefix_container_output { my ($self, %options) = @_; - return "Container '" . $options{instance_value}->{display} . "' "; + return "Container '" . $options{instance_value}->{container} . "' [pod: " . $options{instance_value}->{pod} . "] "; } sub long_output { @@ -149,17 +152,16 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "container:s" => { name => 'container', default => 'container_name!~".*POD.*"' }, - "pod:s" => { name => 'pod', default => 'pod_name=~".*"' }, - "device:s" => { name => 'device', default => 'device=~".*"' }, - "extra-filter:s@" => { name => 'extra_filter' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - "metric-overload:s@" => { name => 'metric_overload' }, - }); - + $options{options}->add_options(arguments => { + "container:s" => { name => 'container', default => 'container_name!~".*POD.*"' }, + "pod:s" => { name => 'pod', default => 'pod_name=~".*"' }, + "device:s" => { name => 'device', default => 'device=~".*"' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); + return $self; } @@ -188,9 +190,7 @@ sub check_options { $self->{extra_filter} = ''; foreach my $filter (@{$self->{option_results}->{extra_filter}}) { $self->{extra_filter} .= ',' . $filter; - } - - $instance_mode = $self; + } } sub manage_selection { @@ -198,23 +198,27 @@ sub manage_selection { $self->{containers} = {}; - my $results = $options{custom}->query(queries => [ 'label_replace({__name__=~"' . $self->{metrics}->{used} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . ',' . - $self->{option_results}->{device} . - $self->{extra_filter} . '}, "__name__", "used", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{limit} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . ',' . - $self->{option_results}->{device} . - $self->{extra_filter} . '}, "__name__", "limit", "", "")' ]); + my $results = $options{custom}->query( + queries => [ + 'label_replace({__name__=~"' . $self->{metrics}->{used} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . ',' . + $self->{option_results}->{device} . + $self->{extra_filter} . '}, "__name__", "used", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{limit} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . ',' . + $self->{option_results}->{device} . + $self->{extra_filter} . '}, "__name__", "limit", "", "")' + ] + ); foreach my $result (@{$results}) { next if (!defined($result->{metric}->{$self->{labels}->{pod}}) || !defined($result->{metric}->{$self->{labels}->{container}})); $self->{containers}->{$result->{metric}->{$self->{labels}->{pod}} . "_" . $result->{metric}->{$self->{labels}->{container}}}->{display} = $result->{metric}->{$self->{labels}->{pod}} . "_" . $result->{metric}->{$self->{labels}->{container}}; - $self->{containers}->{$result->{metric}->{$self->{labels}->{pod}} . "_" . $result->{metric}->{$self->{labels}->{container}}}->{storage}->{$result->{metric}->{$self->{labels}->{device}}}->{container} = $result->{metric}->{$self->{labels}->{container}}; - $self->{containers}->{$result->{metric}->{$self->{labels}->{pod}} . "_" . $result->{metric}->{$self->{labels}->{container}}}->{storage}->{$result->{metric}->{$self->{labels}->{device}}}->{pod} = $result->{metric}->{$self->{labels}->{pod}}; - $self->{containers}->{$result->{metric}->{$self->{labels}->{pod}} . "_" . $result->{metric}->{$self->{labels}->{container}}}->{storage}->{$result->{metric}->{$self->{labels}->{device}}}->{device} = $result->{metric}->{$self->{labels}->{device}}; + $self->{containers}->{$result->{metric}->{$self->{labels}->{pod}} . "_" . $result->{metric}->{$self->{labels}->{container}}}->{container} = $result->{metric}->{$self->{labels}->{container}}; + $self->{containers}->{$result->{metric}->{$self->{labels}->{pod}} . "_" . $result->{metric}->{$self->{labels}->{container}}}->{pod} = $result->{metric}->{$self->{labels}->{pod}}; + $self->{containers}->{$result->{metric}->{$self->{labels}->{pod}} . "_" . $result->{metric}->{$self->{labels}->{container}}}->{storage}->{$result->{metric}->{$self->{labels}->{device}}}->{display} = $result->{metric}->{$self->{labels}->{device}}; $self->{containers}->{$result->{metric}->{$self->{labels}->{pod}} . "_" . $result->{metric}->{$self->{labels}->{container}}}->{storage}->{$result->{metric}->{$self->{labels}->{device}}}->{$result->{metric}->{__name__}} = ${$result->{value}}[1]; } diff --git a/cloud/prometheus/exporters/cadvisor/mode/taskstate.pm b/cloud/prometheus/exporters/cadvisor/mode/taskstate.pm index a25b682ae..a72acf48a 100644 --- a/cloud/prometheus/exporters/cadvisor/mode/taskstate.pm +++ b/cloud/prometheus/exporters/cadvisor/mode/taskstate.pm @@ -30,11 +30,11 @@ sub set_counters { $self->{maps_counters_type} = [ { name => 'containers', type => 1, cb_prefix_output => 'prefix_containers_output', - message_multiple => 'All containers tasks states are ok', skipped_code => { -10 => 1 } }, + message_multiple => 'All containers tasks states are ok', skipped_code => { -10 => 1 } }, ]; $self->{maps_counters}->{containers} = [ - { label => 'sleeping', set => { + { label => 'sleeping', nlabel => 'tasks.sleeping.count', set => { key_values => [ { name => 'sleeping' }, { name => 'container' }, { name => 'pod' }, { name => 'perf' } ], output_template => 'Sleeping: %d', output_change_bytes => 1, @@ -44,7 +44,7 @@ sub set_counters { ], } }, - { label => 'running', set => { + { label => 'running', nlabel => 'tasks.running.count', set => { key_values => [ { name => 'running' }, { name => 'container' }, { name => 'pod' }, { name => 'perf' } ], output_template => 'Running: %d', output_change_bytes => 1, @@ -54,7 +54,7 @@ sub set_counters { ], } }, - { label => 'stopped', set => { + { label => 'stopped', nlabel => 'tasks.stopped.count', set => { key_values => [ { name => 'stopped' }, { name => 'container' }, { name => 'pod' }, { name => 'perf' } ], output_template => 'Stopped: %d', output_change_bytes => 1, @@ -64,7 +64,7 @@ sub set_counters { ], } }, - { label => 'uninterruptible', set => { + { label => 'uninterruptible', nlabel => 'tasks.uninterruptible.count', set => { key_values => [ { name => 'uninterruptible' }, { name => 'container' }, { name => 'pod' }, { name => 'perf' } ], output_template => 'Uninterruptible: %d', output_change_bytes => 1, @@ -74,7 +74,7 @@ sub set_counters { ], } }, - { label => 'iowaiting', set => { + { label => 'iowaiting', nlabel => 'tasks.iowaiting.count', set => { key_values => [ { name => 'iowaiting' }, { name => 'container' }, { name => 'pod' }, { name => 'perf' } ], output_template => 'Iowaiting: %d', output_change_bytes => 1, @@ -99,14 +99,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "container:s" => { name => 'container', default => 'container_name!~".*POD.*"' }, - "pod:s" => { name => 'pod', default => 'pod_name=~".*"' }, - "state:s" => { name => 'state', default => 'state=~".*"' }, - "extra-filter:s@" => { name => 'extra_filter' }, - "metric-overload:s@" => { name => 'metric_overload' }, - }); + $options{options}->add_options(arguments => { + "container:s" => { name => 'container', default => 'container_name!~".*POD.*"' }, + "pod:s" => { name => 'pod', default => 'pod_name=~".*"' }, + "state:s" => { name => 'state', default => 'state=~".*"' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); return $self; } @@ -143,11 +142,15 @@ sub manage_selection { $self->{containers} = {}; - my $results = $options{custom}->query(queries => [ 'label_replace({__name__=~"' . $self->{metrics}->{tasks_state} . '",' . - $self->{option_results}->{container} . ',' . - $self->{option_results}->{pod} . ',' . - $self->{option_results}->{state} . - $self->{extra_filter} . '}, "__name__", "tasks_state", "", "")' ]); + my $results = $options{custom}->query( + queries => [ + 'label_replace({__name__=~"' . $self->{metrics}->{tasks_state} . '",' . + $self->{option_results}->{container} . ',' . + $self->{option_results}->{pod} . ',' . + $self->{option_results}->{state} . + $self->{extra_filter} . '}, "__name__", "tasks_state", "", "")' + ] + ); foreach my $result (@{$results}) { next if (!defined($result->{metric}->{$self->{labels}->{pod}}) || !defined($result->{metric}->{$self->{labels}->{container}})); diff --git a/cloud/prometheus/exporters/nodeexporter/mode/cpu.pm b/cloud/prometheus/exporters/nodeexporter/mode/cpu.pm index e19e697f3..9a07f38d1 100644 --- a/cloud/prometheus/exporters/nodeexporter/mode/cpu.pm +++ b/cloud/prometheus/exporters/nodeexporter/mode/cpu.pm @@ -40,7 +40,7 @@ sub set_counters { ]; $self->{maps_counters}->{global_cpu} = [ - { label => 'node-usage', set => { + { label => 'node-usage', nlabel => 'node.cpu.utilization.percentage', set => { key_values => [ { name => 'node_average' } ], output_template => '%.2f %%', perfdatas => [ @@ -51,7 +51,7 @@ sub set_counters { }, ]; $self->{maps_counters}->{cpu} = [ - { label => 'cpu-usage', set => { + { label => 'cpu-usage', nlabel => 'core.cpu.utilization.percentage', set => { key_values => [ { name => 'cpu_usage' }, { name => 'display' } ], output_template => 'Usage: %.2f %%', perfdatas => [ @@ -93,14 +93,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "instance:s" => { name => 'instance', default => 'instance=~".*"' }, - "cpu:s" => { name => 'cpu', default => 'cpu=~".*"' }, - "extra-filter:s@" => { name => 'extra_filter' }, - "metric-overload:s@" => { name => 'metric_overload' }, - "filter-counters:s" => { name => 'filter_counters' }, - }); + $options{options}->add_options(arguments => { + "instance:s" => { name => 'instance', default => 'instance=~".*"' }, + "cpu:s" => { name => 'cpu', default => 'cpu=~".*"' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); return $self; } @@ -140,12 +138,16 @@ sub manage_selection { $self->{nodes} = {}; - my $results = $options{custom}->query_range(queries => [ '(1 - irate({__name__=~"' . $self->{metrics}->{cpu} . '",' . - 'mode="idle",' . - $self->{option_results}->{instance} . ',' . - $self->{option_results}->{cpu} . - $self->{extra_filter} . '}[' . $self->{prom_step} . '])) * 100' ], - timeframe => $self->{prom_timeframe}, step => $self->{prom_step}); + my $results = $options{custom}->query_range( + queries => [ + '(1 - irate({__name__=~"' . $self->{metrics}->{cpu} . '",' . + 'mode="idle",' . + $self->{option_results}->{instance} . ',' . + $self->{option_results}->{cpu} . + $self->{extra_filter} . '}[' . $self->{prom_step} . '])) * 100' + ], + timeframe => $self->{prom_timeframe}, step => $self->{prom_step} + ); foreach my $result (@{$results}) { my $average = $options{custom}->compute(aggregation => 'average', values => $result->{values}); diff --git a/cloud/prometheus/exporters/nodeexporter/mode/cpudetailed.pm b/cloud/prometheus/exporters/nodeexporter/mode/cpudetailed.pm index e9780c20e..6b4097ce2 100644 --- a/cloud/prometheus/exporters/nodeexporter/mode/cpudetailed.pm +++ b/cloud/prometheus/exporters/nodeexporter/mode/cpudetailed.pm @@ -40,7 +40,7 @@ sub set_counters { ]; $self->{maps_counters}->{global_cpu} = [ - { label => 'node-wait', set => { + { label => 'node-wait', nlabel => 'node.cpu.wait.utilization.percentage', set => { key_values => [ { name => 'iowait' } ], output_template => 'Wait: %.2f %%', perfdatas => [ @@ -49,7 +49,7 @@ sub set_counters { ], } }, - { label => 'node-user', set => { + { label => 'node-user', nlabel => 'node.cpu.user.utilization.percentage', set => { key_values => [ { name => 'user' } ], output_template => 'User: %.2f %%', perfdatas => [ @@ -58,7 +58,7 @@ sub set_counters { ], } }, - { label => 'node-softirq', set => { + { label => 'node-softirq', nlabel => 'node.cpu.softirq.utilization.percentage', set => { key_values => [ { name => 'softirq' } ], output_template => 'Soft Irq: %.2f %%', perfdatas => [ @@ -67,7 +67,7 @@ sub set_counters { ], } }, - { label => 'node-interrupt', set => { + { label => 'node-interrupt', nlabel => 'node.cpu.interrupt.utilization.percentage', set => { key_values => [ { name => 'irq' } ], output_template => 'Interrupt: %.2f %%', perfdatas => [ @@ -76,7 +76,7 @@ sub set_counters { ], } }, - { label => 'node-idle', set => { + { label => 'node-idle', nlabel => 'node.cpu.idle.utilization.percentage', set => { key_values => [ { name => 'idle' } ], output_template => 'Idle: %.2f %%', perfdatas => [ @@ -85,7 +85,7 @@ sub set_counters { ], } }, - { label => 'node-steal', set => { + { label => 'node-steal', nlabel => 'node.cpu.steal.utilization.percentage', set => { key_values => [ { name => 'steal' } ], output_template => 'Steal: %.2f %%', perfdatas => [ @@ -94,7 +94,7 @@ sub set_counters { ], } }, - { label => 'node-system', set => { + { label => 'node-system', nlabel => 'node.cpu.system.utilization.percentage', set => { key_values => [ { name => 'system' } ], output_template => 'System: %.2f %%', perfdatas => [ @@ -103,7 +103,7 @@ sub set_counters { ], } }, - { label => 'node-nice', set => { + { label => 'node-nice', nlabel => 'node.cpu.nice.utilization.percentage', set => { key_values => [ { name => 'nice' } ], output_template => 'Nice: %.2f %%', perfdatas => [ @@ -114,7 +114,7 @@ sub set_counters { }, ]; $self->{maps_counters}->{cpu} = [ - { label => 'cpu-wait', set => { + { label => 'cpu-wait', nlabel => 'core.cpu.wait.utilization.percentage', set => { key_values => [ { name => 'iowait' }, { name => 'display' } ], output_template => 'Wait: %.2f %%', perfdatas => [ @@ -123,7 +123,7 @@ sub set_counters { ], } }, - { label => 'cpu-user', set => { + { label => 'cpu-user', nlabel => 'core.cpu.user.utilization.percentage', set => { key_values => [ { name => 'user' }, { name => 'display' } ], output_template => 'User: %.2f %%', perfdatas => [ @@ -132,7 +132,7 @@ sub set_counters { ], } }, - { label => 'cpu-softirq', set => { + { label => 'cpu-softirq', nlabel => 'core.cpu.softirq.utilization.percentage', set => { key_values => [ { name => 'softirq' }, { name => 'display' } ], output_template => 'Soft Irq: %.2f %%', perfdatas => [ @@ -141,7 +141,7 @@ sub set_counters { ], } }, - { label => 'cpu-interrupt', set => { + { label => 'cpu-interrupt', nlabel => 'core.cpu.interrupt.utilization.percentage', set => { key_values => [ { name => 'irq' }, { name => 'display' } ], output_template => 'Interrupt: %.2f %%', perfdatas => [ @@ -150,7 +150,7 @@ sub set_counters { ], } }, - { label => 'cpu-idle', set => { + { label => 'cpu-idle', nlabel => 'core.cpu.idle.utilization.percentage', set => { key_values => [ { name => 'idle' }, { name => 'display' } ], output_template => 'Idle: %.2f %%', perfdatas => [ @@ -159,7 +159,7 @@ sub set_counters { ], } }, - { label => 'cpu-steal', set => { + { label => 'cpu-steal', nlabel => 'core.cpu.steal.utilization.percentage', set => { key_values => [ { name => 'steal' }, { name => 'display' } ], output_template => 'Steal: %.2f %%', perfdatas => [ @@ -168,7 +168,7 @@ sub set_counters { ], } }, - { label => 'cpu-system', set => { + { label => 'cpu-system', nlabel => 'core.cpu.system.utilization.percentage', set => { key_values => [ { name => 'system' }, { name => 'display' } ], output_template => 'System: %.2f %%', perfdatas => [ @@ -177,7 +177,7 @@ sub set_counters { ], } }, - { label => 'cpu-nice', set => { + { label => 'cpu-nice', nlabel => 'core.cpu.nice.utilization.percentage', set => { key_values => [ { name => 'nice' }, { name => 'display' } ], output_template => 'Nice: %.2f %%', perfdatas => [ @@ -219,15 +219,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "instance:s" => { name => 'instance', default => 'instance=~".*"' }, - "cpu:s" => { name => 'cpu', default => 'cpu=~".*"' }, - "type:s" => { name => 'type', default => 'mode=~".*"' }, - "extra-filter:s@" => { name => 'extra_filter' }, - "metric-overload:s@" => { name => 'metric_overload' }, - "filter-counters:s" => { name => 'filter_counters' }, - }); + $options{options}->add_options(arguments => { + "instance:s" => { name => 'instance', default => 'instance=~".*"' }, + "cpu:s" => { name => 'cpu', default => 'cpu=~".*"' }, + "type:s" => { name => 'type', default => 'mode=~".*"' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); return $self; } @@ -237,7 +235,7 @@ sub check_options { $self->SUPER::check_options(%options); $self->{metrics} = { - 'cpu' => "^node_cpu.*", + 'cpu' => "^node_cpu_seconds_total.*", }; foreach my $metric (@{$self->{option_results}->{metric_overload}}) { next if ($metric !~ /(.*),(.*)/); @@ -267,12 +265,16 @@ sub manage_selection { $self->{nodes} = {}; - my $results = $options{custom}->query_range(queries => [ '(irate({__name__=~"' . $self->{metrics}->{cpu} . '",' . - $self->{option_results}->{instance} . ',' . - $self->{option_results}->{cpu} . ',' . - $self->{option_results}->{type} . - $self->{extra_filter} . '}[' . $self->{prom_step} . '])) * 100' ], - timeframe => $self->{prom_timeframe}, step => $self->{prom_step}); + my $results = $options{custom}->query_range( + queries => [ + '(irate({__name__=~"' . $self->{metrics}->{cpu} . '",' . + $self->{option_results}->{instance} . ',' . + $self->{option_results}->{cpu} . ',' . + $self->{option_results}->{type} . + $self->{extra_filter} . '}[' . $self->{prom_step} . '])) * 100' + ], + timeframe => $self->{prom_timeframe}, step => $self->{prom_step} + ); foreach my $result (@{$results}) { my $average = $options{custom}->compute(aggregation => 'average', values => $result->{values}); @@ -320,17 +322,17 @@ Filter on a specific type (Must be a PromQL filter, Default: 'mode=~".*"') =item B<--warning-*> Threshold warning. -Can be: 'node-idle', 'node-wait', 'node-irq', 'node-nice', +Can be: 'node-idle', 'node-wait', 'node-interrupt', 'node-nice', 'node-softirq', 'node-steal', 'node-system', 'node-user', -'cpu-idle', 'cpu-wait', 'cpu-irq', 'cpu-nice', 'cpu-softirq', +'cpu-idle', 'cpu-wait', 'cpu-interrupt', 'cpu-nice', 'cpu-softirq', 'cpu-steal', 'cpu-system', 'cpu-user'. =item B<--critical-*> Threshold critical. -Can be: 'node-idle', 'node-wait', 'node-irq', 'node-nice', +Can be: 'node-idle', 'node-wait', 'node-interrupt', 'node-nice', 'node-softirq', 'node-steal', 'node-system', 'node-user', -'cpu-idle', 'cpu-wait', 'cpu-irq', 'cpu-nice', 'cpu-softirq', +'cpu-idle', 'cpu-wait', 'cpu-interrupt', 'cpu-nice', 'cpu-softirq', 'cpu-steal', 'cpu-system', 'cpu-user'. =item B<--extra-filter> @@ -347,7 +349,7 @@ Example : --metric-overload='metric,^my_metric_name$' Default : - - cpu: ^node_cpu.* + - cpu: ^node_cpu_seconds_total.* =item B<--filter-counters> diff --git a/cloud/prometheus/exporters/nodeexporter/mode/load.pm b/cloud/prometheus/exporters/nodeexporter/mode/load.pm index aa5d96278..c2847d2ef 100644 --- a/cloud/prometheus/exporters/nodeexporter/mode/load.pm +++ b/cloud/prometheus/exporters/nodeexporter/mode/load.pm @@ -33,7 +33,7 @@ sub set_counters { ]; $self->{maps_counters}->{nodes} = [ - { label => 'load1', set => { + { label => 'load1', nlabel => 'load.1minute.count', set => { key_values => [ { name => 'load1' }, { name => 'display' } ], output_template => 'Load 1 minute: %.2f', output_change_bytes => 1, @@ -43,7 +43,7 @@ sub set_counters { ], } }, - { label => 'load5', set => { + { label => 'load5', nlabel => 'load.5minutes.count', set => { key_values => [ { name => 'load5' }, { name => 'display' } ], output_template => 'Load 5 minutes: %.2f', output_change_bytes => 1, @@ -53,7 +53,7 @@ sub set_counters { ], } }, - { label => 'load15', set => { + { label => 'load15', nlabel => 'load.15minutes.count', set => { key_values => [ { name => 'load15' }, { name => 'display' } ], output_template => 'Load 15 minutes: %.2f', output_change_bytes => 1, @@ -78,13 +78,11 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "instance:s" => { name => 'instance', default => 'instance=~".*"' }, - "extra-filter:s@" => { name => 'extra_filter' }, - "metric-overload:s@" => { name => 'metric_overload' }, - "filter-counters:s" => { name => 'filter_counters' }, - }); + $options{options}->add_options(arguments => { + "instance:s" => { name => 'instance', default => 'instance=~".*"' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); return $self; } @@ -123,15 +121,19 @@ sub manage_selection { $self->{nodes} = {}; - my $results = $options{custom}->query(queries => [ 'label_replace({__name__=~"' . $self->{metrics}->{load1} . '",' . - $self->{option_results}->{instance} . - $self->{extra_filter} . '}, "__name__", "load1", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{load5} . '",' . - $self->{option_results}->{instance} . - $self->{extra_filter} . '}, "__name__", "load5", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{load15} . '",' . - $self->{option_results}->{instance} . - $self->{extra_filter} . '}, "__name__", "load15", "", "")' ]); + my $results = $options{custom}->query( + queries => [ + 'label_replace({__name__=~"' . $self->{metrics}->{load1} . '",' . + $self->{option_results}->{instance} . + $self->{extra_filter} . '}, "__name__", "load1", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{load5} . '",' . + $self->{option_results}->{instance} . + $self->{extra_filter} . '}, "__name__", "load5", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{load15} . '",' . + $self->{option_results}->{instance} . + $self->{extra_filter} . '}, "__name__", "load15", "", "")' + ] + ); foreach my $result (@{$results}) { $self->{nodes}->{$result->{metric}->{$self->{labels}->{instance}}}->{display} = $result->{metric}->{$self->{labels}->{instance}}; diff --git a/cloud/prometheus/exporters/nodeexporter/mode/memory.pm b/cloud/prometheus/exporters/nodeexporter/mode/memory.pm index a430673d2..c6c80e3ca 100644 --- a/cloud/prometheus/exporters/nodeexporter/mode/memory.pm +++ b/cloud/prometheus/exporters/nodeexporter/mode/memory.pm @@ -25,26 +25,27 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + nlabel => 'memory.usage.bytes', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); } sub custom_usage_threshold { @@ -52,11 +53,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, - { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -102,7 +104,7 @@ sub set_counters { closure_custom_threshold_check => $self->can('custom_usage_threshold'), } }, - { label => 'buffer', set => { + { label => 'buffer', nlabel => 'buffer.usage.bytes', set => { key_values => [ { name => 'buffer' }, { name => 'display' } ], output_template => 'Buffer: %.2f %s', output_change_bytes => 1, @@ -112,7 +114,7 @@ sub set_counters { ], } }, - { label => 'cached', set => { + { label => 'cached', nlabel => 'cache.usage.bytes', set => { key_values => [ { name => 'cached' }, { name => 'display' } ], output_template => 'Cached: %.2f %s', output_change_bytes => 1, @@ -137,15 +139,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "instance:s" => { name => 'instance', default => 'instance=~".*"' }, - "units:s" => { name => 'units', default => '%' }, - "extra-filter:s@" => { name => 'extra_filter' }, - "metric-overload:s@" => { name => 'metric_overload' }, - "filter-counters:s" => { name => 'filter_counters' }, - }); - + $options{options}->add_options(arguments => { + "instance:s" => { name => 'instance', default => 'instance=~".*"' }, + "units:s" => { name => 'units', default => '%' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); + return $self; } @@ -176,9 +176,7 @@ sub check_options { $self->{extra_filter} = ''; foreach my $filter (@{$self->{option_results}->{extra_filter}}) { $self->{extra_filter} .= ',' . $filter; - } - - $instance_mode = $self; + } } sub manage_selection { @@ -186,18 +184,22 @@ sub manage_selection { $self->{nodes} = {}; - my $results = $options{custom}->query(queries => [ 'label_replace({__name__=~"' . $self->{metrics}->{total} . '",' . - $self->{option_results}->{instance} . - $self->{extra_filter} . '}, "__name__", "total", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{available} . '",' . - $self->{option_results}->{instance} . - $self->{extra_filter} . '}, "__name__", "available", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{cached} . '",' . - $self->{option_results}->{instance} . - $self->{extra_filter} . '}, "__name__", "cached", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{buffer} . '",' . - $self->{option_results}->{instance} . - $self->{extra_filter} . '}, "__name__", "buffer", "", "")' ]); + my $results = $options{custom}->query( + queries => [ + 'label_replace({__name__=~"' . $self->{metrics}->{total} . '",' . + $self->{option_results}->{instance} . + $self->{extra_filter} . '}, "__name__", "total", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{available} . '",' . + $self->{option_results}->{instance} . + $self->{extra_filter} . '}, "__name__", "available", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{cached} . '",' . + $self->{option_results}->{instance} . + $self->{extra_filter} . '}, "__name__", "cached", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{buffer} . '",' . + $self->{option_results}->{instance} . + $self->{extra_filter} . '}, "__name__", "buffer", "", "")' + ] + ); foreach my $result (@{$results}) { $self->{nodes}->{$result->{metric}->{$self->{labels}->{instance}}}->{display} = $result->{metric}->{$self->{labels}->{instance}}; diff --git a/cloud/prometheus/exporters/nodeexporter/mode/storage.pm b/cloud/prometheus/exporters/nodeexporter/mode/storage.pm index 5dd77765a..5dcc58c77 100644 --- a/cloud/prometheus/exporters/nodeexporter/mode/storage.pm +++ b/cloud/prometheus/exporters/nodeexporter/mode/storage.pm @@ -25,30 +25,31 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{label} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + nlabel => 'storage.space.usage.bytes', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + ); } sub custom_usage_threshold { @@ -56,12 +57,14 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -149,17 +152,16 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "instance:s" => { name => 'instance', default => 'instance=~".*"' }, - "mountpoint:s" => { name => 'mountpoint', default => 'mountpoint=~".*"' }, - "fstype:s" => { name => 'fstype', default => 'fstype!~"linuxfs|rootfs|tmpfs"' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - "extra-filter:s@" => { name => 'extra_filter' }, - "metric-overload:s@" => { name => 'metric_overload' }, - }); - + $options{options}->add_options(arguments => { + "instance:s" => { name => 'instance', default => 'instance=~".*"' }, + "mountpoint:s" => { name => 'mountpoint', default => 'mountpoint=~".*"' }, + "fstype:s" => { name => 'fstype', default => 'fstype!~"linuxfs|rootfs|tmpfs"' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "extra-filter:s@" => { name => 'extra_filter' }, + "metric-overload:s@" => { name => 'metric_overload' }, + }); + return $self; } @@ -188,9 +190,7 @@ sub check_options { $self->{extra_filter} = ''; foreach my $filter (@{$self->{option_results}->{extra_filter}}) { $self->{extra_filter} .= ',' . $filter; - } - - $instance_mode = $self; + } } sub manage_selection { @@ -198,16 +198,20 @@ sub manage_selection { $self->{nodes} = {}; - my $results = $options{custom}->query(queries => [ 'label_replace({__name__=~"' . $self->{metrics}->{free} . '",' . - $self->{option_results}->{instance} . ',' . - $self->{option_results}->{mountpoint} . ',' . - $self->{option_results}->{fstype} . - $self->{extra_filter} . '}, "__name__", "free", "", "")', - 'label_replace({__name__=~"' . $self->{metrics}->{size} . '",' . - $self->{option_results}->{instance} . ',' . - $self->{option_results}->{mountpoint} . ',' . - $self->{option_results}->{fstype} . - $self->{extra_filter} . '}, "__name__", "size", "", "")' ]); + my $results = $options{custom}->query( + queries => [ + 'label_replace({__name__=~"' . $self->{metrics}->{free} . '",' . + $self->{option_results}->{instance} . ',' . + $self->{option_results}->{mountpoint} . ',' . + $self->{option_results}->{fstype} . + $self->{extra_filter} . '}, "__name__", "free", "", "")', + 'label_replace({__name__=~"' . $self->{metrics}->{size} . '",' . + $self->{option_results}->{instance} . ',' . + $self->{option_results}->{mountpoint} . ',' . + $self->{option_results}->{fstype} . + $self->{extra_filter} . '}, "__name__", "size", "", "")' + ] + ); foreach my $result (@{$results}) { $self->{nodes}->{$result->{metric}->{$self->{labels}->{instance}}}->{display} = $result->{metric}->{$self->{labels}->{instance}}; diff --git a/cloud/prometheus/restapi/custom/api.pm b/cloud/prometheus/restapi/custom/api.pm index df5a2216f..266d1fda9 100644 --- a/cloud/prometheus/restapi/custom/api.pm +++ b/cloud/prometheus/restapi/custom/api.pm @@ -42,29 +42,26 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "url-path:s" => { name => 'url_path' }, - "port:s" => { name => 'port' }, - "proto:s" => { name => 'proto' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "header:s@" => { name => 'header' }, - "timeframe:s" => { name => 'timeframe' }, - "step:s" => { name => 'step' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "url-path:s" => { name => 'url_path' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + "header:s@" => { name => 'header' }, + "timeframe:s" => { name => 'timeframe' }, + "step:s" => { name => 'step' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; @@ -303,18 +300,10 @@ Specify this option if you access the API over hidden basic authentication or yo (Use with --credentials) -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL option (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--header> Set HTTP header (Can be multiple, example: --header='Authorization:Bearer ABCD') diff --git a/cloud/prometheus/restapi/mode/expression.pm b/cloud/prometheus/restapi/mode/expression.pm index 3e62f3478..fd88d36d5 100644 --- a/cloud/prometheus/restapi/mode/expression.pm +++ b/cloud/prometheus/restapi/mode/expression.pm @@ -29,14 +29,13 @@ use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold) sub custom_status_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{instance}; - } - foreach my $key (@{$self->{instance_mode}->{custom_keys}}) { - $self->{output}->perfdata_add(label => $key . $extra_label, - value => $self->{result_values}->{$key}); + $self->{output}->perfdata_add( + label => $key, + nlabel => $key, + value => $self->{result_values}->{$key}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef + ); } } @@ -91,17 +90,16 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "query:s@" => { name => 'query' }, - "query-range:s@" => { name => 'query_range' }, - "instance:s" => { name => 'instance' }, - "aggregation:s" => { name => 'aggregation', default => 'average' }, - "output:s" => { name => 'output' }, - "multiple-output:s" => { name => 'multiple_output' }, - "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '' }, - }); + $options{options}->add_options(arguments => { + "query:s@" => { name => 'query' }, + "query-range:s@" => { name => 'query_range' }, + "instance:s" => { name => 'instance' }, + "aggregation:s" => { name => 'aggregation', default => 'average' }, + "output:s" => { name => 'output' }, + "multiple-output:s" => { name => 'multiple_output' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + }); return $self; } diff --git a/cloud/prometheus/restapi/mode/targetstatus.pm b/cloud/prometheus/restapi/mode/targetstatus.pm index 5c2df430b..ea7bd63b4 100644 --- a/cloud/prometheus/restapi/mode/targetstatus.pm +++ b/cloud/prometheus/restapi/mode/targetstatus.pm @@ -67,45 +67,45 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'active', set => { + { label => 'active', nlabel => 'targets.active.count', set => { key_values => [ { name => 'active' } ], - output_template => 'Active : %s', + output_template => 'Active: %s', perfdatas => [ { label => 'active_targets', value => 'active_absolute', template => '%s', min => 0 }, ], } }, - { label => 'dropped', set => { + { label => 'dropped', nlabel => 'targets.dropped.count', set => { key_values => [ { name => 'dropped' } ], - output_template => 'Dropped : %s', + output_template => 'Dropped: %s', perfdatas => [ { label => 'dropped_targets', value => 'dropped_absolute', template => '%s', min => 0 }, ], } }, - { label => 'up', set => { + { label => 'up', nlabel => 'targets.up.count', set => { key_values => [ { name => 'up' } ], - output_template => 'Up : %s', + output_template => 'Up: %s', perfdatas => [ { label => 'up_targets', value => 'up_absolute', template => '%s', min => 0 }, ], } }, - { label => 'down', set => { + { label => 'down', nlabel => 'targets.down.count', set => { key_values => [ { name => 'down' } ], - output_template => 'Down : %s', + output_template => 'Down: %s', perfdatas => [ { label => 'down_targets', value => 'down_absolute', template => '%s', min => 0 }, ], } }, - { label => 'unknown', set => { + { label => 'unknown', nlabel => 'targets.unknown.count', set => { key_values => [ { name => 'unknown' } ], - output_template => 'Unknown : %s', + output_template => 'Unknown: %s', perfdatas => [ { label => 'unknown_targets', value => 'unknown_absolute', template => '%s', min => 0 }, @@ -132,12 +132,11 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-label:s@" => { name => 'filter_label' }, - "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '%{health} !~ /up/' }, - }); + $options{options}->add_options(arguments => { + "filter-label:s@" => { name => 'filter_label' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{health} !~ /up/' }, + }); return $self; } diff --git a/database/cassandra/jmx/mode/cachesusage.pm b/database/cassandra/jmx/mode/cachesusage.pm index ac52ed3bc..19c939fcb 100644 --- a/database/cassandra/jmx/mode/cachesusage.pm +++ b/database/cassandra/jmx/mode/cachesusage.pm @@ -34,7 +34,7 @@ sub set_counters { ]; $self->{maps_counters}->{ccache} = [ - { label => 'used', set => { + { label => 'used', nlabel => 'ccache.utilization.percentage', set => { key_values => [ { name => 'Capacity_Value' }, { name => 'Size_Value' }, { name => 'display' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_output => $self->can('custom_usage_output'), @@ -45,7 +45,7 @@ sub set_counters { ], } }, - { label => 'hits', set => { + { label => 'hits', nlabel => 'ccache.hits.percentage', set => { key_values => [ { name => 'Requests_Count', diff => 1 }, { name => 'Hits_Count', diff => 1 }, { name => 'display' } ], closure_custom_calc => $self->can('custom_hits_calc'), output_template => 'Hits = %.2f %%', output_use => 'hits_prct', threshold_use => 'hits_prct', diff --git a/database/cassandra/jmx/mode/clientrequestsusage.pm b/database/cassandra/jmx/mode/clientrequestsusage.pm index 6c55f8cbb..235778e00 100644 --- a/database/cassandra/jmx/mode/clientrequestsusage.pm +++ b/database/cassandra/jmx/mode/clientrequestsusage.pm @@ -34,7 +34,7 @@ sub set_counters { ]; $self->{maps_counters}->{cr} = [ - { label => 'total-latency', set => { + { label => 'total-latency', nlabel => 'client.request.latency.microsecond', set => { key_values => [ { name => 'TotalLatency_Count', diff => 1 }, { name => 'display' } ], output_template => 'Total Latency : %s us', perfdatas => [ @@ -43,7 +43,7 @@ sub set_counters { ], } }, - { label => 'timeouts', set => { + { label => 'timeouts', nlabel => 'client.request.timeout.count', set => { key_values => [ { name => 'Timeouts_Count', diff => 1 }, { name => 'display' } ], output_template => 'Timeouts : %s', perfdatas => [ @@ -52,7 +52,7 @@ sub set_counters { ], } }, - { label => 'unavailables', set => { + { label => 'unavailables', nlabel => 'client.request.unavailable.count', set => { key_values => [ { name => 'Unavailables_Count', diff => 1 }, { name => 'display' } ], output_template => 'Unavailables : %s', perfdatas => [ @@ -61,7 +61,7 @@ sub set_counters { ], } }, - { label => 'failures', set => { + { label => 'failures', nlabel => 'client.request.failure.count', set => { key_values => [ { name => 'Failures_Count', diff => 1 }, { name => 'display' } ], output_template => 'Failures : %s', perfdatas => [ @@ -122,9 +122,6 @@ sub manage_selection { } } - use Data::Dumper; - print Data::Dumper::Dumper($self->{cr}); - if (scalar(keys %{$self->{cr}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No client request found."); $self->{output}->option_exit(); diff --git a/database/cassandra/jmx/mode/threadpoolsusage.pm b/database/cassandra/jmx/mode/threadpoolsusage.pm index 7ffc5aac1..c3ac7ed91 100644 --- a/database/cassandra/jmx/mode/threadpoolsusage.pm +++ b/database/cassandra/jmx/mode/threadpoolsusage.pm @@ -34,7 +34,7 @@ sub set_counters { ]; $self->{maps_counters}->{thpool} = [ - { label => 'active-tasks', set => { + { label => 'active-tasks', nlabel => 'thread.tasks.active.count', set => { key_values => [ { name => 'ActiveTasks_Value' }, { name => 'display' } ], output_template => 'Current Active Tasks : %s', perfdatas => [ @@ -43,7 +43,7 @@ sub set_counters { ], } }, - { label => 'pending-tasks', set => { + { label => 'pending-tasks', nlabel => 'thread.tasks.pending.count', set => { key_values => [ { name => 'PendingTasks_Value' }, { name => 'display' } ], output_template => 'Current Pending Tasks : %s', perfdatas => [ @@ -52,7 +52,7 @@ sub set_counters { ], } }, - { label => 'total-completed-tasks', set => { + { label => 'total-completed-tasks', nlabel => 'thread.tasks.completed.count', set => { key_values => [ { name => 'CompletedTasks_Value', diff => 1 }, { name => 'display' } ], output_template => 'Total Completed Tasks : %s', perfdatas => [ @@ -61,7 +61,7 @@ sub set_counters { ], } }, - { label => 'total-blocked-tasks', set => { + { label => 'total-blocked-tasks', nlabel => 'thread.tasks.blocked.count', set => { key_values => [ { name => 'TotalBlockedTasks_Count', diff => 1 }, { name => 'display' } ], output_template => 'Total Blocked Tasks : %s', perfdatas => [ @@ -70,9 +70,9 @@ sub set_counters { ], } }, - { label => 'current-blocked-tasks', set => { + { label => 'current-blocked-tasks', nlabel => 'thread.tasks.blocked.current.count', set => { key_values => [ { name => 'CurrentlyBlockedTasks_Count', diff => 1 }, { name => 'display' } ], - output_template => 'Total Currently Blocked Tasks : %s', + output_template => 'Currently Blocked Tasks : %s', perfdatas => [ { label => 'current_blocked_tasks', value => 'CurrentlyBlockedTasks_Count_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, diff --git a/database/firebird/mode/longqueries.pm b/database/firebird/mode/longqueries.pm index 51eb4a615..ba6ffb85b 100644 --- a/database/firebird/mode/longqueries.pm +++ b/database/firebird/mode/longqueries.pm @@ -94,6 +94,7 @@ sub run { short_msg => sprintf("%s queries over %s seconds", $long_queries, $self->{option_results}->{seconds})); $self->{output}->perfdata_add(label => 'longqueries', + nlabel => 'longqueries.count', value => $long_queries, warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), diff --git a/database/firebird/mode/memory.pm b/database/firebird/mode/memory.pm index b73388912..30fdfcd09 100644 --- a/database/firebird/mode/memory.pm +++ b/database/firebird/mode/memory.pm @@ -33,7 +33,7 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'used', set => { + { label => 'used', nlabel => 'database.usage.bytes', set => { key_values => [ { name => 'database_used' }, { name => 'database_allocated' } ], closure_custom_calc => $self->can('custom_unit_calc'), closure_custom_calc_extra_options => { label_ref => 'database' }, closure_custom_output => $self->can('custom_used_output'), @@ -41,7 +41,7 @@ sub set_counters { closure_custom_perfdata => $self->can('custom_used_perfdata'), } }, - { label => 'attachment', set => { + { label => 'attachment', nlabel => 'attachment.usage.bytes', set => { key_values => [ { name => 'attachment_used' }, { name => 'database_allocated' } ], closure_custom_calc => $self->can('custom_unit_calc'), closure_custom_calc_extra_options => { label_ref => 'attachment' }, closure_custom_output => $self->can('custom_unit_output'), @@ -49,7 +49,7 @@ sub set_counters { closure_custom_perfdata => $self->can('custom_unit_perfdata'), } }, - { label => 'transaction', set => { + { label => 'transaction', nlabel => 'transaction.usage.bytes', set => { key_values => [ { name => 'transaction_used' }, { name => 'database_allocated' } ], closure_custom_calc => $self->can('custom_unit_calc'), closure_custom_calc_extra_options => { label_ref => 'transaction' }, closure_custom_output => $self->can('custom_unit_output'), @@ -57,7 +57,7 @@ sub set_counters { closure_custom_perfdata => $self->can('custom_unit_perfdata'), } }, - { label => 'statement', set => { + { label => 'statement', nlabel => 'statement.usage.bytes', set => { key_values => [ { name => 'statement_used' }, { name => 'database_allocated' } ], closure_custom_calc => $self->can('custom_unit_calc'), closure_custom_calc_extra_options => { label_ref => 'statement' }, closure_custom_output => $self->can('custom_unit_output'), @@ -65,7 +65,7 @@ sub set_counters { closure_custom_perfdata => $self->can('custom_unit_perfdata'), } }, - { label => 'call', set => { + { label => 'call', nlabel => 'call.usage.bytes', set => { key_values => [ { name => 'call_used' }, { name => 'database_allocated' } ], closure_custom_calc => $self->can('custom_unit_calc'), closure_custom_calc_extra_options => { label_ref => 'call' }, closure_custom_output => $self->can('custom_unit_output'), @@ -93,21 +93,27 @@ sub custom_used_output { sub custom_used_perfdata { my ($self, %options) = @_; - $self->{output}->perfdata_add(label => 'used', unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + nlabel => $self->{nlabel}, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_unit_perfdata { my ($self, %options) = @_; - $self->{output}->perfdata_add(label => $self->{result_values}->{label}, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $self->{result_values}->{label}, unit => 'B', + nlabel => $self->{nlabel}, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_unit_output { @@ -147,9 +153,7 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => {}); return $self; } diff --git a/database/firebird/mode/pages.pm b/database/firebird/mode/pages.pm index f51d5b9bc..76724f6f1 100644 --- a/database/firebird/mode/pages.pm +++ b/database/firebird/mode/pages.pm @@ -34,7 +34,7 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'reads', set => { + { label => 'reads', nlabel => 'pages.reads.persecond', set => { key_values => [ { name => 'reads', diff => 1 } ], per_second => 1, output_template => 'Reads : %.2f', @@ -44,7 +44,7 @@ sub set_counters { ], } }, - { label => 'writes', set => { + { label => 'writes', nlabel => 'pages.writes.persecond', set => { key_values => [ { name => 'writes', diff => 1 } ], per_second => 1, output_template => 'Writes : %.2f', @@ -54,7 +54,7 @@ sub set_counters { ], } }, - { label => 'fetches', set => { + { label => 'fetches', nlabel => 'pages.fetches.persecond', set => { key_values => [ { name => 'fetches', diff => 1 } ], per_second => 1, output_template => 'Fetches : %.2f', @@ -64,7 +64,7 @@ sub set_counters { ], } }, - { label => 'marks', set => { + { label => 'marks', nlabel => 'pages.marks.persecond', set => { key_values => [ { name => 'marks', diff => 1 } ], per_second => 1, output_template => 'Marks : %.2f', @@ -89,9 +89,7 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => {}); return $self; } diff --git a/database/firebird/mode/queries.pm b/database/firebird/mode/queries.pm index 2a4363f8f..a1523de21 100644 --- a/database/firebird/mode/queries.pm +++ b/database/firebird/mode/queries.pm @@ -34,7 +34,7 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'total', set => { + { label => 'total', nlabel => 'queries.total.persecond', set => { key_values => [ { name => 'total', diff => 1 } ], per_second => 1, output_template => 'Total : %d', @@ -44,7 +44,7 @@ sub set_counters { ], } }, - { label => 'seq-reads', set => { + { label => 'seq-reads', nlabel => 'queries.sequentialreads.persecond', set => { key_values => [ { name => 'seq_reads', diff => 1 } ], per_second => 1, output_template => 'Seq Reads : %d', @@ -54,7 +54,7 @@ sub set_counters { ], } }, - { label => 'inserts', set => { + { label => 'inserts', nlabel => 'queries.insert.persecond', set => { key_values => [ { name => 'inserts', diff => 1 } ], per_second => 1, output_template => 'Inserts : %d', @@ -64,7 +64,7 @@ sub set_counters { ], } }, - { label => 'updates', set => { + { label => 'updates', nlabel => 'queries.updates.persecond', set => { key_values => [ { name => 'updates', diff => 1 } ], per_second => 1, output_template => 'Updates : %d', @@ -74,7 +74,7 @@ sub set_counters { ], } }, - { label => 'deletes', set => { + { label => 'deletes', nlabel => 'queries.deletes.persecond', set => { key_values => [ { name => 'deletes', diff => 1 } ], per_second => 1, output_template => 'Deletes : %d', @@ -84,7 +84,7 @@ sub set_counters { ], } }, - { label => 'backouts', set => { + { label => 'backouts', nlabel => 'queries.backout.persecond', set => { key_values => [ { name => 'backouts', diff => 1 } ], per_second => 1, output_template => 'Backouts : %d', @@ -94,7 +94,7 @@ sub set_counters { ], } }, - { label => 'purges', set => { + { label => 'purges', nlabel => 'queries.purges.persecond', set => { key_values => [ { name => 'purges', diff => 1 } ], per_second => 1, output_template => 'Purges : %d', @@ -104,7 +104,7 @@ sub set_counters { ], } }, - { label => 'expunges', set => { + { label => 'expunges', nlabel => 'queries.expunges.persecond', set => { key_values => [ { name => 'expunges', diff => 1 } ], per_second => 1, output_template => 'Expunges : %d', @@ -129,9 +129,7 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => {}); return $self; } diff --git a/database/firebird/mode/users.pm b/database/firebird/mode/users.pm index 07028e362..4a4190e1d 100644 --- a/database/firebird/mode/users.pm +++ b/database/firebird/mode/users.pm @@ -76,6 +76,7 @@ sub run { $self->{output}->output_add(severity => $exit_code, short_msg => $msg); $self->{output}->perfdata_add(label => 'users', value => $result, + nlabel => 'users.count', warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), min => 0); diff --git a/database/influxdb/custom/api.pm b/database/influxdb/custom/api.pm new file mode 100644 index 000000000..7ff97275c --- /dev/null +++ b/database/influxdb/custom/api.pm @@ -0,0 +1,288 @@ +# +# Copyright 2019 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 database::influxdb::custom::api; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::http; +use URI::Encode; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'CUSTOM MODE OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{http} = centreon::plugins::http->new(%options); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : ''; + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 8086; + $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'http'; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; + $self->{username} = (defined($self->{option_results}->{username})) ? $self->{option_results}->{username} : undef; + $self->{password} = (defined($self->{option_results}->{password})) ? $self->{option_results}->{password} : undef; + $self->{credentials} = (defined($self->{option_results}->{credentials})) ? 1 : undef; + $self->{basic} = (defined($self->{option_results}->{basic})) ? 1 : undef; + + if (!defined($self->{hostname}) || $self->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --hostname option."); + $self->{output}->option_exit(); + } + return 0; +} + +sub get_hostname { + my ($self, %options) = @_; + + return $self->{hostname}; +} + +sub get_port { + my ($self, %options) = @_; + + return $self->{port}; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{warning_status} = ''; + $self->{option_results}->{critical_status} = ''; + $self->{option_results}->{unknown_status} = '%{http_code} < 200 or %{http_code} >= 300'; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub request { + my ($self, %options) = @_; + + $self->settings(); + + $self->{output}->output_add(long_msg => "URL: '" . $self->{proto} . '://' . $self->{hostname} . ':' . $self->{port} . $options{url_path} . "'", debug => 1); + $self->{output}->output_add(long_msg => "Parameters: '" . join(', ', @{$options{post_param}}) . "'", debug => 1) if (defined($options{post_param})); + + my $content = $self->{http}->request(%options); + + if (!defined($content) || $content eq '') { + $self->{output}->add_option_msg(short_msg => "API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->output_add(long_msg => $content, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + if (defined($decoded->{error})) { + $self->{output}->add_option_msg(short_msg => "API returns error '" . $decoded->{error} . "'"); + $self->{output}->option_exit(); + } + + return $decoded; +} + +sub query { + my ($self, %options) = @_; + + my $data; + foreach my $query (@{$options{queries}}) { + my $results = $self->request(method => 'POST', url_path => '/query', post_param => ['q=' . $query]); + + if (defined($results->{results}[0]->{error})) { + $self->{output}->add_option_msg(short_msg => "API returns error '" . $results->{results}[0]->{error} . "'"); + $self->{output}->option_exit(); + } + push @{$data}, @{$results->{results}[0]->{series}} if (defined($results->{results}[0]->{series})); + } + + return $data; +} + +sub compute { + my ($self, %options) = @_; + + my $result; + + if ($options{aggregation} eq 'average') { + my $points = 0; + foreach my $value (@{$options{values}}) { + $result = 0 if (!defined($result)); + $result += $$value[1]; + $points++; + } + $result /= $points; + } elsif ($options{aggregation} eq 'minimum') { + foreach my $value (@{$options{values}}) { + $result = $$value[1] if (!defined($result) || $$value[1] < $result); + } + } elsif ($options{aggregation} eq 'maximum') { + foreach my $value (@{$options{values}}) { + $result = $$value[1] if (!defined($result) || $$value[1] > $result); + } + } elsif ($options{aggregation} eq 'sum') { + foreach my $value (@{$options{values}}) { + $result = 0 if (!defined($result)); + $result += $$value[1]; + } + } + + return $result; +} + +1; + +__END__ + +=head1 NAME + +InfluxDB Rest API + +=head1 CUSTOM MODE OPTIONS + +InfluxDB Rest API + +=over 8 + +=item B<--hostname> + +Remote hostname or IP address. + +=item B<--port> + +Port used (Default: 8086) + +=item B<--proto> + +Specify https if needed (Default: 'http') + +=item B<--credentials> + +Specify this option if you access webpage with authentication + +=item B<--username> + +Specify username for authentication (Mandatory if --credentials is specified) + +=item B<--password> + +Specify password for authentication (Mandatory if --credentials is specified) + +=item B<--basic> + +Specify this option if you access webpage over basic authentication and don't want a '401 UNAUTHORIZED' error to be logged on your webserver. + +Specify this option if you access webpage over hidden basic authentication or you'll get a '404 NOT FOUND' error. + +(Use with --credentials) + +=item B<--timeout> + +Set timeout in seconds (Default: 10). + +=item B<--unknown-status> + +Threshold warning for http response code. +(Default: '%{http_code} < 200 or %{http_code} >= 300') + +=item B<--warning-status> + +Threshold warning for http response code. + +=item B<--critical-status> + +Threshold critical for http response code. + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/database/influxdb/mode/connectiontime.pm b/database/influxdb/mode/connectiontime.pm new file mode 100644 index 000000000..efd36be24 --- /dev/null +++ b/database/influxdb/mode/connectiontime.pm @@ -0,0 +1,97 @@ +# +# Copyright 2019 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 database::influxdb::mode::connectiontime; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Time::HiRes; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'connection-time', nlabel => 'connection.time.milliseconds', set => { + key_values => [ { name => 'connection_time' } ], + output_template => 'Connection established in %d ms', + perfdatas => [ + { value => 'connection_time_absolute', template => '%d', unit => 'ms', + min => 0 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{custom} = $options{custom}; + + my $start = Time::HiRes::time(); + $self->{custom}->request(url_path => '/ping?verbose=true'); + my $end = Time::HiRes::time(); + + $self->{global}->{connection_time} = ($end - $start) * 1000; +} + +1; + +__END__ + +=head1 MODE + +Check database connection time. + +=over 8 + +=item B<--warning-connection-time-milliseconds> + +Threshold warning in milliseconds. + +=item B<--critical-connection-time-milliseconds>> + +Threshold critical in milliseconds. + +=back + +=cut diff --git a/database/influxdb/mode/databasestatistics.pm b/database/influxdb/mode/databasestatistics.pm new file mode 100644 index 000000000..ce5c5e481 --- /dev/null +++ b/database/influxdb/mode/databasestatistics.pm @@ -0,0 +1,136 @@ +# +# Copyright 2019 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 database::influxdb::mode::databasestatistics; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'databases', type => 1, cb_prefix_output => 'prefix_database_output', + message_multiple => 'All databases statistics are ok' }, + ]; + + $self->{maps_counters}->{databases} = [ + { label => 'measurements', nlabel => 'database.measurements.count', set => { + key_values => [ { name => 'numMeasurements' }, { name => 'display' } ], + output_template => 'Measurements: %s', + perfdatas => [ + { value => 'numMeasurements_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'series', nlabel => 'database.series.count', set => { + key_values => [ { name => 'numSeries' }, { name => 'display' } ], + output_template => 'Series: %s', + perfdatas => [ + { value => 'numSeries_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_database_output { + my ($self, %options) = @_; + + return "Database '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-database:s" => { name => 'filter_database' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{custom} = $options{custom}; + + $self->{databases} = {}; + + my $results = $self->{custom}->query(queries => [ "SHOW STATS FOR 'database'" ]); + + foreach my $database (@{$results}) { + next if (defined($self->{option_results}->{filter_database}) && $self->{option_results}->{filter_database} ne '' + && $database->{tags}->{database} !~ /$self->{option_results}->{filter_database}/); + + $self->{databases}->{$database->{tags}->{database}}->{display} = $database->{tags}->{database}; + + my $i = 0; + foreach my $column (@{$database->{columns}}) { + $column =~ s/influxdb_//; + $self->{databases}->{$database->{tags}->{database}}->{$column} = $database->{values}[0][$i]; + $i++; + } + } + + if (scalar(keys %{$self->{databases}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No databases found'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check databases statistics + +=over 8 + +=item B<--filter-database> + +Filter database name (Can use regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'measurements', 'series'. + +=item B<--critical-*> + +Threshold warning. +Can be: 'measurements', 'series'. + +=back + +=cut diff --git a/database/influxdb/mode/httpserverstatistics.pm b/database/influxdb/mode/httpserverstatistics.pm new file mode 100644 index 000000000..9952b8e88 --- /dev/null +++ b/database/influxdb/mode/httpserverstatistics.pm @@ -0,0 +1,189 @@ +# +# Copyright 2019 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 database::influxdb::mode::httpserverstatistics; + +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 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'requests-query-count', nlabel => 'requests.query.count.persecond', set => { + key_values => [ { name => 'queryReq', diff => 1 } ], + per_second => 1, + output_template => 'Query Requests: %.2f/s', + perfdatas => [ + { value => 'queryReq_per_second', template => '%.2f', min => 0 }, + ], + } + }, + { label => 'requests-write-count', nlabel => 'requests.write.count.persecond', set => { + key_values => [ { name => 'writeReq', diff => 1 } ], + per_second => 1, + output_template => 'Write Requests: %.2f/s', + perfdatas => [ + { value => 'writeReq_per_second', template => '%.2f', min => 0 }, + ], + } + }, + { label => 'requests-ping-count', nlabel => 'requests.ping.count.persecond', set => { + key_values => [ { name => 'pingReq', diff => 1 } ], + per_second => 1, + output_template => 'Ping Requests: %.2f/s', + perfdatas => [ + { value => 'pingReq_per_second', template => '%.2f', min => 0 }, + ], + } + }, + { label => 'requests-status-count', nlabel => 'requests.status.count.persecond', set => { + key_values => [ { name => 'statusReq', diff => 1 } ], + per_second => 1, + output_template => 'Status Requests: %.2f/s', + perfdatas => [ + { value => 'statusReq_per_second', template => '%.2f', min => 0 }, + ], + } + }, + { label => 'requests-active', nlabel => 'requests.active.count', set => { + key_values => [ { name => 'reqActive' } ], + output_template => 'Active Requests: %d', + perfdatas => [ + { value => 'reqActive_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'requests-write-active', nlabel => 'requests.write.active.count', set => { + key_values => [ { name => 'writeReqActive' } ], + output_template => 'Active Write Requests: %d', + perfdatas => [ + { value => 'writeReqActive_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'requests-response-data', nlabel => 'requests.response.data.bytes', set => { + key_values => [ { name => 'queryRespBytes', diff => 1 } ], + per_second => 1, + output_change_bytes => 1, + output_template => 'Response Data: %s%s/s', + perfdatas => [ + { value => 'queryRespBytes_per_second', template => '%s', min => 0, unit => 'B/s' }, + ], + } + }, + { label => 'requests-write-data', nlabel => 'requests.write.data.bytes', set => { + key_values => [ { name => 'writeReqBytes', diff => 1 } ], + per_second => 1, + output_change_bytes => 1, + output_template => 'Write Data: %s%s/s', + perfdatas => [ + { value => 'writeReqBytes_per_second', template => '%s', min => 0, unit => 'B/s' }, + ], + } + }, + { label => 'errors-server', nlabel => 'errors.server.persecond', set => { + key_values => [ { name => 'serverError', diff => 1 } ], + per_second => 1, + output_template => 'Server Errors: %.2f/s', + perfdatas => [ + { value => 'serverError_per_second', template => '%.2f', min => 0 }, + ], + } + }, + { label => 'errors-client', nlabel => 'errors.client.persecond', set => { + key_values => [ { name => 'clientError', diff => 1 } ], + per_second => 1, + output_template => 'Client Errors: %.2f/s', + perfdatas => [ + { value => 'clientError_per_second', template => '%.2f', min => 0 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{custom} = $options{custom}; + + $self->{global} = {}; + + my $results = $self->{custom}->query(queries => [ "SHOW STATS FOR 'httpd'" ]); + + my $i = 0; + foreach my $column (@{$$results[0]->{columns}}) { + $column =~ s/influxdb_//; + $self->{global}->{$column} = $$results[0]->{values}[0][$i]; + $i++; + } + + $self->{cache_name} = "influxdb_" . $self->{mode} . '_' . $self->{custom}->get_hostname() . '_' . $self->{custom}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check several statistics from the HTTP server serving API. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'requests-query-count', 'requests-write-count', +'requests-ping-count', 'requests-status-count', 'requests-active', +'requests-write-active', 'requests-response-data', +'requests-write-data', 'errors-server', 'errors-client'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'requests-query-count', 'requests-write-count', +'requests-ping-count', 'requests-status-count', 'requests-active', +'requests-write-active', 'requests-response-data', +'requests-write-data', 'errors-server', 'errors-client'. + +=back + +=cut diff --git a/database/influxdb/mode/listdatabases.pm b/database/influxdb/mode/listdatabases.pm new file mode 100644 index 000000000..73c5686d0 --- /dev/null +++ b/database/influxdb/mode/listdatabases.pm @@ -0,0 +1,98 @@ +# +# Copyright 2019 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 database::influxdb::mode::listdatabases; + +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 => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + $self->{custom} = $options{custom}; + + my $results = $self->{custom}->query(queries => [ 'SHOW DATABASES' ]); + + foreach my $value (@{$$results[0]->{values}}) { + push @{$self->{databases}}, $$value[0]; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + + foreach my $database (sort @{$self->{databases}}) { + $self->{output}->output_add(long_msg => sprintf("[name = %s]", + $database)); + } + $self->{output}->output_add(severity => 'OK', + short_msg => "List databases:"); + + $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']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $database (sort @{$self->{databases}}) { + $self->{output}->add_disco_entry(name => $database); + } +} + +1; + +__END__ + +=head1 MODE + +List databases. + +=over 8 + +=back + +=cut diff --git a/database/influxdb/mode/query.pm b/database/influxdb/mode/query.pm new file mode 100644 index 000000000..0ea3379c7 --- /dev/null +++ b/database/influxdb/mode/query.pm @@ -0,0 +1,240 @@ +# +# Copyright 2019 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 database::influxdb::mode::query; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_perfdata { + my ($self, %options) = @_; + + foreach my $key (@{$self->{instance_mode}->{custom_keys}}) { + $self->{output}->perfdata_add( + label => $key, + nlabel => $key, + value => $self->{result_values}->{$key}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{instance} : undef + ); + } +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = $self->{instance_mode}->{option_results}->{output}; + while ($msg =~ /%\{(.*?)\}/g) { + my $key = $1; + if (defined($self->{result_values}->{$key})) { + $msg =~ s/%\{$key\}/$self->{result_values}->{$key}/g; + } + } + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{instance} = $options{new_datas}->{$self->{instance} . '_instance'}; + foreach my $key (@{$self->{instance_mode}->{custom_keys}}) { + $self->{result_values}->{$key} = $options{new_datas}->{$self->{instance} . '_' . $key}; + } + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'queries_results', type => 1, + message_multiple => 'All queries results are ok', skipped_code => { -11 => 1 } }, + ]; + + $self->{maps_counters}->{queries_results} = [ + { label => 'status', set => { + key_values => [ { name => 'instance' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => $self->can('custom_status_perfdata'), + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "query:s@" => { name => 'query' }, + "instance:s" => { name => 'instance' }, + "aggregation:s" => { name => 'aggregation', default => 'average' }, + "output:s" => { name => 'output' }, + "multiple-output:s" => { name => 'multiple_output' }, + "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); + + if (!defined($self->{option_results}->{output}) || $self->{option_results}->{output} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --output option."); + $self->{output}->option_exit(); + } + + if (!defined($self->{option_results}->{instance}) || $self->{option_results}->{instance} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --instance option."); + $self->{output}->option_exit(); + } + + if (!defined($self->{option_results}->{query})) { + $self->{output}->add_option_msg(short_msg => "Need to specify --query option."); + $self->{output}->option_exit(); + } + + $self->{custom_keys} = []; + $self->{queries} = {}; + foreach my $query (@{$self->{option_results}->{query}}) { + next if ($query !~ /^(.*?),(.*)$/); + $self->{queries}->{$1} = $2; + push @{$self->{maps_counters}->{queries_results}[0]->{set}->{key_values}}, { name => $1 }; + push @{$self->{custom_keys}}, $1; + } + + $self->{maps_counters_type}[0]->{message_multiple} = $self->{option_results}->{multiple_output} if (defined($self->{option_results}->{multiple_output})); + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{queries_results} = {}; + my (@results, @queries); + + foreach my $label (keys %{$self->{queries}}) { + push @queries, $self->{queries}->{$label}; + } + + my $queries_results = $options{custom}->query(queries => \@queries) if (scalar(@queries) > 0); + + foreach my $result (@{$queries_results}) { + next if (!defined($result->{tags}->{$self->{option_results}->{instance}})); + my $value; + $value = $options{custom}->compute(aggregation => $self->{option_results}->{aggregation}, values => $result->{values}) if (defined($result->{values})); + + $self->{queries_results}->{$result->{tags}->{$self->{option_results}->{instance}}}->{instance} = $result->{tags}->{$self->{option_results}->{instance}}; + $self->{queries_results}->{$result->{tags}->{$self->{option_results}->{instance}}}->{$result->{columns}[1]} = $value; + } + + if (scalar(keys %{$self->{queries_results}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No queries found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Launch queries. + +Examples: + +# perl centreon_plugins.pl --plugin=database::influxdb::plugin --mode=query --hostname=localhost --port=8086 +--query='cpu.utilization.percentage,SELECT last("cpu.utilization.percentage") +AS "cpu.utilization.percentage" FROM "centreon"."autogen"."Cpu" GROUP BY "host"' --instance='host' +--critical-status='%{cpu.utilization.percentage} > 90' +--output="Host '%{instance}' Cpu Utilization: %{cpu.utilization.percentage}%" +--multiple-output='All cpu utilization are ok' --verbose + +# perl centreon_plugins.pl --plugin=database::influxdb::plugin --mode=query --hostname=localhost --port=8086 +--query='load1,SELECT last("load1") AS "load1" FROM "centreon"."autogen"."Load" +GROUP BY "host"' --query='load5,SELECT last("load5") AS "load5" FROM "centreon"."autogen"."Load" +GROUP BY "host"' --query='load15,SELECT last("load15") AS "load15" FROM "centreon"."autogen"."Load" +GROUP BY "host"' --instance='host' --output="Host '%{instance}' Load1: %{load1} Load5: %{load5} +Load15: %{load15}" --multiple-output='All load metrics are ok' --verbose + +=over 8 + +=item B<--query> + +Set a InfluxQL query. Query option must be like --query='label,query'. + +Query must contain an "AS" keyword to rename the column +of the selected data, and must match the label. + +(Example: --query='mymetric,SELECT the_data AS "mymetric" +FROM "database"."retention"."measurement" GROUP BY "instance"') + +=item B<--instance> + +Set the instance label on which the results should be calculate for (Example: --instance='name'). + +The instance label must be the same label as the "GROUP BY" keyword. + +=item B<--output> + +Set the output for each instances (Example: --output='Object %{instance} value is {label}'). + +=item B<--multiple-output> + +Set the global output in case everything is fine for multiple instances +(Example: --multiple-output='All instance values are ok'). + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). + +Can use special variables like %{instance} and any other +labels you set through --query. + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). + +Can use special variables like %{instance} and any other +labels you set through --query. + +=item B<--aggregation> + +Set the aggregation on metric values (Can be: 'average', 'min', 'max', 'sum') +(Default: 'average'). + +=over 8 + +=back + +=cut diff --git a/database/influxdb/mode/writestatistics.pm b/database/influxdb/mode/writestatistics.pm new file mode 100644 index 000000000..bbc6be578 --- /dev/null +++ b/database/influxdb/mode/writestatistics.pm @@ -0,0 +1,140 @@ +# +# Copyright 2019 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 database::influxdb::mode::writestatistics; + +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 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'points-written', nlabel => 'points.written.persecond', set => { + key_values => [ { name => 'pointReq', diff => 1 } ], + per_second => 1, + output_template => 'Points Written: %.2f/s', + perfdatas => [ + { value => 'pointReq_per_second', template => '%.2f', min => 0 }, + ], + } + }, + { label => 'writes-ok', nlabel => 'writes.ok.persecond', set => { + key_values => [ { name => 'writeOk', diff => 1 } ], + per_second => 1, + output_template => 'Writes Ok: %.2f/s', + perfdatas => [ + { value => 'writeOk_per_second', template => '%.2f', min => 0 }, + ], + } + }, + { label => 'writes-error', nlabel => 'writes.error.persecond', set => { + key_values => [ { name => 'writeError', diff => 1 } ], + per_second => 1, + output_template => 'Writes Error: %.2f/s', + perfdatas => [ + { value => 'writeError_per_second', template => '%.2f', min => 0 }, + ], + } + }, + { label => 'writes-drop', nlabel => 'writes.drop.persecond', set => { + key_values => [ { name => 'writeDrop', diff => 1 } ], + per_second => 1, + output_template => 'Writes Drop: %.2f/s', + perfdatas => [ + { value => 'writeDrop_per_second', template => '%.2f', min => 0 }, + ], + } + }, + { label => 'writes-timeout', nlabel => 'writes.timeout.persecond', set => { + key_values => [ { name => 'writeTimeout', diff => 1 } ], + per_second => 1, + output_template => 'Writes Timeout: %.2f/s', + perfdatas => [ + { value => 'writeTimeout_per_second', template => '%.2f', min => 0 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{custom} = $options{custom}; + + $self->{global} = {}; + + my $results = $self->{custom}->query(queries => [ "SHOW STATS FOR 'write'" ]); + + my $i = 0; + foreach my $column (@{$$results[0]->{columns}}) { + $column =~ s/influxdb_//; + $self->{global}->{$column} = $$results[0]->{values}[0][$i]; + $i++; + } + + $self->{cache_name} = "influxdb_" . $self->{mode} . '_' . $self->{custom}->get_hostname() . '_' . $self->{custom}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check writes statistics to the data node. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'points-written', 'writes-ok', 'writes-error', +'writes-drop', 'writes-timeout'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'points-written', 'writes-ok', 'writes-error', +'writes-drop', 'writes-timeout'. + +=back + +=cut diff --git a/database/influxdb/plugin.pm b/database/influxdb/plugin.pm new file mode 100644 index 000000000..b39340f0e --- /dev/null +++ b/database/influxdb/plugin.pm @@ -0,0 +1,54 @@ +# +# Copyright 2019 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 database::influxdb::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'connection-time' => 'database::influxdb::mode::connectiontime', + 'database-statistics' => 'database::influxdb::mode::databasestatistics', + 'http-server-statistics' => 'database::influxdb::mode::httpserverstatistics', + 'list-databases' => 'database::influxdb::mode::listdatabases', + 'query' => 'database::influxdb::mode::query', + 'write-statistics' => 'database::influxdb::mode::writestatistics', + ); + + $self->{custom_modes}{api} = 'database::influxdb::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check InfluxDB server. + +=cut diff --git a/database/informix/snmp/mode/archivelevel0.pm b/database/informix/snmp/mode/archivelevel0.pm new file mode 100644 index 000000000..03ecb3b45 --- /dev/null +++ b/database/informix/snmp/mode/archivelevel0.pm @@ -0,0 +1,154 @@ +# +# Copyright 2019 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 database::informix::snmp::mode::archivelevel0; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use DateTime; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'dbspace', type => 1, cb_prefix_output => 'prefix_dbspace_output', message_multiple => 'All dbspace backups are ok' } + ]; + + $self->{maps_counters}->{dbspace} = [ + { label => 'time', set => { + key_values => [ { name => 'seconds' }, { name => 'date'}, { name => 'display' } ], + output_template => "archive level0 last execution date '%s'", + output_use => 'date_absolute', + perfdatas => [ + { label => 'seconds', value => 'seconds_absolute', template => '%s', min => 0, unit => 's', + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_dbspace_output { + my ($self, %options) = @_; + + return "Dbspace '" . $options{instance_value}->{display} . "' "; +} + +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' }, + "timezone:s" => { name => 'timezone' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->{option_results}->{timezone} = 'GMT' if (!defined($self->{option_results}->{timezone}) || $self->{option_results}->{timezone} eq ''); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_applName = '.1.3.6.1.2.1.27.1.1.2'; + my $oid_onDbspaceName = '.1.3.6.1.4.1.893.1.1.1.6.1.2'; + my $oid_onDbspaceLastFullBackupDate = '.1.3.6.1.4.1.893.1.1.1.6.1.15'; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_applName }, + { oid => $oid_onDbspaceName }, + { oid => $oid_onDbspaceLastFullBackupDate }, + ], return_type => 1, nothing_quit => 1 + ); + + my $tz = centreon::plugins::misc::set_timezone(name => $self->{option_results}->{timezone}); + $self->{dbspace} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$oid_onDbspaceName\.(.*?)\.(.*)/); + my ($applIndex, $dbSpaceIndex) = ($1, $2); + + my $name = 'default'; + $name = $snmp_result->{$oid_applName . '.' . $applIndex} + if (defined($snmp_result->{$oid_applName . '.' . $applIndex})); + $name .= '.' . $snmp_result->{$oid_onDbspaceName . '.' . $applIndex. '.' . $dbSpaceIndex}; + + 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; + } + + my ($seconds, $date) = (-1, 'never'); + if (defined($snmp_result->{$oid_onDbspaceLastFullBackupDate . '.' . $applIndex. '.' . $dbSpaceIndex})) { + my @dates = unpack('n C6 a C2', $snmp_result->{$oid_onDbspaceLastFullBackupDate . '.' . $applIndex. '.' . $dbSpaceIndex}); + if ($dates[0] != 0) { + my $dt = DateTime->new(year => $dates[0], month => $dates[1], day => $dates[2], hour => $dates[3], minute => $dates[4], second => $dates[5], %$tz); + $seconds = time() - $dt->epoch; + $date = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $dates[0], $dates[1], $dates[2], $dates[3], $dates[4], $dates[5]); + } + } + $self->{dbspace}->{$name} = { + display => $name, + seconds => $seconds, + date => $date, + }; + } + + if (scalar(keys %{$self->{dbspace}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No dbspace found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check last full backup. + +=over 8 + +=item B<--filter-name> + +Filter dbspace name (can be a regexp). + +=item B<--warning-time> + +Threshold warning in seconds. + +=item B<--critical-time> + +Threshold critical in seconds. + +=back + +=cut diff --git a/database/informix/snmp/mode/chunkstatus.pm b/database/informix/snmp/mode/chunkstatus.pm new file mode 100644 index 000000000..94cc99ea5 --- /dev/null +++ b/database/informix/snmp/mode/chunkstatus.pm @@ -0,0 +1,176 @@ +# +# Copyright 2019 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 database::informix::snmp::mode::chunkstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("status is '%s'", $self->{result_values}->{status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'chunk', type => 1, cb_prefix_output => 'prefix_chunk_output', message_multiple => 'All chunks are ok' } + ]; + + $self->{maps_counters}->{chunk} = [ + { label => 'status', set => { + key_values => [ { name => 'status' }, { 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 => \&catalog_status_threshold, + } + }, + ]; +} + +sub prefix_chunk_output { + my ($self, %options) = @_; + + return "Chunk '" . $options{instance_value}->{display} . "' "; +} + +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' }, + "unknown-status:s" => { name => 'unknown_status' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /inconsistent/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['unknown_status', 'warning_status', 'critical_status']); +} + +my %mapping_status = ( + 1 => 'offline', 2 => 'online', 3 => 'recovering', 4 => 'inconsistent', 5 => 'dropped', +); + +my $mapping = { + onChunkFileName => { oid => '.1.3.6.1.4.1.893.1.1.1.7.1.2' }, + onChunkStatus => { oid => '.1.3.6.1.4.1.893.1.1.1.7.1.7', map => \%mapping_status }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_applName = '.1.3.6.1.2.1.27.1.1.2'; + my $oid_onDbspaceName = '.1.3.6.1.4.1.893.1.1.1.6.1.2'; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_applName }, + { oid => $oid_onDbspaceName }, + { oid => $mapping->{onChunkFileName}->{oid} }, + { oid => $mapping->{onChunkStatus}->{oid} }, + ], return_type => 1, nothing_quit => 1 + ); + + $self->{chunk} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{onChunkFileName}->{oid}\.(.*?)\.(.*?)\.(.*)/); + my ($applIndex, $dbSpaceIndex, $chunkIndex) = ($1, $2, $3); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $applIndex . '.' . $dbSpaceIndex . '.' . $chunkIndex); + + my $name = 'default'; + $name = $snmp_result->{$oid_applName . '.' . $applIndex} + if (defined($snmp_result->{$oid_applName . '.' . $applIndex})); + $name .= '.' . $snmp_result->{$oid_onDbspaceName . '.' . $applIndex. '.' . $dbSpaceIndex}; + $name .= '.' . $result->{onChunkFileName}; + + 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->{chunk}->{$name} = { + display => $name, + status => $result->{onChunkStatus}, + }; + } + + if (scalar(keys %{$self->{chunk}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No chunk found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check chunk status. + +=over 8 + +=item B<--filter-name> + +Filter chunk name (can be a regexp). + +=item B<--unknown-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=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} =~ /inconsistent/'). +Can used special variables like: %{status}, %{display} + +=back + +=cut diff --git a/database/informix/snmp/mode/dbspaceusage.pm b/database/informix/snmp/mode/dbspaceusage.pm new file mode 100644 index 000000000..2e5a7774f --- /dev/null +++ b/database/informix/snmp/mode/dbspaceusage.pm @@ -0,0 +1,138 @@ +# +# Copyright 2019 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 database::informix::snmp::mode::dbspaceusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 1, cb_prefix_output => 'prefix_dbspace_output', message_multiple => 'All dbspaces usage are ok' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'usage', set => { + key_values => [ { name => 'prct_used' }, { name => 'display' } ], + output_template => 'Used: %.2f%%', + perfdatas => [ + { label => 'used', value => 'prct_used_absolute', template => '%.2f', min => 0, max => 100, unit => '%', + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_dbspace_output { + my ($self, %options) = @_; + + return "Dbspace '" . $options{instance_value}->{display} . "' "; +} + +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' }, + }); + + return $self; +} + +my $mapping = { + onDbspaceName => { oid => '.1.3.6.1.4.1.893.1.1.1.6.1.2' }, + onDbspacePagesAllocated => { oid => '.1.3.6.1.4.1.893.1.1.1.6.1.11' }, + onDbspacePagesUsed => { oid => '.1.3.6.1.4.1.893.1.1.1.6.1.12' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_applName = '.1.3.6.1.2.1.27.1.1.2'; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_applName }, + { oid => $mapping->{onDbspaceName}->{oid} }, + { oid => $mapping->{onDbspacePagesAllocated}->{oid} }, + { oid => $mapping->{onDbspacePagesUsed}->{oid} }, + ], return_type => 1, nothing_quit => 1 + ); + + $self->{global} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{onDbspaceName}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + my $name = 'default'; + $name = $snmp_result->{$oid_applName}->{$oid_applName . '.' . $instance} + if (defined($snmp_result->{$oid_applName}->{$oid_applName . '.' . $instance})); + $name .= '.' . $result->{onDbspaceName}; + + 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->{global}->{$name} = { + display => $name, + prct_used => $result->{onDbspacePagesUsed} * 100 / $result->{onDbspacePagesAllocated}, + }; + } + + if (scalar(keys %{$self->{global}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No dbspace found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check dbspaces usage. + +=over 8 + +=item B<--filter-name> + +Filter dbspace name (can be a regexp). + +=item B<--warning-usage> + +Threshold warning in percent. + +=item B<--critical-usage> + +Threshold critical in percent. + +=back + +=cut diff --git a/database/informix/snmp/mode/globalcache.pm b/database/informix/snmp/mode/globalcache.pm new file mode 100644 index 000000000..490ded242 --- /dev/null +++ b/database/informix/snmp/mode/globalcache.pm @@ -0,0 +1,158 @@ +# +# Copyright 2019 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 database::informix::snmp::mode::globalcache; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub custom_usage_calc { + my ($self, %options) = @_; + + my $diff_logical = $options{new_datas}->{$self->{instance} . '_rdbmsSrvInfoLogical' . $options{extra_options}->{label_ref}} - + $options{old_datas}->{$self->{instance} . '_rdbmsSrvInfoLogical' . $options{extra_options}->{label_ref}}; + my $diff_disk = $options{new_datas}->{$self->{instance} . '_rdbmsSrvInfoDisk' . $options{extra_options}->{label_ref}} - + $options{old_datas}->{$self->{instance} . '_rdbmsSrvInfoDisk' . $options{extra_options}->{label_ref}}; + $self->{result_values}->{prct} = $diff_logical <= 0 ? 0 : (100 * ($diff_logical - $diff_disk) / $diff_logical); + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 1, cb_prefix_output => 'prefix_instances_output', message_multiple => 'All instances are ok' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'read', set => { + key_values => [ { name => 'rdbmsSrvInfoDiskReads', diff => 1 }, { name => 'rdbmsSrvInfoLogicalReads', diff => 1 }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_calc_extra_options => { label_ref => 'Reads' }, + output_template => 'Read Cached hitrate at %.2f%%', + threshold_use => 'prct', output_use => 'prct', + perfdatas => [ + { label => 'read', value => 'prct', template => '%.2f', min => 0, max => 100, unit => '%', + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write', set => { + key_values => [ { name => 'rdbmsSrvInfoDiskWrites', diff => 1 }, { name => 'rdbmsSrvInfoLogicalWrites', diff => 1 }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_calc_extra_options => { label_ref => 'Writes' }, + output_template => 'Write Cached hitrate at %.2f%%', + threshold_use => 'prct', output_use => 'prct', + perfdatas => [ + { label => 'write', value => 'prct', template => '%.2f', min => 0, max => 100, unit => '%', + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_instances_output { + my ($self, %options) = @_; + + return "Instance '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +my $mapping = { + rdbmsSrvInfoDiskReads => { oid => '.1.3.6.1.2.1.39.1.6.1.3' }, + rdbmsSrvInfoLogicalReads => { oid => '.1.3.6.1.2.1.39.1.6.1.4' }, + rdbmsSrvInfoDiskWrites => { oid => '.1.3.6.1.2.1.39.1.6.1.5' }, + rdbmsSrvInfoLogicalWrites => { oid => '.1.3.6.1.2.1.39.1.6.1.6' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_applName = '.1.3.6.1.2.1.27.1.1.2'; + my $oid_rdbmsSrvInfoEntry = '.1.3.6.1.2.1.39.1.6.1'; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_applName }, + { oid => $oid_rdbmsSrvInfoEntry, start => $mapping->{rdbmsSrvInfoDiskReads}->{oid}, end => $mapping->{rdbmsSrvInfoLogicalWrites}->{oid} }, + ], nothing_quit => 1 + ); + + $self->{global} = {}; + foreach my $oid (keys %{$snmp_result->{$oid_rdbmsSrvInfoEntry}}) { + next if ($oid !~ /^$mapping->{rdbmsSrvInfoDiskReads}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result->{$oid_rdbmsSrvInfoEntry}, instance => $instance); + + my $name = 'default'; + $name = $snmp_result->{$oid_applName}->{$oid_applName . '.' . $instance} + if (defined($snmp_result->{$oid_applName}->{$oid_applName . '.' . $instance})); + + $self->{global}->{$name} = { + display => $name, + %$result + }; + } + + $self->{cache_name} = "informix_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check write/read cached. + +=over 8 + +=item B<--warning-read> + +Threshold read cached warning in percent. + +=item B<--critical-read> + +Threshold read cached critical in percent. + +=item B<--warning-write> + +Threshold write cached warning in percent. + +=item B<--critical-write> + +Threshold write cached critical in percent. + +=back + +=cut diff --git a/database/informix/snmp/mode/listdbspaces.pm b/database/informix/snmp/mode/listdbspaces.pm new file mode 100644 index 000000000..5b4f9774e --- /dev/null +++ b/database/informix/snmp/mode/listdbspaces.pm @@ -0,0 +1,134 @@ +# +# Copyright 2019 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 database::informix::snmp::mode::listdbspaces; + +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-instance:s" => { name => 'filter_instance' }, + "filter-dbspace:s" => { name => 'filter_dbspace' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_applName = '.1.3.6.1.2.1.27.1.1.2'; + my $oid_onDbspaceName = '.1.3.6.1.4.1.893.1.1.1.6.1.2'; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_applName }, + { oid => $oid_onDbspaceName }, + ], nothing_quit => 1); + + $self->{dbspace} = {}; + foreach my $oid (keys %{$snmp_result->{$oid_onDbspaceName}}) { + $oid =~ /^$oid_onDbspaceName\.(.*?)\.(.*)/; + my ($applIndex, $dbSpaceIndex) = ($1, $2); + + my $instance = 'default'; + $instance = $snmp_result->{$oid_applName}->{$oid_applName . '.' . $applIndex} + if (defined($snmp_result->{$oid_applName}->{$oid_applName . '.' . $applIndex})); + my $dbspace = $snmp_result->{$oid_onDbspaceName}->{$oid}; + if (defined($self->{option_results}->{filter_instance}) && $self->{option_results}->{filter_instance} ne '' && + $instance !~ /$self->{option_results}->{filter_instance}/) { + $self->{output}->output_add(long_msg => "skipping instance '" . $instance . "': no matching filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_dbspace}) && $self->{option_results}->{filter_dbspace} ne '' && + $dbspace !~ /$self->{option_results}->{filter_dbspace}/) { + $self->{output}->output_add(long_msg => "skipping dbspace '" . $dbspace . "': no matching filter.", debug => 1); + next; + } + + $self->{dbspace}->{$applIndex . '.' . $dbSpaceIndex} = { + instance => $instance, + dbspace => $dbspace, + }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{dbspace}}) { + $self->{output}->output_add(long_msg => '[instance = ' . $self->{dbspace}->{$instance}->{instance} . + "] [dbspace = '" . $self->{dbspace}->{$instance}->{dbspace} . "']"); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List dbspaces:'); + $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 => ['instance', 'dbspace']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{dbspace}}) { + $self->{output}->add_disco_entry( + instance => $self->{dbspace}->{$instance}->{instance}, + dbspace => $self->{dbspace}->{$instance}->{dbspace}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List informix instances. + +=over 8 + +=item B<--filter-instance> + +Filter by instance name (can be a regexp). + +=back + +=cut + diff --git a/database/informix/snmp/mode/listinstances.pm b/database/informix/snmp/mode/listinstances.pm new file mode 100644 index 000000000..0a2b46736 --- /dev/null +++ b/database/informix/snmp/mode/listinstances.pm @@ -0,0 +1,114 @@ +# +# Copyright 2019 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 database::informix::snmp::mode::listinstances; + +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-instance:s" => { name => 'filter_instance' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_applName = '.1.3.6.1.2.1.27.1.1.2'; + my $snmp_result = $options{snmp}->get_table(oid => $oid_applName); + $self->{instance} = {}; + foreach my $oid (keys %{$snmp_result}) { + my $name = $snmp_result->{$oid}; + if (defined($self->{option_results}->{filter_instance}) && $self->{option_results}->{filter_instance} ne '' && + $name !~ /$self->{option_results}->{filter_instance}/) { + $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{instance}->{$name} = { instance => $name }; + } + + if (scalar(keys %{$self->{instance}}) == 0) { + $self->{instance}->{default} = { instance => 'default' }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{instance}}) { + $self->{output}->output_add(long_msg => '[instance = ' . $self->{instance}->{$instance}->{instance} . ']'); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List instances:'); + $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 => ['instance']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{instance}}) { + $self->{output}->add_disco_entry(instance => $self->{instance}->{$instance}->{instance}); + } +} + +1; + +__END__ + +=head1 MODE + +List informix instances. + +=over 8 + +=item B<--filter-instance> + +Filter by instance name (can be a regexp). + +=back + +=cut + diff --git a/database/informix/snmp/mode/lockstats.pm b/database/informix/snmp/mode/lockstats.pm new file mode 100644 index 000000000..dd5706fc6 --- /dev/null +++ b/database/informix/snmp/mode/lockstats.pm @@ -0,0 +1,156 @@ +# +# Copyright 2019 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 database::informix::snmp::mode::lockstats; + +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 => 1, cb_prefix_output => 'prefix_instances_output', message_multiple => 'All instances are ok' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'lock-dead', set => { + key_values => [ { name => 'onServerDeadLocks', diff => 1 }, { name => 'display' } ], + output_template => 'Deadlocks %d', + perfdatas => [ + { label => 'lock_dead', value => 'onServerDeadLocks_absolute', template => '%s', min => 0, + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'lock-wait', set => { + key_values => [ { name => 'onServerLockWaits', diff => 1 }, { name => 'display' } ], + output_template => 'Lock Waits %d', + perfdatas => [ + { label => 'lock_wait', value => 'onServerLockWaits_absolute', template => '%s', min => 0, + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'lock-request', set => { + key_values => [ { name => 'onServerLockRequests', diff => 1 }, { name => 'display' } ], + output_template => 'Lock Requests %d', + perfdatas => [ + { label => 'lock_request', value => 'onServerLockRequests_absolute', template => '%s', min => 0, + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'lock-timeout', set => { + key_values => [ { name => 'onServerLockTimeouts', diff => 1 }, { name => 'display' } ], + output_template => 'Lock Timeouts %d', + perfdatas => [ + { label => 'lock_timeout', value => 'onServerLockTimeouts_absolute', template => '%s', min => 0, + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_instances_output { + my ($self, %options) = @_; + + return "Instance '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +my $mapping = { + onServerLockRequests => { oid => '.1.3.6.1.4.1.893.1.1.1.1.1.11' }, + onServerLockWaits => { oid => '.1.3.6.1.4.1.893.1.1.1.1.1.12' }, + onServerDeadLocks => { oid => '.1.3.6.1.4.1.893.1.1.1.1.1.16' }, + onServerLockTimeouts => { oid => '.1.3.6.1.4.1.893.1.1.1.1.1.17' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_applName = '.1.3.6.1.2.1.27.1.1.2'; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_applName }, + { oid => $mapping->{onServerLockWaits}->{oid} }, + { oid => $mapping->{onServerLockRequests}->{oid} }, + { oid => $mapping->{onServerDeadLocks}->{oid} }, + { oid => $mapping->{onServerLockTimeouts}->{oid} }, + ], return_type => 1, nothing_quit => 1 + ); + + $self->{global} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{onServerLockRequests}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + my $name = 'default'; + $name = $snmp_result->{$oid_applName . '.' . $instance} + if (defined($snmp_result->{$oid_applName . '.' . $instance})); + + $self->{global}->{$name} = { + display => $name, + %$result + }; + } + + $self->{cache_name} = "informix_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check instance locks. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'lock-dead', 'lock-wait', 'lock-request', 'lock-timeout'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'lock-dead', 'lock-wait', 'lock-request', 'lock-timeout'. + +=back + +=cut diff --git a/database/informix/snmp/mode/logfileusage.pm b/database/informix/snmp/mode/logfileusage.pm new file mode 100644 index 000000000..d7f68160e --- /dev/null +++ b/database/informix/snmp/mode/logfileusage.pm @@ -0,0 +1,144 @@ +# +# Copyright 2019 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 database::informix::snmp::mode::logfileusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 1, cb_prefix_output => 'prefix_dbspace_output', message_multiple => 'All dbspace log files usage are ok' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'usage', set => { + key_values => [ { name => 'prct_used' }, { name => 'display' } ], + output_template => 'Log Files Used: %.2f%%', + perfdatas => [ + { label => 'used', value => 'prct_used_absolute', template => '%.2f', min => 0, max => 100, unit => '%', + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_dbspace_output { + my ($self, %options) = @_; + + return "Dbspace '" . $options{instance_value}->{display} . "' "; +} + +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' }, + }); + + return $self; +} + +my $mapping = { + onLogicalLogDbspace => { oid => '.1.3.6.1.4.1.893.1.1.1.8.1.3' }, + onLogicalLogPagesAllocated => { oid => '.1.3.6.1.4.1.893.1.1.1.8.1.7' }, + onLogicalLogPagesUsed => { oid => '.1.3.6.1.4.1.893.1.1.1.8.1.8' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_applName = '.1.3.6.1.2.1.27.1.1.2'; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_applName }, + { oid => $mapping->{onLogicalLogDbspace}->{oid} }, + { oid => $mapping->{onLogicalLogPagesAllocated}->{oid} }, + { oid => $mapping->{onLogicalLogPagesUsed}->{oid} }, + ], return_type => 1, nothing_quit => 1 + ); + + $self->{global} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{onLogicalLogDbspace}->{oid}\.(.*?)\.(.*)/); + my ($applIndex, $logIndex) = ($1, $2); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $applIndex . '.' . $logIndex); + + my $name = 'default'; + $name = $snmp_result->{$oid_applName . '.' . $applIndex} + if (defined($snmp_result->{$oid_applName . '.' . $applIndex})); + $name .= '.' . $result->{onLogicalLogDbspace}; + + 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; + } + + if (!defined($self->{global}->{$name})) { + $self->{global}->{$name} = { display => $name, allocated => 0, used => 0 }; + } + + $self->{global}->{$name}->{allocated} += $result->{onLogicalLogPagesAllocated}; + $self->{global}->{$name}->{used} += $result->{onLogicalLogPagesUsed}; + } + + foreach (keys %{$self->{global}}) { + $self->{global}->{$_}->{prct_used} = $self->{global}->{$_}->{used} * 100 / $self->{global}->{$_}->{allocated}; + } + + if (scalar(keys %{$self->{global}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No dbspace found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check log files usage. + +=over 8 + +=item B<--filter-name> + +Filter dbspace name (can be a regexp). + +=item B<--warning-usage> + +Threshold warning in percent. + +=item B<--critical-usage> + +Threshold critical in percent. + +=back + +=cut diff --git a/database/informix/snmp/mode/sessions.pm b/database/informix/snmp/mode/sessions.pm new file mode 100644 index 000000000..c14682bdd --- /dev/null +++ b/database/informix/snmp/mode/sessions.pm @@ -0,0 +1,119 @@ +# +# Copyright 2019 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 database::informix::snmp::mode::sessions; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 1, cb_prefix_output => 'prefix_instances_output', message_multiple => 'All instances are ok' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'sessions', set => { + key_values => [ { name => 'sessions' }, { name => 'display' } ], + output_template => '%d client sessions', + perfdatas => [ + { label => 'sessions', value => 'sessions_absolute', template => '%s', min => 0, + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_instances_output { + my ($self, %options) = @_; + + return "Instance '" . $options{instance_value}->{display} . "' "; +} + +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 => { + }); + + return $self; +} + +my $mapping = { + onSessionUserName => { oid => '.1.3.6.1.4.1.893.1.1.1.10.1.2' }, + onSessionUserProcessId => { oid => '.1.3.6.1.4.1.893.1.1.1.10.1.4' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_applName = '.1.3.6.1.2.1.27.1.1.2'; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_applName }, + { oid => $mapping->{onSessionUserName}->{oid} }, + { oid => $mapping->{onSessionUserProcessId}->{oid} }, + ], return_type => 1, nothing_quit => 1 + ); + + $self->{global} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{onSessionUserName}->{oid}\.(.*?)\.(.*)/); + my ($applIndex, $sessionIndex) = ($1, $2); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $applIndex . '.' . $sessionIndex); + + my $name = 'default'; + $name = $snmp_result->{$oid_applName . '.' . $applIndex} + if (defined($snmp_result->{$oid_applName . '.' . $applIndex})); + + if (!defined($self->{global}->{$name})) { + $self->{global}->{$name} = { display => $name, sessions => 0 }; + } + $self->{global}->{$name}->{sessions}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check number of open sessions ('informix' user is not counted). + +=over 8 + +=item B<--warning-sessions> + +Threshold warning. + +=item B<--critical-sessions> + +Threshold critical. + +=back + +=cut diff --git a/database/informix/snmp/plugin.pm b/database/informix/snmp/plugin.pm new file mode 100644 index 000000000..1a145665d --- /dev/null +++ b/database/informix/snmp/plugin.pm @@ -0,0 +1,56 @@ +# +# Copyright 2019 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 database::informix::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}} = ( + 'archivelevel0' => 'database::informix::snmp::mode::archivelevel0', + 'chunk-status' => 'database::informix::snmp::mode::chunkstatus', + 'dbspace-usage' => 'database::informix::snmp::mode::dbspaceusage', + 'global-cache' => 'database::informix::snmp::mode::globalcache', + 'list-dbspaces' => 'database::informix::snmp::mode::listdbspaces', + 'list-instances' => 'database::informix::snmp::mode::listinstances', + 'lock-stats' => 'database::informix::snmp::mode::lockstats', + 'logfile-usage' => 'database::informix::snmp::mode::logfileusage', + 'sessions' => 'database::informix::snmp::mode::sessions', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Informix in SNMP. + +=cut diff --git a/database/informix/mode/archivelevel0.pm b/database/informix/sql/mode/archivelevel0.pm similarity index 99% rename from database/informix/mode/archivelevel0.pm rename to database/informix/sql/mode/archivelevel0.pm index c3a379803..934912976 100644 --- a/database/informix/mode/archivelevel0.pm +++ b/database/informix/sql/mode/archivelevel0.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package database::informix::mode::archivelevel0; +package database::informix::sql::mode::archivelevel0; use base qw(centreon::plugins::mode); diff --git a/database/informix/mode/checkpoints.pm b/database/informix/sql/mode/checkpoints.pm similarity index 99% rename from database/informix/mode/checkpoints.pm rename to database/informix/sql/mode/checkpoints.pm index 708e17593..4fc7e7cc1 100644 --- a/database/informix/mode/checkpoints.pm +++ b/database/informix/sql/mode/checkpoints.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package database::informix::mode::checkpoints; +package database::informix::sql::mode::checkpoints; use base qw(centreon::plugins::mode); diff --git a/database/informix/mode/chunkstates.pm b/database/informix/sql/mode/chunkstates.pm similarity index 99% rename from database/informix/mode/chunkstates.pm rename to database/informix/sql/mode/chunkstates.pm index 12f0c92e3..287cb6989 100644 --- a/database/informix/mode/chunkstates.pm +++ b/database/informix/sql/mode/chunkstates.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package database::informix::mode::chunkstates; +package database::informix::sql::mode::chunkstates; use base qw(centreon::plugins::mode); diff --git a/database/informix/mode/dbspacesusage.pm b/database/informix/sql/mode/dbspacesusage.pm similarity index 99% rename from database/informix/mode/dbspacesusage.pm rename to database/informix/sql/mode/dbspacesusage.pm index 4ff51e773..fcabe13dd 100644 --- a/database/informix/mode/dbspacesusage.pm +++ b/database/informix/sql/mode/dbspacesusage.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package database::informix::mode::dbspacesusage; +package database::informix::sql::mode::dbspacesusage; use base qw(centreon::plugins::mode); diff --git a/database/informix/mode/globalcache.pm b/database/informix/sql/mode/globalcache.pm similarity index 99% rename from database/informix/mode/globalcache.pm rename to database/informix/sql/mode/globalcache.pm index daa58f972..9b4d9e55e 100644 --- a/database/informix/mode/globalcache.pm +++ b/database/informix/sql/mode/globalcache.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package database::informix::mode::globalcache; +package database::informix::sql::mode::globalcache; use base qw(centreon::plugins::mode); diff --git a/database/informix/mode/listdatabases.pm b/database/informix/sql/mode/listdatabases.pm similarity index 98% rename from database/informix/mode/listdatabases.pm rename to database/informix/sql/mode/listdatabases.pm index e1f350288..05a7dacd6 100644 --- a/database/informix/mode/listdatabases.pm +++ b/database/informix/sql/mode/listdatabases.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package database::informix::mode::listdatabases; +package database::informix::sql::mode::listdatabases; use base qw(centreon::plugins::mode); diff --git a/database/informix/mode/listdbspaces.pm b/database/informix/sql/mode/listdbspaces.pm similarity index 98% rename from database/informix/mode/listdbspaces.pm rename to database/informix/sql/mode/listdbspaces.pm index 699da21cd..c20b47d0f 100644 --- a/database/informix/mode/listdbspaces.pm +++ b/database/informix/sql/mode/listdbspaces.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package database::informix::mode::listdbspaces; +package database::informix::sql::mode::listdbspaces; use base qw(centreon::plugins::mode); diff --git a/database/informix/mode/lockoverflow.pm b/database/informix/sql/mode/lockoverflow.pm similarity index 98% rename from database/informix/mode/lockoverflow.pm rename to database/informix/sql/mode/lockoverflow.pm index 86c9e6f42..fbd0764a5 100644 --- a/database/informix/mode/lockoverflow.pm +++ b/database/informix/sql/mode/lockoverflow.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package database::informix::mode::lockoverflow; +package database::informix::sql::mode::lockoverflow; use base qw(centreon::plugins::mode); diff --git a/database/informix/mode/logfilesusage.pm b/database/informix/sql/mode/logfilesusage.pm similarity index 98% rename from database/informix/mode/logfilesusage.pm rename to database/informix/sql/mode/logfilesusage.pm index 3381c84d5..6a6579748 100644 --- a/database/informix/mode/logfilesusage.pm +++ b/database/informix/sql/mode/logfilesusage.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package database::informix::mode::logfilesusage; +package database::informix::sql::mode::logfilesusage; use base qw(centreon::plugins::mode); diff --git a/database/informix/mode/longtxs.pm b/database/informix/sql/mode/longtxs.pm similarity index 98% rename from database/informix/mode/longtxs.pm rename to database/informix/sql/mode/longtxs.pm index 6e08a2fa4..d128fd5d8 100644 --- a/database/informix/mode/longtxs.pm +++ b/database/informix/sql/mode/longtxs.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package database::informix::mode::longtxs; +package database::informix::sql::mode::longtxs; use base qw(centreon::plugins::mode); diff --git a/database/informix/mode/sessions.pm b/database/informix/sql/mode/sessions.pm similarity index 98% rename from database/informix/mode/sessions.pm rename to database/informix/sql/mode/sessions.pm index 0ef882327..9038a259c 100644 --- a/database/informix/mode/sessions.pm +++ b/database/informix/sql/mode/sessions.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package database::informix::mode::sessions; +package database::informix::sql::mode::sessions; use base qw(centreon::plugins::mode); diff --git a/database/informix/mode/tablelocks.pm b/database/informix/sql/mode/tablelocks.pm similarity index 99% rename from database/informix/mode/tablelocks.pm rename to database/informix/sql/mode/tablelocks.pm index 0666329a9..a49d0b737 100644 --- a/database/informix/mode/tablelocks.pm +++ b/database/informix/sql/mode/tablelocks.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package database::informix::mode::tablelocks; +package database::informix::sql::mode::tablelocks; use base qw(centreon::plugins::mode); diff --git a/database/informix/plugin.pm b/database/informix/sql/plugin.pm similarity index 91% rename from database/informix/plugin.pm rename to database/informix/sql/plugin.pm index 12ef57fa3..be6c5dfca 100644 --- a/database/informix/plugin.pm +++ b/database/informix/sql/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package database::informix::plugin; +package database::informix::sql::plugin; use strict; use warnings; @@ -33,19 +33,19 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'archivelevel0' => 'database::informix::mode::archivelevel0', - 'checkpoints' => 'database::informix::mode::checkpoints', - 'chunkstates' => 'database::informix::mode::chunkstates', + 'archivelevel0' => 'database::informix::sql::mode::archivelevel0', + 'checkpoints' => 'database::informix::sql::mode::checkpoints', + 'chunkstates' => 'database::informix::sql::mode::chunkstates', 'connection-time' => 'centreon::common::protocols::sql::mode::connectiontime', - 'global-cache' => 'database::informix::mode::globalcache', - 'list-dbspaces' => 'database::informix::mode::listdbspaces', - 'list-databases' => 'database::informix::mode::listdatabases', - 'lockoverflow' => 'database::informix::mode::lockoverflow', - 'longtxs' => 'database::informix::mode::longtxs', - 'dbspace-usage' => 'database::informix::mode::dbspacesusage', - 'logfile-usage' => 'database::informix::mode::logfilesusage', - 'sessions' => 'database::informix::mode::sessions', - 'table-locks' => 'database::informix::mode::tablelocks', + 'global-cache' => 'database::informix::sql::mode::globalcache', + 'list-dbspaces' => 'database::informix::sql::mode::listdbspaces', + 'list-databases' => 'database::informix::sql::mode::listdatabases', + 'lockoverflow' => 'database::informix::sql::mode::lockoverflow', + 'longtxs' => 'database::informix::sql::mode::longtxs', + 'dbspace-usage' => 'database::informix::sql::mode::dbspacesusage', + 'logfile-usage' => 'database::informix::sql::mode::logfilesusage', + 'sessions' => 'database::informix::sql::mode::sessions', + 'table-locks' => 'database::informix::sql::mode::tablelocks', 'sql' => 'centreon::common::protocols::sql::mode::sql', ); diff --git a/database/mongodb/custom/driver.pm b/database/mongodb/custom/driver.pm new file mode 100644 index 000000000..0693cd2e0 --- /dev/null +++ b/database/mongodb/custom/driver.pm @@ -0,0 +1,222 @@ +# +# Copyright 2019 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 database::mongodb::custom::driver; + +use strict; +use warnings; +use DateTime; +use MongoDB; +use Hash::Ordered; +use URI::Encode; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'DRIVER OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : 'localhost'; + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 27017; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; + $self->{username} = (defined($self->{option_results}->{username})) ? $self->{option_results}->{username} : ''; + $self->{password} = (defined($self->{option_results}->{password})) ? $self->{option_results}->{password} : ''; + + return 0; +} + +sub get_hostname { + my ($self, %options) = @_; + + return $self->{hostname}; +} + +sub get_port { + my ($self, %options) = @_; + + return $self->{port}; +} + +sub connect { + my ($self, %options) = @_; + + my $uri = URI::Encode->new({encode_reserved => 1}); + my $encoded_username = $uri->encode($self->{username}); + my $encoded_password = $uri->encode($self->{password}); + + $uri = 'mongodb://'; + $uri .= $encoded_username . ':' . $encoded_password . '@' if ($encoded_username ne '' && $encoded_password ne ''); + $uri .= $self->{hostname} if ($self->{hostname} ne ''); + $uri .= ':' . $self->{port} if ($self->{port} ne ''); + + $self->{output}->output_add(long_msg => 'Connection URI: ' . $uri, debug => 1); + + $self->{client} = MongoDB::MongoClient->new(host => $uri); + $self->{client}->connect(); + + eval { + my $conn_status = $self->run_command( + database => 'admin', + command => $self->ordered_hash(ping => 1), + ); + }; + if ($@) { + $self->{output}->output_add(long_msg => $@, debug => 1); + $self->{output}->add_option_msg(short_msg => "Connection error (add --debug option to display error message)"); + $self->{output}->option_exit(); + } +} + +sub ordered_hash { + my ($self, %options) = @_; + + tie my %hash, 'Hash::Ordered'; + my $oh = tied %hash; + $oh->push(%options); + return \%hash; +} + +sub run_command { + my ($self, %options) = @_; + + if (!defined($self->{client})) { + $self->connect(); + } + + my $db = $self->{client}->get_database($options{database}); + return $db->run_command($options{command}); +} + +sub list_databases { + my ($self, %options) = @_; + + if (!defined($self->{client})) { + $self->connect(); + } + + my @dbs = $self->{client}->database_names; + + return \@dbs; +} + +sub list_collections { + my ($self, %options) = @_; + + if (!defined($self->{client})) { + $self->connect(); + } + + my $db = $self->{client}->get_database($options{database}); + my @cls = $db->collection_names; + + return \@cls; +} + +1; + +__END__ + +=head1 NAME + +MongoDB driver + +=head1 DRIVER OPTIONS + +MongoDB driver + +=over 8 + +=item B<--hostname> + +MongoDB server hostname. + +=item B<--port> + +Port used (Default: 27017) + +=item B<--username> + +MongoDB username. + +=item B<--password> + +MongoDB password. + +=item B<--timeout> + +Set timeout in seconds (Default: 10). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/database/mongodb/mode/collectionstatistics.pm b/database/mongodb/mode/collectionstatistics.pm new file mode 100644 index 000000000..c1486390c --- /dev/null +++ b/database/mongodb/mode/collectionstatistics.pm @@ -0,0 +1,187 @@ +# +# Copyright 2019 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 database::mongodb::mode::collectionstatistics; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'databases', type => 3, cb_long_output => 'long_output', + message_multiple => 'All databases statistics are ok', indent_long_output => ' ', + group => [ + { name => 'collections', display_long => 1, cb_prefix_output => 'prefix_output_collection', + message_multiple => 'All collections statistics are ok', type => 1 }, + ] + } + ]; + + $self->{maps_counters}->{collections} = [ + { label => 'storage-size', nlabel => 'collection.size.storage.bytes', set => { + key_values => [ { name => 'storageSize' }, { name => 'display' } ], + output_template => 'Storage Size: %s %s', + output_change_bytes => 1, + perfdatas => [ + { value => 'storageSize_absolute', template => '%s', + min => 0, unit => 'B', label_extra_instance => 1 }, + ], + } + }, + { label => 'index-size', nlabel => 'collection.size.index.bytes', set => { + key_values => [ { name => 'totalIndexSize' }, { name => 'display' } ], + output_template => 'Index Size: %s %s', + output_change_bytes => 1, + perfdatas => [ + { value => 'totalIndexSize_absolute', template => '%s', + min => 0, unit => 'B', label_extra_instance => 1 }, + ], + } + }, + { label => 'documents', nlabel => 'collection.documents.count', set => { + key_values => [ { name => 'count' }, { name => 'display' } ], + output_template => 'Documents: %s', + perfdatas => [ + { value => 'count_absolute', template => '%s', + min => 0, label_extra_instance => 1 }, + ], + } + }, + { label => 'indexes', nlabel => 'collection.indexes.count', set => { + key_values => [ { name => 'nindexes' }, { name => 'display' } ], + output_template => 'Indexes: %s', + perfdatas => [ + { value => 'nindexes_absolute', template => '%s', + min => 0, label_extra_instance => 1 }, + ], + } + }, + ]; +} + +sub long_output { + my ($self, %options) = @_; + + return "Checking database '" . $options{instance_value}->{display} . "' "; +} + +sub prefix_output_collection { + my ($self, %options) = @_; + + return "Collection '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-database:s" => { name => 'filter_database' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{custom} = $options{custom}; + + $self->{databases} = {}; + + my $databases = $self->{custom}->list_databases(); + + foreach my $database (sort @{$databases}) { + next if (defined($self->{option_results}->{filter_database}) && $self->{option_results}->{filter_database} ne '' + && $database !~ /$self->{option_results}->{filter_database}/); + + my $collections = $self->{custom}->list_collections(database => $database); + + $self->{databases}->{$database}->{display} = $database; + + foreach my $collection (sort @{$collections}) { + my $cl_stats = $self->{custom}->run_command( + database => $database, + command => $self->{custom}->ordered_hash(collStats => $collection), + ); + + $self->{databases}->{$database}->{collections}->{$collection} = { + display => $collection, + storageSize => $cl_stats->{storageSize}, + totalIndexSize => $cl_stats->{totalIndexSize}, + count => $cl_stats->{count}, + nindexes => $cl_stats->{nindexes}, + }; + } + } + + if (scalar(keys %{$self->{databases}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No databases found'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check collections statistics per databases + +=over 8 + +=item B<--filter-database> + +Filter database name (Can use regexp). + +=item B<--warning-subinstance-collection-size-*-bytes> + +Threshold warning. +Can be: 'storage', 'index'. + +=item B<--critical-subinstance-collection-size-*-bytes> + +Threshold critical. +Can be: 'storage', 'index'. + +=item B<--warning-subinstance-collection-*-count> + +Threshold warning. +Can be: 'documents', 'indexes'. + +=item B<--critical-subinstance-collection-*-count> + +Threshold critical. +Can be: 'documents', 'indexes'. + +=back + +=cut diff --git a/database/mongodb/mode/connections.pm b/database/mongodb/mode/connections.pm new file mode 100644 index 000000000..3e05d8f02 --- /dev/null +++ b/database/mongodb/mode/connections.pm @@ -0,0 +1,154 @@ +# +# Copyright 2019 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 database::mongodb::mode::connections; + +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, cb_prefix_output => 'prefix_output' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'active', nlabel => 'connections.active.count', set => { + key_values => [ { name => 'active' } ], + output_template => 'Active: %d', + perfdatas => [ + { value => 'active_absolute', template => '%d', min => 0, unit => 'conn' }, + ], + } + }, + { label => 'current', nlabel => 'connections.current.count', set => { + key_values => [ { name => 'current' } ], + output_template => 'Current: %d', + perfdatas => [ + { value => 'current_absolute', template => '%d', min => 0, unit => 'conn' }, + ], + } + }, + { label => 'usage', nlabel => 'connections.usage.percentage', set => { + key_values => [ { name => 'usage' } ], + output_template => 'Usage: %.2f %%', + perfdatas => [ + { value => 'usage_absolute', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'total-created', nlabel => 'connections.created.persecond', set => { + key_values => [ { name => 'totalCreated', diff => 1 } ], + output_template => 'Created: %.2f/s', + per_second => 1, + perfdatas => [ + { value => 'totalCreated_per_second', template => '%.2f', min => 0, unit => 'conn/s' }, + ], + } + }, + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Connections "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{custom} = $options{custom}; + + $self->{global} = {}; + + my $server_stats = $self->{custom}->run_command( + database => 'admin', + command => $self->{custom}->ordered_hash(serverStatus => 1), + ); + + $self->{global}->{active} = $server_stats->{connections}->{active}; + $self->{global}->{current} = $server_stats->{connections}->{current}; + $self->{global}->{usage} = $server_stats->{connections}->{current} / ($server_stats->{connections}->{current} + $server_stats->{connections}->{available}); + $self->{global}->{totalCreated} = $server_stats->{connections}->{totalCreated}; + + $self->{cache_name} = "mongodb_" . $self->{mode} . '_' . $self->{custom}->get_hostname() . '_' . $self->{custom}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check connections statistics + +=over 8 + +=item B<--warning-connections-*-count> + +Threshold warning. +Can be: 'active', 'current'. + +=item B<--critical-connections-*-count> + +Threshold critical. +Can be: 'active', 'current'. + +=item B<--warning-connections-usage-percentage> + +Threshold warning for connections usage (current over available) + +=item B<--critical-connections-usage-percentage> + +Threshold critical for connections usage (current over available) + +=item B<--warning-connections-created-persecond> + +Threshold warning for connections created per second. + +=item B<--critical-connections-created-persecond> + +Threshold critical for connections created per second. + +=back + +=cut diff --git a/database/mongodb/mode/connectiontime.pm b/database/mongodb/mode/connectiontime.pm new file mode 100644 index 000000000..aad805427 --- /dev/null +++ b/database/mongodb/mode/connectiontime.pm @@ -0,0 +1,97 @@ +# +# Copyright 2019 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 database::mongodb::mode::connectiontime; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Time::HiRes; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'connection-time', nlabel => 'connection.time.milliseconds', set => { + key_values => [ { name => 'connection_time' } ], + output_template => 'Connection established in %d ms', + perfdatas => [ + { value => 'connection_time_absolute', template => '%d', unit => 'ms', + min => 0 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{custom} = $options{custom}; + + my $start = Time::HiRes::time(); + $self->{custom}->connect(); + my $end = Time::HiRes::time(); + + $self->{global}->{connection_time} = ($end - $start) * 1000; +} + +1; + +__END__ + +=head1 MODE + +Check database connection time. + +=over 8 + +=item B<--warning-connection-time-milliseconds> + +Threshold warning in milliseconds. + +=item B<--critical-connection-time-milliseconds>> + +Threshold critical in milliseconds. + +=back + +=cut diff --git a/database/mongodb/mode/databasestatistics.pm b/database/mongodb/mode/databasestatistics.pm new file mode 100644 index 000000000..b2e7bd2f7 --- /dev/null +++ b/database/mongodb/mode/databasestatistics.pm @@ -0,0 +1,203 @@ +# +# Copyright 2019 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 database::mongodb::mode::databasestatistics; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'databases', type => 1, cb_prefix_output => 'prefix_database_output', + message_multiple => 'All databases statistics are ok' }, + ]; + + $self->{maps_counters}->{databases} = [ + { label => 'storage-size', nlabel => 'database.size.storage.bytes', set => { + key_values => [ { name => 'storageSize' }, { name => 'display' } ], + output_template => 'Storage Size: %s %s', + output_change_bytes => 1, + perfdatas => [ + { value => 'storageSize_absolute', template => '%s', + min => 0, unit => 'B', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'data-size', nlabel => 'database.size.data.bytes', set => { + key_values => [ { name => 'dataSize' }, { name => 'display' } ], + output_template => 'Data Size: %s %s', + output_change_bytes => 1, + perfdatas => [ + { value => 'dataSize_absolute', template => '%s', + min => 0, unit => 'B', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'index-size', nlabel => 'database.size.index.bytes', set => { + key_values => [ { name => 'indexSize' }, { name => 'display' } ], + output_template => 'Index Size: %s %s', + output_change_bytes => 1, + perfdatas => [ + { value => 'indexSize_absolute', template => '%s', + min => 0, unit => 'B', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'collections', nlabel => 'database.collections.count', set => { + key_values => [ { name => 'collections' }, { name => 'display' } ], + output_template => 'Collections: %s', + perfdatas => [ + { value => 'collections_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'views', nlabel => 'database.views.count', set => { + key_values => [ { name => 'views' }, { name => 'display' } ], + output_template => 'Views: %s', + perfdatas => [ + { value => 'views_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'documents', nlabel => 'database.documents.count', set => { + key_values => [ { name => 'documents' }, { name => 'display' } ], + output_template => 'Documents: %s', + perfdatas => [ + { value => 'documents_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'indexes', nlabel => 'database.indexes.count', set => { + key_values => [ { name => 'indexes' }, { name => 'display' } ], + output_template => 'Indexes: %s', + perfdatas => [ + { value => 'indexes_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_database_output { + my ($self, %options) = @_; + + return "Database '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-database:s" => { name => 'filter_database' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{custom} = $options{custom}; + + $self->{databases} = {}; + + my $databases = $self->{custom}->list_databases(); + + foreach my $database (sort @{$databases}) { + next if (defined($self->{option_results}->{filter_database}) && $self->{option_results}->{filter_database} ne '' + && $database !~ /$self->{option_results}->{filter_database}/); + + my $db_stats = $self->{custom}->run_command( + database => $database, + command => $self->{custom}->ordered_hash('dbStats' => 1), + ); + + $self->{databases}->{$db_stats->{db}} = { + display => $db_stats->{db}, + collections => $db_stats->{collections}, + views => $db_stats->{views}, + documents => $db_stats->{objects}, + storageSize => $db_stats->{storageSize}, + indexSize => $db_stats->{indexSize}, + dataSize => $db_stats->{dataSize}, + indexes => $db_stats->{indexes}, + } + } + + if (scalar(keys %{$self->{databases}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No databases found'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check databases statistics + +=over 8 + +=item B<--filter-database> + +Filter database name (Can use regexp). + +=item B<--warning-instance-database-size-*-bytes> + +Threshold warning. +Can be: 'storage', 'data', 'index'. + +=item B<--critical-instance-database-size-*-bytes> + +Threshold critical. +Can be: 'storage', 'data', 'index'. + +=item B<--warning-instance-database-*-count> + +Threshold warning. +Can be: 'collections', 'views', 'documents', +'indexes'. + +=item B<--critical-instance-database-*-count> + +Threshold critical. +Can be: 'collections', 'views', 'documents', +'indexes'. + +=back + +=cut diff --git a/database/mongodb/mode/listdatabases.pm b/database/mongodb/mode/listdatabases.pm new file mode 100644 index 000000000..4dd362e61 --- /dev/null +++ b/database/mongodb/mode/listdatabases.pm @@ -0,0 +1,94 @@ +# +# Copyright 2019 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 database::mongodb::mode::listdatabases; + +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 => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + $self->{custom} = $options{custom}; + + $self->{databases} = $self->{custom}->list_databases(); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + + foreach my $database (sort @{$self->{databases}}) { + $self->{output}->output_add(long_msg => sprintf("[name = %s]", + $database)); + } + $self->{output}->output_add(severity => 'OK', + short_msg => "List databases:"); + + $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']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $database (sort @{$self->{databases}}) { + $self->{output}->add_disco_entry(name => $database); + } +} + +1; + +__END__ + +=head1 MODE + +List databases. + +=over 8 + +=back + +=cut diff --git a/database/mongodb/mode/queries.pm b/database/mongodb/mode/queries.pm new file mode 100644 index 000000000..7201cd7a3 --- /dev/null +++ b/database/mongodb/mode/queries.pm @@ -0,0 +1,145 @@ +# +# Copyright 2019 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 database::mongodb::mode::queries; + +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, cb_prefix_output => 'prefix_output' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total', nlabel => 'queries.total.persecond', set => { + key_values => [ { name => 'total', diff => 1 } ], + per_second => 1, + output_template => 'Total : %d', + perfdatas => [ + { value => 'total_per_second', template => '%d', unit => '/s', min => 0 }, + ], + } + }, + ]; + + foreach ('insert', 'query', 'update', 'delete', 'getmore', 'command') { + push @{$self->{maps_counters}->{global}}, { + label => $_, nlabel => 'queries.' . $_ . '.persecond', display_ok => 0, set => { + key_values => [ { name => $_, diff => 1 } ], + per_second => 1, + output_template => $_ . ' : %.2f', + perfdatas => [ + { value => $_ . '_per_second',template => '%.2f', unit => '/s', min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{global}}, { + label => $_ . '-count', , nlabel => 'queries.' . $_ . '.count', display_ok => 0, set => { + key_values => [ { name => $_, diff => 1 } ], + output_template => $_ . ' count : %d', + perfdatas => [ + { value => $_ . '_absolute', template => '%d', min => 0 }, + ], + } + }; + } +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Requests "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{custom} = $options{custom}; + + $self->{global} = {}; + + my $server_stats = $self->{custom}->run_command( + database => 'admin', + command => $self->{custom}->ordered_hash(serverStatus => 1), + ); + + foreach my $querie (keys %{$server_stats->{opcounters}}) { + $self->{global}->{$querie} = $server_stats->{opcounters}->{$querie}; + $self->{global}->{total} += $server_stats->{opcounters}->{$querie}; + } + + $self->{cache_name} = "mongodb_" . $self->{mode} . '_' . $self->{custom}->get_hostname() . '_' . $self->{custom}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check number of queries executed (absolute and per second). + +=over 8 + +=item B<--warning-queries-*-persecond> + +Threshold warning. +Can be: 'total', 'insert', 'query', 'update', +'delete', 'getmore', 'command' + +=item B<--critical-queries-*-persecond> + +Threshold critical. +Can be: 'total', 'insert', 'query', 'update', +'delete', 'getmore', 'command' + +=item B<--warning-queries-*-count> + +Threshold warning. +Can be: 'insert', 'query', 'update', +'delete', 'getmore', 'command' + +=item B<--critical-queries-*-count> + +Threshold critical. +Can be: 'insert', 'query', 'update', +'delete', 'getmore', 'command' + +=back + +=cut diff --git a/database/mongodb/mode/replicationstatus.pm b/database/mongodb/mode/replicationstatus.pm new file mode 100644 index 000000000..cd9996d34 --- /dev/null +++ b/database/mongodb/mode/replicationstatus.pm @@ -0,0 +1,254 @@ +# +# Copyright 2019 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 database::mongodb::mode::replicationstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +my %mapping_states = ( + 0 => 'STARTUP', 1 => 'PRIMARY', 2 => 'SECONDARY', + 3 => 'RECOVERING', 5 => 'STARTUP2', 6 => 'UNKNOWN', + 7 => 'ARBITER', 8 => 'DOWN', 9 => 'ROLLBACK', 10 => 'REMOVED', +); +my %mapping_health = ( + 0 => 'down', + 1 => 'up', +); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("Current member state is '%s'", $self->{result_values}->{state}); + $msg .= sprintf(", syncing to '%s'", $self->{result_values}->{sync_host}) if ($self->{result_values}->{state} ne 'PRIMARY'); + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{state} = $mapping_states{$options{new_datas}->{$self->{instance} . '_myState'}}; + $self->{result_values}->{sync_host} = $options{new_datas}->{$self->{instance} . '_syncSourceHost'}; + + return 0; +} + +sub custom_member_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("state is '%s' and health is '%s' [slave delay: %s] [priority: %s]", + $self->{result_values}->{state}, + $self->{result_values}->{health}, + $self->{result_values}->{slave_delay}, + $self->{result_values}->{priority}); + + return $msg; +} + +sub custom_member_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{name} = $options{new_datas}->{$self->{instance} . '_name'}; + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_stateStr'}; + $self->{result_values}->{slave_delay} = $options{new_datas}->{$self->{instance} . '_slaveDelay'}; + $self->{result_values}->{health} = $mapping_health{$options{new_datas}->{$self->{instance} . '_health'}}; + $self->{result_values}->{priority} = $options{new_datas}->{$self->{instance} . '_priority'}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'members', type => 1, cb_prefix_output => 'prefix_output', + message_multiple => 'All members statistics are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'status', set => { + key_values => [ { name => 'myState' }, { name => 'syncSourceHost' } ], + 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 => \&catalog_status_threshold, + } + }, + ]; + $self->{maps_counters}->{members} = [ + { label => 'member-status', set => { + key_values => [ { name => 'stateStr' }, { name => 'health' }, { name => 'slaveDelay' }, + { name => 'priority' }, { name => 'name' } ], + closure_custom_calc => $self->can('custom_member_status_calc'), + closure_custom_output => $self->can('custom_member_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + { label => 'replication-lag', nlabel => 'replication.lag.seconds', set => { + key_values => [ { name => 'lag' }, { name => 'name' } ], + output_template => 'Replication Lag: %s s', + perfdatas => [ + { value => 'lag_absolute', template => '%d', unit => 's', + min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Member '" . $options{instance_value}->{name} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + 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 => '' }, + "warning-member-status:s" => { name => 'warning_member_status', default => '%{state} !~ /PRIMARY|SECONDARY/' }, + "critical-member-status:s" => { name => 'critical_member_status', default => '%{health} !~ /up/' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status', + 'warning_member_status', 'critical_member_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{custom} = $options{custom}; + + my $ismaster = $self->{custom}->run_command( + database => 'admin', + command => $self->{custom}->ordered_hash('ismaster' => 1), + ); + + if (!defined($ismaster->{me})) { + $self->{output}->add_option_msg(short_msg => "No replication detected"); + $self->{output}->option_exit(); + } + + $self->{global} = {}; + $self->{members} = {}; + + my $repl_conf = $self->{custom}->run_command( + database => 'admin', + command => $self->{custom}->ordered_hash('replSetGetConfig' => 1), + ); + + my %config; + foreach my $member (sort @{$repl_conf->{config}->{members}}) { + $config{$member->{host}} = { priority => $member->{priority}, slaveDelay => $member->{slaveDelay} } + } + + my $repl_status = $self->{custom}->run_command( + database => 'admin', + command => $self->{custom}->ordered_hash('replSetGetStatus' => 1), + ); + + $self->{global}->{myState} = $repl_status->{myState}; + $self->{global}->{syncSourceHost} = (defined($repl_status->{syncSourceHost})) ? $repl_status->{syncSourceHost} : $repl_status->{syncingTo}; + $self->{global}->{syncSourceHost} = '-' if (!defined($self->{global}->{syncSourceHost})); + + foreach my $member (sort @{$repl_status->{members}}) { + $self->{members}->{$member->{name}} = { + name => $member->{name}, + stateStr => $member->{stateStr}, + health => $member->{health}, + optimeDate => $member->{optime}->{ts}->{seconds}, + slaveDelay => $config{$member->{name}}->{slaveDelay}, + priority => $config{$member->{name}}->{priority}, + } + } + + foreach my $member (keys %{$self->{members}}) { + next if ($self->{members}->{$member}->{stateStr} !~ /SECONDARY/); + $self->{members}->{$member}->{lag} = $self->{members}->{$ismaster->{primary}}->{optimeDate} - $self->{members}->{$member}->{optimeDate} - $self->{members}->{$member}->{slaveDelay}; + } + + if (scalar(keys %{$self->{members}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No members found'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check replication status + +=over 8 + +=item B<--warning-status> + +Set warning threshold for checked instance status (Default: ''). +Can used special variables like: %{state}, %{sync_host}. + +=item B<--critical-status> + +Set critical threshold for checked instance status (Default: ''). +Can used special variables like: %{state}, %{sync_host}. + +=item B<--warning-member-status> + +Set warning threshold for members status (Default: '%{state} !~ /PRIMARY|SECONDARY/'). +Can used special variables like: %{name}, %{state}, %{health}, +%{slave_delay}, %{priority}. + +=item B<--critical-member-status> + +Set critical threshold for members status (Default: '%{health} !~ /up/'). +Can used special variables like: %{name}, %{state}, %{health}, +%{slave_delay}, %{priority}. + +=item B<--warning-instance-replication-lag-seconds> + +Threshold warning for replication lag between primary and secondary members. +Must not be over 0 (between minus slaveDelay and 0). + +=item B<--critical-instance-replication-lag-seconds> + +Threshold critical for replication lag between primary and secondary members. +Must not be over 0 (between minus slaveDelay and 0). + +=back + +=cut diff --git a/database/mongodb/plugin.pm b/database/mongodb/plugin.pm new file mode 100644 index 000000000..2a0e9a8da --- /dev/null +++ b/database/mongodb/plugin.pm @@ -0,0 +1,55 @@ +# +# Copyright 2019 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 database::mongodb::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'collection-statistics' => 'database::mongodb::mode::collectionstatistics', + 'connections' => 'database::mongodb::mode::connections', + 'connection-time' => 'database::mongodb::mode::connectiontime', + 'database-statistics' => 'database::mongodb::mode::databasestatistics', + 'list-databases' => 'database::mongodb::mode::listdatabases', + 'queries' => 'database::mongodb::mode::queries', + 'replication-status' => 'database::mongodb::mode::replicationstatus', + ); + + $self->{custom_modes}{driver} = 'database::mongodb::custom::driver'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check MongoDB server. + +=cut diff --git a/database/mssql/dbi.pm b/database/mssql/dbi.pm index a81d7979e..967ebc556 100644 --- a/database/mssql/dbi.pm +++ b/database/mssql/dbi.pm @@ -31,11 +31,11 @@ sub set_version { $self->{version} = $self->{instance}->get_info(18); # SQL_DBMS_VER return if (defined($self->{version}) && $self->{version} ne ''); - return if ($self->query(query => q{select SERVERPROPERTY('productversion') as product_version}, continue_error => 1) == 1); + return if ($self->query(query => q{SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR) as product_version}, continue_error => 1) == 1); my $row = $self->fetchrow_hashref(); $self->{version} = $row->{product_version}; } 1; -__END__ \ No newline at end of file +__END__ diff --git a/database/mssql/mode/databasessize.pm b/database/mssql/mode/databasessize.pm index f2250b17b..25ae6fd20 100644 --- a/database/mssql/mode/databasessize.pm +++ b/database/mssql/mode/databasessize.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -51,23 +49,25 @@ sub custom_usage_perfdata { my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . lc($self->{result_values}->{display}) if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -75,14 +75,14 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, - threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, - { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -118,12 +118,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-database:s" => { name => 'filter_database' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "filter-database:s" => { name => 'filter_database' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } @@ -133,13 +133,6 @@ sub prefix_database_output { return "Database '" . $options{instance_value}->{display} . "' "; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/database/mssql/mode/failedjobs.pm b/database/mssql/mode/failedjobs.pm index deb4a9d41..e2530577e 100644 --- a/database/mssql/mode/failedjobs.pm +++ b/database/mssql/mode/failedjobs.pm @@ -25,6 +25,7 @@ use base qw(centreon::plugins::mode); use strict; use warnings; use Time::Local; +use centreon::plugins::misc; my %states = ( 0 => 'failed', @@ -109,6 +110,9 @@ sub run { $self->{sql}->query(query => $query); my $result = $self->{sql}->fetchall_arrayref(); my @job_failed; + # run_date format = YYYYMMDD + # run_time format = HHMMSS. Can be: HMMSS + # run_duration format = HHMMSS foreach my $row (@$result) { next if (defined($self->{option_results}->{filter}) && $$row[0] !~ /$self->{option_results}->{filter}/); next if (defined($self->{option_results}->{lookback}) && $$row[5] > $self->{option_results}->{lookback}); @@ -118,27 +122,30 @@ sub run { my $run_duration; my $run_date = $$row[3]; my ($year,$month,$day) = $run_date =~ /(\d{4})(\d{2})(\d{2})/; - my $run_time = $$row[4]; - my ($hour,$minute,$second) = $run_time =~ /(\d{2})(\d{2})(\d{2})/; + my $run_time = sprintf("%06d", $$row[4]); + my ($hour, $minute, $second) = $run_time =~ /(\d{2})(\d{2})(\d{2})$/; if (defined($$row[2])) { - $run_duration = $$row[2]; + my $run_duration_padding = sprintf("%06d", $$row[2]); + my ($hour_duration, $minute_duration, $second_duration) = $run_duration_padding =~ /(\d{2})(\d{2})(\d{2})$/; + $run_duration = ($hour_duration * 3600 + $minute_duration * 60 + $second_duration); } else { my $start_time = timelocal($second,$minute,$hour,$day,$month-1,$year); - $run_duration = (time() - $start_time) / 60; + $run_duration = (time() - $start_time); } if ($run_status == 0) { $count_failed++; push (@job_failed, $job_name); } else { - my $exit_code1 = $self->{perfdata}->threshold_check(value => $run_duration, threshold => [ { label => 'critical-duration', exit_litteral => 'critical' }, { label => 'warning-duration', exit_litteral => 'warning' } ]); + my $exit_code1 = $self->{perfdata}->threshold_check(value => $run_duration / 60, threshold => [ { label => 'critical-duration', exit_litteral => 'critical' }, { label => 'warning-duration', exit_litteral => 'warning' } ]); if (!$self->{output}->is_status(value => $exit_code1, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit_code1, - short_msg => sprintf("Job '%s' duration : %d minutes", $job_name, $run_duration)); + short_msg => sprintf("Job '%s' duration : %s", $job_name, centreon::plugins::misc::change_seconds(value => $run_duration))); } } - $self->{output}->output_add(long_msg => sprintf("Job '%s' status %s [Runtime : %s %s] [Duration : %d minutes]", $job_name, $states{$run_status}, $run_date, $run_time, $run_duration)); + $self->{output}->output_add(long_msg => sprintf("Job '%s' status %s [Runtime : %s %s] [Duration : %s]", + $job_name, $states{$run_status}, defined($year) ? $year . '-' . $month . '-' . $day : '', $hour . ':' . $minute . ':' . $second, centreon::plugins::misc::change_seconds(value => $run_duration))); } my $exit_code2 = $self->{perfdata}->threshold_check(value => $count_failed, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); diff --git a/database/mssql/mode/listdatabases.pm b/database/mssql/mode/listdatabases.pm index 21b5ffa0d..cf42bad30 100644 --- a/database/mssql/mode/listdatabases.pm +++ b/database/mssql/mode/listdatabases.pm @@ -31,10 +31,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-database:s" => { name => 'filter_database' }, - }); + $options{options}->add_options(arguments => { + "filter-database:s" => { name => 'filter_database' }, + }); + return $self; } @@ -76,7 +76,7 @@ sub run { $self->manage_selection(%options); foreach my $database (sort keys %{$self->{databases}}) { $self->{output}->output_add(long_msg => sprintf("[name = %s] [total = %s]", - $self->{databases}->{$database}->{name}, $self->{databases}->{$database}->{total})); + $self->{databases}->{$database}->{display}, $self->{databases}->{$database}->{total})); } $self->{output}->output_add(severity => 'OK', @@ -97,7 +97,7 @@ sub disco_show { $self->manage_selection(%options); foreach my $database (sort keys %{$self->{databases}}) { $self->{output}->add_disco_entry( - name => $self->{databases}->{$database}->{name}, + name => $self->{databases}->{$database}->{display}, total => $self->{databases}->{$database}->{total}, ); } diff --git a/database/mssql/mode/logssize.pm b/database/mssql/mode/logssize.pm index 458fe8ae5..74bd21466 100644 --- a/database/mssql/mode/logssize.pm +++ b/database/mssql/mode/logssize.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -51,12 +49,12 @@ sub custom_usage_perfdata { my $label = 'log_' . lc($self->{result_values}->{display}) . '_used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'log_' . lc($self->{result_values}->{display}) . '_free'; $value_perf = $self->{result_values}->{free}; } my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } @@ -73,10 +71,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, @@ -116,12 +114,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-log:s" => { name => 'filter_log' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "filter-log:s" => { name => 'filter_log' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } @@ -131,13 +129,6 @@ sub prefix_log_output { return "Log '" . $options{instance_value}->{display} . "' "; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/database/mssql/plugin.pm b/database/mssql/plugin.pm index ab57b7f5d..f02e7a09b 100644 --- a/database/mssql/plugin.pm +++ b/database/mssql/plugin.pm @@ -32,21 +32,21 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'backup-age' => 'database::mssql::mode::backupage', - 'blocked-processes' => 'database::mssql::mode::blockedprocesses', - 'cache-hitratio' => 'database::mssql::mode::cachehitratio', - 'connected-users' => 'database::mssql::mode::connectedusers', - 'connection-time' => 'centreon::common::protocols::sql::mode::connectiontime', - 'dead-locks' => 'database::mssql::mode::deadlocks', - 'databases-size' => 'database::mssql::mode::databasessize', - 'failed-jobs' => 'database::mssql::mode::failedjobs', - 'list-databases' => 'database::mssql::mode::listdatabases', - 'locks-waits' => 'database::mssql::mode::lockswaits', - 'logs-size' => 'database::mssql::mode::logssize', - 'sql' => 'centreon::common::protocols::sql::mode::sql', - 'sql-string' => 'centreon::common::protocols::sql::mode::sqlstring', - 'transactions' => 'database::mssql::mode::transactions', - ); + 'backup-age' => 'database::mssql::mode::backupage', + 'blocked-processes' => 'database::mssql::mode::blockedprocesses', + 'cache-hitratio' => 'database::mssql::mode::cachehitratio', + 'connected-users' => 'database::mssql::mode::connectedusers', + 'connection-time' => 'centreon::common::protocols::sql::mode::connectiontime', + 'dead-locks' => 'database::mssql::mode::deadlocks', + 'databases-size' => 'database::mssql::mode::databasessize', + 'failed-jobs' => 'database::mssql::mode::failedjobs', + 'list-databases' => 'database::mssql::mode::listdatabases', + 'locks-waits' => 'database::mssql::mode::lockswaits', + 'logs-size' => 'database::mssql::mode::logssize', + 'sql' => 'centreon::common::protocols::sql::mode::sql', + 'sql-string' => 'centreon::common::protocols::sql::mode::sqlstring', + 'transactions' => 'database::mssql::mode::transactions', + ); $self->{sql_modes}{dbi} = 'database::mssql::dbi'; return $self; @@ -56,18 +56,30 @@ sub init { my ($self, %options) = @_; $self->{options}->add_options( - arguments => { - 'hostname:s@' => { name => 'hostname' }, - 'port:s@' => { name => 'port' }, - 'database:s' => { name => 'database' }, - } - ); + arguments => { + 'hostname:s@' => { name => 'hostname' }, + 'port:s@' => { name => 'port' }, + 'server:s@' => { name => 'server' }, + 'database:s' => { name => 'database' }, + } + ); $self->{options}->parse_options(); my $options_result = $self->{options}->get_options(); $self->{options}->clean(); + if (defined($options_result->{server})) { + @{$self->{sqldefault}->{dbi}} = (); + for (my $i = 0; $i < scalar(@{$options_result->{server}}); $i++) { + $self->{sqldefault}->{dbi}[$i] = { data_source => 'Sybase:server=' . $options_result->{server}[$i] }; + if ((defined($options_result->{database})) && ($options_result->{database} ne '')) { + $self->{sqldefault}->{dbi}[$i]->{data_source} .= ';database=' . $options_result->{database}; + } + } + } + if (defined($options_result->{hostname})) { @{$self->{sqldefault}->{dbi}} = (); + for (my $i = 0; $i < scalar(@{$options_result->{hostname}}); $i++) { $self->{sqldefault}->{dbi}[$i] = { data_source => 'Sybase:host=' . $options_result->{hostname}[$i] }; if (defined($options_result->{port}[$i])) { @@ -78,6 +90,7 @@ sub init { } } } + $self->SUPER::init(%options); } @@ -99,6 +112,10 @@ Hostname to query. Database Server Port. +=item B<--server> + +An alternative to hostname+port. will be looked up in the file freetds.conf. + =back =cut diff --git a/database/mysql/mode/queries.pm b/database/mysql/mode/queries.pm index 47b108ed7..e6f193fe1 100644 --- a/database/mysql/mode/queries.pm +++ b/database/mysql/mode/queries.pm @@ -20,103 +20,96 @@ package database::mysql::mode::queries; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::statefile; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_output' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total', nlabel => 'queries.total.persecond', set => { + key_values => [ { name => 'Queries', diff => 1 } ], + per_second => 1, + output_template => 'Total : %d', + perfdatas => [ + { label => 'total_requests', template => '%d', value => 'Queries_per_second', + unit => '/s', min => 0 }, + ], + } + }, + ]; + + foreach ('update', 'delete', 'insert', 'truncate', 'select', 'commit', 'begin') { + push @{$self->{maps_counters}->{global}}, { + label => $_, nlabel => 'queries.' . $_ . '.persecond', display_ok => 0, set => { + key_values => [ { name => 'Com_' . $_, diff => 1 } ], + per_second => 1, + output_template => $_ . ' : %d', + perfdatas => [ + { label => $_ . '_requests', template => '%d', value => 'Com_' . $_ . '_per_second', + unit => '/s', min => 0 }, + ], + } + }; + push @{$self->{maps_counters}->{global}}, { + label => $_ . '-count', , nlabel => 'queries.' . $_ . '.count', display_ok => 0, set => { + key_values => [ { name => 'Com_' . $_, diff => 1 } ], + output_template => $_ . ' count : %d', + perfdatas => [ + { label => $_ . '_count', template => '%d', value => 'Com_' . $_ . '_absolute', + min => 0 }, + ], + } + }; + } +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Requests "; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; - + $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - }); - $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + $options{options}->add_options(arguments => { + }); return $self; } -sub check_options { +sub manage_selection { my ($self, %options) = @_; - $self->SUPER::init(%options); - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } - - $self->{statefile_cache}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - # $options{sql} = sqlmode object - $self->{sql} = $options{sql}; - - $self->{sql}->connect(); - $self->{sql}->query(query => q{ - SHOW /*!50000 global */ STATUS WHERE Variable_name IN ('Queries', 'Com_update', 'Com_delete', 'Com_insert', 'Com_truncate', 'Com_select') - }); - my $result = $self->{sql}->fetchall_arrayref(); - - if (!($self->{sql}->is_version_minimum(version => '5.0.76'))) { + $options{sql}->connect(); + if (!($options{sql}->is_version_minimum(version => '5.0.76'))) { $self->{output}->add_option_msg(short_msg => "MySQL version '" . $self->{sql}->{version} . "' is not supported (need version >= '5.0.76')."); $self->{output}->option_exit(); } - my $new_datas = {}; - $self->{statefile_cache}->read(statefile => 'mysql_' . $self->{mode} . '_' . $self->{sql}->get_unique_id4save()); - my $old_timestamp = $self->{statefile_cache}->get(name => 'last_timestamp'); - $new_datas->{last_timestamp} = time(); - - if (defined($old_timestamp) && $new_datas->{last_timestamp} - $old_timestamp == 0) { - $self->{output}->add_option_msg(short_msg => "Need at least one second between two checks."); - $self->{output}->option_exit(); - } - + $options{sql}->query(query => q{ + SHOW /*!50000 global */ STATUS WHERE Variable_name IN ('Queries', 'Com_update', 'Com_delete', 'Com_insert', 'Com_truncate', 'Com_select', 'Com_commit', 'Com_begin') + }); + + $self->{global} = {}; + my $result = $options{sql}->fetchall_arrayref(); foreach my $row (@{$result}) { - next if ($$row[0] !~ /^(Queries|Com_update|Com_delete|Com_insert|Com_truncate|Com_select)/i); - - $new_datas->{$$row[0]} = $$row[1]; - my $old_val = $self->{statefile_cache}->get(name => $$row[0]); - next if (!defined($old_val) || $$row[1] < $old_val); - - my $value = int(($$row[1] - $old_val) / ($new_datas->{last_timestamp} - $old_timestamp)); - if ($$row[0] ne 'Queries') { - $self->{output}->perfdata_add(label => $$row[0] . '_requests', - value => $value, - min => 0); - next; - } - - my $exit_code = $self->{perfdata}->threshold_check(value => $value, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{output}->output_add(severity => $exit_code, - short_msg => sprintf("Total requests = %s", $value)); - $self->{output}->perfdata_add(label => 'total_requests', - value => $value, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); - } - - $self->{statefile_cache}->write(data => $new_datas); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); + $self->{global}->{$$row[0]} = $$row[1]; } - $self->{output}->display(); - $self->{output}->exit(); + $self->{cache_name} = "mysql_" . $self->{mode} . '_' . $options{sql}->get_unique_id4save() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; @@ -129,13 +122,17 @@ Check average number of queries executed. =over 8 -=item B<--warning> +=item B<--warning-*> Threshold warning. +Can be: 'total', 'update', 'insert', 'delete', 'truncate', +'select', 'begin', 'commit'. -=item B<--critical> +=item B<--critical-*> Threshold critical. +Can be: 'total', 'update', 'insert', 'delete', 'truncate', +'select', 'begin', 'commit'. =back diff --git a/database/mysql/mode/tablessize.pm b/database/mysql/mode/tablessize.pm index ce98e1809..29c97f7b9 100644 --- a/database/mysql/mode/tablessize.pm +++ b/database/mysql/mode/tablessize.pm @@ -34,7 +34,7 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'total', set => { + { label => 'total', nlabel => 'table.usage.bytes', set => { key_values => [ { name => 'total' } ], output_template => 'Total Size : %s%s', output_change_bytes => 1, @@ -46,7 +46,7 @@ sub set_counters { }, ]; $self->{maps_counters}->{table} = [ - { label => 'table', set => { + { label => 'table', nlabel => 'table.usage.bytes', set => { key_values => [ { name => 'size' }, { name => 'display' } ], output_template => 'size : %s%s', output_change_bytes => 1, diff --git a/database/mysql/mysqlcmd.pm b/database/mysql/mysqlcmd.pm index b2d21d30d..1653a90ea 100644 --- a/database/mysql/mysqlcmd.pm +++ b/database/mysql/mysqlcmd.pm @@ -164,7 +164,6 @@ sub get_id { return $msg; } - sub get_unique_id4save { my ($self, %options) = @_; @@ -203,6 +202,8 @@ sub command_execution { return ($exit_code, $stdout); } +sub disconnect {} + # Connection initializer sub connect { my ($self, %options) = @_; diff --git a/database/oracle/mode/asmdiskgroupusage.pm b/database/oracle/mode/asmdiskgroupusage.pm index 9d287abf2..1940fb89f 100644 --- a/database/oracle/mode/asmdiskgroupusage.pm +++ b/database/oracle/mode/asmdiskgroupusage.pm @@ -20,73 +20,11 @@ package database::oracle::mode::asmdiskgroupusage; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; - -my $thresholds = { - diskgroup => [ - ['dismounted', 'OK'], - ['mounted', 'OK'], - ['connected', 'OK'], - ], -}; -my $instance_mode; - -my $maps_counters = { - dg => { - '000_status' => { threshold => 0, set => { - key_values => [ { name => 'state' } ], - closure_custom_calc => \&custom_status_calc, - closure_custom_output => \&custom_status_output, - closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&custom_status_threshold, - }, - }, - '001_offline-disks' => { threshold => 0, set => { - key_values => [ { name => 'offline_disks' }, { name => 'type' }, { name => 'display' } ], - closure_custom_calc => \&custom_offline_calc, - closure_custom_output => \&custom_offline_output, - closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&custom_offline_threshold, - }, - }, - '002_usage' => { set => { - key_values => [ { name => 'used' }, { name => 'total' }, { name => 'display' } ], - closure_custom_calc => \&custom_usage_calc, - closure_custom_output => \&custom_usage_output, - closure_custom_perfdata => \&custom_usage_perfdata, - closure_custom_threshold_check => \&custom_usage_threshold, - }, - }, - }, -}; - -sub custom_offline_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_offline_disks}) && $instance_mode->{option_results}->{critical_offline_disks} ne '' && - eval "$instance_mode->{option_results}->{critical_offline_disks}") { - $status = 'critical'; - } elsif (defined($instance_mode->{option_results}->{warning_offline_disks}) && $instance_mode->{option_results}->{warning_offline_disks} ne '' && - eval "$instance_mode->{option_results}->{warning_offline_disks}") { - $status = 'warning'; - } - }; - if (defined($message)) { - $self->{output}->output_add(long_msg => 'filter offline status issue: ' . $message); - } - - return $status; -} +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); sub custom_offline_output { my ($self, %options) = @_; @@ -104,33 +42,28 @@ sub custom_offline_calc { return 0; } -sub custom_status_threshold { - my ($self, %options) = @_; - - my $message; - eval { - local $SIG{__WARN__} = sub { $message = $_[0]; }; - local $SIG{__DIE__} = sub { $message = $_[0]; }; - - $instance_mode->{last_status} = 0; - if (eval "$instance_mode->{check_status}") { - $instance_mode->{last_status} = 1; - } - }; - return $instance_mode->get_severity(section => 'diskgroup', value => $self->{result_values}->{state}); -} - sub custom_status_output { my ($self, %options) = @_; - my $msg = 'Status : ' . $self->{result_values}->{state}; - + + my $msg = 'status: ' . $self->{result_values}->{status}; return $msg; } +sub custom_status_threshold { + my ($self, %options) = @_; + + my $status = catalog_status_threshold($self, %options); + $self->{instance_mode}->{last_status} = 0; + if (!$self->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { + $self->{instance_mode}->{last_status} = 1; + } + return $status; +} + sub custom_status_calc { my ($self, %options) = @_; - $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; return 0; } @@ -139,66 +72,84 @@ sub custom_usage_perfdata { my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if ($self->{result_values}->{total} > 0 && defined($instance_mode->{option_results}->{free})) { + if ($self->{result_values}->{total} > 0 && defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + + $label .= '_' . $self->{result_values}->{label_ref} + if (defined($self->{result_values}->{label_ref})); + my %total_options = (); - if ($self->{result_values}->{total} > 0 && $instance_mode->{option_results}->{units} eq '%') { + if ($self->{result_values}->{total} > 0 && $self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { my ($self, %options) = @_; # cannot use '%' or free option with unlimited system - return 'ok' if ($self->{result_values}->{total} <= 0 && ($instance_mode->{option_results}->{units} eq '%' || $instance_mode->{option_results}->{free})); + return 'ok' if ($self->{result_values}->{total} <= 0 && ($self->{instance_mode}->{option_results}->{units} eq '%' || $self->{instance_mode}->{option_results}->{free})); my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } sub custom_usage_output { my ($self, %options) = @_; + my $label = 'Disk '; + if (defined($self->{result_values}->{label_ref})) { + $label = 'Disk Failure'; + } + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); my $msg; if ($self->{result_values}->{total} <= 0) { - $msg = sprintf("Used: %s (unlimited)", $total_used_value . " " . $total_used_unit); + $msg = sprintf("%s Used: %s (unlimited)", $label, $total_used_value . " " . $total_used_unit); } else { my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); - $msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $msg = sprintf("%s Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $label, $total_size_value . " " . $total_size_unit, $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); } + return $msg; } sub custom_usage_calc { my ($self, %options) = @_; - return -10 if (defined($instance_mode->{last_status}) && $instance_mode->{last_status} == 0); + return -10 if (defined($self->{instance_mode}->{last_status}) && $self->{instance_mode}->{last_status} == 0); + + my $label_used = 'used'; + $label_used .= '_' . $options{extra_options}->{label_ref} + if (defined($options{extra_options}->{label_ref})); + + $self->{result_values}->{label_ref} = defined($options{extra_options}->{label_ref}) ? $options{extra_options}->{label_ref} : undef; $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; - $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_' . $label_used}; return 0 if ($self->{result_values}->{total} == 0); $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; @@ -208,204 +159,122 @@ sub custom_usage_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'dg', type => 1, cb_prefix_output => 'prefix_dg_output', message_multiple => 'All diskgroups are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{dg} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' } ], + 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_output'), + } + }, + { label => 'offline-disks', set => { + key_values => [ { name => 'offline_disks' }, { name => 'type' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_offline_calc'), + closure_custom_output => $self->can('custom_offline_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + { label => 'usage', set => { + key_values => [ { name => 'used' }, { name => 'total' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + { label => 'usage-failure', set => { + key_values => [ { name => 'used_failure' }, { name => 'total' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_calc_extra_options => { label_ref => 'failure' }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +sub prefix_dg_output { + my ($self, %options) = @_; + + return "Diskgroup '" . $options{instance_value}->{display} . "' "; +} + 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-offline-disks:s" => { name => 'warning_offline_disks', default => '(%{offline_disks} > 0 && %{type} eq "extern") || (%{offline_disks} > 1 && %{type} eq "high")' }, - "critical-offline-disks:s" => { name => 'critical_offline_disks', default => '%{offline_disks} > 0 && %{type} =~ /^normal|high$/' }, - "filter-name:s" => { name => 'filter_name', }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "no-component:s" => { name => 'no_component' }, - }); + $options{options}->add_options(arguments => { + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + "warning-offline-disks:s" => { name => 'warning_offline_disks', default => '(%{offline_disks} > 0 && %{type} eq "extern") || (%{offline_disks} > 1 && %{type} eq "high")' }, + "critical-offline-disks:s" => { name => 'critical_offline_disks', default => '%{offline_disks} > 0 && %{type} =~ /^normal|high$/' }, + "filter-name:s" => { name => 'filter_name', }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); - foreach my $key (('dg')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - return $self; } -sub change_macros { - my ($self, %options) = @_; - - foreach (('warning_offline_disks', 'critical_offline_disks')) { - if (defined($self->{option_results}->{$_})) { - $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; - } - } - - $self->{check_status} = '%{state} =~ /^(mounted|dismounted|connected)$/i'; - $self->{check_status} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; -} - sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('dg')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - $instance_mode = $self; - - $self->change_macros(); - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } - - $self->{overload_th} = {}; - foreach my $val (@{$self->{option_results}->{threshold_overload}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $status, $filter) = ($1, $2, $3); - if ($self->{output}->is_litteral_status(status => $status) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); - $self->{output}->option_exit(); - } - $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); - push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status}; - } -} + $self->SUPER::check_options(%options); -sub run { - my ($self, %options) = @_; - $self->{sql} = $options{sql}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{dg}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All diskgroups are ok'); - } - - foreach my $id (sort keys %{$self->{dg}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{dg}}) { - my $obj = $maps_counters->{dg}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{dg}->{$id}); - next if ($value_check == -10); # status issue - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Diskgroup '$self->{dg}->{$id}->{display}' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Diskgroup '$self->{dg}->{$id}->{display}' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Diskgroup '$self->{dg}->{$id}->{display}' $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub get_severity { - my ($self, %options) = @_; - my $status = 'UNKNOWN'; # default - - if (defined($self->{overload_th}->{$options{section}})) { - foreach (@{$self->{overload_th}->{$options{section}}}) { - if ($options{value} =~ /$_->{filter}/i) { - $status = $_->{status}; - return $status; - } - } - } - foreach (@{$thresholds->{$options{section}}}) { - if ($options{value} =~ /$$_[0]/i) { - $status = $$_[1]; - return $status; - } - } - - return $status; + $self->change_macros(macros => [ + 'warning_offline_disks', 'critical_offline_disks', + 'warning_status', 'critical_status', 'unknown_status', + ]); } sub manage_selection { my ($self, %options) = @_; - $self->{sql}->connect(); - my $query = q{SELECT name, state, type, total_mb, usable_file_mb, offline_disks FROM V$ASM_DISKGROUP}; - $self->{sql}->query(query => $query); - my $result = $self->{sql}->fetchall_arrayref(); + $options{sql}->connect(); + my $query = q{SELECT name, state, type, total_mb, usable_file_mb, offline_disks, FREE_MB FROM V$ASM_DISKGROUP}; + $options{sql}->query(query => $query); + my $result = $options{sql}->fetchall_arrayref(); + $options{sql}->disconnect(); $self->{dg} = {}; foreach my $row (@$result) { - my ($name, $state, $type, $total_mb, $usable_file_mb, $offline_disks) = @$row; + my ($name, $state, $type, $total_mb, $usable_file_mb, $offline_disks, $free_mb) = @$row; 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 name.", debug => 1); + $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter name.", debug => 1); next; } - - - $self->{dg}->{$name} = { display => $name, total => $total_mb * 1024 * 1024, - used => ($total_mb * 1024 * 1024) - ($usable_file_mb * 1024 * 1024), - state => $state, type => lc($type), offline_disks => $offline_disks }; + + my $used_failure = ($total_mb * 1024 * 1024) - ($usable_file_mb * 1024 * 1024); + if ($usable_file_mb < 0) { + $used_failure = ($total_mb * 1024 * 1024); + } + $self->{dg}->{$name} = { + display => $name, + total => $total_mb * 1024 * 1024, + used => ($total_mb * 1024 * 1024) - ($free_mb * 1024 * 1024), + used_failure => $used_failure, + status => $state, + type => lc($type), + offline_disks => $offline_disks + }; } if (scalar(keys %{$self->{dg}}) <= 0) { - $self->{output}->output_add(severity => defined($self->{no_components}) ? $self->{no_components} : 'unknown', - short_msg => 'No components are checked.'); + $self->{output}->add_option_msg(short_msg => "No diskgroup found."); + $self->{output}->option_exit(); } } @@ -427,6 +296,29 @@ Threshold warning. Threshold critical. +=item B<--warning-usage-failure> + +Threshold warning. + +=item B<--critical-usage-failure> + +Threshold critical. + +=item B<--unknown-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=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: ''). +Can used special variables like: %{status}, %{display} + =item B<--warning-offline-disks> Set warning threshold for offline disks (Default: '(%{offline_disks} > 0 && %{type} eq "extern") || (%{offline_disks} > 1 && %{type} eq "high")'). @@ -449,12 +341,6 @@ Thresholds are on free space left. Filter by name (regexp can be used). -=item B<--threshold-overload> - -Set to overload default threshold values (syntax: section,status,regexp) -It used before default thresholds (order stays). -Example: --threshold-overload='diskgroup,CRITICAL,^(?!(mounted|connected|dismounted)$)' - =back =cut diff --git a/database/oracle/mode/connectedusers.pm b/database/oracle/mode/connectedusers.pm index e9a98423f..46dae0008 100644 --- a/database/oracle/mode/connectedusers.pm +++ b/database/oracle/mode/connectedusers.pm @@ -31,11 +31,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - }); + $options{options}->add_options(arguments => { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); return $self; } @@ -62,6 +61,7 @@ sub run { $self->{sql}->connect(); $self->{sql}->query(query => q{SELECT COUNT(*) FROM v$session WHERE type = 'USER'}); my $users = $self->{sql}->fetchrow_array(); + $self->{sql}->disconnect(); my $exit_code = $self->{perfdata}->threshold_check(value => $users, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{output}->output_add(severity => $exit_code, diff --git a/database/oracle/mode/corruptedblocks.pm b/database/oracle/mode/corruptedblocks.pm index 35891aef9..6c3cf9e69 100644 --- a/database/oracle/mode/corruptedblocks.pm +++ b/database/oracle/mode/corruptedblocks.pm @@ -31,11 +31,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - }); + $options{options}->add_options(arguments => { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); return $self; } @@ -62,6 +61,7 @@ sub run { $self->{sql}->connect(); $self->{sql}->query(query => q{SELECT COUNT(*) FROM v$database_block_corruption}); my $corrupted_blocks = $self->{sql}->fetchrow_array(); + $self->{sql}->disconnect(); my $exit_code = $self->{perfdata}->threshold_check(value => $corrupted_blocks, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{output}->output_add(severity => $exit_code, diff --git a/database/oracle/mode/datacachehitratio.pm b/database/oracle/mode/datacachehitratio.pm index 1911ed68e..325aab0a7 100644 --- a/database/oracle/mode/datacachehitratio.pm +++ b/database/oracle/mode/datacachehitratio.pm @@ -20,75 +20,82 @@ package database::oracle::mode::datacachehitratio; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +use Digest::MD5 qw(md5_hex); + +sub custom_hitratio_calc { + my ($self, %options) = @_; + + my $delta_phys = ($options{new_datas}->{$self->{instance} . '_physical_reads'} - $options{old_datas}->{$self->{instance} . '_physical_reads'}); + my $delta_cache = + ($options{new_datas}->{$self->{instance} . '_db_block_gets'} - $options{old_datas}->{$self->{instance} . '_db_block_gets'}) + + ($options{new_datas}->{$self->{instance} . '_consistent_gets'} - $options{old_datas}->{$self->{instance} . '_consistent_gets'}); + $self->{result_values}->{hit_ratio} = ($delta_cache == 0) ? 0 : + ((1 - ($delta_phys / $delta_cache)) * 100); + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'usage', set => { + key_values => [ { name => 'physical_reads', diff => 1 }, { name => 'db_block_gets', diff => 1 }, + { name => 'consistent_gets', diff => 1 } ], + closure_custom_calc => $self->can('custom_hitratio_calc'), + output_template => 'Buffer cache hit ratio is %.2f%%', output_error_template => 'Buffer cache hit ratio: %s', + output_use => 'hit_ratio', threshold_use => 'hit_ratio', + perfdatas => [ + { label => 'sga_data_buffer_hit_ratio', value => 'hit_ratio', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; - - $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - }); + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); +sub manage_selection { + my ($self, %options) = @_; - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } -} - -sub run { - my ($self, %options) = @_; - # $options{sql} = sqlmode object - $self->{sql} = $options{sql}; - - $self->{sql}->connect(); - $self->{sql}->query(query => q{ + my $query = q{ SELECT SUM(DECODE(name, 'physical reads', value, 0)), - SUM(DECODE(name, 'physical reads direct', value, 0)), - SUM(DECODE(name, 'physical reads direct (lob)', value, 0)), - SUM(DECODE(name, 'session logical reads', value, 0)) + SUM(DECODE(name, 'db block gets', value, 0)), + SUM(DECODE(name, 'consistent gets', value, 0)) FROM sys.v_$sysstat - }); - my $result = $self->{sql}->fetchall_arrayref(); + }; + + $options{sql}->connect(); + $options{sql}->query(query => $query); + my @result = $options{sql}->fetchrow_array(); + $options{sql}->disconnect(); - my $physical_reads = @$result[0]->[0]; - my $physical_reads_direct = @$result[0]->[1]; - my $physical_reads_direct_lob = @$result[0]->[2]; - my $session_logical_reads = @$result[0]->[3]; + $self->{global} = { + physical_reads => $result[0], + db_block_gets => $result[1], + consistent_gets => $result[2], + }; - my $hitratio = 100 - 100 * (($physical_reads - $physical_reads_direct - $physical_reads_direct_lob) / $session_logical_reads); - - my $exit_code = $self->{perfdata}->threshold_check(value => $hitratio, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{output}->output_add(severity => $exit_code, - short_msg => sprintf("Buffer cache hit ratio is %.2f%%", $hitratio)); - $self->{output}->perfdata_add(label => 'sga_data_buffer_hit_ratio', - value => sprintf("%d",$hitratio), - unit => '%', - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0, - max => 100); - - $self->{output}->display(); - $self->{output}->exit(); + $self->{cache_name} = "oracle_" . $self->{mode} . '_' . $options{sql}->get_unique_id4save() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; @@ -101,11 +108,11 @@ Check Oracle buffer cache hit ratio. =over 8 -=item B<--warning> +=item B<--warning-usage> Threshold warning. -=item B<--critical> +=item B<--critical-usage> Threshold critical. diff --git a/database/oracle/mode/datafilesstatus.pm b/database/oracle/mode/datafilesstatus.pm index 9d4c3c53b..24862642e 100644 --- a/database/oracle/mode/datafilesstatus.pm +++ b/database/oracle/mode/datafilesstatus.pm @@ -25,12 +25,59 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use Digest::MD5 qw(md5_hex); + +sub custom_traffic_calc { + my ($self, %options) = @_; + + my $total_traffic = -1; + foreach (keys %{$options{new_datas}}) { + if (/^(.*)_(phyrds|phywrts)$/) { + my $new_total = $options{new_datas}->{$_}; + next if (!defined($options{old_datas}->{$_})); + $total_traffic = 0 if ($total_traffic == -1); + + my $old_total = $options{old_datas}->{$_}; + if ($old_total > $new_total) { + $options{old_datas}->{$_} = 0; + $old_total = 0; + } + + my $diff_total = $new_total - $old_total; + $total_traffic += $diff_total; + } + } + + if ($total_traffic == -1) { + $self->{error_msg} = "Buffer creation"; + return -1; + } + + $self->{result_values}->{traffic} = $total_traffic / $options{delta_time}; + return 0; +} + sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'df', type => 1, cb_prefix_output => 'prefix_df_output', message_multiple => 'All data files are ok' }, + { name => 'global', type => 0 }, + { name => 'df', type => 1, cb_prefix_output => 'prefix_df_output', message_multiple => 'All data files are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total-traffic', nlabel => 'datafiles.traffic.io.usage.iops', set => { + key_values => [], + closure_custom_calc => $self->can('custom_traffic_calc'), + per_second => 1, manual_keys => 1, + threshold_use => 'traffic', output_use => 'traffic', + output_template => 'Total Traffic IOPs %.2f', + perfdatas => [ + { label => 'total_traffic', value => 'traffic', template => '%.2f', min => 0 , unit => 'iops' }, + ], + } + }, ]; $self->{maps_counters}->{df} = [ @@ -82,19 +129,19 @@ sub custom_online_status_calc { sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-tablespace:s" => { name => 'filter_tablespace' }, - "filter-data-file:s" => { name => 'filter_data_file' }, - "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '' }, - "warning-online-status:s" => { name => 'warning_online_status', default => '%{online_status} =~ /sysoff/i' }, - "critical-online-status:s" => { name => 'critical_online_status', default => '%{online_status} =~ /offline|recover/i' }, - }); + $options{options}->add_options(arguments => { + "filter-tablespace:s" => { name => 'filter_tablespace' }, + "filter-data-file:s" => { name => 'filter_data_file' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + "warning-online-status:s" => { name => 'warning_online_status', default => '%{online_status} =~ /sysoff/i' }, + "critical-online-status:s" => { name => 'critical_online_status', default => '%{online_status} =~ /offline|recover/i' }, + }); + return $self; } @@ -102,7 +149,7 @@ sub check_options { my ($self, %options) = @_; $self->SUPER::check_options(%options); - $self->change_macros(macros => ['warning_status', 'critical_status', 'warning_online_status', 'critical_online_status')]); + $self->change_macros(macros => ['warning_status', 'critical_status', 'warning_online_status', 'critical_online_status']); } sub prefix_df_output { @@ -115,10 +162,32 @@ sub manage_selection { my ($self, %options) = @_; $options{sql}->connect(); - $options{sql}->query(query => "SELECT file_name, tablespace_name, status, online_status - FROM dba_data_files"); - my $result = $options{sql}->fetchall_arrayref(); + if ($options{sql}->is_version_minimum(version => '10')) { + $options{sql}->query(query => q{ + SELECT a.file_name, a.tablespace_name, a.status, b.phyrds, b.phywrts, a.online_status + FROM dba_data_files a, v$filestat b + WHERE a.file_id = b.file# + UNION + SELECT a.name, c.name, a.status, b.phyrds, b.phywrts, NULL + FROM v$tempfile a, v$tablespace c, v$tempstat b + WHERE a.ts#= c.ts# AND a.file# = b.file# + }); + } else { + $options{sql}->query(query => q{ + SELECT a.file_name, a.tablespace_name, a.status, b.phyrds, b.phywrts + FROM dba_data_files a, v$filestat b + WHERE a.file_id = b.file# + UNION + SELECT a.name, c.name, a.status, b.phyrds, b.phywrts + FROM v$tempfile a, v$tablespace c, v$tempstat b + WHERE a.ts#= c.ts# AND a.file# = b.file# + }); + } + my $result = $options{sql}->fetchall_arrayref(); + $options{sql}->disconnect(); + + $self->{global} = {}; $self->{df} = {}; foreach my $row (@$result) { if (defined($self->{option_results}->{filter_data_file}) && $self->{option_results}->{filter_data_file} ne '' && @@ -131,8 +200,26 @@ sub manage_selection { $self->{output}->output_add(long_msg => "skipping '" . $$row[1] . "': no matching filter.", debug => 1); next } - $self->{df}->{$$row[1] . '/' . $$row[0]} = { status => $$row[2], online_status => $$row[3], display => $$row[1] . '/' . $$row[0] }; + + my $name = $$row[1] . '/' . $$row[0]; + $self->{df}->{$name} = { + status => $$row[2], + online_status => defined($$row[5]) ? $$row[5] : undef, + display => $name + }; + $self->{global}->{$name . '_phyrds'} = $$row[3]; + $self->{global}->{$name . '_phywrts'} = $$row[4]; } + + if (scalar(keys %{$self->{df}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No data file found"); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "oracle_" . $self->{mode} . '_' . $options{sql}->get_unique_id4save() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_tablespace}) ? md5_hex($self->{option_results}->{filter_tablespace}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_data_file}) ? md5_hex($self->{option_results}->{filter_data_file}) : md5_hex('all')); } 1; @@ -177,6 +264,11 @@ Can used special variables like: %{display}, %{online_status} Set critical threshold for online status (Default: '%{online_status} =~ /offline|recover/i'). Can used special variables like: %{display}, %{online_status} +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'total-traffic'. + =back =cut diff --git a/database/oracle/mode/dictionarycacheusage.pm b/database/oracle/mode/dictionarycacheusage.pm new file mode 100644 index 000000000..d963b70be --- /dev/null +++ b/database/oracle/mode/dictionarycacheusage.pm @@ -0,0 +1,116 @@ +# +# Copyright 2019 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 database::oracle::mode::dictionarycacheusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub custom_hitratio_calc { + my ($self, %options) = @_; + + my $delta_total = ($options{new_datas}->{$self->{instance} . '_gets'} - $options{old_datas}->{$self->{instance} . '_gets'}); + my $delta_cache = ($options{new_datas}->{$self->{instance} . '_getmisses'} - $options{old_datas}->{$self->{instance} . '_getmisses'}); + $self->{result_values}->{hit_ratio} = $delta_total ? (100 * $delta_cache / $delta_total) : 0; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', cb_prefix_output => 'prefix_global_output', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'get-hits', nlabel => 'dictionary.cache.get.hitratio.percentage', set => { + key_values => [ { name => 'getmisses', diff => 1 }, { name => 'gets', diff => 1 } ], + closure_custom_calc => $self->can('custom_hitratio_calc'), + output_template => 'get hit ratio %.2f%%', + output_use => 'hit_ratio', threshold_use => 'hit_ratio', + perfdatas => [ + { label => 'get_hit_ratio', value => 'hit_ratio', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'SGA dictionary cache '; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $query = q{ + SELECT SUM(gets), SUM(gets-getmisses) FROM v$rowcache + }; + + $options{sql}->connect(); + $options{sql}->query(query => $query); + my @result = $options{sql}->fetchrow_array(); + $options{sql}->disconnect(); + + $self->{global} = { + gets => $result[0], + getmisses => $result[1], + }; + + $self->{cache_name} = "oracle_" . $self->{mode} . '_' . $options{sql}->get_unique_id4save() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check Oracle dictionary cache usage. + +=over 8 + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'get-hits'. + +=back + +=cut diff --git a/database/oracle/mode/eventwaitsusage.pm b/database/oracle/mode/eventwaitsusage.pm index 800aad6eb..a1982bbc7 100644 --- a/database/oracle/mode/eventwaitsusage.pm +++ b/database/oracle/mode/eventwaitsusage.pm @@ -31,7 +31,7 @@ sub set_counters { $self->{maps_counters_type} = [ { name => 'event_count', type => 0 }, - { name => 'event', type => 1, cb_prefix_output => 'prefix_event_output', message_multiple => 'All event waits are OK', skipped_code => { 11 => -1 }}, + { name => 'event', type => 1, cb_prefix_output => 'prefix_event_output', message_multiple => 'All event waits are OK', skipped_code => { -11 => 1, -10 => 1 } }, ]; @@ -86,12 +86,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "wait-time-min:s" => { name => 'wait_time_min', default => 1000 }, - "show-details" => { name => 'show_details' } - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "wait-time-min:s" => { name => 'wait_time_min', default => 1000 }, + "show-details" => { name => 'show_details' } + }); + return $self; } @@ -101,6 +101,46 @@ sub prefix_event_output { return "Event '" . $options{instance_value}->{display} . "' "; } +sub event_count_and_details { + my ($self, %options) = @_; + + my $query_count = "SELECT count(*) as NB + FROM v\$session + WHERE WAIT_TIME_MICRO>" . $self->{option_results}->{wait_time_min} . " + AND status='ACTIVE' and WAIT_CLASS <>'Idle'"; + + $self->{sql}->query(query => $query_count); + my $result = $self->{sql}->fetchrow_hashref(); + + $self->{event_count}->{count} = $result->{NB}; + + if (defined($self->{option_results}->{show_details})) { + my $query_details = "SELECT + a.username USERNAME, + a.program PROGRAM, + a.event EVENT, + round(a.WAIT_TIME_MICRO/1000000,0) SEC_WAIT, + d.sql_text SQL_TEXT + FROM + v\$session a, + v\$sqlstats d + WHERE + a.sql_id = d.sql_id + and a.status='ACTIVE' + and a.wait_class <> 'Idle' + and WAIT_TIME_MICRO>" . $self->{option_results}->{wait_time_min} . " + and a.sid not in (SELECT SID FROM V\$SESSION WHERE audsid = userenv('SESSIONID')) + ORDER BY + a.WAIT_TIME_MICRO desc"; + + $self->{sql}->query(query => $query_details ); + while (my $result = $self->{sql}->fetchrow_hashref()) { + $self->{output}->output_add(long_msg => sprintf("Username: '%s', Program: '%s' Event: '%s', Second wait: '%s's, Details: '%s'\n", + $result->{USERNAME}, $result->{PROGRAM}, $result->{EVENT}, $result->{SEC_WAIT}, $result->{SQL_TEXT})); + } + } +} + sub manage_selection { my ($self, %options) = @_; $self->{sql} = $options{sql}; @@ -141,42 +181,12 @@ sub manage_selection { }; } - my $query_count = "SELECT count(*) as NB - FROM v\$session - WHERE WAIT_TIME_MICRO>" . $self->{option_results}->{wait_time_min} . " - AND status='ACTIVE' and WAIT_CLASS <>'Idle'"; - - $self->{sql}->query(query => $query_count); - $result = $self->{sql}->fetchrow_hashref(); - - $self->{event_count}->{count} = $result->{NB}; - - if (defined($self->{option_results}->{show_details})) { - my $query_details = "SELECT - a.username USERNAME, - a.program PROGRAM, - a.event EVENT, - round(a.WAIT_TIME_MICRO/1000000,0) SEC_WAIT, - d.sql_text SQL_TEXT - FROM - v\$session a, - v\$sqlstats d - WHERE - a.sql_id = d.sql_id - and a.status='ACTIVE' - and a.wait_class <> 'Idle' - and WAIT_TIME_MICRO>" . $self->{option_results}->{wait_time_min} . " - and a.sid not in (SELECT SID FROM V\$SESSION WHERE audsid = userenv('SESSIONID')) - ORDER BY - a.WAIT_TIME_MICRO desc"; - - $self->{sql}->query(query => $query_details ); - while (my $result = $self->{sql}->fetchrow_hashref()) { - $self->{output}->output_add(long_msg => sprintf("Username: '%s', Program: '%s' Event: '%s', Second wait: '%s's, Details: '%s'\n", - $result->{USERNAME}, $result->{PROGRAM}, $result->{EVENT}, $result->{SEC_WAIT}, $result->{SQL_TEXT})); - } + if ($self->{sql}->is_version_minimum(version => '10')) { + $self->event_count_and_details(); } + $self->{sql}->disconnect(); + if (scalar(keys %{$self->{event}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No event found."); $self->{output}->option_exit(); diff --git a/database/oracle/mode/invalidobject.pm b/database/oracle/mode/invalidobject.pm index 156d88bd8..5c51ea251 100644 --- a/database/oracle/mode/invalidobject.pm +++ b/database/oracle/mode/invalidobject.pm @@ -82,11 +82,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-message:s" => { name => 'filter_message' }, - "retention-objects:s" => { name => 'retention_objects', default => 3}, - }); + $options{options}->add_options(arguments => { + "filter-message:s" => { name => 'filter_message' }, + "retention-objects:s" => { name => 'retention_objects', default => 3 }, + }); return $self; } @@ -162,6 +161,8 @@ sub manage_selection { WHERE status <> 'VALID' AND status <> 'OPTION OFF' }); } + + $options{sql}->disconnect(); } 1; diff --git a/database/oracle/mode/librarycacheusage.pm b/database/oracle/mode/librarycacheusage.pm new file mode 100644 index 000000000..6799e74a6 --- /dev/null +++ b/database/oracle/mode/librarycacheusage.pm @@ -0,0 +1,160 @@ +# +# Copyright 2019 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 database::oracle::mode::librarycacheusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub custom_pin_hitratio_calc { + my ($self, %options) = @_; + + my $delta_total = ($options{new_datas}->{$self->{instance} . '_pins'} - $options{old_datas}->{$self->{instance} . '_pins'}); + my $delta_cache = ($options{new_datas}->{$self->{instance} . '_pin_hits'} - $options{old_datas}->{$self->{instance} . '_pin_hits'}); + $self->{result_values}->{hit_ratio} = $delta_total ? (100 * $delta_cache / $delta_total) : 0; + + return 0; +} + +sub custom_get_hitratio_calc { + my ($self, %options) = @_; + + my $delta_total = ($options{new_datas}->{$self->{instance} . '_gets'} - $options{old_datas}->{$self->{instance} . '_gets'}); + my $delta_cache = ($options{new_datas}->{$self->{instance} . '_get_hits'} - $options{old_datas}->{$self->{instance} . '_get_hits'}); + $self->{result_values}->{hit_ratio} = $delta_total ? (100 * $delta_cache / $delta_total) : 0; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', cb_prefix_output => 'prefix_global_output', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'get-hits', nlabel => 'library.cache.get.hitratio.percentage', set => { + key_values => [ { name => 'get_hits', diff => 1 }, { name => 'gets', diff => 1 } ], + closure_custom_calc => $self->can('custom_get_hitratio_calc'), + output_template => 'get hit ratio %.2f%%', + output_use => 'hit_ratio', threshold_use => 'hit_ratio', + perfdatas => [ + { label => 'get_hit_ratio', value => 'hit_ratio', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'pin-hits', nlabel => 'library.cache.pin.hitratio.percentage', set => { + key_values => [ { name => 'pin_hits', diff => 1 }, { name => 'pins', diff => 1 } ], + closure_custom_calc => $self->can('custom_pin_hitratio_calc'), + output_template => 'pin hit ratio %.2f%%', + output_use => 'hit_ratio', threshold_use => 'hit_ratio', + perfdatas => [ + { label => 'pin_hit_ratio', value => 'hit_ratio', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'reloads', nlabel => 'library.cache.reloads.persecond', set => { + key_values => [ { name => 'reloads', diff => 1 }, ], + per_second => 1, + output_template => 'reloads %.2f/s', + perfdatas => [ + { label => 'reloads', value => 'reloads_per_second', template => '%.2f', min => 0, unit => '/s' }, + ], + } + }, + { label => 'invalids', nlabel => 'library.cache.invalids.persecond', set => { + key_values => [ { name => 'invalids', diff => 1 }, ], + per_second => 1, + output_template => 'invalids %.2f/s', + perfdatas => [ + { label => 'invalids', value => 'invalids_per_second', template => '%.2f', min => 0, unit => '/s' }, + ], + } + }, + ]; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'SGA library cache '; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $query = q{ + SELECT SUM(gethits), SUM(gets), SUM(pinhits), SUM(pins), + SUM(reloads), SUM(invalidations) + FROM v$librarycache + }; + + $options{sql}->connect(); + $options{sql}->query(query => $query); + my @result = $options{sql}->fetchrow_array(); + $options{sql}->disconnect(); + + $self->{global} = { + get_hits => $result[0], + gets => $result[1], + pin_hits => $result[2], + pins => $result[3], + reloads => $result[4], + invalids => $result[5], + }; + + $self->{cache_name} = "oracle_" . $self->{mode} . '_' . $options{sql}->get_unique_id4save() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check Oracle library cache usage. + +=over 8 + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'get-hits', 'pin-hits', 'reloads', 'invalid'. + +=back + +=cut diff --git a/database/oracle/mode/listasmdiskgroups.pm b/database/oracle/mode/listasmdiskgroups.pm new file mode 100644 index 000000000..105f1132f --- /dev/null +++ b/database/oracle/mode/listasmdiskgroups.pm @@ -0,0 +1,116 @@ +# +# Copyright 2019 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 database::oracle::mode::listasmdiskgroups; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::misc; + +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 => { + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{sql}->connect(); + $self->{sql}->query(query => q{ +SELECT name, state, type FROM V$ASM_DISKGROUP +}); + $self->{list_dg} = {}; + my $result = $self->{sql}->fetchall_arrayref(); + foreach my $row (@$result) { + $self->{list_dg}->{$row->[0]} = { + state => $row->[1], + type => $row->[2], + }; + } + + $self->{sql}->disconnect(); +} + +sub run { + my ($self, %options) = @_; + $self->{sql} = $options{sql}; + + $self->manage_selection(); + foreach my $name (sort keys %{$self->{list_dg}}) { + $self->{output}->output_add(long_msg => + '[name = ' . $name . '] ' . + '[state = ' . $self->{list_dg}->{$name}->{state} . '] ' . + '[type = ' . $self->{list_dg}->{$name}->{type} . '] ' + ); + } + $self->{output}->output_add(severity => 'OK', + short_msg => "List of asm disk groups:"); + + $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', 'state', 'type']); +} + +sub disco_show { + my ($self, %options) = @_; + $self->{sql} = $options{sql}; + + $self->manage_selection(); + foreach my $name (sort keys %{$self->{list_dg}}) { + $self->{output}->add_disco_entry( + name => $name, + state => $self->{list_dg}->{$name}->{state}, + type => $self->{list_dg}->{$name}->{type} + ); + } +} + +1; + +__END__ + +=head1 MODE + +List asm diskgroup. + +=over 8 + +=back + +=cut diff --git a/database/oracle/mode/longqueries.pm b/database/oracle/mode/longqueries.pm index f9b001ef7..6aea83f79 100644 --- a/database/oracle/mode/longqueries.pm +++ b/database/oracle/mode/longqueries.pm @@ -75,13 +75,12 @@ sub new { 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 => '' }, - "memory" => { name => 'memory' }, - "timezone:s" => { name => 'timezone' }, - }); + $options{options}->add_options(arguments => { + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + "memory" => { name => 'memory' }, + "timezone:s" => { name => 'timezone' }, + }); centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'DateTime', error_msg => "Cannot load module 'DateTime'."); @@ -135,6 +134,8 @@ sub manage_selection { my ($i, $current_time) = (1, time()); while ((my @row = $self->{sql}->fetchrow_array())) { + # can be: 1541985283,999999999999999999999999999996 + $row[1] =~ s/,/./; my @values = localtime($row[1]); my $dt = DateTime->new( year => $values[5] + 1900, @@ -162,6 +163,8 @@ sub manage_selection { if (defined($self->{option_results}->{memory})) { $self->{statefile_cache}->write(data => { last_time => $current_time }); } + + $self->{sql}->disconnect(); } 1; diff --git a/database/oracle/mode/passwordexpiration.pm b/database/oracle/mode/passwordexpiration.pm new file mode 100644 index 000000000..407c8e30f --- /dev/null +++ b/database/oracle/mode/passwordexpiration.pm @@ -0,0 +1,166 @@ +# +# Copyright 2019 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 database::oracle::mode::passwordexpiration; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use centreon::plugins::statefile; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("[username: %s] [account status: %s] expired in : %s", + $self->{result_values}->{username}, + $self->{result_values}->{account_status}, + $self->{result_values}->{expire_time} + ); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{account_status} = $options{new_datas}->{$self->{instance} . '_account_status'}; + $self->{result_values}->{username} = $options{new_datas}->{$self->{instance} . '_username'}; + $self->{result_values}->{expire} = $options{new_datas}->{$self->{instance} . '_expire'}; + $self->{result_values}->{expire_time} = $options{new_datas}->{$self->{instance} . '_expire_time'}; + return 0; +} + + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'users', type => 2, format_output => '%s user(s) detected', display_counter_problem => { label => 'users', min => 0 }, + group => [ { name => 'user', skipped_code => { -11 => 1 } } ] + } + ]; + + $self->{maps_counters}->{user} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'username' }, { name => 'account_status' }, { name => 'expire' }, { name => 'expire_time' } ], + 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 => \&catalog_status_threshold, + } + }, + ]; +} + +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 => '' }, + "timezone:s" => { name => 'timezone' }, + }); + + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'DateTime', + error_msg => "Cannot load module 'DateTime'."); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + $options{sql}->connect(); + + $self->{users}->{global} = { user => {} }; + + my $query = q{ + SELECT username, account_status, ((expiry_date - date '1970-01-01')*24*60*60) + FROM dba_users + WHERE expiry_date is not null AND account_status NOT LIKE '%EXPIRED%' + }; + $options{sql}->query(query => $query); + + my $tz = centreon::plugins::misc::set_timezone(name => $self->{option_results}->{timezone}); + my $i = 1; + while ((my @row = $options{sql}->fetchrow_array())) { + # can be: 1541985283,999999999999999999999999999996 + $row[2] =~ s/,/./; + my @values = localtime($row[2]); + my $dt = DateTime->new( + year => $values[5] + 1900, + month => $values[4] + 1, + day => $values[3], + hour => $values[2], + minute => $values[1], + second => $values[0], + %$tz + ); + + my $expire = abs(time() - $dt->epoch); + $self->{users}->{global}->{user}->{$i} = { + account_status => $row[1], + username => $row[0], + expire => $expire, + expire_time => centreon::plugins::misc::change_seconds(value => $expire) + }; + $i++; + } + + $self->{sql}->disconnect(); +} + +1; + +__END__ + +=head1 MODE + +Check user password expiration. + +=over 8 + +=item B<--warning-status> + +Set warning threshold for status (Default: '') +Can used special variables like: %{username}, %{account_status}, %{expire} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{username}, %{account_status}, %{expire} + +=item B<--timezone> + +Timezone of oracle server (If not set, we use current server execution timezone). + +=back + +=cut diff --git a/database/oracle/mode/processusage.pm b/database/oracle/mode/processusage.pm index 30fdd6f24..2472fc187 100644 --- a/database/oracle/mode/processusage.pm +++ b/database/oracle/mode/processusage.pm @@ -31,11 +31,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - }); + $options{options}->add_options(arguments => { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); return $self; } @@ -62,6 +61,7 @@ sub run { $self->{sql}->connect(); $self->{sql}->query(query => q{SELECT current_utilization/limit_value*100 FROM v$resource_limit WHERE resource_name = 'processes'}); my $session = $self->{sql}->fetchrow_array(); + $self->{sql}->disconnect(); my $exit_code = $self->{perfdata}->threshold_check(value => $session, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{output}->output_add(severity => $exit_code, diff --git a/database/oracle/mode/redologusage.pm b/database/oracle/mode/redologusage.pm new file mode 100644 index 000000000..0c90f773a --- /dev/null +++ b/database/oracle/mode/redologusage.pm @@ -0,0 +1,130 @@ +# +# Copyright 2019 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 database::oracle::mode::redologusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub custom_get_hitratio_calc { + my ($self, %options) = @_; + + my $delta_total = ($options{new_datas}->{$self->{instance} . '_redo_entries'} - $options{old_datas}->{$self->{instance} . '_redo_entries'}); + my $delta_retry = ($options{new_datas}->{$self->{instance} . '_redo_buffer_alloc_retries'} - $options{old_datas}->{$self->{instance} . '_redo_buffer_alloc_retries'}); + $self->{result_values}->{retry_ratio} = $delta_total ? (100 * $delta_retry / $delta_total) : 0; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', cb_prefix_output => 'prefix_global_output', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'retry-ratio', nlabel => 'redolog.retry.ratio.percentage', set => { + key_values => [ { name => 'redo_buffer_alloc_retries', diff => 1 }, { name => 'redo_entries', diff => 1 } ], + closure_custom_calc => $self->can('custom_get_hitratio_calc'), + output_template => 'retry ratio %.2f%%', + output_use => 'retry_ratio', threshold_use => 'retry_ratio', + perfdatas => [ + { label => 'retry_ratio', value => 'retry_ratio', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'traffic-io', nlabel => 'redolog.traffic.io.bytespersecond', set => { + key_values => [ { name => 'redo_size', diff => 1 } ], + output_change_bytes => 1, per_second => 1, + output_template => 'traffic io %s %s/s', + perfdatas => [ + { label => 'traffic_io', value => 'redo_size_per_second', template => '%s', min => 0, unit => 'B/s' }, + ], + } + }, + ]; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'Redo log '; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $query = q{ + SELECT a.value, b.value, c.value + FROM v$sysstat a, v$sysstat b, v$sysstat c + WHERE a.name = 'redo buffer allocation retries' + AND b.name = 'redo entries' + AND c.name = 'redo size' + }; + + $options{sql}->connect(); + $options{sql}->query(query => $query); + my @result = $options{sql}->fetchrow_array(); + $options{sql}->disconnect(); + + $self->{global} = { + redo_buffer_alloc_retries => $result[0], + redo_entries => $result[1], + redo_size => $result[2], + }; + + $self->{cache_name} = "oracle_" . $self->{mode} . '_' . $options{sql}->get_unique_id4save() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check Oracle library cache usage. + +=over 8 + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'retry-ratio', 'traffic-io'. + +=back + +=cut diff --git a/database/oracle/mode/rmanbackupage.pm b/database/oracle/mode/rmanbackupage.pm index afafb33a9..6e5553fca 100644 --- a/database/oracle/mode/rmanbackupage.pm +++ b/database/oracle/mode/rmanbackupage.pm @@ -32,13 +32,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "skip-no-backup" => { name => 'skip_no_backup', }, - "filter-type:s" => { name => 'filter_type', }, - "timezone:s" => { name => 'timezone', }, - "incremental-level" => { name => 'incremental_level', }, - }); + $options{options}->add_options(arguments => { + "skip-no-backup" => { name => 'skip_no_backup', }, + "filter-type:s" => { name => 'filter_type', }, + "timezone:s" => { name => 'timezone', }, + "incremental-level" => { name => 'incremental_level', }, + }); + foreach (('db incr', 'db full', 'archivelog', 'controlfile')) { my $label = $_; $label =~ s/ /-/g; @@ -101,6 +101,7 @@ sub run { } $self->{sql}->query(query => $query); my $result = $self->{sql}->fetchall_arrayref(); + $self->{sql}->disconnect(); $self->{output}->output_add(severity => 'OK', short_msg => sprintf("Rman backup age are ok.")); diff --git a/database/oracle/mode/rmanbackupproblems.pm b/database/oracle/mode/rmanbackupproblems.pm index 550a656aa..071cc388f 100644 --- a/database/oracle/mode/rmanbackupproblems.pm +++ b/database/oracle/mode/rmanbackupproblems.pm @@ -31,12 +31,11 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - "retention:s" => { name => 'retention', default => 3}, - }); + $options{options}->add_options(arguments => { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "retention:s" => { name => 'retention', default => 3 }, + }); return $self; } @@ -65,6 +64,7 @@ sub run { my $query = q{SELECT COUNT(*) FROM v$rman_status WHERE operation = 'BACKUP' AND status != 'COMPLETED' AND status != 'RUNNING' AND start_time > sysdate-} . $retention; $self->{sql}->query(query => $query); my $rman_backup_problems = $self->{sql}->fetchrow_array(); + $self->{sql}->disconnect(); my $exit_code = $self->{perfdata}->threshold_check(value => $rman_backup_problems, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{output}->output_add(severity => $exit_code, diff --git a/database/oracle/mode/rmanonlinebackupage.pm b/database/oracle/mode/rmanonlinebackupage.pm index f07651c53..8578e68de 100644 --- a/database/oracle/mode/rmanonlinebackupage.pm +++ b/database/oracle/mode/rmanonlinebackupage.pm @@ -32,12 +32,11 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - "timezone:s" => { name => 'timezone', }, - }); + $options{options}->add_options(arguments => { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "timezone:s" => { name => 'timezone', }, + }); return $self; } @@ -72,6 +71,7 @@ sub run { }; $self->{sql}->query(query => $query); my $result = $self->{sql}->fetchall_arrayref(); + $self->{sql}->disconnect(); $self->{output}->output_add(severity => 'OK', short_msg => sprintf("Backup online modes are ok.")); diff --git a/database/oracle/mode/rollbacksegmentusage.pm b/database/oracle/mode/rollbacksegmentusage.pm index 53f62c1d3..2b6b39b64 100644 --- a/database/oracle/mode/rollbacksegmentusage.pm +++ b/database/oracle/mode/rollbacksegmentusage.pm @@ -110,9 +110,9 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); + return $self; } @@ -160,6 +160,7 @@ sub manage_selection { $self->{cache_name} = "oracle_" . $self->{mode} . '_' . $self->{sql}->get_unique_id4save() . '_' . (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + $self->{sql}->disconnect(); } 1; diff --git a/database/oracle/mode/sessionusage.pm b/database/oracle/mode/sessionusage.pm index 4bd67306e..b349e1fca 100644 --- a/database/oracle/mode/sessionusage.pm +++ b/database/oracle/mode/sessionusage.pm @@ -31,11 +31,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - }); + $options{options}->add_options(arguments => { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + }); return $self; } @@ -62,7 +61,9 @@ sub run { $self->{sql}->connect(); $self->{sql}->query(query => q{SELECT current_utilization/limit_value*100 FROM v$resource_limit WHERE resource_name = 'sessions'}); my $session = $self->{sql}->fetchrow_array(); + $self->{sql}->disconnect(); + $session =~ s/,/./g; my $exit_code = $self->{perfdata}->threshold_check(value => $session, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{output}->output_add(severity => $exit_code, short_msg => sprintf("%.2f%% of session resources used.", $session)); diff --git a/database/oracle/mode/tablespaceusage.pm b/database/oracle/mode/tablespaceusage.pm index e4985ec84..effcac3be 100644 --- a/database/oracle/mode/tablespaceusage.pm +++ b/database/oracle/mode/tablespaceusage.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -51,23 +49,25 @@ sub custom_usage_perfdata { my $label = 'tbs_' . $self->{result_values}->{display} . '_usage'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'tbs_' . $self->{result_values}->{display} . '_free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -75,12 +75,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -117,13 +117,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-tablespace:s" => { name => 'filter_tablespace' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - "skip" => { name => 'skip' }, - }); + $options{options}->add_options(arguments => { + "filter-tablespace:s" => { name => 'filter_tablespace' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "skip" => { name => 'skip' }, + }); + return $self; } @@ -133,13 +133,6 @@ sub prefix_tablespace_output { return "Tablespace '" . $options{instance_value}->{display} . "' "; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; # $options{sql} = sqlmode object @@ -355,6 +348,7 @@ sub manage_selection { } $self->{sql}->query(query => $query); my $result = $self->{sql}->fetchall_arrayref(); + $self->{sql}->disconnect(); $self->{tablespace} = {}; diff --git a/database/oracle/mode/temptablespace.pm b/database/oracle/mode/temptablespace.pm index a755b7808..7228ad317 100644 --- a/database/oracle/mode/temptablespace.pm +++ b/database/oracle/mode/temptablespace.pm @@ -26,29 +26,29 @@ use strict; use warnings; use Digest::MD5 qw(md5_hex); -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label, - value => $value_perf, unit => 'B', - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, + value => $value_perf, unit => 'B', + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -56,10 +56,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); return $exit; @@ -114,26 +114,18 @@ sub prefix_tablespace_output { sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 0); + my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - - sub manage_selection { my ($self, %options) = @_; $self->{sql} = $options{sql}; @@ -169,6 +161,8 @@ sub manage_selection { while (my $result = $self->{sql}->fetchrow_hashref()) { $self->{tmptablespace}->{$result->{TABLESPACE}} = { used => $result->{B_USED}, total => $result->{B_TOTAL}, display => lc $result->{TABLESPACE} }; } + + $self->{sql}->disconnect(); } 1; diff --git a/database/oracle/mode/tnsping.pm b/database/oracle/mode/tnsping.pm index 4b44a00c2..0867fd90a 100644 --- a/database/oracle/mode/tnsping.pm +++ b/database/oracle/mode/tnsping.pm @@ -66,11 +66,12 @@ sub run { $self->{output}->output_add(severity => 'CRITICAL', short_msg => $msg_error); } else { - my ($sid) = $self->{sql}->{data_source} =~ /sid=(\S+)/; + my ($sid) = $self->{sql}->{data_source} =~ /(?:sid|service_name)=(\S+)/; $self->{output}->output_add(severity => 'OK', short_msg => sprintf("Connection established to listener '%s'.", $sid)); } + $self->{sql}->disconnect(); $self->{output}->display(); $self->{output}->exit(); } diff --git a/database/oracle/mode/undotablespace.pm b/database/oracle/mode/undotablespace.pm index dde50d160..e034bbd26 100644 --- a/database/oracle/mode/undotablespace.pm +++ b/database/oracle/mode/undotablespace.pm @@ -26,20 +26,18 @@ use strict; use warnings; use Digest::MD5 qw(md5_hex); -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } @@ -56,10 +54,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); return $exit; @@ -114,26 +112,18 @@ sub prefix_tablespace_output { sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 0); + my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - - sub manage_selection { my ($self, %options) = @_; $self->{sql} = $options{sql}; @@ -176,6 +166,8 @@ group by a.tablespace_name while (my $result = $self->{sql}->fetchrow_hashref()) { $self->{undotablespace}->{$result->{TABLESPACE_NAME}} = { used => $result->{USED_BYTES}, total => $result->{TOTAL_BYTES}, display => lc $result->{TABLESPACE_NAME} }; } + + $self->{sql}->disconnect(); } 1; diff --git a/database/oracle/plugin.pm b/database/oracle/plugin.pm index 702ea17da..4e0913299 100644 --- a/database/oracle/plugin.pm +++ b/database/oracle/plugin.pm @@ -32,55 +32,71 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'asm-diskgroup-usage' => 'database::oracle::mode::asmdiskgroupusage', - 'connection-time' => 'centreon::common::protocols::sql::mode::connectiontime', - 'connected-users' => 'database::oracle::mode::connectedusers', - 'corrupted-blocks' => 'database::oracle::mode::corruptedblocks', - 'data-files-status' => 'database::oracle::mode::datafilesstatus', - 'datacache-hitratio' => 'database::oracle::mode::datacachehitratio', - 'event-waits-usage' => 'database::oracle::mode::eventwaitsusage', - 'invalid-object' => 'database::oracle::mode::invalidobject', - 'long-queries' => 'database::oracle::mode::longqueries', - 'process-usage' => 'database::oracle::mode::processusage', - 'rman-backup-problems' => 'database::oracle::mode::rmanbackupproblems', - 'rman-backup-age' => 'database::oracle::mode::rmanbackupage', - 'rman-online-backup-age' => 'database::oracle::mode::rmanonlinebackupage', - 'rollback-segment-usage' => 'database::oracle::mode::rollbacksegmentusage', - 'tablespace-usage' => 'database::oracle::mode::tablespaceusage', - 'temp-usage' => 'database::oracle::mode::temptablespace', - 'undo-usage' => 'database::oracle::mode::undotablespace', - 'session-usage' => 'database::oracle::mode::sessionusage', - 'sql' => 'centreon::common::protocols::sql::mode::sql', - 'sql-string' => 'centreon::common::protocols::sql::mode::sqlstring', - 'tnsping' => 'database::oracle::mode::tnsping', - ); + 'asm-diskgroup-usage' => 'database::oracle::mode::asmdiskgroupusage', + 'connection-time' => 'centreon::common::protocols::sql::mode::connectiontime', + 'connected-users' => 'database::oracle::mode::connectedusers', + 'corrupted-blocks' => 'database::oracle::mode::corruptedblocks', + 'data-files-status' => 'database::oracle::mode::datafilesstatus', + 'datacache-hitratio' => 'database::oracle::mode::datacachehitratio', + 'dictionary-cache-usage' => 'database::oracle::mode::dictionarycacheusage', + 'library-cache-usage' => 'database::oracle::mode::librarycacheusage', + 'event-waits-usage' => 'database::oracle::mode::eventwaitsusage', + 'invalid-object' => 'database::oracle::mode::invalidobject', + 'library-cache-usage' => 'database::oracle::mode::librarycacheusage', + 'list-asm-diskgroups' => 'database::oracle::mode::listasmdiskgroups', + 'long-queries' => 'database::oracle::mode::longqueries', + 'password-expiration' => 'database::oracle::mode::passwordexpiration', + 'process-usage' => 'database::oracle::mode::processusage', + 'redolog-usage' => 'database::oracle::mode::redologusage', + 'rman-backup-problems' => 'database::oracle::mode::rmanbackupproblems', + 'rman-backup-age' => 'database::oracle::mode::rmanbackupage', + 'rman-online-backup-age' => 'database::oracle::mode::rmanonlinebackupage', + 'rollback-segment-usage' => 'database::oracle::mode::rollbacksegmentusage', + 'session-usage' => 'database::oracle::mode::sessionusage', + 'sql' => 'centreon::common::protocols::sql::mode::sql', + 'sql-string' => 'centreon::common::protocols::sql::mode::sqlstring', + 'tablespace-usage' => 'database::oracle::mode::tablespaceusage', + 'temp-usage' => 'database::oracle::mode::temptablespace', + 'tnsping' => 'database::oracle::mode::tnsping', + 'undo-usage' => 'database::oracle::mode::undotablespace', + ); + $self->{sql_modes}{sqlpluscmd} = 'database::oracle::sqlpluscmd'; + return $self; } sub init { my ($self, %options) = @_; - $self->{options}->add_options( - arguments => { - 'hostname:s@' => { name => 'hostname' }, - 'port:s@' => { name => 'port' }, - 'sid:s' => { name => 'sid' }, - } - ); + $self->{options}->add_options(arguments => { + 'hostname:s@' => { name => 'hostname' }, + 'port:s@' => { name => 'port' }, + 'sid:s' => { name => 'sid' }, + 'servicename:s' => { name => 'servicename' }, + }); + $self->{options}->parse_options(); my $options_result = $self->{options}->get_options(); $self->{options}->clean(); if (defined($options_result->{hostname})) { @{$self->{sqldefault}->{dbi}} = (); + @{$self->{sqldefault}->{sqlpluscmd}} = (); for (my $i = 0; $i < scalar(@{$options_result->{hostname}}); $i++) { $self->{sqldefault}->{dbi}[$i] = { data_source => 'Oracle:host=' . $options_result->{hostname}[$i] }; + $self->{sqldefault}->{sqlpluscmd}[$i] = { hostname => $options_result->{hostname}[$i] }; if (defined($options_result->{port}[$i])) { $self->{sqldefault}->{dbi}[$i]->{data_source} .= ';port=' . $options_result->{port}[$i]; + $self->{sqldefault}->{sqlpluscmd}[$i]->{port} = $options_result->{port}[$i]; } - if ((defined($options_result->{sid})) && ($options_result->{sid} ne '')) { + if (defined($options_result->{sid}) && $options_result->{sid} ne '') { $self->{sqldefault}->{dbi}[$i]->{data_source} .= ';sid=' . $options_result->{sid}; + $self->{sqldefault}->{sqlpluscmd}[$i]->{sid} = $options_result->{sid}; + } + if (defined($options_result->{servicename}) && $options_result->{servicename} ne '') { + $self->{sqldefault}->{dbi}[$i]->{data_source} .= ';service_name=' . $options_result->{servicename}; + $self->{sqldefault}->{sqlpluscmd}[$i]->{service_name} = $options_result->{servicename}; } } } @@ -107,7 +123,11 @@ Database Server Port. =item B<--sid> -Database SID (SERVICE_NAME). +Database SID. + +=item B<--servicename> + +Database Service Name. =back diff --git a/database/oracle/sqlpluscmd.pm b/database/oracle/sqlpluscmd.pm new file mode 100644 index 000000000..60f44d576 --- /dev/null +++ b/database/oracle/sqlpluscmd.pm @@ -0,0 +1,462 @@ +# +# Copyright 2018 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 database::oracle::sqlpluscmd; + +use strict; +use warnings; +use centreon::plugins::misc; +use Digest::MD5 qw(md5_hex); +use File::Temp qw(tempfile); +use Data::Dumper; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + # $options{options} = options object + # $options{output} = output object + # $options{exit_value} = integer + # $options{noptions} = integer + + if (!defined($options{output})) { + print "Class sqlpluscmd: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class sqlpluscmd: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "sqlplus-cmd:s" => { name => 'sqlplus_cmd'}, + "oracle-home:s" => { name => 'oracle_home' }, + "tnsadmin-home:s" => { name => 'tnsadmin_home' }, + "tnsnames-sid:s" => { name => 'tnsnames_sid'}, + "tnsnames-servicename:s" => { name => 'tnsnames_servicename'}, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "local-connexion" => { name => 'local_connexion', default => 0 }, + "sysdba" => { name => 'sysdba', default => 0 }, + "sql-errors-exit:s" => { name => 'sql_errors_exit', default => 'unknown' }, + "tempdir:s" => { name => 'tempdir', default => '/tmp' }, + } + ); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'sqlpluscmd OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{args} = undef; + $self->{stdout} = undef; + $self->{columns} = undef; + $self->{version} = undef; + + $self->{sid} = undef; + $self->{oracle_home} = undef; + $self->{tnsadmin_home} = undef; + $self->{local_connexion} = undef; + + return $self; +} + +# Method to manage multiples +sub set_options { + my ($self, %options) = @_; + # options{options_result} + + $self->{option_results} = $options{option_results}; +} + +# Method to manage multiples +sub set_defaults { + my ($self, %options) = @_; + # options{default} + + # Manage default value + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + # return 1 = ok still data_source + # return 0 = no data_source left + + $self->{sid} = defined($self->{option_results}->{sid}[0]) ? $self->{option_results}->{sid}[0]: $self->{option_results}->{tnsnames_sid}; + $self->{service_name} = defined($self->{option_results}->{service_name}[0]) ? $self->{option_results}->{service_name}[0]: $self->{option_results}->{tnsnames_servicename}; + $self->{oracle_home} = defined($self->{option_results}->{oracle_home}) ? $self->{option_results}->{oracle_home} : $ENV{'ORACLE_HOME'}; + $self->{tnsadmin_home} = defined($self->{option_results}->{tnsadmin_home}) ? $self->{option_results}->{tnsadmin_home} : $ENV{'TNSADMIN'}; + $self->{local_connexion} = $self->{option_results}->{local_connexion}; + $self->{sqlplus_cmd} = $self->{option_results}->{sqlplus_cmd}; + + $self->{output}->output_add(long_msg => "*** DEBUG MODE****\n", debug => 1); + $self->{output}->output_add(long_msg => Data::Dumper::Dumper($self->{option_results}), debug => 1); + + if ((!defined($self->{sid}) || $self->{sid} eq '') && + (!defined($self->{service_name}) || $self->{service_name} eq '')) { + $self->{output}->add_option_msg(short_msg => "Need to specify sid or servicename argument."); + $self->{output}->option_exit(exit_litteral => $self->{option_results}->{sql_errors_exit}); + } + + # check the ORACLE_HOME variable + if (!defined($self->{oracle_home}) || $self->{oracle_home} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify oracle-home argument."); + $self->{output}->option_exit(exit_litteral => $self->{option_results}->{sql_errors_exit}); + } + + # construct the TNSADMIN variable if not available + if(!defined($self->{tnsadmin_home})) { + $self->{tnsadmin_home} = $self->{oracle_home} . "/network/admin"; + } + + # check the SQLPLUS command to use + if(!$self->{sqlplus_cmd}) { + $self->{sqlplus_cmd} = $self->{oracle_home} . "/bin/sqlplus"; + } + + $self->{args} = ['-L', '-S']; + my $connection_string = ""; + if ($self->{option_results}->{sysdba} == 1) { + $self->{output}->output_add(long_msg => "*** SYDBA MODE****", debug => 1); + $connection_string="/ as sysdba"; + $self->{local_connexion} = 1; + } elsif (defined($self->{option_results}->{username}) && defined($self->{option_results}->{password})) { + $connection_string=$self->{option_results}->{username} . "/" . $self->{option_results}->{password}; + } else { + $self->{output}->add_option_msg(short_msg => "Need to specify username/password arguments or sysdba option."); + $self->{output}->option_exit(exit_litteral => $self->{option_results}->{sql_errors_exit}); + } + + if ($self->{local_connexion} == 0) { + if (defined($self->{option_results}->{hostname})) { + my $port = defined($self->{option_results}->{port}) ? $self->{option_results}->{port}[0] : 1521; + $connection_string .= "\@//" . $self->{option_results}->{hostname}[0] . ":" . $port . "/" . (defined($self->{sid}) && $self->{sid} ne '') ? $self->{sid} : $self->{service_name}); + } else { + $connection_string .= "\@" . (defined($self->{sid}) && $self->{sid} ne '') ? $self->{sid} : $self->{service_name}); + } + } else { + $self->{output}->output_add(long_msg => "*** LOCAL CONNEXION MODE****", debug => 1); + if (defined($self->{sid}) && $self->{sid} ne '') { + $ENV{ORACLE_SID} = $self->{sid}; + } else { + $ENV{TWO_TASK} = '/' . $self->{service_name}; + } + } + + # register a false data_source to be compliant with tnsping mode + if (defined($self->{sid}) && $self->{sid} ne '') { + $self->{data_source} = "sid=" . $self->{sid}; + } else { + $self->{data_source} = "service_name=" . $self->{service_name}; + } + + push @{$self->{args}}, $connection_string; + + # set oracle env variable + $ENV{ORACLE_HOME} = $self->{oracle_home}; + $ENV{TNSADMIN} = $self->{tnsadmin_home}; + + if (defined($self->{option_results}->{sid})) { + return 0; + } + return 1; +} + +sub is_version_minimum { + my ($self, %options) = @_; + # $options{version} = string version to check + + my @version_src = split /\./, $self->{version}; + my @versions = split /\./, $options{version}; + for (my $i = 0; $i < scalar(@versions); $i++) { + return 1 if ($versions[$i] eq 'x'); + return 1 if (!defined($version_src[$i])); + $version_src[$i] =~ /^([0-9]*)/; + next if ($versions[$i] == int($1)); + return 0 if ($versions[$i] > int($1)); + return 1 if ($versions[$i] < int($1)); + } + + return 1; +} + +sub get_id { + my ($self, %options) = @_; + + my $msg = $self->{sid}; + return $msg; +} + + +sub get_unique_id4save { + my ($self, %options) = @_; + + my $msg = $self->{sid}; + return md5_hex($msg); +} + +sub quote { + my $self = shift; + + return undef; +} + +sub command_execution { + my ($self, %options) = @_; + + my ($fh, $tempfile) = tempfile(DIR => $self->{option_results}->{tempdir}, SUFFIX => ".sql", UNLINK => 1); + print $fh "set echo off +-- set heading off +set feedback off +set linesize 16000 +set pagesize 50000 +set colsep '#&!#' +set numwidth 15 +$options{request}; +exit;"; + + $self->{output}->output_add(long_msg => "*** COMMAND: " . $self->{sqlplus_cmd} . ' ' . join(' ', (@{$self->{args}}, '@', $tempfile)), debug => 1); + $self->{output}->output_add(long_msg => "*** REQUEST: " . $options{request}, debug => 1); + my ($lerror, $stdout, $exit_code) = centreon::plugins::misc::backtick( + command => $self->{sqlplus_cmd}, + arguments => [@{$self->{args}}, '@', $tempfile], + timeout => 30, + wait_exit => 1, + redirect_stderr => 1 + ); + $self->{output}->output_add(long_msg => "REQ. STDOUT: '$stdout'", debug => 1); + $self->{output}->output_add(long_msg => "REQ. EXIT_CODE: $exit_code", debug => 1); + + # search oracle error lines + $exit_code = -1 if($stdout =~ /^(ORA\-\d+|TNS\-\d+|SP\d\-\d+)/); + + if ($exit_code <= -1000) { + if ($exit_code == -1000) { + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => $stdout); + } + $self->{output}->display(); + $self->{output}->exit(); + } + + return ($exit_code, $stdout); +} + +sub disconnect {} + +# Connection initializer +sub connect { + my ($self, %options) = @_; + my $dontquit = (defined($options{dontquit}) && $options{dontquit} == 1) ? 1 : 0; + + (my $exit_code, $self->{stdout}) = $self->command_execution(request => "select version from v\$instance"); + if ($exit_code != 0) { + if ($dontquit == 0) { + $self->{output}->add_option_msg(short_msg => "Cannot connect: " . $self->{stdout}); + $self->{output}->option_exit(exit_litteral => $self->{option_results}->{sql_errors_exit}); + } + return (-1, "Cannot connect: " . $self->{stdout}); + } + + $self->{version} = $self->fetchrow_array(); + + $self->{output}->output_add(long_msg => "VERSION: " . $self->{version}, debug => 1); + return 0; +} + +sub fetchall_arrayref { + my ($self, %options) = @_; + my $array_ref = []; + + if($self->{stdout} eq '') { + $self->{output}->output_add(long_msg => "fetchall_arrayref: no data returned (no rows selected)", debug => 1); + return $array_ref; + } + + if (!defined($self->{columns})) { + $self->{stdout} =~ s/^\s*\n(.*?)(\n|$)//; + my $line = $1; + $self->{output}->output_add(long_msg => "fetchall_arrayref COLUMNS: $line", debug => 1) if(defined($line)); + @{$self->{columns}} = split(/#&!#/, $line); + map { s/^\s+|\s+$//g; } @{$self->{columns}}; + $self->{stdout} =~ s/[\-#&!]+(\n|$)//; + } + foreach (split /\n/, $self->{stdout}) { + my $line = $_; + $line =~ s/^\s+|\s+$//g; + $line =~ s/#&!#\s+/#&!#/g; + $line =~ s/\s+#&!#/#&!#/g; + + $self->{output}->output_add(long_msg => "fetchall_arrayref VALUE: " . $line, debug => 1); + push @$array_ref, [map({ s/\\n/\x{0a}/g; s/\\t/\x{09}/g; s/\\/\x{5c}/g; $_; } split(/#&!#/, $line))]; + } + return $array_ref; +} + +sub fetchrow_array { + my ($self, %options) = @_; + my @array_result = (); + + if($self->{stdout} eq '') { + $self->{output}->output_add(long_msg => "fetchrow_array: no data returned (no rows selected)", debug => 1); + return @array_result; + } + + if (!defined($self->{columns})) { + $self->{stdout} =~ s/^\s*\n(.*?)(\n|$)//; + my $line = $1; + $self->{output}->output_add(long_msg => "fetchrow_array COLUMNS: $line", debug => 1); + @{$self->{columns}} = split(/#&!#/, $line); + map { s/^\s+|\s+$//g; } @{$self->{columns}}; + $self->{stdout} =~ s/[\-#&!]+(\n|$)//; + } + $self->{output}->output_add(long_msg => "fetchrow_array STDOUT: '" . $self->{stdout} . "'", debug => 1); + if (($self->{stdout} =~ s/^(.*?)(\n|$)//)) { + my $line = $1; + $self->{output}->output_add(long_msg => "fetchrow_array VALUE: '" . $line . "'", debug => 1); + push @array_result, map({ s/\\n/\x{0a}/g; s/\\t/\x{09}/g; s/\\/\x{5c}/g; $_; } split(/#&!#/, $line)); + map { s/^\s+|\s+$//g; } @array_result; + $self->{output}->output_add(long_msg => "ARRAY: " . Data::Dumper::Dumper(@array_result), debug => 1); + } + + $self->{output}->output_add(long_msg => "RETURN: " . Data::Dumper::Dumper(@array_result), debug => 1); + return scalar(@array_result) == 1 ? $array_result[0] : @array_result; +} + +sub fetchrow_hashref { + my ($self, %options) = @_; + my $array_result = undef; + + if($self->{stdout} eq '') { + $self->{output}->output_add(long_msg => "fetchrow_hashref: no data returned (no rows selected)", debug => 1); + return $array_result; + } + + if (!defined($self->{columns})) { + $self->{stdout} =~ s/^\s*\n(.*?)(\n|$)//; + my $line = $1; + $self->{output}->output_add(long_msg => "fetchrow_hashref COLUMNS: $line", debug => 1); + @{$self->{columns}} = split(/#&!#/, $line); + map { s/^\s+|\s+$//g; } @{$self->{columns}}; + $self->{stdout} =~ s/[\-#&!]+(\n|$)//; + } + if ($self->{stdout} ne '' && $self->{stdout} =~ s/^(.*?)(\n|$)//) { + my $line = $1; + $self->{output}->output_add(long_msg => "fetchrow_hashref VALUE: " . $line, debug => 1); + $array_result = {}; + my @values = split(/#&!#/, $line); + for (my $i = 0; $i < scalar(@values); $i++) { + my $value = $values[$i]; + $value =~ s/^\s+|\s+$//g; + $value =~ s/\\n/\x{0a}/g; + $value =~ s/\\t/\x{09}/g; + $value =~ s/\\/\x{5c}/g; + $self->{output}->output_add(long_msg => "fetchrow_hashref RES: '" . $self->{columns}[$i] . "' = '$value'", debug => 1); + $array_result->{$self->{columns}[$i]} = $value; + } + } + + return $array_result; +} + +sub query { + my ($self, %options) = @_; + + $self->{columns} = undef; + (my $exit_code, $self->{stdout}) = $self->command_execution(request => $options{query}); + if ($exit_code != 0) { + $self->{output}->add_option_msg(short_msg => "Cannot execute query: " . $self->{stdout}); + $self->{output}->option_exit(exit_litteral => $self->{option_results}->{sql_errors_exit}); + } +} + +1; + +__END__ + +=head1 NAME + +sqlpluscmd global + +=head1 SYNOPSIS + +sqlpluscmd class + +=head1 sqlpluscmd OPTIONS + +=over 8 + +=item B<--sqlplus-cmd> + +sqlplus command (Default: 'sqlplus'). + +=item B<--oracle-home> + +Oracle Database Server Home. + +=item B<--tnsadmin-home> + +Oracle TNS Admin Home. Where to locate tnsnames.ora file (default: ${ORACLE_HOME}/network/admin) + +=item B<--tnsnames-sid> + +Oracle SID defined in tnsnames.ora. + +=item B<--tnsnames-servicename> + +Oracle Service Name defined in tnsnames.ora. + +=item B<--username> + +Database username. + +=item B<--password> + +Database password. + +=item B<--sysdba> + +Use a sysdba connexion, need to be execute under the oracle local user on the server, and use a local connexion. + +=item B<--local-connexion> + +Use a local connexion, don't need listener. + +=item B<--sql-errors-exit> + +Exit code for DB Errors (default: unknown) + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/database/postgres/mode/listdatabases.pm b/database/postgres/mode/listdatabases.pm index 1fdc9b15b..491c34b2d 100644 --- a/database/postgres/mode/listdatabases.pm +++ b/database/postgres/mode/listdatabases.pm @@ -31,10 +31,9 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "exclude:s" => { name => 'exclude', }, - }); + $options{options}->add_options(arguments => { + "exclude:s" => { name => 'exclude', }, + }); return $self; } @@ -50,8 +49,9 @@ sub manage_selection { $self->{sql}->connect(); $self->{sql}->query(query => q{ -SELECT datname FROM pg_database -}); + SELECT datname FROM pg_database + } + ); $self->{list_db} = []; while ((my $row = $self->{sql}->fetchrow_hashref())) { if (defined($self->{option_results}->{exclude}) && $row->{datname} !~ /$self->{option_results}->{exclude}/) { diff --git a/database/postgres/mode/querytime.pm b/database/postgres/mode/querytime.pm index be02ced74..3224c170a 100644 --- a/database/postgres/mode/querytime.pm +++ b/database/postgres/mode/querytime.pm @@ -31,13 +31,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - "exclude:s" => { name => 'exclude', }, - "exclude-user:s" => { name => 'exclude_user', }, - }); + $options{options}->add_options(arguments => { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "exclude:s" => { name => 'exclude', }, + "exclude-user:s" => { name => 'exclude_user', }, + }); return $self; } @@ -66,19 +65,19 @@ sub run { my $query; if ($self->{sql}->is_version_minimum(version => '9.2')) { $query = q{ -SELECT datname, datid, pid, usename, client_addr, query AS current_query, state AS state, - CASE WHEN client_port < 0 THEN 0 ELSE client_port END AS client_port, +SELECT pg_database.datname, pgsa.datid, pgsa.pid, pgsa.usename, pgsa.client_addr, pgsa.query AS current_query, pgsa.state AS state, + CASE WHEN pgsa.client_port < 0 THEN 0 ELSE pgsa.client_port END AS client_port, COALESCE(ROUND(EXTRACT(epoch FROM now()-query_start)),0) AS seconds -FROM pg_stat_activity WHERE (query_start IS NOT NULL AND (state NOT LIKE 'idle%' OR state IS NULL)) -ORDER BY query_start, pid DESC +FROM pg_database LEFT JOIN pg_stat_activity pgsa ON pg_database.datname = pgsa.datname AND (pgsa.query_start IS NOT NULL AND (pgsa.state NOT LIKE 'idle%' OR pgsa.state IS NULL)) +ORDER BY pgsa.query_start, pgsa.pid DESC }; } else { $query = q{ -SELECT datname, datid, procpid AS pid, usename, client_addr, current_query AS current_query, '' AS state, - CASE WHEN client_port < 0 THEN 0 ELSE client_port END AS client_port, +SELECT pg_database.datname, pgsa.datid, pgsa.procpid, pgsa.usename, pgsa.client_addr, pgsa.current_query AS current_query, '' AS state, + CASE WHEN pgsa.client_port < 0 THEN 0 ELSE pgsa.client_port END AS client_port, COALESCE(ROUND(EXTRACT(epoch FROM now()-query_start)),0) AS seconds -FROM pg_stat_activity WHERE (query_start IS NOT NULL AND current_query NOT LIKE '%') -ORDER BY query_start, procpid DESC +FROM pg_database LEFT JOIN pg_stat_activity pgsa ON pg_database.datname = pgsa.datname AND (pgsa.query_start IS NOT NULL AND current_query NOT LIKE '%') +ORDER BY pgsa.query_start, pgsa.procpid DESC }; } @@ -88,6 +87,11 @@ ORDER BY query_start, procpid DESC short_msg => "All databases queries time are ok."); my $dbquery = {}; while ((my $row = $self->{sql}->fetchrow_hashref())) { + if (!defined($dbquery->{$row->{datname}})) { + $dbquery->{$row->{datname}} = { total => 0, code => {} }; + } + next if (!defined($row->{datid}) || $row->{datid} eq ''); # No joint + if (defined($self->{option_results}->{exclude}) && $row->{datname} !~ /$self->{option_results}->{exclude}/) { next; } @@ -107,8 +111,6 @@ ORDER BY query_start, procpid DESC foreach my $dbname (keys %$dbquery) { $self->{output}->perfdata_add(label => $dbname . '_qtime_num', value => $dbquery->{$dbname}->{total}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), min => 0); foreach my $exit_code (keys %{$dbquery->{$dbname}->{code}}) { $self->{output}->output_add(severity => $exit_code, diff --git a/database/postgres/mode/statistics.pm b/database/postgres/mode/statistics.pm index ed6bb4a2a..626acddec 100644 --- a/database/postgres/mode/statistics.pm +++ b/database/postgres/mode/statistics.pm @@ -20,271 +20,141 @@ package database::postgres::mode::statistics; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); -my $maps_counters = { - database => { - '000_commit' => { set => { - key_values => [ { name => 'commit', diff => 1 }, { name => 'name' }, ], - output_template => 'Commit : %s', - perfdatas => [ - { label => 'commit', value => 'commit_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, - ], - } - }, - '001_rollback' => { set => { - key_values => [ { name => 'rollback', diff => 1 }, { name => 'name' }, ], - output_template => 'Rollback : %s', - perfdatas => [ - { label => 'rollback', value => 'rollback_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, - ], - } - }, - '002_insert' => { set => { - key_values => [ { name => 'insert', diff => 1 }, { name => 'name' }, ], - output_template => 'Insert : %s', - perfdatas => [ - { label => 'insert', value => 'insert_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, - ], - } - }, - '003_update' => { set => { - key_values => [ { name => 'update', diff => 1 }, { name => 'name' }, ], - output_template => 'Update : %s', - perfdatas => [ - { label => 'update', value => 'update_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, - ], - } - }, - '004_delete' => { set => { - key_values => [ { name => 'delete', diff => 1 }, { name => 'name' }, ], - output_template => 'Delete : %s', - perfdatas => [ - { label => 'delete', value => 'delete_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, - ], - } - }, +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', skipped_code => { -10 => 1 } }, + { name => 'database', type => 1, cb_prefix_output => 'prefix_database_output', message_multiple => 'All database statistics are ok' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total-commit', nlabel => 'queries.commit.count', set => { + key_values => [ { name => 'commit', diff => 1 } ], + output_template => 'Commit : %s', + perfdatas => [ + { label => 'commit', value => 'commit_absolute', template => '%s', min => 0 }, + ], + } }, - total => { - '000_total-commit' => { set => { - key_values => [ { name => 'commit', diff => 1 } ], - output_template => 'Commit : %s', - perfdatas => [ - { label => 'commit', value => 'commit_absolute', template => '%s', min => 0 }, - ], - } - }, - '001_total-rollback' => { set => { - key_values => [ { name => 'rollback', diff => 1 } ], - output_template => 'Rollback : %s', - perfdatas => [ - { label => 'rollback', value => 'rollback_absolute', template => '%s', min => 0 }, - ], - } - }, - '002_total-insert' => { set => { - key_values => [ { name => 'insert', diff => 1 } ], - output_template => 'Insert : %s', - perfdatas => [ - { label => 'insert', value => 'insert_absolute', template => '%s', min => 0 }, - ], - } - }, - '003_total-update' => { set => { - key_values => [ { name => 'update', diff => 1 } ], - output_template => 'Update : %s', - perfdatas => [ - { label => 'update', value => 'update_absolute', template => '%s', min => 0 }, - ], - } - }, - '004_total-delete' => { set => { - key_values => [ { name => 'delete', diff => 1 } ], - output_template => 'Delete : %s', - perfdatas => [ - { label => 'delete', value => 'delete_absolute', template => '%s', min => 0 }, - ], - } - }, - } -}; + { label => 'total-rollback', nlabel => 'queries.rollback.count', set => { + key_values => [ { name => 'rollback', diff => 1 } ], + output_template => 'Rollback : %s', + perfdatas => [ + { label => 'rollback', value => 'rollback_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'total-insert', nlabel => 'queries.insert.count', set => { + key_values => [ { name => 'insert', diff => 1 } ], + output_template => 'Insert : %s', + perfdatas => [ + { label => 'insert', value => 'insert_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'total-update', nlabel => 'queries.update.count', set => { + key_values => [ { name => 'update', diff => 1 } ], + output_template => 'Update : %s', + perfdatas => [ + { label => 'update', value => 'update_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'total-delete', nlabel => 'queries.delete.count', set => { + key_values => [ { name => 'delete', diff => 1 } ], + output_template => 'Delete : %s', + perfdatas => [ + { label => 'delete', value => 'delete_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{database} = [ + { label => 'commit', nlabel => 'queries.commit.count', set => { + key_values => [ { name => 'commit', diff => 1 }, { name => 'name' }, ], + output_template => 'Commit : %s', + perfdatas => [ + { label => 'commit', value => 'commit_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + { label => 'rollback', nlabel => 'queries.rollback.count', set => { + key_values => [ { name => 'rollback', diff => 1 }, { name => 'name' }, ], + output_template => 'Rollback : %s', + perfdatas => [ + { label => 'rollback', value => 'rollback_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + { label => 'insert', nlabel => 'queries.insert.count', set => { + key_values => [ { name => 'insert', diff => 1 }, { name => 'name' }, ], + output_template => 'Insert : %s', + perfdatas => [ + { label => 'insert', value => 'insert_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + { label => 'update', nlabel => 'queries.update.count', set => { + key_values => [ { name => 'update', diff => 1 }, { name => 'name' }, ], + output_template => 'Update : %s', + perfdatas => [ + { label => 'update', value => 'update_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + { label => 'delete', nlabel => 'queries.delete.count', set => { + key_values => [ { name => 'delete', diff => 1 }, { name => 'name' }, ], + output_template => 'Delete : %s', + perfdatas => [ + { label => 'delete', value => 'delete_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, + ], + } + }, + ]; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'Total '; +} + +sub prefix_database_output { + my ($self, %options) = @_; + + return "Database '" . $options{instance_value}->{name} . "' "; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-database:s" => { name => 'filter_database' }, - }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); + $options{options}->add_options(arguments => { + "filter-database:s" => { name => 'filter_database' }, + }); - foreach my $key (('database', 'total')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('database', 'total')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - $self->{statefile_value}->check_options(%options); -} - -sub check_total { - my ($self, %options) = @_; - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{total}}) { - my $obj = $maps_counters->{total}->{$_}->{obj}; - $obj->set(instance => 'global'); - - my ($value_check) = $obj->execute(values => $self->{global}, - new_datas => $self->{new_datas}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(); - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Total $short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "Total $long_msg"); - } -} - -sub run { - my ($self, %options) = @_; - # $options{sql} = sqlmode object - $self->{sql} = $options{sql}; - - $self->manage_selection(); - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "postgres_" . $self->{mode} . '_' . $self->{sql}->get_unique_id4save() . '_' . (defined($self->{option_results}->{filter_database}) ? md5_hex($self->{option_results}->{filter_database}) : md5_hex('.*'))); - $self->{new_datas}->{last_timestamp} = time(); - - my $multiple = 1; - if (scalar(keys %{$self->{db_selected}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->check_total(); - } - - #### - # By database - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All database statistics are ok'); - } - - foreach my $id (sort keys %{$self->{db_selected}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{database}}) { - my $obj = $maps_counters->{database}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{db_selected}->{$id}, - new_datas => $self->{new_datas}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{database}->{$_}->{obj}->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Database '" . $self->{db_selected}->{$id}->{name} . "' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Database '" . $self->{db_selected}->{$id}->{name} . "' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Database '" . $self->{db_selected}->{$id}->{name} . "' $long_msg"); - } - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; - $self->{db_selected} = {}; + $self->{database} = {}; $self->{global} = { commit => 0, rollback => 0, insert => 0, update => 0, delete => 0 }; my $query = q{ SELECT d.datname as name, pg_stat_get_db_xact_commit(d.oid) as commit, @@ -293,26 +163,30 @@ SELECT d.datname as name, pg_stat_get_db_xact_commit(d.oid) as commit, pg_stat_get_tuples_updated(d.oid) as update, pg_stat_get_tuples_updated(d.oid) as delete FROM pg_database d; }; - $self->{sql}->connect(); - $self->{sql}->query(query => $query); + $options{sql}->connect(); + $options{sql}->query(query => $query); - while ((my $row = $self->{sql}->fetchrow_hashref())) { + while ((my $row = $options{sql}->fetchrow_hashref())) { if (defined($self->{option_results}->{filter_database}) && $self->{option_results}->{filter_database} ne '' && $row->{name} !~ /$self->{option_results}->{filter_database}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $row->{name} . "': no matching filter."); + $self->{output}->output_add(long_msg => "skipping '" . $row->{name} . "': no matching filter."); next; } - $self->{db_selected}->{$row->{name}} = {%$row}; + $self->{database}->{$row->{name}} = {%$row}; foreach (keys %{$self->{global}}) { $self->{global}->{$_} += $row->{$_}; } } - if (scalar(keys %{$self->{db_selected}}) <= 0) { + if (scalar(keys %{$self->{database}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No database found."); $self->{output}->option_exit(); } + + $self->{cache_name} = "postgres_" . $self->{mode} . '_' . $options{sql}->get_unique_id4save() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_database}) ? md5_hex($self->{option_results}->{filter_database}) : md5_hex('all')); } 1; diff --git a/database/postgres/psqlcmd.pm b/database/postgres/psqlcmd.pm index 2186c50ac..5d5d02912 100644 --- a/database/postgres/psqlcmd.pm +++ b/database/postgres/psqlcmd.pm @@ -170,7 +170,6 @@ sub get_id { return $msg; } - sub get_unique_id4save { my ($self, %options) = @_; @@ -209,6 +208,8 @@ sub command_execution { return ($exit_code, $stdout); } +sub disconnect {} + # Connection initializer sub connect { my ($self, %options) = @_; @@ -273,7 +274,7 @@ sub fetchrow_array { $self->{stdout} =~ s/^(.*?)\Q$self->{record_separator}\E//ms; @{$self->{columns}} = split(/\Q$self->{field_separator}\E/, $1); } - if (($self->{stdout} =~ s/^(.*?)\Q$self->{record_separator}\E//ms)) { + if (($self->{stdout} =~ s/^(.*?)(\Q$self->{record_separator}\E|\Z)//ms)) { push @array_result, split(/\Q$self->{field_separator}\E/, $1); } @@ -288,7 +289,7 @@ sub fetchrow_hashref { $self->{stdout} =~ s/^(.*?)\Q$self->{record_separator}\E//ms; @{$self->{columns}} = split(/\Q$self->{field_separator}\E/, $1); } - if ($self->{stdout} ne '' && $self->{stdout} =~ s/^(.*?)\Q$self->{record_separator}\E//ms) { + if ($self->{stdout} ne '' && $self->{stdout} =~ s/^(.*?)(\Q$self->{record_separator}\E|\Z)//ms) { $array_result = {}; my @values = split(/\Q$self->{field_separator}\E/, $1); for (my $i = 0; $i < scalar(@values); $i++) { diff --git a/database/sap/hana/mode/blockedtransactions.pm b/database/sap/hana/mode/blockedtransactions.pm index 2078834a3..9078ef59b 100644 --- a/database/sap/hana/mode/blockedtransactions.pm +++ b/database/sap/hana/mode/blockedtransactions.pm @@ -32,7 +32,7 @@ sub set_counters { { name => 'global', type => 0 }, ]; $self->{maps_counters}->{global} = [ - { label => 'blocked-transactions', set => { + { label => 'blocked-transactions', nlabel => 'transactions.blocked.count', set => { key_values => [ { name => 'total' } ], output_template => 'Current Total Blocked Transactions : %s', perfdatas => [ diff --git a/database/sap/hana/mode/connectedusers.pm b/database/sap/hana/mode/connectedusers.pm index 9a4a29427..a5061eb70 100644 --- a/database/sap/hana/mode/connectedusers.pm +++ b/database/sap/hana/mode/connectedusers.pm @@ -32,7 +32,7 @@ sub set_counters { { name => 'host', type => 1, cb_prefix_output => 'prefix_output', message_multiple => 'All connected users are ok' }, ]; $self->{maps_counters}->{host} = [ - { label => 'users', set => { + { label => 'users', nlabel => 'users.count', set => { key_values => [ { name => 'total' }, { name => 'display' } ], output_template => 'Connected Users : %s', perfdatas => [ diff --git a/database/sap/hana/mode/diskusage.pm b/database/sap/hana/mode/diskusage.pm index 62b21f1d7..099211c03 100644 --- a/database/sap/hana/mode/diskusage.pm +++ b/database/sap/hana/mode/diskusage.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -35,7 +33,7 @@ sub set_counters { ]; $self->{maps_counters}->{disk} = [ - { label => 'usage', set => { + { label => 'usage', nlabel => 'disk.usage.bytes', set => { key_values => [ { name => 'used' }, { name => 'total' }, { name => 'display' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_output => $self->can('custom_usage_output'), @@ -49,25 +47,28 @@ sub set_counters { sub custom_usage_perfdata { my ($self, %options) = @_; - my $label = 'used_' . $self->{result_values}->{display}; + my ($label, $nlabel) = ('used', $self->{nlabel}); my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { - $label = 'free_' . $self->{result_values}->{display}; + if (defined($self->{instance_mode}->{option_results}->{free})) { + ($label, $nlabel) = ('free', 'disk.usage.free.bytes'); $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + nlabel => $self->{nlabel}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -75,12 +76,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -117,12 +118,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } @@ -132,13 +133,6 @@ sub prefix_disk_output { return "Disk '" . $options{instance_value}->{display} . "' "; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; $options{sql}->connect(); diff --git a/database/sap/hana/mode/hostcpu.pm b/database/sap/hana/mode/hostcpu.pm index 7d10d925c..420af0800 100644 --- a/database/sap/hana/mode/hostcpu.pm +++ b/database/sap/hana/mode/hostcpu.pm @@ -33,7 +33,7 @@ sub set_counters { { name => 'cpu', type => 1, cb_prefix_output => 'prefix_cpu_output', message_multiple => 'All cpu usages are ok' }, ]; $self->{maps_counters}->{cpu} = [ - { label => 'user', set => { + { label => 'user', nlabel => 'host.cpu.user.utilization.percentage', set => { key_values => [ { name => 'total', diff => 1 }, { name => 'user', diff => 1 }, { name => 'display' } ], closure_custom_calc => $self->can('custom_data_calc'), closure_custom_calc_extra_options => { label_ref => 'user' }, output_template => 'User %.2f %%', output_use => 'user_prct', threshold_use => 'user_prct', @@ -43,7 +43,7 @@ sub set_counters { ], } }, - { label => 'sys', set => { + { label => 'sys', nlabel => 'host.cpu.system.utilization.percentage', set => { key_values => [ { name => 'total', diff => 1 }, { name => 'sys', diff => 1 }, { name => 'display' } ], closure_custom_calc => $self->can('custom_data_calc'), closure_custom_calc_extra_options => { label_ref => 'sys' }, output_template => 'System %.2f %%', output_use => 'sys_prct', threshold_use => 'sys_prct', @@ -53,7 +53,7 @@ sub set_counters { ], } }, - { label => 'wait', set => { + { label => 'wait', nlabel => 'host.cpu.wait.utilization.percentage', set => { key_values => [ { name => 'total', diff => 1 }, { name => 'wait', diff => 1 }, { name => 'display' } ], closure_custom_calc => $self->can('custom_data_calc'), closure_custom_calc_extra_options => { label_ref => 'wait' }, output_template => 'Wait %.2f %%', output_use => 'wait_prct', threshold_use => 'wait_prct', @@ -63,7 +63,7 @@ sub set_counters { ], } }, - { label => 'idle', set => { + { label => 'idle', nlabel => 'host.cpu.idle.utilization.percentage', set => { key_values => [ { name => 'total', diff => 1 }, { name => 'idle', diff => 1 }, { name => 'display' } ], closure_custom_calc => $self->can('custom_data_calc'), closure_custom_calc_extra_options => { label_ref => 'idle' }, output_template => 'Idle %.2f %%', output_use => 'idle_prct', threshold_use => 'idle_prct', @@ -102,9 +102,7 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => {}); return $self; } diff --git a/database/sap/hana/mode/hostmemory.pm b/database/sap/hana/mode/hostmemory.pm index dc878b53b..d79ce2aff 100644 --- a/database/sap/hana/mode/hostmemory.pm +++ b/database/sap/hana/mode/hostmemory.pm @@ -27,21 +27,22 @@ use warnings; sub custom_usage_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - $self->{output}->perfdata_add(label => $self->{result_values}->{label} . '_used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + nlabel => $self->{nlabel}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{result_values}->{label} . '-usage', exit_litteral => 'critical' }, { label => 'warning-' . $self->{result_values}->{label} . '-usage', exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -80,7 +81,7 @@ sub set_counters { ]; $self->{maps_counters}->{memory} = [ - { label => 'physical-usage', set => { + { label => 'physical-usage', nlabel => 'host.memory.usage.bytes', set => { key_values => [ { name => 'free' }, { name => 'used' }, { name => 'display' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_calc_extra_options => { label_ref => 'physical' }, closure_custom_output => $self->can('custom_usage_output'), @@ -90,7 +91,7 @@ sub set_counters { }, ]; $self->{maps_counters}->{swap} = [ - { label => 'swap-usage', set => { + { label => 'swap-usage', nlabel => 'host.swap.usage.bytes', set => { key_values => [ { name => 'free' }, { name => 'used' }, { name => 'display' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_calc_extra_options => { label_ref => 'swap' }, closure_custom_output => $self->can('custom_usage_output'), diff --git a/database/sap/hana/mode/volumeusage.pm b/database/sap/hana/mode/volumeusage.pm index 8e9e2f1ce..c463cb05d 100644 --- a/database/sap/hana/mode/volumeusage.pm +++ b/database/sap/hana/mode/volumeusage.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -35,7 +33,7 @@ sub set_counters { ]; $self->{maps_counters}->{volume} = [ - { label => 'usage', set => { + { label => 'usage', nlabel => 'volume.usage.bytes', set => { key_values => [ { name => 'used' }, { name => 'total' }, { name => 'display' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_output => $self->can('custom_usage_output'), @@ -49,25 +47,28 @@ sub set_counters { sub custom_usage_perfdata { my ($self, %options) = @_; - my $label = 'used_' . $self->{result_values}->{display}; + my ($label, $nlabel) = ('used', $self->{nlabel}); my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { - $label = 'free_' . $self->{result_values}->{display}; + if (defined($self->{instance_mode}->{option_results}->{free})) { + ($label, $nlabel) = ('free', 'volume.free.usage.bytes'); $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + nlabel => $self->{nlabel}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -75,12 +76,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -117,12 +118,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } @@ -132,13 +133,6 @@ sub prefix_volume_output { return "Volume '" . $options{instance_value}->{display} . "' "; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; $options{sql}->connect(); diff --git a/database/sybase/mode/databasessize.pm b/database/sybase/mode/databasessize.pm index fa2bfb43d..83baa96d7 100644 --- a/database/sybase/mode/databasessize.pm +++ b/database/sybase/mode/databasessize.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -59,23 +57,25 @@ sub custom_usage_perfdata { my $label = $self->{result_values}->{label} . '_used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = $self->{result_values}->{label} . '_free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -83,12 +83,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -127,12 +127,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-database:s" => { name => 'filter_database' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "filter-database:s" => { name => 'filter_database' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } @@ -142,13 +142,6 @@ sub prefix_database_output { return "Database '" . $options{instance_value}->{display} . "' "; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/docs/en/developer/guide.rst b/docs/en/developer/guide.rst index 2037e55af..9eec3f5e8 100644 --- a/docs/en/developer/guide.rst +++ b/docs/en/developer/guide.rst @@ -1255,7 +1255,7 @@ We suppose these options are defined : .. code-block:: perl - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(output => $self->{output}, options => $self->{options}); $self->{http}->set_options(%{$self->{option_results}}); my $webcontent = $self->{http}->request(); print $webcontent; @@ -2139,8 +2139,6 @@ The model can also be used to check strings (not only counters). So we want to c use strict; use warnings; - my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -2194,8 +2192,6 @@ The model can also be used to check strings (not only counters). So we want to c my ($self, %options) = @_; $self->SUPER::check_options(%options); - # Sometimes, you'll need to have access of the current object in the callback - $instance_mode = $self; } sub manage_selection { diff --git a/docs/en/user/guide.rst b/docs/en/user/guide.rst index d1d7b8376..8b4c70cd9 100644 --- a/docs/en/user/guide.rst +++ b/docs/en/user/guide.rst @@ -609,8 +609,23 @@ We exclude the module ``IO::Socket::INET6`` (Perl 5.14 has the full set of IPv6 --link=%PERL_INSTALL_DIR%\c\bin\libiconv-2__.dll ^ --link=%PERL_INSTALL_DIR%\c\bin\liblzma-5__.dll ^ --link=%PERL_INSTALL_DIR%\c\bin\zlib1__.dll ^ + --link=%PERL_INSTALL_DIR%\c\bin\libcrypto-1_1-x64__.dll ^ + --link=%PERL_INSTALL_DIR%\c\bin\libssl-1_1-x64__.dll ^ + -M IO::Socket::SSL ^ -M Win32::Job ^ + -M Email::Send::SMTP::Gmail ^ + -M HTTP::ProxyPAC ^ + -M JE ^ + -M Tie::RefHash::Weak ^ + -M XML::LibXML::SAX ^ + -M Net::FTPSSL ^ + -M Authen::NTLM ^ + -M JSON::XS ^ -M centreon::plugins::script ^ + -M centreon::plugins::backend::http::lwp ^ + -M centreon::plugins::backend::http::curl ^ + -M centreon::plugins::backend::http::useragent ^ + -M centreon::plugins::backend::http::curlconstants ^ -M centreon::plugins::alternative::Getopt ^ -M apps::backup::netbackup::local::plugin ^ -M apps::backup::netbackup::local::mode::dedupstatus ^ @@ -619,8 +634,12 @@ We exclude the module ``IO::Socket::INET6`` (Perl 5.14 has the full set of IPv6 -M apps::backup::netbackup::local::mode::jobstatus ^ -M apps::backup::netbackup::local::mode::listpolicies ^ -M apps::backup::netbackup::local::mode::tapeusage ^ + -M apps::backup::veeam::local::plugin ^ + -M apps::backup::veeam::local::mode::jobstatus ^ + -M apps::backup::veeam::local::mode::listjobs ^ -M apps::activedirectory::local::plugin ^ -M apps::activedirectory::local::mode::dcdiag ^ + -M apps::activedirectory::local::mode::dfsrbacklog ^ -M apps::activedirectory::local::mode::netdom ^ -M apps::citrix::local::plugin ^ -M apps::citrix::local::mode::license ^ @@ -652,11 +671,65 @@ We exclude the module ``IO::Socket::INET6`` (Perl 5.14 has the full set of IPv6 -M apps::cluster::mscs::local::mode::resourcestatus ^ -M apps::cluster::mscs::local::mode::resourcegroupstatus ^ -M os::windows::local::plugin ^ + -M os::windows::local::mode::cmdreturn ^ -M os::windows::local::mode::ntp ^ - -M os::windows::local::mode::rdpsessions ^ + -M os::windows::local::mode::pendingreboot ^ + -M os::windows::local::mode::sessions ^ + -M os::windows::local::mode::liststorages ^ + -M centreon::common::powershell::windows::liststorages ^ -M storage::dell::compellent::local::plugin ^ -M storage::dell::compellent::local::mode::hbausage ^ -M storage::dell::compellent::local::mode::volumeusage ^ + -M hardware::devices::safenet::hsm::protecttoolkit::plugin ^ + -M hardware::devices::safenet::hsm::protecttoolkit::mode::hardware ^ + -M hardware::devices::safenet::hsm::protecttoolkit::mode::components::temperature ^ + -M hardware::devices::safenet::hsm::protecttoolkit::mode::components::hwstatus ^ + -M hardware::devices::safenet::hsm::protecttoolkit::mode::components::memory ^ + -M apps::centreon::local::plugin ^ + -M apps::centreon::local::mode::downtimetrap ^ + -M apps::centreon::local::mode::centreonpluginsversion ^ + -M apps::hyperv::2012::local::plugin ^ + -M apps::hyperv::2012::local::mode::listnodevms ^ + -M apps::hyperv::2012::local::mode::scvmmintegrationservice ^ + -M apps::hyperv::2012::local::mode::scvmmsnapshot ^ + -M apps::hyperv::2012::local::mode::scvmmvmstatus ^ + -M apps::hyperv::2012::local::mode::nodeintegrationservice ^ + -M apps::hyperv::2012::local::mode::nodereplication ^ + -M apps::hyperv::2012::local::mode::nodesnapshot ^ + -M apps::hyperv::2012::local::mode::nodevmstatus ^ + -M centreon::common::powershell::hyperv::2012::listnodevms ^ + -M centreon::common::powershell::hyperv::2012::nodeintegrationservice ^ + -M centreon::common::powershell::hyperv::2012::nodereplication ^ + -M centreon::common::powershell::hyperv::2012::nodesnapshot ^ + -M centreon::common::powershell::hyperv::2012::nodevmstatus ^ + -M centreon::common::powershell::hyperv::2012::scvmmintegrationservice ^ + -M centreon::common::powershell::hyperv::2012::scvmmsnapshot ^ + -M centreon::common::powershell::hyperv::2012::scvmmvmstatus ^ + -M apps::protocols::http::plugin ^ + -M apps::protocols::http::mode::expectedcontent ^ + -M apps::protocols::http::mode::response ^ + -M apps::protocols::tcp::plugin ^ + -M apps::protocols::tcp::mode::responsetime ^ + -M apps::protocols::ftp::plugin ^ + -M apps::protocols::ftp::mode::commands ^ + -M apps::protocols::ftp::mode::date ^ + -M apps::protocols::ftp::mode::filescount ^ + -M apps::protocols::ftp::mode::login ^ + -M apps::backup::veeam::local::plugin ^ + -M apps::backup::veeam::local::mode::jobstatus ^ + -M apps::backup::veeam::local::mode::listjobs ^ + -M centreon::common::powershell::veeam::jobstatus ^ + -M centreon::common::powershell::veeam::listjobs ^ + -M centreon::common::powershell::wsus::computersstatus ^ + -M centreon::common::powershell::wsus::updatesstatus ^ + -M centreon::common::powershell::wsus::synchronisationstatus ^ + -M centreon::common::powershell::wsus::serverstatistics ^ + -M apps::wsus::local::plugin ^ + -M apps::wsus::local::mode::computersstatus ^ + -M apps::wsus::local::mode::updatesstatus ^ + -M apps::wsus::local::mode::synchronisationstatus ^ + -M apps::wsus::local::mode::serverstatistics ^ + -M centreon::common::powershell::functions ^ --verbose pause @@ -673,7 +746,7 @@ If you want to change the executable version and ico file, add following code af chdir /d %~dp0 for /f "tokens=4 delims= " %%i in ('type centreon-plugins\centreon\plugins\script.pm ^| findstr global_version ^| findstr my') do set "VERSION_PLUGIN=%%i" - set VERSION_PLUGIN=%VERSION_PLUGIN:~0,8% + set VERSION_PLUGIN=%VERSION_PLUGIN:~1,8% ( echo #define PP_MANIFEST_FILEFLAGS 0 diff --git a/docs/fr/developer/guide.rst b/docs/fr/developer/guide.rst index 98c98d6cf..1ad51596b 100644 --- a/docs/fr/developer/guide.rst +++ b/docs/fr/developer/guide.rst @@ -1243,7 +1243,7 @@ Nous supposons que ces options sont définies : .. code-block:: perl - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(output => $self->{output}, options => $self->{options}); $self->{http}->set_options(%{$self->{option_results}}); my $webcontent = $self->{http}->request(); print $webcontent; diff --git a/docs/fr/user/guide.rst b/docs/fr/user/guide.rst index da0251baa..af37347a5 100644 --- a/docs/fr/user/guide.rst +++ b/docs/fr/user/guide.rst @@ -609,8 +609,23 @@ Nous excluons le module ``IO::Socket::INET6`` (Perl 5.14 intègre la fonctionnal --link=%PERL_INSTALL_DIR%\c\bin\libiconv-2__.dll ^ --link=%PERL_INSTALL_DIR%\c\bin\liblzma-5__.dll ^ --link=%PERL_INSTALL_DIR%\c\bin\zlib1__.dll ^ + --link=%PERL_INSTALL_DIR%\c\bin\libcrypto-1_1-x64__.dll ^ + --link=%PERL_INSTALL_DIR%\c\bin\libssl-1_1-x64__.dll ^ + -M IO::Socket::SSL ^ -M Win32::Job ^ + -M Email::Send::SMTP::Gmail ^ + -M HTTP::ProxyPAC ^ + -M JE ^ + -M Tie::RefHash::Weak ^ + -M XML::LibXML::SAX ^ + -M Net::FTPSSL ^ + -M Authen::NTLM ^ + -M JSON::XS ^ -M centreon::plugins::script ^ + -M centreon::plugins::backend::http::lwp ^ + -M centreon::plugins::backend::http::curl ^ + -M centreon::plugins::backend::http::useragent ^ + -M centreon::plugins::backend::http::curlconstants ^ -M centreon::plugins::alternative::Getopt ^ -M apps::backup::netbackup::local::plugin ^ -M apps::backup::netbackup::local::mode::dedupstatus ^ @@ -619,8 +634,12 @@ Nous excluons le module ``IO::Socket::INET6`` (Perl 5.14 intègre la fonctionnal -M apps::backup::netbackup::local::mode::jobstatus ^ -M apps::backup::netbackup::local::mode::listpolicies ^ -M apps::backup::netbackup::local::mode::tapeusage ^ + -M apps::backup::veeam::local::plugin ^ + -M apps::backup::veeam::local::mode::jobstatus ^ + -M apps::backup::veeam::local::mode::listjobs ^ -M apps::activedirectory::local::plugin ^ -M apps::activedirectory::local::mode::dcdiag ^ + -M apps::activedirectory::local::mode::dfsrbacklog ^ -M apps::activedirectory::local::mode::netdom ^ -M apps::citrix::local::plugin ^ -M apps::citrix::local::mode::license ^ @@ -652,11 +671,65 @@ Nous excluons le module ``IO::Socket::INET6`` (Perl 5.14 intègre la fonctionnal -M apps::cluster::mscs::local::mode::resourcestatus ^ -M apps::cluster::mscs::local::mode::resourcegroupstatus ^ -M os::windows::local::plugin ^ + -M os::windows::local::mode::cmdreturn ^ -M os::windows::local::mode::ntp ^ - -M os::windows::local::mode::rdpsessions ^ + -M os::windows::local::mode::pendingreboot ^ + -M os::windows::local::mode::sessions ^ + -M os::windows::local::mode::liststorages ^ + -M centreon::common::powershell::windows::liststorages ^ -M storage::dell::compellent::local::plugin ^ -M storage::dell::compellent::local::mode::hbausage ^ -M storage::dell::compellent::local::mode::volumeusage ^ + -M hardware::devices::safenet::hsm::protecttoolkit::plugin ^ + -M hardware::devices::safenet::hsm::protecttoolkit::mode::hardware ^ + -M hardware::devices::safenet::hsm::protecttoolkit::mode::components::temperature ^ + -M hardware::devices::safenet::hsm::protecttoolkit::mode::components::hwstatus ^ + -M hardware::devices::safenet::hsm::protecttoolkit::mode::components::memory ^ + -M apps::centreon::local::plugin ^ + -M apps::centreon::local::mode::downtimetrap ^ + -M apps::centreon::local::mode::centreonpluginsversion ^ + -M apps::hyperv::2012::local::plugin ^ + -M apps::hyperv::2012::local::mode::listnodevms ^ + -M apps::hyperv::2012::local::mode::scvmmintegrationservice ^ + -M apps::hyperv::2012::local::mode::scvmmsnapshot ^ + -M apps::hyperv::2012::local::mode::scvmmvmstatus ^ + -M apps::hyperv::2012::local::mode::nodeintegrationservice ^ + -M apps::hyperv::2012::local::mode::nodereplication ^ + -M apps::hyperv::2012::local::mode::nodesnapshot ^ + -M apps::hyperv::2012::local::mode::nodevmstatus ^ + -M centreon::common::powershell::hyperv::2012::listnodevms ^ + -M centreon::common::powershell::hyperv::2012::nodeintegrationservice ^ + -M centreon::common::powershell::hyperv::2012::nodereplication ^ + -M centreon::common::powershell::hyperv::2012::nodesnapshot ^ + -M centreon::common::powershell::hyperv::2012::nodevmstatus ^ + -M centreon::common::powershell::hyperv::2012::scvmmintegrationservice ^ + -M centreon::common::powershell::hyperv::2012::scvmmsnapshot ^ + -M centreon::common::powershell::hyperv::2012::scvmmvmstatus ^ + -M apps::protocols::http::plugin ^ + -M apps::protocols::http::mode::expectedcontent ^ + -M apps::protocols::http::mode::response ^ + -M apps::protocols::tcp::plugin ^ + -M apps::protocols::tcp::mode::responsetime ^ + -M apps::protocols::ftp::plugin ^ + -M apps::protocols::ftp::mode::commands ^ + -M apps::protocols::ftp::mode::date ^ + -M apps::protocols::ftp::mode::filescount ^ + -M apps::protocols::ftp::mode::login ^ + -M apps::backup::veeam::local::plugin ^ + -M apps::backup::veeam::local::mode::jobstatus ^ + -M apps::backup::veeam::local::mode::listjobs ^ + -M centreon::common::powershell::veeam::jobstatus ^ + -M centreon::common::powershell::veeam::listjobs ^ + -M centreon::common::powershell::wsus::computersstatus ^ + -M centreon::common::powershell::wsus::updatesstatus ^ + -M centreon::common::powershell::wsus::synchronisationstatus ^ + -M centreon::common::powershell::wsus::serverstatistics ^ + -M apps::wsus::local::plugin ^ + -M apps::wsus::local::mode::computersstatus ^ + -M apps::wsus::local::mode::updatesstatus ^ + -M apps::wsus::local::mode::synchronisationstatus ^ + -M apps::wsus::local::mode::serverstatistics ^ + -M centreon::common::powershell::functions ^ --verbose pause @@ -672,7 +745,7 @@ Pour changer la version et l'icône du binaire, ajouter le code suivant après ` chdir /d %~dp0 for /f "tokens=4 delims= " %%i in ('type centreon-plugins\centreon\plugins\script.pm ^| findstr global_version ^| findstr my') do set "VERSION_PLUGIN=%%i" - set VERSION_PLUGIN=%VERSION_PLUGIN:~0,8% + set VERSION_PLUGIN=%VERSION_PLUGIN:~1,8% ( echo #define PP_MANIFEST_FILEFLAGS 0 diff --git a/hardware/ats/eaton/snmp/mode/inputlines.pm b/hardware/ats/eaton/snmp/mode/inputlines.pm new file mode 100644 index 000000000..61bc33582 --- /dev/null +++ b/hardware/ats/eaton/snmp/mode/inputlines.pm @@ -0,0 +1,168 @@ +# +# Copyright 2019 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 hardware::ats::eaton::snmp::mode::inputlines; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'line', type => 1, cb_prefix_output => 'prefix_line_output', message_multiple => 'All input lines are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{line} = [ + { label => 'voltage', nlabel => 'line.input.voltage.volt', set => { + key_values => [ { name => 'voltage' }, { name => 'display' } ], + output_template => 'Voltage : %.2f V', + perfdatas => [ + { value => 'voltage_absolute', template => '%s', + unit => 'V', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'frequence', nlabel => 'line.input.frequence.hertz', set => { + key_values => [ { name => 'frequency', no_value => -1 } ], + output_template => 'Frequence : %.2f Hz', + perfdatas => [ + { value => 'frequency_absolute', template => '%.2f', + unit => 'Hz', label_extra_instance => 1 }, + ], + } + }, + ]; +} + +sub prefix_line_output { + my ($self, %options) = @_; + + return "Input Line '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +my $map_input_name = { + 1 => 'source-1', + 2 => 'source-2', +}; + +sub check_ats { + my ($self, %options) = @_; + + return if (scalar(keys %{$self->{line}}) > 0); + + my $mapping = { + atsInputIndex => { oid => '.1.3.6.1.4.1.534.10.1.3.1.1.1', map => $map_input_name }, + atsInputVoltage => { oid => '.1.3.6.1.4.1.534.10.1.3.1.1.2' }, + atsInputFrequency => { oid => '.1.3.6.1.4.1.534.10.1.3.1.1.3' }, + }; + + my $oid_atsInputEntry = '.1.3.6.1.4.1.534.10.1.3.1.1'; + my $snmp_result = $options{snmp}->get_table(oid => $oid_atsInputEntry, nothing_quit => 1); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{atsInputIndex}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $self->{line}->{$result->{atsInputIndex}} = { + display => $result->{atsInputIndex}, + voltage => $result->{atsInputVoltage} * 0.1, + frequency => $result->{atsInputFrequency} * 0.1, + }; + } +} + +sub check_ats2 { + my ($self, %options) = @_; + + my $mapping = { + ats2InputIndex => { oid => '.1.3.6.1.4.1.534.10.2.2.2.1.1', map => $map_input_name }, + ats2InputVoltage => { oid => '.1.3.6.1.4.1.534.10.2.2.2.1.2' }, + ats2InputFrequency => { oid => '.1.3.6.1.4.1.534.10.2.2.2.1.3' }, + }; + + my $oid_ats2InputEntry = '.1.3.6.1.4.1.534.10.2.2.2.1'; + my $snmp_result = $options{snmp}->get_table(oid => $oid_ats2InputEntry); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{ats2InputIndex}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $self->{line}->{$result->{ats2InputIndex}} = { + display => $result->{ats2InputIndex}, + voltage => $result->{ats2InputVoltage} * 0.1, + frequency => $result->{ats2InputFrequency} * 0.1, + }; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{line} = {}; + + $self->check_ats2(%options); + $self->check_ats(%options); + + if (scalar(keys %{$self->{line}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No line found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check input lines. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^voltage$' + +=item B<--warning-*> B<--critical-*> + +Threshold warning. +Can be: 'voltage', 'frequence'. + +=back + +=cut diff --git a/hardware/ats/eaton/snmp/mode/outputline.pm b/hardware/ats/eaton/snmp/mode/outputline.pm new file mode 100644 index 000000000..571b84f4c --- /dev/null +++ b/hardware/ats/eaton/snmp/mode/outputline.pm @@ -0,0 +1,135 @@ +# +# Copyright 2019 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 hardware::ats::eaton::snmp::mode::outputline; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'oline', type => 0, cb_prefix_output => 'prefix_line_output', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{oline} = [ + { label => 'voltage', nlabel => 'line.output.voltage.volt', set => { + key_values => [ { name => 'voltage' } ], + output_template => 'Voltage : %.2f V', + perfdatas => [ + { value => 'voltage_absolute', template => '%s', + unit => 'V' }, + ], + } + }, + { label => 'current', nlabel => 'line.current.ampere', set => { + key_values => [ { name => 'current' } ], + output_template => 'current : %s A', + perfdatas => [ + { template => '%s', value => 'current_absolute', + unit => 'A', min => 0 }, + ], + } + }, + ]; +} + +sub prefix_line_output { + my ($self, %options) = @_; + + return "Output line "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +my $oid_atsOutputVoltage = '.1.3.6.1.4.1.534.10.1.3.2.1.0'; +my $oid_atsOutputCurrent = '.1.3.6.1.4.1.534.10.1.3.2.2.0'; +my $oid_ats2OutputVoltage = '.1.3.6.1.4.1.534.10.2.2.3.1.0'; +my $oid_ats2OutputCurrent = '.1.3.6.1.4.1.534.10.2.2.3.2.0'; + +sub check_ats2 { + my ($self, %options) = @_; + + return if (!defined($options{result}->{$oid_ats2OutputVoltage})); + + $self->{oline} = { + voltage => $options{result}->{$oid_ats2OutputVoltage} * 0.1, + current => $options{result}->{$oid_ats2OutputCurrent} * 0.1 + }; +} + +sub check_ats { + my ($self, %options) = @_; + + return if (defined($self->{oline})); + + $self->{oline} = { + voltage => $options{result}->{$oid_atsOutputVoltage} * 0.1, + current => $options{result}->{$oid_atsOutputCurrent} * 0.1 + }; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_leef(oids => [ + $oid_atsOutputVoltage, $oid_atsOutputCurrent, + $oid_ats2OutputVoltage, $oid_ats2OutputCurrent, + ], nothing_quit => 1); + $self->check_ats2(result => $snmp_result); + $self->check_ats(result => $snmp_result); +} + +1; + +__END__ + +=head1 MODE + +Check output line. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^voltage$' + +=item B<--warning-*> B<--critical-*> + +Threshold warning. +Can be: 'voltage', 'current'. + +=back + +=cut diff --git a/hardware/ats/eaton/snmp/mode/system.pm b/hardware/ats/eaton/snmp/mode/system.pm new file mode 100644 index 000000000..f9c132903 --- /dev/null +++ b/hardware/ats/eaton/snmp/mode/system.pm @@ -0,0 +1,193 @@ +# +# Copyright 2019 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 hardware::ats::eaton::snmp::mode::system; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'operation mode : ' . $self->{result_values}->{operation_mode}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{operation_mode} = $options{new_datas}->{$self->{instance} . '_operation_mode'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, message_separator => ' - ', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'operation_mode' } ], + 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 => \&catalog_status_threshold, + } + }, + { label => 'temperature', nlabel => 'system.temperature.celsius', set => { + key_values => [ { name => 'temperature' } ], + output_template => 'temperature : %s C', + perfdatas => [ + { label => 'temperature', value => 'temperature_absolute', template => '%s', + unit => 'C' }, + ], + } + }, + { label => 'humidity', nlabel => 'system.humidity.percentage', set => { + key_values => [ { name => 'humidity' } ], + output_template => 'humidity : %s %%', + perfdatas => [ + { label => 'humidity', value => 'humidity_absolute', template => '%s', + unit => '%', min => 9, max => 100 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{operation_mode} !~ /source1|source2/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status', 'unknown_status']); +} + +my $map_opmode = { + 1 => 'initialization', + 2 => 'diagnosis', + 3 => 'off', + 4 => 'source1', + 5 => 'source2', + 6 => 'safe', + 7 => 'fault', +}; +my $oid_ats2OperationMode = '.1.3.6.1.4.1.534.10.2.2.4.0'; +my $oid_ats2EnvRemoteTemp = '.1.3.6.1.4.1.534.10.2.5.1.0'; +my $oid_ats2EnvRemoteHumidity = '.1.3.6.1.4.1.534.10.2.5.2.0'; +my $oid_atsMeasureTemperatureC = '.1.3.6.1.4.1.534.10.1.3.3.0'; +my $oid_atsMessureOperationMode = '.1.3.6.1.4.1.534.10.1.3.7.0'; + +sub check_ats2 { + my ($self, %options) = @_; + + return if (!defined($options{result}->{$oid_ats2OperationMode})); + + $self->{global} = { + operation_mode => $map_opmode->{$options{result}->{$oid_ats2OperationMode}}, + temperature => $options{result}->{$oid_ats2EnvRemoteTemp}, + humidity => $options{result}->{$oid_ats2EnvRemoteHumidity} + }; +} + +sub check_ats { + my ($self, %options) = @_; + + return if (defined($self->{global})); + + $self->{global} = { + operation_mode => $map_opmode->{$options{result}->{$oid_atsMessureOperationMode}}, + temperature => $options{result}->{$oid_atsMeasureTemperatureC}, + }; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_leef(oids => [ + $oid_ats2OperationMode, $oid_ats2EnvRemoteTemp, $oid_ats2EnvRemoteHumidity, + $oid_atsMeasureTemperatureC, $oid_atsMessureOperationMode, + ], nothing_quit => 1); + $self->check_ats2(result => $snmp_result); + $self->check_ats(result => $snmp_result); +} + +1; + +__END__ + +=head1 MODE + +Check system (operation mode, temperature). + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^status$' + +=item B<--unknown-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: operation_mode + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: operation_mode + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{operation_mode} !~ /source1|source2/i'). +Can used special variables like: %{operation_mode} + +=item B<--warning-*> + +Threshold warning. +Can be: 'temperature', 'humidity'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'temperature', 'humidity'. + +=back + +=cut diff --git a/hardware/ats/eaton/snmp/plugin.pm b/hardware/ats/eaton/snmp/plugin.pm new file mode 100644 index 000000000..fe6b812aa --- /dev/null +++ b/hardware/ats/eaton/snmp/plugin.pm @@ -0,0 +1,50 @@ +# +# Copyright 2019 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 hardware::ats::eaton::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} = '0.1'; + %{$self->{modes}} = ( + 'input-lines' => 'hardware::ats::eaton::snmp::mode::inputlines', + 'system' => 'hardware::ats::eaton::snmp::mode::system', + 'output-line' => 'hardware::ats::eaton::snmp::mode::outputline', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Eaton ATS in SNMP. + +=cut diff --git a/hardware/devices/aeg/acm/snmp/mode/acstatus.pm b/hardware/devices/aeg/acm/snmp/mode/acstatus.pm index c066b7129..bc76fd530 100644 --- a/hardware/devices/aeg/acm/snmp/mode/acstatus.pm +++ b/hardware/devices/aeg/acm/snmp/mode/acstatus.pm @@ -65,11 +65,10 @@ sub new { 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} =~ /true/i' }, - }); + $options{options}->add_options(arguments => { + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /true/i' }, + }); return $self; } @@ -99,11 +98,14 @@ sub manage_selection { my ($self, %options) = @_; $self->{global} = {}; - $self->{results} = $options{snmp}->get_multiple_table(oids => [ { oid => $oid_acm1000AcPlant }, - { oid => $oid_acmi1000AcPlant }, - ], - nothing_quit => 1); - + $self->{results} = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oid_acm1000AcPlant }, + { oid => $oid_acmi1000AcPlant }, + ], + nothing_quit => 1 + ); + my $result_acm1000 = $options{snmp}->map_instance(mapping => $mapping_acm1000, results => $self->{results}->{$oid_acm1000AcPlant}, instance => '0'); my $result_acmi1000 = $options{snmp}->map_instance(mapping => $mapping_acmi1000, results => $self->{results}->{$oid_acmi1000AcPlant}, instance => '0'); diff --git a/hardware/devices/aeg/acm/snmp/mode/alarmsstatus.pm b/hardware/devices/aeg/acm/snmp/mode/alarmsstatus.pm index 8cae7f0db..58ef680f7 100644 --- a/hardware/devices/aeg/acm/snmp/mode/alarmsstatus.pm +++ b/hardware/devices/aeg/acm/snmp/mode/alarmsstatus.pm @@ -62,9 +62,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } @@ -102,4 +101,4 @@ Example: --threshold-overload='multiple,2,OK,true' =back -=cut \ No newline at end of file +=cut diff --git a/hardware/devices/aeg/acm/snmp/mode/batterystatus.pm b/hardware/devices/aeg/acm/snmp/mode/batterystatus.pm index 1af7197cf..6b9556ae5 100644 --- a/hardware/devices/aeg/acm/snmp/mode/batterystatus.pm +++ b/hardware/devices/aeg/acm/snmp/mode/batterystatus.pm @@ -137,11 +137,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /onBattery/i' }, - "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /disconnected/i || %{status} =~ /shutdown/i' }, - }); + $options{options}->add_options(arguments => { + "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /onBattery/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /disconnected/i || %{status} =~ /shutdown/i' }, + }); return $self; } diff --git a/hardware/devices/aeg/acm/snmp/mode/rectifierstatus.pm b/hardware/devices/aeg/acm/snmp/mode/rectifierstatus.pm index 55f3b243d..c3345a48f 100644 --- a/hardware/devices/aeg/acm/snmp/mode/rectifierstatus.pm +++ b/hardware/devices/aeg/acm/snmp/mode/rectifierstatus.pm @@ -102,11 +102,10 @@ sub new { 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} !~ /ok|notInstalled/i' }, - }); + $options{options}->add_options(arguments => { + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /ok|notInstalled/i' }, + }); return $self; } diff --git a/hardware/devices/aeg/acm/snmp/plugin.pm b/hardware/devices/aeg/acm/snmp/plugin.pm index 8d586054b..2c21dfe0b 100644 --- a/hardware/devices/aeg/acm/snmp/plugin.pm +++ b/hardware/devices/aeg/acm/snmp/plugin.pm @@ -31,12 +31,12 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'ac-status' => 'hardware::devices::aeg::acm::snmp::mode::acstatus', - 'alarms-status' => 'hardware::devices::aeg::acm::snmp::mode::alarmsstatus', - 'battery-status' => 'hardware::devices::aeg::acm::snmp::mode::batterystatus', - 'load-status' => 'hardware::devices::aeg::acm::snmp::mode::loadstatus', - 'rectifier-status' => 'hardware::devices::aeg::acm::snmp::mode::rectifierstatus', - ); + 'ac-status' => 'hardware::devices::aeg::acm::snmp::mode::acstatus', + 'alarms-status' => 'hardware::devices::aeg::acm::snmp::mode::alarmsstatus', + 'battery-status' => 'hardware::devices::aeg::acm::snmp::mode::batterystatus', + 'load-status' => 'hardware::devices::aeg::acm::snmp::mode::loadstatus', + 'rectifier-status' => 'hardware::devices::aeg::acm::snmp::mode::rectifierstatus', + ); return $self; } diff --git a/hardware/devices/safenet/hsm/protecttoolkit/mode/components/memory.pm b/hardware/devices/safenet/hsm/protecttoolkit/mode/components/memory.pm index 77489d66d..66698394b 100644 --- a/hardware/devices/safenet/hsm/protecttoolkit/mode/components/memory.pm +++ b/hardware/devices/safenet/hsm/protecttoolkit/mode/components/memory.pm @@ -50,10 +50,13 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => $message); } - $self->{output}->perfdata_add(label => "used_memory", unit => 'B', - value => $used, - warning => $warn, - critical => $crit, min => 0, total => $total); + $self->{output}->perfdata_add( + label => "used_memory", unit => 'B', + nlabel => 'hardware.memory.usage.bytes', + value => $used, + warning => $warn, + critical => $crit, min => 0, total => $total + ); } -1; \ No newline at end of file +1; diff --git a/hardware/devices/safenet/hsm/protecttoolkit/mode/components/temperature.pm b/hardware/devices/safenet/hsm/protecttoolkit/mode/components/temperature.pm index 1acbacf75..81705f7b4 100644 --- a/hardware/devices/safenet/hsm/protecttoolkit/mode/components/temperature.pm +++ b/hardware/devices/safenet/hsm/protecttoolkit/mode/components/temperature.pm @@ -41,10 +41,13 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature is %s C", $temperature)); } - $self->{output}->perfdata_add(label => "temp", unit => 'C', - value => $temperature, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "temp", unit => 'C', + nlabel => 'hardware.temperature.celsius', + value => $temperature, + warning => $warn, + critical => $crit + ); } -1; \ No newline at end of file +1; diff --git a/hardware/devices/video/axis/snmp/mode/components/temperature.pm b/hardware/devices/video/axis/snmp/mode/components/temperature.pm index fc58bca4b..f6a0bca4e 100644 --- a/hardware/devices/video/axis/snmp/mode/components/temperature.pm +++ b/hardware/devices/video/axis/snmp/mode/components/temperature.pm @@ -75,10 +75,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s degree centigrade", $instance, $result->{axisTemperatureCelsius})); } - $self->{output}->perfdata_add(label => "temperature_" . $instance, unit => 'C', - value => $result->{axisTemperatureCelsius}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "temperature", unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $instance, + value => $result->{axisTemperatureCelsius}, + warning => $warn, + critical => $crit + ); } } } diff --git a/hardware/pdu/apc/snmp/mode/components/humidity.pm b/hardware/pdu/apc/snmp/mode/components/humidity.pm index 893665e6c..ea1ee4fb5 100644 --- a/hardware/pdu/apc/snmp/mode/components/humidity.pm +++ b/hardware/pdu/apc/snmp/mode/components/humidity.pm @@ -92,13 +92,17 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Humidity '%s' value is %s %%", $result->{rPDU2SensorTempHumidityStatusName}, $value)); } - $self->{output}->perfdata_add(label => 'hum_' . $result->{rPDU2SensorTempHumidityStatusName}, unit => '%', - value => $value, - warning => $warn, - critical => $crit, - min => 0, max => 100); + $self->{output}->perfdata_add( + label => 'hum', unit => '%', + nlabel => 'hardware.sensor.humidity.percentage', + instances => $result->{rPDU2SensorTempHumidityStatusName}, + value => $value, + warning => $warn, + critical => $crit, + min => 0, max => 100 + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/pdu/apc/snmp/mode/components/temperature.pm b/hardware/pdu/apc/snmp/mode/components/temperature.pm index 4594c827c..91256a26c 100644 --- a/hardware/pdu/apc/snmp/mode/components/temperature.pm +++ b/hardware/pdu/apc/snmp/mode/components/temperature.pm @@ -92,12 +92,16 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Temperature '%s' value is %s C", $result->{rPDU2SensorTempHumidityStatusName}, $value)); } - $self->{output}->perfdata_add(label => 'temp_' . $result->{rPDU2SensorTempHumidityStatusName}, unit => 'C', - value => $value, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.sensor.temperature.celsius', + instances => $result->{rPDU2SensorTempHumidityStatusName}, + value => $value, + warning => $warn, + critical => $crit + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/pdu/apc/snmp/mode/load.pm b/hardware/pdu/apc/snmp/mode/load.pm index 891d8ab4c..1867d7141 100644 --- a/hardware/pdu/apc/snmp/mode/load.pm +++ b/hardware/pdu/apc/snmp/mode/load.pm @@ -20,225 +20,280 @@ package hardware::pdu::apc::snmp::mode::load; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::misc; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); -my $thresholds = { - load => [ - ['phaseLoadNormal', 'OK'], - ['phaseLoadLow', 'WARNING'], - ['phaseLoadNearOverload', 'WARNING'], - ['phaseLoadOverload', 'CRITICAL'], - ], -}; -my %map_status = ( - 1 => 'phaseLoadNormal', - 2 => 'phaseLoadLow', - 3 => 'phaseLoadNearOverload', - 4 => 'phaseLoadOverload', -); +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} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'device', type => 1, cb_prefix_output => 'prefix_device_output', message_multiple => 'All devices are ok', skipped_code => { -10 => 1 } }, + { name => 'bank', type => 1, cb_prefix_output => 'prefix_bank_output', message_multiple => 'All banks are ok', skipped_code => { -10 => 1 } }, + { name => 'phase', type => 1, cb_prefix_output => 'prefix_phase_output', message_multiple => 'All phases are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{bank} = [ + { label => 'bank-status', threshold => 0, set => { + key_values => [ { name => 'status' }, { 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 => \&catalog_status_threshold, + } + }, + { label => 'current', nlabel => 'bank.current.ampere', set => { + key_values => [ { name => 'current' }, { name => 'display' } ], + output_template => 'current : %s A', + perfdatas => [ + { label => 'current_bank', template => '%s', value => 'current_absolute', + unit => 'A', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; + + $self->{maps_counters}->{phase} = [ + { label => 'phase-status', threshold => 0, set => { + key_values => [ { name => 'status' }, { 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 => \&catalog_status_threshold, + } + }, + { label => 'current', nlabel => 'phase.current.ampere', set => { + key_values => [ { name => 'current' }, { name => 'display' } ], + output_template => 'current : %s A', + perfdatas => [ + { label => 'current_phase', template => '%s', value => 'current_absolute', + unit => 'A', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'power', nlabel => 'phase.power.watt', set => { + key_values => [ { name => 'power' }, { name => 'display' } ], + output_template => 'power : %s W', + perfdatas => [ + { label => 'power_phase', template => '%s', value => 'power_absolute', + unit => 'W', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; + + $self->{maps_counters}->{device} = [ + { label => 'power', nlabel => 'device.power.watt', set => { + key_values => [ { name => 'power' }, { name => 'display' } ], + output_template => 'power : %s W', + perfdatas => [ + { label => 'power_phase', template => '%s', value => 'power_absolute', + unit => 'W', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_bank_output { + my ($self, %options) = @_; + + return "Bank '" . $options{instance_value}->{display} . "' "; +} + +sub prefix_phase_output { + my ($self, %options) = @_; + + return "Phase '" . $options{instance_value}->{display} . "' "; +} + +sub prefix_device_output { + my ($self, %options) = @_; + + return "Device '" . $options{instance_value}->{display} . "' "; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter:s@" => { name => 'filter' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, - }); + $options{options}->add_options(arguments => { + "unknown-bank-status:s" => { name => 'unknown_bank_status', default => '' }, + "warning-bank-status:s" => { name => 'warning_bank_status', default => '%{status} =~ /low|nearOverload/i' }, + "critical-bank-status:s" => { name => 'critical_bank_status', default => '%{status} =~ /^overload/i' }, + "unknown-phase-status:s" => { name => 'unknown_phase_status', default => '' }, + "warning-phase-status:s" => { name => 'warning_phase_status', default => '%{status} =~ /low|nearOverload/i' }, + "critical-phase-status:s" => { name => 'critical_phase_status', default => '%{status} =~ /^overload/i' }, + }); return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - $self->{filter} = []; - foreach my $val (@{$self->{option_results}->{filter}}) { - next if (!defined($val) || $val eq ''); - my @values = split (/,/, $val); - push @{$self->{filter}}, { filter => $values[0], instance => $values[1] }; - } - - $self->{overload_th} = {}; - foreach my $val (@{$self->{option_results}->{threshold_overload}}) { - next if (!defined($val) || $val eq ''); - my @values = split (/,/, $val); - if (scalar(@values) < 3) { - $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $instance, $status, $filter); - if (scalar(@values) == 3) { - ($section, $status, $filter) = @values; - $instance = '.*'; - } else { - ($section, $instance, $status, $filter) = @values; - } - if ($section !~ /^load$/) { - $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload section '" . $val . "'."); - $self->{output}->option_exit(); - } - if ($self->{output}->is_litteral_status(status => $status) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); - $self->{output}->option_exit(); - } - $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); - push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status, instance => $instance }; - } - - $self->{numeric_threshold} = {}; - foreach my $option (('warning', 'critical')) { - foreach my $val (@{$self->{option_results}->{$option}}) { - next if (!defined($val) || $val eq ''); - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $instance, $value) = ($1, $2, $3); - if ($section !~ /^load$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my $position = 0; - if (defined($self->{numeric_threshold}->{$section})) { - $position = scalar(@{$self->{numeric_threshold}->{$section}}); - } - if (($self->{perfdata}->threshold_validate(label => $option . '-' . $section . '-' . $position, value => $value)) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong $option threshold '" . $value . "'."); - $self->{output}->option_exit(); - } - $self->{numeric_threshold}->{$section} = [] if (!defined($self->{numeric_threshold}->{$section})); - push @{$self->{numeric_threshold}->{$section}}, { label => $option . '-' . $section . '-' . $position, threshold => $option, instance => $instance }; - } - } + $self->SUPER::check_options(%options); + + $self->change_macros(macros => [ + 'warning_bank_status', 'critical_bank_status', 'unknown_bank_status', + 'warning_phase_status', 'critical_phase_status', 'unknown_phase_status', + ]); } -my $mapping = { - rPDULoadStatusLoad => { oid => '.1.3.6.1.4.1.318.1.1.12.2.3.1.1.2' }, - rPDULoadStatusLoadState => { oid => '.1.3.6.1.4.1.318.1.1.12.2.3.1.1.3', map => \%map_status }, - rPDULoadStatusPhaseNumber => { oid => '.1.3.6.1.4.1.318.1.1.12.2.3.1.1.4' }, - rPDULoadStatusBankNumber => { oid => '.1.3.6.1.4.1.318.1.1.12.2.3.1.1.5' }, +my $map_rpdu_status = { + 1 => 'normal', + 2 => 'low', + 3 => 'nearOverload', + 4 => 'overload', }; -sub run { +sub check_rpdu { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; + + return if (scalar(keys %{$self->{phase}}) > 0); + + my $mapping = { + rPDULoadStatusLoad => { oid => '.1.3.6.1.4.1.318.1.1.12.2.3.1.1.2' }, + rPDULoadStatusLoadState => { oid => '.1.3.6.1.4.1.318.1.1.12.2.3.1.1.3', map => $map_rpdu_status }, + rPDULoadStatusPhaseNumber => { oid => '.1.3.6.1.4.1.318.1.1.12.2.3.1.1.4' }, + rPDULoadStatusBankNumber => { oid => '.1.3.6.1.4.1.318.1.1.12.2.3.1.1.5' }, # Bank 0 = no bank (phase total) + }; my $oid_rPDULoadStatusEntry = '.1.3.6.1.4.1.318.1.1.12.2.3.1.1'; + my $snmp_result = $options{snmp}->get_table(oid => $oid_rPDULoadStatusEntry, nothing_quit => 1); - $self->{results} = $self->{snmp}->get_table(oid => $oid_rPDULoadStatusEntry, nothing_quit => 1); - - $self->{output}->output_add(severity => 'OK', - short_msg => 'All phase/bank loads are ok'); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}})) { + foreach my $oid (keys %{$snmp_result}) { next if ($oid !~ /^$mapping->{rPDULoadStatusLoadState}->{oid}\.(.*)$/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); - - next if ($self->check_filter(section => 'load', instance => $instance)); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); - $self->{output}->output_add(long_msg => sprintf("Phase '%s' on Bank '%s' status is '%s' [instance: %s, value: %s]", - $result->{rPDULoadStatusPhaseNumber}, $result->{rPDULoadStatusBankNumber}, $result->{rPDULoadStatusLoadState}, - $instance, defined($result->{rPDULoadStatusLoad}) ? $result->{rPDULoadStatusLoad} : '-')); - my $exit = $self->get_severity(section => 'load', instance => $instance, value => $result->{rPDULoadStatusLoadState}); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Phase '%s' on Bank '%s' status is '%s'", - $result->{rPDULoadStatusPhaseNumber}, $result->{rPDULoadStatusBankNumber}, $result->{rPDULoadStatusLoadState})); - } - - if (defined($result->{rPDULoadStatusLoad}) && $result->{rPDULoadStatusLoad} =~ /[0-9]/) { - $result->{rPDULoadStatusLoad} /= 10; - my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'load', instance => $instance, value => $result->{rPDULoadStatusLoad}); - if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit2, - short_msg => sprintf("Phase '%s' on Bank '%s' load is %s A", - $result->{rPDULoadStatusPhaseNumber}, $result->{rPDULoadStatusBankNumber}, $result->{rPDULoadStatusLoad})); - } - $self->{output}->perfdata_add(label => 'load_bank_' . $result->{rPDULoadStatusBankNumber} . '_phase_' . $result->{rPDULoadStatusPhaseNumber}, unit => 'A', - value => $result->{rPDULoadStatusLoad}, - warning => $warn, - critical => $crit, - min => 0); + if ($result->{rPDULoadStatusBankNumber} == 0) { + $self->{phase}->{$result->{rPDULoadStatusPhaseNumber}} = { + display => $result->{rPDULoadStatusPhaseNumber}, + status => $result->{rPDULoadStatusLoadState}, + current => $result->{rPDULoadStatusLoad} / 10, + }; + } else { + $self->{bank}->{$result->{rPDULoadStatusBankNumber}} = { display => $result->{rPDULoadStatusBankNumber}, current => 0 } + if (!defined($self->{bank}->{$result->{rPDULoadStatusBankNumber}})); + $self->{bank}->{$result->{rPDULoadStatusBankNumber}}->{status} = $result->{rPDULoadStatusLoadState}; + $self->{bank}->{$result->{rPDULoadStatusBankNumber}}->{current} += $result->{rPDULoadStatusLoad} / 10; } } - $self->{output}->display(); - $self->{output}->exit(); + my $oid_rPDUIdentName = '.1.3.6.1.4.1.318.1.1.12.1.1.0'; + my $oid_rPDUIdentDevicePowerWatts = '.1.3.6.1.4.1.318.1.1.12.1.16.0'; + $snmp_result = $options{snmp}->get_leef(oids => [$oid_rPDUIdentName, $oid_rPDUIdentDevicePowerWatts]); + $self->{device}->{0} = { + display => $snmp_result->{$oid_rPDUIdentName}, + power => $snmp_result->{$oid_rPDUIdentDevicePowerWatts} * 10, + }; } -sub check_filter { +my $map_rpdu2_status = { + 1 => 'low', + 2 => 'normal', + 3 => 'nearOverload', + 4 => 'overload', +}; + +sub check_rpdu2 { my ($self, %options) = @_; - foreach (@{$self->{filter}}) { - if ($options{section} =~ /$_->{filter}/) { - if (!defined($options{instance}) && !defined($_->{instance})) { - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); - return 1; - } elsif (defined($options{instance}) && $options{instance} =~ /$_->{instance}/) { - $self->{components}->{$options{section}}->{skip}++ if (defined($self->{components}->{$options{section}})); - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); - return 1; - } + my $mapping_phase = { + rPDU2PhaseStatusNumber => { oid => '.1.3.6.1.4.1.318.1.1.26.6.3.1.3' }, + rPDU2PhaseStatusLoadState => { oid => '.1.3.6.1.4.1.318.1.1.26.6.3.1.4', map => $map_rpdu2_status }, + rPDU2PhaseStatusCurrent => { oid => '.1.3.6.1.4.1.318.1.1.26.6.3.1.5' }, + rPDU2PhaseStatusPower => { oid => '.1.3.6.1.4.1.318.1.1.26.6.3.1.7' }, + }; + my $mapping_bank = { + rPDU2BankStatusNumber => { oid => '.1.3.6.1.4.1.318.1.1.26.8.3.1.3' }, + rPDU2BankStatusLoadState => { oid => '.1.3.6.1.4.1.318.1.1.26.8.3.1.4', map => $map_rpdu2_status }, + rPDU2BankStatusCurrent => { oid => '.1.3.6.1.4.1.318.1.1.26.8.3.1.5' }, + }; + my $mapping_device = { + rPDU2DeviceStatusName => { oid => '.1.3.6.1.4.1.318.1.1.26.4.3.1.3' }, + rPDU2DeviceStatusPower => { oid => '.1.3.6.1.4.1.318.1.1.26.4.3.1.5' }, + }; + + my $oid_rPDU2DeviceStatusEntry = '.1.3.6.1.4.1.318.1.1.26.4.3.1'; + my $oid_rPDU2PhaseStatusEntry = '.1.3.6.1.4.1.318.1.1.26.6.3.1'; + my $oid_rPDU2BankStatusEntry = '.1.3.6.1.4.1.318.1.1.26.8.3.1'; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_rPDU2PhaseStatusEntry, end => $mapping_phase->{rPDU2PhaseStatusPower}->{oid} }, + { oid => $oid_rPDU2BankStatusEntry, end => $mapping_bank->{rPDU2BankStatusCurrent}->{oid} }, + { oid => $oid_rPDU2DeviceStatusEntry, end => $mapping_bank->{rPDU2DeviceStatusPower}->{oid} }, + ]); + + foreach my $oid (keys %{$snmp_result->{$oid_rPDU2PhaseStatusEntry}}) { + next if ($oid !~ /^$mapping_phase->{rPDU2PhaseStatusLoadState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping_phase, results => $snmp_result->{$oid_rPDU2PhaseStatusEntry}, instance => $instance); + + $self->{phase}->{$result->{rPDU2PhaseStatusNumber}} = { + display => $result->{rPDU2PhaseStatusNumber}, + status => $result->{rPDU2PhaseStatusLoadState}, + current => $result->{rPDU2PhaseStatusCurrent} / 10, + power => $result->{rPDU2PhaseStatusPower} * 10, # hundreth of kW. So * 10 for watt + } + } + + foreach my $oid (keys %{$snmp_result->{$oid_rPDU2BankStatusEntry}}) { + next if ($oid !~ /^$mapping_phase->{rPDU2BankStatusLoadState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping_bank, results => $snmp_result->{$oid_rPDU2BankStatusEntry}, instance => $instance); + + $self->{bank}->{$result->{rPDU2BankStatusNumber}} = { + display => $result->{rPDU2BankStatusNumber}, + status => $result->{rPDU2BankStatusLoadState}, + current => $result->{rPDU2BankStatusCurrent} / 10, + } + } + + foreach my $oid (keys %{$snmp_result->{$oid_rPDU2DeviceStatusEntry}}) { + next if ($oid !~ /^$mapping_device->{rPDU2DeviceStatusPower}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping_device, results => $snmp_result->{$oid_rPDU2DeviceStatusEntry}, instance => $instance); + + $self->{device}->{$result->{rPDU2DeviceStatusName}} = { + display => $result->{rPDU2DeviceStatusName}, + power => $result->{rPDU2DeviceStatusPower} * 10, } } - - return 0; } -sub get_severity_numeric { +sub manage_selection { my ($self, %options) = @_; - my $status = 'OK'; # default - my $thresholds = { warning => undef, critical => undef }; - my $checked = 0; - - if (defined($self->{numeric_threshold}->{$options{section}})) { - my $exits = []; - foreach (@{$self->{numeric_threshold}->{$options{section}}}) { - if ($options{instance} =~ /$_->{instance}/) { - push @{$exits}, $self->{perfdata}->threshold_check(value => $options{value}, threshold => [ { label => $_->{label}, exit_litteral => $_->{threshold} } ]); - $thresholds->{$_->{threshold}} = $self->{perfdata}->get_perfdata_for_output(label => $_->{label}); - $checked = 1; - } - } - $status = $self->{output}->get_most_critical(status => $exits) if (scalar(@{$exits}) > 0); - } - - return ($status, $thresholds->{warning}, $thresholds->{critical}, $checked); -} -sub get_severity { - my ($self, %options) = @_; - my $status = 'UNKNOWN'; # default + $self->{bank} = {}; + $self->{phase} = {}; + $self->{device} = {}; - if (defined($self->{overload_th}->{$options{section}})) { - foreach (@{$self->{overload_th}->{$options{section}}}) { - if ($options{value} =~ /$_->{filter}/i && - (!defined($options{instance}) || $options{instance} =~ /$_->{instance}/)) { - $status = $_->{status}; - return $status; - } - } - } - my $label = defined($options{label}) ? $options{label} : $options{section}; - foreach (@{$thresholds->{$label}}) { - if ($options{value} =~ /$$_[0]/i) { - $status = $$_[1]; - return $status; - } - } + $self->check_rpdu2(%options); + $self->check_rpdu(%options); - return $status; + if (scalar(keys %{$self->{device}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No device found."); + $self->{output}->option_exit(); + } } 1; @@ -247,30 +302,45 @@ __END__ =head1 MODE -Check phase/bank load state. +Check phase/bank load. =over 8 -=item B<--filter> +=item B<--unknown-bank-status> -Exclude some parts (comma seperated list) -Can also exclude specific instance: --filter=load,1 +Set warning threshold for status. +Can used special variables like: %{type}, %{status}, %{display} -=item B<--threshold-overload> +=item B<--warning-bank-status> -Set to overload default threshold values (syntax: section,[instance,]status,regexp) -It used before default thresholds (order stays). -Example: --threshold-overload='load,CRITICAL,^(?!(PhaseLoadNormal)$)' +Set warning threshold for status (Default: '%{status} =~ /low|nearOverload/i'). +Can used special variables like: %{type}, %{status}, %{display} -=item B<--warning> +=item B<--critical-bank-status> -Set warning threshold for temperatures (syntax: type,instance,threshold) -Example: --warning='load,.*,30' +Set critical threshold for status (Default: '%{status} =~ /^overload/'). +Can used special variables like: %{type}, %{status}, %{display} -=item B<--critical> +=item B<--unknown-phase-status> + +Set warning threshold for status. +Can used special variables like: %{status}, %{display} + +=item B<--warning-pĥase-status> + +Set warning threshold for status (Default: '%{status} =~ /low|nearOverload/i'). +Can used special variables like: %{status}, %{display} + +=item B<--critical-phase-status> + +Set critical threshold for status (Default: '%{status} =~ /^overload/i'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'current', 'power'. -Set critical threshold for temperatures (syntax: type,instance,threshold) -Example: --critical='load,.*,40' =back =cut diff --git a/hardware/pdu/apc/snmp/mode/outlet.pm b/hardware/pdu/apc/snmp/mode/outlet.pm index 66761e536..9b5bf4ec9 100644 --- a/hardware/pdu/apc/snmp/mode/outlet.pm +++ b/hardware/pdu/apc/snmp/mode/outlet.pm @@ -20,23 +20,92 @@ package hardware::pdu::apc::snmp::mode::outlet; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::misc; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); -my $thresholds = { - outlet => [ - ['outletStatusOn', 'OK'], - ['outletStatusOff', 'CRITICAL'], - ], -}; -my %map_status = ( - 1 => 'outletStatusOn', - 2 => 'outletStatusOff', +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = "status : '" . $self->{result_values}->{status} . "' [bank : " . $self->{result_values}->{bank} . ', phase : ' . $self->{result_values}->{phase} . ']'; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{bank} = $options{new_datas}->{$self->{instance} . '_bank'}; + $self->{result_values}->{phase} = $options{new_datas}->{$self->{instance} . '_phase'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'outlet', type => 1, cb_prefix_output => 'prefix_outlet_output', message_multiple => 'All outlets are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{outlet} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'bank' }, { name => 'phase' }, { 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 => \&catalog_status_threshold, + } + }, + { label => 'current', nlabel => 'outlet.current.ampere', set => { + key_values => [ { name => 'current' }, { name => 'display' } ], + output_template => 'current : %s A', + perfdatas => [ + { label => 'current', template => '%s', value => 'current_absolute', + unit => 'A', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_outlet_output { + my ($self, %options) = @_; + + return "Outlet '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /off/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => [ + 'warning_status', 'critical_status', 'unknown_status', + ]); +} + +my %map_rpdu_status = ( + 1 => 'on', + 2 => 'off', ); -my %map_phase = ( +my %map_rpdu_phase = ( 1 => 'phase1', 2 => 'phase2', 3 => 'phase3', @@ -45,209 +114,55 @@ my %map_phase = ( 6 => 'phase3-1', ); -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:s@" => { name => 'filter' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, - }); - - return $self; -} - -sub check_options { +sub check_rpdu { my ($self, %options) = @_; - $self->SUPER::init(%options); - - $self->{filter} = []; - foreach my $val (@{$self->{option_results}->{filter}}) { - next if (!defined($val) || $val eq ''); - my @values = split (/,/, $val); - push @{$self->{filter}}, { filter => $values[0], instance => $values[1] }; - } - - $self->{overload_th} = {}; - foreach my $val (@{$self->{option_results}->{threshold_overload}}) { - next if (!defined($val) || $val eq ''); - my @values = split (/,/, $val); - if (scalar(@values) < 3) { - $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $instance, $status, $filter); - if (scalar(@values) == 3) { - ($section, $status, $filter) = @values; - $instance = '.*'; - } else { - ($section, $instance, $status, $filter) = @values; - } - if ($section !~ /^outlet$/) { - $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload section '" . $val . "'."); - $self->{output}->option_exit(); - } - if ($self->{output}->is_litteral_status(status => $status) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); - $self->{output}->option_exit(); - } - $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); - push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status, instance => $instance }; - } - - $self->{numeric_threshold} = {}; - foreach my $option (('warning', 'critical')) { - foreach my $val (@{$self->{option_results}->{$option}}) { - next if (!defined($val) || $val eq ''); - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $instance, $value) = ($1, $2, $3); - if ($section !~ /^load$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my $position = 0; - if (defined($self->{numeric_threshold}->{$section})) { - $position = scalar(@{$self->{numeric_threshold}->{$section}}); - } - if (($self->{perfdata}->threshold_validate(label => $option . '-' . $section . '-' . $position, value => $value)) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong $option threshold '" . $value . "'."); - $self->{output}->option_exit(); - } - $self->{numeric_threshold}->{$section} = [] if (!defined($self->{numeric_threshold}->{$section})); - push @{$self->{numeric_threshold}->{$section}}, { label => $option . '-' . $section . '-' . $position, threshold => $option, instance => $instance }; - } - } -} -my $mapping = { - rPDUOutletStatusOutletName => { oid => '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.2' }, - rPDUOutletStatusOutletPhase => { oid => '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.3', map => \%map_phase }, - rPDUOutletStatusOutletState => { oid => '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.4', map => \%map_status }, - rPDUOutletStatusOutletBank => { oid => '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.6' }, - rPDUOutletStatusLoad => { oid => '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.7' }, -}; + return if (scalar(keys %{$self->{outlet}}) > 0); -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; + my $mapping = { + rPDUOutletStatusOutletName => { oid => '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.2' }, + rPDUOutletStatusOutletPhase => { oid => '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.3', map => \%map_rpdu_phase }, + rPDUOutletStatusOutletState => { oid => '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.4', map => \%map_rpdu_status }, + rPDUOutletStatusOutletBank => { oid => '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.6' }, + rPDUOutletStatusLoad => { oid => '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.7' }, + }; my $oid_rPDUOutletStatusEntry = '.1.3.6.1.4.1.318.1.1.12.3.5.1.1'; + my $snmp_result = $options{snmp}->get_table(oid => $oid_rPDUOutletStatusEntry, nothing_quit => 1); - $self->{results} = $self->{snmp}->get_table(oid => $oid_rPDUOutletStatusEntry, nothing_quit => 1); - - $self->{output}->output_add(severity => 'OK', - short_msg => 'All outlets are ok'); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}})) { + foreach my $oid (keys %{$snmp_result}) { next if ($oid !~ /^$mapping->{rPDUOutletStatusOutletState}->{oid}\.(.*)$/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); - - next if ($self->check_filter(section => 'outlet', instance => $instance)); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); - $self->{output}->output_add(long_msg => sprintf("Outlet '%s' state is '%s' [instance: %s, bank : %s, phase : %s, load: %s]", - $result->{rPDUOutletStatusOutletName}, $result->{rPDUOutletStatusOutletState}, - $instance, $result->{rPDUOutletStatusOutletBank}, $result->{rPDUOutletStatusOutletPhase}, - defined($result->{rPDUOutletStatusLoad}) ? $result->{rPDUOutletStatusLoad} : '-')); - my $exit = $self->get_severity(section => 'outlet', instance => $instance, value => $result->{rPDUOutletStatusOutletState}); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Outlet '%s' state is '%s' [bank : %s, phase : %s]", - $result->{rPDUOutletStatusOutletName}, $result->{rPDUOutletStatusOutletState}, - $result->{rPDUOutletStatusOutletBank}, $result->{rPDUOutletStatusOutletPhase})); - } - - if (defined($result->{rPDUOutletStatusLoad}) && $result->{rPDUOutletStatusLoad} =~ /[0-9]/ && $result->{rPDUOutletStatusLoad} != 0) { - $result->{rPDUOutletStatusLoad} /= 10; - my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'load', instance => $instance, value => $result->{rPDUOutletStatusLoad}); - if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit2, - short_msg => sprintf("Outlet '%s' load is %s A [bank : %s, phase : %s]", - $result->{rPDUOutletStatusOutletName}, $result->{rPDUOutletStatusLoad}, - $result->{rPDUOutletStatusOutletBank}, $result->{rPDUOutletStatusOutletPhase})); - } - $self->{output}->perfdata_add(label => 'load_' . $result->{rPDUOutletStatusOutletName} . '_bank_' . $result->{rPDUOutletStatusOutletBank} . '_' . $result->{rPDUOutletStatusOutletPhase} . '_' . $instance, - unit => 'A', - value => $result->{rPDUOutletStatusLoad}, - warning => $warn, - critical => $crit, - min => 0); - } + $self->{outlet}->{$instance} = { + display => $result->{rPDUOutletStatusOutletName}, + status => $result->{rPDUOutletStatusOutletState}, + bank => $result->{rPDUOutletStatusOutletBank}, + phase => $result->{rPDUOutletStatusOutletPhase}, + current => $result->{rPDUOutletStatusLoad} / 10, + }; } - - $self->{output}->display(); - $self->{output}->exit(); } -sub check_filter { +sub check_rpdu2 { my ($self, %options) = @_; - foreach (@{$self->{filter}}) { - if ($options{section} =~ /$_->{filter}/) { - if (!defined($options{instance}) && !defined($_->{instance})) { - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); - return 1; - } elsif (defined($options{instance}) && $options{instance} =~ /$_->{instance}/) { - $self->{components}->{$options{section}}->{skip}++ if (defined($self->{components}->{$options{section}})); - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); - return 1; - } - } - } - - return 0; + # not implemented yet } -sub get_severity_numeric { +sub manage_selection { my ($self, %options) = @_; - my $status = 'OK'; # default - my $thresholds = { warning => undef, critical => undef }; - my $checked = 0; - - if (defined($self->{numeric_threshold}->{$options{section}})) { - my $exits = []; - foreach (@{$self->{numeric_threshold}->{$options{section}}}) { - if ($options{instance} =~ /$_->{instance}/) { - push @{$exits}, $self->{perfdata}->threshold_check(value => $options{value}, threshold => [ { label => $_->{label}, exit_litteral => $_->{threshold} } ]); - $thresholds->{$_->{threshold}} = $self->{perfdata}->get_perfdata_for_output(label => $_->{label}); - $checked = 1; - } - } - $status = $self->{output}->get_most_critical(status => $exits) if (scalar(@{$exits}) > 0); - } - - return ($status, $thresholds->{warning}, $thresholds->{critical}, $checked); -} -sub get_severity { - my ($self, %options) = @_; - my $status = 'UNKNOWN'; # default + $self->{outlet} = {}; - if (defined($self->{overload_th}->{$options{section}})) { - foreach (@{$self->{overload_th}->{$options{section}}}) { - if ($options{value} =~ /$_->{filter}/i && - (!defined($options{instance}) || $options{instance} =~ /$_->{instance}/)) { - $status = $_->{status}; - return $status; - } - } - } - my $label = defined($options{label}) ? $options{label} : $options{section}; - foreach (@{$thresholds->{$label}}) { - if ($options{value} =~ /$$_[0]/i) { - $status = $$_[1]; - return $status; - } - } + $self->check_rpdu2(%options); + $self->check_rpdu(%options); - return $status; + if (scalar(keys %{$self->{outlet}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No outlet found."); + $self->{output}->option_exit(); + } } 1; @@ -256,30 +171,30 @@ __END__ =head1 MODE -Check outlet state. +Check outlet. =over 8 -=item B<--filter> +=item B<--unknown-status> -Exclude some parts (comma seperated list) -Can also exclude specific instance: --filter=outlet,1 +Set warning threshold for status. +Can used special variables like: %{status}, %{display} -=item B<--threshold-overload> +=item B<--warning-status> -Set to overload default threshold values (syntax: section,[instance,]status,regexp) -It used before default thresholds (order stays). -Example: --threshold-overload='outlet,WARNING,^(?!(outletStatusOn)$)' +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{phase}, %{bank}, %{display} -=item B<--warning> +=item B<--critical-status> -Set warning threshold for temperatures (syntax: type,instance,threshold) -Example: --warning='load,.*,30' +Set critical threshold for status (Default: '%{status} =~ /off/'). +Can used special variables like: %{status}, %{phase}, %{bank}, %{display} -=item B<--critical> +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'current'. -Set critical threshold for temperatures (syntax: type,instance,threshold) -Example: --critical='load,.*,40' =back =cut diff --git a/hardware/pdu/eaton/mode/group.pm b/hardware/pdu/eaton/mode/group.pm deleted file mode 100644 index bbece2371..000000000 --- a/hardware/pdu/eaton/mode/group.pm +++ /dev/null @@ -1,196 +0,0 @@ -# -# Copyright 2019 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 hardware::pdu::eaton::mode::group; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my %oids = ( - '.1.3.6.1.4.1.534.6.6.7.5.3.1.3' => { counter => 'voltage', no_present => 0 }, # in mVolt groupVoltage - '.1.3.6.1.4.1.534.6.6.7.5.4.1.3' => { counter => 'current', no_present => 0 }, # in mA groupCurrent - '.1.3.6.1.4.1.534.6.6.7.5.5.1.3' => { counter => 'power', no_present => 0 }, # in Watt groupWatts -); - -my $oid_groups = '.1.3.6.1.4.1.534.6.6.7.5'; - -my $maps_counters = { - voltage => { thresholds => { - warning_voltage => { label => 'warning-voltage', exit_value => 'warning' }, - critical_voltage => { label => 'critical-voltage', exit_value => 'critical' }, - }, - output_msg => 'Voltage : %.2f V', - factor => 0.001, unit => 'V', - }, - current => { thresholds => { - warning_current => { label => 'warning-current', exit_value => 'warning' }, - critical_current => { label => 'critical-current', exit_value => 'critical' }, - }, - output_msg => 'Current : %.2f A', - factor => 0.001, unit => 'A', - }, - power => { thresholds => { - warning_power => { label => 'warning-power', exit_value => 'warning' }, - critical_power => { label => 'critical-power', exit_value => 'critical' }, - }, - output_msg => 'Power : %.2f W', - factor => 1, unit => 'W', - }, -}; - -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 => - { - }); - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - } - } - - $self->{counters_value} = {}; - $self->{instances_done} = {}; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - } - } - } -} - -sub build_values { - my ($self, %options) = @_; - my $counters_value = {}; - my $instance = undef; - - foreach my $oid (keys %oids) { - if ($options{current} =~ /^$oid\.(.*)/) { - $instance = $1; - last; - } - } - - # Skip already done - if (!defined($instance) || defined($self->{instances_done}->{$instance})) { - return 0; - } - - $self->{instances_done}->{$instance} = 1; - $self->{counters_value}->{$instance} = {}; - foreach my $oid (keys %oids) { - my $full_oid = $oid . '.' . $instance; - $self->{counters_value}->{$instance}->{$oids{$oid}->{counter}} = defined($options{result}->{$oid . '.' . $instance}) ? $options{result}->{$oid . '.' . $instance} : 0; - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - my $result = $self->{snmp}->get_table(oid => $oid_groups, nothing_quit => 1); - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - $self->build_values(current => $key, result => $result); - } - - my $num = scalar(keys %{$self->{instances_done}}); - foreach my $instance (keys %{$self->{instances_done}}) { - my $instance_output = $instance; - $instance_output =~ s/\./#/g; - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (defined($self->{counters_value}->{$instance}->{$_}) && $self->{counters_value}->{$instance}->{$_} != 0) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{counters_value}->{$instance}->{$_}*$maps_counters->{$_}->{factor}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = "Group '$instance_output' "; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - next if (!defined($self->{counters_value}->{$instance}->{$_}) || $self->{counters_value}->{$instance}->{$_} == 0); - - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{counters_value}->{$instance}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{counters_value}->{$instance}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check Group metrics (voltage, current and power). - -=over 8 - -=item B<--warning-*> - -Threshold warning. -Can be: 'voltage', 'current', 'power'. - -=item B<--critical-*> - -Threshold critical. -Can be: 'voltage', 'current', 'power'. - -=back - -=cut diff --git a/hardware/pdu/eaton/mode/outlet.pm b/hardware/pdu/eaton/mode/outlet.pm deleted file mode 100644 index 598449695..000000000 --- a/hardware/pdu/eaton/mode/outlet.pm +++ /dev/null @@ -1,200 +0,0 @@ -# -# Copyright 2019 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 hardware::pdu::eaton::mode::outlet; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my %oids = ( - '.1.3.6.1.4.1.534.6.6.7.6.3.1.2' => { counter => 'voltage', no_present => 0 }, # in mVolt outletVoltage - '.1.3.6.1.4.1.534.6.6.7.6.4.1.3' => { counter => 'current', no_present => 0 }, # in mA outletCurrent - '.1.3.6.1.4.1.534.6.6.7.6.5.1.3' => { counter => 'power', no_present => 0 }, # in Watt outletWatts -); - -my $oid_outlets = '.1.3.6.1.4.1.534.6.6.7.6'; - -my $maps_counters = { - voltage => { thresholds => { - warning_voltage => { label => 'warning-voltage', exit_value => 'warning' }, - critical_voltage => { label => 'critical-voltage', exit_value => 'critical' }, - }, - output_msg => 'Voltage : %.2f V', - factor => 0.001, unit => 'V', - }, - current => { thresholds => { - warning_current => { label => 'warning-current', exit_value => 'warning' }, - critical_current => { label => 'critical-current', exit_value => 'critical' }, - }, - output_msg => 'Current : %.2f A', - factor => 0.001, unit => 'A', - }, - power => { thresholds => { - warning_power => { label => 'warning-power', exit_value => 'warning' }, - critical_power => { label => 'critical-power', exit_value => 'critical' }, - }, - output_msg => 'Power : %.2f W', - factor => 1, unit => 'W', - }, -}; - -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 => - { - }); - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - } - } - - $self->{counters_value} = {}; - $self->{instances_done} = {}; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - } - } - } -} - -sub build_values { - my ($self, %options) = @_; - my $counters_value = {}; - my $instance = undef; - - foreach my $oid (keys %oids) { - #if ($options{current} =~ /^$oid_outlets\.(.*)/) { - if ($options{current} =~ /^$oid\.(.*)/) { - $instance = $1; - #$instance =~ s/1\.1\.3\.//g; - last; - } - } - - # Skip already done - if (!defined($instance) || defined($self->{instances_done}->{$instance})) { - return 0; - } - - $self->{instances_done}->{$instance} = 1; - $self->{counters_value}->{$instance} = {}; - foreach my $oid (keys %oids) { - my $full_oid = $oid . '.' . $instance; - $self->{counters_value}->{$instance}->{$oids{$oid}->{counter}} = defined($options{result}->{$oid . '.' . $instance}) ? $options{result}->{$oid . '.' . $instance} : 0; - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - #my $oid_outletName = '.1.3.6.1.4.1.534.6.6.7.6.1.1.3'; - #my $result = $self->{snmp}->get_table(oid => $oid_outletName, nothing_quit => 1); - my $result = $self->{snmp}->get_table(oid => $oid_outlets, nothing_quit => 1); - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - $self->build_values(current => $key, result => $result); - } - - my $num = scalar(keys %{$self->{instances_done}}); - foreach my $instance (keys %{$self->{instances_done}}) { - my $instance_output = $instance; - $instance_output =~ s/\./#/g; - - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (defined($self->{counters_value}->{$instance}->{$_}) && $self->{counters_value}->{$instance}->{$_} != 0) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{counters_value}->{$instance}->{$_}*$maps_counters->{$_}->{factor}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = "Outlet '$instance_output' "; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - next if (!defined($self->{counters_value}->{$instance}->{$_}) || $self->{counters_value}->{$instance}->{$_} == 0); - - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{counters_value}->{$instance}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{counters_value}->{$instance}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check Outlet metrics (voltage, current and power). - -=over 8 - -=item B<--warning-*> - -Threshold warning. -Can be: 'voltage', 'current', 'power'. - -=item B<--critical-*> - -Threshold critical. -Can be: 'voltage', 'current', 'power'. - -=back - -=cut diff --git a/hardware/pdu/eaton/snmp/mode/group.pm b/hardware/pdu/eaton/snmp/mode/group.pm new file mode 100644 index 000000000..89e35eefb --- /dev/null +++ b/hardware/pdu/eaton/snmp/mode/group.pm @@ -0,0 +1,146 @@ +# +# Copyright 2019 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 hardware::pdu::eaton::snmp::mode::group; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'group', type => 1, cb_prefix_output => 'prefix_group_output', message_multiple => 'All groups are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{group} = [ + { label => 'current', nlabel => 'group.current.ampere', set => { + key_values => [ { name => 'groupCurrent', no_value => 0 } ], + output_template => 'Current : %.2f A', + perfdatas => [ + { value => 'groupCurrent_absolute', template => '%.2f', + min => 0, unit => 'A', label_extra_instance => 1 }, + ], + } + }, + { label => 'voltage', nlabel => 'group.voltage.volt', set => { + key_values => [ { name => 'groupVoltage', no_value => 0 } ], + output_template => 'Voltage : %.2f V', + perfdatas => [ + { value => 'groupVoltage_absolute', template => '%.2f', + unit => 'V', label_extra_instance => 1 }, + ], + } + }, + { label => 'power', nlabel => 'group.power.watt', set => { + key_values => [ { name => 'groupWatts', no_value => 0 } ], + output_template => 'Power : %.2f W', + perfdatas => [ + { value => 'groupWatts_absolute', template => '%.2f', + unit => 'W', label_extra_instance => 1 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +sub prefix_group_output { + my ($self, %options) = @_; + + return "Group '" . $options{instance_value}->{display} . "' "; +} + +my $mapping = { + groupName => { oid => '.1.3.6.1.4.1.534.6.6.7.5.1.1.3' }, + groupVoltage => { oid => '.1.3.6.1.4.1.534.6.6.7.5.3.1.3' }, # in mVolt + groupCurrent => { oid => '.1.3.6.1.4.1.534.6.6.7.5.4.1.3' }, # in mA + groupWatts => { oid => '.1.3.6.1.4.1.534.6.6.7.5.5.1.3' }, # in Watt +}; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{group} = {}; + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $mapping->{groupName}->{oid} }, + { oid => $mapping->{groupVoltage}->{oid} }, + { oid => $mapping->{groupCurrent}->{oid} }, + { oid => $mapping->{groupWatts}->{oid} }, + ], + return_type => 1, nothing_quit => 1 + ); + + foreach my $oid (keys %{$snmp_result}) { + $oid =~ /\.(\d+\.\d+)$/; + my $instance = $1; + next if (defined($self->{group}->{$instance})); + + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + $result->{groupVoltage} *= 0.001 if (defined($result->{groupVoltage})); + $result->{groupCurrent} *= 0.001 if (defined($result->{groupCurrent})); + my $display = $instance; + $display = $result->{groupName} if (defined($result->{groupName}) && $result->{groupName} ne ''); + $self->{group}->{$display} = { display => $display, %$result }; + } + + if (scalar(keys %{$self->{group}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No group found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check group metrics (voltage, current and power). + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'voltage', 'current', 'power'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'voltage', 'current', 'power'. + +=back + +=cut diff --git a/hardware/pdu/eaton/snmp/mode/outlet.pm b/hardware/pdu/eaton/snmp/mode/outlet.pm new file mode 100644 index 000000000..cdfce890a --- /dev/null +++ b/hardware/pdu/eaton/snmp/mode/outlet.pm @@ -0,0 +1,146 @@ +# +# Copyright 2019 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 hardware::pdu::eaton::snmp::mode::outlet; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'outlet', type => 1, cb_prefix_output => 'prefix_outlet_output', message_multiple => 'All outlets are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{outlet} = [ + { label => 'current', nlabel => 'outlet.current.ampere', set => { + key_values => [ { name => 'outletCurrent', no_value => 0 } ], + output_template => 'Current : %.2f A', + perfdatas => [ + { value => 'outletCurrent_absolute', template => '%.2f', + min => 0, unit => 'A', label_extra_instance => 1 }, + ], + } + }, + { label => 'voltage', nlabel => 'outlet.voltage.volt', set => { + key_values => [ { name => 'outletVoltage', no_value => 0 } ], + output_template => 'Voltage : %.2f V', + perfdatas => [ + { value => 'outletVoltage_absolute', template => '%.2f', + unit => 'V', label_extra_instance => 1 }, + ], + } + }, + { label => 'power', nlabel => 'outlet.power.watt', set => { + key_values => [ { name => 'outletWatts', no_value => 0 } ], + output_template => 'Power : %.2f W', + perfdatas => [ + { value => 'outletWatts_absolute', template => '%.2f', + unit => 'W', label_extra_instance => 1 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +sub prefix_outlet_output { + my ($self, %options) = @_; + + return "Outlet '" . $options{instance_value}->{display} . "' "; +} + +my $mapping = { + outletName => { oid => '.1.3.6.1.4.1.534.6.6.7.6.1.1.3' }, + outletVoltage => { oid => '.1.3.6.1.4.1.534.6.6.7.6.3.1.2' }, # in mVolt + outletCurrent => { oid => '.1.3.6.1.4.1.534.6.6.7.6.4.1.3' }, # in mA + outletWatts => { oid => '.1.3.6.1.4.1.534.6.6.7.6.5.1.3' }, # in Watt +}; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{outlet} = {}; + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $mapping->{outletName}->{oid} }, + { oid => $mapping->{outletVoltage}->{oid} }, + { oid => $mapping->{outletCurrent}->{oid} }, + { oid => $mapping->{outletWatts}->{oid} }, + ], + return_type => 1, nothing_quit => 1 + ); + + foreach my $oid (keys %{$snmp_result}) { + $oid =~ /\.(\d+\.\d+)$/; + my $instance = $1; + next if (defined($self->{outlet}->{$instance})); + + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + $result->{outletVoltage} *= 0.001 if (defined($result->{outletVoltage})); + $result->{outletCurrent} *= 0.001 if (defined($result->{outletCurrent})); + my $display = $instance; + $display = $result->{outletName} if (defined($result->{outletName}) && $result->{outletName} ne ''); + $self->{outlet}->{$display} = { display => $display, %$result }; + } + + if (scalar(keys %{$self->{outlet}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No outlet found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check outlet metrics (voltage, current and power). + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'voltage', 'current', 'power'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'voltage', 'current', 'power'. + +=back + +=cut diff --git a/hardware/pdu/eaton/plugin.pm b/hardware/pdu/eaton/snmp/plugin.pm similarity index 82% rename from hardware/pdu/eaton/plugin.pm rename to hardware/pdu/eaton/snmp/plugin.pm index adf5569ea..830cf1702 100644 --- a/hardware/pdu/eaton/plugin.pm +++ b/hardware/pdu/eaton/snmp/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package hardware::pdu::eaton::plugin; +package hardware::pdu::eaton::snmp::plugin; use strict; use warnings; @@ -31,9 +31,9 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'group' => 'hardware::pdu::eaton::mode::group', - 'outlet' => 'hardware::pdu::eaton::mode::outlet', - ); + 'group' => 'hardware::pdu::eaton::snmp::mode::group', + 'outlet' => 'hardware::pdu::eaton::snmp::mode::outlet', + ); return $self; } diff --git a/hardware/pdu/raritan/snmp/mode/components/resources.pm b/hardware/pdu/raritan/snmp/mode/components/resources.pm index eece42266..c5fa2c8f5 100644 --- a/hardware/pdu/raritan/snmp/mode/components/resources.pm +++ b/hardware/pdu/raritan/snmp/mode/components/resources.pm @@ -33,29 +33,29 @@ our @ISA = qw(Exporter); our @EXPORT_OK = qw($thresholds $mapping %raritan_type %map_type); my %map_units = ( - -1 => '', # none - 0 => 'other', - 1 => 'V', # volt, - 2 => 'A', # amp, - 3 => 'W', # watt - 4 => 'voltamp', - 5 => 'wattHour', - 6 => 'voltampHour', - 7 => 'C', # degreeC - 8 => 'Hz', # hertz - 9 => '%', # percent - 10 => 'meterpersec', - 11 => 'pascal', - 12 => 'psi', - 13 => 'g', - 14 => 'degreeF', - 15 => 'feet', - 16 => 'inches', - 17 => 'cm', - 18 => 'meters', - 19 => 'rpm', - 20 => 'degrees', - 21 => 'lux', + -1 => { unit => '' }, # none + 0 => { unit => 'other', nunit => 'count' }, + 1 => { unit => 'V', nunit => 'volt' }, # volt, + 2 => { unit => 'A', nunit => 'ampere' }, # amp, + 3 => { unit => 'W', nunit => 'watt' }, # watt + 4 => { unit => 'voltamp' }, + 5 => { unit => 'wattHour' }, + 6 => { unit => 'voltampHour' }, + 7 => { unit => 'C', nunit => 'celsius' }, # degreeC + 8 => { unit => 'Hz', nunit => 'hertz' }, # hertz + 9 => { unit => '%', nunit => 'percentage' }, # percent + 10 => { unit => 'meterpersec' }, + 11 => { unit => 'pascal' }, + 12 => { unit => 'psi' }, + 13 => { unit => 'g' }, + 14 => { unit => 'degreeF', nunit => 'fahrenheit' }, + 15 => { unit => 'feet' }, + 16 => { unit => 'inches' }, + 17 => { unit => 'cm' }, + 18 => { unit => 'meters' }, + 19 => { unit => 'rpm' }, + 20 => { unit => 'degrees' }, + 21 => { unit => 'lux' }, ); my %map_state = ( @@ -247,4 +247,4 @@ $thresholds = { ], }; -1; \ No newline at end of file +1; diff --git a/hardware/pdu/raritan/snmp/mode/components/sensor.pm b/hardware/pdu/raritan/snmp/mode/components/sensor.pm index 706e5c003..4949c1d36 100644 --- a/hardware/pdu/raritan/snmp/mode/components/sensor.pm +++ b/hardware/pdu/raritan/snmp/mode/components/sensor.pm @@ -74,7 +74,7 @@ sub check { } $self->{output}->output_add(long_msg => sprintf("'%s' %s state is '%s' [instance: %s, value: %s, unit: %s, label: %s]", $instance, $component, $result->{State}, - $instance, $value, $result->{Unit}, $result2->{Label})); + $instance, $value, $result->{Unit}->{unit}, $result2->{Label})); my $exit = $self->get_severity(section => $component, label => $value_type, instance => $instance, value => $result->{State}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { @@ -84,7 +84,7 @@ sub check { } if ($value =~ /[0-9]/) { - next if ($value =~ /^0$/ && $result->{Unit} eq ''); + next if ($value =~ /^0$/ && $result->{Unit}->{unit} eq ''); my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => $component, instance => $instance, value => $value); if ($checked == 0) { $result->{EnabledThresholds} = oct("0b". unpack('b*', $result->{EnabledThresholds})); @@ -114,15 +114,21 @@ sub check { if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("'%s' %s value is %s %s", - $instance, $component, $value, $result->{Unit})); + $instance, $component, $value, $result->{Unit}->{unit})); } - $self->{output}->perfdata_add(label => $instance . "_" . $component, unit => $result->{Unit}, - value => $value, - warning => $warn, - critical => $crit); + + my $nunit = (!defined($result->{Unit}->{nunit}) ? $result->{Unit}->{nunit} : lc($result->{Unit}->{unit})); + $self->{output}->perfdata_add( + label => $component, unit => $result->{Unit}->{unit}, + nlabel => 'hardware.sensor.' . $options{type} . '.' . lc($component) . '.' . $nunit, + instances => $instance, + value => $value, + warning => $warn, + critical => $crit + ); } } } } -1; \ No newline at end of file +1; diff --git a/hardware/pdu/raritan/snmp/mode/ocprotsensors.pm b/hardware/pdu/raritan/snmp/mode/ocprotsensors.pm index 9a8285a07..84e8ca213 100644 --- a/hardware/pdu/raritan/snmp/mode/ocprotsensors.pm +++ b/hardware/pdu/raritan/snmp/mode/ocprotsensors.pm @@ -80,9 +80,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } @@ -129,4 +128,4 @@ Example: --critical='powerQuality,.*,40' =back -=cut \ No newline at end of file +=cut diff --git a/hardware/pdu/raritan/snmp/mode/outletsensors.pm b/hardware/pdu/raritan/snmp/mode/outletsensors.pm index 782c5b0a5..dc6ba649b 100644 --- a/hardware/pdu/raritan/snmp/mode/outletsensors.pm +++ b/hardware/pdu/raritan/snmp/mode/outletsensors.pm @@ -80,9 +80,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } @@ -129,4 +128,4 @@ Example: --critical='powerQuality,.*,40' =back -=cut \ No newline at end of file +=cut diff --git a/hardware/pdu/schleifenbauer/gateway/snmp/mode/components/contact.pm b/hardware/pdu/schleifenbauer/gateway/snmp/mode/components/contact.pm new file mode 100644 index 000000000..24618c2f5 --- /dev/null +++ b/hardware/pdu/schleifenbauer/gateway/snmp/mode/components/contact.pm @@ -0,0 +1,82 @@ +# +# Copyright 2019 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 hardware::pdu::schleifenbauer::gateway::snmp::mode::components::contact; + +use strict; +use warnings; +use hardware::pdu::schleifenbauer::gateway::snmp::mode::components::resources qw($oid_pdumeasuresEntry $oid_deviceName $mapping); + +sub load {} + +sub check_contact { + my ($self, %options) = @_; + + my $description = $options{device_name}; + $description .= '.' . ((defined($options{sensor_name}) && $options{sensor_name} ne '') ? $options{sensor_name} : $options{num}); + + next if ($self->check_filter(section => 'contact', instance => $options{instance}, name => $description)); + $self->{components}->{contact}->{total}++; + $self->{output}->output_add(long_msg => sprintf("contact '%s' is %s [instance = %s]", + $description, $options{value}, $options{instance})); + + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'contact', instance => $options{instance}, name => $description, value => $options{value}); + + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Contact '%s' is %s %%", $description, $options{value})); + } + $self->{output}->perfdata_add( + label => 'contact', + nlabel => 'hardware.sensor.contact.count', + instances => [$options{device_name}, (defined($options{sensor_name}) && $options{sensor_name} ne '') ? $options{sensor_name} : $options{num}], + value => $options{value}, + warning => $warn, + critical => $crit, + min => 0, max => 100 + ); +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking contact"); + $self->{components}->{contact} = { name => 'contact', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'contact')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_deviceName}})) { + $oid =~ /^$oid_deviceName.(.*)$/; + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_pdumeasuresEntry}, instance => $instance); + + for (my $i = 1; $i <= 16; $i++) { + next if (!defined($result->{'sensor' . $i . 'Type'}) || $result->{'sensor' . $i . 'Type'} !~ /I/); + check_contact($self, + instance => $instance, + device_name => $self->{results}->{$oid_deviceName}->{$oid}, + num => $i, + value => $result->{'sensor' . $i . 'Value'}, + sensor_name => $result->{'sensor' . $i . 'Name'}, + ); + } + } +} + +1; diff --git a/hardware/pdu/schleifenbauer/gateway/snmp/mode/components/humidity.pm b/hardware/pdu/schleifenbauer/gateway/snmp/mode/components/humidity.pm new file mode 100644 index 000000000..ca609cd23 --- /dev/null +++ b/hardware/pdu/schleifenbauer/gateway/snmp/mode/components/humidity.pm @@ -0,0 +1,82 @@ +# +# Copyright 2019 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 hardware::pdu::schleifenbauer::gateway::snmp::mode::components::humidity; + +use strict; +use warnings; +use hardware::pdu::schleifenbauer::gateway::snmp::mode::components::resources qw($oid_pdumeasuresEntry $oid_deviceName $mapping); + +sub load {} + +sub check_humidity { + my ($self, %options) = @_; + + my $description = $options{device_name}; + $description .= '.' . ((defined($options{sensor_name}) && $options{sensor_name} ne '') ? $options{sensor_name} : $options{num}); + + next if ($self->check_filter(section => 'humidity', instance => $options{instance}, name => $description)); + $self->{components}->{humidity}->{total}++; + $self->{output}->output_add(long_msg => sprintf("humidity '%s' is %s %% [instance = %s]", + $description, $options{value}, $options{instance})); + + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'humidity', instance => $options{instance}, name => $description, value => $options{value}); + + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Humdity '%s' is %s %%", $description, $options{value})); + } + $self->{output}->perfdata_add( + label => 'humidity', unit => '%', + nlabel => 'hardware.sensor.humidity.percentage', + instances => [$options{device_name}, (defined($options{sensor_name}) && $options{sensor_name} ne '') ? $options{sensor_name} : $options{num}], + value => $options{value}, + warning => $warn, + critical => $crit, + min => 0, max => 100 + ); +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking humidity"); + $self->{components}->{humidity} = { name => 'humidity', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'humidity')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_deviceName}})) { + $oid =~ /^$oid_deviceName.(.*)$/; + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_pdumeasuresEntry}, instance => $instance); + + for (my $i = 1; $i <= 16; $i++) { + next if (!defined($result->{'sensor' . $i . 'Type'}) || $result->{'sensor' . $i . 'Type'} !~ /H/); + check_humidity($self, + instance => $instance, + device_name => $self->{results}->{$oid_deviceName}->{$oid}, + num => $i, + value => $result->{'sensor' . $i . 'Value'}, + sensor_name => $result->{'sensor' . $i . 'Name'}, + ); + } + } +} + +1; diff --git a/hardware/pdu/schleifenbauer/gateway/snmp/mode/components/resources.pm b/hardware/pdu/schleifenbauer/gateway/snmp/mode/components/resources.pm new file mode 100644 index 000000000..9fed5fd9b --- /dev/null +++ b/hardware/pdu/schleifenbauer/gateway/snmp/mode/components/resources.pm @@ -0,0 +1,90 @@ +# +# Copyright 2019 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 hardware::pdu::schleifenbauer::gateway::snmp::mode::components::resources; + +use strict; +use warnings; +use Exporter; + +our $oid_pdumeasuresEntry; +our $oid_deviceName; +our $mapping; + +our @ISA = qw(Exporter); +our @EXPORT_OK = qw($oid_pdumeasuresEntry $oid_deviceName $mapping); + +$oid_pdumeasuresEntry = '.1.3.6.1.4.1.31034.1.1.8.1'; +$oid_deviceName = '.1.3.6.1.4.1.31034.1.1.4.1.3'; + +$mapping = { + pduIntTemperature => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.3' }, + pduExtTemperature => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.4' }, + sensor1Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.7' }, + sensor1Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.8' }, + sensor1Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.9' }, + sensor2Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.10' }, + sensor2Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.11' }, + sensor2Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.12' }, + sensor3Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.13' }, + sensor3Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.14' }, + sensor3Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.15' }, + sensor4Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.16' }, + sensor4Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.17' }, + sensor4Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.18' }, + sensor5Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.19' }, + sensor5Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.20' }, + sensor5Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.21' }, + sensor6Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.22' }, + sensor6Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.23' }, + sensor6Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.24' }, + sensor7Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.25' }, + sensor7Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.26' }, + sensor7Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.27' }, + sensor8Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.28' }, + sensor8Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.29' }, + sensor8Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.30' }, + sensor9Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.31' }, + sensor9Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.32' }, + sensor9Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.33' }, + sensor10Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.34' }, + sensor10Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.35' }, + sensor10Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.36' }, + sensor11Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.37' }, + sensor11Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.38' }, + sensor11Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.39' }, + sensor12Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.40' }, + sensor12Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.41' }, + sensor12Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.42' }, + sensor13Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.43' }, + sensor13Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.44' }, + sensor13Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.45' }, + sensor14Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.46' }, + sensor14Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.47' }, + sensor14Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.48' }, + sensor15Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.49' }, + sensor15Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.50' }, + sensor15Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.51' }, + sensor16Type => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.52' }, + sensor16Value => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.53' }, + sensor16Name => { oid => '.1.3.6.1.4.1.31034.1.1.8.1.54' }, +}; + +1; diff --git a/hardware/pdu/schleifenbauer/gateway/snmp/mode/components/temperature.pm b/hardware/pdu/schleifenbauer/gateway/snmp/mode/components/temperature.pm new file mode 100644 index 000000000..e80e480ff --- /dev/null +++ b/hardware/pdu/schleifenbauer/gateway/snmp/mode/components/temperature.pm @@ -0,0 +1,96 @@ +# +# Copyright 2019 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 hardware::pdu::schleifenbauer::gateway::snmp::mode::components::temperature; + +use strict; +use warnings; +use hardware::pdu::schleifenbauer::gateway::snmp::mode::components::resources qw($oid_pdumeasuresEntry $oid_deviceName $mapping); + +sub load {} + +sub check_temperature { + my ($self, %options) = @_; + + my $description = $options{device_name}; + $description .= '.' . ((defined($options{sensor_name}) && $options{sensor_name} ne '') ? $options{sensor_name} : $options{num}); + + next if ($self->check_filter(section => 'temperature', instance => $options{instance}, name => $description)); + $self->{components}->{temperature}->{total}++; + $self->{output}->output_add(long_msg => sprintf("temperature '%s' is %s C [instance = %s]", + $description, $options{value}, $options{instance})); + + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $options{instance}, name => $description, value => $options{value}); + + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' is %s C", $description, $options{value})); + } + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.sensor.temperature.celsius', + instances => [$options{device_name}, (defined($options{sensor_name}) && $options{sensor_name} ne '') ? $options{sensor_name} : $options{num}], + value => $options{value}, + warning => $warn, + critical => $crit, + ); +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking temperature"); + $self->{components}->{temperature} = { name => 'temperature', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'temperature')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_deviceName}})) { + $oid =~ /^$oid_deviceName.(.*)$/; + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_pdumeasuresEntry}, instance => $instance); + + for (my $i = 1; $i <= 16; $i++) { + next if (!defined($result->{'sensor' . $i . 'Type'}) || $result->{'sensor' . $i . 'Type'} !~ /T/); + check_temperature($self, + instance => $instance, + device_name => $self->{results}->{$oid_deviceName}->{$oid}, + num => $i, + value => $result->{'sensor' . $i . 'Value'}, + sensor_name => $result->{'sensor' . $i . 'Name'}, + ); + } + + check_temperature($self, + instance => $instance, + device_name => $self->{results}->{$oid_deviceName}->{$oid}, + num => 0, + value => $result->{pduIntTemperature}, + sensor_name => 'Internal', + ) if ($result->{pduIntTemperature} != 0); + check_temperature($self, + instance => $instance, + device_name => $self->{results}->{$oid_deviceName}->{$oid}, + num => 0, + value => $result->{pduExtTemperature}, + sensor_name => 'External', + ) if ($result->{pduExtTemperature} != 0); + } +} + +1; diff --git a/hardware/pdu/schleifenbauer/gateway/snmp/mode/sensors.pm b/hardware/pdu/schleifenbauer/gateway/snmp/mode/sensors.pm new file mode 100644 index 000000000..c40b1c5fd --- /dev/null +++ b/hardware/pdu/schleifenbauer/gateway/snmp/mode/sensors.pm @@ -0,0 +1,101 @@ +# +# Copyright 2019 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 hardware::pdu::schleifenbauer::gateway::snmp::mode::sensors; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; +use hardware::pdu::schleifenbauer::gateway::snmp::mode::components::resources qw($oid_pdumeasuresEntry $oid_deviceName); + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(temperature|humidity|contact)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|humidity|contact)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{components_path} = 'hardware::pdu::schleifenbauer::gateway::snmp::mode::components'; + $self->{components_module} = ['humidity', 'temperature', 'contact']; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => [ + { oid => $oid_deviceName }, + { oid => $oid_pdumeasuresEntry }, + ]); +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check sensors. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'temperature', 'humidity', 'contact'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=temperature --filter=contact) +Can also exclude specific instance: --filter=temperature,1 + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=item B<--warning> + +Set warning threshold for 'temperature', 'humidity', 'contact' (syntax: type,regexp,threshold) +Example: --warning='temperature,.*,30' + +=item B<--critical> + +Set critical threshold for 'temperature', 'humidity', 'contact' (syntax: type,regexp,threshold) +Example: --warning='temperature,.*,50' + +=back + +=cut + diff --git a/hardware/pdu/schleifenbauer/gateway/snmp/plugin.pm b/hardware/pdu/schleifenbauer/gateway/snmp/plugin.pm new file mode 100644 index 000000000..8b3094580 --- /dev/null +++ b/hardware/pdu/schleifenbauer/gateway/snmp/plugin.pm @@ -0,0 +1,48 @@ +# +# Copyright 2019 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 hardware::pdu::schleifenbauer::gateway::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}} = ( + 'sensors' => 'hardware::pdu::schleifenbauer::gateway::snmp::mode::sensors', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Schleifenbauwer gateway in SNMP. + +=cut diff --git a/hardware/sensors/akcp/snmp/mode/components/humidity.pm b/hardware/sensors/akcp/snmp/mode/components/humidity.pm index d967b12eb..f8e5337e2 100644 --- a/hardware/sensors/akcp/snmp/mode/components/humidity.pm +++ b/hardware/sensors/akcp/snmp/mode/components/humidity.pm @@ -103,11 +103,15 @@ sub check_humidity { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Humdity '%s' is %s %%", $result->{HumidityDescription}, $result->{HumidityPercent})); } - $self->{output}->perfdata_add(label => 'humidity_' . $result->{HumidityDescription}, unit => '%', - value => $result->{HumidityPercent}, - warning => $warn, - critical => $crit, - min => 0, max => 100); + $self->{output}->perfdata_add( + label => 'humidity', unit => '%', + nlabel => 'hardware.sensor.humidity.percentage', + instances => $result->{HumidityDescription}, + value => $result->{HumidityPercent}, + warning => $warn, + critical => $crit, + min => 0, max => 100 + ); } } diff --git a/hardware/sensors/akcp/snmp/mode/components/resources.pm b/hardware/sensors/akcp/snmp/mode/components/resources.pm index 7054548b6..c194d8fa7 100644 --- a/hardware/sensors/akcp/snmp/mode/components/resources.pm +++ b/hardware/sensors/akcp/snmp/mode/components/resources.pm @@ -57,8 +57,8 @@ our @EXPORT_OK = qw(%map_default1_status %map_default2_status %map_online %map_d ); %map_degree_type = ( - 0 => 'F', - 1 => 'C', + 0 => { unit => 'F', unit_long => 'fahrenheit' }, + 1 => { unit => 'C', unit_long => 'celsius' }, ); 1; diff --git a/hardware/sensors/akcp/snmp/mode/components/temperature.pm b/hardware/sensors/akcp/snmp/mode/components/temperature.pm index b10c8dedf..dac736526 100644 --- a/hardware/sensors/akcp/snmp/mode/components/temperature.pm +++ b/hardware/sensors/akcp/snmp/mode/components/temperature.pm @@ -103,13 +103,16 @@ sub check_temperature { if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit2, - short_msg => sprintf("Temperature '%s' is %s %s", $result->{TempDescription}, $result->{TempDegree}, $result->{TempDegreeType})); + short_msg => sprintf("Temperature '%s' is %s %s", $result->{TempDescription}, $result->{TempDegree}, $result->{TempDegreeType}->{unit})); } - $self->{output}->perfdata_add(label => 'temperature_' . $result->{TempDescription}, unit => $result->{TempDegreeType}, - value => $result->{TempDegree}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temperature', unit => $result->{TempDegreeType}->{unit}, + nlabel => 'hardware.sensor.temperature.' . $result->{TempDegreeType}->{unit_long}, + instances => $result->{TempDescription}, + value => $result->{TempDegree}, + warning => $warn, + critical => $crit, + ); } } diff --git a/hardware/sensors/comet/p8000/snmp/mode/sensors.pm b/hardware/sensors/comet/p8000/snmp/mode/sensors.pm index 7b107b0cf..9035bc1f0 100644 --- a/hardware/sensors/comet/p8000/snmp/mode/sensors.pm +++ b/hardware/sensors/comet/p8000/snmp/mode/sensors.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_temperature_perfdata { my ($self, %options) = @_; @@ -62,14 +60,14 @@ sub custom_sensor_threshold { my ($self, %options) = @_; my $warn_limit; - if (defined($instance_mode->{option_results}->{'warning-' . $self->{label}}) && $instance_mode->{option_results}->{'warning-' . $self->{label}} ne '') { - $warn_limit = $instance_mode->{option_results}->{'warning-' . $self->{label}}; + if (defined($self->{instance_mode}->{option_results}->{'warning-' . $self->{label}}) && $self->{instance_mode}->{option_results}->{'warning-' . $self->{label}} ne '') { + $warn_limit = $self->{instance_mode}->{option_results}->{'warning-' . $self->{label}}; } $self->{perfdata}->threshold_validate(label => 'warning-' . $self->{label} . '_' . $self->{result_values}->{display_absolute}, value => $warn_limit); my $crit_limit = $self->{result_values}->{limit_lo_absolute} . ':' . $self->{result_values}->{limit_hi_absolute}; - if (defined($instance_mode->{option_results}->{'critical-' . $self->{label}}) && $instance_mode->{option_results}->{'critical-' . $self->{label}} ne '') { - $crit_limit = $instance_mode->{option_results}->{'critical-' . $self->{label}}; + if (defined($self->{instance_mode}->{option_results}->{'critical-' . $self->{label}}) && $self->{instance_mode}->{option_results}->{'critical-' . $self->{label}} ne '') { + $crit_limit = $self->{instance_mode}->{option_results}->{'critical-' . $self->{label}}; } $self->{perfdata}->threshold_validate(label => 'critical-' . $self->{label} . '_' . $self->{result_values}->{display_absolute}, value => $crit_limit); @@ -110,20 +108,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub prefix_channel_output { my ($self, %options) = @_; diff --git a/hardware/sensors/hwgste/snmp/mode/components/humidity.pm b/hardware/sensors/hwgste/snmp/mode/components/humidity.pm index 3cbd60924..161d562d5 100644 --- a/hardware/sensors/hwgste/snmp/mode/components/humidity.pm +++ b/hardware/sensors/hwgste/snmp/mode/components/humidity.pm @@ -24,8 +24,6 @@ use strict; use warnings; use hardware::sensors::hwgste::snmp::mode::components::resources qw($mapping); -my $oid_sensEntry = '.1.3.6.1.4.1.21796.4.1.3.1'; - sub load {} sub check { @@ -35,17 +33,19 @@ sub check { $self->{components}->{humidity} = {name => 'humidity', total => 0, skip => 0}; return if ($self->check_filter(section => 'humidity')); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_sensEntry}})) { - next if ($oid !~ /^$mapping->{sensState}->{oid}\.(.*)$/); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{ $mapping->{branch_sensors}->{$self->{branch}} }})) { + next if ($oid !~ /^$mapping->{$self->{branch}}->{sensState}->{oid}\.(.*)$/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_sensEntry}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping->{$self->{branch}}, results => $self->{results}->{ $mapping->{branch_sensors}->{$self->{branch}} }, instance => $instance); next if (!(defined($result->{sensUnit}) && $result->{sensUnit} eq '%')); next if ($self->check_filter(section => 'humidity', instance => $instance)); $self->{components}->{humidity}->{total}++; + $result->{sensValue} /= 10 if ($result->{sensValue} =~ /\d+/); + $self->{output}->output_add(long_msg => sprintf("humidity '%s' state is '%s' [instance: %s, value: %s]", - $result->{sensName}, $result->{sensState}, $instance, $result->{sensTemp})); + $result->{sensName}, $result->{sensState}, $instance, $result->{sensValue})); my $exit = $self->get_severity(section => 'humidity', label => 'default', instance => $instance, value => $result->{sensState}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { @@ -53,18 +53,22 @@ sub check { short_msg => sprintf("humidity '%s' state is '%s'", $result->{sensName}, $result->{sensState})); } - if ($result->{sensTemp} =~ /\d+/) { - my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'humidity', instance => $instance, value => $result->{sensTemp}); + if ($result->{sensValue} =~ /\d+/) { + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'humidity', instance => $instance, value => $result->{sensValue}); if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit2, - short_msg => sprintf("humidity '%s' value is %s %s", $result->{sensName}, $result->{sensTemp}, $result->{sensUnit})); + short_msg => sprintf("humidity '%s' value is %s %s", $result->{sensName}, $result->{sensValue}, $result->{sensUnit})); } - $self->{output}->perfdata_add(label => 'sensor_' . $result->{sensName}, unit => $result->{sensUnit}, - value => $result->{sensTemp}, - warning => $warn, - critical => $crit, min => 0, max => 100); + $self->{output}->perfdata_add( + label => 'sensor', unit => '%', + nlabel => 'hardware.sensor.humidity.percentage', + instances => $result->{sensName}, + value => $result->{sensValue}, + warning => $warn, + critical => $crit, min => 0, max => 100 + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/sensors/hwgste/snmp/mode/components/resources.pm b/hardware/sensors/hwgste/snmp/mode/components/resources.pm index cacaad748..7456e15bb 100644 --- a/hardware/sensors/hwgste/snmp/mode/components/resources.pm +++ b/hardware/sensors/hwgste/snmp/mode/components/resources.pm @@ -48,10 +48,22 @@ our @EXPORT_OK = qw($mapping); ); $mapping = { - sensName => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.2' }, - sensState => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.3', map => \%map_sens_state }, - sensTemp => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.4' }, - sensUnit => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.7', map => \%map_sens_unit }, + branch_sensors => { + hwgste => '.1.3.6.1.4.1.21796.4.1.3', + hwgste2 => '.1.3.6.1.4.1.21796.4.9.3', + }, + hwgste => { + sensName => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.2' }, + sensState => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.3', map => \%map_sens_state }, + sensValue => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.5' }, + sensUnit => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.7', map => \%map_sens_unit }, + }, + hwgste2 => { + sensName => { oid => '.1.3.6.1.4.1.21796.4.9.3.1.2' }, + sensState => { oid => '.1.3.6.1.4.1.21796.4.9.3.1.3', map => \%map_sens_state }, + sensValue => { oid => '.1.3.6.1.4.1.21796.4.9.3.1.5' }, + sensUnit => { oid => '.1.3.6.1.4.1.21796.4.9.3.1.7', map => \%map_sens_unit }, + }, }; -1; \ No newline at end of file +1; diff --git a/hardware/sensors/hwgste/snmp/mode/components/temperature.pm b/hardware/sensors/hwgste/snmp/mode/components/temperature.pm index 6deb17546..6602a09cc 100644 --- a/hardware/sensors/hwgste/snmp/mode/components/temperature.pm +++ b/hardware/sensors/hwgste/snmp/mode/components/temperature.pm @@ -24,8 +24,6 @@ use strict; use warnings; use hardware::sensors::hwgste::snmp::mode::components::resources qw($mapping); -my $oid_sensEntry = '.1.3.6.1.4.1.21796.4.1.3.1'; - sub load {} sub check { @@ -35,17 +33,19 @@ sub check { $self->{components}->{temperature} = {name => 'temperature', total => 0, skip => 0}; return if ($self->check_filter(section => 'temperature')); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_sensEntry}})) { - next if ($oid !~ /^$mapping->{sensState}->{oid}\.(.*)$/); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{ $mapping->{branch_sensors}->{$self->{branch}} }})) { + next if ($oid !~ /^$mapping->{$self->{branch}}->{sensState}->{oid}\.(.*)$/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_sensEntry}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping->{$self->{branch}}, results => $self->{results}->{ $mapping->{branch_sensors}->{$self->{branch}} }, instance => $instance); next if (!(defined($result->{sensUnit}) && $result->{sensUnit} =~ /C|F|K/i)); next if ($self->check_filter(section => 'temperature', instance => $instance)); $self->{components}->{temperature}->{total}++; + $result->{sensValue} /= 10 if ($result->{sensValue} =~ /\d+/); + $self->{output}->output_add(long_msg => sprintf("temperature '%s' state is '%s' [instance: %s, value: %s]", - $result->{sensName}, $result->{sensState}, $instance, $result->{sensTemp})); + $result->{sensName}, $result->{sensState}, $instance, $result->{sensValue})); my $exit = $self->get_severity(section => 'temperature', label => 'default', instance => $instance, value => $result->{sensState}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { @@ -53,18 +53,26 @@ sub check { short_msg => sprintf("temperature '%s' state is '%s'", $result->{sensName}, $result->{sensState})); } - if ($result->{sensTemp} =~ /\d+/) { - my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{sensTemp}); + if ($result->{sensValue} =~ /\d+/) { + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{sensValue}); if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit2, - short_msg => sprintf("temperature '%s' value is %s %s", $result->{sensName}, $result->{sensTemp}, $result->{sensUnit})); + short_msg => sprintf("temperature '%s' value is %s %s", $result->{sensName}, $result->{sensValue}, $result->{sensUnit})); } - $self->{output}->perfdata_add(label => 'sensor_' . $result->{sensName}, unit => $result->{sensUnit}, - value => $result->{sensTemp}, - warning => $warn, - critical => $crit); + + my $nunit = 'celsius'; + $nunit = 'fahrenheit' if ($result->{sensUnit} =~ /F/i); + $nunit = 'kelvin' if ($result->{sensUnit} =~ /K/i); + $self->{output}->perfdata_add( + label => 'sensor', unit => $result->{sensUnit}, + nlabel => 'hardware.sensor.temperature.' . $nunit, + instances => $result->{sensName}, + value => $result->{sensValue}, + warning => $warn, + critical => $crit + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/sensors/hwgste/snmp/mode/sensors.pm b/hardware/sensors/hwgste/snmp/mode/sensors.pm index 1f99d437e..0d681701a 100644 --- a/hardware/sensors/hwgste/snmp/mode/sensors.pm +++ b/hardware/sensors/hwgste/snmp/mode/sensors.pm @@ -24,6 +24,7 @@ use base qw(centreon::plugins::templates::hardware); use strict; use warnings; +use hardware::sensors::hwgste::snmp::mode::components::resources qw($mapping); sub set_system { my ($self, %options) = @_; @@ -52,9 +53,14 @@ sub snmp_execute { my ($self, %options) = @_; $self->{snmp} = $options{snmp}; - my $oid_sensEntry = '.1.3.6.1.4.1.21796.4.1.3.1'; - push @{$self->{request}}, { oid => $oid_sensEntry }; - $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); + $self->{results} = $self->{snmp}->get_multiple_table( + oids => [{ oid => $mapping->{branch_sensors}->{hwgste} }, { oid => $mapping->{branch_sensors}->{hwgste2} }] + ); + $self->{branch} = 'hwgste'; + if (defined($self->{results}->{ $mapping->{branch_sensors}->{hwgste2} }) && + scalar(keys %{$self->{results}->{ $mapping->{branch_sensors}->{hwgste2} }}) > 0) { + $self->{branch} = 'hwgste2'; + } } sub new { @@ -63,9 +69,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } diff --git a/hardware/sensors/jacarta/snmp/mode/components/humidity.pm b/hardware/sensors/jacarta/snmp/mode/components/humidity.pm index b0d723a4d..a9072e295 100644 --- a/hardware/sensors/jacarta/snmp/mode/components/humidity.pm +++ b/hardware/sensors/jacarta/snmp/mode/components/humidity.pm @@ -98,12 +98,16 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Humdity '%s' is %s %%", $result->{isDeviceMonitorHumidityName}, $result->{isDeviceMonitorHumidity})); } - $self->{output}->perfdata_add(label => 'humidity_' . $result->{isDeviceMonitorHumidityName}, unit => '%', - value => $result->{isDeviceMonitorHumidity}, - warning => $warn, - critical => $crit, - min => 0, max => 100); + $self->{output}->perfdata_add( + label => 'humidity', unit => '%', + nlabel => 'hardware.humidity.percentage', + instances => $result->{isDeviceMonitorHumidityName}, + value => $result->{isDeviceMonitorHumidity}, + warning => $warn, + critical => $crit, + min => 0, max => 100 + ); } } -1; \ No newline at end of file +1; diff --git a/hardware/sensors/jacarta/snmp/mode/components/temperature.pm b/hardware/sensors/jacarta/snmp/mode/components/temperature.pm index 348a1b38e..34261f5d4 100644 --- a/hardware/sensors/jacarta/snmp/mode/components/temperature.pm +++ b/hardware/sensors/jacarta/snmp/mode/components/temperature.pm @@ -99,12 +99,15 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Temperature '%s' is %s %s", $result->{isDeviceMonitorTemperatureName}, $result->{isDeviceMonitorTemperature}, $self->{temperature_unit})); } - $self->{output}->perfdata_add(label => 'temperature_' . $result->{isDeviceMonitorTemperatureName}, unit => $self->{temperature_unit}, - value => $result->{isDeviceMonitorTemperature}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temperature', unit => $self->{temperature_unit}, + nlabel => 'hardware.temperature.' . (($self->{temperature_unit} eq 'C') ? 'celsius' : 'fahrenheit'), + instances => $result->{isDeviceMonitorTemperatureName}, + value => $result->{isDeviceMonitorTemperature}, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1; diff --git a/hardware/sensors/jacarta/snmp/mode/sensors.pm b/hardware/sensors/jacarta/snmp/mode/sensors.pm index 1ee692a3f..5b450f2f5 100644 --- a/hardware/sensors/jacarta/snmp/mode/sensors.pm +++ b/hardware/sensors/jacarta/snmp/mode/sensors.pm @@ -72,9 +72,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } @@ -122,4 +121,4 @@ Example: --warning='temperature,.*,50' =back -=cut \ No newline at end of file +=cut diff --git a/hardware/sensors/netbotz/snmp/mode/components/airflow.pm b/hardware/sensors/netbotz/snmp/mode/components/airflow.pm index 961f23342..0a89aa3c5 100644 --- a/hardware/sensors/netbotz/snmp/mode/components/airflow.pm +++ b/hardware/sensors/netbotz/snmp/mode/components/airflow.pm @@ -72,12 +72,15 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Air flow '%s' is %s m/min", $label, $result->{airFlowSensorValue})); } - $self->{output}->perfdata_add(label => 'airflow_' . $label, unit => 'm/min', - value => $result->{airFlowSensorValue}, - warning => $warn, - critical => $crit, min => 0 - ); + $self->{output}->perfdata_add( + label => 'airflow', unit => 'm/min', + nlabel => 'hardware.sensor.airflow.cubicmeterperminute', + instances => $label, + value => $result->{airFlowSensorValue}, + warning => $warn, + critical => $crit, min => 0 + ); } } -1; \ No newline at end of file +1; diff --git a/hardware/sensors/netbotz/snmp/mode/components/dewpoint.pm b/hardware/sensors/netbotz/snmp/mode/components/dewpoint.pm index ba2d96224..0bc9a1436 100644 --- a/hardware/sensors/netbotz/snmp/mode/components/dewpoint.pm +++ b/hardware/sensors/netbotz/snmp/mode/components/dewpoint.pm @@ -72,12 +72,15 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Dew point '%s' is %s C", $label, $result->{dewPointSensorValue})); } - $self->{output}->perfdata_add(label => 'dewpoint_' . $label, unit => 'C', - value => $result->{dewPointSensorValue}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'dewpoint', unit => 'C', + nlabel => 'hardware.sensor.dewpoint.celsius', + instances => $label, + value => $result->{dewPointSensorValue}, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1; diff --git a/hardware/sensors/netbotz/snmp/mode/components/humidity.pm b/hardware/sensors/netbotz/snmp/mode/components/humidity.pm index 7cb49073b..e380c35f5 100644 --- a/hardware/sensors/netbotz/snmp/mode/components/humidity.pm +++ b/hardware/sensors/netbotz/snmp/mode/components/humidity.pm @@ -72,12 +72,15 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Humidity '%s' is %s %%", $label, $result->{humiSensorValue})); } - $self->{output}->perfdata_add(label => 'humidity_' . $label, unit => '%', - value => $result->{humiSensorValue}, - warning => $warn, - critical => $crit, min => 0, max => 100 - ); + $self->{output}->perfdata_add( + label => 'humidity', unit => '%', + nlabel => 'hardware.sensor.humidity.percentage', + instances => $label, + value => $result->{humiSensorValue}, + warning => $warn, + critical => $crit, min => 0, max => 100 + ); } } -1; \ No newline at end of file +1; diff --git a/hardware/sensors/netbotz/snmp/mode/components/temperature.pm b/hardware/sensors/netbotz/snmp/mode/components/temperature.pm index 30312cc5f..ff22051db 100644 --- a/hardware/sensors/netbotz/snmp/mode/components/temperature.pm +++ b/hardware/sensors/netbotz/snmp/mode/components/temperature.pm @@ -72,12 +72,15 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Temperature '%s' is %s C", $label, $result->{tempSensorValue})); } - $self->{output}->perfdata_add(label => 'temperature_' . $label, unit => 'C', - value => $result->{tempSensorValue}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.sensor.temperature.celsius', + instances => $label, + value => $result->{tempSensorValue}, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1; diff --git a/hardware/sensors/sensorip/snmp/mode/components/humidity.pm b/hardware/sensors/sensorip/snmp/mode/components/humidity.pm index 22280ac60..a4a7fc38d 100644 --- a/hardware/sensors/sensorip/snmp/mode/components/humidity.pm +++ b/hardware/sensors/sensorip/snmp/mode/components/humidity.pm @@ -104,14 +104,17 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Humidity sensor '%s' is %s %%", $result->{sensorProbeHumidityDescription}, $result->{sensorProbeHumidityPercent})); } - $self->{output}->perfdata_add(label => 'humdity_' . $instance, unit => '%', - value => $result->{sensorProbeHumidityPercent}, - warning => $warn, - critical => $crit, - min => 0, max => 100 - ); + $self->{output}->perfdata_add( + label => 'humdity', unit => '%', + nlabel => 'hardware.sensor.humidity.percentage', + instances => $instance, + value => $result->{sensorProbeHumidityPercent}, + warning => $warn, + critical => $crit, + min => 0, max => 100 + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/sensors/sensorip/snmp/mode/components/temperature.pm b/hardware/sensors/sensorip/snmp/mode/components/temperature.pm index 270a6c8af..dd108cb4c 100644 --- a/hardware/sensors/sensorip/snmp/mode/components/temperature.pm +++ b/hardware/sensors/sensorip/snmp/mode/components/temperature.pm @@ -104,13 +104,16 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature sensor '%s' is %s degree centigrade", $result->{sensorProbeTempDescription}, $result->{sensorProbeTempDegree})); } - $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', - value => $result->{sensorProbeTempDegree}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.sensor.temperature.celsius', + instances => $instance, + value => $result->{sensorProbeTempDegree}, + warning => $warn, + critical => $crit, + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/sensors/sensormetrix/em01/web/mode/contact.pm b/hardware/sensors/sensormetrix/em01/web/mode/contact.pm index 21963cf7b..65d7cbe43 100644 --- a/hardware/sensors/sensormetrix/em01/web/mode/contact.pm +++ b/hardware/sensors/sensormetrix/em01/web/mode/contact.pm @@ -32,8 +32,7 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { + $options{options}->add_options(arguments => { "hostname:s" => { name => 'hostname' }, "port:s" => { name => 'port', }, "proto:s" => { name => 'proto' }, @@ -42,15 +41,13 @@ sub new { "basic" => { name => 'basic' }, "username:s" => { name => 'username' }, "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, "warning" => { name => 'warning' }, "critical" => { name => 'critical' }, "closed" => { name => 'closed' }, "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + }); $self->{status} = { closed => 'ok', opened => 'ok' }; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -112,10 +109,6 @@ IP Addr/FQDN of the webserver host Port used by Apache -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Specify https if needed @@ -148,10 +141,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning> Warning if door is opened (can set --close for closed door) diff --git a/hardware/sensors/sensormetrix/em01/web/mode/flood.pm b/hardware/sensors/sensormetrix/em01/web/mode/flood.pm index c73364b09..f63a5bf85 100644 --- a/hardware/sensors/sensormetrix/em01/web/mode/flood.pm +++ b/hardware/sensors/sensormetrix/em01/web/mode/flood.pm @@ -32,25 +32,22 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "warning" => { name => 'warning' }, - "critical" => { name => 'critical' }, - "dry" => { name => 'dry' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "warning" => { name => 'warning' }, + "critical" => { name => 'critical' }, + "dry" => { name => 'dry' }, + "timeout:s" => { name => 'timeout' }, + }); $self->{status} = { dry => 'ok', wet => 'ok' }; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -112,10 +109,6 @@ IP Addr/FQDN of the webserver host Port used by Apache -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Specify https if needed @@ -148,10 +141,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning> Warning if flood sensor is wet (can set --dry for dry sensor) diff --git a/hardware/sensors/sensormetrix/em01/web/mode/humidity.pm b/hardware/sensors/sensormetrix/em01/web/mode/humidity.pm index 85583d4d8..4bc058897 100644 --- a/hardware/sensors/sensormetrix/em01/web/mode/humidity.pm +++ b/hardware/sensors/sensormetrix/em01/web/mode/humidity.pm @@ -32,23 +32,20 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/index.htm?em" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/index.htm?em" }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "timeout:s" => { name => 'timeout' }, + }); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -113,10 +110,6 @@ IP Addr/FQDN of the webserver host Port used by Apache -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Specify https if needed @@ -149,10 +142,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning> Warning Threshold for Humidity diff --git a/hardware/sensors/sensormetrix/em01/web/mode/illumination.pm b/hardware/sensors/sensormetrix/em01/web/mode/illumination.pm index a714ab4f3..021fb8642 100644 --- a/hardware/sensors/sensormetrix/em01/web/mode/illumination.pm +++ b/hardware/sensors/sensormetrix/em01/web/mode/illumination.pm @@ -32,8 +32,7 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { + $options{options}->add_options(arguments => { "hostname:s" => { name => 'hostname' }, "port:s" => { name => 'port', }, "proto:s" => { name => 'proto' }, @@ -42,13 +41,11 @@ sub new { "basic" => { name => 'basic' }, "username:s" => { name => 'username' }, "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, "warning:s" => { name => 'warning' }, "critical:s" => { name => 'critical' }, "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + }); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -113,10 +110,6 @@ IP Addr/FQDN of the webserver host Port used by Apache -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Specify https if needed @@ -149,10 +142,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning> Warning Threshold for Illumination diff --git a/hardware/sensors/sensormetrix/em01/web/mode/temperature.pm b/hardware/sensors/sensormetrix/em01/web/mode/temperature.pm index fd9528309..770171e59 100644 --- a/hardware/sensors/sensormetrix/em01/web/mode/temperature.pm +++ b/hardware/sensors/sensormetrix/em01/web/mode/temperature.pm @@ -32,23 +32,20 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/index.htm?em" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/index.htm?em" }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "timeout:s" => { name => 'timeout' }, + }); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -112,10 +109,6 @@ IP Addr/FQDN of the webserver host Port used by Apache -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Specify https if needed @@ -148,10 +141,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning> Warning Threshold for Temperature diff --git a/hardware/sensors/sensormetrix/em01/web/mode/thermistor.pm b/hardware/sensors/sensormetrix/em01/web/mode/thermistor.pm index 9a5acec4f..3eb3586d5 100644 --- a/hardware/sensors/sensormetrix/em01/web/mode/thermistor.pm +++ b/hardware/sensors/sensormetrix/em01/web/mode/thermistor.pm @@ -32,23 +32,20 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/index.htm?eR" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/index.htm?eR" }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "timeout:s" => { name => 'timeout' }, + }); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -112,10 +109,6 @@ IP Addr/FQDN of the webserver host Port used by Apache -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Specify https if needed @@ -148,10 +141,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning> Warning Threshold for Thermistor Temperature diff --git a/hardware/sensors/sensormetrix/em01/web/mode/voltage.pm b/hardware/sensors/sensormetrix/em01/web/mode/voltage.pm index 4c8cd8803..c8365d86b 100644 --- a/hardware/sensors/sensormetrix/em01/web/mode/voltage.pm +++ b/hardware/sensors/sensormetrix/em01/web/mode/voltage.pm @@ -32,23 +32,20 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/index.htm?ev" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', }, + "proto:s" => { name => 'proto' }, + "urlpath:s" => { name => 'url_path', default => "/index.htm?ev" }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "timeout:s" => { name => 'timeout' }, + }); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -113,10 +110,6 @@ IP Addr/FQDN of the webserver host Port used by Apache -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Specify https if needed @@ -149,10 +142,6 @@ Specify this option if you access server-status page over hidden basic authentic Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--warning> Warning Threshold for Voltage diff --git a/hardware/server/dell/cmc/snmp/mode/components/chassis.pm b/hardware/server/dell/cmc/snmp/mode/components/chassis.pm index 483d013bf..a36ca0114 100644 --- a/hardware/server/dell/cmc/snmp/mode/components/chassis.pm +++ b/hardware/server/dell/cmc/snmp/mode/components/chassis.pm @@ -25,8 +25,8 @@ use warnings; # In MIB 'DELL-RAC-MIB' my $mapping = { - drsWattsReading => { oid => '.1.3.6.1.4.1.674.10892.2.4.1.1.13', section => 'power', label => 'power', unit => 'W' }, - drsAmpsReading => { oid => '.1.3.6.1.4.1.674.10892.2.4.1.1.14', section => 'current', label => 'current', unit => 'A' }, + drsWattsReading => { oid => '.1.3.6.1.4.1.674.10892.2.4.1.1.13', section => 'power', label => 'power', unit => 'watt' }, + drsAmpsReading => { oid => '.1.3.6.1.4.1.674.10892.2.4.1.1.14', section => 'current', label => 'current', unit => 'ampere' }, }; my $oid_drsCMCPowerTableEntrydrsCMCPowerTableEntry = '.1.3.6.1.4.1.674.10892.2.4.1.1'; @@ -63,12 +63,16 @@ sub check { short_msg => sprintf("Chassis '%s' %s is %s%s", $instance, $mapping->{$probe}->{section}, $result->{$probe}, $mapping->{$probe}->{unit})); } - $self->{output}->perfdata_add(label => 'chassis_' . $mapping->{$probe}->{label} . '_' . $instance, unit => $mapping->{$probe}->{unit}, - value => $result->{$probe}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'chassis_' . $mapping->{$probe}->{label}, unit => $mapping->{$probe}->{unit}, + nlabel => 'hardware.chassis.' . $mapping->{$probe}->{label} . '.' . $mapping->{$probe}->{unit}, + instances => $instance, + value => $result->{$probe}, + warning => $warn, + critical => $crit + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/server/dell/cmc/snmp/mode/components/psu.pm b/hardware/server/dell/cmc/snmp/mode/components/psu.pm index 5cd98df3b..a0d15df09 100644 --- a/hardware/server/dell/cmc/snmp/mode/components/psu.pm +++ b/hardware/server/dell/cmc/snmp/mode/components/psu.pm @@ -33,9 +33,9 @@ my %map_psu_capable = ( my $mapping = { drsPSULocation => { oid => '.1.3.6.1.4.1.674.10892.2.4.2.1.3' }, drsPSUMonitoringCapable => { oid => '.1.3.6.1.4.1.674.10892.2.4.2.1.4', map => \%map_psu_capable }, - drsPSUVoltsReading => { oid => '.1.3.6.1.4.1.674.10892.2.4.2.1.5', section => 'voltage', label => 'voltage', unit => 'V' }, - drsPSUAmpsReading => { oid => '.1.3.6.1.4.1.674.10892.2.4.2.1.6', section => 'current', label => 'current', unit => 'A' }, - drsPSUWattsReading => { oid => '.1.3.6.1.4.1.674.10892.2.4.2.1.7', section => 'power', label => 'power', unit => 'W' }, + drsPSUVoltsReading => { oid => '.1.3.6.1.4.1.674.10892.2.4.2.1.5', section => 'voltage', label => 'voltage', unit => 'volt' }, + drsPSUAmpsReading => { oid => '.1.3.6.1.4.1.674.10892.2.4.2.1.6', section => 'current', label => 'current', unit => 'ampere' }, + drsPSUWattsReading => { oid => '.1.3.6.1.4.1.674.10892.2.4.2.1.7', section => 'power', label => 'power', unit => 'watt' }, }; my $oid_drsCMCPSUTableEntry = '.1.3.6.1.4.1.674.10892.2.4.2.1'; @@ -73,12 +73,16 @@ sub check { short_msg => sprintf("Power supply '%s' %s is %s%s", $result->{drsPSULocation}, $mapping->{$probe}->{section}, $result->{$probe}, $mapping->{$probe}->{unit})); } - $self->{output}->perfdata_add(label => 'psu_' . $mapping->{$probe}->{label} . '_' . $instance, unit => $mapping->{$probe}->{unit}, - value => $result->{$probe}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'psu_' . $mapping->{$probe}->{label}, unit => $mapping->{$probe}->{unit}, + nlabel => 'hardware.' . $mapping->{$probe}->{label} . '.' . $mapping->{$probe}->{unit}, + instances => $instance, + value => $result->{$probe}, + warning => $warn, + critical => $crit + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/server/dell/cmc/snmp/mode/components/temperature.pm b/hardware/server/dell/cmc/snmp/mode/components/temperature.pm index 8086d65ef..30aa9e7b1 100644 --- a/hardware/server/dell/cmc/snmp/mode/components/temperature.pm +++ b/hardware/server/dell/cmc/snmp/mode/components/temperature.pm @@ -25,9 +25,9 @@ use warnings; # In MIB 'DELL-RAC-MIB' my $mapping = { - drsChassisFrontPanelAmbientTemperature => { oid => '.1.3.6.1.4.1.674.10892.2.3.1.10', instance => 'chassis', label => 'temp_chassis', descr => 'Chassis Ambient temperature' }, - drsCMCAmbientTemperature => { oid => '.1.3.6.1.4.1.674.10892.2.3.1.11', instance => 'ambient', label => 'temp_ambient', descr => 'CMC Ambient temperarture' }, - drsCMCProcessorTemperature => { oid => '.1.3.6.1.4.1.674.10892.2.3.1.12', instance => 'processor', label => 'temp_processor', descr => 'Processor temperature' }, + drsChassisFrontPanelAmbientTemperature => { oid => '.1.3.6.1.4.1.674.10892.2.3.1.10', instance => 'chassis', descr => 'Chassis Ambient temperature' }, + drsCMCAmbientTemperature => { oid => '.1.3.6.1.4.1.674.10892.2.3.1.11', instance => 'ambient', descr => 'CMC Ambient temperarture' }, + drsCMCProcessorTemperature => { oid => '.1.3.6.1.4.1.674.10892.2.3.1.12', instance => 'processor', descr => 'Processor temperature' }, }; my $oid_drsChassisStatusGroup = '.1.3.6.1.4.1.674.10892.2.3'; @@ -61,11 +61,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("%s is %sC", $mapping->{$probe}->{descr}, $result->{$probe})); } - $self->{output}->perfdata_add(label => $mapping->{$probe}->{label}, unit => 'C', - value => $result->{$probe}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $mapping->{$probe}->{instance}, + value => $result->{$probe}, + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/hardware/server/dell/idrac/snmp/mode/components/amperage.pm b/hardware/server/dell/idrac/snmp/mode/components/amperage.pm index caad1f879..8eb118bf4 100644 --- a/hardware/server/dell/idrac/snmp/mode/components/amperage.pm +++ b/hardware/server/dell/idrac/snmp/mode/components/amperage.pm @@ -110,13 +110,16 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Amperage '%s' is %s %s", $result->{amperageProbeLocationName}, $result->{amperageProbeReading}, $unit)); } - $self->{output}->perfdata_add(label => 'amperage_' . $result->{amperageProbeLocationName}, unit => $unit, - value => $result->{amperageProbeReading}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'amperage', unit => $unit, + nlabel => 'hardware.probe.amperage.' . ($unit eq 'A' ? 'ampere' : 'watt'), + instances => $result->{amperageProbeLocationName}, + value => $result->{amperageProbeReading}, + warning => $warn, + critical => $crit, + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/server/dell/idrac/snmp/mode/components/coolingdevice.pm b/hardware/server/dell/idrac/snmp/mode/components/coolingdevice.pm index 327ea0c56..558d1763b 100644 --- a/hardware/server/dell/idrac/snmp/mode/components/coolingdevice.pm +++ b/hardware/server/dell/idrac/snmp/mode/components/coolingdevice.pm @@ -101,13 +101,16 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Cooling device '%s' is %s rpm", $result->{coolingDeviceLocationName}, $result->{coolingDeviceReading})); } - $self->{output}->perfdata_add(label => 'fan_' . $result->{coolingDeviceLocationName}, unit => 'rpm', - value => $result->{coolingDeviceReading}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $result->{coolingDeviceLocationName}, + value => $result->{coolingDeviceReading}, + warning => $warn, + critical => $crit, + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/server/dell/idrac/snmp/mode/components/temperature.pm b/hardware/server/dell/idrac/snmp/mode/components/temperature.pm index 8964fdc1f..ea81c9cac 100644 --- a/hardware/server/dell/idrac/snmp/mode/components/temperature.pm +++ b/hardware/server/dell/idrac/snmp/mode/components/temperature.pm @@ -109,13 +109,16 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s degree centigrade", $result->{temperatureProbeLocationName}, $result->{temperatureProbeReading})); } - $self->{output}->perfdata_add(label => 'temp_' . $result->{temperatureProbeLocationName}, unit => 'C', - value => $result->{temperatureProbeReading}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.probe.temperature.celsius', + instances => $result->{temperatureProbeLocationName}, + value => $result->{temperatureProbeReading}, + warning => $warn, + critical => $crit, + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/server/dell/idrac/snmp/mode/components/voltage.pm b/hardware/server/dell/idrac/snmp/mode/components/voltage.pm index 0ba98b994..fd37b8ad3 100644 --- a/hardware/server/dell/idrac/snmp/mode/components/voltage.pm +++ b/hardware/server/dell/idrac/snmp/mode/components/voltage.pm @@ -101,13 +101,16 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Voltage '%s' is %s V", $result->{voltageProbeLocationName}, $result->{voltageProbeReading})); } - $self->{output}->perfdata_add(label => 'voltage_' . $result->{voltageProbeLocationName}, unit => 'V', - value => $result->{voltageProbeReading}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'voltage', unit => 'V', + nlabel => 'hardware.probe.voltage.volt', + instances => $result->{voltageProbeLocationName}, + value => $result->{voltageProbeReading}, + warning => $warn, + critical => $crit, + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/server/dell/idrac/snmp/mode/globalstatus.pm b/hardware/server/dell/idrac/snmp/mode/globalstatus.pm index 247d0b163..19a3733c8 100644 --- a/hardware/server/dell/idrac/snmp/mode/globalstatus.pm +++ b/hardware/server/dell/idrac/snmp/mode/globalstatus.pm @@ -20,19 +20,66 @@ package hardware::server::dell::idrac::snmp::mode::globalstatus; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); -my %states = ( - 1 => ['other', 'WARNING'], - 2 => ['unknown', 'UNKNOWN'], - 3 => ['ok', 'OK'], - 4 => ['non critical', 'WARNING'], - 5 => ['critical', 'CRITICAL'], - 6 => ['nonRecoverable', 'WARNING'], -); +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("global status is '%s'", $self->{result_values}->{status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + return 0; +} + +sub custom_storage_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("storage status is '%s'", $self->{result_values}->{status}); + return $msg; +} + +sub custom_storage_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_storage_status'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, message_separator => ', ', cb_prefix_output => 'prefix_global_output', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' } ], + 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 => \&catalog_status_threshold, + } + }, + { label => 'storage-status', threshold => 0, set => { + key_values => [ { name => 'storage_status' } ], + closure_custom_calc => $self->can('custom_storage_status_calc'), + closure_custom_output => $self->can('custom_storage_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + ]; +} sub new { my ($class, %options) = @_; @@ -40,41 +87,74 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + "unknown-status:s" => { name => 'unknown_status', default => '%{status} =~ /^unknown/i' }, + "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /nonRecoverable|non critical|other/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /^critical/i' }, + "unknown-storage-status:s" => { name => 'unknown_storage_status', default => '%{status} =~ /^unknown/i' }, + "warning-storage-status:s" => { name => 'warning_storage_status', default => '%{status} =~ /nonRecoverable|non critical|other/i' }, + "critical-storage-status:s" => { name => 'critical_storage_status', default => '%{status} =~ /^critical/i' }, + }); return $self; } -sub check_options { + +sub prefix_global_output { my ($self, %options) = @_; - $self->SUPER::init(%options); + + return "Card '" . $self->{global}->{display} . "' : "; } -sub run { +sub check_options { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; + $self->SUPER::check_options(%options); + $self->change_macros(macros => [ + 'unknown_storage_status', 'warning_storage_status', 'critical_storage_status', + 'unknown_status', 'warning_status', 'critical_status', + ]); +} + +my %states = ( + 1 => 'other', + 2 => 'unknown', + 3 => 'ok', + 4 => 'non critical', + 5 => 'critical', + 6 => 'nonRecoverable', +); + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_racShortName = '.1.3.6.1.4.1.674.10892.5.1.1.2.0'; + my $oid_racVersion = '.1.3.6.1.4.1.674.10892.5.1.1.5.0'; my $oid_drsGlobalSystemStatus = '.1.3.6.1.4.1.674.10892.2.2.1.0'; my $oid_globalSystemStatus = '.1.3.6.1.4.1.674.10892.5.2.1.0'; my $oid_globalStorageStatus = '.1.3.6.1.4.1.674.10892.5.2.3.0'; - my $result = $self->{snmp}->get_leef(oids => [$oid_drsGlobalSystemStatus, $oid_globalSystemStatus, $oid_globalStorageStatus], nothing_quit => 1); + my $result = $options{snmp}->get_leef(oids => [ + $oid_racShortName, $oid_racVersion, $oid_drsGlobalSystemStatus, $oid_globalSystemStatus, $oid_globalStorageStatus + ], nothing_quit => 1); + my ($global_status, $storage_status); if (defined($result->{$oid_globalSystemStatus})) { - $self->{output}->output_add(severity => ${$states{$result->{$oid_globalSystemStatus}}}[1], - short_msg => sprintf("Overall global status is '%s'", - ${$states{$result->{$oid_globalSystemStatus}}}[0])); - $self->{output}->output_add(severity => ${$states{$result->{$oid_globalStorageStatus}}}[1], - short_msg => sprintf("Overall storage status is '%s'", - ${$states{$result->{$oid_globalStorageStatus}}}[0])); + $global_status = $states{$result->{$oid_globalSystemStatus}}; + $storage_status = defined($result->{$oid_globalStorageStatus}) ? $states{$result->{$oid_globalStorageStatus}} : undef; } else { - $self->{output}->output_add(severity => ${$states{$result->{$oid_drsGlobalSystemStatus}}}[1], - short_msg => sprintf("Overall global status is '%s'", - ${$states{$result->{$oid_drsGlobalSystemStatus}}}[0])); - } - $self->{output}->display(); - $self->{output}->exit(); + $global_status = $states{$result->{$oid_drsGlobalSystemStatus}}; + } + + my $display = 'unknown'; + $display = $result->{$oid_racShortName} + if (defined($result->{$oid_racShortName})); + $display .= '.' . $result->{$oid_racVersion} + if (defined($result->{$oid_racVersion})); + $self->{global} = { + display => $display, + status => $global_status, + storage_status => $storage_status, + }; } 1; @@ -87,6 +167,36 @@ Check the overall status of iDrac card. =over 8 +=item B<--unknown-status> + +Set warning threshold for status (Default: '%{status} =~ /^unknown/i'). +Can used special variables like: %{status} + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{status} =~ /nonRecoverable|non critical|other/i'). +Can used special variables like: %{status} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /^critical/i'). +Can used special variables like: %{status} + +=item B<--unknown-storage-status> + +Set warning threshold for status (Default: '%{status} =~ /^unknown/i'). +Can used special variables like: %{status} + +=item B<--warning-storage-status> + +Set warning threshold for status (Default: '%{status} =~ /nonRecoverable|non critical|other/i'). +Can used special variables like: %{status} + +=item B<--critical-storage-status> + +Set critical threshold for status (Default: '%{status} =~ /^critical/i'). +Can used special variables like: %{status} + =back =cut diff --git a/hardware/server/dell/openmanage/snmp/mode/components/fan.pm b/hardware/server/dell/openmanage/snmp/mode/components/fan.pm index a826ef9c0..815ed3fca 100644 --- a/hardware/server/dell/openmanage/snmp/mode/components/fan.pm +++ b/hardware/server/dell/openmanage/snmp/mode/components/fan.pm @@ -88,12 +88,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '%s' speed is %s rpm", $instance, $result->{coolingDeviceReading})); } - $self->{output}->perfdata_add(label => 'fan_' . $instance, unit => 'rpm', - value => $result->{coolingDeviceReading}, - warning => $warn, - critical => $crit, - min => 0 - ); + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $instance, + value => $result->{coolingDeviceReading}, + warning => $warn, + critical => $crit, + min => 0 + ); } } } diff --git a/hardware/server/dell/openmanage/snmp/mode/components/psu.pm b/hardware/server/dell/openmanage/snmp/mode/components/psu.pm index 6b333c64e..e55704144 100644 --- a/hardware/server/dell/openmanage/snmp/mode/components/psu.pm +++ b/hardware/server/dell/openmanage/snmp/mode/components/psu.pm @@ -119,12 +119,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Power supply '%s' power is %s W", $instance, $result->{powerSupplyOutputWatts})); } - $self->{output}->perfdata_add(label => 'psu_power_' . $instance, unit => 'W', - value => $result->{powerSupplyOutputWatts}, - warning => $warn, - critical => $crit, - min => 0 - ); + $self->{output}->perfdata_add( + label => 'psu_power', unit => 'W', + nlabel => 'hardware.powersupply.power.watt', + instances => $instance, + value => $result->{powerSupplyOutputWatts}, + warning => $warn, + critical => $crit, + min => 0 + ); } } } diff --git a/hardware/server/dell/openmanage/snmp/mode/components/temperature.pm b/hardware/server/dell/openmanage/snmp/mode/components/temperature.pm index cd7d38bf1..e37c7f710 100644 --- a/hardware/server/dell/openmanage/snmp/mode/components/temperature.pm +++ b/hardware/server/dell/openmanage/snmp/mode/components/temperature.pm @@ -92,12 +92,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s degree centigrade", $instance, $result->{temperatureProbeReading})); } - $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', - value => $result->{temperatureProbeReading}, - warning => $warn, - critical => $crit, - min => 0 - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $instance, + value => $result->{temperatureProbeReading}, + warning => $warn, + critical => $crit, + min => 0 + ); } } } diff --git a/hardware/server/fujitsu/snmp/mode/components/fan.pm b/hardware/server/fujitsu/snmp/mode/components/fan.pm index 906b1d14a..2f63cdeae 100644 --- a/hardware/server/fujitsu/snmp/mode/components/fan.pm +++ b/hardware/server/fujitsu/snmp/mode/components/fan.pm @@ -88,12 +88,15 @@ sub check_fan { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '%s' speed is %s rpm", $result->{$options{name}}, $result->{$options{speed}})); } - $self->{output}->perfdata_add(label => 'fan_' . $result->{$options{name}}, unit => 'rpm', - value => $result->{$options{speed}}, - warning => $warn, - critical => $crit, - min => 0 - ); + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $result->{$options{name}}, + value => $result->{$options{speed}}, + warning => $warn, + critical => $crit, + min => 0 + ); } } diff --git a/hardware/server/fujitsu/snmp/mode/components/psu.pm b/hardware/server/fujitsu/snmp/mode/components/psu.pm index d51654359..6f13e3df4 100644 --- a/hardware/server/fujitsu/snmp/mode/components/psu.pm +++ b/hardware/server/fujitsu/snmp/mode/components/psu.pm @@ -81,12 +81,15 @@ sub check_psu { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Power supply '%s' is %s W", $result->{$options{name}}, $result->{$options{current}})); } - $self->{output}->perfdata_add(label => 'power_' . $result->{$options{name}}, unit => 'W', - value => $result->{$options{current}}, - warning => $warn, - critical => $crit, - min => 0 - ); + $self->{output}->perfdata_add( + label => 'power', unit => 'W', + nlabel => 'hardware.powersupply.power.watt', + instances => $result->{$options{name}}, + value => $result->{$options{current}}, + warning => $warn, + critical => $crit, + min => 0 + ); } } diff --git a/hardware/server/fujitsu/snmp/mode/components/temperature.pm b/hardware/server/fujitsu/snmp/mode/components/temperature.pm index 35b79ba90..6bcf9fa00 100644 --- a/hardware/server/fujitsu/snmp/mode/components/temperature.pm +++ b/hardware/server/fujitsu/snmp/mode/components/temperature.pm @@ -87,11 +87,14 @@ sub check_temperature { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s V", $result->{$options{name}}, $result->{$options{current}})); } - $self->{output}->perfdata_add(label => 'temperature_' . $result->{$options{name}}, unit => 'C', - value => $result->{$options{current}}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $result->{$options{name}}, + value => $result->{$options{current}}, + warning => $warn, + critical => $crit, + ); } } diff --git a/hardware/server/fujitsu/snmp/mode/components/voltage.pm b/hardware/server/fujitsu/snmp/mode/components/voltage.pm index c2fb0fc70..43dcd03d6 100644 --- a/hardware/server/fujitsu/snmp/mode/components/voltage.pm +++ b/hardware/server/fujitsu/snmp/mode/components/voltage.pm @@ -89,11 +89,14 @@ sub check_voltage { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Voltage '%s' is %s V", $result->{$options{name}}, $result->{$options{current}})); } - $self->{output}->perfdata_add(label => 'voltage_' . $result->{$options{name}}, unit => 'V', - value => $result->{$options{current}}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'voltage', unit => 'V', + nlabel => 'hardware.voltage.volt', + instances => $result->{$options{name}}, + value => $result->{$options{current}}, + warning => $warn, + critical => $crit, + ); } } diff --git a/hardware/server/hp/bladechassis/snmp/mode/components/psu.pm b/hardware/server/hp/bladechassis/snmp/mode/components/psu.pm index 76bdd9c86..5e44e2b67 100644 --- a/hardware/server/hp/bladechassis/snmp/mode/components/psu.pm +++ b/hardware/server/hp/bladechassis/snmp/mode/components/psu.pm @@ -136,20 +136,35 @@ sub check { $psu_index, $map_conditions{$psu_condition})); } - $self->{output}->perfdata_add(label => "psu_" . $psu_index . "_power", unit => 'W', - value => $psu_pwrout); + $self->{output}->perfdata_add( + label => 'psu_power', unit => 'W', + nlabel => 'hardware.powersupply.power.watt', + instances => $psu_index, + value => $psu_pwrout + ); if (defined($psu_intemp) && $psu_intemp != -1) { - $self->{output}->perfdata_add(label => "psu_" . $psu_index . "_temp_intake", unit => 'C', - value => $psu_intemp); + $self->{output}->perfdata_add( + label => 'psu_temp', unit => 'C', + nlabel => 'hardware.powersupply.temperature.celsius', + instances => [$psu_index, 'intake'], + value => $psu_intemp + ); } if (defined($psu_exhtemp) && $psu_exhtemp != -1) { - $self->{output}->perfdata_add(label => "psu_" . $psu_index . "_temp_exhaust", unit => 'C', - value => $psu_exhtemp); + $self->{output}->perfdata_add( + label => 'psu_temp', unit => 'C', + nlabel => 'hardware.powersupply.temperature.celsius', + instances => [$psu_index, 'exhaust'], + value => $psu_exhtemp + ); } } - $self->{output}->perfdata_add(label => "total_power", unit => 'W', - value => $total_watts); + $self->{output}->perfdata_add( + label => 'total_power', unit => 'W', + nlabel => 'hardware.powersupply.power.watt', + value => $total_watts + ); } -1; \ No newline at end of file +1; diff --git a/hardware/server/hp/bladechassis/snmp/mode/components/temperature.pm b/hardware/server/hp/bladechassis/snmp/mode/components/temperature.pm index 2f55c1bbb..2eb61307b 100644 --- a/hardware/server/hp/bladechassis/snmp/mode/components/temperature.pm +++ b/hardware/server/hp/bladechassis/snmp/mode/components/temperature.pm @@ -98,9 +98,13 @@ sub check { $temp_index, $map_conditions{$temp_condition})); } - $self->{output}->perfdata_add(label => "temp_" . $temp_index, unit => 'C', - value => $temp_current, - warning => $temp_threshold); + $self->{output}->perfdata_add( + label => "temp", unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $temp_index, + value => $temp_current, + warning => $temp_threshold + ); } } diff --git a/hardware/server/hp/ilo/xmlapi/custom/api.pm b/hardware/server/hp/ilo/xmlapi/custom/api.pm index a8c4683c2..ac0266fc3 100644 --- a/hardware/server/hp/ilo/xmlapi/custom/api.pm +++ b/hardware/server/hp/ilo/xmlapi/custom/api.pm @@ -41,16 +41,15 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "port:s" => { name => 'port', default => 443 }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - 'ssl-opt:s%' => { name => 'ssl_opt' }, - "force-ilo3" => { name => 'force_ilo3' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "port:s" => { name => 'port', default => 443 }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + 'ssl-opt:s%' => { name => 'ssl_opt' }, + "force-ilo3" => { name => 'force_ilo3' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'XML API OPTIONS', once => 1); diff --git a/hardware/server/hp/ilo/xmlapi/mode/components/fan.pm b/hardware/server/hp/ilo/xmlapi/mode/components/fan.pm index 2037607e3..f568f292c 100644 --- a/hardware/server/hp/ilo/xmlapi/mode/components/fan.pm +++ b/hardware/server/hp/ilo/xmlapi/mode/components/fan.pm @@ -71,13 +71,16 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Fan '%s' is %s %s", $result->{LABEL}->{VALUE}, $result->{SPEED}->{VALUE}, $unit)); } - $self->{output}->perfdata_add(label => 'fan_' . $instance, unit => $unit, - value => $result->{SPEED}->{VALUE}, - warning => $warn, - critical => $crit, - min => 0 - ); + $self->{output}->perfdata_add( + label => 'fan', unit => $unit, + nlabel => 'hardware.fan.speed.' . lc($result->{SPEED}->{UNIT}), + instances => $instance, + value => $result->{SPEED}->{VALUE}, + warning => $warn, + critical => $crit, + min => 0 + ); } } -1; \ No newline at end of file +1; diff --git a/hardware/server/hp/ilo/xmlapi/mode/components/temperature.pm b/hardware/server/hp/ilo/xmlapi/mode/components/temperature.pm index b54dcbdae..6f268072f 100644 --- a/hardware/server/hp/ilo/xmlapi/mode/components/temperature.pm +++ b/hardware/server/hp/ilo/xmlapi/mode/components/temperature.pm @@ -72,12 +72,15 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Temperature '%s' is %s %s", $result->{LABEL}->{VALUE}, $result->{CURRENTREADING}->{VALUE}, $unit)); } - $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => $unit, - value => $result->{CURRENTREADING}->{VALUE}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temp', unit => $unit, + nlabel => 'hardware.temperature.' . lc($result->{CURRENTREADING}->{UNIT}), + instances => $instance, + value => $result->{CURRENTREADING}->{VALUE}, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1; diff --git a/hardware/server/hp/ilo/xmlapi/mode/hardware.pm b/hardware/server/hp/ilo/xmlapi/mode/hardware.pm index 812461db2..bc39e325a 100644 --- a/hardware/server/hp/ilo/xmlapi/mode/hardware.pm +++ b/hardware/server/hp/ilo/xmlapi/mode/hardware.pm @@ -48,6 +48,7 @@ sub set_system { nic => [ ['Ok', 'OK'], ['Unknown', 'OK'], + ['Disabled', 'OK'], ['.*', 'CRITICAL'], ], }; diff --git a/hardware/server/hp/proliant/snmp/mode/components/fan.pm b/hardware/server/hp/proliant/snmp/mode/components/fan.pm index 0c2770f2c..c2bcec34d 100644 --- a/hardware/server/hp/proliant/snmp/mode/components/fan.pm +++ b/hardware/server/hp/proliant/snmp/mode/components/fan.pm @@ -114,10 +114,14 @@ sub check { } if (defined($result->{cpqHeFltTolFanCurrentSpeed})) { - $self->{output}->perfdata_add(label => "fan_speed_" . $instance, unit => 'rpm', - value => $result->{cpqHeFltTolFanCurrentSpeed}); + $self->{output}->perfdata_add( + label => 'fan_speed', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $instance, + value => $result->{cpqHeFltTolFanCurrentSpeed} + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/server/hp/proliant/snmp/mode/components/psu.pm b/hardware/server/hp/proliant/snmp/mode/components/psu.pm index 5c4d270d6..36e60e98d 100644 --- a/hardware/server/hp/proliant/snmp/mode/components/psu.pm +++ b/hardware/server/hp/proliant/snmp/mode/components/psu.pm @@ -115,12 +115,20 @@ sub check { $instance, $result->{cpqHeFltTolPowerSupplyCondition})); } - $self->{output}->perfdata_add(label => "psu_power_" . $instance, unit => 'W', - value => $result->{cpqHeFltTolPowerSupplyCapacityUsed}, - critical => $result->{cpqHeFltTolPowerSupplyCapacityMaximum}); - $self->{output}->perfdata_add(label => "psu_voltage" . $instance, unit => 'V', - value => $result->{cpqHeFltTolPowerSupplyMainVoltage}); + $self->{output}->perfdata_add( + label => 'psu_power', unit => 'W', + nlabel => 'hardware.powersupply.power.watt', + instances => $instance, + value => $result->{cpqHeFltTolPowerSupplyCapacityUsed}, + critical => $result->{cpqHeFltTolPowerSupplyCapacityMaximum} + ); + $self->{output}->perfdata_add( + label => 'psu_voltage', unit => 'V', + nlabel => 'hardware.powersupply.voltage.volt', + instances => $instance, + value => $result->{cpqHeFltTolPowerSupplyMainVoltage} + ); } } -1; \ No newline at end of file +1; diff --git a/hardware/server/hp/proliant/snmp/mode/components/temperature.pm b/hardware/server/hp/proliant/snmp/mode/components/temperature.pm index a12b5bc77..e59dd59fe 100644 --- a/hardware/server/hp/proliant/snmp/mode/components/temperature.pm +++ b/hardware/server/hp/proliant/snmp/mode/components/temperature.pm @@ -105,12 +105,16 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Temperature '%s' %s is %s degree centigrade", $instance, $result->{cpqHeTemperatureLocale}, $result->{cpqHeTemperatureCelsius})); } - $self->{output}->perfdata_add(label => "temp_" . $instance . "_" . $result->{cpqHeTemperatureLocale}, unit => 'C', - value => $result->{cpqHeTemperatureCelsius}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "temp", unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => [$instance, $result->{cpqHeTemperatureLocale}], + value => $result->{cpqHeTemperatureCelsius}, + warning => $warn, + critical => $crit + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/server/huawei/hmm/snmp/mode/components/cpu.pm b/hardware/server/huawei/hmm/snmp/mode/components/cpu.pm index f83deaed9..0a8183e16 100644 --- a/hardware/server/huawei/hmm/snmp/mode/components/cpu.pm +++ b/hardware/server/huawei/hmm/snmp/mode/components/cpu.pm @@ -78,12 +78,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Cpu '%s' temperature is %s celsius degrees", $result->{bladeCPUMark}, $result->{bladeCPUTemperature})); } - $self->{output}->perfdata_add(label => 'temperature_' . $result->{bladeCPUMark}, unit => 'C', - value => $result->{bladeCPUTemperature}, - warning => $warn, - critical => $crit, - min => 0 - ); + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.cpu.temperature.celsius', + instances => $result->{bladeCPUMark}, + value => $result->{bladeCPUTemperature}, + warning => $warn, + critical => $crit, min => 0 + ); } $self->{output}->output_add(long_msg => sprintf("Cpu '%s' status is '%s' [instance = %s]", @@ -98,4 +100,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/hardware/server/huawei/hmm/snmp/mode/components/temperature.pm b/hardware/server/huawei/hmm/snmp/mode/components/temperature.pm index 120ae57b4..89dae2e8f 100644 --- a/hardware/server/huawei/hmm/snmp/mode/components/temperature.pm +++ b/hardware/server/huawei/hmm/snmp/mode/components/temperature.pm @@ -64,12 +64,15 @@ sub check { short_msg => sprintf("Temperature '%s' is '%s' celsius degrees", $result->{bladeTemperatureIndex}, $result->{bladeTemperatureReading})); } - $self->{output}->perfdata_add(label => 'temperature_' . $result->{bladeTemperatureIndex}, unit => 'C', - value => $result->{bladeTemperatureReading}, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $result->{bladeTemperatureIndex}, + value => $result->{bladeTemperatureReading}, + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/hardware/server/huawei/ibmc/snmp/mode/components/fan.pm b/hardware/server/huawei/ibmc/snmp/mode/components/fan.pm index a352a164b..c8f6caf2d 100644 --- a/hardware/server/huawei/ibmc/snmp/mode/components/fan.pm +++ b/hardware/server/huawei/ibmc/snmp/mode/components/fan.pm @@ -75,14 +75,16 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '%s' speed is %s RPM", $result->{fanDevicename}, $result->{fanSpeed})); } - my $perf_label = $result->{fanDevicename}; - $perf_label =~ s/ /_/g; - $self->{output}->perfdata_add(label => 'speed_' . $perf_label, unit => 'rpm', - value => $result->{fanSpeed}, - warning => $warn, - critical => $crit, - min => 0 - ); + + $self->{output}->perfdata_add( + label => 'speed', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $result->{fanDevicename}, + value => $result->{fanSpeed}, + warning => $warn, + critical => $crit, + min => 0 + ); } $self->{output}->output_add(long_msg => sprintf("Fan '%s' status is '%s' [instance = %s]", @@ -97,4 +99,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/hardware/server/huawei/ibmc/snmp/mode/components/harddisk.pm b/hardware/server/huawei/ibmc/snmp/mode/components/harddisk.pm index fd43983d6..0efcda209 100644 --- a/hardware/server/huawei/ibmc/snmp/mode/components/harddisk.pm +++ b/hardware/server/huawei/ibmc/snmp/mode/components/harddisk.pm @@ -75,14 +75,16 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Hard Disk '%s' temperature is %s celsius degrees", $result->{hardDiskDevicename}, $result->{hardDiskTemperature})); } - my $perf_label = $result->{hardDiskDevicename}; - $perf_label =~ s/ /_/g; - $self->{output}->perfdata_add(label => 'temperature_' . $perf_label, unit => 'C', - value => $result->{hardDiskTemperature}, - warning => $warn, - critical => $crit, - min => 0 - ); + + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.harddisk.temperature.celsius', + instances => $result->{hardDiskDevicename}, + value => $result->{hardDiskTemperature}, + warning => $warn, + critical => $crit, + min => 0 + ); } $self->{output}->output_add(long_msg => sprintf("Hard disk '%s' status is '%s' [instance = %s]", @@ -97,4 +99,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/hardware/server/huawei/ibmc/snmp/mode/components/psu.pm b/hardware/server/huawei/ibmc/snmp/mode/components/psu.pm index 93d940872..29ef12462 100644 --- a/hardware/server/huawei/ibmc/snmp/mode/components/psu.pm +++ b/hardware/server/huawei/ibmc/snmp/mode/components/psu.pm @@ -77,15 +77,17 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Power supply '%s' power is %s watts", $result->{powerSupplyDevicename}, $result->{powerSupplyInputPower})); } - my $perf_label = $result->{powerSupplyDevicename}; - $perf_label =~ s/ /_/g; - $self->{output}->perfdata_add(label => 'power_' . $perf_label, unit => 'W', - value => $result->{powerSupplyInputPower}, - warning => $warn, - critical => $crit, - min => 0, - max => $result->{powerSupplyPowerRating} - ); + + $self->{output}->perfdata_add( + label => 'power', unit => 'W', + nlabel => 'hardware.powersupply.power.watt', + instances => $result->{powerSupplyDevicename}, + value => $result->{powerSupplyInputPower}, + warning => $warn, + critical => $crit, + min => 0, + max => $result->{powerSupplyPowerRating} + ); } $self->{output}->output_add(long_msg => sprintf("Power supply '%s' status is '%s' [instance = %s]", @@ -100,4 +102,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/hardware/server/huawei/ibmc/snmp/mode/components/temperature.pm b/hardware/server/huawei/ibmc/snmp/mode/components/temperature.pm index 4dc9e5a7f..3a3ac26b0 100644 --- a/hardware/server/huawei/ibmc/snmp/mode/components/temperature.pm +++ b/hardware/server/huawei/ibmc/snmp/mode/components/temperature.pm @@ -60,12 +60,15 @@ sub check { short_msg => sprintf("Temperature of '%s' is '%s' celsius degrees", $result->{temperatureObject}, $result->{temperatureReading} / 10)); } - $self->{output}->perfdata_add(label => 'temperature_' . $result->{temperatureObject}, unit => 'C', - value => $result->{temperatureReading} / 10, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $result->{temperatureObject}, + value => $result->{temperatureReading} / 10, + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/ambient.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/ambient.pm index a690c9dd5..180321f3d 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/ambient.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/ambient.pm @@ -79,11 +79,15 @@ sub check { short_msg => sprintf("ambient '%s' is %s degree centigrade", $temp, $value)); } - $self->{output}->perfdata_add(label => 'temp_' . $temp, unit => 'C', - value => $value, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.ambient.temperature.celsius', + instances => $temp, + value => $value, + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/blower.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/blower.pm index aa5eedeac..081baacc5 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/blower.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/blower.pm @@ -76,11 +76,15 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Blower speed '%s' is %s %%", $instance, $blower_speed)); } - $self->{output}->perfdata_add(label => "blower_speed_" . $instance, unit => '%', - value => $blower_speed, - warning => $warn, - critical => $crit, - min => 0, max => 100); + $self->{output}->perfdata_add( + label => "blower_speed", unit => '%', + nlabel => 'hardware.blower.speed.percentage', + instances => $instance, + value => $blower_speed, + warning => $warn, + critical => $crit, + min => 0, max => 100 + ); } $self->{output}->output_add(long_msg => sprintf("Blower '%s' state is %s (%d %%).", @@ -108,4 +112,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/chassisfan.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/chassisfan.pm index 4a23ec653..f508b2bd2 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/chassisfan.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/chassisfan.pm @@ -74,13 +74,17 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Chassis fan '%s' speed is %s rpm", $instance, $result->{chassisFanSpeedRPM})); } - $self->{output}->perfdata_add(label => "chassisfan_" . $instance, unit => 'rpm', - value => $result->{chassisFanSpeedRPM}, - warning => $warn, - critical => $crit, - min => 0); + $self->{output}->perfdata_add( + label => "chassisfan", unit => 'rpm', + nlabel => 'hardware.chassis.fan.speed.rpm', + instances => $instance, + value => $result->{chassisFanSpeedRPM}, + warning => $warn, + critical => $crit, + min => 0 + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/fanpack.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/fanpack.pm index 583ffe9e4..9238732e0 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/fanpack.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/fanpack.pm @@ -83,13 +83,17 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Fanpack '%s' speed is %s rpm", $instance, $result->{fanPackAverageSpeedRPM})); } - $self->{output}->perfdata_add(label => "fanpack_" . $instance, unit => 'rpm', - value => $result->{fanPackAverageSpeedRPM}, - warning => $warn, - critical => $crit, - min => 0); + $self->{output}->perfdata_add( + label => "fanpack", unit => 'rpm', + nlabel => 'hardware.fanpack.speed.rpm', + instances => $instance, + value => $result->{fanPackAverageSpeedRPM}, + warning => $warn, + critical => $crit, + min => 0 + ); } } } -1; \ No newline at end of file +1; diff --git a/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/fan.pm b/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/fan.pm index 69b915148..ead3b961b 100644 --- a/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/fan.pm +++ b/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/fan.pm @@ -71,11 +71,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '%s' is '%s' %%", $result->{fanDescr}, $fan_speed)); } - $self->{output}->perfdata_add(label => 'fan_' . $result->{fanDescr}, unit => '%', - value => $fan_speed, - warning => $warn, - critical => $crit, min => 0, max => 100 - ); + $self->{output}->perfdata_add( + label => 'fan', unit => '%', + nlabel => 'hardware.fan.speed.percentage', + instances => $result->{fanDescr}, + value => $fan_speed, + warning => $warn, + critical => $crit, min => 0, max => 100 + ); } } diff --git a/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/temperature.pm b/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/temperature.pm index 5976afaaf..48d24c30e 100644 --- a/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/temperature.pm +++ b/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/temperature.pm @@ -78,10 +78,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s C", $result->{tempDescr}, $result->{tempReading})); } - $self->{output}->perfdata_add(label => "temp_" . $result->{tempDescr}, unit => 'C', - value => $result->{tempReading}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "temp", unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $result->{tempDescr}, + value => $result->{tempReading}, + warning => $warn, + critical => $crit + ); } } } diff --git a/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/voltage.pm b/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/voltage.pm index 3639291a9..6b99a8ba7 100644 --- a/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/voltage.pm +++ b/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/voltage.pm @@ -78,10 +78,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Voltage '%s' is %s", $result->{voltDescr}, $result->{voltReading})); } - $self->{output}->perfdata_add(label => "volt_" . $result->{voltDescr}, - value => $result->{voltReading}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "volt", + nlabel => 'hardware.voltage.volt', + instances => $result->{voltDescr}, + value => $result->{voltReading}, + warning => $warn, + critical => $crit + ); } } } diff --git a/hardware/server/lenovo/xcc/snmp/mode/components/disk.pm b/hardware/server/lenovo/xcc/snmp/mode/components/disk.pm new file mode 100644 index 000000000..378c0ed94 --- /dev/null +++ b/hardware/server/lenovo/xcc/snmp/mode/components/disk.pm @@ -0,0 +1,66 @@ +# +# Copyright 2019 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 hardware::server::lenovo::xcc::snmp::mode::components::disk; + +use strict; +use warnings; +use centreon::plugins::misc; + +my $mapping = { + diskFruName => { oid => '.1.3.6.1.4.1.19046.11.1.1.12.2.1.2' }, + diskHealthStatus => { oid => '.1.3.6.1.4.1.19046.11.1.1.12.2.1.3' }, +}; +my $oid_diskEntry = '.1.3.6.1.4.1.19046.11.1.1.12.2.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_diskEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking disks"); + $self->{components}->{disk} = { name => 'disk', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'disk')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_diskEntry}})) { + next if ($oid !~ /^$mapping->{diskFruName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_diskEntry}, instance => $instance); + + next if ($self->check_filter(section => 'disk', instance => $instance)); + $result->{diskFruName} = centreon::plugins::misc::trim($result->{diskFruName}); + $self->{components}->{disk}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("disk '%s' status is %s [instance: %s].", + $result->{diskFruName}, $result->{diskHealthStatus}, $instance)); + + my $exit = $self->get_severity(label => 'default', section => 'disk', value => $result->{diskHealthStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Disk '%s' status is '%s'", $result->{diskFruName}, $result->{diskHealthStatus})); + } + } +} + +1; diff --git a/hardware/server/lenovo/xcc/snmp/mode/components/fan.pm b/hardware/server/lenovo/xcc/snmp/mode/components/fan.pm new file mode 100644 index 000000000..eada336c0 --- /dev/null +++ b/hardware/server/lenovo/xcc/snmp/mode/components/fan.pm @@ -0,0 +1,85 @@ +# +# Copyright 2019 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 hardware::server::lenovo::xcc::snmp::mode::components::fan; + +use strict; +use warnings; +use centreon::plugins::misc; + +my $mapping = { + fanDescr => { oid => '.1.3.6.1.4.1.19046.11.1.1.3.2.1.2' }, + fanSpeed => { oid => '.1.3.6.1.4.1.19046.11.1.1.3.2.1.3' }, + fanHealthStatus => { oid => '.1.3.6.1.4.1.19046.11.1.1.3.2.1.10' }, +}; +my $oid_fanEntry = '.1.3.6.1.4.1.19046.11.1.1.3.2.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_fanEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fans"); + $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; + return if ($self->check_filter(section => 'fan')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_fanEntry}})) { + next if ($oid !~ /^$mapping->{fanSpeed}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_fanEntry}, instance => $instance); + $result->{fanDescr} = centreon::plugins::misc::trim($result->{fanDescr}); + $result->{fanSpeed} = centreon::plugins::misc::trim($result->{fanSpeed}); + + next if ($self->check_filter(section => 'fan', instance => $instance)); + + $self->{components}->{fan}->{total}++; + $self->{output}->output_add(long_msg => sprintf("Fan '%s' status is '%s' [instance = %s][value: %s]", + $result->{fanDescr}, $result->{fanHealthStatus}, $instance, $result->{fanSpeed})); + + my $exit = $self->get_severity(label => 'default', section => 'fan', value => $result->{fanHealthStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Fan '%s' status is '%s'", $result->{fanDescr}, $result->{fanHealthStatus})); + } + + next if ($result->{fanSpeed} !~ /(\d+)/); + + my $fan_speed = $1; + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $fan_speed); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Fan '%s' is '%s' %%", $result->{fanDescr}, $fan_speed)); + } + $self->{output}->perfdata_add( + label => 'fan', unit => '%', + nlabel => 'hardware.fan.speed.percentage', + instances => $result->{fanDescr}, + value => $fan_speed, + warning => $warn, + critical => $crit, min => 0, max => 100 + ); + } +} + +1; diff --git a/hardware/server/lenovo/xcc/snmp/mode/components/psu.pm b/hardware/server/lenovo/xcc/snmp/mode/components/psu.pm new file mode 100644 index 000000000..aa358147c --- /dev/null +++ b/hardware/server/lenovo/xcc/snmp/mode/components/psu.pm @@ -0,0 +1,66 @@ +# +# Copyright 2019 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 hardware::server::lenovo::xcc::snmp::mode::components::psu; + +use strict; +use warnings; +use centreon::plugins::misc; + +my $mapping = { + powerFruName => { oid => '.1.3.6.1.4.1.19046.11.1.1.11.2.1.2' }, + powerHealthStatus => { oid => '.1.3.6.1.4.1.19046.11.1.1.11.2.1.6' }, +}; +my $oid_powerEntry = '.1.3.6.1.4.1.19046.11.1.1.11.2.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_powerEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + $self->{components}->{psu} = { name => 'psu', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'psu')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_powerEntry}})) { + next if ($oid !~ /^$mapping->{powerFruName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_powerEntry}, instance => $instance); + + next if ($self->check_filter(section => 'psu', instance => $instance)); + $result->{powerFruName} = centreon::plugins::misc::trim($result->{powerFruName}); + $self->{components}->{psu}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("power supply '%s' status is %s [instance: %s].", + $result->{powerFruName}, $result->{powerHealthStatus}, $instance)); + + my $exit = $self->get_severity(label => 'default', section => 'psu', value => $result->{powerHealthStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Power supply '%s' status is '%s'", $result->{powerFruName}, $result->{powerHealthStatus})); + } + } +} + +1; diff --git a/hardware/server/lenovo/xcc/snmp/mode/components/raidvolume.pm b/hardware/server/lenovo/xcc/snmp/mode/components/raidvolume.pm new file mode 100644 index 000000000..886dc7a14 --- /dev/null +++ b/hardware/server/lenovo/xcc/snmp/mode/components/raidvolume.pm @@ -0,0 +1,66 @@ +# +# Copyright 2019 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 hardware::server::lenovo::xcc::snmp::mode::components::raidvolume; + +use strict; +use warnings; +use centreon::plugins::misc; + +my $mapping = { + raidVolumeName => { oid => '.1.3.6.1.4.1.19046.11.1.1.13.1.7.1.2' }, + raidVolumeStatus => { oid => '.1.3.6.1.4.1.19046.11.1.1.13.1.7.1.4' }, +}; +my $oid_raidVolumeEntry = '.1.3.6.1.4.1.19046.11.1.1.13.1.7.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_raidVolumeEntry, end => $mapping->{raidVolumeStatus}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking raid volumes"); + $self->{components}->{raidvolume} = { name => 'raidvolume', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'raidvolume')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_raidVolumeEntry}})) { + next if ($oid !~ /^$mapping->{raidVolumeName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_raidVolumeEntry}, instance => $instance); + + next if ($self->check_filter(section => 'raidvolume', instance => $instance)); + $result->{raidVolumeName} = centreon::plugins::misc::trim($result->{raidVolumeName}); + $self->{components}->{raidvolume}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("raid volume '%s' status is %s [instance: %s].", + $result->{raidVolumeName}, $result->{raidVolumeStatus}, $instance)); + + my $exit = $self->get_severity(section => 'raidvolume', value => $result->{raidVolumeStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Raid volume '%s' status is '%s'", $result->{raidVolumeName}, $result->{raidVolumeStatus})); + } + } +} + +1; diff --git a/hardware/server/lenovo/xcc/snmp/mode/components/temperature.pm b/hardware/server/lenovo/xcc/snmp/mode/components/temperature.pm new file mode 100644 index 000000000..7fc720773 --- /dev/null +++ b/hardware/server/lenovo/xcc/snmp/mode/components/temperature.pm @@ -0,0 +1,100 @@ +# +# Copyright 2019 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 hardware::server::lenovo::xcc::snmp::mode::components::temperature; + +use strict; +use warnings; +use centreon::plugins::misc; + +my $mapping = { + tempDescr => { oid => '.1.3.6.1.4.1.19046.11.1.1.1.2.1.2' }, + tempReading => { oid => '.1.3.6.1.4.1.19046.11.1.1.1.2.1.3' }, + tempCritLimitHigh => { oid => '.1.3.6.1.4.1.19046.11.1.1.1.2.1.6' }, + tempNonCritLimitHigh => { oid => '.1.3.6.1.4.1.19046.11.1.1.1.2.1.7' }, + tempCritLimitLow => { oid => '.1.3.6.1.4.1.19046.11.1.1.1.2.1.9' }, + tempNonCritLimitLow => { oid => '.1.3.6.1.4.1.19046.11.1.1.1.2.1.10' }, + tempHealthStatus => { oid => '.1.3.6.1.4.1.19046.11.1.1.1.2.1.11' }, +}; +my $oid_tempEntry = '.1.3.6.1.4.1.19046.11.1.1.1.2.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_tempEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking temperatures"); + $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; + return if ($self->check_filter(section => 'temperature')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_tempEntry}})) { + next if ($oid !~ /^$mapping->{tempDescr}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_tempEntry}, instance => $instance); + + next if ($self->check_filter(section => 'temperature', instance => $instance)); + $result->{tempDescr} = centreon::plugins::misc::trim($result->{tempDescr}); + $self->{components}->{temperature}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("temperature '%s' status is %s [instance: %s][value: %s C].", + $result->{tempDescr}, $result->{tempHealthStatus}, $instance, $result->{tempReading})); + + my $exit = $self->get_severity(label => 'default', section => 'temperature', value => $result->{tempHealthStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' status is '%s'", $result->{tempDescr}, $result->{tempHealthStatus})); + } + + if (defined($result->{tempReading})) { + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{tempReading}); + if ($checked == 0) { + my $warn_th = ($result->{tempNonCritLimitLow} =~ /\d+(\.\d+)?/ ? $result->{tempNonCritLimitLow} : '') . ':' . ($result->{tempNonCritLimitHigh} =~ /\d+(\.\d+)?/ ? $result->{tempNonCritLimitHigh} : ''); + my $crit_th = ($result->{tempCritLimitLow} =~ /\d+(\.\d+)?/ ? $result->{tempCritLimitLow} : '') . ':' . ($result->{tempCritLimitHigh} =~ /\d+(\.\d+)?/ ? $result->{tempCritLimitHigh} : ''); + $self->{perfdata}->threshold_validate(label => 'warning-temperature-instance-' . $instance, value => $warn_th) if ($warn_th ne ':'); + $self->{perfdata}->threshold_validate(label => 'critical-temperature-instance-' . $instance, value => $crit_th) if ($crit_th ne ':'); + $exit = $self->{perfdata}->threshold_check( + value => $result->{tempReading}, + threshold => [ { label => 'critical-temperature-instance-' . $instance, exit_litteral => 'critical' }, + { label => 'warning-temperature-instance-' . $instance, exit_litteral => 'warning' } ]); + + $warn = $self->{perfdata}->get_perfdata_for_output(label => 'warning-temperature-instance-' . $instance); + $crit = $self->{perfdata}->get_perfdata_for_output(label => 'critical-temperature-instance-' . $instance); + } + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Temperature '%s' is %s C", $result->{tempDescr}, $result->{tempReading})); + } + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $result->{tempDescr}, + value => $result->{tempReading}, + warning => $warn, + critical => $crit + ); + } + } +} + +1; diff --git a/hardware/server/lenovo/xcc/snmp/mode/components/voltage.pm b/hardware/server/lenovo/xcc/snmp/mode/components/voltage.pm new file mode 100644 index 000000000..e74fe9ade --- /dev/null +++ b/hardware/server/lenovo/xcc/snmp/mode/components/voltage.pm @@ -0,0 +1,100 @@ +# +# Copyright 2019 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 hardware::server::lenovo::xcc::snmp::mode::components::voltage; + +use strict; +use warnings; +use centreon::plugins::misc; + +my $mapping = { + voltDescr => { oid => '.1.3.6.1.4.1.19046.11.1.1.2.2.1.2' }, + voltReading => { oid => '.1.3.6.1.4.1.19046.11.1.1.2.2.1.3' }, + voltCritLimitHigh => { oid => '.1.3.6.1.4.1.19046.11.1.1.2.2.1.6' }, + voltNonCritLimitHigh => { oid => '.1.3.6.1.4.1.19046.11.1.1.2.2.1.7' }, + voltCritLimitLow => { oid => '.1.3.6.1.4.1.19046.11.1.1.2.2.1.9' }, + voltNonCritLimitLow => { oid => '.1.3.6.1.4.1.19046.11.1.1.2.2.1.10' }, + voltHealthStatus => { oid => '.1.3.6.1.4.1.19046.11.1.1.2.2.1.11' }, +}; +my $oid_voltEntry = '.1.3.6.1.4.1.19046.11.1.1.2.2.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_voltEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking voltages"); + $self->{components}->{voltage} = {name => 'voltages', total => 0, skip => 0}; + return if ($self->check_filter(section => 'voltage')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_voltEntry}})) { + next if ($oid !~ /^$mapping->{voltDescr}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_voltEntry}, instance => $instance); + + next if ($self->check_filter(section => 'voltage', instance => $instance)); + $result->{voltDescr} = centreon::plugins::misc::trim($result->{voltDescr}); + $self->{components}->{voltage}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("voltage '%s' status is %s [instance: %s][value: %s].", + $result->{voltDescr}, $result->{voltHealthStatus}, $instance, $result->{voltReading})); + + my $exit = $self->get_severity(label => 'default', section => 'voltage', value => $result->{voltHealthStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Voltage '%s' status is '%s'", $result->{voltDescr}, $result->{voltHealthStatus})); + } + + next if (!defined($result->{voltReading})); + + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'voltage', instance => $instance, value => $result->{voltReading}); + if ($checked == 0) { + my $warn_th = ($result->{voltNonCritLimitLow} =~ /\d+(\.\d+)?/ ? $result->{voltNonCritLimitLow} : '') . ':' . ($result->{voltNonCritLimitHigh} =~ /\d+(\.\d+)?/ ? $result->{voltNonCritLimitHigh} : ''); + my $crit_th = ($result->{voltCritLimitLow} =~ /\d+(\.\d+)?/ ? $result->{voltCritLimitLow} : '') . ':' . ($result->{voltCritLimitHigh} =~ /\d+(\.\d+)?/ ? $result->{voltCritLimitHigh} : ''); + $self->{perfdata}->threshold_validate(label => 'warning-voltage-instance-' . $instance, value => $warn_th) if ($warn_th ne ':'); + $self->{perfdata}->threshold_validate(label => 'critical-voltage-instance-' . $instance, value => $crit_th) if ($crit_th ne ':'); + $exit = $self->{perfdata}->threshold_check( + value => $result->{voltReading}, + threshold => [ { label => 'critical-voltage-instance-' . $instance, exit_litteral => 'critical' }, + { label => 'warning-voltage-instance-' . $instance, exit_litteral => 'warning' } ]); + + $warn = $self->{perfdata}->get_perfdata_for_output(label => 'warning-voltage-instance-' . $instance); + $crit = $self->{perfdata}->get_perfdata_for_output(label => 'critical-voltage-instance-' . $instance); + } + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Voltage '%s' is %s", $result->{voltDescr}, $result->{voltReading})); + } + $self->{output}->perfdata_add( + label => 'volt', + nlabel => 'hardware.voltage.volt', + instances => $result->{voltDescr}, + value => $result->{voltReading}, + warning => $warn, + critical => $crit + ); + } +} + +1; diff --git a/hardware/server/lenovo/xcc/snmp/mode/hardware.pm b/hardware/server/lenovo/xcc/snmp/mode/hardware.pm new file mode 100644 index 000000000..b622d5601 --- /dev/null +++ b/hardware/server/lenovo/xcc/snmp/mode/hardware.pm @@ -0,0 +1,115 @@ +# +# Copyright 2019 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 hardware::server::lenovo::xcc::snmp::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(temperature|voltage|fan|psu|disk|raidvolume)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|voltage|fan)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + default => [ + ['Normal', 'OK'], + ['.*', 'CRITICAL'], + ], + raidvolume => [ + ['Optimal', 'OK'], + ['.*', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'hardware::server::lenovo::xcc::snmp::mode::components'; + $self->{components_module} = ['temperature', 'voltage', 'fan', 'psu', 'disk', 'raidvolume']; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); +} + +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 => + { + }); + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'temperature', 'voltage', 'fan', 'psu', 'disk', 'raidvolume'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=temperature) +Can also exclude specific instance: --filter=fan,1 + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=item B<--threshold-overload> + +Set to overload default threshold values (syntax: section,[instance,]status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='fan,OK,offline' + +=item B<--warning> + +Set warning threshold for 'temperature', 'fan', 'voltage' (syntax: type,regexp,threshold) +Example: --warning='temperature,.*,30' + +=item B<--critical> + +Set critical threshold for temperature', 'fan', 'voltage' (syntax: type,regexp,threshold) +Example: --critical='temperature,.*,40' + +=back + +=cut + diff --git a/hardware/server/lenovo/xcc/snmp/plugin.pm b/hardware/server/lenovo/xcc/snmp/plugin.pm new file mode 100644 index 000000000..6017fbd89 --- /dev/null +++ b/hardware/server/lenovo/xcc/snmp/plugin.pm @@ -0,0 +1,48 @@ +# +# Copyright 2019 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 hardware::server::lenovo::xcc::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}} = ( + 'hardware' => 'hardware::server::lenovo::xcc::snmp::mode::hardware', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Lenovo XCC Card in SNMP. + +=cut diff --git a/hardware/server/sun/mgmt_cards/mode/showfaulty.pm b/hardware/server/sun/mgmt_cards/mode/showfaulty.pm index e6419e5f9..1bd3c7915 100644 --- a/hardware/server/sun/mgmt_cards/mode/showfaulty.pm +++ b/hardware/server/sun/mgmt_cards/mode/showfaulty.pm @@ -33,15 +33,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "memory" => { name => 'memory' }, - "command-plink:s" => { name => 'command_plink', default => 'plink' }, - }); + $options{options}->add_options(arguments => { + 'hostname:s' => { name => 'hostname' }, + 'username:s' => { name => 'username' }, + 'password:s' => { name => 'password' }, + 'timeout:s' => { name => 'timeout', default => 30 }, + 'memory' => { name => 'memory' }, + 'command-plink:s' => { name => 'command_plink', default => 'plink' }, + }); + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); return $self; } @@ -77,10 +77,10 @@ sub run { my $cmd_in = 'show -o table -level all /SP/faultmgmt'; my $cmd = "echo '$cmd_in' | " . $self->{option_results}->{command_plink} . " -T -l '" . $self->{option_results}->{username} . "' -batch -pw '" . $self->{option_results}->{password} . "' " . $self->{option_results}->{hostname} . " 2>&1"; my ($lerror, $stdout, $exit_code) = centreon::plugins::misc::backtick( - command => $cmd, - timeout => $self->{option_results}->{timeout}, - wait_exit => 1 - ); + command => $cmd, + timeout => $self->{option_results}->{timeout}, + wait_exit => 1 + ); $stdout =~ s/\r//g; if ($lerror <= -1000) { $self->{output}->output_add(severity => 'UNKNOWN', diff --git a/hardware/server/sun/mgmt_cards/plugin.pm b/hardware/server/sun/mgmt_cards/plugin.pm index 2b0f1b385..a153f53ba 100644 --- a/hardware/server/sun/mgmt_cards/plugin.pm +++ b/hardware/server/sun/mgmt_cards/plugin.pm @@ -31,15 +31,15 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'show-faulty' => 'hardware::server::sun::mgmt_cards::mode::showfaulty', - 'showfaults' => 'hardware::server::sun::mgmt_cards::mode::showfaults', - 'showstatus' => 'hardware::server::sun::mgmt_cards::mode::showstatus', - 'showboards' => 'hardware::server::sun::mgmt_cards::mode::showboards', - 'showenvironment' => 'hardware::server::sun::mgmt_cards::mode::showenvironment', - 'environment-v8xx' => 'hardware::server::sun::mgmt_cards::mode::environmentv8xx', - 'environment-v4xx' => 'hardware::server::sun::mgmt_cards::mode::environmentv4xx', - 'environment-sf2xx' => 'hardware::server::sun::mgmt_cards::mode::environmentsf2xx', - ); + 'show-faulty' => 'hardware::server::sun::mgmt_cards::mode::showfaulty', + 'showfaults' => 'hardware::server::sun::mgmt_cards::mode::showfaults', + 'showstatus' => 'hardware::server::sun::mgmt_cards::mode::showstatus', + 'showboards' => 'hardware::server::sun::mgmt_cards::mode::showboards', + 'showenvironment' => 'hardware::server::sun::mgmt_cards::mode::showenvironment', + 'environment-v8xx' => 'hardware::server::sun::mgmt_cards::mode::environmentv8xx', + 'environment-v4xx' => 'hardware::server::sun::mgmt_cards::mode::environmentv4xx', + 'environment-sf2xx' => 'hardware::server::sun::mgmt_cards::mode::environmentsf2xx', + ); return $self; } diff --git a/hardware/server/sun/mseries/mode/hardware.pm b/hardware/server/sun/mseries/mode/hardware.pm index fdb7b1152..7f2b4de74 100644 --- a/hardware/server/sun/mseries/mode/hardware.pm +++ b/hardware/server/sun/mseries/mode/hardware.pm @@ -128,11 +128,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "with-sensors" => { name => 'with_sensors' }, - "exclude:s@" => { name => 'exclude' }, - }); + $options{options}->add_options(arguments => { + "with-sensors" => { name => 'with_sensors' }, + "exclude:s@" => { name => 'exclude' }, + }); return $self; } @@ -196,9 +195,14 @@ sub run { my $oid_end = $2; my $hex_val = md5_hex($board_type . '.' . $oid_end); - $self->{output}->perfdata_add(label => $components_board_types{$board_type} . "_" . $hex_val, - unit => $oids_monitor_units->{$oid_scfMonitorUnits . '.' . $board_type . '.' . $oid_end}, - value => $oids_monitor_values->{$oid}); + # need some snmpwalk to do unit mapping!! experimental + $self->{output}->perfdata_add( + label => $components_board_types{$board_type}, + unit => $oids_monitor_units->{$oid_scfMonitorUnits . '.' . $board_type . '.' . $oid_end}, + nlabel => 'hardware.' . lc($components_board_types{$board_type}) . '.' . $oids_monitor_units->{$oid_scfMonitorUnits . '.' . $board_type . '.' . $oid_end}, + instances => $hex_val, + value => $oids_monitor_values->{$oid} + ); } } @@ -230,4 +234,4 @@ PART = name =back =cut - \ No newline at end of file + diff --git a/hardware/server/supermicro/snmp/mode/hardware.pm b/hardware/server/supermicro/snmp/mode/hardware.pm index 4e19b7ce3..6a6983358 100644 --- a/hardware/server/supermicro/snmp/mode/hardware.pm +++ b/hardware/server/supermicro/snmp/mode/hardware.pm @@ -182,10 +182,16 @@ sub check { short_msg => sprintf("Sensor '%s' is %s %s", $result->{smHealthMonitorName}, $result->{smHealthMonitorReading}, defined($result->{smHealthMonitorReadingUnit}) ? $result->{smHealthMonitorReadingUnit} : '')); } - $self->{output}->perfdata_add(label => $component . '_' . $result->{smHealthMonitorName}, unit => $result->{smHealthMonitorReadingUnit}, - value => $result->{smHealthMonitorReading}, - warning => $warn, - critical => $crit); + + # need some snmpwalk to do unit mapping!! experimental + $self->{output}->perfdata_add( + label => $component, unit => $result->{smHealthMonitorReadingUnit}, + nlabel => 'hardware.sensor.' . $result->{smHealthMonitorType} . '.' . $result->{smHealthMonitorReadingUnit}, + instances => $result->{smHealthMonitorName}, + value => $result->{smHealthMonitorReading}, + warning => $warn, + critical => $crit + ); } } diff --git a/hardware/telephony/avaya/mediagateway/snmp/mode/components/alarm.pm b/hardware/telephony/avaya/mediagateway/snmp/mode/components/alarm.pm new file mode 100644 index 000000000..c3f25675f --- /dev/null +++ b/hardware/telephony/avaya/mediagateway/snmp/mode/components/alarm.pm @@ -0,0 +1,88 @@ +# +# Copyright 2019 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 hardware::telephony::avaya::mediagateway::snmp::mode::components::alarm; + +use strict; +use warnings; + +sub load {} + +my $bits_alarm = { + 23 => 'at least two fans have been operating at less than 90% of their nominal speed for 5 minutes or more', + 22 => 'the power supply fan has been operating at less than 90% of its nominal speed for 10 minutes or more, but less than 15 minutes', + 21 => 'the power supply fan has been operating at less than 90% of its nominal speed for 15 minutes or more', + 19 => 'cmgCpuTemp has exceeded its warning threshold', + 18 => 'mgDspTemp has exceeded its warning threshold', + 16 => 'Power On Status Test failure -NCE, QUICC test failures on power up', + 15 => 'The +5.1 v power supply to the MG processor is out of range', + 14 => 'The +3.3 v power supply to the VoIP complexes is out of range', + 13 => 'The +3.3 v power supply to the VoIP complexes is out of range', + 12 => 'The +1.58 v power supply to the DSP units is out of range', + 11 => 'The +2.5 v power supply to the 8260 processor is out of range', + 10 => 'The -48 v auxiliary power supply to the endpoints is out of range', + 9 => 'The +12 v power supply to the fans is out of range', + 7 => 'Clock synchronization signal is lost', + 6 => 'Clock synchronization signal warning. Only one clock syncronization signal source remains', + 5 => 'Clock synchronization signal excessive switching', + 4 => 'TDM Test Expansion Box 1 Failure', + 3 => 'TDM Test Expansion Box 2 Failure', + 2 => 'PoE Power Supply Base Box Failure', + 1 => 'PoE Power Supply Expansion Box 1 Failure', + 0 => 'PoE Power Supply Expansion Box 2 Failure', +}; + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking alarms"); + $self->{components}->{alarm} = { name => 'alarms', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'alarm')); + + my $oid_cmgHardwareFaultMask = '.1.3.6.1.4.1.6889.2.9.1.1.10.12.0'; + return if (!defined($self->{results}->{$oid_cmgHardwareFaultMask})); + + $self->{results}->{$oid_cmgHardwareFaultMask} = oct("0b" . unpack('B*', $self->{results}->{$oid_cmgHardwareFaultMask})); + foreach (sort { $a <=> $b } keys %$bits_alarm) { + my $instance = $_; + my $status = 'disabled'; + if (($self->{results}->{$oid_cmgHardwareFaultMask} & (1 << $_))) { + $status = 'enabled'; + } + + next if ($self->check_filter(section => 'alarm', instance => $instance)); + $self->{components}->{alarm}->{total}++; + + $self->{output}->output_add( + long_msg => sprintf( + "alarm '%s' status is '%s' [instance: %s]", + $bits_alarm->{$_}, $status, $instance + ) + ); + my $exit = $self->get_severity(section => 'alarm', instance => $instance, value => $status); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Alarm '%s' status is '%s'", + $bits_alarm->{$_}, $status)); + } + } +} + +1; diff --git a/hardware/telephony/avaya/mediagateway/snmp/mode/controllerstatus.pm b/hardware/telephony/avaya/mediagateway/snmp/mode/controllerstatus.pm new file mode 100644 index 000000000..5efff4db7 --- /dev/null +++ b/hardware/telephony/avaya/mediagateway/snmp/mode/controllerstatus.pm @@ -0,0 +1,139 @@ +# +# Copyright 2019 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 hardware::telephony::avaya::mediagateway::snmp::mode::controllerstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions; + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("controller registration state is '%s' [h248 link status: '%s']", $self->{result_values}->{registration_state}, $self->{result_values}->{h248_link_status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{registration_state} = $options{new_datas}->{$self->{instance} . '_cmgRegistrationState'}; + $self->{result_values}->{h248_link_status} = $options{new_datas}->{$self->{instance} . '_cmgH248LinkStatus'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'cmgRegistrationState' }, { name => 'cmgH248LinkStatus' } ], + 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 => \¢reon::plugins::templates::catalog_functions::catalog_status_threshold, + } + }, + ]; +} + +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 => { + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{h248_link_status} =~ /down/i || %{registration_state} =~ /notRegistred/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status', 'unknown_status']); +} + +my %map_registration_state = ( + 1 => 'registred', + 2 => 'notRegistred', +); +my %map_h248_link_status = ( + 1 => 'up', + 2 => 'down', +); + +my $mapping = { + cmgRegistrationState => { oid => '.1.3.6.1.4.1.6889.2.9.1.3.1', map => \%map_registration_state }, + cmgH248LinkStatus => { oid => '.1.3.6.1.4.1.6889.2.9.1.3.3', map => \%map_h248_link_status }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + + my $snmp_result = $options{snmp}->get_leef( + oids => [$mapping->{cmgRegistrationState}->{oid} . '.0', $mapping->{cmgH248LinkStatus}->{oid} . '.0'], + nothing_quit => 1 + ); + + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => '0'); + $self->{global} = { %$result }; +} + +1; + +__END__ + +=head1 MODE + +Check controller status. + +=over 8 + +=item B<--unknown-status> + +Set warning threshold for status (Default: '%{status} =~ /unknown/i'). +Can used special variables like: %{h248_link_status}, %{registration_state} + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{status} =~ /batteryLow/i'). +Can used special variables like: %{h248_link_status}, %{registration_state} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{h248_link_status} =~ /down/i || %{registration_state} =~ /notRegistred/i'). +Can used special variables like: %{h248_link_status}, %{registration_state} + +=back + +=cut diff --git a/hardware/telephony/avaya/mediagateway/snmp/mode/hardware.pm b/hardware/telephony/avaya/mediagateway/snmp/mode/hardware.pm new file mode 100644 index 000000000..76a0b3498 --- /dev/null +++ b/hardware/telephony/avaya/mediagateway/snmp/mode/hardware.pm @@ -0,0 +1,98 @@ +# +# Copyright 2019 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 hardware::telephony::avaya::mediagateway::snmp::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(alarm)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + alarm => [ + ['enabled', 'CRITICAL'], + ['disabled', 'OK'], + ], + }; + + $self->{components_path} = 'hardware::telephony::avaya::mediagateway::snmp::mode::components'; + $self->{components_module} = ['alarm']; +} + +sub snmp_execute { + my ($self, %options) = @_; + + my $oid_cmgHardwareFaultMask = '.1.3.6.1.4.1.6889.2.9.1.1.10.12.0'; + $self->{results} = $options{snmp}->get_leef(oids => [$oid_cmgHardwareFaultMask]); +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1, no_performance => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'alarm'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=alarm) +Can also exclude specific instance: --filter=alarm,1 + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=item B<--threshold-overload> + +Set to overload default threshold values (syntax: section,[instance,]status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='alarm,1,OK,enabled' + +=back + +=cut diff --git a/hardware/telephony/avaya/mediagateway/snmp/plugin.pm b/hardware/telephony/avaya/mediagateway/snmp/plugin.pm new file mode 100644 index 000000000..76efdfd5b --- /dev/null +++ b/hardware/telephony/avaya/mediagateway/snmp/plugin.pm @@ -0,0 +1,51 @@ +# +# Copyright 2019 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 hardware::telephony::avaya::mediagateway::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}} = ( + 'controller-status' => 'hardware::telephony::avaya::mediagateway::snmp::mode::controllerstatus', + 'cpu' => 'centreon::common::avaya::snmp::mode::cpu', + 'hardware' => 'hardware::telephony::avaya::mediagateway::snmp::mode::hardware', + 'memory' => 'centreon::common::avaya::snmp::mode::memory', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check avaya mediagateway equipment in SNMP. + +=cut diff --git a/hardware/ups/apc/snmp/mode/inputlines.pm b/hardware/ups/apc/snmp/mode/inputlines.pm new file mode 100644 index 000000000..051780b9a --- /dev/null +++ b/hardware/ups/apc/snmp/mode/inputlines.pm @@ -0,0 +1,165 @@ +# +# Copyright 2019 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 hardware::ups::apc::snmp::mode::inputlines; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("Last input line fail cause is '%s'", $self->{result_values}->{last_cause}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{last_cause} = $options{new_datas}->{$self->{instance} . '_upsAdvInputLineFailCause'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'voltage', set => { + key_values => [ { name => 'upsAdvInputLineVoltage' } ], + output_template => 'Voltage : %s V', + perfdatas => [ + { label => 'voltage', value => 'upsAdvInputLineVoltage_absolute', template => '%s', + unit => 'V' }, + ], + } + }, + { label => 'frequence', set => { + key_values => [ { name => 'upsAdvInputFrequency' } ], + output_template => 'Frequence : %s Hz', + perfdatas => [ + { label => 'frequence', value => 'upsAdvInputFrequency_absolute', template => '%s', + unit => 'Hz' }, + ], + } + }, + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'upsAdvInputLineFailCause' } ], + 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 => \&catalog_status_threshold, + } + }, + ]; +} + +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 => '' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +my %map_status = ( + 1 => 'noTransfer', 2 => 'highLineVoltage', 3 => 'brownout', 4 => 'blackout', + 5 => 'smallMomentarySag', 6 => 'deepMomentarySag', 7 => 'smallMomentarySpike', + 8 => 'largeMomentarySpike', 9 => 'selfTest', 10 => 'rateOfVoltageChange', +); + +my $mapping = { + upsAdvInputLineVoltage => { oid => '.1.3.6.1.4.1.318.1.1.1.3.2.1' }, + upsAdvInputFrequency => { oid => '.1.3.6.1.4.1.318.1.1.1.3.2.4' }, + upsAdvInputLineFailCause => { oid => '.1.3.6.1.4.1.318.1.1.1.3.2.5', map => \%map_status }, +}; +my $oid_upsAdvInput = '.1.3.6.1.4.1.318.1.1.1.3.2'; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global} = {}; + my $snmp_result = $options{snmp}->get_table(oid => $oid_upsAdvInput, + nothing_quit => 1); + + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => '0'); + + foreach my $name (keys %{$mapping}) { + $self->{global}->{$name} = $result->{$name}; + } +} + +1; + +__END__ + +=head1 MODE + +Check input lines. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^frequence|voltage$' + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{last_cause} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{last_cause} + +=item B<--warning-*> + +Threshold warning. +Can be: 'voltage', 'frequence'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'voltage', 'frequence'. + +=back + +=cut diff --git a/hardware/ups/apc/snmp/plugin.pm b/hardware/ups/apc/snmp/plugin.pm index 9683ee0e4..54abc9e79 100644 --- a/hardware/ups/apc/snmp/plugin.pm +++ b/hardware/ups/apc/snmp/plugin.pm @@ -29,10 +29,11 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'battery-status' => 'hardware::ups::apc::snmp::mode::batterystatus', - 'output-lines' => 'hardware::ups::apc::snmp::mode::outputlines', - 'sensors' => 'hardware::ups::apc::snmp::mode::sensors', - ); + 'battery-status' => 'hardware::ups::apc::snmp::mode::batterystatus', + 'input-lines' => 'hardware::ups::apc::snmp::mode::inputlines', + 'output-lines' => 'hardware::ups::apc::snmp::mode::outputlines', + 'sensors' => 'hardware::ups::apc::snmp::mode::sensors', + ); return $self; } diff --git a/hardware/ups/mge/snmp/mode/environment.pm b/hardware/ups/mge/snmp/mode/environment.pm index e12888ef7..9b054c132 100644 --- a/hardware/ups/mge/snmp/mode/environment.pm +++ b/hardware/ups/mge/snmp/mode/environment.pm @@ -20,130 +20,72 @@ package hardware::ups::mge::snmp::mode::environment; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -my $maps_counters = { - temperature => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'temperature', no_value => 0, }, - ], - output_template => 'Ambiant Temperature: %.2f C', output_error_template => 'Ambiant Temperature: %s', - perfdatas => [ - { value => 'temperature_absolute', label => 'temperature', template => '%.2f', - unit => 'C' }, - ], - } - }, - humidity => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'humidity', no_value => 0 }, - ], - output_template => 'Humidity: %.2f %%', output_error_template => 'Humidity: %s', - perfdatas => [ - { value => 'humidity_absolute', label => 'humidity', template => '%.2f', - unit => '%', min => 0, max => 100 }, - ], - } - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + ]; -my $oid_upsmgEnvironAmbientTemp = '.1.3.6.1.4.1.705.1.8.1.0'; # in 0.1 degree centigrade -my $oid_upsmgEnvironAmbientHumidity = '.1.3.6.1.4.1.705.1.8.2.0'; # in 0.1 % + $self->{maps_counters}->{global} = [ + { label => 'temperature', nlabel => 'hardware.sensor.temperature.celsius', set => { + key_values => [ { name => 'temperature', no_value => 0, } ], + output_template => 'Ambiant Temperature: %.2f C', output_error_template => 'Ambiant Temperature: %s', + perfdatas => [ + { value => 'temperature_absolute', label => 'temperature', template => '%.2f', + unit => 'C' }, + ], + } + }, + { label => 'humidity', nlabel => 'hardware.sensor.humidity.percentage', set => { + key_values => [ { name => 'humidity', no_value => 0 } ], + output_template => 'Humidity: %.2f %%', output_error_template => 'Humidity: %s', + perfdatas => [ + { value => 'humidity_absolute', label => 'humidity', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.1'; - $options{options}->add_options(arguments => - { - }); + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); - $self->{instance_selected} = {}; - - foreach (keys %{$maps_counters}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } -} - -sub manage_counters { - my ($self, %options) = @_; - - foreach (sort keys %{$options{maps_counters}}) { - $options{maps_counters}->{$_}->{obj}->set(instance => $options{instance}); - - my ($value_check) = $options{maps_counters}->{$_}->{obj}->execute(values => $self->{instance_selected}->{$options{instance}}); - - # We don't want to display no value - next if ($value_check == -10); - if ($value_check != 0) { - next; - } - my $exit = $options{maps_counters}->{$_}->{obj}->threshold_check(); - - my $output = $options{maps_counters}->{$_}->{obj}->output(); - - $self->{output}->output_add(severity => $exit, - short_msg => $output - ); - - $options{maps_counters}->{$_}->{obj}->perfdata(); - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - $self->manage_counters(instance => 'ambiant', maps_counters => $maps_counters); - - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; my $values_ok = 0; - $self->{instance_selected}->{ambiant} = {}; - $self->{results} = $self->{snmp}->get_leef(oids => [$oid_upsmgEnvironAmbientTemp, $oid_upsmgEnvironAmbientHumidity], - nothing_quit => 1); - - if (defined($self->{results}->{$oid_upsmgEnvironAmbientTemp}) && $self->{results}->{$oid_upsmgEnvironAmbientTemp} ne '' && - $self->{results}->{$oid_upsmgEnvironAmbientTemp} != 0) { - $self->{instance_selected}->{ambiant}->{temperature} = $self->{results}->{$oid_upsmgEnvironAmbientTemp} / 10; + my $oid_upsmgEnvironAmbientTemp = '.1.3.6.1.4.1.705.1.8.1.0'; # in 0.1 degree centigrade + my $oid_upsmgEnvironAmbientHumidity = '.1.3.6.1.4.1.705.1.8.2.0'; # in 0.1 % + my $snmp_result = $options{snmp}->get_leef( + oids => [$oid_upsmgEnvironAmbientTemp, $oid_upsmgEnvironAmbientHumidity], + nothing_quit => 1 + ); + + $self->{global} = {}; + if (defined($snmp_result->{$oid_upsmgEnvironAmbientTemp}) && $snmp_result->{$oid_upsmgEnvironAmbientTemp} ne '' && + $snmp_result->{$oid_upsmgEnvironAmbientTemp} != 0) { + $self->{global}->{temperature} = $snmp_result->{$oid_upsmgEnvironAmbientTemp} / 10; $values_ok++; } - if (defined($self->{results}->{$oid_upsmgEnvironAmbientHumidity}) && $self->{results}->{$oid_upsmgEnvironAmbientHumidity} ne '' && - $self->{results}->{$oid_upsmgEnvironAmbientHumidity} != 0) { - $self->{instance_selected}->{ambiant}->{humidity} = $self->{results}->{$oid_upsmgEnvironAmbientHumidity} / 10; + if (defined($snmp_result->{$oid_upsmgEnvironAmbientHumidity}) && $snmp_result->{$oid_upsmgEnvironAmbientHumidity} ne '' && + $snmp_result->{$oid_upsmgEnvironAmbientHumidity} != 0) { + $self->{global}->{humidity} = $snmp_result->{$oid_upsmgEnvironAmbientHumidity} / 10; $values_ok++; } diff --git a/hardware/ups/mge/snmp/mode/inputlines.pm b/hardware/ups/mge/snmp/mode/inputlines.pm index 700df1997..b94c40118 100644 --- a/hardware/ups/mge/snmp/mode/inputlines.pm +++ b/hardware/ups/mge/snmp/mode/inputlines.pm @@ -20,64 +20,77 @@ package hardware::ups::mge::snmp::mode::inputlines; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -my %map_input_status = ( - 1 => 'no', - 2 => 'outoftolvolt', - 3 => 'outoftolfreq', - 4 => 'utilityoff', -); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); -my $maps_counters = { - voltage => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'voltage', no_value => 0, }, - ], - output_template => 'Voltage: %.2f V', output_error_template => 'Voltage: %s', - perfdatas => [ - { value => 'voltage_absolute', label => 'voltage', template => '%.2f', - unit => 'V', min => 0, label_extra_instance => 1 }, - ], - } - }, - current => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'current', no_value => 0 }, - ], - output_template => 'Current: %.2f A', output_error_template => 'Current: %s', - perfdatas => [ - { value => 'current_absolute', label => 'current', template => '%.2f', - unit => 'A', min => 0, label_extra_instance => 1 }, - ], - } - }, - frequence => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'frequence', no_value => 0, }, - ], - output_template => 'Frequence: %.2f Hz', output_error_template => 'Frequence: %s', - perfdatas => [ - { value => 'frequence_absolute', label => 'frequence', template => '%.2f', - unit => 'Hz', min => 0 }, - ], - } - }, -}; +sub custom_status_output { + my ($self, %options) = @_; -my $oid_upsmgInputPhaseNumEntry = '.1.3.6.1.4.1.705.1.6.1'; -my $oid_mginputVoltageEntry = '.1.3.6.1.4.1.705.1.6.2.1.2'; # in dV -my $oid_mginputFrequencyEntry = '.1.3.6.1.4.1.705.1.6.2.1.3'; # in dHz -my $oid_mginputCurrentEntry = '.1.3.6.1.4.1.705.1.6.2.1.6'; # in dA -my $oid_upsmgInputBadStatusEntry = '.1.3.6.1.4.1.705.1.6.3'; -my $oid_upsmgInputLineFailCauseEntry = '.1.3.6.1.4.1.705.1.6.4'; + my $msg = "Input Line(s) bad status is '" . $self->{result_values}->{badstatus} . "' [failcause = " . $self->{result_values}->{failcause} . "]"; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{badstatus} = $options{new_datas}->{$self->{instance} . '_badstatus'}; + $self->{result_values}->{failcause} = $options{new_datas}->{$self->{instance} . '_failcause'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'iline', type => 1, cb_prefix_output => 'prefix_iline_output', message_multiple => 'All input lines are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'status', set => { + key_values => [ { name => 'badstatus' }, { name => 'failcause' } ], + 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 => \&catalog_status_threshold, + } + }, + ]; + + $self->{maps_counters}->{iline} = [ + { label => 'current', set => { + key_values => [ { name => 'mginputCurrent', no_value => 0 } ], + output_template => 'Current : %.2f A', + perfdatas => [ + { label => 'current', value => 'mginputCurrent_absolute', template => '%.2f', + min => 0, unit => 'A', label_extra_instance => 1 }, + ], + } + }, + { label => 'voltage', set => { + key_values => [ { name => 'mginputVoltage', no_value => 0 } ], + output_template => 'Voltage : %.2f V', + perfdatas => [ + { label => 'voltage', value => 'mginputVoltage_absolute', template => '%.2f', + unit => 'V', label_extra_instance => 1 }, + ], + } + }, + { label => 'frequence', set => { + key_values => [ { name => 'mginputFrequency', no_value => 0 } ], + output_template => 'Frequence : %.2f Hz', + perfdatas => [ + { label => 'frequence', value => 'mginputFrequency_absolute', template => '%.2f', + unit => 'Hz', label_extra_instance => 1 }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; @@ -85,169 +98,83 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status', default => '%{badstatus} =~ /yes/' }, + }); - $self->{instance_selected} = {}; - - foreach (keys %{$maps_counters}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->SUPER::check_options(%options); - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } + $self->change_macros(macros => ['warning_status', 'critical_status']); } -sub manage_counters { +sub prefix_iline_output { my ($self, %options) = @_; - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$options{maps_counters}}) { - $options{maps_counters}->{$_}->{obj}->set(instance => $options{instance}); - - my ($value_check) = $options{maps_counters}->{$_}->{obj}->execute(values => $self->{instance_selected}->{$options{instance}}); - # We don't want to display no value - next if ($value_check == -10); - if ($value_check != 0) { - $long_msg .= $long_msg_append . $options{maps_counters}->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $options{maps_counters}->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $options{maps_counters}->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $options{maps_counters}->{$_}->{obj}->perfdata(level => 1, extra_instance => $self->{multiple}); - } - - $self->{output}->output_add(long_msg => $options{label} . " " . $long_msg); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => $options{label} . " " . $short_msg - ); - } - - if ($self->{multiple} == 0) { - $self->{output}->output_add(short_msg => $options{label} . " " . $long_msg); - } + return "Input Line '" . $options{instance_value}->{display} . "' "; } -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; +my %map_input_failcause = ( + 1 => 'no', + 2 => 'outoftolvolt', + 3 => 'outoftolfreq', + 4 => 'utilityoff', +); +my %map_bad_status = ( + 1 => 'yes', + 2 => 'no', +); - $self->manage_selection(); - - $self->{output}->output_add(severity => 'OK', - short_msg => 'Input Line(s) status is ok'); - if (defined($self->{results}->{$oid_upsmgInputBadStatusEntry}->{$oid_upsmgInputBadStatusEntry . '.0'}) && - $self->{results}->{$oid_upsmgInputBadStatusEntry}->{$oid_upsmgInputBadStatusEntry . '.0'} == 1) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Input Line(s) status is '%s'", - $map_input_status{$self->{results}->{$oid_upsmgInputLineFailCauseEntry}->{$oid_upsmgInputLineFailCauseEntry . '.0'}})); - } - - $self->{multiple} = 1; - if (scalar(keys %{$self->{instance_selected}}) == 1) { - $self->{multiple} = 0; - } - - if ($self->{multiple} == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'Input Lines are ok'); - } - - foreach my $id (sort keys %{$self->{instance_selected}}) { - $self->manage_counters(instance => $id, maps_counters => $maps_counters, label => "Input Line '" . $id . "'"); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub add_result { - my ($self, %options) = @_; - - $self->{instance_selected}->{$options{instance}} = {} if (!defined($self->{instance_selected}->{$options{instance}})); - $self->{instance_selected}->{$options{instance}}->{$options{name}} = $self->{results}->{$options{oid}}->{$options{oid} . '.' . $options{instance2}} * 0.1; -} +my $mapping = { + mginputVoltage => { oid => '.1.3.6.1.4.1.705.1.6.2.1.2' }, # in dV + mginputFrequency => { oid => '.1.3.6.1.4.1.705.1.6.2.1.3' }, # in dHz + mginputCurrent => { oid => '.1.3.6.1.4.1.705.1.6.2.1.6' }, # in dA +}; +my $oid_upsmgInput = '.1.3.6.1.4.1.705.1.6'; +my $oid_upsmgInputPhaseEntry = '.1.3.6.1.4.1.705.1.6.2.1'; +my $oid_upsmgInputPhaseNum = '.1.3.6.1.4.1.705.1.6.1.0'; +my $oid_upsmgInputBadStatus = '.1.3.6.1.4.1.705.1.6.3.0'; +my $oid_upsmgInputLineFailCause = '.1.3.6.1.4.1.705.1.6.4.0'; sub manage_selection { my ($self, %options) = @_; - - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_upsmgInputPhaseNumEntry }, - { oid => $oid_mginputVoltageEntry }, - { oid => $oid_mginputFrequencyEntry }, - { oid => $oid_mginputCurrentEntry }, - { oid => $oid_upsmgInputBadStatusEntry }, - { oid => $oid_upsmgInputLineFailCauseEntry }, - ], - , nothing_quit => 1); - if (!defined($self->{results}->{$oid_upsmgInputPhaseNumEntry}->{$oid_upsmgInputPhaseNumEntry . '.0'}) || - $self->{results}->{$oid_upsmgInputPhaseNumEntry}->{$oid_upsmgInputPhaseNumEntry . '.0'} == 0) { + $self->{iline} = {}; + my $snmp_result = $options{snmp}->get_table( + oid => $oid_upsmgInput, + nothing_quit => 1 + ); + + if (!defined($snmp_result->{$oid_upsmgInputPhaseNum}) || + $snmp_result->{$oid_upsmgInputPhaseNum} == 0) { $self->{output}->add_option_msg(short_msg => "No input lines found."); $self->{output}->option_exit(); } - my %instances = (); - # can be 'xxx.1' or 'xxx.1.0' (cannot respect MIB :) - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_mginputVoltageEntry}})) { - $oid =~ /^$oid_mginputVoltageEntry\.((\d+).*)/; - if (scalar(keys %instances) < $self->{results}->{$oid_upsmgInputPhaseNumEntry}->{$oid_upsmgInputPhaseNumEntry . '.0'}) { - $instances{$2} = 1; - $self->add_result(instance => $2, instance2 => $1, name => 'voltage', oid => $oid_mginputVoltageEntry); - } - } - %instances = (); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_mginputCurrentEntry}})) { - $oid =~ /^$oid_mginputCurrentEntry\.((\d+).*)/; - if (scalar(keys %instances) < $self->{results}->{$oid_upsmgInputPhaseNumEntry}->{$oid_upsmgInputPhaseNumEntry . '.0'}) { - $instances{$2} = 1; - $self->add_result(instance => $2, instance2 => $1, name => 'current', oid => $oid_mginputCurrentEntry); - } - } - %instances = (); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_mginputFrequencyEntry}})) { - $oid =~ /^$oid_mginputFrequencyEntry\.((\d+).*)/; - if (scalar(keys %instances) < $self->{results}->{$oid_upsmgInputPhaseNumEntry}->{$oid_upsmgInputPhaseNumEntry . '.0'}) { - $instances{$2} = 1; - $self->add_result(instance => $2, instance2 => $1, name => 'frequence', oid => $oid_mginputFrequencyEntry); - } + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$oid_upsmgInputPhaseEntry\.\d+\.(.*)$/); + my $instance = $1; + next if (defined($self->{iline}->{$instance})); + + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + $result->{mginputVoltage} *= 0.1 if (defined($result->{mginputVoltage})); + $result->{mginputFrequency} *= 0.1 if (defined($result->{mginputFrequency})); + $result->{mginputCurrent} *= 0.1 if (defined($result->{mginputCurrent})); + next if ((!defined($result->{mginputVoltage}) || $result->{mginputVoltage} == 0) && + (!defined($result->{mginputFrequency}) || $result->{mginputFrequency} == 0) && + (!defined($result->{mginputCurrent}) || $result->{mginputCurrent} == 0)); + $self->{iline}->{$instance} = { display => $instance, %$result }; } - if (scalar(keys %{$self->{instance_selected}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No input lines found."); - $self->{output}->option_exit(); - } + $self->{global} = { + badstatus => $map_bad_status{$snmp_result->{$oid_upsmgInputBadStatus}}, + failcause => $map_input_failcause{$snmp_result->{$oid_upsmgInputLineFailCause}}, + }; } 1; @@ -270,6 +197,16 @@ Can be: 'frequence', 'voltage', 'current'. Threshold critical. Can be: 'frequence', 'voltage', 'current'. +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{badstatus}, %{failcause} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{badstatus} =~ /yes/'). +Can used special variables like: %{badstatus}, %{failcause} + =back =cut diff --git a/hardware/ups/mge/snmp/mode/outputlines.pm b/hardware/ups/mge/snmp/mode/outputlines.pm index 6d154499b..db752567a 100644 --- a/hardware/ups/mge/snmp/mode/outputlines.pm +++ b/hardware/ups/mge/snmp/mode/outputlines.pm @@ -20,83 +20,69 @@ package hardware::ups::mge::snmp::mode::outputlines; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -my $maps_counters = { - voltage => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'voltage', no_value => 0 }, - ], - output_template => 'Voltage: %.2f V', output_error_template => 'Voltage: %s', - perfdatas => [ - { value => 'voltage_absolute', label => 'voltage', template => '%.2f', - unit => 'V', min => 0, label_extra_instance => 1 }, - ], - } - }, - current => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'current', no_value => 0 }, - ], - output_template => 'Current: %.2f A', output_error_template => 'Current: %s', - perfdatas => [ - { value => 'current_absolute', label => 'current', template => '%.2f', - unit => 'A', min => 0, label_extra_instance => 1 }, - ], - } - }, - frequence => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'frequence', no_value => 0 }, - ], - output_template => 'Frequence: %.2f Hz', output_error_template => 'Frequence: %s', - perfdatas => [ - { value => 'frequence_absolute', label => 'frequence', template => '%.2f', - unit => 'Hz', min => 0 }, - ], - } - }, - load => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'load', no_value => -1 }, - ], - output_template => 'Load: %.2f %%', output_error_template => 'Load: %s', - perfdatas => [ - { value => 'load_absolute', label => 'load', template => '%.2f', - unit => '%', min => 0 }, - ], - } - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'oline', type => 1, cb_prefix_output => 'prefix_oline_output', message_multiple => 'All output lines are ok', skipped_code => { -10 => 1 } }, + ]; -my $maps_counters2 = { - 'stdev-3phases' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'stdev' }, - ], - output_template => 'Load Standard Deviation : %.2f', output_error_template => 'Load Standard Deviation : %s', - perfdatas => [ - { value => 'stdev_absolute', label => 'stdev', template => '%.2f', - min => 0 }, - ], - } - }, -}; + $self->{maps_counters}->{global} = [ + { label => 'stdev-3phases', nlabel => 'output.3phases.stdev.gauge', set => { + key_values => [ { name => 'stdev' } ], + output_template => 'Load Standard Deviation : %.2f', + perfdatas => [ + { label => 'stdev', value => 'stdev_absolute', template => '%.2f' }, + ], + } + }, + ]; -my $oid_upsmgOutputPhaseNumEntry = '.1.3.6.1.4.1.705.1.7.1'; -my $oid_mgoutputVoltageEntry = '.1.3.6.1.4.1.705.1.7.2.1.2'; # in dV -my $oid_mgoutputFrequencyEntry = '.1.3.6.1.4.1.705.1.7.2.1.3'; # in dHz -my $oid_mgoutputCurrentEntry = '.1.3.6.1.4.1.705.1.7.2.1.5'; # in dA -my $oid_mgoutputLoadPerPhaseEntry = '.1.3.6.1.4.1.705.1.7.2.1.4'; # in % + $self->{maps_counters}->{oline} = [ + { label => 'load', nlabel => 'line.output.load.percentage', set => { + key_values => [ { name => 'mgoutputLoadPerPhase', no_value => 0 } ], + output_template => 'Load : %.2f %%', + perfdatas => [ + { value => 'mgoutputLoadPerPhase_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1 }, + ], + } + }, + { label => 'current', nlabel => 'line.output.current.ampere', set => { + key_values => [ { name => 'mgoutputCurrent', no_value => 0 } ], + output_template => 'Current : %.2f A', + perfdatas => [ + { value => 'mgoutputCurrent_absolute', template => '%.2f', + min => 0, unit => 'A', label_extra_instance => 1 }, + ], + } + }, + { label => 'voltage', nlabel => 'line.output.voltage.volt', set => { + key_values => [ { name => 'mgoutputVoltage', no_value => 0 } ], + output_template => 'Voltage : %.2f V', + perfdatas => [ + { value => 'mgoutputVoltage_absolute', template => '%.2f', + unit => 'V', label_extra_instance => 1 }, + ], + } + }, + { label => 'frequence', nlabel => 'line.output.frequence.hertz', set => { + key_values => [ { name => 'mgoutputFrequency', no_value => -1 } ], + output_template => 'Frequence : %.2f Hz', + perfdatas => [ + { value => 'mgoutputFrequency_absolute', template => '%.2f', + unit => 'Hz', label_extra_instance => 1 }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; @@ -104,195 +90,69 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); - $self->{instance_selected} = {}; - - foreach (keys %{$maps_counters}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - foreach (keys %{$maps_counters2}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters2->{$_}->{class}; - $maps_counters2->{$_}->{obj} = $class->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters2->{$_}->{obj}->set(%{$maps_counters2->{$_}->{set}}); - } - return $self; } -sub check_options { +sub prefix_oline_output { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - foreach (keys %{$maps_counters2}) { - $maps_counters2->{$_}->{obj}->init(option_results => $self->{option_results}); - } + + return "Output Line '" . $options{instance_value}->{display} . "' "; } -sub manage_counters { +sub stdev { my ($self, %options) = @_; - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$options{maps_counters}}) { - $options{maps_counters}->{$_}->{obj}->set(instance => $options{instance}); - - my ($value_check) = $options{maps_counters}->{$_}->{obj}->execute(values => $self->{instance_selected}->{$options{instance}}); - - # We don't want to display no value - next if ($value_check == -10); - if ($value_check != 0) { - $long_msg .= $long_msg_append . $options{maps_counters}->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $options{maps_counters}->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $options{maps_counters}->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $options{maps_counters}->{$_}->{obj}->perfdata(level => 1, extra_instance => $self->{multiple}); - } - - $self->{output}->output_add(long_msg => $options{label} . " " . $long_msg); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => $options{label} . " " . $short_msg - ); + # Calculate stdev + my $total = 0; + my $num_present = scalar(keys %{$self->{oline}}); + foreach my $instance (keys %{$self->{oline}}) { + next if (!defined($self->{oline}->{$instance}->{mgoutputLoadPerPhase})); + $total += $self->{oline}->{$instance}->{mgoutputLoadPerPhase}; } - if ($self->{multiple} == 0) { - $self->{output}->output_add(short_msg => $options{label} . " " . $long_msg); + my $mean = $total / $num_present; + $total = 0; + foreach my $instance (keys %{$self->{oline}}) { + next if (!defined($self->{oline}->{$instance}->{mgoutputLoadPerPhase})); + $total += ($mean - $self->{oline}->{$instance}->{mgoutputLoadPerPhase}) ** 2; } + my $stdev = sqrt($total / $num_present); + $self->{global} = { stdev => $stdev }; } -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - $self->{multiple} = 1; - if (scalar(keys %{$self->{instance_selected}}) == 1) { - $self->{multiple} = 0; - } - - if ($self->{multiple} == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'Output Lines are ok.'); - } - - foreach my $id (sort keys %{$self->{instance_selected}}) { - $self->manage_counters(instance => $id, maps_counters => $maps_counters, label => "Output Line '" . $id . "'"); - } - - if ($self->{results}->{$oid_upsmgOutputPhaseNumEntry}->{$oid_upsmgOutputPhaseNumEntry . '.0'} > 1) { - $self->{instance_selected}->{lines} = { stdev => $self->{stdev} }; - $self->manage_counters(instance => 'lines', maps_counters => $maps_counters2, label => "Output Lines"); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub add_result { - my ($self, %options) = @_; - - $self->{instance_selected}->{$options{instance}} = {} if (!defined($self->{instance_selected}->{$options{instance}})); - $self->{instance_selected}->{$options{instance}}->{$options{name}} = $self->{results}->{$options{oid}}->{$options{oid} . '.' . $options{instance2}} * $options{multiple}; -} +my $mapping = { + mgoutputVoltage => { oid => '.1.3.6.1.4.1.705.1.7.2.1.2' }, # in dV + mgoutputFrequency => { oid => '.1.3.6.1.4.1.705.1.7.2.1.3' }, # in dHz + mgoutputLoadPerPhase => { oid => '.1.3.6.1.4.1.705.1.7.2.1.4' }, # in % + mgoutputCurrent => { oid => '.1.3.6.1.4.1.705.1.7.2.1.5' }, # in dA +}; +my $oid_upsmgOutputPhaseEntry = '.1.3.6.1.4.1.705.1.7.2.1'; sub manage_selection { my ($self, %options) = @_; - - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_upsmgOutputPhaseNumEntry }, - { oid => $oid_mgoutputVoltageEntry }, - { oid => $oid_mgoutputFrequencyEntry }, - { oid => $oid_mgoutputCurrentEntry }, - { oid => $oid_mgoutputLoadPerPhaseEntry }, - ], - , nothing_quit => 1); - if (!defined($self->{results}->{$oid_upsmgOutputPhaseNumEntry}->{$oid_upsmgOutputPhaseNumEntry . '.0'}) || - $self->{results}->{$oid_upsmgOutputPhaseNumEntry}->{$oid_upsmgOutputPhaseNumEntry . '.0'} == 0) { - $self->{output}->add_option_msg(short_msg => "No output lines found."); - $self->{output}->option_exit(); - } + $self->{oline} = {}; + my $snmp_result = $options{snmp}->get_table( + oid => $oid_upsmgOutputPhaseEntry, + nothing_quit => 1 + ); + foreach my $oid (keys %{$snmp_result}) { + $oid =~ /^$oid_upsmgOutputPhaseEntry\.\d+\.(.*)$/; + my $instance = $1; + next if (defined($self->{oline}->{$instance})); - my %instances = (); - # can be 'xxx.1' or 'xxx.1.0' (cannot respect MIB :) - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_mgoutputVoltageEntry}})) { - $oid =~ /^$oid_mgoutputVoltageEntry\.((\d+).*)/; - if (scalar(keys %instances) < $self->{results}->{$oid_upsmgOutputPhaseNumEntry}->{$oid_upsmgOutputPhaseNumEntry . '.0'}) { - $instances{$2} = 1; - $self->add_result(instance => $2, instance2 => $1, name => 'voltage', oid => $oid_mgoutputVoltageEntry, multiple => 0.1); - } - } - %instances = (); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_mgoutputCurrentEntry}})) { - $oid =~ /^$oid_mgoutputCurrentEntry\.((\d+).*)/; - if (scalar(keys %instances) < $self->{results}->{$oid_upsmgOutputPhaseNumEntry}->{$oid_upsmgOutputPhaseNumEntry . '.0'}) { - $instances{$2} = 1; - $self->add_result(instance => $2, instance2 => $1, name => 'current', oid => $oid_mgoutputCurrentEntry, multiple => 0.1); - } - } - %instances = (); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_mgoutputFrequencyEntry}})) { - $oid =~ /^$oid_mgoutputFrequencyEntry\.((\d+).*)/; - if (scalar(keys %instances) < $self->{results}->{$oid_upsmgOutputPhaseNumEntry}->{$oid_upsmgOutputPhaseNumEntry . '.0'}) { - $instances{$2} = 1; - $self->add_result(instance => $2, instance2 => $1, name => 'frequence', oid => $oid_mgoutputFrequencyEntry, multiple => 0.1); - } + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + $result->{mgoutputVoltage} *= 0.1 if (defined($result->{mgoutputVoltage})); + $result->{mgoutputFrequency} *= 0.1 if (defined($result->{mgoutputFrequency})); + $result->{mgoutputCurrent} *= 0.1 if (defined($result->{mgoutputCurrent})); + $self->{oline}->{$instance} = { display => $instance, %$result }; } - %instances = (); - # Calculate stdev - my $total = 0; - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_mgoutputLoadPerPhaseEntry}})) { - $oid =~ /^$oid_mgoutputLoadPerPhaseEntry\.((\d+).*)/; - if (scalar(keys %instances) < $self->{results}->{$oid_upsmgOutputPhaseNumEntry}->{$oid_upsmgOutputPhaseNumEntry . '.0'}) { - $instances{$2} = $self->{results}->{$oid_mgoutputLoadPerPhaseEntry}->{$oid}; - $self->add_result(instance => $2, instance2 => $1, name => 'load', oid => $oid_mgoutputLoadPerPhaseEntry, multiple => 1); - $total += $self->{results}->{$oid_mgoutputLoadPerPhaseEntry}->{$oid}; - } - } - - my $mean = $total / $self->{results}->{$oid_upsmgOutputPhaseNumEntry}->{$oid_upsmgOutputPhaseNumEntry . '.0'}; - $total = 0; - foreach (keys %instances) { - $total += ($mean - $instances{$_}) ** 2; - } - $self->{stdev} = sqrt($total / $self->{results}->{$oid_upsmgOutputPhaseNumEntry}->{$oid_upsmgOutputPhaseNumEntry . '.0'}); - - if (scalar(keys %{$self->{instance_selected}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No output lines found."); - $self->{output}->option_exit(); + if (scalar(keys %{$self->{oline}}) > 1) { + $self->stdev(); } } diff --git a/hardware/ups/powerware/snmp/mode/inputlines.pm b/hardware/ups/powerware/snmp/mode/inputlines.pm index 8627da270..486fee3c9 100644 --- a/hardware/ups/powerware/snmp/mode/inputlines.pm +++ b/hardware/ups/powerware/snmp/mode/inputlines.pm @@ -20,71 +20,61 @@ package hardware::ups::powerware::snmp::mode::inputlines; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -my $maps_counters = { - voltage => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'voltage', no_value => 0, }, - ], - output_template => 'Voltage: %.2f V', output_error_template => 'Voltage: %s', - perfdatas => [ - { value => 'voltage_absolute', label => 'voltage', template => '%.2f', - unit => 'V', min => 0, label_extra_instance => 1 }, - ], - } - }, - current => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'current', no_value => 0 }, - ], - output_template => 'Current: %.2f A', output_error_template => 'Current: %s', - perfdatas => [ - { value => 'current_absolute', label => 'current', template => '%.2f', - unit => 'A', min => 0, label_extra_instance => 1 }, - ], - } - }, - power => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'power', no_value => 0 }, - ], - output_template => 'Power: %.2f W', output_error_template => 'Power: %s', - perfdatas => [ - { value => 'power_absolute', label => 'power', template => '%.2f', - unit => 'W', min => 0, label_extra_instance => 1 }, - ], - } - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'iline', type => 1, cb_prefix_output => 'prefix_iline_output', message_multiple => 'All input lines are ok', skipped_code => { -10 => 1 } }, + ]; -my $maps_counters2 = { - frequence => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'frequence', no_value => 0, }, - ], - output_template => 'Frequence: %.2f Hz', output_error_template => 'Frequence: %s', - perfdatas => [ - { value => 'frequence_absolute', label => 'frequence', template => '%.2f', - unit => 'Hz', min => 0 }, - ], - } - }, -}; + $self->{maps_counters}->{global} = [ + { label => 'frequence', nlabel => 'lines.input.frequence.hertz', set => { + key_values => [ { name => 'xupsInputFrequency', no_value => 0 } ], + output_template => 'Frequence : %.2f Hz', + perfdatas => [ + { value => 'xupsInputFrequency_absolute', template => '%.2f', + unit => 'Hz' }, + ], + } + }, + ]; -my $oid_xupsInputVoltageEntry = '.1.3.6.1.4.1.534.1.3.4.1.2'; # in V -my $oid_xupsInputCurrentEntry = '.1.3.6.1.4.1.534.1.3.4.1.3'; # in A -my $oid_xupsInputWattsEntry = '.1.3.6.1.4.1.534.1.3.4.1.4'; # in W -my $oid_xupsInputFrequencyEntry = '.1.3.6.1.4.1.534.1.3.1'; -my $oid_xupsInputFrequency = '.1.3.6.1.4.1.534.1.3.1.0'; # in dHZ + $self->{maps_counters}->{iline} = [ + { label => 'current', nlabel => 'line.input.current.ampere', set => { + key_values => [ { name => 'xupsInputCurrent', no_value => 0 } ], + output_template => 'Current : %.2f A', + perfdatas => [ + { value => 'xupsInputCurrent_absolute', template => '%.2f', + min => 0, unit => 'A', label_extra_instance => 1 }, + ], + } + }, + { label => 'voltage', nlabel => 'line.input.voltage.volt', set => { + key_values => [ { name => 'xupsInputVoltage', no_value => 0 } ], + output_template => 'Voltage : %.2f V', + perfdatas => [ + { value => 'xupsInputVoltage_absolute', template => '%.2f', + unit => 'V', label_extra_instance => 1 }, + ], + } + }, + { label => 'power', nlabel => 'line.input.power.watt', set => { + key_values => [ { name => 'xupsInputWatts', no_value => 0 } ], + output_template => 'Power: %.2f W', + perfdatas => [ + { value => 'xupsInputWatts_absolute', template => '%.2f', + unit => 'W', label_extra_instance => 1 }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; @@ -92,157 +82,59 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); - $self->{instance_selected} = {}; - - foreach (keys %{$maps_counters}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - foreach (keys %{$maps_counters2}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters2->{$_}->{class}; - $maps_counters2->{$_}->{obj} = $class->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters2->{$_}->{obj}->set(%{$maps_counters2->{$_}->{set}}); - } - return $self; } -sub check_options { +sub prefix_iline_output { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - foreach (keys %{$maps_counters2}) { - $maps_counters2->{$_}->{obj}->init(option_results => $self->{option_results}); - } + + return "Input Line '" . $options{instance_value}->{display} . "' "; } -sub manage_counters { - my ($self, %options) = @_; - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$options{maps_counters}}) { - $options{maps_counters}->{$_}->{obj}->set(instance => $options{instance}); - - my ($value_check) = $options{maps_counters}->{$_}->{obj}->execute(values => $self->{instance_selected}->{$options{instance}}); +my $mapping = { + xupsInputVoltage => { oid => '.1.3.6.1.4.1.534.1.3.4.1.2' }, # in V + xupsInputCurrent => { oid => '.1.3.6.1.4.1.534.1.3.4.1.3' }, # in A + xupsInputWatts => { oid => '.1.3.6.1.4.1.534.1.3.4.1.4' }, # in W +}; +my $mapping2 = { + xupsInputFrequency => { oid => '.1.3.6.1.4.1.534.1.3.1' }, # in dHZ +}; - # We don't want to display no value - next if ($value_check == -10); - if ($value_check != 0) { - $long_msg .= $long_msg_append . $options{maps_counters}->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $options{maps_counters}->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $options{maps_counters}->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $options{maps_counters}->{$_}->{obj}->perfdata(level => 1, extra_instance => $self->{multiple}); - } - - $self->{output}->output_add(long_msg => $options{label} . " " . $long_msg); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => $options{label} . " " . $short_msg - ); - } - - if ($self->{multiple} == 0) { - $self->{output}->output_add(short_msg => $options{label} . " " . $long_msg); - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - $self->{multiple} = 1; - if (scalar(keys %{$self->{instance_selected}}) == 1) { - $self->{multiple} = 0; - } - - if ($self->{multiple} == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'Input Lines are ok.'); - } - - foreach my $id (sort keys %{$self->{instance_selected}}) { - $self->manage_counters(instance => $id, maps_counters => $maps_counters, label => "Input Line '" . $id . "'"); - } - - if (defined($self->{results}->{$oid_xupsInputFrequencyEntry}->{$oid_xupsInputFrequencyEntry . '.0'})) { - $self->{instance_selected}->{frequence} = { frequence => $self->{results}->{$oid_xupsInputFrequencyEntry}->{$oid_xupsInputFrequencyEntry . '.0'} * 0.1 }; - $self->manage_counters(instance => 'frequence', maps_counters => $maps_counters2, label => "Input Lines"); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub add_result { - my ($self, %options) = @_; - - $self->{instance_selected}->{$options{instance}} = {} if (!defined($self->{instance_selected}->{$options{instance}})); - $self->{instance_selected}->{$options{instance}}->{$options{name}} = $self->{results}->{$options{oid}}->{$options{oid} . '.' . $options{instance}}; -} +my $oid_xupsInputEntry = '.1.3.6.1.4.1.534.1.3.4.1'; sub manage_selection { my ($self, %options) = @_; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_xupsInputVoltageEntry }, - { oid => $oid_xupsInputCurrentEntry }, - { oid => $oid_xupsInputWattsEntry }, - { oid => $oid_xupsInputFrequencyEntry }, - ], - , nothing_quit => 1); - - foreach my $oid (keys %{$self->{results}->{$oid_xupsInputVoltageEntry}}) { - $oid =~ /^$oid_xupsInputVoltageEntry\.(\d)$/; - $self->add_result(instance => $1, name => 'voltage', oid => $oid_xupsInputVoltageEntry); - } - foreach my $oid (keys %{$self->{results}->{$oid_xupsInputCurrentEntry}}) { - $oid =~ /^$oid_xupsInputCurrentEntry\.(\d)$/; - $self->add_result(instance => $1, name => 'current', oid => $oid_xupsInputCurrentEntry); - } - foreach my $oid (keys %{$self->{results}->{$oid_xupsInputWattsEntry}}) { - $oid =~ /^$oid_xupsInputWattsEntry\.(\d)$/; - $self->add_result(instance => $1, name => 'power', oid => $oid_xupsInputWattsEntry); + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $mapping2->{xupsInputFrequency}->{oid} }, + { oid => $oid_xupsInputEntry }, + ], + return_type => 1, nothing_quit => 1 + ); + + $self->{iline} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$oid_xupsInputEntry\.\d+\.(.*)$/); + my $instance = $1; + next if (defined($self->{iline}->{$instance})); + + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + $self->{iline}->{$instance} = { display => $instance, %$result }; } - if (scalar(keys %{$self->{instance_selected}}) <= 0) { + if (scalar(keys %{$self->{iline}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No input lines found."); $self->{output}->option_exit(); - } + } + + my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result, instance => '0'); + + $result->{xupsInputFrequency} = defined($result->{xupsInputFrequency}) ? ($result->{xupsInputFrequency} * 0.1) : 0; + $self->{global} = { %$result }; } 1; diff --git a/hardware/ups/powerware/snmp/mode/outputlines.pm b/hardware/ups/powerware/snmp/mode/outputlines.pm index 294195029..ba586b19e 100644 --- a/hardware/ups/powerware/snmp/mode/outputlines.pm +++ b/hardware/ups/powerware/snmp/mode/outputlines.pm @@ -20,85 +20,70 @@ package hardware::ups::powerware::snmp::mode::outputlines; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -my $maps_counters = { - voltage => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'voltage', no_value => 0 }, - ], - output_template => 'Voltage: %.2f V', output_error_template => 'Voltage: %s', - perfdatas => [ - { value => 'voltage_absolute', label => 'voltage', template => '%.2f', - unit => 'V', min => 0, label_extra_instance => 1 }, - ], - } - }, - current => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'current', no_value => 0 }, - ], - output_template => 'Current: %.2f A', output_error_template => 'Current: %s', - perfdatas => [ - { value => 'current_absolute', label => 'current', template => '%.2f', - unit => 'A', min => 0, label_extra_instance => 1 }, - ], - } - }, - power => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'power', no_value => 0 }, - ], - output_template => 'Power: %.2f W', output_error_template => 'Power: %s', - perfdatas => [ - { value => 'power_absolute', label => 'power', template => '%.2f', - unit => 'W', min => 0, label_extra_instance => 1 }, - ], - } - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'oline', type => 1, cb_prefix_output => 'prefix_oline_output', message_multiple => 'All output lines are ok', skipped_code => { -10 => 1 } }, + ]; -my $maps_counters2 = { - frequence => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'frequence', no_value => 0 }, - ], - output_template => 'Frequence: %.2f Hz', output_error_template => 'Frequence: %s', - perfdatas => [ - { value => 'frequence_absolute', label => 'frequence', template => '%.2f', - unit => 'Hz', min => 0 }, - ], - } - }, - load => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'load', no_value => -1 }, - ], - output_template => 'Load: %.2f %%', output_error_template => 'Load: %s', - perfdatas => [ - { value => 'load_absolute', label => 'load', template => '%.2f', - unit => '%', min => 0 }, - ], - } - }, -}; + $self->{maps_counters}->{global} = [ + { label => 'load', nlabel => 'lines.output.load.percentage', set => { + key_values => [ { name => 'xupsOutputLoad', no_value => -1 } ], + output_template => 'Load : %.2f %%', + perfdatas => [ + { value => 'xupsOutputLoad_absolute', template => '%.2f', + min => 0, max => 100 }, + ], + } + }, + { label => 'frequence', nlabel => 'lines.output.frequence.hertz', set => { + key_values => [ { name => 'xupsOutputFrequency', no_value => 0 } ], + output_template => 'Frequence : %.2f Hz', + perfdatas => [ + { value => 'xupsOutputFrequency_absolute', template => '%.2f', + unit => 'Hz' }, + ], + } + }, + ]; -my $oid_xupsOutputVoltageEntry = '.1.3.6.1.4.1.534.1.4.4.1.2'; # in V -my $oid_xupsOutputCurrentEntry = '.1.3.6.1.4.1.534.1.4.4.1.3'; # in A -my $oid_xupsOutputWattsEntry = '.1.3.6.1.4.1.534.1.4.4.1.4'; # in W -my $oid_xupsOutputFrequencyEntry = '.1.3.6.1.4.1.534.1.4.2'; -my $oid_xupsOutputFrequency = '.1.3.6.1.4.1.534.1.4.2.0'; # in dHZ -my $oid_xupsOutputLoadEntry = '.1.3.6.1.4.1.534.1.4.1'; -my $oid_xupsOutputLoad = '.1.3.6.1.4.1.534.1.4.1.0'; # in % + $self->{maps_counters}->{oline} = [ + { label => 'current', nlabel => 'line.output.current.ampere', set => { + key_values => [ { name => 'xupsOutputCurrent', no_value => 0 } ], + output_template => 'Current : %.2f A', + perfdatas => [ + { value => 'xupsOutputCurrent_absolute', template => '%.2f', + min => 0, unit => 'A', label_extra_instance => 1 }, + ], + } + }, + { label => 'voltage', nlabel => 'line.output.voltage.volt', set => { + key_values => [ { name => 'xupsOutputVoltage', no_value => 0 } ], + output_template => 'Voltage : %.2f V', + perfdatas => [ + { value => 'xupsOutputVoltage_absolute', template => '%.2f', + unit => 'V', label_extra_instance => 1 }, + ], + } + }, + { label => 'power', nlabel => 'line.output.power.watt', set => { + key_values => [ { name => 'xupsOutputWatts', no_value => 0 } ], + output_template => 'Power: %.2f W', + perfdatas => [ + { value => 'xupsOutputWatts_absolute', template => '%.2f', + unit => 'W', label_extra_instance => 1 }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; @@ -106,157 +91,59 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); - $self->{instance_selected} = {}; - - foreach (keys %{$maps_counters}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - foreach (keys %{$maps_counters2}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters2->{$_}->{class}; - $maps_counters2->{$_}->{obj} = $class->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters2->{$_}->{obj}->set(%{$maps_counters2->{$_}->{set}}); - } - return $self; } -sub check_options { +sub prefix_oline_output { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - foreach (keys %{$maps_counters2}) { - $maps_counters2->{$_}->{obj}->init(option_results => $self->{option_results}); - } + + return "Output Line '" . $options{instance_value}->{display} . "' "; } -sub manage_counters { - my ($self, %options) = @_; - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$options{maps_counters}}) { - $options{maps_counters}->{$_}->{obj}->set(instance => $options{instance}); - - my ($value_check) = $options{maps_counters}->{$_}->{obj}->execute(values => $self->{instance_selected}->{$options{instance}}); +my $mapping = { + xupsOutputVoltage => { oid => '.1.3.6.1.4.1.534.1.4.4.1.2' }, # in V + xupsOutputCurrent => { oid => '.1.3.6.1.4.1.534.1.4.4.1.3' }, # in A + xupsOutputWatts => { oid => '.1.3.6.1.4.1.534.1.4.4.1.4' }, # in W +}; +my $mapping2 = { + xupsOutputLoad => { oid => '.1.3.6.1.4.1.534.1.4.1' }, # in % + xupsOutputFrequency => { oid => '.1.3.6.1.4.1.534.1.4.2' }, # in dHZ +}; - # We don't want to display no value - next if ($value_check == -10); - if ($value_check != 0) { - $long_msg .= $long_msg_append . $options{maps_counters}->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $options{maps_counters}->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $options{maps_counters}->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $options{maps_counters}->{$_}->{obj}->perfdata(level => 1, extra_instance => $self->{multiple}); - } - - $self->{output}->output_add(long_msg => $options{label} . " " . $long_msg); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => $options{label} . " " . $short_msg - ); - } - - if ($self->{multiple} == 0) { - $self->{output}->output_add(short_msg => $options{label} . " " . $long_msg); - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - $self->{multiple} = 1; - if (scalar(keys %{$self->{instance_selected}}) == 1) { - $self->{multiple} = 0; - } - - if ($self->{multiple} == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'Output Lines are ok.'); - } - - foreach my $id (sort keys %{$self->{instance_selected}}) { - $self->manage_counters(instance => $id, maps_counters => $maps_counters, label => "Output Line '" . $id . "'"); - } - - $self->{instance_selected}->{lines} = { frequence => defined($self->{results}->{$oid_xupsOutputFrequencyEntry}->{$oid_xupsOutputFrequency}) ? $self->{results}->{$oid_xupsOutputFrequencyEntry}->{$oid_xupsOutputFrequency} * 0.1 : 0, - load => defined($self->{results}->{$oid_xupsOutputLoadEntry}->{$oid_xupsOutputLoad}) ? $self->{results}->{$oid_xupsOutputLoadEntry}->{$oid_xupsOutputLoad} : -1 }; - $self->manage_counters(instance => 'lines', maps_counters => $maps_counters2, label => "Output Lines"); - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub add_result { - my ($self, %options) = @_; - - $self->{instance_selected}->{$options{instance}} = {} if (!defined($self->{instance_selected}->{$options{instance}})); - $self->{instance_selected}->{$options{instance}}->{$options{name}} = $self->{results}->{$options{oid}}->{$options{oid} . '.' . $options{instance}}; -} +my $oid_xupsOutput = '.1.3.6.1.4.1.534.1.4'; +my $oid_xupsOutputEntry = '.1.3.6.1.4.1.534.1.4.4.1'; sub manage_selection { my ($self, %options) = @_; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_xupsOutputVoltageEntry }, - { oid => $oid_xupsOutputCurrentEntry }, - { oid => $oid_xupsOutputWattsEntry }, - { oid => $oid_xupsOutputFrequencyEntry }, - { oid => $oid_xupsOutputLoadEntry }, - ], - , nothing_quit => 1); - - foreach my $oid (keys %{$self->{results}->{$oid_xupsOutputVoltageEntry}}) { - $oid =~ /^$oid_xupsOutputVoltageEntry\.(\d)$/; - $self->add_result(instance => $1, name => 'voltage', oid => $oid_xupsOutputVoltageEntry); - } - foreach my $oid (keys %{$self->{results}->{$oid_xupsOutputCurrentEntry}}) { - $oid =~ /^$oid_xupsOutputCurrentEntry\.(\d)$/; - $self->add_result(instance => $1, name => 'current', oid => $oid_xupsOutputCurrentEntry); - } - foreach my $oid (keys %{$self->{results}->{$oid_xupsOutputWattsEntry}}) { - $oid =~ /^$oid_xupsOutputWattsEntry\.(\d)$/; - $self->add_result(instance => $1, name => 'power', oid => $oid_xupsOutputWattsEntry); + $self->{oline} = {}; + my $snmp_result = $options{snmp}->get_table( + oid => $oid_xupsOutput, + nothing_quit => 1 + ); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$oid_xupsOutputEntry\.\d+\.(.*)$/); + my $instance = $1; + next if (defined($self->{oline}->{$instance})); + + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + $self->{oline}->{$instance} = { display => $instance, %$result }; } - if (scalar(keys %{$self->{instance_selected}}) <= 0) { + if (scalar(keys %{$self->{oline}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No output lines found."); $self->{output}->option_exit(); - } + } + + my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result, instance => '0'); + + $result->{xupsOutputFrequency} = defined($result->{xupsOutputFrequency}) ? ($result->{xupsOutputFrequency} * 0.1) : 0; + $result->{xupsOutputLoad} = defined($result->{xupsOutputLoad}) ? $result->{xupsOutputLoad} : -1; + $self->{global} = { %$result }; } 1; diff --git a/hardware/ups/standard/rfc1628/snmp/mode/outputlines.pm b/hardware/ups/standard/rfc1628/snmp/mode/outputlines.pm index ef7c0bd2e..6d34d78d4 100644 --- a/hardware/ups/standard/rfc1628/snmp/mode/outputlines.pm +++ b/hardware/ups/standard/rfc1628/snmp/mode/outputlines.pm @@ -20,48 +20,69 @@ package hardware::ups::standard::rfc1628::snmp::mode::outputlines; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my %oids = ( - '.1.3.6.1.2.1.33.1.4.4.1.5' => { counter => 'load', no_present => -1 }, # upsOutputPercentLoad - '.1.3.6.1.2.1.33.1.4.4.1.2' => { counter => 'voltage', no_present => 0 }, # in Volt upsOutputVoltage - '.1.3.6.1.2.1.33.1.4.4.1.3' => { counter => 'current', no_present => 0 }, # in dA upsOutputCurrent - '.1.3.6.1.2.1.33.1.4.4.1.4' => { counter => 'power', no_present => 0 }, # in Watt upsOutputPower -); +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'oline', type => 1, cb_prefix_output => 'prefix_oline_output', message_multiple => 'All output lines are ok', skipped_code => { -10 => 1 } }, + ]; -my $maps_counters = { - load => { thresholds => { - warning_frequence => { label => 'warning-load', exit_value => 'warning' }, - critical_frequence => { label => 'critical-load', exit_value => 'critical' }, - }, - output_msg => 'Load : %.2f %%', no_present => -1, - factor => 1, unit => '%', - }, - voltage => { thresholds => { - warning_voltage => { label => 'warning-voltage', exit_value => 'warning' }, - critical_voltage => { label => 'critical-voltage', exit_value => 'critical' }, - }, - output_msg => 'Voltage : %.2f V', no_present => 0, - factor => 1, unit => 'V', - }, - current => { thresholds => { - warning_current => { label => 'warning-current', exit_value => 'warning' }, - critical_current => { label => 'critical-current', exit_value => 'critical' }, - }, - output_msg => 'Current : %.2f A', no_present => 0, - factor => 0.1, unit => 'A', - }, - power => { thresholds => { - warning_power => { label => 'warning-power', exit_value => 'warning' }, - critical_power => { label => 'critical-power', exit_value => 'critical' }, - }, - output_msg => 'Power : %.2f W', no_present => 0, - factor => 1, unit => 'W', - }, -}; + $self->{maps_counters}->{global} = [ + { label => 'stdev-3phases', nlabel => 'output.3phases.stdev.gauge', set => { + key_values => [ { name => 'stdev' } ], + output_template => 'Load Standard Deviation : %.2f', + perfdatas => [ + { label => 'stdev', value => 'stdev_absolute', template => '%.2f' }, + ], + } + }, + ]; + + $self->{maps_counters}->{oline} = [ + { label => 'load', nlabel => 'line.output.load.percentage', set => { + key_values => [ { name => 'upsOutputPercentLoad' } ], + output_template => 'Load : %.2f %%', + perfdatas => [ + { value => 'upsOutputPercentLoad_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1 }, + ], + } + }, + { label => 'current', nlabel => 'line.output.current.ampere', set => { + key_values => [ { name => 'upsOutputCurrent' } ], + output_template => 'Current : %.2f A', + perfdatas => [ + { value => 'upsOutputCurrent_absolute', template => '%.2f', + min => 0, unit => 'A', label_extra_instance => 1 }, + ], + } + }, + { label => 'voltage', nlabel => 'line.output.voltage.volt', set => { + key_values => [ { name => 'upsOutputVoltage' } ], + output_template => 'Voltage : %.2f V', + perfdatas => [ + { value => 'upsOutputVoltage_absolute', template => '%.2f', + unit => 'V', label_extra_instance => 1 }, + ], + } + }, + { label => 'power', nlabel => 'line.output.power.watt', set => { + key_values => [ { name => 'upsOutputPower' } ], + output_template => 'Power : %.2f W', + perfdatas => [ + { value => 'upsOutputPower_absolute', template => '%.2f', + unit => 'W', label_extra_instance => 1 }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; @@ -69,69 +90,16 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning-stdev-3phases:s" => { name => 'warning_stdev' }, - "critical-stdev-3phases:s" => { name => 'critical_stdev' }, - }); - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - } - } + $options{options}->add_options(arguments => { + }); - $self->{counters_value} = {}; - $self->{instances_done} = {}; return $self; } -sub check_options { +sub prefix_oline_output { my ($self, %options) = @_; - $self->SUPER::init(%options); - if (($self->{perfdata}->threshold_validate(label => 'warning-stdev-3phases', value => $self->{option_results}->{warning_stdev})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning-stdev-3phases threshold '" . $self->{option_results}->{warning_stdev} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical-stdev-3phases', value => $self->{option_results}->{critical_stdev})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical-stdev-3phases threshold '" . $self->{option_results}->{critical_stdev} . "'."); - $self->{output}->option_exit(); - } - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - } - } - } -} - -sub build_values { - my ($self, %options) = @_; - my $counters_value = {}; - my $instance = undef; - - foreach my $oid (keys %oids) { - if ($options{current} =~ /^$oid\.(.*)/) { - $instance = $1; - last; - } - } - - # Skip already done - if (!defined($instance) || defined($self->{instances_done}->{$instance})) { - return 0; - } - - $self->{instances_done}->{$instance} = 1; - $self->{counters_value}->{$instance} = {}; - foreach my $oid (keys %oids) { - $self->{counters_value}->{$instance}->{$oids{$oid}->{counter}} = defined($options{result}->{$oid . '.' . $instance}) ? $options{result}->{$oid . '.' . $instance} : $oids{$oid}->{no_present}; - } + return "Output Line '" . $options{instance_value}->{display} . "' "; } sub stdev { @@ -139,86 +107,51 @@ sub stdev { # Calculate stdev my $total = 0; - my $num_present = 0; - foreach my $instance (keys %{$self->{instances_done}}) { - next if ($self->{counters_value}->{$instance}->{load} == -1); # Not present - $total += $self->{counters_value}->{$instance}->{load}; - $num_present++; + my $num_present = scalar(keys %{$self->{oline}}); + foreach my $instance (keys %{$self->{oline}}) { + next if (!defined($self->{oline}->{$instance}->{upsOutputPercentLoad})); + $total += $self->{oline}->{$instance}->{upsOutputPercentLoad}; } + my $mean = $total / $num_present; $total = 0; - foreach my $instance (keys %{$self->{instances_done}}) { - next if ($self->{counters_value}->{$instance}->{load} == -1); # Not present - $total += ($mean - $self->{counters_value}->{$instance}->{load}) ** 2; + foreach my $instance (keys %{$self->{oline}}) { + next if (!defined($self->{oline}->{$instance}->{upsOutputPercentLoad})); + $total += ($mean - $self->{oline}->{$instance}->{upsOutputPercentLoad}) ** 2; } my $stdev = sqrt($total / $num_present); - - my $exit = $self->{perfdata}->threshold_check(value => $stdev, threshold => [ { label => 'critical-stdev-3phases', 'exit_litteral' => 'critical' }, { label => 'warning-stdev-3phases', exit_litteral => 'warning' } ]); - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Load Standard Deviation : %.2f", $stdev)); - - $self->{output}->perfdata_add(label => 'stdev', - value => sprintf("%.2f", $stdev), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-stdev-3phases'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-stdev-3phases')); + $self->{global} = { stdev => $stdev }; } -sub run { +my $mapping = { + upsOutputVoltage => { oid => '.1.3.6.1.2.1.33.1.4.4.1.2' }, # in Volt + upsOutputCurrent => { oid => '.1.3.6.1.2.1.33.1.4.4.1.3' }, # in dA + upsOutputPower => { oid => '.1.3.6.1.2.1.33.1.4.4.1.4' }, # in Watt + upsOutputPercentLoad => { oid => '.1.3.6.1.2.1.33.1.4.4.1.5' }, +}; +my $oid_upsOutputEntry = '.1.3.6.1.2.1.33.1.4.4.1'; + +sub manage_selection { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - my $oid_upsOutputEntry = '.1.3.6.1.2.1.33.1.4.4.1'; - my $result = $self->{snmp}->get_table(oid => $oid_upsOutputEntry, nothing_quit => 1); - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - $self->build_values(current => $key, result => $result); - } - my $num = scalar(keys %{$self->{instances_done}}); - foreach my $instance (keys %{$self->{instances_done}}) { - my $instance_output = $instance; - $instance_output =~ s/\./#/g; + $self->{oline} = {}; + my $snmp_result = $options{snmp}->get_table( + oid => $oid_upsOutputEntry, + nothing_quit => 1 + ); + foreach my $oid (keys %{$snmp_result}) { + $oid =~ /^$oid_upsOutputEntry\.\d+\.(.*)$/; + my $instance = $1; + next if (defined($self->{oline}->{$instance})); - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (defined($self->{counters_value}->{$instance}->{$_}) && $self->{counters_value}->{$instance}->{$_} =~ /\d/ && $self->{counters_value}->{$instance}->{$_} != $maps_counters->{$_}->{no_present}) { - push @exits, $self->{perfdata}->threshold_check(value => $self->{counters_value}->{$instance}->{$_} * $maps_counters->{$_}->{factor}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - my $extra_label = ''; - $extra_label = '_' . $instance_output if ($num > 1); - - my $str_output = "Output Line '$instance_output' "; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - next if (!defined($self->{counters_value}->{$instance}->{$_}) || $self->{counters_value}->{$instance}->{$_} !~ /\d/ || $self->{counters_value}->{$instance}->{$_} == $maps_counters->{$_}->{no_present}); - - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $self->{counters_value}->{$instance}->{$_} * $maps_counters->{$_}->{factor}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => $maps_counters->{$_}->{unit}, - value => sprintf("%.2f", $self->{counters_value}->{$instance}->{$_} * $maps_counters->{$_}->{factor}), - warning => $warning, - critical => $critical); - } - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + $result->{upsOutputCurrent} *= 0.1 if (defined($result->{upsOutputCurrent})); + $self->{oline}->{$instance} = { display => $instance, %$result }; } - if ($num > 1) { + if (scalar(keys %{$self->{oline}}) > 1) { $self->stdev(); } - - $self->{output}->display(); - $self->{output}->exit(); } 1; diff --git a/network/3com/snmp/mode/cpu.pm b/network/3com/snmp/mode/cpu.pm index 9f8a9a281..41e59276c 100644 --- a/network/3com/snmp/mode/cpu.pm +++ b/network/3com/snmp/mode/cpu.pm @@ -32,7 +32,7 @@ sub set_counters { { name => 'cpu', type => 1, cb_prefix_output => 'prefix_cpu_output', message_multiple => 'All CPU usages are ok' } ]; $self->{maps_counters}->{cpu} = [ - { label => '5s', set => { + { label => '5s', nlabel => 'cpu.utilization.5s.percentage', set => { key_values => [ { name => 'usage_5s' }, { name => 'display' } ], output_template => '%s %% (5sec)', output_error_template => "%s (5sec)", perfdatas => [ @@ -41,7 +41,7 @@ sub set_counters { ], } }, - { label => '1m', set => { + { label => '1m', nlabel => 'cpu.utilization.1m.percentage', set => { key_values => [ { name => 'usage_1m' }, { name => 'display' } ], output_template => '%s %% (1m)', output_error_template => "%s (1min)", perfdatas => [ @@ -50,7 +50,7 @@ sub set_counters { ], } }, - { label => '5m', set => { + { label => '5m', nlabel => 'cpu.utilization.5m.percentage', set => { key_values => [ { name => 'usage_5m' }, { name => 'display' } ], output_template => '%s %% (5min)', output_error_template => "%s (5min)", perfdatas => [ diff --git a/network/3com/snmp/mode/memory.pm b/network/3com/snmp/mode/memory.pm index 93f267d8d..311b74515 100644 --- a/network/3com/snmp/mode/memory.pm +++ b/network/3com/snmp/mode/memory.pm @@ -27,22 +27,22 @@ use warnings; sub custom_usage_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + nlabel => $self->{nlabel}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -80,7 +80,7 @@ sub set_counters { ]; $self->{maps_counters}->{memory} = [ - { label => 'usage', set => { + { label => 'usage', nlabel => 'memory.usage.bytes', set => { key_values => [ { name => 'display' }, { name => 'total' }, { name => 'used' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_output => $self->can('custom_usage_output'), diff --git a/network/a10/ax/snmp/mode/cpu.pm b/network/a10/ax/snmp/mode/cpu.pm index 0cd72c148..195c1cc86 100644 --- a/network/a10/ax/snmp/mode/cpu.pm +++ b/network/a10/ax/snmp/mode/cpu.pm @@ -33,7 +33,7 @@ sub set_counters { ]; $self->{maps_counters}->{cpu} = [ - { label => 'cpu-30s', set => { + { label => 'cpu-30s', nlabel => 'cpu.utilization.30s.percentage', set => { key_values => [ { name => 'cpu_30s' }, { name => 'display' } ], output_template => '30s : %s %%', perfdatas => [ @@ -42,7 +42,7 @@ sub set_counters { ], } }, - { label => 'cpu-1m', set => { + { label => 'cpu-1m', nlabel => 'cpu.utilization.1m.percentage', set => { key_values => [ { name => 'cpu_1m' }, { name => 'display' } ], output_template => '1m : %s %%', perfdatas => [ diff --git a/network/a10/ax/snmp/mode/disk.pm b/network/a10/ax/snmp/mode/disk.pm index 7d4ffd6df..000ecda8c 100644 --- a/network/a10/ax/snmp/mode/disk.pm +++ b/network/a10/ax/snmp/mode/disk.pm @@ -29,16 +29,17 @@ sub custom_usage_perfdata { my ($self, %options) = @_; $self->{output}->perfdata_add(label => 'used', unit => 'B', + nlabel => $self->{nlabel}, value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), min => 0, max => $self->{result_values}->{total}); } sub custom_usage_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -76,7 +77,7 @@ sub set_counters { ]; $self->{maps_counters}->{disk} = [ - { label => 'usage', set => { + { label => 'usage', nlabel => 'disk.usage.bytes', set => { key_values => [ { name => 'free' }, { name => 'total' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_output => $self->can('custom_usage_output'), diff --git a/network/a10/ax/snmp/mode/globalstats.pm b/network/a10/ax/snmp/mode/globalstats.pm index 24f99b05f..a597691dc 100644 --- a/network/a10/ax/snmp/mode/globalstats.pm +++ b/network/a10/ax/snmp/mode/globalstats.pm @@ -34,7 +34,7 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'current-connections', set => { + { label => 'current-connections', nlabel => 'connections.current.count', set => { key_values => [ { name => 'current_connections' } ], output_template => 'Current Connections : %s', perfdatas => [ @@ -43,7 +43,7 @@ sub set_counters { ], } }, - { label => 'total-connections', set => { + { label => 'total-connections', nlabel => 'connections.total.count', set => { key_values => [ { name => 'total_connections', diff => 1 } ], output_template => 'Total Connections : %s', perfdatas => [ @@ -52,7 +52,7 @@ sub set_counters { ], } }, - { label => 'total-ssl-connections', set => { + { label => 'total-ssl-connections', nlabel => 'connections.ssl.total.count', set => { key_values => [ { name => 'total_ssl_connections', diff => 1 } ], output_template => 'Total SSL Connections : %s', perfdatas => [ diff --git a/network/a10/ax/snmp/mode/hardware.pm b/network/a10/ax/snmp/mode/hardware.pm index 25a17f847..c90c051e6 100644 --- a/network/a10/ax/snmp/mode/hardware.pm +++ b/network/a10/ax/snmp/mode/hardware.pm @@ -60,9 +60,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } @@ -165,11 +164,14 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("fan '%s' speed is %s rpm", $result->{axFanName}, $result->{axFanSpeed})); } - $self->{output}->perfdata_add(label => $result->{axFanName}, unit => 'rpm', - value => $result->{axFanSpeed}, - warning => $warn, - critical => $crit, min => 0 - ); + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $result->{axFanName}, + value => $result->{axFanSpeed}, + warning => $warn, + critical => $crit, min => 0 + ); } } } @@ -250,11 +252,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("physical temperature is %s C", $result->{axSysHwPhySystemTemp})); } - $self->{output}->perfdata_add(label => 'temperature_physical', unit => 'C', - value => $result->{axSysHwPhySystemTemp}, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => 'physical', + value => $result->{axSysHwPhySystemTemp}, + warning => $warn, + critical => $crit + ); } 1; diff --git a/network/a10/ax/snmp/mode/memory.pm b/network/a10/ax/snmp/mode/memory.pm index 2eaffd72e..8c2eeeb70 100644 --- a/network/a10/ax/snmp/mode/memory.pm +++ b/network/a10/ax/snmp/mode/memory.pm @@ -29,16 +29,17 @@ sub custom_usage_perfdata { my ($self, %options) = @_; $self->{output}->perfdata_add(label => 'used', unit => 'B', + nlabel => $self->{nlabel}, value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), min => 0, max => $self->{result_values}->{total}); } sub custom_usage_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -76,7 +77,7 @@ sub set_counters { ]; $self->{maps_counters}->{memory} = [ - { label => 'usage', set => { + { label => 'usage', nlabel => 'memory.usage.bytes', set => { key_values => [ { name => 'used' }, { name => 'total' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_output => $self->can('custom_usage_output'), diff --git a/network/a10/ax/snmp/mode/vserverusage.pm b/network/a10/ax/snmp/mode/vserverusage.pm index 7d506ca41..0b2f85e1b 100644 --- a/network/a10/ax/snmp/mode/vserverusage.pm +++ b/network/a10/ax/snmp/mode/vserverusage.pm @@ -58,7 +58,7 @@ sub set_counters { closure_custom_threshold_check => \&catalog_status_threshold, } }, - { label => 'current-con', set => { + { label => 'current-con', nlabel => 'virtualserver.connections.current.count', set => { key_values => [ { name => 'axVirtualServerStatCurConns' }, { name => 'display' } ], output_template => 'Current Connections : %s', perfdatas => [ @@ -67,7 +67,7 @@ sub set_counters { ], } }, - { label => 'total-con', set => { + { label => 'total-con', nlabel => 'virtualserver.connections.total.count', set => { key_values => [ { name => 'axVirtualServerStatTotConns', diff => 1 }, { name => 'display' } ], output_template => 'Total Connections : %s', perfdatas => [ @@ -76,7 +76,7 @@ sub set_counters { ], } }, - { label => 'traffic-in', set => { + { label => 'traffic-in', nlabel => 'virtualserver.traffic.in.bitspersecond', set => { key_values => [ { name => 'axVirtualServerStatBytesIn', diff => 1 }, { name => 'display' } ], per_second => 1, output_change_bytes => 2, output_template => 'Traffic In : %s %s/s', @@ -86,7 +86,7 @@ sub set_counters { ], } }, - { label => 'traffic-out', set => { + { label => 'traffic-out', nlabel => 'virtualserver.traffic.out.bitspersecond', set => { key_values => [ { name => 'axVirtualServerStatBytesOut', diff => 1 }, { name => 'display' } ], per_second => 1, output_change_bytes => 2, output_template => 'Traffic Out : %s %s/s', diff --git a/network/acmepacket/snmp/mode/components/fan.pm b/network/acmepacket/snmp/mode/components/fan.pm index 5d4abe7cc..a0a9b8f83 100644 --- a/network/acmepacket/snmp/mode/components/fan.pm +++ b/network/acmepacket/snmp/mode/components/fan.pm @@ -68,11 +68,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '%s' is '%s' %%", $result->{apEnvMonFanStatusDescr}, $result->{apEnvMonFanStatusValue})); } - $self->{output}->perfdata_add(label => 'fan_' . $result->{apEnvMonFanStatusDescr}, unit => '%', - value => $result->{apEnvMonFanStatusValue}, - warning => $warn, - critical => $crit, min => 0, max => 100 - ); + $self->{output}->perfdata_add( + label => 'fan', unit => '%', + nlabel => 'hardware.fan.speed.percentage', + instances => $result->{apEnvMonFanStatusDescr}, + value => $result->{apEnvMonFanStatusValue}, + warning => $warn, + critical => $crit, min => 0, max => 100 + ); } } diff --git a/network/acmepacket/snmp/mode/components/temperature.pm b/network/acmepacket/snmp/mode/components/temperature.pm index a7bd62ee8..0886e3e55 100644 --- a/network/acmepacket/snmp/mode/components/temperature.pm +++ b/network/acmepacket/snmp/mode/components/temperature.pm @@ -69,11 +69,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is '%s' C", $result->{apEnvMonTemperatureStatusDescr}, $result->{apEnvMonTemperatureStatusValue})); } - $self->{output}->perfdata_add(label => 'temperature_' . $result->{apEnvMonTemperatureStatusDescr}, unit => 'C', - value => $result->{apEnvMonTemperatureStatusValue}, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $result->{apEnvMonTemperatureStatusDescr}, + value => $result->{apEnvMonTemperatureStatusValue}, + warning => $warn, + critical => $crit + ); } } diff --git a/network/acmepacket/snmp/mode/components/voltage.pm b/network/acmepacket/snmp/mode/components/voltage.pm index cee94e7b6..17c96cca9 100644 --- a/network/acmepacket/snmp/mode/components/voltage.pm +++ b/network/acmepacket/snmp/mode/components/voltage.pm @@ -70,11 +70,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Voltage '%s' is '%s' V", $result->{apEnvMonVoltageStatusDescr}, $result->{apEnvMonVoltageStatusValue})); } - $self->{output}->perfdata_add(label => 'voltage_' . $result->{apEnvMonVoltageStatusDescr}, unit => 'V', - value => $result->{apEnvMonVoltageStatusValue}, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'voltage', unit => 'V', + nlabel => 'hardware.voltage.volt', + instances => $result->{apEnvMonVoltageStatusDescr}, + value => $result->{apEnvMonVoltageStatusValue}, + warning => $warn, + critical => $crit + ); } } diff --git a/network/acmepacket/snmp/mode/realmusage.pm b/network/acmepacket/snmp/mode/realmusage.pm index e24983c96..a5d35354b 100644 --- a/network/acmepacket/snmp/mode/realmusage.pm +++ b/network/acmepacket/snmp/mode/realmusage.pm @@ -34,7 +34,7 @@ sub set_counters { ]; $self->{maps_counters}->{realm} = [ - { label => 'current-in-sessions', set => { + { label => 'current-in-sessions', nlabel => 'realm.sessions.in.current.count', set => { key_values => [ { name => 'apSigRealmStatsCurrentActiveSessionsInbound' }, { name => 'display' } ], output_template => 'Current Inbound Sessions : %s', perfdatas => [ @@ -43,7 +43,7 @@ sub set_counters { ], } }, - { label => 'current-in-sessions-rate', set => { + { label => 'current-in-sessions-rate', nlabel => 'realm.sessions.in.rate.count', set => { key_values => [ { name => 'apSigRealmStatsCurrentSessionRateInbound' }, { name => 'display' } ], output_template => 'Current Inbound Sessions Rate : %s/s', perfdatas => [ @@ -52,7 +52,7 @@ sub set_counters { ], } }, - { label => 'total-in-sessions', set => { + { label => 'total-in-sessions', nlabel => 'realm.sessions.in.total.count', set => { key_values => [ { name => 'apSigRealmStatsTotalSessionsInbound', diff => 1 }, { name => 'display' } ], output_template => 'Total Inbound Sessions : %s', perfdatas => [ @@ -61,7 +61,7 @@ sub set_counters { ], } }, - { label => 'current-out-sessions', set => { + { label => 'current-out-sessions', nlabel => 'realm.sessions.out.current.count', set => { key_values => [ { name => 'apSigRealmStatsCurrentActiveSessionsOutbound' }, { name => 'display' } ], output_template => 'Current Outbound Sessions : %s', perfdatas => [ @@ -70,7 +70,7 @@ sub set_counters { ], } }, - { label => 'current-out-sessions-rate', set => { + { label => 'current-out-sessions-rate', nlabel => 'realm.sessions.out.current.count', set => { key_values => [ { name => 'apSigRealmStatsCurrentSessionRateOutbound' }, { name => 'display' } ], output_template => 'Current Outbound Sessions Rate : %s/s', perfdatas => [ @@ -79,7 +79,7 @@ sub set_counters { ], } }, - { label => 'total-out-sessions', set => { + { label => 'total-out-sessions', nlabel => 'realm.sessions.out.total.count', set => { key_values => [ { name => 'apSigRealmStatsTotalSessionsOutbound', diff => 1 }, { name => 'display' } ], output_template => 'Total Outbound Sessions : %s', perfdatas => [ @@ -88,7 +88,7 @@ sub set_counters { ], } }, - { label => 'avg-qos-rfactor', set => { + { label => 'avg-qos-rfactor', nlabel => 'realm.rfactor.qos.average.count', set => { key_values => [ { name => 'apSigRealmStatsAverageQoSRFactor' }, { name => 'display' } ], output_template => 'Average QoS RFactor : %s', perfdatas => [ @@ -97,7 +97,7 @@ sub set_counters { ], } }, - { label => 'total-rfactor', set => { + { label => 'total-rfactor', nlabel => 'realm.rfactor.execeded.total.count', set => { key_values => [ { name => 'apSigRealmStatsTotalMajorRFactorExceeded', diff => 1 }, { name => 'display' } ], output_template => 'Total Rfactor Exceeded : %s', perfdatas => [ diff --git a/network/acmepacket/snmp/mode/sipusage.pm b/network/acmepacket/snmp/mode/sipusage.pm index b79b2ba8a..65578e2b2 100644 --- a/network/acmepacket/snmp/mode/sipusage.pm +++ b/network/acmepacket/snmp/mode/sipusage.pm @@ -57,7 +57,7 @@ sub set_counters { closure_custom_threshold_check => \&catalog_status_threshold, } }, - { label => 'in-sessions-rate', set => { + { label => 'in-sessions-rate', nlabel => 'sip.sessions.in.rate', set => { key_values => [ { name => 'apSipSAStatsTotalSessionsInbound', diff => 1 }, { name => 'display' } ], output_template => 'Inbound Sessions Rate : %.2f/s', per_second => 1, @@ -67,7 +67,7 @@ sub set_counters { ], } }, - { label => 'out-sessions-rate', set => { + { label => 'out-sessions-rate', nlabel => 'sip.sessions.out.rate', set => { key_values => [ { name => 'apSipSAStatsTotalSessionsOutbound', diff => 1 }, { name => 'display' } ], output_template => 'Outbound Sessions Rate : %.2f/s', per_second => 1, @@ -77,7 +77,7 @@ sub set_counters { ], } }, - { label => 'latency', set => { + { label => 'latency', nlabel => 'sip.stats.latency.milliseconds', set => { key_values => [ { name => 'apSipSAStatsAverageLatency' }, { name => 'display' } ], output_template => 'Average Latency : %s ms', perfdatas => [ @@ -86,7 +86,7 @@ sub set_counters { ], } }, - { label => 'asr', set => { + { label => 'asr', nlabel => 'sip.stats.asr.percentage', set => { key_values => [ { name => 'apSipSAStatsPeriodASR' }, { name => 'display' } ], output_template => 'Answer-to-seizure Ratio : %s %%', perfdatas => [ diff --git a/network/acmepacket/snmp/mode/systemusage.pm b/network/acmepacket/snmp/mode/systemusage.pm index 427b6e763..8aa44ed19 100644 --- a/network/acmepacket/snmp/mode/systemusage.pm +++ b/network/acmepacket/snmp/mode/systemusage.pm @@ -48,7 +48,7 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'health-score', set => { + { label => 'health-score', nlabel => 'health.score.percentage', set => { key_values => [ { name => 'health_score' } ], output_template => 'Health Score : %.2f %%', perfdatas => [ @@ -57,7 +57,7 @@ sub set_counters { ], } }, - { label => 'cpu-load', set => { + { label => 'cpu-load', nlabel => 'cpu.utilization.percentage', set => { key_values => [ { name => 'cpu_load' } ], output_template => 'Cpu Load : %.2f %%', perfdatas => [ @@ -66,7 +66,7 @@ sub set_counters { ], } }, - { label => 'memory-usage', set => { + { label => 'memory-usage', nlabel => 'memory.usage.percentage', set => { key_values => [ { name => 'memory_used' } ], output_template => 'Memory Used : %.2f %%', perfdatas => [ @@ -75,7 +75,7 @@ sub set_counters { ], } }, - { label => 'license-usage', set => { + { label => 'license-usage', nlabel => 'licence.usage.percentage', set => { key_values => [ { name => 'license_used' } ], output_template => 'License Used : %.2f %%', perfdatas => [ @@ -84,7 +84,7 @@ sub set_counters { ], } }, - { label => 'current-sessions', set => { + { label => 'current-sessions', nlabel => 'sessions.current.count', set => { key_values => [ { name => 'current_sessions' } ], output_template => 'Current Sessions : %s', perfdatas => [ @@ -93,7 +93,7 @@ sub set_counters { ], } }, - { label => 'current-calls', set => { + { label => 'current-calls', nlabel => 'calls.current.count', set => { key_values => [ { name => 'current_calls' } ], output_template => 'Current Calls : %s/s', perfdatas => [ @@ -143,6 +143,7 @@ sub manage_selection { 4 => 'outOfService', 5 => 'unassigned', 6 => 'activePending', 7 => 'standbyPending', 8 => 'outOfServicePending', 9 => 'recovery', ); + my $oid_apSysCPUUtil = '.1.3.6.1.4.1.9148.3.2.1.1.1.0'; my $oid_apSysMemoryUtil = '.1.3.6.1.4.1.9148.3.2.1.1.2.0'; my $oid_apSysHealthScore = '.1.3.6.1.4.1.9148.3.2.1.1.3.0'; @@ -155,6 +156,7 @@ sub manage_selection { $oid_apSysLicenseCapacity, $oid_apSysGlobalConSess, $oid_apSysGlobalCPS ], nothing_quit => 1); + $self->{global} = { cpu_load => $result->{$oid_apSysCPUUtil}, memory_used => $result->{$oid_apSysMemoryUtil}, diff --git a/network/adva/fsp3000/snmp/mode/interfaces.pm b/network/adva/fsp3000/snmp/mode/interfaces.pm index 5130ce721..052e31a75 100644 --- a/network/adva/fsp3000/snmp/mode/interfaces.pm +++ b/network/adva/fsp3000/snmp/mode/interfaces.pm @@ -36,72 +36,70 @@ sub set_oids_traffic { $self->{currentEthRxHighSpeed1dayBytes} = '.1.3.6.1.4.1.2544.1.11.2.6.2.89.1.4'; # in B } +sub set_counters_traffic { + my ($self, %options) = @_; + + push @{$self->{maps_counters}->{int}}, + { label => 'traffic-in', filter => 'add_traffic', nlabel => 'interface.traffic.in.bitspersecond', set => { + key_values => [ { name => 'traffic_in_15min', diff => 1 }, { name => 'traffic_in_1day', 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' }, + closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic In : %s', + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }, + { label => 'traffic-out', filter => 'add_traffic', nlabel => 'interface.traffic.out.bitspersecond', set => { + key_values => [ { name => 'traffic_out_15min', diff => 1 }, { name => 'traffic_out_1day', 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' }, + closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic Out : %s', + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }, + ; +} + sub set_counters { my ($self, %options) = @_; - $self->{maps_counters} = { int => {}, global => {} }; - $self->{maps_counters}->{int}->{'030_traffic-in'} = { filter => 'add_traffic', - set => { - key_values => [ { name => 'traffic_in_15min', diff => 1 }, { name => 'traffic_in_1day', 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' }, - closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic In : %s', - closure_custom_perfdata => $self->can('custom_traffic_perfdata'), - closure_custom_threshold_check => $self->can('custom_traffic_threshold'), - } - }; - $self->{maps_counters}->{int}->{'031_traffic-out'} = { filter => 'add_traffic', - set => { - key_values => [ { name => 'traffic_out_15min', diff => 1 }, { name => 'traffic_out_1day', 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' }, - closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic Out : %s', - closure_custom_perfdata => $self->can('custom_traffic_perfdata'), - closure_custom_threshold_check => $self->can('custom_traffic_threshold'), - } - }; - $self->{maps_counters}->{int}->{'090_laser-temp'} = { filter => 'add_optical', - set => { - key_values => [ { name => 'laser_temp' }, { name => 'display' } ], - output_template => 'Laser Temperature : %.2f C', output_error_template => 'Laser Temperature : %.2f', - perfdatas => [ - { label => 'laser_temp', value => 'laser_temp_absolute', template => '%.2f', - unit => 'C', label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }; - $self->{maps_counters}->{int}->{'091_input-power'} = { filter => 'add_optical', - set => { - key_values => [ { name => 'input_power' }, { name => 'display' } ], - output_template => 'Input Power : %s dBm', output_error_template => 'Input Power : %s', - perfdatas => [ - { label => 'input_power', value => 'input_power_absolute', template => '%s', - unit => 'dBm', label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }; - $self->{maps_counters}->{int}->{'091_output-power'} = { filter => 'add_optical', - set => { - key_values => [ { name => 'output_power' }, { name => 'display' } ], - output_template => 'Output Power : %s dBm', output_error_template => 'Output Power : %s', - perfdatas => [ - { label => 'output_power', value => 'output_power_absolute', template => '%s', - unit => 'dBm', label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }; - $self->SUPER::set_counters(%options); + + push @{$self->{maps_counters}->{int}}, + { label => 'laser-temp', filter => 'add_optical', nlabel => 'interface.laser.temperature.celsius', set => { + key_values => [ { name => 'laser_temp' }, { name => 'display' } ], + output_template => 'Laser Temperature : %.2f C', output_error_template => 'Laser Temperature : %.2f', + perfdatas => [ + { label => 'laser_temp', value => 'laser_temp_absolute', template => '%.2f', + unit => 'C', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'input-power', filter => 'add_optical', nlabel => 'interface.input.power.dbm', set => { + key_values => [ { name => 'input_power' }, { name => 'display' } ], + output_template => 'Input Power : %s dBm', output_error_template => 'Input Power : %s', + perfdatas => [ + { label => 'input_power', value => 'input_power_absolute', template => '%s', + unit => 'dBm', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'output-power', filter => 'add_optical', nlabel => 'interface.output.power.dbm', set => { + key_values => [ { name => 'output_power' }, { name => 'display' } ], + output_template => 'Output Power : %s dBm', output_error_template => 'Output Power : %s', + perfdatas => [ + { label => 'output_power', value => 'output_power_absolute', template => '%s', + unit => 'dBm', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ; } 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 ($self->{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); @@ -111,11 +109,15 @@ sub custom_traffic_perfdata { $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}); } - $self->{output}->perfdata_add(label => 'traffic_' . $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}); + $self->{output}->perfdata_add( + label => 'traffic_' . $self->{result_values}->{label}, unit => 'b/s', + nlabel => $self->{nlabel}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{traffic_per_seconds}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed} + ); } sub custom_traffic_threshold { @@ -123,9 +125,9 @@ sub custom_traffic_threshold { my $exit = 'ok'; if ($self->{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' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } elsif ($self->{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' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_per_seconds}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } return $exit; } @@ -173,15 +175,26 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_set_traffic => 1, no_errors => 1, no_cast => 1); bless $self, $class; - $options{options}->add_options(arguments => - { - "add-optical" => { name => 'add_optical' }, - } + $options{options}->add_options(arguments => { + 'add-optical' => { name => 'add_optical' }, + } ); return $self; } +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->{checking} = ''; + foreach (('add_global', 'add_status', 'add_traffic', 'add_speed', 'add_volume', 'add_optical')) { + if (defined($self->{option_results}->{$_})) { + $self->{checking} .= $_; + } + } +} + my $oid_opticalIfDiagLaserTemp = '.1.3.6.1.4.1.2544.1.11.2.4.3.5.1.2'; my $oid_opticalIfDiagInputPower = '.1.3.6.1.4.1.2544.1.11.2.4.3.5.1.3'; my $oid_opticalIfDiagOutputPower = '.1.3.6.1.4.1.2544.1.11.2.4.3.5.1.4'; @@ -197,24 +210,24 @@ sub custom_load { sub custom_add_result { my ($self, %options) = @_; - + return if (!defined($self->{option_results}->{add_optical})); - $self->{interface_selected}->{$options{instance}}->{laser_temp} = undef; + $self->{int}->{$options{instance}}->{laser_temp} = undef; if (defined($self->{results}->{$oid_opticalIfDiagLaserTemp . '.' . $options{instance}}) && $self->{results}->{$oid_opticalIfDiagLaserTemp . '.' . $options{instance}} != -2147483648) { - $self->{interface_selected}->{$options{instance}}->{laser_temp} = $self->{results}->{$oid_opticalIfDiagLaserTemp . '.' . $options{instance}} * 0.1; + $self->{int}->{$options{instance}}->{laser_temp} = $self->{results}->{$oid_opticalIfDiagLaserTemp . '.' . $options{instance}} * 0.1; } - $self->{interface_selected}->{$options{instance}}->{input_power} = undef; + $self->{int}->{$options{instance}}->{input_power} = undef; if (defined($self->{results}->{$oid_opticalIfDiagInputPower . '.' . $options{instance}}) && $self->{results}->{$oid_opticalIfDiagInputPower . '.' . $options{instance}} != -65535) { - $self->{interface_selected}->{$options{instance}}->{input_power} = $self->{results}->{$oid_opticalIfDiagInputPower . '.' . $options{instance}} / 10; + $self->{int}->{$options{instance}}->{input_power} = $self->{results}->{$oid_opticalIfDiagInputPower . '.' . $options{instance}} / 10; } - $self->{interface_selected}->{$options{instance}}->{output_power} = undef; + $self->{int}->{$options{instance}}->{output_power} = undef; if (defined($self->{results}->{$oid_opticalIfDiagOutputPower . '.' . $options{instance}}) && $self->{results}->{$oid_opticalIfDiagOutputPower . '.' . $options{instance}} != -65535) { - $self->{interface_selected}->{$options{instance}}->{output_power} = $self->{results}->{$oid_opticalIfDiagOutputPower . '.' . $options{instance}} / 10; + $self->{int}->{$options{instance}}->{output_power} = $self->{results}->{$oid_opticalIfDiagOutputPower . '.' . $options{instance}} / 10; } } @@ -235,26 +248,26 @@ sub load_traffic { sub add_result_traffic { my ($self, %options) = @_; - $self->{interface_selected}->{$options{instance}}->{traffic_in_15min} = + $self->{int}->{$options{instance}}->{traffic_in_15min} = defined($self->{results}->{$self->{currentEthRxHighSpeed15minBytes} . '.' . $options{instance}}) ? $self->{results}->{$self->{currentEthRxHighSpeed15minBytes} . '.' . $options{instance}} * 8 : (defined($self->{results}->{$self->{currentEthRx15minBytes} . '.' . $options{instance}}) ? $self->{results}->{$self->{currentEthRx15minBytes} . '.' . $options{instance}} * 8 : undef); - $self->{interface_selected}->{$options{instance}}->{traffic_in_1day} = + $self->{int}->{$options{instance}}->{traffic_in_1day} = defined($self->{results}->{$self->{currentEthRxHighSpeed1dayBytes} . '.' . $options{instance}}) ? $self->{results}->{$self->{currentEthRxHighSpeed1dayBytes} . '.' . $options{instance}} * 8 : (defined($self->{results}->{$self->{currentEthRx1dayBytes} . '.' . $options{instance}}) ? $self->{results}->{$self->{currentEthRx1dayBytes} . '.' . $options{instance}} * 8 : undef); - $self->{interface_selected}->{$options{instance}}->{traffic_out_15min} = + $self->{int}->{$options{instance}}->{traffic_out_15min} = defined($self->{results}->{$self->{currentEthTx15minBytes} . '.' . $options{instance}}) ? $self->{results}->{$self->{currentEthTx15minBytes} . '.' . $options{instance}} * 8 : undef; - $self->{interface_selected}->{$options{instance}}->{traffic_out_1day} = + $self->{int}->{$options{instance}}->{traffic_out_1day} = defined($self->{results}->{$self->{currentEthTx1dayBytes} . '.' . $options{instance}}) ? $self->{results}->{$self->{currentEthTx1dayBytes} . '.' . $options{instance}} * 8 : undef; - $self->{interface_selected}->{$options{instance}}->{speed_in} = 0; - $self->{interface_selected}->{$options{instance}}->{speed_out} = 0; + $self->{int}->{$options{instance}}->{speed_in} = 0; + $self->{int}->{$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->{int}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed} * 1000000; + $self->{int}->{$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 ''); + $self->{int}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed_in} * 1000000 if (defined($self->{option_results}->{speed_in}) && $self->{option_results}->{speed_in} ne ''); + $self->{int}->{$options{instance}}->{speed_out} = $self->{option_results}->{speed_out} * 1000000 if (defined($self->{option_results}->{speed_out}) && $self->{option_results}->{speed_out} ne ''); } } diff --git a/network/aerohive/snmp/mode/connectedusers.pm b/network/aerohive/snmp/mode/connectedusers.pm index 2829f309e..527b7001e 100644 --- a/network/aerohive/snmp/mode/connectedusers.pm +++ b/network/aerohive/snmp/mode/connectedusers.pm @@ -33,7 +33,7 @@ sub set_counters { { name => 'ssid', type => 1, cb_prefix_output => 'prefix_ssid_output', message_multiple => 'All users by SSID are ok' }, ]; $self->{maps_counters}->{global} = [ - { label => 'total', set => { + { label => 'total', nlabel => 'users.current.count', set => { key_values => [ { name => 'total' } ], output_template => 'Total Users : %s', perfdatas => [ @@ -44,7 +44,7 @@ sub set_counters { }, ]; $self->{maps_counters}->{ssid} = [ - { label => 'ssid', set => { + { label => 'ssid', nlabel => 'ssid.users.current.count', set => { key_values => [ { name => 'total' }, { name => 'display' } ], output_template => 'users : %s', perfdatas => [ diff --git a/network/alcatel/isam/snmp/mode/components/cardtemperature.pm b/network/alcatel/isam/snmp/mode/components/cardtemperature.pm index 4dfa79231..c13135fba 100644 --- a/network/alcatel/isam/snmp/mode/components/cardtemperature.pm +++ b/network/alcatel/isam/snmp/mode/components/cardtemperature.pm @@ -59,13 +59,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Card '%s' temperature is %s C", $name, $temperature)); } - $self->{output}->perfdata_add(label => 'cardtemperature_' . $name, - unit => 'C', - value => $temperature, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'cardtemperature', unit => 'C', + nlabel => 'hardware.card.temperature.celsius', + instances => $name, + value => $temperature, + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/network/alcatel/isam/snmp/mode/components/sfp.pm b/network/alcatel/isam/snmp/mode/components/sfp.pm index 68cc4f2d9..057269b73 100644 --- a/network/alcatel/isam/snmp/mode/components/sfp.pm +++ b/network/alcatel/isam/snmp/mode/components/sfp.pm @@ -84,12 +84,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Sfp '%s' voltage is %s VDC", $name, $value)); } - $self->{output}->perfdata_add(label => 'sfp_voltage_' . $name, - unit => 'VDC', - value => $value, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'sfp_voltage', unit => 'vdc', + nlabel => 'hardware.sfp.voltage.voltdc', + instances => $name, + value => $value, + warning => $warn, + critical => $crit + ); } if ($result2->{sfpDiagTemperature} =~ /(\S+)\s+degrees Celsius/i) { @@ -99,12 +101,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Sfp '%s' temperature is %s C", $name, $value)); } - $self->{output}->perfdata_add(label => 'sfp_temperature_' . $name, - unit => 'C', - value => $value, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'sfp_temperature', unit => 'C', + nlabel => 'hardware.sfp.temperature.celsius', + instances => $name, + value => $value, + warning => $warn, + critical => $crit + ); } if ($result2->{sfpDiagTxPower} =~ /(\S+)\s+dBm/i) { @@ -114,12 +118,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Sfp '%s' tx power is %s dBm", $name, $value)); } - $self->{output}->perfdata_add(label => 'sfp_txpower_' . $name, - unit => 'dBm', - value => $value, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'sfp_txpower', unit => 'dBm', + nlabel => 'hardware.sfp.txpower.dbm', + instances => $name, + value => $value, + warning => $warn, + critical => $crit + ); } if ($result2->{sfpDiagRxPower} =~ /(\S+)\s+dBm/i) { @@ -129,12 +135,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Sfp '%s' rx power is %s dBm", $name, $value)); } - $self->{output}->perfdata_add(label => 'sfp_rxpower_' . $name, - unit => 'dBm', - value => $value, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'sfp_rxpower', unit => 'dBm', + nlabel => 'hardware.sfp.rxpower.dbm', + instances => $name, + value => $value, + warning => $warn, + critical => $crit + ); } if ($result2->{sfpDiagTxBiasCurrent} =~ /(\S+)\s+mA/i) { @@ -144,12 +152,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Sfp '%s' current is %s mA", $name, $value)); } - $self->{output}->perfdata_add(label => 'sfp_current_' . $name, - unit => 'mA', - value => $value, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'sfp_current', unit => 'mA', + nlabel => 'hardware.sfp.current.milliampere', + instances => $name, + value => $value, + warning => $warn, + critical => $crit + ); } } } diff --git a/network/alcatel/isam/snmp/mode/cpu.pm b/network/alcatel/isam/snmp/mode/cpu.pm index dc72eb2ac..01e979b61 100644 --- a/network/alcatel/isam/snmp/mode/cpu.pm +++ b/network/alcatel/isam/snmp/mode/cpu.pm @@ -33,7 +33,7 @@ sub set_counters { ]; $self->{maps_counters}->{cpu} = [ - { label => 'usage', set => { + { label => 'usage', nlabel => 'cpu.utilization.percentage', set => { key_values => [ { name => 'usage' }, { name => 'display' }, ], output_template => 'Usage : %.2f %%', perfdatas => [ diff --git a/network/alcatel/isam/snmp/mode/hubsapusage.pm b/network/alcatel/isam/snmp/mode/hubsapusage.pm index ce02eeec3..b0767fe1b 100644 --- a/network/alcatel/isam/snmp/mode/hubsapusage.pm +++ b/network/alcatel/isam/snmp/mode/hubsapusage.pm @@ -45,7 +45,7 @@ sub set_counters { closure_custom_threshold_check => $self->can('custom_status_threshold'), } }, - { label => 'in-traffic', set => { + { label => 'in-traffic', nlabel => 'sap.traffic.in.bitspersecond', set => { key_values => [ { name => 'in', diff => 1 }, { name => 'display' } ], per_second => 1, closure_custom_calc => $self->can('custom_sap_calc'), closure_custom_calc_extra_options => { label_ref => 'in' }, @@ -54,7 +54,7 @@ sub set_counters { closure_custom_threshold_check => $self->can('custom_qsap_threshold'), } }, - { label => 'out-traffic', set => { + { label => 'out-traffic', nlabel => 'sap.traffic.out.bitspersecond', set => { key_values => [ { name => 'out', diff => 1 }, { name => 'display' } ], per_second => 1, closure_custom_calc => $self->can('custom_sap_calc'), closure_custom_calc_extra_options => { label_ref => 'out' }, @@ -66,7 +66,7 @@ sub set_counters { ]; $self->{maps_counters}->{global} = [ - { label => 'total-in-traffic', set => { + { label => 'total-in-traffic', nlabel => 'sap.traffic.in.bitspersecond', set => { key_values => [], manual_keys => 1, per_second => 1, output_change_bytes => 2, closure_custom_calc => $self->can('custom_total_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'in' }, @@ -75,7 +75,7 @@ sub set_counters { closure_custom_threshold_check => $self->can('custom_total_traffic_threshold'), } }, - { label => 'total-out-traffic', set => { + { label => 'total-out-traffic', nlabel => 'sap.traffic.out.bitspersecond', set => { key_values => [], manual_keys => 1, per_second => 1, output_change_bytes => 2, closure_custom_calc => $self->can('custom_total_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'out' }, @@ -92,18 +92,21 @@ sub custom_total_traffic_perfdata { my ($warning, $critical); if ($self->{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); + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); } elsif ($self->{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}); + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}); } - $self->{output}->perfdata_add(label => 'total_traffic_' . $self->{result_values}->{label}, unit => 'b/s', - value => sprintf("%.2f", $self->{result_values}->{total_traffic}), - warning => $warning, - critical => $critical, - min => 0, max => $self->{result_values}->{speed}); + $self->{output}->perfdata_add( + label => 'total_traffic_' . $self->{result_values}->{label}, unit => 'b/s', + nlabel => $self->{nlabel}, + value => sprintf("%.2f", $self->{result_values}->{total_traffic}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed} + ); } sub custom_total_traffic_threshold { @@ -111,9 +114,9 @@ sub custom_total_traffic_threshold { my $exit = 'ok'; if ($self->{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' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } elsif ($self->{instance_mode}->{option_results}->{units_traffic} eq 'b/s') { - $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{total_traffic}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{total_traffic}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } return $exit; } @@ -211,26 +214,25 @@ sub custom_status_calc { sub custom_sap_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 ($self->{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); + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); } elsif ($self->{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}); + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}); } - $self->{output}->perfdata_add(label => 'traffic_' . $self->{result_values}->{label} . $extra_label, unit => 'b/s', - value => sprintf("%.2f", $self->{result_values}->{traffic}), - warning => $warning, - critical => $critical, - min => 0, max => $self->{result_values}->{speed}); + $self->{output}->perfdata_add( + label => 'traffic_' . $self->{result_values}->{label}, unit => 'b/s', + nlabel => $self->{nlabel}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{traffic}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed} + ); } sub custom_sap_threshold { @@ -238,9 +240,9 @@ sub custom_sap_threshold { my $exit = 'ok'; if ($self->{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' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } elsif ($self->{instance_mode}->{option_results}->{units_traffic} eq 'b/s') { - $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } return $exit; } @@ -281,19 +283,18 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "reload-cache-time:s" => { name => 'reload_cache_time', default => 300 }, - "display-name:s" => { name => 'display_name', default => '%{SvcDescription}.%{IfName}.%{SapEncapName}' }, - "filter-name:s" => { name => 'filter_name' }, - "speed-in:s" => { name => 'speed_in' }, - "speed-out:s" => { name => 'speed_out' }, - "speed-total-in:s" => { name => 'speed_total_in' }, - "speed-total-out:s" => { name => 'speed_total_out' }, - "units-traffic:s" => { name => 'units_traffic', default => '%' }, - "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '%{admin} =~ /up/i and %{status} !~ /up/i' }, - }); + $options{options}->add_options(arguments => { + "reload-cache-time:s" => { name => 'reload_cache_time', default => 300 }, + "display-name:s" => { name => 'display_name', default => '%{SvcDescription}.%{IfName}.%{SapEncapName}' }, + "filter-name:s" => { name => 'filter_name' }, + "speed-in:s" => { name => 'speed_in' }, + "speed-out:s" => { name => 'speed_out' }, + "speed-total-in:s" => { name => 'speed_total_in' }, + "speed-total-out:s" => { name => 'speed_total_out' }, + "units-traffic:s" => { name => 'units_traffic', default => '%' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{admin} =~ /up/i and %{status} !~ /up/i' }, + }); $self->{statefile_cache} = centreon::plugins::statefile->new(%options); return $self; @@ -378,6 +379,7 @@ sub manage_selection { $self->{global} = {}; $self->{sap} = {}; + foreach my $oid (keys %{$snmp_result->{$oid_sapDescription}}) { next if ($oid !~ /^$oid_sapDescription\.(.*?)\.(.*?)\.(.*?)$/); # $SvcId and $SapEncapValue is the same. We use service table @@ -401,6 +403,7 @@ sub manage_selection { SvcId => $SvcId, SapPortId => $SapPortId, SapEncapValue => $SapEncapValue); + 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); @@ -414,7 +417,9 @@ sub manage_selection { $mapping->{fadSapStatsEgressOctets}->{oid}, $mapping->{sapAdminStatus}->{oid}, $mapping->{sapOperStatus}->{oid}], instances => [keys %{$self->{sap}}], instance_regexp => '(\d+\.\d+\.\d+)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + foreach (keys %{$self->{sap}}) { my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); $self->{sap}->{$_}->{in} = $result->{fadSapStatsIngressOctets} * 8; diff --git a/network/alcatel/isam/snmp/mode/memory.pm b/network/alcatel/isam/snmp/mode/memory.pm index 97246f349..d4aaf37da 100644 --- a/network/alcatel/isam/snmp/mode/memory.pm +++ b/network/alcatel/isam/snmp/mode/memory.pm @@ -25,30 +25,31 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; - my $label = 'used'; + my ($label, $nlabel) = ('used', $self->{nlabel}); my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { - $label = 'free'; + if (defined($self->{instance_mode}->{option_results}->{free})) { + ($label, $nlabel) = ('free', 'memory.free.bytes'); $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + nlabel => $nlabel, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -56,12 +57,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -99,7 +100,7 @@ sub set_counters { ]; $self->{maps_counters}->{memory} = [ - { label => 'usage', set => { + { label => 'usage', nlabel => 'memory.usage.bytes', set => { key_values => [ { name => 'display' }, { name => 'used' }, { name => 'total' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_output => $self->can('custom_usage_output'), @@ -116,23 +117,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub prefix_memory_output { my ($self, %options) = @_; diff --git a/network/alcatel/omniswitch/snmp/mode/components/backplane.pm b/network/alcatel/omniswitch/snmp/mode/components/backplane.pm index 03a5851df..9355a40b5 100644 --- a/network/alcatel/omniswitch/snmp/mode/components/backplane.pm +++ b/network/alcatel/omniswitch/snmp/mode/components/backplane.pm @@ -34,17 +34,17 @@ sub check { return if ($self->check_filter(section => 'backplane')); my @instances = (); - foreach my $key (keys %{$self->{results}->{$oids{entPhysicalClass}}}) { - if ($self->{results}->{$oids{entPhysicalClass}}->{$key} == 4) { - next if ($key !~ /^$oids{entPhysicalClass}\.(.*)$/); + foreach my $key (keys %{$self->{results}->{$oids{common}->{entPhysicalClass}}}) { + if ($self->{results}->{$oids{common}->{entPhysicalClass}}->{$key} == 4) { + next if ($key !~ /^$oids{common}->{entPhysicalClass}\.(.*)$/); push @instances, $1; } } foreach my $instance (@instances) { - next if (!defined($self->{results}->{entity}->{$oids{chasEntPhysAdminStatus} . '.' . $instance})); + next if (!defined($self->{results}->{entity}->{$oids{$self->{type}}{chasEntPhysAdminStatus} . '.' . $instance})); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{entity}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping->{$self->{type}}, results => $self->{results}->{entity}, instance => $instance); next if ($self->check_filter(section => 'backplane', instance => $instance)); $self->{components}->{backplane}->{total}++; @@ -55,9 +55,13 @@ sub check { ); if ($result->{chasEntPhysPower} > 0) { - $self->{output}->perfdata_add(label => "power_" . $instance, unit => 'W', - value => $result->{chasEntPhysPower}, - min => 0); + $self->{output}->perfdata_add( + label => "power", unit => 'W', + nlabel => 'hardware.backplane.power.watt', + instances => $instance, + value => $result->{chasEntPhysPower}, + min => 0 + ); } my $exit = $self->get_severity(label => 'admin', section => 'backplane.admin', value => $result->{chasEntPhysAdminStatus}); diff --git a/network/alcatel/omniswitch/snmp/mode/components/chassis.pm b/network/alcatel/omniswitch/snmp/mode/components/chassis.pm index 82bf73d3c..e026d1c6b 100644 --- a/network/alcatel/omniswitch/snmp/mode/components/chassis.pm +++ b/network/alcatel/omniswitch/snmp/mode/components/chassis.pm @@ -34,17 +34,17 @@ sub check { return if ($self->check_filter(section => 'chassis')); my @instances = (); - foreach my $key (keys %{$self->{results}->{$oids{entPhysicalClass}}}) { - if ($self->{results}->{$oids{entPhysicalClass}}->{$key} == 3) { - next if ($key !~ /^$oids{entPhysicalClass}\.(.*)$/); + foreach my $key (keys %{$self->{results}->{$oids{common}->{entPhysicalClass}}}) { + if ($self->{results}->{$oids{common}->{entPhysicalClass}}->{$key} == 3) { + next if ($key !~ /^$oids{common}->{entPhysicalClass}\.(.*)$/); push @instances, $1; } } foreach my $instance (@instances) { - next if (!defined($self->{results}->{entity}->{$oids{chasEntPhysAdminStatus} . '.' . $instance})); + next if (!defined($self->{results}->{entity}->{$oids{$self->{type}}{chasEntPhysAdminStatus} . '.' . $instance})); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{entity}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping->{$self->{type}}, results => $self->{results}->{entity}, instance => $instance); next if ($self->check_filter(section => 'chassis', instance => $instance)); $self->{components}->{chassis}->{total}++; @@ -55,9 +55,13 @@ sub check { ); if ($result->{chasEntPhysPower} > 0) { - $self->{output}->perfdata_add(label => "power_" . $instance, unit => 'W', - value => $result->{chasEntPhysPower}, - min => 0); + $self->{output}->perfdata_add( + label => "power", unit => 'W', + nlabel => 'hardware.chassis.power.watt', + instances => $instance, + value => $result->{chasEntPhysPower}, + min => 0 + ); } my $exit = $self->get_severity(label => 'admin', section => 'chassis.admin', value => $result->{chasEntPhysAdminStatus}); diff --git a/network/alcatel/omniswitch/snmp/mode/components/container.pm b/network/alcatel/omniswitch/snmp/mode/components/container.pm index f3853cbbb..2e0c214f0 100644 --- a/network/alcatel/omniswitch/snmp/mode/components/container.pm +++ b/network/alcatel/omniswitch/snmp/mode/components/container.pm @@ -34,17 +34,17 @@ sub check { return if ($self->check_filter(section => 'container')); my @instances = (); - foreach my $key (keys %{$self->{results}->{$oids{entPhysicalClass}}}) { - if ($self->{results}->{$oids{entPhysicalClass}}->{$key} == 5) { - next if ($key !~ /^$oids{entPhysicalClass}\.(.*)$/); + foreach my $key (keys %{$self->{results}->{$oids{common}->{entPhysicalClass}}}) { + if ($self->{results}->{$oids{common}->{entPhysicalClass}}->{$key} == 5) { + next if ($key !~ /^$oids{common}->{entPhysicalClass}\.(.*)$/); push @instances, $1; } } foreach my $instance (@instances) { - next if (!defined($self->{results}->{entity}->{$oids{chasEntPhysAdminStatus} . '.' . $instance})); + next if (!defined($self->{results}->{entity}->{$oids{$self->{type}}{chasEntPhysAdminStatus} . '.' . $instance})); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{entity}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping->{$self->{type}}, results => $self->{results}->{entity}, instance => $instance); next if ($self->check_filter(section => 'container', instance => $instance)); $self->{components}->{container}->{total}++; @@ -55,9 +55,13 @@ sub check { ); if ($result->{chasEntPhysPower} > 0) { - $self->{output}->perfdata_add(label => "power_" . $instance, unit => 'W', - value => $result->{chasEntPhysPower}, - min => 0); + $self->{output}->perfdata_add( + label => "power", unit => 'W', + nlabel => 'hardware.container.power.watt', + instances => $instance, + value => $result->{chasEntPhysPower}, + min => 0 + ); } my $exit = $self->get_severity(label => 'admin', section => 'container.admin', value => $result->{chasEntPhysAdminStatus}); diff --git a/network/alcatel/omniswitch/snmp/mode/components/fan.pm b/network/alcatel/omniswitch/snmp/mode/components/fan.pm index f290066f9..6cb4c8288 100644 --- a/network/alcatel/omniswitch/snmp/mode/components/fan.pm +++ b/network/alcatel/omniswitch/snmp/mode/components/fan.pm @@ -40,17 +40,17 @@ sub check { return if ($self->check_filter(section => 'fan')); my @instances = (); - foreach my $key (keys %{$self->{results}->{$oids{entPhysicalClass}}}) { - if ($self->{results}->{$oids{entPhysicalClass}}->{$key} == 7) { - next if ($key !~ /^$oids{entPhysicalClass}\.(.*)$/); + foreach my $key (keys %{$self->{results}->{$oids{common}->{entPhysicalClass}}}) { + if ($self->{results}->{$oids{common}->{entPhysicalClass}}->{$key} == 7) { + next if ($key !~ /^$oids{common}->{entPhysicalClass}\.(.*)$/); push @instances, $1; } } foreach my $instance (@instances) { - next if (!defined($self->{results}->{entity}->{$oids{chasEntPhysAdminStatus} . '.' . $instance})); + next if (!defined($self->{results}->{entity}->{$oids{$self->{type}}{chasEntPhysAdminStatus} . '.' . $instance})); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{entity}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping->{$self->{type}}, results => $self->{results}->{entity}, instance => $instance); next if ($self->check_filter(section => 'fan', instance => $instance)); $self->{components}->{fan}->{total}++; @@ -61,9 +61,13 @@ sub check { ); if ($result->{chasEntPhysPower} > 0) { - $self->{output}->perfdata_add(label => "power_" . $instance, unit => 'W', - value => $result->{chasEntPhysPower}, - min => 0); + $self->{output}->perfdata_add( + label => "power", unit => 'W', + nlabel => 'hardware.fan.power.watt', + instances => $instance, + value => $result->{chasEntPhysPower}, + min => 0 + ); } my $exit = $self->get_severity(label => 'admin', section => 'fan.admin', value => $result->{chasEntPhysAdminStatus}); @@ -84,14 +88,14 @@ sub check { } } - foreach my $key (keys %{$self->{results}->{$oids{alaChasEntPhysFanStatus}}}) { - next if ($key !~ /^$oids{alaChasEntPhysFanStatus}\.(.*?)\.(.*?)$/); + foreach my $key (keys %{$self->{results}->{$oids{$self->{type}}->{alaChasEntPhysFanStatus}}}) { + next if ($key !~ /^$oids{$self->{type}}->{alaChasEntPhysFanStatus}\.(.*?)\.(.*?)$/); my ($phys_index, $loc_index) = ($1, $2); - my $status = $self->{results}->{$oids{alaChasEntPhysFanStatus}}->{$key}; - my $descr = defined($self->{results}->{entity}->{$oids{entPhysicalDescr} . '.' . $phys_index}) ? - $self->{results}->{entity}->{$oids{entPhysicalDescr} . '.' . $phys_index} : 'unknown'; - my $name = defined($self->{results}->{entity}->{$oids{entPhysicalName} . '.' . $phys_index}) ? - $self->{results}->{entity}->{$oids{entPhysicalName} . '.' . $phys_index} : 'unknown'; + my $status = $self->{results}->{$oids{$self->{type}}->{alaChasEntPhysFanStatus}}->{$key}; + my $descr = defined($self->{results}->{entity}->{$oids{common}->{entPhysicalDescr} . '.' . $phys_index}) ? + $self->{results}->{entity}->{$oids{common}->{entPhysicalDescr} . '.' . $phys_index} : 'unknown'; + my $name = defined($self->{results}->{entity}->{$oids{common}->{entPhysicalName} . '.' . $phys_index}) ? + $self->{results}->{entity}->{$oids{common}->{entPhysicalName} . '.' . $phys_index} : 'unknown'; next if ($self->check_filter(section => 'fan', instance => $phys_index . '.' . $loc_index)); $self->{components}->{fan}->{total}++; diff --git a/network/alcatel/omniswitch/snmp/mode/components/module.pm b/network/alcatel/omniswitch/snmp/mode/components/module.pm index 3a638aeff..ee048d4b3 100644 --- a/network/alcatel/omniswitch/snmp/mode/components/module.pm +++ b/network/alcatel/omniswitch/snmp/mode/components/module.pm @@ -34,17 +34,17 @@ sub check { return if ($self->check_filter(section => 'module')); my @instances = (); - foreach my $key (keys %{$self->{results}->{$oids{entPhysicalClass}}}) { - if ($self->{results}->{$oids{entPhysicalClass}}->{$key} == 9) { - next if ($key !~ /^$oids{entPhysicalClass}\.(.*)$/); + foreach my $key (keys %{$self->{results}->{$oids{common}->{entPhysicalClass}}}) { + if ($self->{results}->{$oids{common}->{entPhysicalClass}}->{$key} == 9) { + next if ($key !~ /^$oids{common}->{entPhysicalClass}\.(.*)$/); push @instances, $1; } } foreach my $instance (@instances) { - next if (!defined($self->{results}->{entity}->{$oids{chasEntPhysAdminStatus} . '.' . $instance})); + next if (!defined($self->{results}->{entity}->{$oids{$self->{type}}{chasEntPhysAdminStatus} . '.' . $instance})); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{entity}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping->{$self->{type}}, results => $self->{results}->{entity}, instance => $instance); next if ($self->check_filter(section => 'module', instance => $instance)); $self->{components}->{module}->{total}++; @@ -55,9 +55,13 @@ sub check { ); if ($result->{chasEntPhysPower} > 0) { - $self->{output}->perfdata_add(label => "power_" . $instance, unit => 'W', - value => $result->{chasEntPhysPower}, - min => 0); + $self->{output}->perfdata_add( + label => "power", unit => 'W', + nlabel => 'hardware.module.power.watt', + instances => $instance, + value => $result->{chasEntPhysPower}, + min => 0 + ); } my $exit = $self->get_severity(label => 'admin', section => 'module.admin', value => $result->{chasEntPhysAdminStatus}); diff --git a/network/alcatel/omniswitch/snmp/mode/components/other.pm b/network/alcatel/omniswitch/snmp/mode/components/other.pm index eccd11d53..d69e3ea36 100644 --- a/network/alcatel/omniswitch/snmp/mode/components/other.pm +++ b/network/alcatel/omniswitch/snmp/mode/components/other.pm @@ -34,17 +34,17 @@ sub check { return if ($self->check_filter(section => 'other')); my @instances = (); - foreach my $key (keys %{$self->{results}->{$oids{entPhysicalClass}}}) { - if ($self->{results}->{$oids{entPhysicalClass}}->{$key} == 1) { - next if ($key !~ /^$oids{entPhysicalClass}\.(.*)$/); + foreach my $key (keys %{$self->{results}->{$oids{common}->{entPhysicalClass}}}) { + if ($self->{results}->{$oids{common}->{entPhysicalClass}}->{$key} == 1) { + next if ($key !~ /^$oids{common}->{entPhysicalClass}\.(.*)$/); push @instances, $1; } } foreach my $instance (@instances) { - next if (!defined($self->{results}->{entity}->{$oids{chasEntPhysAdminStatus} . '.' . $instance})); + next if (!defined($self->{results}->{entity}->{$oids{$self->{type}}{chasEntPhysAdminStatus} . '.' . $instance})); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{entity}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping->{$self->{type}}, results => $self->{results}->{entity}, instance => $instance); next if ($self->check_filter(section => 'other', instance => $instance)); $self->{components}->{other}->{total}++; @@ -55,9 +55,13 @@ sub check { ); if ($result->{chasEntPhysPower} > 0) { - $self->{output}->perfdata_add(label => "power_" . $instance, unit => 'W', - value => $result->{chasEntPhysPower}, - min => 0); + $self->{output}->perfdata_add( + label => "power", unit => 'W', + nlabel => 'hardware.other.power.watt', + instances => $instance, + value => $result->{chasEntPhysPower}, + min => 0 + ); } my $exit = $self->get_severity(label => 'admin', section => 'other.admin', value => $result->{chasEntPhysAdminStatus}); diff --git a/network/alcatel/omniswitch/snmp/mode/components/port.pm b/network/alcatel/omniswitch/snmp/mode/components/port.pm index b3a3ddf5f..08a3d7be5 100644 --- a/network/alcatel/omniswitch/snmp/mode/components/port.pm +++ b/network/alcatel/omniswitch/snmp/mode/components/port.pm @@ -34,17 +34,17 @@ sub check { return if ($self->check_filter(section => 'port')); my @instances = (); - foreach my $key (keys %{$self->{results}->{$oids{entPhysicalClass}}}) { - if ($self->{results}->{$oids{entPhysicalClass}}->{$key} == 10) { - next if ($key !~ /^$oids{entPhysicalClass}\.(.*)$/); + foreach my $key (keys %{$self->{results}->{$oids{common}->{entPhysicalClass}}}) { + if ($self->{results}->{$oids{common}->{entPhysicalClass}}->{$key} == 10) { + next if ($key !~ /^$oids{common}->{entPhysicalClass}\.(.*)$/); push @instances, $1; } } foreach my $instance (@instances) { - next if (!defined($self->{results}->{entity}->{$oids{chasEntPhysAdminStatus} . '.' . $instance})); + next if (!defined($self->{results}->{entity}->{$oids{$self->{type}}{chasEntPhysAdminStatus} . '.' . $instance})); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{entity}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping->{$self->{type}}, results => $self->{results}->{entity}, instance => $instance); next if ($self->check_filter(section => 'port', instance => $instance)); $self->{components}->{port}->{total}++; @@ -55,9 +55,13 @@ sub check { ); if ($result->{chasEntPhysPower} > 0) { - $self->{output}->perfdata_add(label => "power_" . $instance, unit => 'W', - value => $result->{chasEntPhysPower}, - min => 0); + $self->{output}->perfdata_add( + label => "power", unit => 'W', + nlabel => 'hardware.port.power.watt', + instances => $instance, + value => $result->{chasEntPhysPower}, + min => 0 + ); } my $exit = $self->get_severity(label => 'admin', section => 'port.admin', value => $result->{chasEntPhysAdminStatus}); diff --git a/network/alcatel/omniswitch/snmp/mode/components/psu.pm b/network/alcatel/omniswitch/snmp/mode/components/psu.pm index 01204b79e..1f11a99ea 100644 --- a/network/alcatel/omniswitch/snmp/mode/components/psu.pm +++ b/network/alcatel/omniswitch/snmp/mode/components/psu.pm @@ -34,17 +34,17 @@ sub check { return if ($self->check_filter(section => 'psu')); my @instances = (); - foreach my $key (keys %{$self->{results}->{$oids{entPhysicalClass}}}) { - if ($self->{results}->{$oids{entPhysicalClass}}->{$key} == 6) { - next if ($key !~ /^$oids{entPhysicalClass}\.(.*)$/); + foreach my $key (keys %{$self->{results}->{$oids{common}->{entPhysicalClass}}}) { + if ($self->{results}->{$oids{common}->{entPhysicalClass}}->{$key} == 6) { + next if ($key !~ /^$oids{common}->{entPhysicalClass}\.(.*)$/); push @instances, $1; } } foreach my $instance (@instances) { - next if (!defined($self->{results}->{entity}->{$oids{chasEntPhysAdminStatus} . '.' . $instance})); + next if (!defined($self->{results}->{entity}->{$oids{$self->{type}}{chasEntPhysAdminStatus} . '.' . $instance})); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{entity}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping->{$self->{type}}, results => $self->{results}->{entity}, instance => $instance); next if ($self->check_filter(section => 'psu', instance => $instance)); $self->{components}->{psu}->{total}++; @@ -55,9 +55,13 @@ sub check { ); if ($result->{chasEntPhysPower} > 0) { - $self->{output}->perfdata_add(label => "power_" . $instance, unit => 'W', - value => $result->{chasEntPhysPower}, - min => 0); + $self->{output}->perfdata_add( + label => "power", unit => 'W', + nlabel => 'hardware.powersupply.power.watt', + instances => $instance, + value => $result->{chasEntPhysPower}, + min => 0 + ); } my $exit = $self->get_severity(label => 'admin', section => 'psu.admin', value => $result->{chasEntPhysAdminStatus}); diff --git a/network/alcatel/omniswitch/snmp/mode/components/resources.pm b/network/alcatel/omniswitch/snmp/mode/components/resources.pm index 75efd53d6..753d560be 100644 --- a/network/alcatel/omniswitch/snmp/mode/components/resources.pm +++ b/network/alcatel/omniswitch/snmp/mode/components/resources.pm @@ -57,7 +57,7 @@ our @EXPORT_OK = qw(%physical_class %phys_oper_status %phys_admin_status %oids $ 7 => 'unpowered', 8 => 'master', 9 => 'idle', - 10 => 'unpoweredLicMismatch', + 10 => 'pwrsave', ); %phys_admin_status = ( @@ -70,29 +70,58 @@ our @EXPORT_OK = qw(%physical_class %phys_oper_status %phys_admin_status %oids $ 7 => 'standby', 8 => 'resetWithFabric', 9 => 'takeoverWithFabrc', + 10 => 'vcTakeover', + 11 => 'resetVcAll', ); %oids = ( - entPhysicalDescr => '.1.3.6.1.2.1.47.1.1.1.1.2', - entPhysicalClass => '.1.3.6.1.2.1.47.1.1.1.1.5', - entPhysicalName => '.1.3.6.1.2.1.47.1.1.1.1.7', - chasEntPhysAdminStatus => '.1.3.6.1.4.1.6486.800.1.1.1.1.1.1.1.1', - chasEntPhysOperStatus => '.1.3.6.1.4.1.6486.800.1.1.1.1.1.1.1.2', - chasEntPhysPower => '.1.3.6.1.4.1.6486.800.1.1.1.1.1.1.1.4', + common => { + entPhysicalDescr => '.1.3.6.1.2.1.47.1.1.1.1.2', + entPhysicalClass => '.1.3.6.1.2.1.47.1.1.1.1.5', + entPhysicalName => '.1.3.6.1.2.1.47.1.1.1.1.7', + }, + aos6 => { + entreprise_alcatel_base => '.1.3.6.1.4.1.6486.800', + + chasEntPhysAdminStatus => '.1.3.6.1.4.1.6486.800.1.1.1.1.1.1.1.1', + chasEntPhysOperStatus => '.1.3.6.1.4.1.6486.800.1.1.1.1.1.1.1.2', + chasEntPhysPower => '.1.3.6.1.4.1.6486.800.1.1.1.1.1.1.1.4', - chasHardwareBoardTemp => '.1.3.6.1.4.1.6486.800.1.1.1.3.1.1.3.1.4', - chasTempThreshold => '.1.3.6.1.4.1.6486.800.1.1.1.3.1.1.3.1.7', - chasDangerTempThreshold => '.1.3.6.1.4.1.6486.800.1.1.1.3.1.1.3.1.8', + chasHardwareBoardTemp => '.1.3.6.1.4.1.6486.800.1.1.1.3.1.1.3.1.4', + chasTempThreshold => '.1.3.6.1.4.1.6486.800.1.1.1.3.1.1.3.1.7', + chasDangerTempThreshold => '.1.3.6.1.4.1.6486.800.1.1.1.3.1.1.3.1.8', - alaChasEntPhysFanStatus => '.1.3.6.1.4.1.6486.800.1.1.1.3.1.1.11.1.2', + alaChasEntPhysFanStatus => '.1.3.6.1.4.1.6486.800.1.1.1.3.1.1.11.1.2', + }, + aos7 => { + entreprise_alcatel_base => '.1.3.6.1.4.1.6486.801', + + chasEntPhysAdminStatus => '1.3.6.1.4.1.6486.801.1.1.1.1.1.1.1.1', + chasEntPhysOperStatus => '1.3.6.1.4.1.6486.801.1.1.1.1.1.1.1.2', + chasEntPhysPower => '1.3.6.1.4.1.6486.801.1.1.1.1.1.1.1.3', + + chasTempThreshold => '1.3.6.1.4.1.6486.801.1.1.1.3.1.1.3.1.5', + chasDangerTempThreshold => '1.3.6.1.4.1.6486.801.1.1.1.3.1.1.3.1.6', + + alaChasEntPhysFanStatus => '1.3.6.1.4.1.6486.801.1.1.1.3.1.1.11.1.2', + }, ); $mapping = { - entPhysicalDescr => { oid => $oids{entPhysicalDescr} }, - entPhysicalName => { oid => $oids{entPhysicalName} }, - chasEntPhysAdminStatus => { oid => $oids{chasEntPhysAdminStatus}, map => \%phys_admin_status, default => 'unknown' }, - chasEntPhysOperStatus => { oid => $oids{chasEntPhysOperStatus}, map => \%phys_oper_status, default => 'unknown' }, - chasEntPhysPower => { oid => $oids{chasEntPhysPower}, default => -1 }, + aos6 => { + entPhysicalDescr => { oid => $oids{common}->{entPhysicalDescr} }, + entPhysicalName => { oid => $oids{common}->{entPhysicalName} }, + chasEntPhysAdminStatus => { oid => $oids{aos6}->{chasEntPhysAdminStatus}, map => \%phys_admin_status, default => 'unknown' }, + chasEntPhysOperStatus => { oid => $oids{aos6}->{chasEntPhysOperStatus}, map => \%phys_oper_status, default => 'unknown' }, + chasEntPhysPower => { oid => $oids{aos6}->{chasEntPhysPower}, default => -1 }, + }, + aos7 => { + entPhysicalDescr => { oid => $oids{common}->{entPhysicalDescr} }, + entPhysicalName => { oid => $oids{common}->{entPhysicalName} }, + chasEntPhysAdminStatus => { oid => $oids{aos7}->{chasEntPhysAdminStatus}, map => \%phys_admin_status, default => 'unknown' }, + chasEntPhysOperStatus => { oid => $oids{aos7}->{chasEntPhysOperStatus}, map => \%phys_oper_status, default => 'unknown' }, + chasEntPhysPower => { oid => $oids{aos7}->{chasEntPhysPower}, default => -1 }, + }, }; -1; \ No newline at end of file +1; diff --git a/network/alcatel/omniswitch/snmp/mode/components/sensor.pm b/network/alcatel/omniswitch/snmp/mode/components/sensor.pm index 3c12e0135..30dc6b127 100644 --- a/network/alcatel/omniswitch/snmp/mode/components/sensor.pm +++ b/network/alcatel/omniswitch/snmp/mode/components/sensor.pm @@ -34,17 +34,17 @@ sub check { return if ($self->check_filter(section => 'sensor')); my @instances = (); - foreach my $key (keys %{$self->{results}->{$oids{entPhysicalClass}}}) { - if ($self->{results}->{$oids{entPhysicalClass}}->{$key} == 8) { - next if ($key !~ /^$oids{entPhysicalClass}\.(.*)$/); + foreach my $key (keys %{$self->{results}->{$oids{common}->{entPhysicalClass}}}) { + if ($self->{results}->{$oids{common}->{entPhysicalClass}}->{$key} == 8) { + next if ($key !~ /^$oids{common}->{entPhysicalClass}\.(.*)$/); push @instances, $1; } } foreach my $instance (@instances) { - next if (!defined($self->{results}->{entity}->{$oids{chasEntPhysAdminStatus} . '.' . $instance})); + next if (!defined($self->{results}->{entity}->{$oids{$self->{type}}{chasEntPhysAdminStatus} . '.' . $instance})); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{entity}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping->{$self->{type}}, results => $self->{results}->{entity}, instance => $instance); next if ($self->check_filter(section => 'sensor', instance => $instance)); $self->{components}->{sensor}->{total}++; @@ -55,9 +55,13 @@ sub check { ); if ($result->{chasEntPhysPower} > 0) { - $self->{output}->perfdata_add(label => "power_" . $instance, unit => 'W', - value => $result->{chasEntPhysPower}, - min => 0); + $self->{output}->perfdata_add( + label => "power", unit => 'W', + nlabel => 'hardware.sensor.power.watt', + instances => $instance, + value => $result->{chasEntPhysPower}, + min => 0 + ); } my $exit = $self->get_severity(label => 'admin', section => 'sensor.admin', value => $result->{chasEntPhysAdminStatus}); diff --git a/network/alcatel/omniswitch/snmp/mode/components/stack.pm b/network/alcatel/omniswitch/snmp/mode/components/stack.pm index 3876abb68..2feb6419f 100644 --- a/network/alcatel/omniswitch/snmp/mode/components/stack.pm +++ b/network/alcatel/omniswitch/snmp/mode/components/stack.pm @@ -34,17 +34,17 @@ sub check { return if ($self->check_filter(section => 'stack')); my @instances = (); - foreach my $key (keys %{$self->{results}->{$oids{entPhysicalClass}}}) { - if ($self->{results}->{$oids{entPhysicalClass}}->{$key} == 11) { - next if ($key !~ /^$oids{entPhysicalClass}\.(.*)$/); + foreach my $key (keys %{$self->{results}->{$oids{common}->{entPhysicalClass}}}) { + if ($self->{results}->{$oids{common}->{entPhysicalClass}}->{$key} == 11) { + next if ($key !~ /^$oids{common}->{entPhysicalClass}\.(.*)$/); push @instances, $1; } } foreach my $instance (@instances) { - next if (!defined($self->{results}->{entity}->{$oids{chasEntPhysAdminStatus} . '.' . $instance})); + next if (!defined($self->{results}->{entity}->{$oids{$self->{type}}{chasEntPhysAdminStatus} . '.' . $instance})); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{entity}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping->{$self->{type}}, results => $self->{results}->{entity}, instance => $instance); next if ($self->check_filter(section => 'stack', instance => $instance)); $self->{components}->{stack}->{total}++; @@ -55,9 +55,13 @@ sub check { ); if ($result->{chasEntPhysPower} > 0) { - $self->{output}->perfdata_add(label => "power_" . $instance, unit => 'W', - value => $result->{chasEntPhysPower}, - min => 0); + $self->{output}->perfdata_add( + label => "power", unit => 'W', + nlabel => 'hardware.stack.power.watt', + instances => $instance, + value => $result->{chasEntPhysPower}, + min => 0 + ); } my $exit = $self->get_severity(label => 'admin', section => 'stack.admin', value => $result->{chasEntPhysAdminStatus}); diff --git a/network/alcatel/omniswitch/snmp/mode/components/unknown.pm b/network/alcatel/omniswitch/snmp/mode/components/unknown.pm index 907d91812..f753a42b0 100644 --- a/network/alcatel/omniswitch/snmp/mode/components/unknown.pm +++ b/network/alcatel/omniswitch/snmp/mode/components/unknown.pm @@ -34,17 +34,17 @@ sub check { return if ($self->check_filter(section => 'unknown')); my @instances = (); - foreach my $key (keys %{$self->{results}->{$oids{entPhysicalClass}}}) { - if ($self->{results}->{$oids{entPhysicalClass}}->{$key} == 2) { - next if ($key !~ /^$oids{entPhysicalClass}\.(.*)$/); + foreach my $key (keys %{$self->{results}->{$oids{common}->{entPhysicalClass}}}) { + if ($self->{results}->{$oids{common}->{entPhysicalClass}}->{$key} == 2) { + next if ($key !~ /^$oids{common}->{entPhysicalClass}\.(.*)$/); push @instances, $1; } } foreach my $instance (@instances) { - next if (!defined($self->{results}->{entity}->{$oids{chasEntPhysAdminStatus} . '.' . $instance})); + next if (!defined($self->{results}->{entity}->{$oids{$self->{type}}->{chasEntPhysAdminStatus} . '.' . $instance})); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{entity}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping->{$self->{type}}, results => $self->{results}->{entity}, instance => $instance); next if ($self->check_filter(section => 'unknown', instance => $instance)); $self->{components}->{unknown}->{total}++; @@ -55,9 +55,13 @@ sub check { ); if ($result->{chasEntPhysPower} > 0) { - $self->{output}->perfdata_add(label => "power_" . $instance, unit => 'W', - value => $result->{chasEntPhysPower}, - min => 0); + $self->{output}->perfdata_add( + label => "power", unit => 'W', + nlabel => 'hardware.unknown.power.watt', + instances => $instance, + value => $result->{chasEntPhysPower}, + min => 0 + ); } my $exit = $self->get_severity(label => 'admin', section => 'unknown.admin', value => $result->{chasEntPhysAdminStatus}); diff --git a/network/alcatel/omniswitch/snmp/mode/cpu.pm b/network/alcatel/omniswitch/snmp/mode/cpu.pm index 1f72651a2..0fa71361c 100644 --- a/network/alcatel/omniswitch/snmp/mode/cpu.pm +++ b/network/alcatel/omniswitch/snmp/mode/cpu.pm @@ -31,11 +31,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning', default => '' }, - "critical:s" => { name => 'critical', default => '' }, - }); + $options{options}->add_options(arguments => { + "warning:s" => { name => 'warning', default => '' }, + "critical:s" => { name => 'critical', default => '' }, + }); return $self; } @@ -68,13 +67,20 @@ sub check_options { sub check_cpu { my ($self, %options) = @_; - my $exit1 = $self->{perfdata}->threshold_check(value => $options{'1min'}, threshold => [ { label => 'crit1m', exit_litteral => 'critical' }, - { label => 'warn1m', exit_litteral => 'warning' }, - ]); - - my $exit2 = $self->{perfdata}->threshold_check(value => $options{'1hour'}, threshold => [ { label => 'crit1h', exit_litteral => 'critical' }, - { label => 'warn1h', exit_litteral => 'warning' }, - ]); + my $exit1 = $self->{perfdata}->threshold_check( + value => $options{'1min'}, + threshold => [ + { label => 'crit1m', exit_litteral => 'critical' }, + { label => 'warn1m', exit_litteral => 'warning' }, + ] + ); + my $exit2 = $self->{perfdata}->threshold_check( + value => $options{'1hour'}, + threshold => [ + { label => 'crit1h', exit_litteral => 'critical' }, + { label => 'warn1h', exit_litteral => 'warning' }, + ] + ); my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2 ]); @@ -95,28 +101,60 @@ sub check_cpu { sub run { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - my $oid_healthDeviceCpu1MinAvg = '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.1.14'; # it's '.0' but it's for walk multiple - my $oid_healthDeviceCpu1HrAvg = '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.1.15'; # it's '.0' but it's for walk multiple - my $oid_healthModuleCpu1MinAvg = '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.2.1.1.15'; - my $oid_healthModuleCpu1HrAvg = '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.2.1.1.16'; + my $mapping = { + aos6 => { + entry_device => '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.1', + entry_module => '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.2.1.1', + device => { + healthDeviceCpu1MinAvg => { oid => '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.1.14' }, + healthDeviceCpu1HrAvg => { oid => '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.1.15' }, + }, + module => { + healthModuleCpu1MinAvg => { oid => '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.2.1.1.15' }, + healthModuleCpu1HrAvg => { oid => '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.2.1.1.16' }, + }, + }, + aos7 => { + entry_module => '.1.3.6.1.4.1.6486.801.1.2.1.16.1.1.1.1.1', + module => { + healthModuleCpu1MinAvg => { oid => '.1.3.6.1.4.1.6486.801.1.2.1.16.1.1.1.1.1.11' }, + healthModuleCpu1HrAvg => { oid => '.1.3.6.1.4.1.6486.801.1.2.1.16.1.1.1.1.1.12' }, + }, + }, + }; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{aos6}->{entry_device}, start => $mapping->{aos6}->{device}->{healthDeviceCpu1MinAvg}->{oid}, end => $mapping->{aos6}->{device}->{healthDeviceCpu1HrAvg}->{oid} }, + { oid => $mapping->{aos6}->{entry_module}, start => $mapping->{aos6}->{module}->{healthModuleCpu1MinAvg}->{oid}, end => $mapping->{aos6}->{module}->{healthModuleCpu1HrAvg}->{oid} }, + { oid => $mapping->{aos7}->{entry_module}, start => $mapping->{aos7}->{module}->{healthModuleCpu1MinAvg}->{oid}, end => $mapping->{aos7}->{module}->{healthModuleCpu1HrAvg}->{oid} }, + ], nothing_quit => 1); - my $result = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_healthDeviceCpu1MinAvg }, - { oid => $oid_healthDeviceCpu1HrAvg }, - { oid => $oid_healthModuleCpu1MinAvg }, - { oid => $oid_healthModuleCpu1HrAvg }, - ], nothing_quit => 1); + my $type = 'aos6'; + if (scalar(keys %{$snmp_result->{ $mapping->{aos7}->{entry_module} }}) > 0) { + $type = 'aos7'; + } - $self->check_cpu(name => 'Device cpu', perf_label => '_device', - '1min' => $result->{$oid_healthDeviceCpu1MinAvg}->{$oid_healthDeviceCpu1MinAvg . '.' . 0}, - '1hour' => $result->{$oid_healthDeviceCpu1HrAvg}->{$oid_healthDeviceCpu1HrAvg . '.' . 0}); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_healthModuleCpu1MinAvg}})) { - $oid =~ /^$oid_healthModuleCpu1MinAvg\.(.*)$/; - $self->check_cpu(name => "Module cpu '$1'", perf_label => "_module_$1", - '1min' => $result->{$oid_healthModuleCpu1MinAvg}->{$oid_healthModuleCpu1MinAvg . '.' . $1}, - '1hour' => $result->{$oid_healthModuleCpu1HrAvg}->{$oid_healthModuleCpu1HrAvg . '.' . $1}); + if (defined($mapping->{$type}->{device})) { + my $result = $options{snmp}->map_instance(mapping => $mapping->{$type}->{device}, results => $snmp_result->{ $mapping->{$type}->{entry_device} }, instance => '0'); + $self->check_cpu( + name => 'Device cpu', + perf_label => '_device', + '1min' => $result->{healthDeviceCpu1MinAvg}, + '1hour' => $result->{healthDeviceCpu1HrAvg} + ); + } + + foreach my $oid ($options{snmp}->oid_lex_sort(keys %{$snmp_result->{ $mapping->{$type}->{entry_module} }})) { + next if ($oid !~ /^$mapping->{$type}->{module}->{healthModuleCpu1MinAvg}->{oid}\.(.*)$/); + my $result = $options{snmp}->map_instance(mapping => $mapping->{$type}->{module}, results => $snmp_result->{ $mapping->{$type}->{entry_module} }, instance => $1); + + $self->check_cpu( + name => "Module cpu '$1'", + perf_label => "_module_$1", + '1min' => $result->{healthModuleCpu1MinAvg}, + '1hour' => $result->{healthModuleCpu1HrAvg} + ); } $self->{output}->display(); diff --git a/network/alcatel/omniswitch/snmp/mode/flashmemory.pm b/network/alcatel/omniswitch/snmp/mode/flashmemory.pm index 34abec981..d0c182d9a 100644 --- a/network/alcatel/omniswitch/snmp/mode/flashmemory.pm +++ b/network/alcatel/omniswitch/snmp/mode/flashmemory.pm @@ -20,94 +20,122 @@ package network::alcatel::omniswitch::snmp::mode::flashmemory; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + + my $msg = sprintf("Memory Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{free} = $options{new_datas}->{$self->{instance} . '_free'}; + $self->{result_values}->{used} = $self->{result_values}->{total} - $self->{result_values}->{free}; + $self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 1, cb_prefix_output => 'prefix_memory_output', message_multiple => 'All flash memories are ok' }, + ]; + + $self->{maps_counters}->{memory} = [ + { label => 'usage', nlabel => 'flash.usage.bytes', set => { + key_values => [ { name => 'total' }, { name => 'free' }, { name => 'display' }, ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + threshold_use => 'prct_used', + perfdatas => [ + { label => 'used', value => 'used', template => '%.2f', min => 0, max => 'total', + unit => 'B', label_extra_instance => 1, instance_use => 'display', cast_int => 1 }, + ], + } + }, + ]; +} + +sub prefix_memory_output { + my ($self, %options) = @_; + + return "Memory '" . $options{instance_value}->{display} . "' "; +} + 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:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - }); + $options{options}->add_options(arguments => { + }); return $self; } -sub check_options { +sub manage_selection { my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } -} -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; + my $mapping = { + aos6 => { + entry => '.1.3.6.1.4.1.6486.800.1.1.1.3.1.1.9.1', + flash => { + chasSupervisionFlashSize => { oid => '.1.3.6.1.4.1.6486.800.1.1.1.3.1.1.9.1.2' }, # in B + chasSupervisionFlashFree => { oid => '.1.3.6.1.4.1.6486.800.1.1.1.3.1.1.9.1.3' }, # in B + }, + }, + aos7 => { + entry => '.1.3.6.1.4.1.6486.801.1.1.1.3.1.1.9.1', + flash => { + chasSupervisionFlashSize => { oid => '.1.3.6.1.4.1.6486.801.1.1.1.3.1.1.9.1.2' }, # in B + chasSupervisionFlashFree => { oid => '.1.3.6.1.4.1.6486.801.1.1.1.3.1.1.9.1.3' }, # in B + }, + }, + }; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{aos6}->{entry} }, + { oid => $mapping->{aos7}->{entry} }, + ], nothing_quit => 1); - my $oid_chasSupervisionFlashMemEntry = '.1.3.6.1.4.1.6486.800.1.1.1.3.1.1.9.1'; - my $oid_chasSupervisionFlashSize = '.1.3.6.1.4.1.6486.800.1.1.1.3.1.1.9.1.2'; # in B - my $oid_chasSupervisionFlashFree = '.1.3.6.1.4.1.6486.800.1.1.1.3.1.1.9.1.3'; # in B - my $result = $self->{snmp}->get_table(oid => $oid_chasSupervisionFlashMemEntry, nothing_quit => 1); - - $self->{output}->output_add(severity => 'OK', - short_msg => 'All flash memories are ok.'); - - foreach my $oid (keys %$result) { - next if ($oid !~ /^$oid_chasSupervisionFlashSize\./); - $oid =~ /\.([0-9]+)$/; + my $type = 'aos6'; + if (scalar(keys %{$snmp_result->{ $mapping->{aos7}->{entry} }}) > 0) { + $type = 'aos7'; + } + + $self->{memory} = {}; + foreach my $oid ($options{snmp}->oid_lex_sort(keys %{$snmp_result->{ $mapping->{$type}->{entry} }})) { + next if ($oid !~ /^$mapping->{$type}->{flash}->{chasSupervisionFlashSize}->{oid}\.(.*)$/); my $instance = $1; - + my $result = $options{snmp}->map_instance(mapping => $mapping->{$type}->{flash}, results => $snmp_result->{ $mapping->{$type}->{entry} }, instance => $instance); + # Skip if total = 0 - next if ($result->{$oid_chasSupervisionFlashSize . '.' . $instance} == 0); - - my $memory_name = $instance; - my $memory_used = $result->{$oid_chasSupervisionFlashSize . '.' . $instance} - $result->{$oid_chasSupervisionFlashFree . '.' . $instance}; - my $memory_free = $result->{$oid_chasSupervisionFlashFree . '.' . $instance}; + next if ($result->{chasSupervisionFlashSize} == 0); - my $total_size = $memory_used + $memory_free; - my $prct_used = $memory_used * 100 / $total_size; - my $prct_free = 100 - $prct_used; - - my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $total_size); - my ($used_value, $used_unit) = $self->{perfdata}->change_bytes(value => $memory_used); - my ($free_value, $free_unit) = $self->{perfdata}->change_bytes(value => $memory_free); - - $self->{output}->output_add(long_msg => sprintf("Memory '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $memory_name, - $total_value . " " . $total_unit, - $used_value . " " . $used_unit, $prct_used, - $free_value . " " . $free_unit, $prct_free)); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Memory '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $memory_name, - $total_value . " " . $total_unit, - $used_value . " " . $used_unit, $prct_used, - $free_value . " " . $free_unit, $prct_free)); - } - - $self->{output}->perfdata_add(label => "used_" . $memory_name, unit => 'B', - value => $memory_used, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size), - min => 0, max => $total_size); + $self->{memory}->{$instance} = { + display => $instance, + free => $result->{chasSupervisionFlashFree}, + total => $result->{chasSupervisionFlashSize}, + }; } - - $self->{output}->display(); - $self->{output}->exit(); } 1; @@ -120,11 +148,11 @@ Check flash memory (AlcatelIND1Chassis.mib). =over 8 -=item B<--warning> +=item B<--warning-usage> Threshold warning in percent. -=item B<--critical> +=item B<--critical-usage> Threshold critical in percent. diff --git a/network/alcatel/omniswitch/snmp/mode/hardware.pm b/network/alcatel/omniswitch/snmp/mode/hardware.pm index 57ca9f270..4ec73fc53 100644 --- a/network/alcatel/omniswitch/snmp/mode/hardware.pm +++ b/network/alcatel/omniswitch/snmp/mode/hardware.pm @@ -61,16 +61,28 @@ sub snmp_execute { $self->{snmp} = $options{snmp}; $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oids{entPhysicalClass} }, - { oid => $oids{alaChasEntPhysFanStatus} }, + { oid => $oids{common}->{entPhysicalClass} }, + { oid => $oids{aos6}->{alaChasEntPhysFanStatus} }, + { oid => $oids{aos7}->{alaChasEntPhysFanStatus} }, ]); $self->{results}->{entity} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oids{entPhysicalDescr} }, - { oid => $oids{entPhysicalName} }, - { oid => $oids{chasEntPhysAdminStatus} }, - { oid => $oids{chasEntPhysOperStatus} }, - { oid => $oids{chasEntPhysPower} }, + { oid => $oids{common}->{entPhysicalDescr} }, + { oid => $oids{common}->{entPhysicalName} }, + { oid => $oids{aos6}->{chasEntPhysAdminStatus} }, + { oid => $oids{aos6}->{chasEntPhysOperStatus} }, + { oid => $oids{aos6}->{chasEntPhysPower} }, + { oid => $oids{aos7}->{chasEntPhysAdminStatus} }, + { oid => $oids{aos7}->{chasEntPhysOperStatus} }, + { oid => $oids{aos7}->{chasEntPhysPower} }, ], return_type => 1); + + $self->{type} = 'aos6'; + foreach (keys %{$self->{results}->{entity}}) { + if (/^$oids{aos7}->{entreprise_alcatel_base}\./) { + $self->{type} = 'aos7'; + last; + } + } } sub new { @@ -79,9 +91,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } diff --git a/network/alcatel/omniswitch/snmp/mode/memory.pm b/network/alcatel/omniswitch/snmp/mode/memory.pm index 5543b03e3..582ae7489 100644 --- a/network/alcatel/omniswitch/snmp/mode/memory.pm +++ b/network/alcatel/omniswitch/snmp/mode/memory.pm @@ -31,11 +31,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning', default => '' }, - "critical:s" => { name => 'critical', default => '' }, - }); + $options{options}->add_options(arguments => { + "warning:s" => { name => 'warning', default => '' }, + "critical:s" => { name => 'critical', default => '' }, + }); return $self; } @@ -95,28 +94,60 @@ sub check_memory { sub run { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - my $oid_healthDeviceMemory1MinAvg = '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.1.10'; # it's '.0' but it's for walk multiple - my $oid_healthDeviceMemory1HrAvg = '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.1.11'; # it's '.0' but it's for walk multiple - my $oid_healthModuleMemory1MinAvg = '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.2.1.1.11'; - my $oid_healthModuleMemory1HrAvg = '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.2.1.1.12'; + my $mapping = { + aos6 => { + entry_device => '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.1', + entry_module => '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.2.1.1', + device => { + healthDeviceMemory1MinAvg => { oid => '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.1.10' }, + healthDeviceMemory1HrAvg => { oid => '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.1.11' }, + }, + module => { + healthModuleMemory1MinAvg => { oid => '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.2.1.1.11' }, + healthModuleMemory1HrAvg => { oid => '.1.3.6.1.4.1.6486.800.1.2.1.16.1.1.2.1.1.12' }, + }, + }, + aos7 => { + entry_module => '.1.3.6.1.4.1.6486.801.1.2.1.16.1.1.1.1.1', + module => { + healthModuleMemory1MinAvg => { oid => '.1.3.6.1.4.1.6486.801.1.2.1.16.1.1.1.1.1.8' }, + healthModuleMemory1HrAvg => { oid => '.1.3.6.1.4.1.6486.801.1.2.1.16.1.1.1.1.1.9' }, + }, + }, + }; - my $result = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_healthDeviceMemory1MinAvg }, - { oid => $oid_healthDeviceMemory1HrAvg }, - { oid => $oid_healthModuleMemory1MinAvg }, - { oid => $oid_healthModuleMemory1HrAvg }, - ], nothing_quit => 1); + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{aos6}->{entry_device}, start => $mapping->{aos6}->{device}->{healthDeviceMemory1MinAvg}->{oid}, end => $mapping->{aos6}->{device}->{healthDeviceMemory1HrAvg}->{oid} }, + { oid => $mapping->{aos6}->{entry_module}, start => $mapping->{aos6}->{module}->{healthModuleMemory1MinAvg}->{oid}, end => $mapping->{aos6}->{module}->{healthModuleMemory1HrAvg}->{oid} }, + { oid => $mapping->{aos7}->{entry_module}, start => $mapping->{aos7}->{module}->{healthModuleMemory1MinAvg}->{oid}, end => $mapping->{aos7}->{module}->{healthModuleMemory1HrAvg}->{oid} }, + ], nothing_quit => 1); + + my $type = 'aos6'; + if (scalar(keys %{$snmp_result->{ $mapping->{aos7}->{entry_module} }}) > 0) { + $type = 'aos7'; + } - $self->check_memory(name => 'Device memory', perf_label => '_device', - '1min' => $result->{$oid_healthDeviceMemory1MinAvg}->{$oid_healthDeviceMemory1MinAvg . '.' . 0}, - '1hour' => $result->{$oid_healthDeviceMemory1HrAvg}->{$oid_healthDeviceMemory1HrAvg . '.' . 0}); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_healthModuleMemory1MinAvg}})) { - $oid =~ /^$oid_healthModuleMemory1MinAvg\.(.*)$/; - $self->check_memory(name => "Module memory '$1'", perf_label => "_module_$1", - '1min' => $result->{$oid_healthModuleMemory1MinAvg}->{$oid_healthModuleMemory1MinAvg . '.' . $1}, - '1hour' => $result->{$oid_healthModuleMemory1HrAvg}->{$oid_healthModuleMemory1HrAvg . '.' . $1}); + if (defined($mapping->{$type}->{device})) { + my $result = $options{snmp}->map_instance(mapping => $mapping->{$type}->{device}, results => $snmp_result->{ $mapping->{$type}->{entry_device} }, instance => '0'); + $self->check_memory( + name => 'Device memory', + perf_label => '_device', + '1min' => $result->{healthDeviceMemory1MinAvg}, + '1hour' => $result->{healthDeviceMemory1HrAvg} + ); + } + + foreach my $oid ($options{snmp}->oid_lex_sort(keys %{$snmp_result->{ $mapping->{$type}->{entry_module} }})) { + next if ($oid !~ /^$mapping->{$type}->{module}->{healthModuleMemory1MinAvg}->{oid}\.(.*)$/); + my $result = $options{snmp}->map_instance(mapping => $mapping->{$type}->{module}, results => $snmp_result->{ $mapping->{$type}->{entry_module} }, instance => $1); + + $self->check_memory( + name => "Module memory '$1'", + perf_label => "_module_$1", + '1min' => $result->{healthModuleMemory1MinAvg}, + '1hour' => $result->{healthModuleMemory1HrAvg} + ); } $self->{output}->display(); diff --git a/network/alcatel/oxe/snmp/mode/domainusage.pm b/network/alcatel/oxe/snmp/mode/domainusage.pm index 110c59815..3502525ca 100644 --- a/network/alcatel/oxe/snmp/mode/domainusage.pm +++ b/network/alcatel/oxe/snmp/mode/domainusage.pm @@ -20,55 +20,29 @@ package network::alcatel::oxe::snmp::mode::domainusage; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; - -my $maps_counters = { - domain => { - '000_cac-usage' => { - set => { - key_values => [ { name => 'display' }, { name => 'cacUsed' }, { name => 'cacAllowed' } ], - closure_custom_calc => \&custom_cac_usage_calc, - closure_custom_calc_extra_options => { label_output => 'External Communication', label_perf => 'cac' }, - closure_custom_output => \&custom_usage_output, - closure_custom_perfdata => \&custom_usage_perfdata, - closure_custom_threshold_check => \&custom_usage_threshold, - }, - }, - '001_conference-usage' => { - set => { - key_values => [ { name => 'display' }, { name => 'confBusy' }, { name => 'confAvailable' } ], - closure_custom_calc => \&custom_conference_usage_calc, - closure_custom_calc_extra_options => { label_output => 'Conference circuits', label_perf => 'conference' }, - closure_custom_output => \&custom_usage_output, - closure_custom_perfdata => \&custom_usage_perfdata, - closure_custom_threshold_check => \&custom_usage_threshold, - }, - }, - } -}; sub custom_usage_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => $self->{result_values}->{label_perf} . '_used' . $extra_label, - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + + $self->{output}->perfdata_add( + label => $self->{result_values}->{label_perf} . '_used', + nlabel => $self->{nlabel}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -119,150 +93,91 @@ sub custom_conference_usage_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'domain', type => 1, cb_prefix_output => 'prefix_domain_output', message_multiple => 'All domain are ok', skipped_code => { -2 => 1, -10 => 1 } } + ]; + + $self->{maps_counters}->{domain} = [ + { label => 'cac-usage', nlabel => 'domain.communications.external.current.count', set => { + key_values => [ { name => 'display' }, { name => 'cacUsed' }, { name => 'cacAllowed' } ], + closure_custom_calc => $self->can('custom_cac_usage_calc'), + closure_custom_calc_extra_options => { label_output => 'External Communication', label_perf => 'cac' }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + { label => 'conference-usage', nlabel => 'domain.conference.circuits.current.count', set => { + key_values => [ { name => 'display' }, { name => 'confBusy' }, { name => 'confAvailable' } ], + closure_custom_calc => $self->can('custom_conference_usage_calc'), + closure_custom_calc_extra_options => { label_output => 'Conference circuits', label_perf => 'conference' }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +sub prefix_domain_output { + my ($self, %options) = @_; + + return "Domain '" . $options{instance_value}->{display} . "' "; +} + 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 => - { - "no-component:s" => { name => 'no_component' }, - "filter-domain:s" => { name => 'filter_domain' }, - }); - $self->{no_components} = undef; - - foreach my $key (('domain')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - + $options{options}->add_options(arguments => { + "filter-domain:s" => { name => 'filter_domain' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('domain')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{domain}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All Domains are ok'); - } - - foreach my $id (sort keys %{$self->{domain}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{domain}}) { - my $obj = $maps_counters->{domain}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{domain}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Domain '$self->{domain}->{$id}->{display}' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Domain '$self->{domain}->{$id}->{display}' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Domain '$self->{domain}->{$id}->{display}' $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} - my $mapping = { - confAvailable => { oid => '.1.3.6.1.4.1.637.64.4400.1.3.1.2' }, - confBusy => { oid => '.1.3.6.1.4.1.637.64.4400.1.3.1.3' }, - confOutOfOrder => { oid => '.1.3.6.1.4.1.637.64.4400.1.3.1.4' }, - cacAllowed => { oid => '.1.3.6.1.4.1.637.64.4400.1.3.1.9' }, - cacUsed => { oid => '.1.3.6.1.4.1.637.64.4400.1.3.1.10' }, + confAvailable => { oid => '.1.3.6.1.4.1.637.64.4400.1.3.1.2' }, + confBusy => { oid => '.1.3.6.1.4.1.637.64.4400.1.3.1.3' }, + confOutOfOrder => { oid => '.1.3.6.1.4.1.637.64.4400.1.3.1.4' }, + cacAllowed => { oid => '.1.3.6.1.4.1.637.64.4400.1.3.1.9' }, + cacUsed => { oid => '.1.3.6.1.4.1.637.64.4400.1.3.1.10' }, }; sub manage_selection { my ($self, %options) = @_; - $self->{domain} = {}; my $oid_ipDomainEntry = '.1.3.6.1.4.1.637.64.4400.1.3.1'; - $self->{results} = $self->{snmp}->get_table(oid => $oid_ipDomainEntry, - nothing_quit => 1); - foreach my $oid (keys %{$self->{results}}) { + my $snmp_result = $options{snmp}->get_table( + oid => $oid_ipDomainEntry, + nothing_quit => 1 + ); + + $self->{domain} = {}; + foreach my $oid (keys %$snmp_result) { next if ($oid !~ /^$mapping->{cacAllowed}->{oid}\.(\d+)/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); if (defined($self->{option_results}->{filter_domain}) && $self->{option_results}->{filter_domain} ne '' && $instance !~ /$self->{option_results}->{filter_domain}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $instance . "': no matching filter.", debug => 1); + $self->{output}->output_add(long_msg => "skipping '" . $instance . "': no matching filter.", debug => 1); next; } - $self->{domain}->{$instance} = { display => $instance, - %{$result}}; + $self->{domain}->{$instance} = { + display => $instance, + %{$result} + }; } - + if (scalar(keys %{$self->{domain}}) <= 0) { - $self->{output}->output_add(severity => defined($self->{no_components}) ? $self->{no_components} : 'unknown', - short_msg => 'No components are checked.'); + $self->{output}->add_option_msg(short_msg => "No domain found."); + $self->{output}->option_exit(); } } @@ -290,10 +205,6 @@ Can be: 'cac-usage' (%), 'conference-usage' (%). Threshold critical. Can be: 'cac-usage' (%), 'conference-usage' (%). -=item B<--no-component> - -Set the threshold where no components (Default: 'unknown' returns). - =back =cut diff --git a/network/alvarion/breezeaccess/snmp/mode/radiostatus.pm b/network/alvarion/breezeaccess/snmp/mode/radiostatus.pm new file mode 100644 index 000000000..4e0dfe5f6 --- /dev/null +++ b/network/alvarion/breezeaccess/snmp/mode/radiostatus.pm @@ -0,0 +1,140 @@ +# +# Copyright 2018 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::alvarion::breezeaccess::snmp::mode::radiostatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub custom_badframes_calc { + my ($self, %options) = @_; + + my $delta_value = $options{new_datas}->{$self->{instance} . '_bad_frames'} - $options{old_datas}->{$self->{instance} . '_bad_frames'}; + my $delta_total = $options{new_datas}->{$self->{instance} . '_total_frames'} - $options{old_datas}->{$self->{instance} . '_total_frames'}; + + $self->{result_values}->{bad_prct} = 0; + if ($delta_total > 0) { + $self->{result_values}->{bad_prct} = $delta_value * 100 / $delta_total; + } + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + ]; + $self->{maps_counters}->{global} = [ + { label => 'rx-snr', nlabel => 'rx.signal.noise.ratio.dbm', set => { + key_values => [ { name => 'rx_snr' } ], + output_template => 'Average signal to noise ratio: %s Dbm', + perfdatas => [ + { label => 'rx_snr', value => 'rx_snr_absolute', template => '%s', min => 0 , unit => 'Dbm' }, + ], + } + }, + { label => 'rx-power', nlabel => 'rx.signal.strength.dbm', set => { + key_values => [ { name => 'rx_power' } ], + output_template => 'Received signal strength: %s Dbm', + perfdatas => [ + { label => 'rx_power', value => 'rx_power_absolute', template => '%s', min => 0 , unit => 'Dbm' }, + ], + } + }, + { label => 'bad-frames', nlabel => 'frames.bad.percentage', set => { + key_values => [ { name => 'total_frames', diff => 1 }, { name => 'bad_frames', diff => 1 } ], + closure_custom_calc => $self->can('custom_badframes_calc'), + output_template => 'Bad frames: %.2f %%', output_use => 'bad_prct', threshold_use => 'bad_prct', + perfdatas => [ + { label => 'bad_frames', value => 'bad_prct', template => '%.2f', min => 0, max => 100, + unit => '%' }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_brzaccVLAverageReceiveSNR = '.1.3.6.1.4.1.12394.1.1.11.1.0'; + my $oid_brzaccVLAverageReceiveRSSI = '.1.3.6.1.4.1.12394.1.1.11.10.0'; + my $oid_brzaccVLRecievedBadFrames = '.1.3.6.1.4.1.12394.1.1.11.2.3.7.0'; + my $oid_brzaccVLTotalRecievedDataFrames = '.1.3.6.1.4.1.12394.1.1.11.2.3.6.0'; + my $result = $options{snmp}->get_leef(oids => [ + $oid_brzaccVLAverageReceiveSNR, $oid_brzaccVLAverageReceiveRSSI, $oid_brzaccVLRecievedBadFrames, + $oid_brzaccVLTotalRecievedDataFrames + ], nothing_quit => 1); + + $self->{cache_name} = "alvarion_breezeaccess_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + $self->{global} = { + rx_snr => $result->{$oid_brzaccVLAverageReceiveSNR}, + rx_power => $result->{$oid_brzaccVLAverageReceiveRSSI}, + bad_frames => $result->{$oid_brzaccVLRecievedBadFrames}, + total_frames => $result->{$oid_brzaccVLTotalRecievedDataFrames}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check radio signal + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='rx-power' + +=item B<--warning-*> + +Threshold warning. +Can be: 'rx-snr', 'rx-power', 'bad-frames'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'rx-snr', 'rx-power', 'bad-frames'. + +=back + +=cut diff --git a/network/alvarion/breezeaccess/snmp/plugin.pm b/network/alvarion/breezeaccess/snmp/plugin.pm new file mode 100644 index 000000000..ee68c6ab8 --- /dev/null +++ b/network/alvarion/breezeaccess/snmp/plugin.pm @@ -0,0 +1,51 @@ +# +# Copyright 2018 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::alvarion::breezeaccess::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}} = ( + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'radio-status' => 'network::alvarion::breezeaccess::snmp::mode::radiostatus', + 'uptime' => 'snmp_standard::mode::uptime', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Alvarion BreezeACCESS in SNMP + +=cut diff --git a/network/arista/snmp/mode/memory.pm b/network/arista/snmp/mode/memory.pm index bfdd6033e..c2ca16b32 100644 --- a/network/arista/snmp/mode/memory.pm +++ b/network/arista/snmp/mode/memory.pm @@ -39,7 +39,7 @@ sub set_counters { ]; $self->{maps_counters}->{storage} = [ - { label => 'usage', set => { + { label => 'usage', nlabel => 'memory.usage.bytes', set => { key_values => [ { name => 'display' }, { name => 'used' }, { name => 'size' }, { name => 'allocation_units' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_output => $self->can('custom_usage_output'), diff --git a/network/atrica/snmp/mode/connections.pm b/network/atrica/snmp/mode/connections.pm index 59fcc3233..1af2398a1 100644 --- a/network/atrica/snmp/mode/connections.pm +++ b/network/atrica/snmp/mode/connections.pm @@ -29,8 +29,8 @@ 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', + 'atrconncepgendescr' => { oid => '.1.3.6.1.4.1.6110.2.7.5.1.1', cache => 'reload_cache_index_value' }, + 'atrconningdescr' => { oid => '.1.3.6.1.4.1.6110.2.2.1.1.2', cache => 'reload_cache_index_value' }, }; } @@ -142,82 +142,77 @@ sub default_oid_display_name { return 'atrConnCepGenDescr'; } -sub set_counters { +sub set_counters_traffic { 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); + push @{$self->{maps_counters}->{int}}, + { label => 'in-cir', filter => 'add_traffic', nlabel => 'interface.traffic.in.cir.bitspersecond', 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'), + } + }, + { label => 'in-eir', filter => 'add_traffic', nlabel => 'interface.traffic.in.eir.bitspersecond', 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'), + } + }, + { label => 'out-cir', filter => 'add_traffic', nlabel => 'interface.traffic.out.cir.bitspersecond', 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'), + } + }, + { label => 'out-eir', filter => 'add_traffic', nlabel => 'interface.traffic.out.eir.bitspersecond', 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'), + } + }, + ; +} + +sub set_counters_errors { + my ($self, %options) = @_; + + push @{$self->{maps_counters}->{int}}, + { label => 'in-eir-discard', filter => 'add_errors', nlabel => 'interface.packets.in.eir.discards.count', 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'), + } + }, + { label => 'out-eir-discard', filter => 'add_errors', nlabel => 'interface.packets.out.eir.discards.count', 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'), + } + }, + ; } 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 ($self->{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); @@ -227,11 +222,15 @@ sub custom_traffic_perfdata { $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}); + $self->{output}->perfdata_add( + label => $self->{result_values}->{label}, unit => 'b/s', + nlabel => $self->{nlabel}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{traffic_per_seconds}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed} + ); } sub custom_traffic_threshold { @@ -239,9 +238,9 @@ sub custom_traffic_threshold { my $exit = 'ok'; if ($self->{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' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } elsif ($self->{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' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_per_seconds}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } return $exit; } @@ -333,41 +332,41 @@ sub load_errors { sub add_result_speed { my ($self, %options) = @_; - return if (defined($self->{interface_selected}->{$options{instance}}->{speed_in})); - $self->{interface_selected}->{$options{instance}}->{speed_in} = 0; - $self->{interface_selected}->{$options{instance}}->{speed_out} = 0; + return if (defined($self->{int}->{$options{instance}}->{speed_in})); + $self->{int}->{$options{instance}}->{speed_in} = 0; + $self->{int}->{$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->{int}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed} * 1000000; + $self->{int}->{$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 ''); + $self->{int}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed_in} * 1000000 if (defined($self->{option_results}->{speed_in}) && $self->{option_results}->{speed_in} ne ''); + $self->{int}->{$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 = defined($self->{results}->{$self->{oid_speed} . "." . $options{instance}}) ? $self->{results}->{$self->{oid_speed} . "." . $options{instance}} : 0; $interface_speed *= 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 ''); + $self->{int}->{$options{instance}}->{speed_in} = $interface_speed; + $self->{int}->{$options{instance}}->{speed_out} = $interface_speed; + $self->{int}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed_in} * 1000000 if (defined($self->{option_results}->{speed_in}) && $self->{option_results}->{speed_in} ne ''); + $self->{int}->{$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->{int}->{$options{instance}}->{in_eir_discard} = $self->{results}->{$self->{oid_ing_eir_discard} . '.' . $options{instance}} * 8; + $self->{int}->{$options{instance}}->{out_eir_discard} = $self->{results}->{$self->{oid_eg_eir_discard} . '.' . $options{instance}} * 8; $self->add_result_speed(%options); } 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->{int}->{$options{instance}}->{in_cir} = $self->{results}->{$self->{oid_ing_cir} . '.' . $options{instance}} * 8; + $self->{int}->{$options{instance}}->{in_eir} = $self->{results}->{$self->{oid_ing_eir} . '.' . $options{instance}} * 8; + $self->{int}->{$options{instance}}->{out_cir} = $self->{results}->{$self->{oid_eg_cir} . '.' . $options{instance}} * 8; + $self->{int}->{$options{instance}}->{out_eir} = $self->{results}->{$self->{oid_eg_eir} . '.' . $options{instance}} * 8; $self->add_result_speed(%options); } diff --git a/network/atto/fiberbridge/snmp/mode/components/alarm.pm b/network/atto/fiberbridge/snmp/mode/components/alarm.pm new file mode 100644 index 000000000..df79cbd68 --- /dev/null +++ b/network/atto/fiberbridge/snmp/mode/components/alarm.pm @@ -0,0 +1,62 @@ +# +# Copyright 2018 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. +# +# Author : ArnoMLT +# + +package network::atto::fiberbridge::snmp::mode::components::alarm; + +use strict; +use warnings; + +my %map_throughput_status = ( + 1 => 'normal', 2 => 'warning' +); +my $oid_chassisThroughputStatus = '.1.3.6.1.4.1.4547.2.3.2.11.0'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, $oid_chassisThroughputStatus; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "checking alarms"); + $self->{components}->{alarm} = { name => 'alarms', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'alarm')); + + return if (!defined($self->{results}->{$oid_chassisThroughputStatus})); + my ($instance, $name) = (1, 'throughput'); + my $status = $map_throughput_status{$self->{results}->{$oid_chassisThroughputStatus}}; + + next if ($self->check_filter(section => 'alarm', instance => $instance, name => $name)); + $self->{components}->{alarm}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("alarm '%s' status is %s [instance = %s]", + $name, $status, $instance)); + my $exit = $self->get_severity(section => 'alarm', value => $status); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Alarm '%s' status is %s", $name, $status)); + } +} + +1; diff --git a/network/atto/fiberbridge/snmp/mode/components/temperature.pm b/network/atto/fiberbridge/snmp/mode/components/temperature.pm new file mode 100644 index 000000000..f3ae18e17 --- /dev/null +++ b/network/atto/fiberbridge/snmp/mode/components/temperature.pm @@ -0,0 +1,78 @@ +# +# Copyright 2018 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. +# +# Author : ArnoMLT +# + +package network::atto::fiberbridge::snmp::mode::components::temperature; + +use strict; +use warnings; + +my %map_chassis_status = ( + 1 => 'normal', 2 => 'warning', 3 => 'critical', +); +my $oid_chassisTemperatureStatus = '.1.3.6.1.4.1.4547.2.3.2.9.0'; +my $oid_chassisTemperature = '.1.3.6.1.4.1.4547.2.3.2.8.0'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, $oid_chassisTemperatureStatus, $oid_chassisTemperature; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "checking temperatures"); + $self->{components}->{temperature} = { name => 'temperatures', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'temperature')); + + return if (!defined($self->{results}->{$oid_chassisTemperatureStatus})); + my ($instance, $name) = (1, 'chassis'); + my $status = $map_chassis_status{$self->{results}->{$oid_chassisTemperatureStatus}}; + my $temperature = $self->{results}->{$oid_chassisTemperature}; + + next if ($self->check_filter(section => 'temperature', instance => $instance, name => $name)); + $self->{components}->{temperature}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("temperature '%s' status is %s [instance = %s, value = %s C]", + $name, $status, $instance, $temperature)); + my $exit = $self->get_severity(section => 'temperature', value => $status); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' status is %s", $name, $status)); + } + + my ($exit2, $warn, $crit) = $self->get_severity_numeric(section => 'temperature', instance => $instance, name => $name, value => $temperature); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Temperature '%s' is %s C", $name, $temperature)); + } + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $name, + value => $temperature, + warning => $warn, + critical => $crit + ); +} + +1; diff --git a/network/atto/fiberbridge/snmp/mode/fcportusage.pm b/network/atto/fiberbridge/snmp/mode/fcportusage.pm new file mode 100644 index 000000000..c73c5cfb2 --- /dev/null +++ b/network/atto/fiberbridge/snmp/mode/fcportusage.pm @@ -0,0 +1,223 @@ +# +# Copyright 2019 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::atto::fiberbridge::snmp::mode::fcportusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use Digest::MD5 qw(md5_hex); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'status : ' . $self->{result_values}->{status} . ' [admin: ' . $self->{result_values}->{admin} . ']'; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_fcPortOperationalState'}; + $self->{result_values}->{admin} = $options{new_datas}->{$self->{instance} . '_fcPortAdminState'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'fc', type => 1, cb_prefix_output => 'prefix_fc_output', message_multiple => 'All fc ports are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{fc} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'fcPortOperationalState' }, { name => 'fcPortAdminState' }, { 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 => \&catalog_status_threshold, + } + }, + { label => 'traffic-in', nlabel => 'fc.port.traffic.in.wordspersecond', set => { + key_values => [ { name => 'fcStatsRxWords', diff => 1 }, { name => 'display' } ], + per_second => 1, + output_template => 'traffic in : %.2f words/s', + perfdatas => [ + { label => 'traffic_in', template => '%.2f', value => 'fcStatsRxWords_per_second', + unit => 'words/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-out', nlabel => 'fc.port.traffic.out.wordspersecond', set => { + key_values => [ { name => 'fcStatsTxWords', diff => 1 }, { name => 'display' } ], + per_second => 1, + output_template => 'traffic out : %.2f words/s', + perfdatas => [ + { label => 'traffic_out', template => '%.2f', value => 'fcStatsTxWords_per_second', + unit => 'words/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'invalid-crc', nlabel => 'fc.port.invalid.crc.count', set => { + key_values => [ { name => 'fcStatsErrInvalidCRC', diff => 1 }, { name => 'display' } ], + output_template => 'number of invalid CRC : %s', + perfdatas => [ + { label => 'invalid_crc', value => 'fcStatsErrInvalidCRC_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'signal-loss', nlabel => 'fc.port.signal.loss.count', set => { + key_values => [ { name => 'fcStatsErrSignalLoss', diff => 1 }, { name => 'display' } ], + output_template => 'number of signal loss : %s', + perfdatas => [ + { label => 'signal_loss', value => 'fcStatsErrSignalLoss_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_fc_output { + my ($self, %options) = @_; + + return "fc port '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{admin} =~ /enabled/ and %{status} !~ /online/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +my $map_oper_state = { -1 => 'unknown', 1 => 'online', 2 => 'offline' }; +my $map_admin_state = { -1 => 'unknown', 1 => 'disabled', 2 => 'enabled' }; + +my $mapping = { + fcPortOperationalState => { oid => '.1.3.6.1.4.1.4547.2.3.3.1.1.3', map => $map_oper_state }, + fcPortAdminState => { oid => '.1.3.6.1.4.1.4547.2.3.3.1.1.4', map => $map_admin_state }, + + fcStatsTxWords => { oid => '.1.3.6.1.4.1.4547.2.3.3.2.1.2' }, + fcStatsRxWords => { oid => '.1.3.6.1.4.1.4547.2.3.3.2.1.3' }, + fcStatsErrInvalidCRC => { oid => '.1.3.6.1.4.1.4547.2.3.3.2.1.7' }, + fcStatsErrSignalLoss => { oid => '.1.3.6.1.4.1.4547.2.3.3.2.1.11' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_fcSFPSerialNum = '.1.3.6.1.4.1.4547.2.3.2.12.1.3'; + + $self->{fc} = {}; + my $snmp_result = $options{snmp}->get_table(oid => $oid_fcSFPSerialNum, nothing_quit => 1); + foreach my $oid (keys %{$snmp_result}) { + $oid =~ /^$oid_fcSFPSerialNum\.(.*)$/; + my $instance = $1; + my $name = centreon::plugins::misc::trim($snmp_result->{$oid_fcSFPSerialNum . '.' . $instance}); + + 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 fc port '" . $name . "'.", debug => 1); + next; + } + + $self->{fc}->{$instance} = { display => $name }; + } + + if (scalar(keys %{$self->{fc}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No entry found."); + $self->{output}->option_exit(); + } + + $options{snmp}->load(oids => [ + map($_->{oid}, values(%$mapping)) + ], + instances => [keys %{$self->{fc}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{fc}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + $self->{fc}->{$_} = { %{$self->{fc}->{$_}}, %$result }; + } + + $self->{cache_name} = "atto_fiberbridge_" . $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')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check fc port usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^status$' + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'traffic-in', 'traffic-out', 'invalid-crc', 'signal-loss'. + +=item B<--filter-name> + +Filter name (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{admin}, %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{admin} =~ /enabled/ and %{status} !~ /online/'). +Can used special variables like: %{admin}, %{status}, %{display} + +=back + +=cut diff --git a/network/atto/fiberbridge/snmp/mode/hardware.pm b/network/atto/fiberbridge/snmp/mode/hardware.pm new file mode 100644 index 000000000..fe573c18a --- /dev/null +++ b/network/atto/fiberbridge/snmp/mode/hardware.pm @@ -0,0 +1,116 @@ +# +# Copyright 2018 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. +# +# Author : ArnoMLT +# + +package network::atto::fiberbridge::snmp::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(temperature|alarm)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + temperature => [ + ['normal', 'OK'], + ['warning', 'WARNING'], + ['critical', 'CRITICAL'], + ], + alarm => [ + ['normal', 'OK'], + ['warning', 'WARNING'], + ], + }; + + $self->{components_path} = 'network::atto::fiberbridge::snmp::mode::components'; + $self->{components_module} = ['alarm', 'temperature']; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_leef(oids => $self->{request}); +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'psu', 'alarm'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=psu) +Can also exclude specific instance: --filter=psu,1 + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=item B<--threshold-overload> + +Set to overload default threshold values (syntax: section,[instance,]status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='alarm,OK,warning' + +=item B<--warning> + +Set warning threshold for temperatures, fan (syntax: type,instance,threshold) +Example: --warning='xxxxx,.*,30' + +=item B<--critical> + +Set critical threshold for temperatures, fan (syntax: type,instance,threshold) +Example: --critical='xxxxx,.*,40' + +=back + +=cut diff --git a/network/atto/fiberbridge/snmp/plugin.pm b/network/atto/fiberbridge/snmp/plugin.pm new file mode 100644 index 000000000..1947a9d01 --- /dev/null +++ b/network/atto/fiberbridge/snmp/plugin.pm @@ -0,0 +1,49 @@ +# +# Copyright 2019 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::atto::fiberbridge::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}} = ( + 'hardware' => 'network::atto::fiberbridge::snmp::mode::hardware', + 'fcport-usage' => 'network::atto::fiberbridge::snmp::mode::fcportusage', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Atto FiberBridge (6500, 7500,...) in SNMP. + +=cut diff --git a/network/audiocodes/snmp/mode/cpu.pm b/network/audiocodes/snmp/mode/cpu.pm index 62ea1ee87..e3c7892c0 100644 --- a/network/audiocodes/snmp/mode/cpu.pm +++ b/network/audiocodes/snmp/mode/cpu.pm @@ -32,7 +32,7 @@ sub set_counters { { name => 'global', type => 0, message_separator => ' - ' }, ]; $self->{maps_counters}->{global} = [ - { label => 'voip', set => { + { label => 'voip', nlabel => 'cpu.voip.utilization.percentage', set => { key_values => [ { name => 'voip' } ], output_template => 'CPU VoIp Usage : %.2f %%', perfdatas => [ @@ -40,7 +40,7 @@ sub set_counters { ], } }, - { label => 'data', set => { + { label => 'data', nlabel => 'cpu.data.utilization.percentage', set => { key_values => [ { name => 'data' } ], output_template => 'CPU Data Usage : %.2f %%', perfdatas => [ diff --git a/network/audiocodes/snmp/mode/memory.pm b/network/audiocodes/snmp/mode/memory.pm index ba82234a9..8baf9c847 100644 --- a/network/audiocodes/snmp/mode/memory.pm +++ b/network/audiocodes/snmp/mode/memory.pm @@ -32,7 +32,7 @@ sub set_counters { { name => 'global', type => 0, message_separator => ' - ' }, ]; $self->{maps_counters}->{global} = [ - { label => 'voip', set => { + { label => 'voip', nlabel => 'memory.voip.utilization.percentage', set => { key_values => [ { name => 'voip' } ], output_template => 'Memory VoIp Usage : %.2f %%', perfdatas => [ @@ -40,7 +40,7 @@ sub set_counters { ], } }, - { label => 'data', set => { + { label => 'data', nlabel => 'memory.data.utilization.percentage', set => { key_values => [ { name => 'data' } ], output_template => 'Memory Data Usage : %.2f %%', perfdatas => [ diff --git a/network/barracuda/cloudgen/snmp/mode/components/fan.pm b/network/barracuda/cloudgen/snmp/mode/components/fan.pm index 2c9b0e296..847ce791a 100644 --- a/network/barracuda/cloudgen/snmp/mode/components/fan.pm +++ b/network/barracuda/cloudgen/snmp/mode/components/fan.pm @@ -60,15 +60,16 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '%s' speed is '%s' RPM", $result->{hwSensorName}, $result->{hwSensorValue})); } - - my $perf_label = $result->{hwSensorName}; - $perf_label =~ s/ /_/g; - $self->{output}->perfdata_add(label => 'speed_' . $perf_label, unit => 'rpm', - value => $result->{hwSensorValue}, - warning => $warn, - critical => $crit - ); + + $self->{output}->perfdata_add( + label => 'speed', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $result->{hwSensorName}, + value => $result->{hwSensorValue}, + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/network/barracuda/cloudgen/snmp/mode/components/temperature.pm b/network/barracuda/cloudgen/snmp/mode/components/temperature.pm index 60b8b7924..db9bec13b 100644 --- a/network/barracuda/cloudgen/snmp/mode/components/temperature.pm +++ b/network/barracuda/cloudgen/snmp/mode/components/temperature.pm @@ -60,15 +60,16 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is '%s' celsius degrees", $result->{hwSensorName}, $result->{hwSensorValue} / 1000)); } - - my $perf_label = $result->{hwSensorName}; - $perf_label =~ s/ /_/g; - $self->{output}->perfdata_add(label => 'temperature_' . $perf_label, unit => 'C', - value => $result->{hwSensorValue} / 1000, - warning => $warn, - critical => $crit - ); + + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $result->{hwSensorName}, + value => $result->{hwSensorValue} / 1000, + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/network/barracuda/cloudgen/snmp/mode/components/voltage.pm b/network/barracuda/cloudgen/snmp/mode/components/voltage.pm index 3262e6422..eb1dff13d 100644 --- a/network/barracuda/cloudgen/snmp/mode/components/voltage.pm +++ b/network/barracuda/cloudgen/snmp/mode/components/voltage.pm @@ -61,14 +61,15 @@ sub check { short_msg => sprintf("Voltage '%s' is '%s' mV", $result->{hwSensorName}, $result->{hwSensorValue})); } - my $perf_label = $result->{hwSensorName}; - $perf_label =~ s/ /_/g; - $self->{output}->perfdata_add(label => 'voltage_' . $perf_label, unit => 'mV', - value => $result->{hwSensorValue}, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'voltage', unit => 'mV', + nlabel => 'hardware.voltage.millivolt', + instances => $result->{hwSensorName}, + value => $result->{hwSensorValue}, + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/network/beeware/snmp/mode/reverseproxyusage.pm b/network/beeware/snmp/mode/reverseproxyusage.pm index 5a74241e7..bf91721f1 100644 --- a/network/beeware/snmp/mode/reverseproxyusage.pm +++ b/network/beeware/snmp/mode/reverseproxyusage.pm @@ -57,7 +57,7 @@ sub set_counters { closure_custom_threshold_check => \&catalog_status_threshold, } }, - { label => 'cpu', set => { + { label => 'cpu', nlabel => 'reverseproxy.cpu.utilization.percentage', set => { key_values => [ { name => 'cpu' }, { name => 'display' } ], output_template => 'CPU Usage : %.2f %%', perfdatas => [ @@ -66,7 +66,7 @@ sub set_counters { ], } }, - { label => 'memory', set => { + { label => 'memory', nlabel => 'reverseproxy.memory.usage.bytes', set => { key_values => [ { name => 'memory' }, { name => 'display' } ], output_template => 'Memory Usage : %s %s', output_change_bytes => 1, @@ -76,7 +76,7 @@ sub set_counters { ], } }, - { label => 'nbchilds', set => { + { label => 'nbchilds', nlabel => 'reverseproxy.child.count', set => { key_values => [ { name => 'nbchilds' }, { name => 'display' } ], output_template => 'Num childs : %s', perfdatas => [ diff --git a/network/bluecoat/snmp/mode/components/sensor.pm b/network/bluecoat/snmp/mode/components/sensor.pm index 5216fd364..1a5eae544 100644 --- a/network/bluecoat/snmp/mode/components/sensor.pm +++ b/network/bluecoat/snmp/mode/components/sensor.pm @@ -46,22 +46,22 @@ my %map_code = ( 15 => 'fanStopped', ); my %map_units = ( - 1 => '', # other - 2 => '', # truthvalue - 3 => '', # specialEnum - 4 => 'V', # volts - 5 => 'C', # celsius - 6 => 'rpm' + 1 => { unit => '', nunit => '' }, # other + 2 => { unit => '', nunit => '' }, # truthvalue + 3 => { unit => '', nunit => '' }, # specialEnum + 4 => { unit => 'V', nunit => 'voltage.volt' }, # volts + 5 => { unit => 'C', nunit => 'temperature.celsius' }, # celsius + 6 => { unit => 'rpm', nunit => 'speed.rpm' }, ); # In MIB 'BLUECOAT-SG-SENSOR-MIB' my $mapping = { - deviceSensorUnits => { oid => '.1.3.6.1.4.1.3417.2.1.1.1.1.1.3', map => \%map_units }, - deviceSensorScale => { oid => '.1.3.6.1.4.1.3417.2.1.1.1.1.1.4' }, - deviceSensorValue => { oid => '.1.3.6.1.4.1.3417.2.1.1.1.1.1.5' }, - deviceSensorCode => { oid => '.1.3.6.1.4.1.3417.2.1.1.1.1.1.6', map => \%map_code }, - deviceSensorStatus => { oid => '.1.3.6.1.4.1.3417.2.1.1.1.1.1.7', map => \%map_status }, - deviceSensorName => { oid => '.1.3.6.1.4.1.3417.2.1.1.1.1.1.9' }, + deviceSensorUnits => { oid => '.1.3.6.1.4.1.3417.2.1.1.1.1.1.3', map => \%map_units }, + deviceSensorScale => { oid => '.1.3.6.1.4.1.3417.2.1.1.1.1.1.4' }, + deviceSensorValue => { oid => '.1.3.6.1.4.1.3417.2.1.1.1.1.1.5' }, + deviceSensorCode => { oid => '.1.3.6.1.4.1.3417.2.1.1.1.1.1.6', map => \%map_code }, + deviceSensorStatus => { oid => '.1.3.6.1.4.1.3417.2.1.1.1.1.1.7', map => \%map_status }, + deviceSensorName => { oid => '.1.3.6.1.4.1.3417.2.1.1.1.1.1.9' }, }; my $oid_deviceSensorValueEntry = '.1.3.6.1.4.1.3417.2.1.1.1.1.1'; @@ -77,7 +77,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking sensors"); $self->{components}->{sensor} = {name => 'sensors', total => 0, skip => 0}; return if ($self->check_filter(section => 'sensor')); - + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_deviceSensorValueEntry}})) { next if ($oid !~ /^$mapping->{deviceSensorStatus}->{oid}\.(.*)$/); my $instance = $1; @@ -89,7 +89,7 @@ sub check { $self->{output}->output_add(long_msg => sprintf("Sensor '%s' status is '%s' [instance: %s, operational status: %s, value: %s, scale: %s, unit: %s]", $result->{deviceSensorName}, $result->{deviceSensorCode}, $instance, $result->{deviceSensorStatus}, $result->{deviceSensorValue}, $result->{deviceSensorScale}, - $result->{deviceSensorUnits})); + $result->{deviceSensorUnits}->{unit})); my $exit = $self->get_severity(section => 'sensor_opstatus', value => $result->{deviceSensorStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, @@ -103,19 +103,24 @@ sub check { $result->{deviceSensorName}, $result->{deviceSensorCode})); } - if (defined($result->{deviceSensorValue}) && $result->{deviceSensorValue} =~ /[0-9]/ && $result->{deviceSensorUnits} ne '') { + if (defined($result->{deviceSensorValue}) && $result->{deviceSensorValue} =~ /[0-9]/ && $result->{deviceSensorUnits}->{unit} ne '') { my $value = ($result->{deviceSensorValue} * (10 ** $result->{deviceSensorScale})); my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'sensor', instance => $instance, value => $value); if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit2, - short_msg => sprintf("Sensor '%s' value is %s %s", $result->{deviceSensorName}, $value, $result->{deviceSensorUnits})); + short_msg => sprintf("Sensor '%s' value is %s %s", $result->{deviceSensorName}, $value, $result->{deviceSensorUnits}->{unit})); } - $self->{output}->perfdata_add(label => $result->{deviceSensorName}, unit => $result->{deviceSensorUnits}, - value => $value, - warning => $warn, - critical => $crit); + + $self->{output}->perfdata_add( + label => 'sensor', unit => $result->{deviceSensorUnits}->{unit}, + nlabel => 'hardware.sensor.' . $result->{deviceSensorUnits}->{nunit}, + instances => $result->{deviceSensorName}, + value => $value, + warning => $warn, + critical => $crit + ); } } } -1; \ No newline at end of file +1; diff --git a/network/bluecoat/snmp/mode/cpu.pm b/network/bluecoat/snmp/mode/cpu.pm index 774cc4b03..7c10239a3 100644 --- a/network/bluecoat/snmp/mode/cpu.pm +++ b/network/bluecoat/snmp/mode/cpu.pm @@ -106,7 +106,7 @@ sub manage_selection { $self->{cpu}->{$i} = { display => $i, - idle => $result->{sgProxyCpuCoreBusyTime}, busy => $result->{sgProxyCpuCoreIdleTime} + idle => $result->{sgProxyCpuCoreIdleTime}, busy => $result->{sgProxyCpuCoreBusyTime} }; $i++; } diff --git a/network/brocade/snmp/mode/hardware.pm b/network/brocade/snmp/mode/hardware.pm index e20b7a931..ecebb53f6 100644 --- a/network/brocade/snmp/mode/hardware.pm +++ b/network/brocade/snmp/mode/hardware.pm @@ -61,9 +61,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } @@ -131,7 +130,7 @@ use centreon::plugins::misc; my %map_status = (1 => 'unknown', 2 => 'faulty', 3 => 'below-min', 4 => 'nominal', 5 => 'above-max', 6 => 'absent'); my %map_type = (1 => 'temperature', 2 => 'fan', 3 => 'power-supply'); -my %map_unit = (temperature => 'C', fan => 'rpm'); # No voltage value available +my %map_unit = (temperature => 'celsius', fan => 'rpm'); # No voltage value available my $mapping = { swSensorType => { oid => '.1.3.6.1.4.1.1588.2.1.1.1.1.22.1.2', map => \%map_type }, @@ -180,11 +179,14 @@ sub check { short_msg => sprintf("%s sensor '%s' is %s %s", $result->{swSensorType}, $result->{swSensorInfo}, $result->{swSensorValue}, $map_unit{$result->{swSensorType}})); } - $self->{output}->perfdata_add(label => $result->{swSensorInfo}, unit => $map_unit{$result->{swSensorType}}, - value => $result->{swSensorValue}, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'sensor', unit => $map_unit{$result->{swSensorType}}, + nlabel => 'hardware.sensor.' . $result->{swSensorType} . '.' . $map_unit{$result->{swSensorType}}, + instances => $result->{swSensorInfo}, + value => $result->{swSensorValue}, + warning => $warn, + critical => $crit + ); } } } diff --git a/network/checkpoint/snmp/mode/components/fan.pm b/network/checkpoint/snmp/mode/components/fan.pm index 697ef4ee5..3528cdb1f 100644 --- a/network/checkpoint/snmp/mode/components/fan.pm +++ b/network/checkpoint/snmp/mode/components/fan.pm @@ -68,8 +68,12 @@ sub check { } if (defined($result->{fanSpeedSensorValue}) && $result->{fanSpeedSensorValue} =~ /^[0-9\.]+$/) { - $self->{output}->perfdata_add(label => $result->{fanSpeedSensorName}, unit => 'rpm', - value => sprintf("%d", $result->{fanSpeedSensorValue})); + $self->{output}->perfdata_add( + label => 'fan_speed', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => [$result->{fanSpeedSensorName}, $instance], + value => sprintf("%d", $result->{fanSpeedSensorValue}) + ); } } } diff --git a/network/checkpoint/snmp/mode/components/temperature.pm b/network/checkpoint/snmp/mode/components/temperature.pm index 715c9bd00..a0527671e 100644 --- a/network/checkpoint/snmp/mode/components/temperature.pm +++ b/network/checkpoint/snmp/mode/components/temperature.pm @@ -67,8 +67,12 @@ sub check { } if (defined($result->{tempertureSensorValue}) && $result->{tempertureSensorValue} =~ /^[0-9\.]+$/) { - $self->{output}->perfdata_add(label => 'temp_' . $result->{tempertureSensorName} . '_' . $instance , unit => 'C', - value => sprintf("%.2f", $result->{tempertureSensorValue})); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => [$result->{tempertureSensorName}, $instance], + value => sprintf("%.2f", $result->{tempertureSensorValue}) + ); } } } diff --git a/network/checkpoint/snmp/mode/components/voltage.pm b/network/checkpoint/snmp/mode/components/voltage.pm index 6019e9500..339bc5632 100644 --- a/network/checkpoint/snmp/mode/components/voltage.pm +++ b/network/checkpoint/snmp/mode/components/voltage.pm @@ -67,8 +67,12 @@ sub check { } if (defined($result->{voltageSensorValue}) && $result->{voltageSensorValue} =~ /^[0-9\.]+$/) { - $self->{output}->perfdata_add(label => 'volt_' . $result->{voltageSensorName} . '_' . $instance, unit => 'V', - value => sprintf("%.2f", $result->{voltageSensorValue})); + $self->{output}->perfdata_add( + label => 'volt', unit => 'V', + nlabel => 'hardware.voltage.volt', + instances => [$result->{voltageSensorName}, $instance], + value => sprintf("%.2f", $result->{voltageSensorValue}) + ); } } } diff --git a/network/checkpoint/snmp/mode/hastate.pm b/network/checkpoint/snmp/mode/hastate.pm index 7d932689b..d2d57c130 100644 --- a/network/checkpoint/snmp/mode/hastate.pm +++ b/network/checkpoint/snmp/mode/hastate.pm @@ -101,7 +101,7 @@ sub manage_selection { nothing_quit => 1); if ($result->{$oid_haInstalled} < 1 or $result->{$oid_haStarted} eq "no") { - $self->{output}->output_add(severity => $self->{option_results}->{no_ha_state}, + $self->{output}->output_add(severity => $self->{option_results}->{no_ha_status}, short_msg => sprintf("Looks like HA is not started, or not installed .."), long_msg => sprintf("HA Installed : '%u' HA Started : '%s'", $result->{$oid_haInstalled}, $result->{$oid_haStarted}), diff --git a/network/checkpoint/snmp/mode/vpnstatus.pm b/network/checkpoint/snmp/mode/vpnstatus.pm index 1b015ad15..fd03aa8b6 100644 --- a/network/checkpoint/snmp/mode/vpnstatus.pm +++ b/network/checkpoint/snmp/mode/vpnstatus.pm @@ -67,12 +67,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '%{type} eq "permanent" and %{status} =~ /down/i' }, - }); + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' }, + 'warning-status:s' => { name => 'warning_status', default => '' }, + 'critical-status:s' => { name => 'critical_status', default => '%{type} eq "permanent" and %{status} =~ /down/i' }, + 'filter-name:s' => { name => 'filter_name' }, + 'buggy-snmp' => { name => 'buggy_snmp' }, + }); return $self; } @@ -100,16 +101,22 @@ my $mapping = { tunnelState => { oid => '.1.3.6.1.4.1.2620.500.9002.1.3', map => \%map_state }, tunnelType => { oid => '.1.3.6.1.4.1.2620.500.9002.1.11', map => \%map_type }, }; +my $oid_tunnelEntry = '.1.3.6.1.4.1.2620.500.9002.1'; sub manage_selection { my ($self, %options) = @_; $self->{vs} = {}; - my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + my $snmp_result; + if (defined($self->{option_results}->{buggy_snmp})) { + $snmp_result = $options{snmp}->get_table(oid => $oid_tunnelEntry, nothing_quit => 1); + } else { + $snmp_result = $options{snmp}->get_multiple_table(oids => [ { oid => $mapping->{tunnelPeerObjName}->{oid} }, { oid => $mapping->{tunnelState}->{oid} }, { oid => $mapping->{tunnelType}->{oid} }, ], nothing_quit => 1, return_type => 1); + } foreach my $oid (keys %{$snmp_result}) { next if ($oid !~ /^$mapping->{tunnelState}->{oid}\.(.*)$/); @@ -122,9 +129,11 @@ sub manage_selection { next; } - $self->{vpn}->{$instance} = { display => $result->{tunnelPeerObjName}, - status => $result->{tunnelState}, - type => $result->{tunnelType} }; + $self->{vpn}->{$instance} = { + display => $result->{tunnelPeerObjName}, + status => $result->{tunnelState}, + type => $result->{tunnelType} + }; } if (scalar(keys %{$self->{vpn}}) <= 0) { @@ -157,6 +166,10 @@ Can used special variables like: %{type}, %{status}, %{display} Set critical threshold for status (Default: '%{type} eq "permanent" and %{status} =~ /down/i'). Can used special variables like: %{type}, %{status}, %{display} +=item B<--buggy-snmp> + +Checkpoint snmp can be buggy. Test that option if no response. + =back =cut diff --git a/network/cisco/aci/apic/restapi/custom/api.pm b/network/cisco/aci/apic/restapi/custom/api.pm new file mode 100644 index 000000000..110be3c1e --- /dev/null +++ b/network/cisco/aci/apic/restapi/custom/api.pm @@ -0,0 +1,269 @@ +# +# Copyright 2019 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::aci::apic::restapi::custom::api; + +use strict; +use warnings; +use DateTime; +use centreon::plugins::http; +use centreon::plugins::statefile; +use JSON::XS; +use Digest::MD5 qw(md5_hex); + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + 'username:s' => { name => 'username' }, + 'password:s' => { name => 'password' }, + 'hostname:s' => { name => 'hostname' }, + 'timeout:s' => { name => 'timeout' }, + 'port:s' => { name => 'port'}, + 'proto:s' => { name => 'proto'} + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{http} = centreon::plugins::http->new(%options); + $self->{cache} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + $self->{username} = (defined($self->{option_results}->{username})) ? $self->{option_results}->{username} : undef; + $self->{password} = (defined($self->{option_results}->{password})) ? $self->{option_results}->{password} : undef; + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : undef; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443; + $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; + + if (!defined($self->{hostname}) || $self->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify --hostname option.'); + $self->{output}->option_exit(); + } + if (!defined($self->{username}) || $self->{username} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify --username option.'); + $self->{output}->option_exit(); + } + if (!defined($self->{password}) || $self->{password} eq '') { + $self->{output}->add_option_msg(short_msg => 'Need to specify --password option.'); + $self->{output}->option_exit(); + } + + $self->{cache}->check_options(option_results => $self->{option_results}); + return 0; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{warning_status} = ''; + $self->{option_results}->{critical_status} = ''; + $self->{option_results}->{unknown_status} = ''; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->add_header(key => 'Accept', value => 'application/json'); + $self->{http}->add_header(key => 'Content-Type', value => 'application/json'); + if (defined($self->{access_token})) { + $self->{http}->add_header(key => 'Cookie', value => 'APIC-Cookie=' . $self->{access_token}); + } + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub get_access_token { + my ($self, %options) = @_; + + my $has_cache_file = $options{statefile}->read(statefile => 'cisco_aci_apic_' . md5_hex($self->{hostname}) . '_' . md5_hex($self->{username})); + my $expires_on = $options{statefile}->get(name => 'expires_on'); + my $access_token = $options{statefile}->get(name => 'access_token'); + my $last_timestamp = $options{statefile}->get(name => 'last_timestamp'); + + if ($has_cache_file == 0 || !defined($access_token) || (($expires_on - time()) < 10)) { + my $login = { aaaUser => { attributes => { name => $self->{username}, pwd => $self->{password} } } }; + my $post_json = JSON::XS->new->utf8->encode($login); + + $self->settings(); + + my $content = $self->{http}->request( + method => 'POST', + query_form_post => $post_json, + url_path => '/api/aaaLogin.json' + ); + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->output_add(long_msg => $content, debug => 1); + $self->{output}->add_option_msg(short_msg => 'Cannot get token from API'); + $self->{output}->option_exit(); + } + if (defined($decoded->{imdata}->[0]->{error}->{attributes})) { + $self->{output}->add_option_msg(short_msg => "Error '" . uc($decoded->{imdata}->[0]->{error}->{attributes}->{code}) . " " + . $decoded->{imdata}->[0]->{error}->{attributes}->{text} . "'"); + $self->{output}->option_exit(); + } + + $access_token = $decoded->{imdata}->[0]->{aaaLogin}->{attributes}->{token}; + my $datas = { + last_timestamp => time(), + access_token => $decoded->{imdata}->[0]->{aaaLogin}->{attributes}->{token}, + expires_on => time() + $decoded->{imdata}->[0]->{aaaLogin}->{attributes}->{refreshTimeoutSeconds} + }; + $options{statefile}->write(data => $datas); + } + + return $access_token; +} + +sub request_api { + my ($self, %options) = @_; + + if (!defined($self->{access_token})) { + $self->{access_token} = $self->get_access_token(statefile => $self->{cache}); + } + + $self->settings(); + my $content = $self->{http}->request(%options); + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->output_add(long_msg => $content, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + if (defined($decoded->{imdata}->[0]->{error}->{attributes})) { + $self->{output}->add_option_msg(short_msg => "Error '" . uc($decoded->{imdata}->[0]->{error}->{attributes}->{code}) . " " . $decoded->{imdata}->[0]->{error}->{attributes}->{text} . "'"); + $self->{output}->option_exit(); + } + + return $decoded; +} + +sub get_fabric_health { + my ($self, %options) = @_; + + my $response = $self->request_api(method => 'GET', url_path => '/api/class/fabricHealthTotal.json'); + return $response; +} + +sub get_node_health_5m { + my ($self, %options) = @_; + + my $response = $self->request_api(method => 'GET', url_path => '/api/class/fabricNodeHealth5min.json'); + return $response; +} + +sub get_tenant_health { + my ($self, %options) = @_; + + my $response = $self->request_api(method => 'GET', url_path => '/api/class/fvTenant.json?rsp-subtree-include=health,required'); + return $response; +} + +1; + +__END__ + +=head1 NAME + +Cisco ACI APIC API Interface + +=head1 REST API OPTIONS + +Cisco ACI APIC Interface + +=over 8 + +=item B<--hostname> + +IP/FQDN of the Cisco ACI APIC + +=item B<--username> + +Username to connect to ACI APIC + +=item B<--hostname> + +Password to connect to ACI APIC + +=item B<--timeout> + +Set timeout in seconds (Default: 10). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/network/cisco/aci/apic/restapi/mode/fabric.pm b/network/cisco/aci/apic/restapi/mode/fabric.pm new file mode 100644 index 000000000..239d1a67b --- /dev/null +++ b/network/cisco/aci/apic/restapi/mode/fabric.pm @@ -0,0 +1,141 @@ +# +# Copyright 2019 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::aci::apic::restapi::mode::fabric; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold catalog_status_calc); + +sub custom_health_output { + my ($self, %options) = @_; + + my $msg = sprintf("health current: %d%%, previous: %d%%", $self->{result_values}->{current}, $self->{result_values}->{previous}); + return $msg; +} + +sub custom_health_perfdata { + my ($self, %options) = @_; + + foreach ('current', 'previous') { + $self->{output}->perfdata_add( + label => $_, + nlabel => 'fabric.health.' . $_ . '.percentage', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{dn} : undef, + value => $self->{result_values}->{$_}, + unit => '%', min => 0, max => 100 + ); + } +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'fabric', type => 1, cb_prefix_output => 'prefix_fabric_output', message_multiple => 'all fabrics are ok' }, + ]; + + $self->{maps_counters}->{fabric} = [ + { label => 'health', threshold => 0, set => { + key_values => [ { name => 'current' }, { name => 'previous' }, { name => 'dn' } ], + closure_custom_calc => \&catalog_status_calc, + closure_custom_output => $self->can('custom_health_output'), + closure_custom_threshold_check => \&catalog_status_threshold, + closure_custom_perfdata => $self->can('custom_health_perfdata'), + } + }, + ]; +} + +sub prefix_fabric_output { + my ($self, %options) = @_; + + return "Fabric '" . $options{instance_value}->{dn} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + 'warning-health:s' => { name => 'warning_health' }, + 'critical-health:s' => { name => 'critical_health' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_health', 'critical_health']); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{fabric} = {}; + + my $result_global = $options{custom}->get_fabric_health(); + foreach my $object (@{$result_global->{imdata}}) { + my $dn = $object->{fabricHealthTotal}->{attributes}->{dn}; + $self->{fabric}->{$dn} = { + current => $object->{fabricHealthTotal}->{attributes}->{cur}, + previous => $object->{fabricHealthTotal}->{attributes}->{prev}, + dn => $dn + }; + } + + if (scalar(keys %{$self->{fabric}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No fabric found (try --debug)"); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check fabrics. + +=over 8 + +=item B<--warning-health> + +Set warning for the health level +Can used special variables like: %{current}, %{previous}. +example: --warning-health='%{previous} < %{current}' + +=item B<--critical-health> + +Set critical for the health level +Can used special variables like: %{current}, %{previous}. +example: --critical-health='%{current} < 98' + +=back + +=cut diff --git a/network/cisco/aci/apic/restapi/mode/node.pm b/network/cisco/aci/apic/restapi/mode/node.pm new file mode 100644 index 000000000..3dcd4a643 --- /dev/null +++ b/network/cisco/aci/apic/restapi/mode/node.pm @@ -0,0 +1,145 @@ +# +# Copyright 2019 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::aci::apic::restapi::mode::node; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'nodes', type => 1, cb_prefix_output => 'prefix_nodes_output', message_multiple => 'All fabric nodes are ok' }, + ]; + + $self->{maps_counters}->{nodes} = [ + { label => 'health-current', nlabel => 'node.health.current.percentage', set => { + key_values => [ { name => 'current' }, { name => 'dn' } ], + output_template => 'current: %s %%', output_error_template => "current: %s %%", + perfdatas => [ + { label => 'health_current', value => 'current_absolute', template => '%d', + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'dn_absolute' }, + ], + } + }, + { label => 'health-minimum', nlabel => 'node.health.minimum.percentage', set => { + key_values => [ { name => 'min' }, { name => 'dn' } ], + output_template => 'min: %s %%', output_error_template => "min: %s %%", + perfdatas => [ + { label => 'health_min', value => 'min_absolute', template => '%d', + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'dn_absolute' }, + ], + } + }, + { label => 'health-average', nlabel => 'node.health.average.percentage', set => { + key_values => [ { name => 'avg' }, { name => 'dn' } ], + output_template => 'average: %s %%', output_error_template => "average %s %%", + perfdatas => [ + { label => 'health_avg', value => 'avg_absolute', template => '%d', + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'dn_absolute' }, + ], + } + }, + ]; +} + +sub prefix_nodes_output { + my ($self, %options) = @_; + + return "Node '" . $options{instance_value}->{dn} . "' health "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + 'filter-node:s' => { name => 'filter_node' }, + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{nodes} = {}; + + my $result_nodes = $options{custom}->get_node_health_5m(); + + foreach my $node (@{$result_nodes->{imdata}}) { + $node->{fabricNodeHealth5min}->{attributes}->{dn} =~ /^topology\/(.*)\/sys\/CDfabricNodeHealth5min$/; + my $node_dn = $1; + if (defined($self->{option_results}->{filter_node}) && $self->{option_results}->{filter_node} ne '' && + $node_dn =~ /$self->{option_results}->{filter_node}/) { + $self->{output}->output_add(long_msg => "skipping '" . $node_dn . "': no matching filter node '" . $node . "'", debug => 1); + next; + } + $self->{nodes}->{$node_dn} = { + min => $node->{fabricNodeHealth5min}->{attributes}->{healthMin}, + current => $node->{fabricNodeHealth5min}->{attributes}->{healthLast}, + avg => $node->{fabricNodeHealth5min}->{attributes}->{healthAvg}, + dn => $node_dn + }; + } + + if (scalar(keys %{$self->{nodes}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No nodes found (try --debug)"); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check fabric nodes. + +=over 8 + +=item B<--filter-node> + +Regexp filter on the pod / node name + +=item B<--warning-*> + +Set warning for each health percentage value. Can be : +--warning-health-average=90: +--warning-health-current +--warning-health-minimum + +=item B<--critical-*> + +Set criticai for each health percentage value. Can be : +--critical-health-average=90: +--critical-health-current=95: +--critical-health-minimum + +=back + +=cut diff --git a/network/cisco/aci/apic/restapi/mode/tenant.pm b/network/cisco/aci/apic/restapi/mode/tenant.pm new file mode 100644 index 000000000..34856e43d --- /dev/null +++ b/network/cisco/aci/apic/restapi/mode/tenant.pm @@ -0,0 +1,152 @@ +# +# Copyright 2019 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::aci::apic::restapi::mode::tenant; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold catalog_status_calc); + +sub custom_health_output { + my ($self, %options) = @_; + + my $msg = sprintf("health current: %d%%, previous: %d%%", $self->{result_values}->{current}, $self->{result_values}->{previous}); + return $msg; +} + +sub custom_health_perfdata { + my ($self, %options) = @_; + + foreach ('current', 'previous') { + $self->{output}->perfdata_add( + label => $_, + nlabel => 'tenant.health.' . $_ . '.percentage', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{dn} : undef, + value => $self->{result_values}->{$_}, + unit => '%', min => 0, max => 100 + ); + } +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'tenant', type => 1, cb_prefix_output => 'prefix_tenant_output', message_multiple => 'All tenants are ok' }, + ]; + + $self->{maps_counters}->{tenant} = [ + { label => 'health', threshold => 0, set => { + key_values => [ { name => 'current' }, { name => 'previous' }, { name => 'dn' } ], + closure_custom_calc => \&catalog_status_calc, + closure_custom_output => $self->can('custom_health_output'), + closure_custom_threshold_check => \&catalog_status_threshold, + closure_custom_perfdata => $self->can('custom_health_perfdata') + } + }, + ]; +} + +sub prefix_tenant_output { + my ($self, %options) = @_; + + return "Tenant '" . $options{instance_value}->{dn} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + 'filter-tenant:s' => { name => 'filter_tenant' }, + 'warning-health:s' => { name => 'warning_health' }, + 'critical-health:s' => { name => 'critical_health' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_health', 'critical_health']); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{tenant} = {}; + + my $result = $options{custom}->get_tenant_health(); + + foreach my $object (@{$result->{imdata}}) { + my $dn = $object->{fvTenant}->{attributes}->{name}; + if (defined($self->{option_results}->{filter_tenant}) && $self->{option_results}->{filter_tenant} ne '' && + $dn =~ /$self->{option_results}->{filter_tenant}/) { + $self->{output}->output_add(long_msg => "skipping '" . $dn . "': no matching filter ", debug => 1); + next; + } + $self->{tenant}->{$dn} = { + current => $object->{fvTenant}->{children}->[0]->{healthInst}->{attributes}->{cur}, + previous => $object->{fvTenant}->{children}->[0]->{healthInst}->{attributes}->{prev}, + dn => $dn + }; + } + + if (scalar(keys %{$self->{tenant}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No tenants found (try --debug)"); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check tenants. + +=over 8 + +=item B<--filter-tenant> + +Regexp filter on the tenant name + +=item B<--warning-health> + +Set warning for the health level +Can used special variables like: %{current}, %{previous}. +example: --warning-health='%{previous} < %{current}' + +=item B<--critical-health> + +Set critical for the health level +Can used special variables like: %{current}, %{previous}. +example: --critical-health='%{current} < 98' + +=back + +=cut diff --git a/network/cisco/aci/apic/restapi/plugin.pm b/network/cisco/aci/apic/restapi/plugin.pm new file mode 100644 index 000000000..40d543410 --- /dev/null +++ b/network/cisco/aci/apic/restapi/plugin.pm @@ -0,0 +1,51 @@ +# +# Copyright 2019 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::aci::apic::restapi::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + %{ $self->{modes} } = ( + 'node' => 'network::cisco::aci::apic::restapi::mode::node', + 'tenant' => 'network::cisco::aci::apic::restapi::mode::tenant', + 'fabric' => 'network::cisco::aci::apic::restapi::mode::fabric', + ); + + $self->{custom_modes}{api} = 'network::cisco::aci::apic::restapi::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Cisco ACI with APIC Rest API + +=cut diff --git a/network/cisco/esa/xmlapi/plugin.pm b/network/cisco/esa/xmlapi/plugin.pm new file mode 100644 index 000000000..85663cb99 --- /dev/null +++ b/network/cisco/esa/xmlapi/plugin.pm @@ -0,0 +1,48 @@ +# +# Copyright 2019 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::esa::xmlapi::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_simple); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'system-usage' => 'centreon::common::cisco::ironport::xmlapi::mode::systemusage', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Cisco ESA (Email Security Appliance) through xml status page. + +=cut diff --git a/network/cisco/ironport/snmp/plugin.pm b/network/cisco/ironport/snmp/plugin.pm index f7e63f5fa..2cc0ae8da 100644 --- a/network/cisco/ironport/snmp/plugin.pm +++ b/network/cisco/ironport/snmp/plugin.pm @@ -31,13 +31,14 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'cpu' => 'network::cisco::ironport::snmp::mode::cpu', - 'hardware' => 'network::cisco::ironport::snmp::mode::hardware', - 'keys-expire' => 'network::cisco::ironport::snmp::mode::keysexpire', - 'interfaces' => 'snmp_standard::mode::interfaces', - 'list-interfaces' => 'snmp_standard::mode::listinterfaces', - 'memory' => 'network::cisco::ironport::snmp::mode::memory', - ); + 'cpu' => 'centreon::common::cisco::ironport::snmp::mode::cpu', + 'hardware' => 'centreon::common::cisco::ironport::snmp::mode::hardware', + 'keys-expire' => 'centreon::common::cisco::ironport::snmp::mode::keysexpire', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'centreon::common::cisco::ironport::snmp::mode::memory', + 'proxy-usage' => 'centreon::common::cisco::ironport::snmp::mode::proxyusage', + ); return $self; } diff --git a/network/cisco/meraki/cloudcontroller/snmp/mode/deviceusage.pm b/network/cisco/meraki/cloudcontroller/snmp/mode/deviceusage.pm index f9382ea65..1123e38c9 100644 --- a/network/cisco/meraki/cloudcontroller/snmp/mode/deviceusage.pm +++ b/network/cisco/meraki/cloudcontroller/snmp/mode/deviceusage.pm @@ -29,7 +29,7 @@ use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold) sub custom_status_output { my ($self, %options) = @_; - my $msg = 'Status : ' . $self->{result_values}->{status}; + my $msg = 'status : ' . $self->{result_values}->{status}; return $msg; } @@ -45,25 +45,23 @@ sub custom_status_calc { 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 ($self->{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); + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); } elsif ($self->{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}); + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}); } - $self->{output}->perfdata_add(label => 'traffic_' . $self->{result_values}->{label} . $extra_label, unit => 'b/s', - value => sprintf("%.2f", $self->{result_values}->{traffic}), - warning => $warning, - critical => $critical, - min => 0, max => $self->{result_values}->{speed}); + $self->{output}->perfdata_add( + label => 'traffic_' . $self->{result_values}->{label}, unit => 'b/s', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{traffic}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed} + ); } sub custom_traffic_threshold { @@ -71,9 +69,9 @@ sub custom_traffic_threshold { my $exit = 'ok'; if ($self->{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' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } elsif ($self->{instance_mode}->{option_results}->{units_traffic} eq 'b/s') { - $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } return $exit; } @@ -112,7 +110,7 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'global', type => 0 }, + { name => 'global', type => 0, cb_init => 'skip_global' }, { name => 'device', type => 1, cb_prefix_output => 'prefix_device_output', message_multiple => 'All devices are ok' }, { name => 'interface', type => 1, cb_prefix_output => 'prefix_interface_output', message_multiple => 'All device interfaces are ok', skipped_code => { -10 => 1 } }, ]; @@ -175,16 +173,17 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "filter-interface:s" => { name => 'filter_interface' }, - "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /offline/' }, - "speed-in:s" => { name => 'speed_in' }, - "speed-out:s" => { name => 'speed_out' }, - "units-traffic:s" => { name => 'units_traffic', default => '%' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "filter-interface:s" => { name => 'filter_interface' }, + "filter-network:s" => { name => 'filter_network' }, + "filter-product:s" => { name => 'filter_product' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /offline/' }, + "speed-in:s" => { name => 'speed_in' }, + "speed-out:s" => { name => 'speed_out' }, + "units-traffic:s" => { name => 'units_traffic', default => '%' }, + }); return $self; } @@ -196,10 +195,17 @@ sub check_options { $self->change_macros(macros => ['warning_status', 'critical_status']); } +sub skip_global { + my ($self, %options) = @_; + + scalar(keys %{$self->{device}}) > 1 ? return(0) : return(1); +} + sub prefix_device_output { my ($self, %options) = @_; - return "Device '" . $options{instance_value}->{display} . "' "; + return "Device '" . $options{instance_value}->{display} . "' [network: " . $options{instance_value}->{network} . "]" . + " [product: " . $options{instance_value}->{product} . "] "; } sub prefix_interface_output { @@ -216,6 +222,8 @@ my $mapping = { devName => { oid => '.1.3.6.1.4.1.29671.1.1.4.1.2' }, devStatus => { oid => '.1.3.6.1.4.1.29671.1.1.4.1.3', map => \%map_status }, devClientCount => { oid => '.1.3.6.1.4.1.29671.1.1.4.1.5' }, + devProductCode => { oid => '.1.3.6.1.4.1.29671.1.1.4.1.9' }, + devNetworkName => { oid => '.1.3.6.1.4.1.29671.1.1.4.1.11' }, }; my $mapping2 = { devInterfaceName => { oid => '.1.3.6.1.4.1.29671.1.1.5.1.3' }, @@ -230,20 +238,35 @@ sub manage_selection { $self->{interface} = {}; $self->{global} = { total => 0 }; - my $snmp_result = $options{snmp}->get_multiple_table(oids => - [ { oid => $mapping->{devName}->{oid} }, - { oid => $mapping2->{devInterfaceName}->{oid} }, - ], nothing_quit => 1); + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{devName}->{oid} }, + { oid => $mapping2->{devInterfaceName}->{oid} }, + { oid => $mapping->{devProductCode}->{oid} }, + { oid => $mapping->{devNetworkName}->{oid} } + ], nothing_quit => 1); foreach my $oid (keys %{$snmp_result->{ $mapping->{devName}->{oid} }}) { $oid =~ /^$mapping->{devName}->{oid}\.(.*)$/; my $instance = $1; - my $dev_name = $snmp_result->{$mapping->{devName}->{oid}}->{$oid}; + my $dev_name = $snmp_result->{$mapping->{devName}->{oid}}->{$oid}; + my $network = defined($snmp_result->{$mapping->{devNetworkName}->{oid}}->{ $mapping->{devNetworkName}->{oid} . '.' . $instance }) + ? $snmp_result->{$mapping->{devNetworkName}->{oid}}->{ $mapping->{devNetworkName}->{oid} . '.' . $instance } : 'n/a'; + my $product = $snmp_result->{$mapping->{devProductCode}->{oid}}->{ $mapping->{devProductCode}->{oid} . '.' . $instance }; if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $dev_name !~ /$self->{option_results}->{filter_name}/) { $self->{output}->output_add(long_msg => "skipping device '" . $dev_name . "': no matching filter.", debug => 1); next; } + if (defined($self->{option_results}->{filter_product}) && $self->{option_results}->{filter_product} ne '' && + $product !~ /$self->{option_results}->{filter_product}/) { + $self->{output}->output_add(long_msg => "skipping device '" . $dev_name . "': no matching filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_network}) && $self->{option_results}->{filter_network} ne '' && + $network !~ /$self->{option_results}->{filter_network}/) { + $self->{output}->output_add(long_msg => "skipping device '" . $dev_name . "': no matching filter.", debug => 1); + next; + } foreach (keys %{$snmp_result->{ $mapping2->{devInterfaceName}->{oid} }}) { next if (!/^$mapping2->{devInterfaceName}->{oid}\.$instance\.(.*)/); @@ -260,7 +283,7 @@ sub manage_selection { } $self->{global}->{total}++; - $self->{device}->{$instance} = { display => $dev_name }; + $self->{device}->{$instance} = { display => $dev_name, network => $network, product => $product }; } if (scalar(keys %{$self->{interface}}) > 0) { @@ -290,7 +313,8 @@ sub manage_selection { $self->{cache_name} = "cisco_meraki_" . $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')) . '_' . (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_interface}) ? md5_hex($self->{option_results}->{filter_interface}) : md5_hex('all')); + (defined($self->{option_results}->{filter_interface}) ? md5_hex($self->{option_results}->{filter_interface}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_product}) ? md5_hex($self->{option_results}->{filter_product}) : md5_hex('all')); } 1; @@ -312,6 +336,14 @@ Example: --filter-counters='^clients$' Filter device name (can be a regexp). +=item B<--filter-product> + +Filter device product code (can be a regexp). + +=item B<--filter-network> + +Filter by network name (can be a regexp). + =item B<--filter-interface> Filter interface name (can be a regexp). diff --git a/network/cisco/meraki/cloudcontroller/snmp/mode/listdevices.pm b/network/cisco/meraki/cloudcontroller/snmp/mode/listdevices.pm new file mode 100644 index 000000000..54b21b4af --- /dev/null +++ b/network/cisco/meraki/cloudcontroller/snmp/mode/listdevices.pm @@ -0,0 +1,140 @@ +# +# Copyright 2019 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::meraki::cloudcontroller::snmp::mode::listdevices; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my %map_status = ( + 0 => 'offline', + 1 => 'online', +); +my $mapping = { + devName => { oid => '.1.3.6.1.4.1.29671.1.1.4.1.2' }, + devStatus => { oid => '.1.3.6.1.4.1.29671.1.1.4.1.3', map => \%map_status }, + devProductCode => { oid => '.1.3.6.1.4.1.29671.1.1.4.1.9' }, + devNetworkName => { oid => '.1.3.6.1.4.1.29671.1.1.4.1.11' }, +}; + +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' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{devName}->{oid} }, + { oid => $mapping->{devStatus}->{oid} }, + { oid => $mapping->{devProductCode}->{oid} }, + { oid => $mapping->{devNetworkName}->{oid} } + ], return_type => 1, nothing_quit => 1); + + $self->{devices} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{devName}->{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->{devName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping device '" . $result->{devName} . "': no matching filter.", debug => 1); + next; + } + + $self->{devices}->{$instance} = { + name => $result->{devName}, + status => $result->{devStatus}, + network => $result->{devNetworkName}, + product => $result->{devProductCode}, + }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{devices}}) { + $self->{output}->output_add(long_msg => "[name = '" . $self->{devices}->{$instance}->{name} . "']" . + " [status = '" . $self->{devices}->{$instance}->{status} . "']" . + " [network = '" . $self->{devices}->{$instance}->{network} . "']" . + " [product = '" . $self->{devices}->{$instance}->{product} . "']"); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List devices:'); + $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', 'status', 'network', 'product']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{devices}}) { + $self->{output}->add_disco_entry( + name => $self->{devices}->{$instance}->{name}, + status => $self->{devices}->{$instance}->{status}, + network => $self->{devices}->{$instance}->{network}, + product => $self->{devices}->{$instance}->{product}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List devices. + +=over 8 + +=item B<--filter-name> + +Filter by device name (can be a regexp). + +=back + +=cut diff --git a/network/cisco/meraki/cloudcontroller/snmp/plugin.pm b/network/cisco/meraki/cloudcontroller/snmp/plugin.pm index a19d8be42..d387f9615 100644 --- a/network/cisco/meraki/cloudcontroller/snmp/plugin.pm +++ b/network/cisco/meraki/cloudcontroller/snmp/plugin.pm @@ -31,8 +31,9 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'device-usage' => 'network::cisco::meraki::cloudcontroller::snmp::mode::deviceusage', - ); + 'device-usage' => 'network::cisco::meraki::cloudcontroller::snmp::mode::deviceusage', + 'list-devices' => 'network::cisco::meraki::cloudcontroller::snmp::mode::listdevices', + ); return $self; } diff --git a/network/cisco/prime/restapi/custom/api.pm b/network/cisco/prime/restapi/custom/api.pm index d36947b3e..774ab8787 100644 --- a/network/cisco/prime/restapi/custom/api.pm +++ b/network/cisco/prime/restapi/custom/api.pm @@ -40,24 +40,21 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s@" => { name => 'hostname' }, - "port:s@" => { name => 'port' }, - "proto:s@" => { name => 'proto' }, - "url-path:s@" => { name => 'url_path' }, - "username:s@" => { name => 'username' }, - "password:s@" => { name => 'password' }, - "proxyurl:s@" => { name => 'proxyurl' }, - "timeout:s@" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s@" => { name => 'hostname' }, + "port:s@" => { name => 'port' }, + "proto:s@" => { name => 'proto' }, + "url-path:s@" => { name => 'url_path' }, + "username:s@" => { name => 'username' }, + "password:s@" => { name => 'password' }, + "timeout:s@" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; @@ -102,7 +99,6 @@ sub check_options { $self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : ''; $self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{password}}) : ''; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef; if (!defined($self->{hostname})) { $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); @@ -123,7 +119,6 @@ sub build_options_for_httplib { $self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{port} = $self->{port}; $self->{option_results}->{proto} = $self->{proto}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; $self->{option_results}->{credentials} = 1; $self->{option_results}->{basic} = 1; $self->{option_results}->{username} = $self->{username}; @@ -227,24 +222,16 @@ Cisco Prime API Path (Default: '/webacs/api/v1/data/'). =item B<--username> -Storeonce username. +Cisco Prime username. =item B<--password> -Storeonce password. - -=item B<--proxyurl> - -Proxy URL if any +Cisco Prime password. =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/network/cisco/standard/snmp/plugin.pm b/network/cisco/standard/snmp/plugin.pm index 8b84e89ce..ed9f7f3fe 100644 --- a/network/cisco/standard/snmp/plugin.pm +++ b/network/cisco/standard/snmp/plugin.pm @@ -31,21 +31,21 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'configuration' => 'centreon::common::cisco::standard::snmp::mode::configuration', - 'cpu' => 'centreon::common::cisco::standard::snmp::mode::cpu', - 'environment' => 'centreon::common::cisco::standard::snmp::mode::environment', - 'hsrp' => 'centreon::common::cisco::standard::snmp::mode::hsrp', - 'interfaces' => 'snmp_standard::mode::interfaces', - 'ipsla' => 'centreon::common::cisco::standard::snmp::mode::ipsla', - 'list-interfaces' => 'snmp_standard::mode::listinterfaces', - 'list-spanning-trees' => 'snmp_standard::mode::listspanningtrees', - 'memory' => 'centreon::common::cisco::standard::snmp::mode::memory', - 'memory-flash' => 'centreon::common::cisco::standard::snmp::mode::memoryflash', - 'qos-usage' => 'centreon::common::cisco::standard::snmp::mode::qosusage', - 'spanning-tree' => 'snmp_standard::mode::spanningtree', - 'stack' => 'centreon::common::cisco::standard::snmp::mode::stack', - 'uptime' => 'snmp_standard::mode::uptime', - ); + 'configuration' => 'centreon::common::cisco::standard::snmp::mode::configuration', + 'cpu' => 'centreon::common::cisco::standard::snmp::mode::cpu', + 'environment' => 'centreon::common::cisco::standard::snmp::mode::environment', + 'hsrp' => 'centreon::common::cisco::standard::snmp::mode::hsrp', + 'interfaces' => 'centreon::common::cisco::standard::snmp::mode::interfaces', + 'ipsla' => 'centreon::common::cisco::standard::snmp::mode::ipsla', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-spanning-trees' => 'snmp_standard::mode::listspanningtrees', + 'memory' => 'centreon::common::cisco::standard::snmp::mode::memory', + 'memory-flash' => 'centreon::common::cisco::standard::snmp::mode::memoryflash', + 'qos-usage' => 'centreon::common::cisco::standard::snmp::mode::qosusage', + 'spanning-tree' => 'snmp_standard::mode::spanningtree', + 'stack' => 'centreon::common::cisco::standard::snmp::mode::stack', + 'uptime' => 'snmp_standard::mode::uptime', + ); return $self; } diff --git a/network/cisco/vcs/restapi/custom/xmlapi.pm b/network/cisco/vcs/restapi/custom/xmlapi.pm index d8cbeeb88..2605d38fa 100644 --- a/network/cisco/vcs/restapi/custom/xmlapi.pm +++ b/network/cisco/vcs/restapi/custom/xmlapi.pm @@ -40,24 +40,21 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "url-path:s" => { name => 'url_path' }, - "port:s" => { name => 'port' }, - "proto:s" => { name => 'proto' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "url-path:s" => { name => 'url_path' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'XMLAPI OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -94,8 +91,6 @@ sub check_options { $self->{password} = (defined($self->{option_results}->{password})) ? $self->{option_results}->{password} : undef; $self->{url_path} = (defined($self->{option_results}->{url_path})) ? $self->{option_results}->{url_path} : '/getxml?location='; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? $self->{option_results}->{proxyurl} : undef; - $self->{ssl_opt} = (defined($self->{option_results}->{ssl_opt})) ? $self->{option_results}->{ssl_opt} : undef; if (!defined($self->{option_results}->{hostname}) || $self->{option_results}->{hostname} eq '') { $self->{output}->add_option_msg(short_msg => "Need to specify --hostname option."); @@ -124,7 +119,6 @@ sub build_options_for_httplib { $self->{option_results}->{password} = $self->{password}; $self->{option_results}->{credentials} = 1; $self->{option_results}->{basic} = 1; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; $self->{option_results}->{warning_status} = ''; $self->{option_results}->{critical_status} = ''; } @@ -220,18 +214,10 @@ Set API username Set API password -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL options if needed (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/network/cisco/wlc/snmp/plugin.pm b/network/cisco/wlc/snmp/plugin.pm index e30ef14f5..c55c18a70 100644 --- a/network/cisco/wlc/snmp/plugin.pm +++ b/network/cisco/wlc/snmp/plugin.pm @@ -31,16 +31,16 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'ap-channel-interference' => 'centreon::common::airespace::snmp::mode::apchannelinterference', - 'ap-channel-noise' => 'centreon::common::airespace::snmp::mode::apchannelnoise', - 'ap-status' => 'centreon::common::airespace::snmp::mode::apstatus', - 'ap-users' => 'centreon::common::airespace::snmp::mode::apusers', - 'cpu' => 'centreon::common::airespace::snmp::mode::cpu', - 'hardware' => 'centreon::common::airespace::snmp::mode::hardware', - 'interfaces' => 'snmp_standard::mode::interfaces', - 'list-interfaces' => 'snmp_standard::mode::listinterfaces', - 'memory' => 'centreon::common::airespace::snmp::mode::memory', - ); + 'ap-channel-interference' => 'centreon::common::airespace::snmp::mode::apchannelinterference', + 'ap-channel-noise' => 'centreon::common::airespace::snmp::mode::apchannelnoise', + 'ap-status' => 'centreon::common::airespace::snmp::mode::apstatus', + 'ap-users' => 'centreon::common::airespace::snmp::mode::apusers', + 'cpu' => 'centreon::common::airespace::snmp::mode::cpu', + 'hardware' => 'centreon::common::airespace::snmp::mode::hardware', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'centreon::common::airespace::snmp::mode::memory', + ); return $self; } diff --git a/network/citrix/netscaler/snmp/mode/components/fanspeed.pm b/network/citrix/netscaler/snmp/mode/components/fanspeed.pm index 75fe10d5b..837def1a6 100644 --- a/network/citrix/netscaler/snmp/mode/components/fanspeed.pm +++ b/network/citrix/netscaler/snmp/mode/components/fanspeed.pm @@ -60,12 +60,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '%s' speed is %s rpm", $result->{sysHealthCounterName}, $result->{sysHealthCounterValue})); } - $self->{output}->perfdata_add(label => 'speed_' . $result->{sysHealthCounterName}, unit => 'rpm', - value => $result->{sysHealthCounterValue}, - warning => $warn, - critical => $crit, min => 0 - ); + $self->{output}->perfdata_add( + label => 'speed', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $result->{sysHealthCounterName}, + value => $result->{sysHealthCounterValue}, + warning => $warn, + critical => $crit, min => 0 + ); } } -1; \ No newline at end of file +1; diff --git a/network/citrix/netscaler/snmp/mode/components/temperature.pm b/network/citrix/netscaler/snmp/mode/components/temperature.pm index ca5e903d1..89379afb3 100644 --- a/network/citrix/netscaler/snmp/mode/components/temperature.pm +++ b/network/citrix/netscaler/snmp/mode/components/temperature.pm @@ -60,12 +60,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s C", $result->{sysHealthCounterName}, $result->{sysHealthCounterValue})); } - $self->{output}->perfdata_add(label => 'temp_' . $result->{sysHealthCounterName}, unit => 'C', - value => $result->{sysHealthCounterValue}, - warning => $warn, - critical => $crit, min => 0 - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $result->{sysHealthCounterName}, + value => $result->{sysHealthCounterValue}, + warning => $warn, + critical => $crit, min => 0 + ); } } -1; \ No newline at end of file +1; diff --git a/network/citrix/netscaler/snmp/mode/components/voltage.pm b/network/citrix/netscaler/snmp/mode/components/voltage.pm index 6e012252b..0d1b7e9c8 100644 --- a/network/citrix/netscaler/snmp/mode/components/voltage.pm +++ b/network/citrix/netscaler/snmp/mode/components/voltage.pm @@ -61,12 +61,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Voltage '%s' is %s V", $result->{sysHealthCounterName}, $result->{sysHealthCounterValue})); } - $self->{output}->perfdata_add(label => 'volt_' . $result->{sysHealthCounterName}, unit => 'V', - value => $result->{sysHealthCounterValue}, - warning => $warn, - critical => $crit, min => 0 - ); + $self->{output}->perfdata_add( + label => 'volt', unit => 'V', + nlabel => 'hardware.voltage.volt', + instances => $result->{sysHealthCounterName}, + value => $result->{sysHealthCounterValue}, + warning => $warn, + critical => $crit, min => 0 + ); } } -1; \ No newline at end of file +1; diff --git a/network/citrix/netscaler/snmp/mode/storage.pm b/network/citrix/netscaler/snmp/mode/storage.pm index b6922db36..69bbac621 100644 --- a/network/citrix/netscaler/snmp/mode/storage.pm +++ b/network/citrix/netscaler/snmp/mode/storage.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -51,23 +49,25 @@ sub custom_usage_perfdata { my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -75,12 +75,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -122,23 +122,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - my $mapping = { sysHealthDiskName => { oid => '.1.3.6.1.4.1.5951.4.1.1.41.8.1.1' }, sysHealthDiskSize => { oid => '.1.3.6.1.4.1.5951.4.1.1.41.8.1.2' }, # in MB diff --git a/network/citrix/netscaler/snmp/mode/vserverstatus.pm b/network/citrix/netscaler/snmp/mode/vserverstatus.pm index 732a217d9..ea69818ce 100644 --- a/network/citrix/netscaler/snmp/mode/vserverstatus.pm +++ b/network/citrix/netscaler/snmp/mode/vserverstatus.pm @@ -26,8 +26,6 @@ use strict; use warnings; use Digest::MD5 qw(md5_hex); -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -158,13 +156,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "filter-type:s" => { name => 'filter_type' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "filter-type:s" => { name => 'filter_type' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); + return $self; } diff --git a/network/citrix/sdx/snmp/mode/diskusage.pm b/network/citrix/sdx/snmp/mode/diskusage.pm index d60f14ee8..b616a03a8 100644 --- a/network/citrix/sdx/snmp/mode/diskusage.pm +++ b/network/citrix/sdx/snmp/mode/diskusage.pm @@ -26,30 +26,30 @@ use strict; use warnings; use Digest::MD5 qw(md5_hex); -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -57,12 +57,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -137,23 +137,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub prefix_disk_output { my ($self, %options) = @_; diff --git a/network/citrix/sdx/snmp/mode/srusage.pm b/network/citrix/sdx/snmp/mode/srusage.pm index 1298e7998..2fe3216b0 100644 --- a/network/citrix/sdx/snmp/mode/srusage.pm +++ b/network/citrix/sdx/snmp/mode/srusage.pm @@ -50,19 +50,21 @@ sub custom_usage_perfdata { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -75,7 +77,7 @@ sub custom_usage_threshold { $threshold_value = $self->{result_values}->{prct_used}; $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } diff --git a/network/citrix/sdx/snmp/mode/xenusage.pm b/network/citrix/sdx/snmp/mode/xenusage.pm index 386bf507c..4353993d6 100644 --- a/network/citrix/sdx/snmp/mode/xenusage.pm +++ b/network/citrix/sdx/snmp/mode/xenusage.pm @@ -25,30 +25,30 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'memory_used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'memory_free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -56,12 +56,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -125,23 +125,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub prefix_disk_output { my ($self, %options) = @_; diff --git a/network/dlink/standard/snmp/mode/components/fan.pm b/network/dlink/standard/snmp/mode/components/fan.pm index cfb421c59..273bc23a1 100644 --- a/network/dlink/standard/snmp/mode/components/fan.pm +++ b/network/dlink/standard/snmp/mode/components/fan.pm @@ -77,12 +77,16 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("fan '%s' speed is %s rpm", $instance, $result->{swFanSpeed})); } - $self->{output}->perfdata_add(label => "fan_" . $instance, unit => 'rpm', - value => $result->{swFanSpeed}, - warning => $warn, - critical => $crit, min => 0); + $self->{output}->perfdata_add( + label => "fan", unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $instance, + value => $result->{swFanSpeed}, + warning => $warn, + critical => $crit, min => 0 + ); } } } -1; \ No newline at end of file +1; diff --git a/network/dlink/standard/snmp/mode/components/temperature.pm b/network/dlink/standard/snmp/mode/components/temperature.pm index 4c292c36e..254037dcb 100644 --- a/network/dlink/standard/snmp/mode/components/temperature.pm +++ b/network/dlink/standard/snmp/mode/components/temperature.pm @@ -58,11 +58,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s degree centigrade", $instance, $result->{swTemperatureCurrent})); } - $self->{output}->perfdata_add(label => "temp_" . $instance, unit => 'C', - value => $result->{swTemperatureCurrent}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "temp", unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $instance, + value => $result->{swTemperatureCurrent}, + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/network/extreme/snmp/mode/components/fan.pm b/network/extreme/snmp/mode/components/fan.pm index 6b7885214..f19edd3ee 100644 --- a/network/extreme/snmp/mode/components/fan.pm +++ b/network/extreme/snmp/mode/components/fan.pm @@ -70,12 +70,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '%s' is '%s' rpm", $instance, $result->{extremeFanSpeed})); } - $self->{output}->perfdata_add(label => 'fan_' . $instance, unit => 'rpm', - value => $result->{extremeFanSpeed}, - warning => $warn, - critical => $crit, min => 0 - ); + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $instance, + value => $result->{extremeFanSpeed}, + warning => $warn, + critical => $crit, min => 0 + ); } } -1; \ No newline at end of file +1; diff --git a/network/extreme/snmp/mode/components/poe.pm b/network/extreme/snmp/mode/components/poe.pm index df74ff15f..79a878512 100644 --- a/network/extreme/snmp/mode/components/poe.pm +++ b/network/extreme/snmp/mode/components/poe.pm @@ -87,12 +87,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Poe '%s' is '%s' W", $instance, $result2->{extremePethSlotMeasuredPower})); } - $self->{output}->perfdata_add(label => 'poe_power_' . $instance, unit => 'W', - value => $result2->{extremePethSlotMeasuredPower}, - warning => $warn, - critical => $crit, min => 0 - ); + $self->{output}->perfdata_add( + label => 'poe_power', unit => 'W', + nlabel => 'hardware.poe.power.watt', + instances => $instance, + value => $result2->{extremePethSlotMeasuredPower}, + warning => $warn, + critical => $crit, min => 0 + ); } } -1; \ No newline at end of file +1; diff --git a/network/extreme/snmp/mode/components/psu.pm b/network/extreme/snmp/mode/components/psu.pm index a910143f6..6c2b4a31e 100644 --- a/network/extreme/snmp/mode/components/psu.pm +++ b/network/extreme/snmp/mode/components/psu.pm @@ -103,13 +103,16 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Power supply '%s' power is '%s' W", $instance, $power)); } - $self->{output}->perfdata_add(label => 'psu_power_' . $instance, unit => 'W', - value => $power, - warning => $warn, - critical => $crit, min => 0 - ); + $self->{output}->perfdata_add( + label => 'psu_power', unit => 'W', + nlabel => 'hardware.powersupply.power.watt', + instances => $instance, + value => $power, + warning => $warn, + critical => $crit, min => 0 + ); } } } -1; \ No newline at end of file +1; diff --git a/network/extreme/snmp/mode/components/temperature.pm b/network/extreme/snmp/mode/components/temperature.pm index 76536e722..8fd87f274 100644 --- a/network/extreme/snmp/mode/components/temperature.pm +++ b/network/extreme/snmp/mode/components/temperature.pm @@ -55,10 +55,13 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature is %s degree centigrade", $result->{extremeCurrentTemperature})); } - $self->{output}->perfdata_add(label => "temp", unit => 'C', - value => $result->{extremeCurrentTemperature}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "temp", unit => 'C', + nlabel => 'hardware.temperature.celsius', + value => $result->{extremeCurrentTemperature}, + warning => $warn, + critical => $crit + ); } -1; \ No newline at end of file +1; diff --git a/network/extreme/snmp/mode/memory.pm b/network/extreme/snmp/mode/memory.pm index 1e55c347d..a1d3de1fd 100644 --- a/network/extreme/snmp/mode/memory.pm +++ b/network/extreme/snmp/mode/memory.pm @@ -28,21 +28,20 @@ use warnings; sub custom_usage_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } diff --git a/network/extreme/snmp/mode/stack.pm b/network/extreme/snmp/mode/stack.pm index 3d8607a83..3adfcd543 100644 --- a/network/extreme/snmp/mode/stack.pm +++ b/network/extreme/snmp/mode/stack.pm @@ -108,7 +108,8 @@ sub run { ], nothing_quit => 1); my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $results->{$mapping->{extremeStackDetection}->{oid}}, instance => '0'); - if ($result->{extremeStackDetection} eq 'disabled') { + # disable is voluntary + if ($result->{extremeStackDetection} eq 'disable') { $self->{output}->output_add(severity => 'OK', short_msg => 'Stacking is disable'); $self->{output}->display(); @@ -183,4 +184,4 @@ Example: --threshold-overload='stack,WARNING,mismatch' =back =cut - \ No newline at end of file + diff --git a/network/f5/bigip/snmp/mode/components/fan.pm b/network/f5/bigip/snmp/mode/components/fan.pm index 311fc9aa8..7be8fdb0f 100644 --- a/network/f5/bigip/snmp/mode/components/fan.pm +++ b/network/f5/bigip/snmp/mode/components/fan.pm @@ -75,11 +75,15 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("fan speed '%s' is %s rpm", $instance, $result->{sysChassisFanSpeed})); } - $self->{output}->perfdata_add(label => "fan_" . $instance, unit => 'rpm', - value => $result->{sysChassisFanSpeed}, - warning => $warn, - critical => $crit, - min => 0); + $self->{output}->perfdata_add( + label => "fan", unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $instance, + value => $result->{sysChassisFanSpeed}, + warning => $warn, + critical => $crit, + min => 0 + ); } } } diff --git a/network/f5/bigip/snmp/mode/components/temperature.pm b/network/f5/bigip/snmp/mode/components/temperature.pm index 9073e01ad..cb6456fde 100644 --- a/network/f5/bigip/snmp/mode/components/temperature.pm +++ b/network/f5/bigip/snmp/mode/components/temperature.pm @@ -58,10 +58,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %.2f C", $instance, $result->{sysChassisTempTemperature})); } - $self->{output}->perfdata_add(label => "temp_" . $instance, unit => 'C', - value => sprintf("%.2f", $result->{sysChassisTempTemperature}), - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "temp", unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $instance, + value => sprintf("%.2f", $result->{sysChassisTempTemperature}), + warning => $warn, + critical => $crit + ); } } } diff --git a/network/f5/bigip/snmp/mode/connections.pm b/network/f5/bigip/snmp/mode/connections.pm index 3403f8f07..b7d28eff4 100644 --- a/network/f5/bigip/snmp/mode/connections.pm +++ b/network/f5/bigip/snmp/mode/connections.pm @@ -99,10 +99,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-counters:s" => { name => 'filter_counters' }, - }); + $options{options}->add_options(arguments => { + }); return $self; } @@ -166,4 +164,4 @@ Can be: 'client', 'server', 'client-ssl', 'server-ssl', 'client-ssl-tps'. =back -=cut \ No newline at end of file +=cut diff --git a/network/f5/bigip/snmp/mode/listvirtualservers.pm b/network/f5/bigip/snmp/mode/listvirtualservers.pm index 38643a845..5bac80b0c 100644 --- a/network/f5/bigip/snmp/mode/listvirtualservers.pm +++ b/network/f5/bigip/snmp/mode/listvirtualservers.pm @@ -25,21 +25,17 @@ use base qw(centreon::plugins::mode); use strict; use warnings; -my $oid_ltmVsStatusName = '.1.3.6.1.4.1.3375.2.2.10.13.2.1.1'; - 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 => - { - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - }); - $self->{vs_id_selected} = []; - + $options{options}->add_options(arguments => { + "name:s" => { name => 'name' }, + "regexp" => { name => 'use_regexp' }, + }); + return $self; } @@ -48,43 +44,77 @@ sub check_options { $self->SUPER::init(%options); } +my %map_vs_status = ( + 0 => 'none', + 1 => 'green', + 2 => 'yellow', + 3 => 'red', + 4 => 'blue', # unknown + 5 => 'gray', +); +my %map_vs_enabled = ( + 0 => 'none', + 1 => 'enabled', + 2 => 'disabled', + 3 => 'disabledbyparent', +); +my $mapping = { + new => { + AvailState => { oid => '.1.3.6.1.4.1.3375.2.2.10.13.2.1.2', map => \%map_vs_status }, + EnabledState => { oid => '.1.3.6.1.4.1.3375.2.2.10.13.2.1.3', map => \%map_vs_enabled }, + }, + old => { + AvailState => { oid => '.1.3.6.1.4.1.3375.2.2.10.1.2.1.22', map => \%map_vs_status }, + EnabledState => { oid => '.1.3.6.1.4.1.3375.2.2.10.1.2.1.23', map => \%map_vs_enabled }, + }, +}; +my $oid_ltmVsStatusEntry = '.1.3.6.1.4.1.3375.2.2.10.13.2.1'; # new +my $oid_ltmVirtualServEntry = '.1.3.6.1.4.1.3375.2.2.10.1.2.1'; # old + sub manage_selection { my ($self, %options) = @_; - $self->{result_names} = $self->{snmp}->get_table(oid => $oid_ltmVsStatusName, nothing_quit => 1); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{result_names}})) { - next if ($oid !~ /^$oid_ltmVsStatusName\.(.*)$/); + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_ltmVirtualServEntry, start => $mapping->{old}->{AvailState}->{oid}, end => $mapping->{old}->{EnabledState}->{oid} }, + { oid => $oid_ltmVsStatusEntry, start => $mapping->{new}->{AvailState}->{oid}, end => $mapping->{new}->{EnabledState}->{oid} }, + ], nothing_quit => 1); + + my ($branch, $map) = ($oid_ltmVsStatusEntry, 'new'); + if (!defined($snmp_result->{$oid_ltmVsStatusEntry}) || scalar(keys %{$snmp_result->{$oid_ltmVsStatusEntry}}) == 0) { + ($branch, $map) = ($oid_ltmVirtualServEntry, 'old'); + } + + $self->{vs} = {}; + foreach my $oid (keys %{$snmp_result->{$branch}}) { + next if ($oid !~ /^$mapping->{$map}->{AvailState}->{oid}\.(.*)$/); my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping->{$map}, results => $snmp_result->{$branch}, instance => $instance); - # Get all without a name - if (!defined($self->{option_results}->{name})) { - push @{$self->{vs_id_selected}}, $instance; - next; + $result->{Name} = ''; + foreach (split /\./, $instance) { + $result->{Name} .= chr if ($_ >= 32 && $_ <= 126); + } + $result->{Name} =~ s/^.//; + + if (defined($self->{option_results}->{name}) && $self->{option_results}->{name} ne '') { + next if (defined($self->{option_results}->{use_regexp}) && $result->{Name} !~ /$self->{option_results}->{name}/); + next if ($result->{Name} ne $self->{option_results}->{name}); } - $self->{result_names}->{$oid} = $self->{output}->to_utf8($self->{result_names}->{$oid}); - if (!defined($self->{option_results}->{use_regexp}) && $self->{result_names}->{$oid} eq $self->{option_results}->{name}) { - push @{$self->{vs_id_selected}}, $instance; - next; - } - if (defined($self->{option_results}->{use_regexp}) && $self->{result_names}->{$oid} =~ /$self->{option_results}->{name}/) { - push @{$self->{vs_id_selected}}, $instance; - next; - } - - $self->{output}->output_add(long_msg => "Skipping virtual server '" . $self->{result_names}->{$oid} . "': no matching filter name", debug => 1); + $self->{vs}->{$result->{Name}} = { %$result }; } } sub run { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->manage_selection(); - foreach my $instance (sort @{$self->{vs_id_selected}}) { - my $name = $self->{result_names}->{$oid_ltmVsStatusName . '.' . $instance}; - - $self->{output}->output_add(long_msg => "'" . $name . "'"); + $self->manage_selection(%options); + foreach (sort keys %{$self->{vs}}) { + $self->{output}->output_add(long_msg => + "[name = '" . $self->{vs}->{$_}->{Name} . "']" . + "[availstate = '" . $self->{vs}->{$_}->{AvailState} . "']" . + "[enabledtate = '" . $self->{vs}->{$_}->{EnabledState} . "']" + ); } $self->{output}->output_add(severity => 'OK', @@ -96,18 +126,19 @@ sub run { sub disco_format { my ($self, %options) = @_; - $self->{output}->add_disco_format(elements => ['name']); + $self->{output}->add_disco_format(elements => ['name', 'availstate', 'enabledtate']); } sub disco_show { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->manage_selection(disco => 1); - foreach my $instance (sort @{$self->{vs_id_selected}}) { - my $name = $self->{result_names}->{$oid_ltmVsStatusName . '.' . $instance}; - - $self->{output}->add_disco_entry(name => $name); + $self->manage_selection(%options); + foreach (sort keys %{$self->{vs}}) { + $self->{output}->add_disco_entry( + name => $self->{vs}->{$_}->{Name}, + availstate => $self->{vs}->{$_}->{AvailState}, + enabledtate => $self->{vs}->{$_}->{EnabledState}, + ); } } @@ -132,4 +163,4 @@ Allows to use regexp to filter virtual server name (with option --name). =back =cut - \ No newline at end of file + diff --git a/network/f5/bigip/snmp/mode/nodestatus.pm b/network/f5/bigip/snmp/mode/nodestatus.pm index 07fad2826..7179e9506 100644 --- a/network/f5/bigip/snmp/mode/nodestatus.pm +++ b/network/f5/bigip/snmp/mode/nodestatus.pm @@ -35,12 +35,11 @@ my $thresholds = { ['gray', 'UNKNOWN'], ], }; -my $instance_mode; sub custom_threshold_output { my ($self, %options) = @_; - return $instance_mode->get_severity(section => 'node', value => $self->{result_values}->{AvailState}); + return $self->{instance_mode}->get_severity(section => 'node', value => $self->{result_values}->{AvailState}); } sub custom_status_calc { @@ -90,11 +89,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); return $self; } @@ -102,9 +100,7 @@ sub new { sub check_options { my ($self, %options) = @_; $self->SUPER::check_options(%options); - - $instance_mode = $self; - + $self->{overload_th} = {}; foreach my $val (@{$self->{option_results}->{threshold_overload}}) { if ($val !~ /^(.*?),(.*?),(.*)$/) { diff --git a/network/f5/bigip/snmp/mode/poolstatus.pm b/network/f5/bigip/snmp/mode/poolstatus.pm index a14277b3a..a1a7548d6 100644 --- a/network/f5/bigip/snmp/mode/poolstatus.pm +++ b/network/f5/bigip/snmp/mode/poolstatus.pm @@ -35,12 +35,11 @@ my $thresholds = { ['gray', 'UNKNOWN'], ], }; -my $instance_mode; sub custom_threshold_output { my ($self, %options) = @_; - return $instance_mode->get_severity(section => 'pool', value => $self->{result_values}->{AvailState}); + return $self->{instance_mode}->get_severity(section => 'pool', value => $self->{result_values}->{AvailState}); } sub custom_status_calc { @@ -90,11 +89,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); return $self; } @@ -102,9 +100,7 @@ sub new { sub check_options { my ($self, %options) = @_; $self->SUPER::check_options(%options); - - $instance_mode = $self; - + $self->{overload_th} = {}; foreach my $val (@{$self->{option_results}->{threshold_overload}}) { if ($val !~ /^(.*?),(.*?),(.*)$/) { diff --git a/network/f5/bigip/snmp/mode/tmmusage.pm b/network/f5/bigip/snmp/mode/tmmusage.pm index e5985e488..93d02e3cd 100644 --- a/network/f5/bigip/snmp/mode/tmmusage.pm +++ b/network/f5/bigip/snmp/mode/tmmusage.pm @@ -29,21 +29,20 @@ use Digest::MD5 qw(md5_hex); sub custom_usage_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => 'memory_used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'memory_used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } diff --git a/network/f5/bigip/snmp/mode/trunks.pm b/network/f5/bigip/snmp/mode/trunks.pm index e0fd422d4..608644689 100644 --- a/network/f5/bigip/snmp/mode/trunks.pm +++ b/network/f5/bigip/snmp/mode/trunks.pm @@ -26,8 +26,6 @@ use strict; use warnings; use Digest::MD5 qw(md5_hex); -my $instance_mode; - my $thresholds = { trunk => [ ['up', 'OK'], @@ -42,7 +40,7 @@ my $thresholds = { sub custom_threshold_output { my ($self, %options) = @_; - return $instance_mode->get_severity(section => 'trunk', value => $self->{result_values}->{sysTrunkStatus}); + return $self->{instance_mode}->get_severity(section => 'trunk', value => $self->{result_values}->{sysTrunkStatus}); } sub custom_status_calc { @@ -54,38 +52,36 @@ sub custom_status_calc { 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}) && $self->{result_values}->{speed} > 0) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-traffic-' . $self->{result_values}->{label}, total => $self->{result_values}->{speed}, cast_int => 1); - $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-traffic-' . $self->{result_values}->{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-traffic-' . $self->{result_values}->{label}); - $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-traffic-' . $self->{result_values}->{label}); + if ($self->{instance_mode}->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed}) && $self->{result_values}->{speed} > 0) { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); + } elsif ($self->{instance_mode}->{option_results}->{units_traffic} eq 'b/s') { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}); } my $speed = $self->{result_values}->{speed} > 0 ? $self->{result_values}->{speed} : undef; - $self->{output}->perfdata_add(label => 'traffic_' . $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 => $speed); + $self->{output}->perfdata_add( + label => 'traffic_' . $self->{result_values}->{label}, unit => 'b/s', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{traffic_per_seconds}), + warning => $warning, + critical => $critical, + min => 0, max => $speed + ); } sub custom_traffic_threshold { my ($self, %options) = @_; my $exit = 'ok'; - if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed}) && $self->{result_values}->{speed} > 0) { - $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-traffic-' . $self->{result_values}->{label}, exit_litteral => 'critical' }, { label => 'warning-traffic-' . $self->{result_values}->{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-traffic-' . $self->{result_values}->{label}, exit_litteral => 'critical' }, { label => 'warning-traffic-' . $self->{result_values}->{label}, exit_litteral => 'warning' } ]); + if ($self->{instance_mode}->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed}) && $self->{result_values}->{speed} > 0) { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); + } elsif ($self->{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->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } return $exit; } @@ -110,7 +106,7 @@ sub custom_traffic_calc { my $diff_traffic = ($options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}} - $options{old_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}}); - $self->{result_values}->{speed} = defined($instance_mode->{option_results}->{speed}) && $instance_mode->{option_results}->{speed} ne '' ? $instance_mode->{option_results}->{speed} : $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{speed}}; + $self->{result_values}->{speed} = defined($self->{instance_mode}->{option_results}->{speed}) && $self->{instance_mode}->{option_results}->{speed} ne '' ? $self->{instance_mode}->{option_results}->{speed} : $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{speed}}; $self->{result_values}->{speed} = $self->{result_values}->{speed} * 1000 * 1000; # bits $self->{result_values}->{traffic_per_seconds} = $diff_traffic * 8 / $options{delta_time}; $self->{result_values}->{traffic_prct} = $self->{result_values}->{traffic_per_seconds} * 100 / $self->{result_values}->{speed} if ($self->{result_values}->{speed} > 0); @@ -122,26 +118,24 @@ sub custom_traffic_calc { sub custom_errors_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } + my $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}); + my $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}); - my $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-packets-error-' . $self->{result_values}->{label}); - my $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-packets-error-' . $self->{result_values}->{label}); - - $self->{output}->perfdata_add(label => 'packets_error_' . $self->{result_values}->{label} . $extra_label, unit => '%', - value => sprintf("%.2f", $self->{result_values}->{errors_prct}), - warning => $warning, - critical => $critical, - min => 0, max => 100); + $self->{output}->perfdata_add( + label => 'packets_error_' . $self->{result_values}->{label}, unit => '%', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{errors_prct}), + warning => $warning, + critical => $critical, + min => 0, max => 100 + ); } sub custom_errors_threshold { my ($self, %options) = @_; my $exit = 'ok'; - $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{errors_prct}, threshold => [ { label => 'critical-packets-error-' . $self->{result_values}->{label}, exit_litteral => 'critical' }, { label => 'warning-packets-error-' . $self->{result_values}->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{errors_prct}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -174,26 +168,24 @@ sub custom_errors_calc { sub custom_drops_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } + my $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}); + my $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}); - my $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-packets-drop-' . $self->{result_values}->{label}); - my $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-packets-drop-' . $self->{result_values}->{label}); - - $self->{output}->perfdata_add(label => 'packets_drop_' . $self->{result_values}->{label} . $extra_label, unit => '%', - value => sprintf("%.2f", $self->{result_values}->{drops_prct}), - warning => $warning, - critical => $critical, - min => 0, max => 100); + $self->{output}->perfdata_add( + label => 'packets_drop_' . $self->{result_values}->{label}, unit => '%', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{drops_prct}), + warning => $warning, + critical => $critical, + min => 0, max => 100 + ); } sub custom_drops_threshold { my ($self, %options) = @_; my $exit = 'ok'; - $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{drops_prct}, threshold => [ { label => 'critial-packets-drop-' . $self->{result_values}->{label}, exit_litteral => 'critical' }, { label => 'warning-packets-drop-' . $self->{result_values}->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{drops_prct}, threshold => [ { label => 'critial-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -309,22 +301,19 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "units-traffic:s" => { name => 'units_traffic', default => '%' }, - "speed:s" => { name => 'speed' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + "units-traffic:s" => { name => 'units_traffic', default => '%' }, + "speed:s" => { name => 'speed' }, + }); + return $self; } sub check_options { my ($self, %options) = @_; $self->SUPER::check_options(%options); - - $instance_mode = $self; $self->{overload_th} = {}; foreach my $val (@{$self->{option_results}->{threshold_overload}}) { diff --git a/network/f5/bigip/snmp/mode/virtualserverstatus.pm b/network/f5/bigip/snmp/mode/virtualserverstatus.pm index 8ddd4dc49..e25c7def7 100644 --- a/network/f5/bigip/snmp/mode/virtualserverstatus.pm +++ b/network/f5/bigip/snmp/mode/virtualserverstatus.pm @@ -35,12 +35,11 @@ my $thresholds = { ['gray', 'UNKNOWN'], ], }; -my $instance_mode; sub custom_threshold_output { my ($self, %options) = @_; - return $instance_mode->get_severity(section => 'vs', value => $self->{result_values}->{AvailState}); + return $self->{instance_mode}->get_severity(section => 'vs', value => $self->{result_values}->{AvailState}); } sub custom_status_calc { @@ -81,11 +80,10 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); return $self; } @@ -93,9 +91,7 @@ sub new { sub check_options { my ($self, %options) = @_; $self->SUPER::check_options(%options); - - $instance_mode = $self; - + $self->{overload_th} = {}; foreach my $val (@{$self->{option_results}->{threshold_overload}}) { if ($val !~ /^(.*?),(.*?),(.*)$/) { @@ -169,9 +165,9 @@ sub manage_selection { my ($self, %options) = @_; $self->{results} = $options{snmp}->get_multiple_table(oids => [ - { oid => $oid_ltmVirtualServEntry, start => $mapping->{old}->{AvailState}->{oid} }, - { oid => $oid_ltmVsStatusEntry, start => $mapping->{new}->{AvailState}->{oid} }, - ], nothing_quit => 1); + { oid => $oid_ltmVirtualServEntry, start => $mapping->{old}->{AvailState}->{oid}, end => $mapping->{old}->{StatusReason}->{oid} }, + { oid => $oid_ltmVsStatusEntry, start => $mapping->{new}->{AvailState}->{oid}, end => $mapping->{new}->{StatusReason}->{oid} }, + ], nothing_quit => 1); my ($branch, $map) = ($oid_ltmVsStatusEntry, 'new'); if (!defined($self->{results}->{$oid_ltmVsStatusEntry}) || scalar(keys %{$self->{results}->{$oid_ltmVsStatusEntry}}) == 0) { diff --git a/network/fortinet/fortigate/plugin.pm b/network/fortinet/fortigate/plugin.pm index ad9850d0c..1e149e5d6 100644 --- a/network/fortinet/fortigate/plugin.pm +++ b/network/fortinet/fortigate/plugin.pm @@ -31,25 +31,26 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'cluster-status' => 'centreon::common::fortinet::fortigate::mode::clusterstatus', - 'cpu' => 'centreon::common::fortinet::fortigate::mode::cpu', - 'disk' => 'centreon::common::fortinet::fortigate::mode::disk', - 'hardware' => 'centreon::common::fortinet::fortigate::mode::hardware', - 'interfaces' => 'snmp_standard::mode::interfaces', - 'ips-stats' => 'centreon::common::fortinet::fortigate::mode::ipsstats', - 'list-interfaces' => 'snmp_standard::mode::listinterfaces', - 'list-virtualdomains' => 'centreon::common::fortinet::fortigate::mode::listvirtualdomains', - 'memory' => 'centreon::common::fortinet::fortigate::mode::memory', - 'sessions' => 'centreon::common::fortinet::fortigate::mode::sessions', - 'signatures' => 'centreon::common::fortinet::fortigate::mode::signatures', - 'vdom-cpu' => 'centreon::common::fortinet::fortigate::mode::vdomcpu', - 'vdom-memory' => 'centreon::common::fortinet::fortigate::mode::vdommemory', - 'vdom-session' => 'centreon::common::fortinet::fortigate::mode::vdomsession', - 'vdom-state' => 'centreon::common::fortinet::fortigate::mode::vdomstate', - 'vdom-usage' => 'centreon::common::fortinet::fortigate::mode::vdomusage', - 'virus' => 'centreon::common::fortinet::fortigate::mode::virus', - 'vpn' => 'centreon::common::fortinet::fortigate::mode::vpn', - ); + 'ap-usage' => 'centreon::common::fortinet::fortigate::mode::apusage', + 'cluster-status' => 'centreon::common::fortinet::fortigate::mode::clusterstatus', + 'cpu' => 'centreon::common::fortinet::fortigate::mode::cpu', + 'disk' => 'centreon::common::fortinet::fortigate::mode::disk', + 'hardware' => 'centreon::common::fortinet::fortigate::mode::hardware', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'ips-stats' => 'centreon::common::fortinet::fortigate::mode::ipsstats', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-virtualdomains' => 'centreon::common::fortinet::fortigate::mode::listvirtualdomains', + 'memory' => 'centreon::common::fortinet::fortigate::mode::memory', + 'sessions' => 'centreon::common::fortinet::fortigate::mode::sessions', + 'signatures' => 'centreon::common::fortinet::fortigate::mode::signatures', + 'vdom-cpu' => 'centreon::common::fortinet::fortigate::mode::vdomcpu', + 'vdom-memory' => 'centreon::common::fortinet::fortigate::mode::vdommemory', + 'vdom-session' => 'centreon::common::fortinet::fortigate::mode::vdomsession', + 'vdom-state' => 'centreon::common::fortinet::fortigate::mode::vdomstate', + 'vdom-usage' => 'centreon::common::fortinet::fortigate::mode::vdomusage', + 'virus' => 'centreon::common::fortinet::fortigate::mode::virus', + 'vpn' => 'centreon::common::fortinet::fortigate::mode::vpn', + ); return $self; } diff --git a/network/freebox/restapi/custom/api.pm b/network/freebox/restapi/custom/api.pm index 7a20b5b8e..11f066f4a 100644 --- a/network/freebox/restapi/custom/api.pm +++ b/network/freebox/restapi/custom/api.pm @@ -41,23 +41,20 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s@" => { name => 'hostname' }, - "freebox-app-id:s@" => { name => 'freebox_app_id' }, - "freebox-app-token:s@" => { name => 'freebox_app_token' }, - "freebox-api-version:s@" => { name => 'freebox_api_version', }, - "proxyurl:s@" => { name => 'proxyurl' }, - "timeout:s@" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "resolution:s@" => { name => 'resolution' }, - }); + $options{options}->add_options(arguments => { + "hostname:s@" => { name => 'hostname' }, + "freebox-app-id:s@" => { name => 'freebox_app_id' }, + "freebox-app-token:s@" => { name => 'freebox_app_token' }, + "freebox-api-version:s@" => { name => 'freebox_api_version', }, + "timeout:s@" => { name => 'timeout' }, + "resolution:s@" => { name => 'resolution' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); $self->{session_token} = undef; @@ -95,7 +92,6 @@ sub check_options { $self->{freebox_app_token} = (defined($self->{option_results}->{freebox_app_token})) ? shift(@{$self->{option_results}->{freebox_app_token}}) : undef; $self->{freebox_api_version} = (defined($self->{option_results}->{freebox_api_version})) ? shift(@{$self->{option_results}->{freebox_api_version}}) : 'v4'; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef; $self->{resolution} = (defined($self->{option_results}->{resolution})) ? shift(@{$self->{option_results}->{resolution}}) : 300; if (!defined($self->{hostname})) { @@ -125,7 +121,6 @@ sub build_options_for_httplib { $self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{port} = 80; $self->{option_results}->{proto} = 'http'; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; } sub settings { @@ -143,8 +138,7 @@ sub settings { sub manage_response { my ($self, %options) = @_; - my $response = $self->{http}->get_response(); - if ($response->code() != 200) { + if ($self->{http}->get_code() != 200) { $self->{output}->add_option_msg(short_msg => "Connection issue: " . $options{content}); $self->{output}->option_exit(); } @@ -286,18 +280,10 @@ Freebox App Token. Freebox API version (Default: 'v4'). -=item B<--proxyurl> - -Proxy URL if any. - =item B<--timeout> Set HTTP timeout in seconds (Default: '10'). -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--resolution> Selected data performance resolution in seconds (Default: '300'). diff --git a/network/hirschmann/standard/snmp/mode/components/led.pm b/network/hirschmann/standard/snmp/mode/components/led.pm index a2d747a02..6c9500499 100644 --- a/network/hirschmann/standard/snmp/mode/components/led.pm +++ b/network/hirschmann/standard/snmp/mode/components/led.pm @@ -99,8 +99,8 @@ sub check { } else { return ; } - + check_led($self, mapping => $mapping); } -1; \ No newline at end of file +1; diff --git a/network/hirschmann/standard/snmp/mode/components/psu.pm b/network/hirschmann/standard/snmp/mode/components/psu.pm index b3d47f08f..edb2ffca7 100644 --- a/network/hirschmann/standard/snmp/mode/components/psu.pm +++ b/network/hirschmann/standard/snmp/mode/components/psu.pm @@ -29,30 +29,51 @@ my %map_psu_status = ( 3 => 'notInstalled', 4 => 'unknown', ); +my %map_psu_state = ( + 1 => 'error', 2 => 'ignore', +); +my %map_psid = ( + 1 => 9, # hmDevMonSensePS1State + 2 => 10, # hmDevMonSensePS2State + 3 => 14, # hmDevMonSensePS3State + 4 => 15, # hmDevMonSensePS4State + 5 => 17, # hmDevMonSensePS5State + 6 => 18, # hmDevMonSensePS6State + 7 => 19, # hmDevMonSensePS7State + 8 => 20, # hmDevMonSensePS8State +); # In MIB 'hmpriv.mib' my $mapping = { hmPSState => { oid => '.1.3.6.1.4.1.248.14.1.2.1.3', map => \%map_psu_status }, }; +my $oid_hmDevMonConfigEntry = '.1.3.6.1.4.1.248.14.2.12.3.1'; sub load { my ($self) = @_; - push @{$self->{request}}, { oid => $mapping->{hmPSState}->{oid} }; + push @{$self->{request}}, { oid => $mapping->{hmPSState}->{oid} }, { oid => $oid_hmDevMonConfigEntry }; } sub check { my ($self) = @_; $self->{output}->output_add(long_msg => "Checking power supplies"); - $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; + $self->{components}->{psu} = { name => 'psus', total => 0, skip => 0 }; return if ($self->check_filter(section => 'psu')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$mapping->{hmPSState}->{oid}}})) { - next if ($oid !~ /^$mapping->{hmPSState}->{oid}\.(.*)$/); - my $instance = $1; + next if ($oid !~ /^$mapping->{hmPSState}->{oid}\.(\d+)\.(\d+)$/); + my $instance = $1 . '.' . $2; + my ($sysid, $psid) = ($1, $2); my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{hmPSState}->{oid}}, instance => $instance); + if (defined($map_psid{$psid}) && + defined($self->{results}->{$oid_hmDevMonConfigEntry}->{$oid_hmDevMonConfigEntry . '.' . $map_psid{$psid} . '.' . $sysid})) { + my $state = $map_psu_state{$self->{results}->{$oid_hmDevMonConfigEntry}->{$oid_hmDevMonConfigEntry . '.' . $map_psid{$psid} . '.' . $sysid}}; + $result->{hmPSState} = 'ignore' if ($state eq 'ignore'); + } + next if ($self->check_filter(section => 'psu', instance => $instance)); next if ($result->{hmPSState} =~ /notInstalled/i && $self->absent_problem(section => 'psu', instance => $instance)); @@ -71,4 +92,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/network/hirschmann/standard/snmp/mode/components/temperature.pm b/network/hirschmann/standard/snmp/mode/components/temperature.pm index aaae1f30e..52447bedc 100644 --- a/network/hirschmann/standard/snmp/mode/components/temperature.pm +++ b/network/hirschmann/standard/snmp/mode/components/temperature.pm @@ -67,10 +67,13 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature is %s degree centigrade", $result->{hmTemperature})); } - $self->{output}->perfdata_add(label => "temp", unit => 'C', - value => $result->{hmTemperature}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "temp", unit => 'C', + nlabel => 'hardware.temperature.celsius', + value => $result->{hmTemperature}, + warning => $warn, + critical => $crit + ); } -1; \ No newline at end of file +1; diff --git a/network/hirschmann/standard/snmp/mode/cpu.pm b/network/hirschmann/standard/snmp/mode/cpu.pm index 743da4e37..d8f0c69fb 100644 --- a/network/hirschmann/standard/snmp/mode/cpu.pm +++ b/network/hirschmann/standard/snmp/mode/cpu.pm @@ -31,11 +31,11 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - }); + $options{options}->add_options(arguments => { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + return $self; } diff --git a/network/hirschmann/standard/snmp/mode/hardware.pm b/network/hirschmann/standard/snmp/mode/hardware.pm index 0d6a5e4db..95fc50828 100644 --- a/network/hirschmann/standard/snmp/mode/hardware.pm +++ b/network/hirschmann/standard/snmp/mode/hardware.pm @@ -43,9 +43,10 @@ sub set_system { ['failed', 'CRITICAL'], ['notInstalled', 'OK'], ['unknown', 'UNKNOWN'], + ['ignore', 'OK'], ], led => [ - ['off', 'UNKNOWN'], + ['off', 'OK'], ['green', 'OK'], ['yellow', 'WARNING'], ['red', 'CRITICAL'], @@ -69,9 +70,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } diff --git a/network/hirschmann/standard/snmp/mode/memory.pm b/network/hirschmann/standard/snmp/mode/memory.pm index 3f40a9a9d..75cfdf1d2 100644 --- a/network/hirschmann/standard/snmp/mode/memory.pm +++ b/network/hirschmann/standard/snmp/mode/memory.pm @@ -31,11 +31,11 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - }); + $options{options}->add_options(arguments => { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + return $self; } diff --git a/network/huawei/snmp/mode/memory.pm b/network/huawei/snmp/mode/memory.pm index 0815f9bfd..df2df7fd2 100644 --- a/network/huawei/snmp/mode/memory.pm +++ b/network/huawei/snmp/mode/memory.pm @@ -27,30 +27,32 @@ use warnings; sub custom_usage_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } + if ($self->{result_values}->{total} > 0) { - $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } else { - $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => '%', - value => $self->{result_values}->{prct_used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}), - min => 0, max => 100); + $self->{output}->perfdata_add( + label => 'used', unit => '%', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{prct_used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0, max => 100 + ); } } sub custom_usage_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } diff --git a/network/juniper/common/junos/mode/components/alarm.pm b/network/juniper/common/junos/mode/components/alarm.pm new file mode 100644 index 000000000..fd132ea44 --- /dev/null +++ b/network/juniper/common/junos/mode/components/alarm.pm @@ -0,0 +1,73 @@ +# +# Copyright 2019 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::juniper::common::junos::mode::components::alarm; + +use strict; +use warnings; + +my %map_alarm_states = ( + 1 => 'other', + 2 => 'off', + 3 => 'on', +); + +sub check_alarm { + my ($self, %options) = @_; + + return if ($self->check_filter(section => 'alarm', instance => $options{instance}, name => $options{name})); + $self->{components}->{alarm}->{total}++; + + $self->{output}->output_add(long_msg => + sprintf( + "alarm '%s' state is %s [instance: %s]", + $options{name}, $options{value}, $options{instance} + ) + ); + my $exit = $self->get_severity(section => 'alarm', value => $options{value}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf( + "Alarm '%s' state is %s", + $options{name}, $options{value} + ) + ); + } +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking alarms"); + $self->{components}->{alarm} = { name => 'alarm', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'alarm')); + + my $oid_jnxYellowAlarmState = '.1.3.6.1.4.1.2636.3.4.2.2.1.0'; + my $oid_jnxRedAlarmState = '.1.3.6.1.4.1.2636.3.4.2.3.1.0'; + my $results = $self->{snmp}->get_leef(oids => [$oid_jnxYellowAlarmState, $oid_jnxRedAlarmState]); + + check_alarm($self, instance => 0, name => 'yellow', value => $map_alarm_states{$results->{$oid_jnxYellowAlarmState}}) + if (defined($results->{$oid_jnxYellowAlarmState})); + check_alarm($self, instance => 0, name => 'red', value => $map_alarm_states{$results->{$oid_jnxRedAlarmState}}) + if (defined($results->{$oid_jnxRedAlarmState})); +} + +1; diff --git a/network/juniper/common/junos/mode/components/fru.pm b/network/juniper/common/junos/mode/components/fru.pm index 2f61edf65..9cbb99589 100644 --- a/network/juniper/common/junos/mode/components/fru.pm +++ b/network/juniper/common/junos/mode/components/fru.pm @@ -69,7 +69,7 @@ sub check { my ($self) = @_; $self->{output}->output_add(long_msg => "Checking frus"); - $self->{components}->{fru} = {name => 'frus', total => 0, skip => 0}; + $self->{components}->{fru} = { name => 'frus', total => 0, skip => 0 }; return if ($self->check_filter(section => 'fru')); my $mapping = { @@ -82,15 +82,15 @@ sub check { foreach my $instance (sort $self->get_instances(oid_entry => $self->{oids_fru}->{jnxFruEntry}, oid_name => $self->{oids_fru}->{jnxFruName})) { my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance); - - next if ($self->check_filter(section => 'fru', instance => $instance)); + my $name = $self->get_cache(oid_entry => $self->{oids_fru}->{jnxFruEntry}, oid_name => $self->{oids_fru}->{jnxFruName}, instance => $instance); + + next if ($self->check_filter(section => 'fru', instance => $instance, name => $name)); next if ($result->{jnxFruState} =~ /empty/i && - $self->absent_problem(section => 'fru', instance => $instance)); + $self->absent_problem(section => 'fru', instance => $instance, name => $name)); $self->{components}->{fru}->{total}++; - my $name = $self->get_cache(oid_entry => $self->{oids_fru}->{jnxFruEntry}, oid_name => $self->{oids_fru}->{jnxFruName}, instance => $instance); my $type = $self->get_cache(oid_entry => $self->{oids_fru}->{jnxFruEntry}, oid_name => $self->{oids_fru}->{jnxFruType}, instance => $instance); - $self->{output}->output_add(long_msg => sprintf("Fru '%s' state is %s [instance: %s, type: %s, offline reason: %s]", + $self->{output}->output_add(long_msg => sprintf("fru '%s' state is %s [instance: %s, type: %s, offline reason: %s]", $name, $result->{jnxFruState}, $instance, $map_fru_type{$type}, $result->{jnxFruOfflineReason})); my $exit = $self->get_severity(section => 'fru', value => $result->{jnxFruState}); @@ -101,17 +101,21 @@ sub check { } if (defined($result->{jnxFruTemp}) && $result->{jnxFruTemp} != 0) { - my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fru-temperature', instance => $instance, value => $result->{jnxFruTemp}); + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fru-temperature', instance => $instance, name => $name, value => $result->{jnxFruTemp}); if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Fru '%s' temperature is %s degree centigrade", $name, $result->{jnxFruTemp})); } - $self->{output}->perfdata_add(label => "temp_" . $name, unit => 'C', - value => $result->{jnxFruTemp}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "temp", unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $name, + value => $result->{jnxFruTemp}, + warning => $warn, + critical => $crit + ); } } } -1; \ No newline at end of file +1; diff --git a/network/juniper/common/junos/mode/components/operating.pm b/network/juniper/common/junos/mode/components/operating.pm index d09769b1d..137aa5c79 100644 --- a/network/juniper/common/junos/mode/components/operating.pm +++ b/network/juniper/common/junos/mode/components/operating.pm @@ -37,7 +37,7 @@ sub check { my ($self) = @_; $self->{output}->output_add(long_msg => "Checking operatings"); - $self->{components}->{operating} = {name => 'operatings', total => 0, skip => 0}; + $self->{components}->{operating} = { name => 'operatings', total => 0, skip => 0 }; return if ($self->check_filter(section => 'operating')); my $mapping = { @@ -48,12 +48,12 @@ sub check { foreach my $instance (sort $self->get_instances(oid_entry => $self->{oids_operating}->{jnxOperatingEntry}, oid_name => $self->{oids_operating}->{jnxOperatingDescr})) { my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance); - - next if ($self->check_filter(section => 'operating', instance => $instance)); + my $desc = $self->get_cache(oid_entry => $self->{oids_operating}->{jnxOperatingEntry}, oid_name => $self->{oids_operating}->{jnxOperatingDescr}, instance => $instance); + + next if ($self->check_filter(section => 'operating', instance => $instance, name => $desc)); $self->{components}->{operating}->{total}++; - my $desc = $self->get_cache(oid_entry => $self->{oids_operating}->{jnxOperatingEntry}, oid_name => $self->{oids_operating}->{jnxOperatingDescr}, instance => $instance); - $self->{output}->output_add(long_msg => sprintf("Operating '%s' state is %s [instance: %s]", + $self->{output}->output_add(long_msg => sprintf("operating '%s' state is %s [instance: %s]", $desc, $result->{jnxOperatingState}, $instance)); my $exit = $self->get_severity(section => 'operating', value => $result->{jnxOperatingState}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { @@ -64,4 +64,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/network/juniper/common/junos/mode/hardware.pm b/network/juniper/common/junos/mode/hardware.pm index 5dda1d92b..fcf965888 100644 --- a/network/juniper/common/junos/mode/hardware.pm +++ b/network/juniper/common/junos/mode/hardware.pm @@ -29,7 +29,7 @@ use centreon::plugins::statefile; sub set_system { my ($self, %options) = @_; - $self->{regexp_threshold_overload_check_section_option} = '^(fru|operating)$'; + $self->{regexp_threshold_overload_check_section_option} = '^(fru|operating|alarm)$'; $self->{regexp_threshold_numeric_check_section_option} = '^(fru-temperature)$'; $self->{cb_hook1} = 'init_cache'; @@ -58,10 +58,15 @@ sub set_system { ['down', 'CRITICAL'], ['standby', 'OK'], ], + alarm => [ + ['other', 'OK'], + ['off', 'OK'], + ['on', 'CRITICAL'], + ], }; $self->{components_path} = 'network::juniper::common::junos::mode::components'; - $self->{components_module} = ['fru', 'operating']; + $self->{components_module} = ['fru', 'operating', 'alarm']; } sub snmp_execute { @@ -78,10 +83,9 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "reload-cache-time:s" => { name => 'reload_cache_time', default => 180 }, - }); + $options{options}->add_options(arguments => { + 'reload-cache-time:s' => { name => 'reload_cache_time', default => 180 }, + }); $self->{statefile_cache} = centreon::plugins::statefile->new(%options); return $self; @@ -163,7 +167,7 @@ sub get_type { my $result = $options{snmp}->get_leef(oids => [$oid_jnxBoxDescr]); $self->{env_type} = defined($result->{$oid_jnxBoxDescr}) ? $result->{$oid_jnxBoxDescr} : 'unknown'; - $self->{output}->output_add(long_msg => sprintf("Environment type: %s", $self->{env_type})); + $self->{output}->output_add(long_msg => sprintf("environment type: %s", $self->{env_type})); } sub load_components { @@ -204,7 +208,11 @@ Check Hardware (JUNIPER-MIB) (frus, operating). =item B<--component> Which component to check (Default: '.*'). -Can be: 'fru', 'operating'. +Can be: 'fru', 'operating', 'alarm'. + +=item B<--add-name-instance> + +Add literal description for instance value (used in filter, absent-problem and threshold options). =item B<--filter> @@ -245,4 +253,4 @@ Use '-1' to disable cache reload. =back =cut - \ No newline at end of file + diff --git a/network/juniper/common/junos/mode/interfaces.pm b/network/juniper/common/junos/mode/interfaces.pm new file mode 100644 index 000000000..c1fe904e8 --- /dev/null +++ b/network/juniper/common/junos/mode/interfaces.pm @@ -0,0 +1,177 @@ +# +# Copyright 2019 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::juniper::common::junos::mode::interfaces; + +use base qw(snmp_standard::mode::interfaces); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + return $self; +} + +sub add_result_status { + my ($self, %options) = @_; + + $self->{int}->{$options{instance}}->{opstatus} = defined($self->{results}->{$self->{oid_opstatus} . '.' . $options{instance}}) ? $self->{oid_opstatus_mapping}->{$self->{results}->{$self->{oid_opstatus} . '.' . $options{instance}}} : 'unknown'; + $self->{int}->{$options{instance}}->{admstatus} = defined($self->{results}->{$self->{oid_adminstatus} . '.' . $options{instance}}) ? $self->{oid_adminstatus_mapping}->{$self->{results}->{$self->{oid_adminstatus} . '.' . $options{instance}}} : 'unknown'; +} + +1; + +__END__ + +=head1 MODE + +Check interfaces. + +=over 8 + +=item B<--add-global> + +Check global port statistics (By default if no --add-* option is set). + +=item B<--add-status> + +Check interface status. + +=item B<--add-traffic> + +Check interface traffic. + +=item B<--add-errors> + +Check interface errors. + +=item B<--add-cast> + +Check interface cast. + +=item B<--add-speed> + +Check interface speed. + +=item B<--add-volume> + +Check interface data volume between two checks (not supposed to be graphed, useful for BI reporting). + +=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: '%{admstatus} eq "up" and %{opstatus} ne "up"'). +Can used special variables like: %{admstatus}, %{opstatus}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down', +'in-traffic', 'out-traffic', 'in-error', 'in-discard', 'out-error', 'out-discard', +'in-ucast' (%), 'in-bcast' (%), 'in-mcast' (%), 'out-ucast' (%), 'out-bcast' (%), 'out-mcast' (%), +'speed' (b/s). + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down', +'in-traffic', 'out-traffic', 'in-error', 'in-discard', 'out-error', 'out-discard', +'in-ucast' (%), 'in-bcast' (%), 'in-mcast' (%), 'out-ucast' (%), 'out-bcast' (%), 'out-mcast' (%), +'speed' (b/s). + +=item B<--units-traffic> + +Units of thresholds for the traffic (Default: '%') ('%', 'b/s'). + +=item B<--units-errors> + +Units of thresholds for errors/discards (Default: '%') ('%', 'absolute'). + +=item B<--nagvis-perfdata> + +Display traffic perfdata to be compatible with nagvis widget. + +=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<--no-skipped-counters> + +Don't skip counters when no change. + +=item B<--force-counters32> + +Force to use 32 bits counters (even in snmp v2c and v3). Should be used when 64 bits counters are buggy. + +=item B<--reload-cache-time> + +Time in minutes before reloading cache file (default: 180). + +=item B<--oid-filter> + +Choose OID used to filter interface (default: ifName) (values: ifDesc, ifAlias, ifName). + +=item B<--oid-display> + +Choose OID used to display interface (default: ifName) (values: ifDesc, ifAlias, ifName). + +=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/juniper/common/screenos/snmp/mode/components/temperature.pm b/network/juniper/common/screenos/snmp/mode/components/temperature.pm index 244f88a80..9e78498a0 100644 --- a/network/juniper/common/screenos/snmp/mode/components/temperature.pm +++ b/network/juniper/common/screenos/snmp/mode/components/temperature.pm @@ -59,10 +59,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s C", $result->{nsTemperatureDesc}, $result->{nsTemperatureCur})); } - $self->{output}->perfdata_add(label => $result->{nsTemperatureDesc}, unit => 'C', - value => $result->{nsTemperatureCur}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $result->{nsTemperatureDesc}, + value => $result->{nsTemperatureCur}, + warning => $warn, + critical => $crit + ); } } diff --git a/network/juniper/ggsn/mode/apnstats.pm b/network/juniper/ggsn/mode/apnstats.pm index 4fdd5bf1d..fd681067b 100644 --- a/network/juniper/ggsn/mode/apnstats.pm +++ b/network/juniper/ggsn/mode/apnstats.pm @@ -20,168 +20,12 @@ package network::juniper::ggsn::mode::apnstats; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); -my $maps_counters = { - '000_traffic-in' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnApnUplinkBytes', diff => 1 }, { name => 'ggsnApnName' }, - ], - per_second => 1, output_change_bytes => 2, - output_template => 'Traffic In : %s %s/s', - perfdatas => [ - { label => 'traffic_in', value => 'ggsnApnUplinkBytes_per_second', template => '%s', - unit => 'b/s', min => 0, label_extra_instance => 1, cast_int => 1, instance_use => 'ggsnApnName_absolute' }, - ], - } - }, - '001_traffic-out' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnApnDownlinkBytes', diff => 1 }, { name => 'ggsnApnName' }, - ], - per_second => 1, output_change_bytes => 2, - output_template => 'Traffic Out : %s %s/s', - perfdatas => [ - { label => 'traffic_out', value => 'ggsnApnDownlinkBytes_per_second', template => '%s', - unit => 'b/s', min => 0, label_extra_instance => 1, cast_int => 1, instance_use => 'ggsnApnName_absolute' }, - ], - } - }, - '004_drop-in' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnApnUplinkDrops', diff => 1 }, { name => 'ggsnApnUplinkPackets', diff => 1 }, { name => 'ggsnApnName' }, - ], - output_template => 'Drop In Packets : %.2f %%', threshold_use => 'drop_prct', output_use => 'drop_prct', - closure_custom_calc => \&custom_drop_in_calc, - perfdatas => [ - { label => 'drop_in', value => 'ggsnApnUplinkDrops_absolute', template => '%s', - min => 0, max => 'ggsnApnUplinkPackets_absolute', label_extra_instance => 1, instance_use => 'ggsnApnName' }, - ], - } - }, - '005_drop-out' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnApnDownlinkDrops', diff => 1 }, { name => 'ggsnApnDownlinkPackets', diff => 1 }, { name => 'ggsnApnName' }, - ], - output_template => 'Drop Out Packets : %.2f %%', threshold_use => 'drop_prct', output_use => 'drop_prct', - closure_custom_calc => \&custom_drop_out_calc, - perfdatas => [ - { label => 'drop_out', value => 'ggsnApnDownlinkDrops_absolute', template => '%s', - min => 0, max => 'ggsnApnDownlinkPackets_absolute', label_extra_instance => 1, instance_use => 'ggsnApnName' }, - ], - } - }, - '006_active-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnApnActivePdpContextCount' }, { name => 'ggsnApnName' }, - ], - output_template => 'Active Pdp : %s', - perfdatas => [ - { label => 'active_pdp', value => 'ggsnApnActivePdpContextCount_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, - ], - } - }, - '007_attempted-activation-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnApnAttemptedActivation', diff => 1 }, { name => 'ggsnApnName' }, - ], - output_template => 'Attempted Activation Pdp : %s', - perfdatas => [ - { label => 'attempted_activation_pdp', value => 'ggsnApnAttemptedActivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, - ], - } - }, - '008_attempted-dyn-activation-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnApnAttemptedDynActivation', diff => 1 }, { name => 'ggsnApnName' }, - ], - output_template => 'Attempted Dyn Activation Pdp : %s', - perfdatas => [ - { label => 'attempted_dyn_activation_pdp', value => 'ggsnApnAttemptedDynActivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, - ], - } - }, - '009_attempted-deactivation-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnApnAttemptedDeactivation', diff => 1 }, { name => 'ggsnApnName' }, - ], - output_template => 'Attempted Deactivation Pdp : %s', - perfdatas => [ - { label => 'attempted_deactivation_pdp', value => 'ggsnApnAttemptedDeactivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, - ], - } - }, - '010_attempted-self-deactivation-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnApnAttemptedSelfDeactivation', diff => 1 }, { name => 'ggsnApnName' }, - ], - output_template => 'Attempted Self Deactivation Pdp : %s', - perfdatas => [ - { label => 'attempted_self_deactivation_pdp', value => 'ggsnApnAttemptedSelfDeactivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, - ], - } - }, - '011_completed-activation-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnApnCompletedActivation', diff => 1 }, { name => 'ggsnApnName' }, - ], - output_template => 'Completed Activation Pdp : %s', - perfdatas => [ - { label => 'completed_activation_pdp', value => 'ggsnApnCompletedActivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, - ], - } - }, - '012_completed-dyn-activation-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnApnCompletedDynActivation', diff => 1 }, { name => 'ggsnApnName' }, - ], - output_template => 'Completed Dyn Activation Pdp : %s', - perfdatas => [ - { label => 'completed_dyn_activation_pdp', value => 'ggsnApnCompletedDynActivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, - ], - } - }, - '013_completed-deactivation-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnApnCompletedDeactivation', diff => 1 }, { name => 'ggsnApnName' }, - ], - output_template => 'Completed Deactivation Pdp : %s', - perfdatas => [ - { label => 'completed_deactivation_pdp', value => 'ggsnApnCompletedDeactivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, - ], - } - }, - '014_completed-self-deactivation-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnApnCompletedSelfDeactivation', diff => 1 }, { name => 'ggsnApnName' }, - ], - output_template => 'Completed Self Deactivation Pdp : %s', - perfdatas => [ - { label => 'completed_self_deactivation_pdp', value => 'ggsnApnCompletedSelfDeactivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, - ], - } - }, -}; - sub custom_drop_in_calc { my ($self, %options) = @_; @@ -210,120 +54,146 @@ sub custom_drop_out_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'apn', type => 1, cb_prefix_output => 'prefix_apn_output', message_multiple => 'All apn statistics are ok' } + ]; + + $self->{maps_counters}->{apn} = [ + { label => 'traffic-in', set => { + key_values => [ { name => 'ggsnApnUplinkBytes', diff => 1 }, { name => 'ggsnApnName' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic In : %s %s/s', + perfdatas => [ + { label => 'traffic_in', value => 'ggsnApnUplinkBytes_per_second', template => '%s', + unit => 'b/s', min => 0, label_extra_instance => 1, cast_int => 1, instance_use => 'ggsnApnName_absolute' }, + ], + } + }, + { label => 'traffic-out', set => { + key_values => [ { name => 'ggsnApnDownlinkBytes', diff => 1 }, { name => 'ggsnApnName' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic Out : %s %s/s', + perfdatas => [ + { label => 'traffic_out', value => 'ggsnApnDownlinkBytes_per_second', template => '%s', + unit => 'b/s', min => 0, label_extra_instance => 1, cast_int => 1, instance_use => 'ggsnApnName_absolute' }, + ], + } + }, + { label => 'drop-in', set => { + key_values => [ { name => 'ggsnApnUplinkDrops', diff => 1 }, { name => 'ggsnApnUplinkPackets', diff => 1 }, { name => 'ggsnApnName' } ], + output_template => 'Drop In Packets : %.2f %%', threshold_use => 'drop_prct', output_use => 'drop_prct', + closure_custom_calc => $self->can('custom_drop_in_calc'), + perfdatas => [ + { label => 'drop_in', value => 'ggsnApnUplinkDrops_absolute', template => '%s', + min => 0, max => 'ggsnApnUplinkPackets_absolute', label_extra_instance => 1, instance_use => 'ggsnApnName' }, + ], + } + }, + { label => 'drop-out', set => { + key_values => [ { name => 'ggsnApnDownlinkDrops', diff => 1 }, { name => 'ggsnApnDownlinkPackets', diff => 1 }, { name => 'ggsnApnName' } ], + output_template => 'Drop Out Packets : %.2f %%', threshold_use => 'drop_prct', output_use => 'drop_prct', + closure_custom_calc => $self->can('custom_drop_out_calc'), + perfdatas => [ + { label => 'drop_out', value => 'ggsnApnDownlinkDrops_absolute', template => '%s', + min => 0, max => 'ggsnApnDownlinkPackets_absolute', label_extra_instance => 1, instance_use => 'ggsnApnName' }, + ], + } + }, + { label => 'active-pdp', set => { + key_values => [ { name => 'ggsnApnActivePdpContextCount' }, { name => 'ggsnApnName' } ], + output_template => 'Active Pdp : %s', + perfdatas => [ + { label => 'active_pdp', value => 'ggsnApnActivePdpContextCount_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, + ], + } + }, + { label => 'attempted-activation-pdp', set => { + key_values => [ { name => 'ggsnApnAttemptedActivation', diff => 1 }, { name => 'ggsnApnName' } ], + output_template => 'Attempted Activation Pdp : %s', + perfdatas => [ + { label => 'attempted_activation_pdp', value => 'ggsnApnAttemptedActivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, + ], + } + }, + { label => 'attempted-dyn-activation-pdp', set => { + key_values => [ { name => 'ggsnApnAttemptedDynActivation', diff => 1 }, { name => 'ggsnApnName' } ], + output_template => 'Attempted Dyn Activation Pdp : %s', + perfdatas => [ + { label => 'attempted_dyn_activation_pdp', value => 'ggsnApnAttemptedDynActivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, + ], + } + }, + { label => 'attempted-deactivation-pdp', set => { + key_values => [ { name => 'ggsnApnAttemptedDeactivation', diff => 1 }, { name => 'ggsnApnName' } ], + output_template => 'Attempted Deactivation Pdp : %s', + perfdatas => [ + { label => 'attempted_deactivation_pdp', value => 'ggsnApnAttemptedDeactivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, + ], + } + }, + { label => 'attempted-self-deactivation-pdp', set => { + key_values => [ { name => 'ggsnApnAttemptedSelfDeactivation', diff => 1 }, { name => 'ggsnApnName' } ], + output_template => 'Attempted Self Deactivation Pdp : %s', + perfdatas => [ + { label => 'attempted_self_deactivation_pdp', value => 'ggsnApnAttemptedSelfDeactivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, + ], + } + }, + { label => 'completed-activation-pdp', set => { + key_values => [ { name => 'ggsnApnCompletedActivation', diff => 1 }, { name => 'ggsnApnName' } ], + output_template => 'Completed Activation Pdp : %s', + perfdatas => [ + { label => 'completed_activation_pdp', value => 'ggsnApnCompletedActivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, + ], + } + }, + { label => 'completed-dyn-activation-pdp', set => { + key_values => [ { name => 'ggsnApnCompletedDynActivation', diff => 1 }, { name => 'ggsnApnName' } ], + output_template => 'Completed Dyn Activation Pdp : %s', + perfdatas => [ + { label => 'completed_dyn_activation_pdp', value => 'ggsnApnCompletedDynActivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, + ], + } + }, + { label => 'completed-deactivation-pdp', set => { + key_values => [ { name => 'ggsnApnCompletedDeactivation', diff => 1 }, { name => 'ggsnApnName' } ], + output_template => 'Completed Deactivation Pdp : %s', + perfdatas => [ + { label => 'completed_deactivation_pdp', value => 'ggsnApnCompletedDeactivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, + ], + } + }, + { label => 'completed-self-deactivation-pdp', set => { + key_values => [ { name => 'ggsnApnCompletedSelfDeactivation', diff => 1 }, { name => 'ggsnApnName' } ], + output_template => 'Completed Self Deactivation Pdp : %s', + perfdatas => [ + { label => 'completed_self_deactivation_pdp', value => 'ggsnApnCompletedSelfDeactivation_absolute', template => '%s', min => 0, label_extra_instance => 1, instance_use => 'ggsnApnName_absolute' }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); - foreach (keys %{$maps_counters}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$_}->{threshold}) || $maps_counters->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - return $self; } -sub check_options { +sub prefix_apn_output { my ($self, %options) = @_; - $self->SUPER::init(%options); - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - if ($self->{snmp}->is_snmpv1()) { - $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); - $self->{output}->option_exit(); - } - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{apn_selected}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All apn statistics are ok'); - } - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "juniper_ggsn_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('.*'))); - $self->{new_datas}->{last_timestamp} = time(); - - foreach my $id (sort keys %{$self->{apn_selected}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => $id); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{apn_selected}->{$id}, - new_datas => $self->{new_datas}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{$_}->{obj}->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "APN '" . $self->{apn_selected}->{$id}->{ggsnApnName} . "' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "APN '" . $self->{apn_selected}->{$id}->{ggsnApnName} . "' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "APN '" . $self->{apn_selected}->{$id}->{ggsnApnName} . "' $long_msg"); - } - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); + return "APN '" . $options{instance_value}->{ggsnApnName} . "' "; } my $mapping = { @@ -348,29 +218,40 @@ my $mapping = { sub manage_selection { my ($self, %options) = @_; - $self->{apn_selected} = {}; + if ($options{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); + $self->{output}->option_exit(); + } + + $self->{apn} = {}; my $oid_ggsnApnStatsEntry = '.1.3.6.1.4.1.10923.1.1.1.1.1.5.1'; - $self->{results} = $self->{snmp}->get_table(oid => $oid_ggsnApnStatsEntry, - nothing_quit => 1); - foreach my $oid (keys %{$self->{results}}) { + my $snmp_result = $options{snmp}->get_table( + oid => $oid_ggsnApnStatsEntry, + nothing_quit => 1 + ); + foreach my $oid (keys %$snmp_result) { next if ($oid !~ /^$mapping->{ggsnApnName}->{oid}\.(\d+)/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); + 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->{ggsnApnName} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $result->{ggsnApnName} . "': no matching filter."); + $self->{output}->output_add(long_msg => "skipping '" . $result->{ggsnApnName} . "': no matching filter."); next; } $result->{ggsnApnDownlinkBytes} *= 8 if (defined($result->{ggsnApnDownlinkBytes})); $result->{ggsnApnUplinkBytes} *= 8 if (defined($result->{ggsnApnUplinkBytes})); - $self->{apn_selected}->{$instance} = $result; + $self->{apn}->{$instance} = $result; } - if (scalar(keys %{$self->{apn_selected}}) <= 0) { + if (scalar(keys %{$self->{apn}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No entry found."); $self->{output}->option_exit(); } + + $self->{cache_name} = "juniper_ggsn_" . $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')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); } 1; diff --git a/network/juniper/ggsn/mode/globalstats.pm b/network/juniper/ggsn/mode/globalstats.pm index fddec4e93..ad29c46fd 100644 --- a/network/juniper/ggsn/mode/globalstats.pm +++ b/network/juniper/ggsn/mode/globalstats.pm @@ -20,166 +20,11 @@ package network::juniper::ggsn::mode::globalstats; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -use centreon::plugins::statefile; - -my $maps_counters = { - '000_traffic-in' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnUplinkBytes', diff => 1 }, - ], - per_second => 1, output_change_bytes => 2, - output_template => 'Traffic In : %s %s/s', - perfdatas => [ - { label => 'traffic_in', value => 'ggsnUplinkBytes_per_second', template => '%s', - unit => 'b/s', min => 0, cast_int => 1 }, - ], - } - }, - '001_traffic-out' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnDownlinkBytes', diff => 1 }, - ], - per_second => 1, output_change_bytes => 2, - output_template => 'Traffic Out : %s %s/s', - perfdatas => [ - { label => 'traffic_out', value => 'ggsnDownlinkBytes_per_second', template => '%s', - unit => 'b/s', min => 0, cast_int => 1 }, - ], - } - }, - '004_drop-in' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnUplinkDrops', diff => 1 }, { name => 'ggsnUplinkPackets', diff => 1 }, - ], - output_template => 'Drop In Packets : %.2f %%', threshold_use => 'drop_prct', output_use => 'drop_prct', - closure_custom_calc => \&custom_drop_in_calc, - perfdatas => [ - { label => 'drop_in', value => 'ggsnUplinkDrops_absolute', template => '%s', - min => 0, max => 'ggsnUplinkPackets_absolute' }, - ], - } - }, - '005_drop-out' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnDownlinkDrops', diff => 1 }, { name => 'ggsnDownlinkPackets', diff => 1 }, - ], - output_template => 'Drop Out Packets : %.2f %%', threshold_use => 'drop_prct', output_use => 'drop_prct', - closure_custom_calc => \&custom_drop_out_calc, - perfdatas => [ - { label => 'drop_out', value => 'ggsnDownlinkDrops_absolute', template => '%s', - min => 0, max => 'ggsnDownlinkPackets_absolute' }, - ], - } - }, - '006_active-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnNbrOfActivePdpContexts' }, - ], - output_template => 'Active Pdp : %s', - perfdatas => [ - { label => 'active_pdp', value => 'ggsnNbrOfActivePdpContexts_absolute', template => '%s', min => 0 }, - ], - } - }, - '007_attempted-activation-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnAttemptedActivation', diff => 1 }, - ], - output_template => 'Attempted Activation Pdp : %s', - perfdatas => [ - { label => 'attempted_activation_pdp', value => 'ggsnAttemptedActivation_absolute', template => '%s', min => 0 }, - ], - } - }, - '008_attempted-deactivation-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnAttemptedDeactivation', diff => 1 }, - ], - output_template => 'Attempted Deactivation Pdp : %s', - perfdatas => [ - { label => 'attempted_deactivation_pdp', value => 'ggsnAttemptedDeactivation_absolute', template => '%s', min => 0 }, - ], - } - }, - '009_attempted-self-deactivation-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnAttemptedSelfDeactivation', diff => 1 }, - ], - output_template => 'Attempted Self Deactivation Pdp : %s', - perfdatas => [ - { label => 'attempted_self_deactivation_pdp', value => 'ggsnAttemptedSelfDeactivation_absolute', template => '%s', min => 0 }, - ], - } - }, - '010_attempted-update-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnAttemptedUpdate', diff => 1 }, - ], - output_template => 'Attempted Update Pdp : %s', - perfdatas => [ - { label => 'attempted_update_pdp', value => 'ggsnAttemptedUpdate_absolute', template => '%s', min => 0 }, - ], - } - }, - '011_completed-activation-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnCompletedActivation', diff => 1 }, - ], - output_template => 'Completed Activation Pdp : %s', - perfdatas => [ - { label => 'completed_activation_pdp', value => 'ggsnCompletedActivation_absolute', template => '%s', min => 0 }, - ], - } - }, - '012_completed-deactivation-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnCompletedDeactivation', diff => 1 }, - ], - output_template => 'Completed Deactivation Pdp : %s', - perfdatas => [ - { label => 'completed_deactivation_pdp', value => 'ggsnCompletedDeactivation_absolute', template => '%s', min => 0 }, - ], - } - }, - '013_completed-self-deactivation-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnCompletedSelfDeactivation', diff => 1 }, - ], - output_template => 'Completed Self Deactivation Pdp : %s', - perfdatas => [ - { label => 'completed_self_deactivation_pdp', value => 'ggsnCompletedSelfDeactivation_absolute', template => '%s', min => 0 }, - ], - } - }, - '014_completed-update-pdp' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'ggsnCompletedUpdate', diff => 1 }, - ], - output_template => 'Completed Update Pdp : %s', - perfdatas => [ - { label => 'completed_update_pdp', value => 'ggsnCompletedUpdate_absolute', template => '%s', min => 0 }, - ], - } - }, -}; +use Digest::MD5 qw(md5_hex); sub custom_drop_in_calc { my ($self, %options) = @_; @@ -207,106 +52,155 @@ sub custom_drop_out_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'traffic-in', set => { + key_values => [ { name => 'ggsnUplinkBytes', diff => 1 } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic In : %s %s/s', + perfdatas => [ + { label => 'traffic_in', value => 'ggsnUplinkBytes_per_second', template => '%s', + unit => 'b/s', min => 0, cast_int => 1 }, + ], + } + }, + { label => 'traffic-out', set => { + key_values => [ { name => 'ggsnDownlinkBytes', diff => 1 } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic Out : %s %s/s', + perfdatas => [ + { label => 'traffic_out', value => 'ggsnDownlinkBytes_per_second', template => '%s', + unit => 'b/s', min => 0, cast_int => 1 }, + ], + } + }, + { label => 'drop-in', set => { + key_values => [ { name => 'ggsnUplinkDrops', diff => 1 }, { name => 'ggsnUplinkPackets', diff => 1 } ], + output_template => 'Drop In Packets : %.2f %%', threshold_use => 'drop_prct', output_use => 'drop_prct', + closure_custom_calc => \&custom_drop_in_calc, + perfdatas => [ + { label => 'drop_in', value => 'ggsnUplinkDrops_absolute', template => '%s', + min => 0, max => 'ggsnUplinkPackets_absolute' }, + ], + } + }, + { label => 'drop-out', set => { + key_values => [ { name => 'ggsnDownlinkDrops', diff => 1 }, { name => 'ggsnDownlinkPackets', diff => 1 } ], + output_template => 'Drop Out Packets : %.2f %%', threshold_use => 'drop_prct', output_use => 'drop_prct', + closure_custom_calc => \&custom_drop_out_calc, + perfdatas => [ + { label => 'drop_out', value => 'ggsnDownlinkDrops_absolute', template => '%s', + min => 0, max => 'ggsnDownlinkPackets_absolute' }, + ], + } + }, + { label => 'active-pdp', set => { + key_values => [ { name => 'ggsnNbrOfActivePdpContexts' } ], + output_template => 'Active Pdp : %s', + perfdatas => [ + { label => 'active_pdp', value => 'ggsnNbrOfActivePdpContexts_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'attempted-activation-pdp', set => { + key_values => [ { name => 'ggsnAttemptedActivation', diff => 1 } ], + output_template => 'Attempted Activation Pdp : %s', + perfdatas => [ + { label => 'attempted_activation_pdp', value => 'ggsnAttemptedActivation_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'attempted-deactivation-pdp', set => { + key_values => [ { name => 'ggsnAttemptedDeactivation', diff => 1 } ], + output_template => 'Attempted Deactivation Pdp : %s', + perfdatas => [ + { label => 'attempted_deactivation_pdp', value => 'ggsnAttemptedDeactivation_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'attempted-deactivation-pdp', set => { + key_values => [ { name => 'ggsnAttemptedDeactivation', diff => 1 } ], + output_template => 'Attempted Deactivation Pdp : %s', + perfdatas => [ + { label => 'attempted_deactivation_pdp', value => 'ggsnAttemptedDeactivation_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'attempted-self-deactivation-pdp', set => { + key_values => [ { name => 'ggsnAttemptedSelfDeactivation', diff => 1 } ], + output_template => 'Attempted Self Deactivation Pdp : %s', + perfdatas => [ + { label => 'attempted_self_deactivation_pdp', value => 'ggsnAttemptedSelfDeactivation_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'attempted-update-pdp', set => { + key_values => [ { name => 'ggsnAttemptedUpdate', diff => 1 } ], + output_template => 'Attempted Update Pdp : %s', + perfdatas => [ + { label => 'attempted_update_pdp', value => 'ggsnAttemptedUpdate_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'completed-activation-pdp', set => { + key_values => [ { name => 'ggsnCompletedActivation', diff => 1 } ], + output_template => 'Completed Activation Pdp : %s', + perfdatas => [ + { label => 'completed_activation_pdp', value => 'ggsnCompletedActivation_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'completed-deactivation-pdp', set => { + key_values => [ { name => 'ggsnCompletedDeactivation', diff => 1 } ], + output_template => 'Completed Deactivation Pdp : %s', + perfdatas => [ + { label => 'completed_deactivation_pdp', value => 'ggsnCompletedDeactivation_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'completed-self-deactivation-pdp', set => { + key_values => [ { name => 'ggsnCompletedSelfDeactivation', diff => 1 } ], + output_template => 'Completed Self Deactivation Pdp : %s', + perfdatas => [ + { label => 'completed_self_deactivation_pdp', value => 'ggsnCompletedSelfDeactivation_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'completed-update-pdp', set => { + key_values => [ { name => 'ggsnCompletedUpdate', diff => 1 } ], + output_template => 'Completed Update Pdp : %s', + perfdatas => [ + { label => 'completed_update_pdp', value => 'ggsnCompletedUpdate_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return 'Global Stats '; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); + $options{options}->add_options(arguments => { + }); - foreach (keys %{$maps_counters}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$_}->{threshold}) || $maps_counters->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - if ($self->{snmp}->is_snmpv1()) { - $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); - $self->{output}->option_exit(); - } - - $self->manage_selection(); - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "juniper_ggsn_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode}); - $self->{new_datas}->{last_timestamp} = time(); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => 'global'); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{global}, - new_datas => $self->{new_datas}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{$_}->{obj}->perfdata(); - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Global Stats $short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "Global Stats $long_msg"); - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - my $mapping = { ggsnNbrOfActivePdpContexts => { oid => '.1.3.6.1.4.1.10923.1.1.1.1.1.3.2' }, ggsnAttemptedActivation => { oid => '.1.3.6.1.4.1.10923.1.1.1.1.1.3.3.1' }, @@ -328,12 +222,22 @@ my $mapping = { sub manage_selection { my ($self, %options) = @_; + if ($options{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); + $self->{output}->option_exit(); + } + my $oid_ggsnGlobalStats = '.1.3.6.1.4.1.10923.1.1.1.1.1.3'; - $self->{results} = $self->{snmp}->get_table(oid => $oid_ggsnGlobalStats, - nothing_quit => 1); - $self->{global} = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => '0'); + my $snmp_result = $options{snmp}->get_table( + oid => $oid_ggsnGlobalStats, + nothing_quit => 1 + ); + $self->{global} = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => '0'); $self->{global}->{ggsnDownlinkBytes} *= 8 if (defined($self->{global}->{ggsnDownlinkBytes})); $self->{global}->{ggsnUplinkBytes} *= 8 if (defined($self->{global}->{ggsnUplinkBytes})); + + $self->{cache_name} = "juniper_ggsn_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; diff --git a/network/juniper/mseries/plugin.pm b/network/juniper/mseries/plugin.pm index a4c0954f0..da05f664b 100644 --- a/network/juniper/mseries/plugin.pm +++ b/network/juniper/mseries/plugin.pm @@ -31,17 +31,17 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'cpu-routing' => 'network::juniper::common::junos::mode::cpurouting', # routing engine - 'hardware' => 'network::juniper::common::junos::mode::hardware', - 'interfaces' => 'snmp_standard::mode::interfaces', - 'ldp-session-status' => 'network::juniper::common::junos::mode::ldpsessionstatus', - 'lsp-status' => 'network::juniper::common::junos::mode::lspstatus', - 'list-interfaces' => 'snmp_standard::mode::listinterfaces', - 'list-storages' => 'snmp_standard::mode::liststorages', - 'memory-routing' => 'network::juniper::common::junos::mode::memoryrouting', # routing engine - 'rsvp-session-status' => 'network::juniper::common::junos::mode::rsvpsessionstatus', - 'storage' => 'snmp_standard::mode::storage', - ); + 'cpu-routing' => 'network::juniper::common::junos::mode::cpurouting', # routing engine + 'hardware' => 'network::juniper::common::junos::mode::hardware', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'ldp-session-status' => 'network::juniper::common::junos::mode::ldpsessionstatus', + 'lsp-status' => 'network::juniper::common::junos::mode::lspstatus', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-storages' => 'snmp_standard::mode::liststorages', + 'memory-routing' => 'network::juniper::common::junos::mode::memoryrouting', # routing engine + 'rsvp-session-status' => 'network::juniper::common::junos::mode::rsvpsessionstatus', + 'storage' => 'snmp_standard::mode::storage', + ); return $self; } diff --git a/network/juniper/srx/plugin.pm b/network/juniper/srx/plugin.pm index 781f1ec60..985234adc 100644 --- a/network/juniper/srx/plugin.pm +++ b/network/juniper/srx/plugin.pm @@ -38,7 +38,7 @@ sub new { 'memory-forwarding' => 'network::juniper::common::junos::mode::memoryforwarding', # packet forwarding engine 'cp-sessions' => 'network::juniper::common::junos::mode::cpsessions', # CP = 'central point' 'flow-sessions' => 'network::juniper::common::junos::mode::flowsessions', - 'interfaces' => 'snmp_standard::mode::interfaces', + 'interfaces' => 'network::juniper::common::junos::mode::interfaces', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', 'list-storages' => 'snmp_standard::mode::liststorages', 'storage' => 'snmp_standard::mode::storage', diff --git a/network/mikrotik/snmp/mode/components/current.pm b/network/mikrotik/snmp/mode/components/current.pm index 6c74247e2..14d00b182 100644 --- a/network/mikrotik/snmp/mode/components/current.pm +++ b/network/mikrotik/snmp/mode/components/current.pm @@ -27,13 +27,7 @@ my $mapping = { mtxrHlCurrent => { oid => '.1.3.6.1.4.1.14988.1.1.3.13' }, }; -my $oid_mtxrHealth = '.1.3.6.1.4.1.14988.1.1.3'; - -sub load { - my ($self) = @_; - - push @{$self->{request}}, { oid => $oid_mtxrHealth }; -} +sub load {} sub check { my ($self) = @_; @@ -44,7 +38,7 @@ sub check { my $instance = 0; my ($exit, $warn, $crit, $checked); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_mtxrHealth}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); if (defined($result->{mtxrHlCurrent}) && $result->{mtxrHlCurrent} =~ /[0-9]+/) { @@ -55,10 +49,13 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Current is '%s' A", $result->{mtxrHlCurrent} / 100)); } - $self->{output}->perfdata_add(label => 'current', unit => 'A', - value => $result->{mtxrHlCurrent} / 100, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'current', unit => 'A', + nlabel => 'hardware.current.ampere', + value => $result->{mtxrHlCurrent} / 100, + warning => $warn, + critical => $crit + ); $self->{components}->{current}->{total}++; } } diff --git a/network/mikrotik/snmp/mode/components/fan.pm b/network/mikrotik/snmp/mode/components/fan.pm index ee730333a..726c5326b 100644 --- a/network/mikrotik/snmp/mode/components/fan.pm +++ b/network/mikrotik/snmp/mode/components/fan.pm @@ -28,13 +28,7 @@ my $mapping = { mtxrHlFanSpeed2 => { oid => '.1.3.6.1.4.1.14988.1.1.3.18' }, }; -my $oid_mtxrHealth = '.1.3.6.1.4.1.14988.1.1.3'; - -sub load { - my ($self) = @_; - - push @{$self->{request}}, { oid => $oid_mtxrHealth }; -} +sub load {} sub check { my ($self) = @_; @@ -45,7 +39,7 @@ sub check { my $instance = 0; my ($exit, $warn, $crit, $checked); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_mtxrHealth}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); if (defined($result->{mtxrHlFanSpeed1}) && $result->{mtxrHlFanSpeed1} =~ /[0-9]+/) { @@ -56,10 +50,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '1' speed is '%s' RPM", $result->{mtxrHlFanSpeed1})); } - $self->{output}->perfdata_add(label => 'fan_speed_1', unit => 'RPM', - value => $result->{mtxrHlFanSpeed1}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'fan_speed', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => '1', + value => $result->{mtxrHlFanSpeed1}, + warning => $warn, + critical => $crit + ); $self->{components}->{fan}->{total}++; } if (defined($result->{mtxrHlFanSpeed2}) && $result->{mtxrHlFanSpeed2} =~ /[0-9]+/) { @@ -71,10 +69,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '2' speed is '%s' RPM", $result->{mtxrHlFanSpeed2})); } - $self->{output}->perfdata_add(label => 'fan_speed_2', unit => 'RPM', - value => $result->{mtxrHlFanSpeed2}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'fan_speed', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => '2', + value => $result->{mtxrHlFanSpeed2}, + warning => $warn, + critical => $crit + ); $self->{components}->{fan}->{total}++; } } diff --git a/network/mikrotik/snmp/mode/components/power.pm b/network/mikrotik/snmp/mode/components/power.pm deleted file mode 100644 index 7610d23e2..000000000 --- a/network/mikrotik/snmp/mode/components/power.pm +++ /dev/null @@ -1,66 +0,0 @@ -# -# Copyright 2019 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::mikrotik::snmp::mode::components::power; - -use strict; -use warnings; - -my $mapping = { - mtxrHlPower => { oid => '.1.3.6.1.4.1.14988.1.1.3.12' }, -}; - -my $oid_mtxrHealth = '.1.3.6.1.4.1.14988.1.1.3'; - -sub load { - my ($self) = @_; - - push @{$self->{request}}, { oid => $oid_mtxrHealth }; -} - -sub check { - my ($self) = @_; - - $self->{output}->output_add(long_msg => "Checking power"); - $self->{components}->{power} = {name => 'power', total => 0, skip => 0}; - return if ($self->check_filter(section => 'power')); - - my $instance = 0; - my ($exit, $warn, $crit, $checked); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_mtxrHealth}, instance => $instance); - - if (defined($result->{mtxrHlPower}) && $result->{mtxrHlPower} =~ /[0-9]+/) { - - $self->{output}->output_add(long_msg => sprintf("Power is '%s' W", $result->{mtxrHlPower})); - - ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'power', instance => $instance, value => $result->{mtxrHlPower}); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Power is '%s' W", $result->{mtxrHlPower})); - } - $self->{output}->perfdata_add(label => 'power', unit => 'W', - value => $result->{mtxrHlPower}, - warning => $warn, - critical => $crit); - $self->{components}->{power}->{total}++; - } -} - -1; diff --git a/network/mikrotik/snmp/mode/components/psu.pm b/network/mikrotik/snmp/mode/components/psu.pm new file mode 100644 index 000000000..5579e4e53 --- /dev/null +++ b/network/mikrotik/snmp/mode/components/psu.pm @@ -0,0 +1,90 @@ +# +# Copyright 2019 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::mikrotik::snmp::mode::components::psu; + +use strict; +use warnings; + +my $map_status = { 0 => 'false', 1 => 'true' }; + +my $mapping = { + mtxrHlPower => { oid => '.1.3.6.1.4.1.14988.1.1.3.12' }, + mtxrHlPowerSupplyState => { oid => '.1.3.6.1.4.1.14988.1.1.3.15', map => $map_status }, + mtxrHlBackupPowerSupplyState => { oid => '.1.3.6.1.4.1.14988.1.1.3.16', map => $map_status }, +}; + +sub load {} + +sub check_psu { + my ($self, %options) = @_; + + return if (!defined($options{value})); + + $self->{output}->output_add( + long_msg => sprintf( + "psu %s status is '%s'", + $options{type}, $options{value}, + ) + ); + + my $exit = $self->get_severity(section => 'psu.' . $options{type}, value => $options{value}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("psu %s status is '%s'", $options{type}, $options{value})); + } + + $self->{components}->{psu}->{total}++; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + $self->{components}->{psu} = {name => 'psu', total => 0, skip => 0}; + return if ($self->check_filter(section => 'psu')); + + my $instance = '0'; + my ($exit, $warn, $crit, $checked); + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); + + check_psu($self, value => $result->{mtxrHlPowerSupplyState}, type => 'primary'); + check_psu($self, value => $result->{mtxrHlBackupPowerSupplyState}, type => 'backup'); + + if (defined($result->{mtxrHlPower}) && $result->{mtxrHlPower} =~ /[0-9]+/) { + $self->{output}->output_add(long_msg => sprintf("Power is '%s' W", $result->{mtxrHlPower} / 10)); + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'psu', instance => $instance, value => $result->{mtxrHlPower} / 10); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Power is '%s' W", $result->{mtxrHlPower} / 10)); + } + $self->{output}->perfdata_add( + label => 'power', unit => 'W', + nlabel => 'hardware.power.watt', + value => $result->{mtxrHlPower} / 10, + warning => $warn, + critical => $crit + ); + $self->{components}->{psu}->{total}++; + } +} + +1; diff --git a/network/mikrotik/snmp/mode/components/temperature.pm b/network/mikrotik/snmp/mode/components/temperature.pm index b294921ec..0ced1876d 100644 --- a/network/mikrotik/snmp/mode/components/temperature.pm +++ b/network/mikrotik/snmp/mode/components/temperature.pm @@ -28,13 +28,7 @@ my $mapping = { mtxrHlProcessorTemperature => { oid => '.1.3.6.1.4.1.14988.1.1.3.11' }, }; -my $oid_mtxrHealth = '.1.3.6.1.4.1.14988.1.1.3'; - -sub load { - my ($self) = @_; - - push @{$self->{request}}, { oid => $oid_mtxrHealth }; -} +sub load {} sub check { my ($self) = @_; @@ -45,7 +39,7 @@ sub check { my $instance = 0; my ($exit, $warn, $crit, $checked); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_mtxrHealth}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); if (defined($result->{mtxrHlTemperature}) && $result->{mtxrHlTemperature} =~ /[0-9]+/) { @@ -56,10 +50,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature is '%s' C", $result->{mtxrHlTemperature} / 10)); } - $self->{output}->perfdata_add(label => 'temperature', unit => 'C', - value => $result->{mtxrHlTemperature} / 10, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => 'system', + value => $result->{mtxrHlTemperature} / 10, + warning => $warn, + critical => $crit + ); $self->{components}->{temperature}->{total}++; } if (defined($result->{mtxrHlProcessorTemperature}) && $result->{mtxrHlProcessorTemperature} =~ /[0-9]+/) { @@ -71,10 +69,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Processor temperature is '%s' C", $result->{mtxrHlProcessorTemperature} / 10)); } - $self->{output}->perfdata_add(label => 'temperature_processor', unit => 'C', - value => $result->{mtxrHlProcessorTemperature} / 10, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => 'processor', + value => $result->{mtxrHlProcessorTemperature} / 10, + warning => $warn, + critical => $crit + ); $self->{components}->{temperature}->{total}++; } } diff --git a/network/mikrotik/snmp/mode/components/voltage.pm b/network/mikrotik/snmp/mode/components/voltage.pm index 85d428992..32cab293b 100644 --- a/network/mikrotik/snmp/mode/components/voltage.pm +++ b/network/mikrotik/snmp/mode/components/voltage.pm @@ -27,13 +27,7 @@ my $mapping = { mtxrHlVoltage => { oid => '.1.3.6.1.4.1.14988.1.1.3.8' }, }; -my $oid_mtxrHealth = '.1.3.6.1.4.1.14988.1.1.3'; - -sub load { - my ($self) = @_; - - push @{$self->{request}}, { oid => $oid_mtxrHealth }; -} +sub load {} sub check { my ($self) = @_; @@ -44,7 +38,7 @@ sub check { my $instance = 0; my ($exit, $warn, $crit, $checked); - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_mtxrHealth}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); if (defined($result->{mtxrHlVoltage}) && $result->{mtxrHlVoltage} =~ /[0-9]+/) { @@ -55,10 +49,13 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Voltage is '%s' V", $result->{mtxrHlVoltage} / 10)); } - $self->{output}->perfdata_add(label => 'voltage', unit => 'V', - value => $result->{mtxrHlVoltage} / 10, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'voltage', unit => 'V', + nlabel => 'hardware.voltage.volt', + value => $result->{mtxrHlVoltage} / 10, + warning => $warn, + critical => $crit + ); $self->{components}->{voltage}->{total}++; } } diff --git a/network/mikrotik/snmp/mode/environment.pm b/network/mikrotik/snmp/mode/environment.pm index 2ae23b49d..3012ab166 100644 --- a/network/mikrotik/snmp/mode/environment.pm +++ b/network/mikrotik/snmp/mode/environment.pm @@ -28,19 +28,30 @@ use warnings; sub set_system { my ($self, %options) = @_; - $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|voltage|fan|current|power)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|voltage|fan|current|psu)$'; $self->{cb_hook2} = 'snmp_execute'; + $self->{thresholds} = { + 'psu.primary' => [ + ['true', 'OK'], + ['false', 'CRITICAL'], + ], + 'psu.backup' => [ + ['true', 'OK'], + ['false', 'CRITICAL'], + ], + }; $self->{components_path} = 'network::mikrotik::snmp::mode::components'; - $self->{components_module} = ['current', 'fan', 'power', 'temperature', 'voltage']; + $self->{components_module} = ['current', 'fan', 'psu', 'temperature', 'voltage']; } sub snmp_execute { my ($self, %options) = @_; + my $oid_mtxrHealth = '.1.3.6.1.4.1.14988.1.1.3'; $self->{snmp} = $options{snmp}; - $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); + $self->{results} = $self->{snmp}->get_table(oid => $oid_mtxrHealth); } sub new { @@ -49,10 +60,9 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); - + $options{options}->add_options(arguments => { + }); + return $self; } @@ -69,7 +79,7 @@ Check hardware. =item B<--component> Which component to check (Default: '.*'). -Can be: 'voltage', 'temperature', 'fan'. +Can be: 'current', 'fan', 'psu', 'temperature', 'voltage'. =item B<--filter> @@ -86,7 +96,6 @@ Can be specific or global: --absent-problem=fan,1 Return an error if no compenents are checked. If total (with skipped) is 0. (Default: 'critical' returns). - =item B<--warning> Set warning threshold for 'temperature', 'fan', 'voltage' (syntax: type,regexp,threshold) diff --git a/network/mikrotik/snmp/mode/interfaces.pm b/network/mikrotik/snmp/mode/interfaces.pm new file mode 100644 index 000000000..128e2ac02 --- /dev/null +++ b/network/mikrotik/snmp/mode/interfaces.pm @@ -0,0 +1,294 @@ +# +# Copyright 2019 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::mikrotik::snmp::mode::interfaces; + +use base qw(snmp_standard::mode::interfaces); + +use strict; +use warnings; + +sub set_oids_errors { + my ($self, %options) = @_; + + $self->{oids_errors}->{oid_ifInDiscard} = '.1.3.6.1.2.1.2.2.1.13'; + $self->{oids_errors}->{oid_ifInError} = '.1.3.6.1.2.1.2.2.1.14'; + $self->{oids_errors}->{oid_ifOutDiscard} = '.1.3.6.1.2.1.2.2.1.19'; + $self->{oids_errors}->{oid_ifOutError} = '.1.3.6.1.2.1.2.2.1.20'; + $self->{oids_errors}->{oid_ifInTooShort} = '.1.3.6.1.4.1.14988.1.1.14.1.1.33'; + $self->{oids_errors}->{oid_ifInTooLong} = '.1.3.6.1.4.1.14988.1.1.14.1.1.41'; + $self->{oids_errors}->{oid_ifInFCSError} = '.1.3.6.1.4.1.14988.1.1.14.1.1.45'; + $self->{oids_errors}->{oid_ifInAlignError} = '.1.3.6.1.4.1.14988.1.1.14.1.1.46'; + $self->{oids_errors}->{oid_ifInFragment} = '.1.3.6.1.4.1.14988.1.1.14.1.1.47'; + $self->{oids_errors}->{oid_ifInOverflow} = '.1.3.6.1.4.1.14988.1.1.14.1.1.48'; + $self->{oids_errors}->{oid_ifInUnknownOp} = '.1.3.6.1.4.1.14988.1.1.14.1.1.50'; + $self->{oids_errors}->{oid_ifInLengthError} = '.1.3.6.1.4.1.14988.1.1.14.1.1.51'; + $self->{oids_errors}->{oid_ifInCodeError} = '.1.3.6.1.4.1.14988.1.1.14.1.1.52'; + $self->{oids_errors}->{oid_ifInCarrierError} = '.1.3.6.1.4.1.14988.1.1.14.1.1.53'; + $self->{oids_errors}->{oid_ifInJabber} = '.1.3.6.1.4.1.14988.1.1.14.1.1.54'; + $self->{oids_errors}->{oid_ifInDrop} = '.1.3.6.1.4.1.14988.1.1.14.1.1.55'; + $self->{oids_errors}->{oid_ifOutTooShort} = '.1.3.6.1.4.1.14988.1.1.14.1.1.63'; + $self->{oids_errors}->{oid_ifOutTooLong} = '.1.3.6.1.4.1.14988.1.1.14.1.1.71'; + $self->{oids_errors}->{oid_ifOutUnderrun} = '.1.3.6.1.4.1.14988.1.1.14.1.1.75'; + $self->{oids_errors}->{oid_ifOutCollision} = '.1.3.6.1.4.1.14988.1.1.14.1.1.76'; + $self->{oids_errors}->{oid_ifOutExcessiveCollision} = '.1.3.6.1.4.1.14988.1.1.14.1.1.77'; + $self->{oids_errors}->{oid_ifOutMultipleCollision} = '.1.3.6.1.4.1.14988.1.1.14.1.1.78'; + $self->{oids_errors}->{oid_ifOutSingleCollision} = '.1.3.6.1.4.1.14988.1.1.14.1.1.79'; + $self->{oids_errors}->{oid_ifOutExcessiveDeferred} = '.1.3.6.1.4.1.14988.1.1.14.1.1.80'; + $self->{oids_errors}->{oid_ifOutDeferred} = '.1.3.6.1.4.1.14988.1.1.14.1.1.81'; + $self->{oids_errors}->{oid_ifOutLateCollision} = '.1.3.6.1.4.1.14988.1.1.14.1.1.82'; + $self->{oids_errors}->{oid_ifOutTotalCollision} = '.1.3.6.1.4.1.14988.1.1.14.1.1.83'; + $self->{oids_errors}->{oid_ifOutDrop} = '.1.3.6.1.4.1.14988.1.1.14.1.1.85'; + $self->{oids_errors}->{oid_ifOutJabber} = '.1.3.6.1.4.1.14988.1.1.14.1.1.86'; + $self->{oids_errors}->{oid_ifOutFCSError} = '.1.3.6.1.4.1.14988.1.1.14.1.1.87'; + $self->{oids_errors}->{oid_ifOutFragment} = '.1.3.6.1.4.1.14988.1.1.14.1.1.89'; +} + +sub set_counters_errors { + my ($self, %options) = @_; + + $self->set_oids_errors(); + + foreach my $oid (keys %{$self->{oids_errors}}) { + $oid =~ /^oid_if(In|Out)(.*)$/; + push @{$self->{maps_counters}->{int}}, + { label => lc($1) . '-' . lc($2), filter => 'add_errors', nlabel => 'interface.packets.' . lc($1) . '.' . lc($2) . '.count', set => { + key_values => [ { name => lc($1.$2), diff => 1 }, { name => 'total_' . lc($1) . '_packets', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], + closure_custom_calc => $self->can('custom_errors_calc'), closure_custom_calc_extra_options => { label => $1 . ' ' . $2, label_ref1 => lc($1), label_ref2 => lc($2) }, + closure_custom_output => $self->can('custom_errors_output'), output_error_template => 'Packets ' . $1 . ' ' . $2 . ' : %s', + closure_custom_perfdata => $self->can('custom_errors_perfdata'), + closure_custom_threshold_check => $self->can('custom_errors_threshold'), + } + }, + ; + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'warning-errors:s' => { name => 'warning_errors' }, + 'critical-errors:s' => { name => 'critical_errors' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + + foreach ('warning', 'critical') { + next if (!defined($options{option_results}->{$_ . '_errors'}) || $options{option_results}->{$_ . '_errors'} eq ''); + foreach my $oid (keys %{$self->{oids_errors}}) { + $oid =~ /^oid_if(In|Out)(.*)$/; + if (!defined($options{option_results}->{$_ . '-instance-interface-packets-' . lc($1) . '-' . lc($2) . '-count'})) { + $options{option_results}->{$_ . '-instance-interface-packets-' . lc($1) . '-' . lc($2) . '-count'} = $options{option_results}->{$_ . '_errors'}; + } + if (!defined($options{option_results}->{$_ . '-' . lc($1) . '-' . lc($2)})) { + $options{option_results}->{$_ . '-' . lc($1) . '-' . lc($2)} = $options{option_results}->{$_ . '_errors'}; + } + } + } + + $self->SUPER::check_options(%options); +} + +sub load_errors { + my ($self, %options) = @_; + + $self->{snmp}->load( + oids => [ values %{$self->{oids_errors}} ], + instances => $self->{array_interface_selected} + ); +} + +sub add_result_errors { + my ($self, %options) = @_; + + foreach my $oid (keys %{$self->{oids_errors}}) { + $oid =~ /^oid_if(In|Out)(.*)$/; + $self->{int}->{$options{instance}}->{lc($1.$2)} = $self->{results}->{$self->{oids_errors}->{$oid} . '.' . $options{instance}}; + } +} + +1; + +__END__ + +=head1 MODE + +Check interfaces. + +=over 8 + +=item B<--add-global> + +Check global port statistics (By default if no --add-* option is set). + +=item B<--add-status> + +Check interface status. + +=item B<--add-duplex-status> + +Check duplex status (with --warning-status and --critical-status). + +=item B<--add-traffic> + +Check interface traffic. + +=item B<--add-errors> + +Check interface errors. + +=item B<--add-cast> + +Check interface cast. + +=item B<--add-speed> + +Check interface speed. + +=item B<--add-volume> + +Check interface data volume between two checks (not supposed to be graphed, useful for BI reporting). + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). +Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} + +=item B<--warning-errors> + +Set warning threshold for all error counters. + +=item B<--critical-errors> + +Set critical threshold for all error counters. + +=item B<--warning-*> + +Threshold warning (will superseed --warning-errors). +Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down', +'in-traffic', 'out-traffic', 'in-error', 'in-discard', 'out-error', 'out-discard', +'in-ucast' (%), 'in-bcast' (%), 'in-mcast' (%), 'out-ucast' (%), 'out-bcast' (%), 'out-mcast' (%), +'speed' (b/s). + +And also: 'in-tooshort' (%), 'in-toolong' (%), 'in-fcserror' (%), 'in-alignerror' (%), 'in-fragment' (%), +'in-overflow' (%), 'in-unknownop' (%), 'in-lengtherror' (%), 'in-codeerror' (%), 'in-carriererror' (%), +'in-jabber' (%), 'in-drop' (%), 'out-tooshort' (%), 'out-toolong' (%), 'out-underrun' (%), +'out-collision' (%), 'out-excessivecollision' (%), 'out-multiplecollision' (%), 'out-singlecollision' (%), +'out-excessivedeferred' (%),'out-deferred' (%), 'out-latecollision' (%), 'out-totalcollision' (%), +'out-drop' (%), 'out-jabber' (%), 'out-fcserror' (%), 'out-fragment' (%). + +=item B<--critical-*> + +Threshold critical (will superseed --warning-errors). +Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down', +'in-traffic', 'out-traffic', 'in-error', 'in-discard', 'out-error', 'out-discard', +'in-ucast' (%), 'in-bcast' (%), 'in-mcast' (%), 'out-ucast' (%), 'out-bcast' (%), 'out-mcast' (%), +'speed' (b/s). + +And also: 'in-tooshort' (%), 'in-toolong' (%), 'in-fcserror' (%), 'in-alignerror' (%), 'in-fragment' (%), +'in-overflow' (%), 'in-unknownop' (%), 'in-lengtherror' (%), 'in-codeerror' (%), 'in-carriererror' (%), +'in-jabber' (%), 'in-drop' (%), 'out-tooshort' (%), 'out-toolong' (%), 'out-underrun' (%), +'out-collision' (%), 'out-excessivecollision' (%), 'out-multiplecollision' (%), 'out-singlecollision' (%), +'out-excessivedeferred' (%),'out-deferred' (%), 'out-latecollision' (%), 'out-totalcollision' (%), +'out-drop' (%), 'out-jabber' (%), 'out-fcserror' (%), 'out-fragment' (%). + +=item B<--units-traffic> + +Units of thresholds for the traffic (Default: '%') ('%', 'b/s'). + +=item B<--units-errors> + +Units of thresholds for errors/discards (Default: '%') ('%', 'absolute'). + +=item B<--nagvis-perfdata> + +Display traffic perfdata to be compatible with nagvis widget. + +=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<--no-skipped-counters> + +Don't skip counters when no change. + +=item B<--force-counters32> + +Force to use 32 bits counters (even in snmp v2c and v3). Should be used when 64 bits counters are buggy. + +=item B<--reload-cache-time> + +Time in minutes before reloading cache file (default: 180). + +=item B<--oid-filter> + +Choose OID used to filter interface (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). + +=item B<--oid-display> + +Choose OID used to display interface (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). + +=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/mikrotik/snmp/plugin.pm b/network/mikrotik/snmp/plugin.pm index 02d811983..506043bcc 100644 --- a/network/mikrotik/snmp/plugin.pm +++ b/network/mikrotik/snmp/plugin.pm @@ -33,12 +33,14 @@ sub new { %{$self->{modes}} = ( 'cpu' => 'snmp_standard::mode::cpu', 'environment' => 'network::mikrotik::snmp::mode::environment', - 'interfaces' => 'snmp_standard::mode::interfaces', + 'interfaces' => 'network::mikrotik::snmp::mode::interfaces', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', 'list-frequencies' => 'network::mikrotik::snmp::mode::listfrequencies', 'list-ssids' => 'network::mikrotik::snmp::mode::listssids', 'memory' => 'network::mikrotik::snmp::mode::memory', 'signal' => 'network::mikrotik::snmp::mode::signal', + 'time' => 'snmp_standard::mode::ntp', + 'uptime' => 'snmp_standard::mode::uptime', ); return $self; diff --git a/network/mitel/3300icp/snmp/mode/zapbandwidth.pm b/network/mitel/3300icp/snmp/mode/zapbandwidth.pm index 306a7040d..1fe09d7fb 100644 --- a/network/mitel/3300icp/snmp/mode/zapbandwidth.pm +++ b/network/mitel/3300icp/snmp/mode/zapbandwidth.pm @@ -32,17 +32,23 @@ sub custom_usage_calc { $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_mitelBWMCurrentBandwidthInUse'} * 1000; $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_mitelBWMCurrentBandwidthLimit'} * 1000; $self->{result_values}->{used_prct} = $self->{result_values}->{used} / $self->{result_values}->{total} * 100; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; return 0; } sub custom_usage_perfdata { my ($self, %options) = @_; + + my $extra_label = ''; + $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - $self->{output}->perfdata_add(label => 'usage', unit => 'b/s', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'usage' . $extra_label, unit => 'b/s', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_output { @@ -56,12 +62,14 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'zap', type => 1, cb_prefix_output => 'prefix_zap_output', message_multiple => 'All zone access points are ok' }, + { name => 'zap', type => 1, cb_prefix_output => 'prefix_zap_output', + message_multiple => 'All zone access points are ok' }, ]; $self->{maps_counters}->{zap} = [ { label => 'usage', set => { - key_values => [ { name => 'mitelBWMCurrentBandwidthInUse' }, { name => 'mitelBWMCurrentBandwidthLimit' }, + key_values => [ { name => 'mitelBWMCurrentBandwidthInUse' }, + { name => 'mitelBWMCurrentBandwidthLimit' }, { name => 'display' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_output => $self->can('custom_usage_output'), @@ -84,10 +92,9 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); return $self; } @@ -99,8 +106,8 @@ sub check_options { my $oid_mitelBWMCurrentZAPLabel = '.1.3.6.1.4.1.1027.4.1.1.2.5.1.1.1.1.4', my $mapping = { - mitelBWMCurrentBandwidthInUse => { oid => '.1.3.6.1.4.1.1027.4.1.1.2.5.1.1.1.1.5' }, - mitelBWMCurrentBandwidthLimit => { oid => '.1.3.6.1.4.1.1027.4.1.1.2.5.1.1.1.1.6' }, + mitelBWMCurrentBandwidthInUse => { oid => '.1.3.6.1.4.1.1027.4.1.1.2.5.1.1.1.1.5' }, + mitelBWMCurrentBandwidthLimit => { oid => '.1.3.6.1.4.1.1027.4.1.1.2.5.1.1.1.1.6' }, }; sub manage_selection { @@ -127,8 +134,7 @@ sub manage_selection { $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); foreach (keys %{$self->{zap}}) { - my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); - + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); foreach my $name (keys %{$mapping}) { $self->{zap}->{$_}->{$name} = $result->{$name}; } diff --git a/network/mrv/optiswitch/snmp/mode/interfaces.pm b/network/mrv/optiswitch/snmp/mode/interfaces.pm index e9d230847..9ac129ecc 100644 --- a/network/mrv/optiswitch/snmp/mode/interfaces.pm +++ b/network/mrv/optiswitch/snmp/mode/interfaces.pm @@ -28,6 +28,9 @@ use warnings; sub custom_status_output { my ($self, %options) = @_; my $msg = 'Status : ' . $self->{result_values}->{linkstatus} . ' (oper: ' . $self->{result_values}->{opstatus} . ', ' . 'admin: ' . $self->{result_values}->{admstatus} . ')'; + if (defined($self->{instance_mode}->{option_results}->{add_duplex_status})) { + $msg .= ' (duplex: ' . $self->{result_values}->{duplexstatus} . ')'; + } return $msg; } @@ -38,252 +41,69 @@ sub custom_status_calc { $self->{result_values}->{linkstatus} = $options{new_datas}->{$self->{instance} . '_linkstatus'}; $self->{result_values}->{opstatus} = $options{new_datas}->{$self->{instance} . '_opstatus'}; $self->{result_values}->{admstatus} = $options{new_datas}->{$self->{instance} . '_admstatus'}; + $self->{result_values}->{duplexstatus} = $options{new_datas}->{$self->{instance} . '_duplexstatus'}; $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; return 0; } -sub set_counters { +sub set_counters_global { my ($self, %options) = @_; - - $self->{maps_counters} = { int => {}, global => {} } if (!defined($self->{maps_counters})); - - $self->{maps_counters}->{global}->{'000_total-port'} = { filter => 'add_global', - set => { - key_values => [ { name => 'total_port' } ], - output_template => 'Total port : %s', output_error_template => 'Total port : %s', - output_use => 'total_port_absolute', threshold_use => 'total_port_absolute', - perfdatas => [ - { label => 'total_port', value => 'total_port_absolute', template => '%s', - min => 0, max => 'total_port_absolute' }, - ], - } - }; - $self->{maps_counters}->{global}->{'001_total-admin-up'} = { filter => 'add_global', - set => { - key_values => [ { name => 'global_admin_up' }, { name => 'total_port' } ], - output_template => 'AdminStatus Up : %s', output_error_template => 'AdminStatus Up : %s', - output_use => 'global_admin_up_absolute', threshold_use => 'global_admin_up_absolute', - perfdatas => [ - { label => 'total_admin_up', value => 'global_admin_up_absolute', template => '%s', - min => 0, max => 'total_port_absolute' }, - ], - } - }; - $self->{maps_counters}->{global}->{'002_total-admin-down'} = { filter => 'add_global', - set => { - key_values => [ { name => 'global_admin_down' }, { name => 'total_port' } ], - output_template => 'AdminStatus Down : %s', output_error_template => 'AdminStatus Down : %s', - output_use => 'global_admin_down_absolute', threshold_use => 'global_admin_down_absolute', - perfdatas => [ - { label => 'total_admin_down', value => 'global_admin_down_absolute', template => '%s', - min => 0, max => 'total_port_absolute' }, - ], - } - }; - $self->{maps_counters}->{global}->{'003_total-oper-up'} = { filter => 'add_global', - set => { - key_values => [ { name => 'global_oper_up' }, { name => 'total_port' } ], - output_template => 'OperStatus Up : %s', output_error_template => 'OperStatus Up : %s', - output_use => 'global_oper_up_absolute', threshold_use => 'global_oper_up_absolute', - perfdatas => [ - { label => 'total_oper_up', value => 'global_oper_up_absolute', template => '%s', - min => 0, max => 'total_port_absolute' }, - ], - } - }; - $self->{maps_counters}->{global}->{'004_total-oper-down'} = { filter => 'add_global', - set => { - key_values => [ { name => 'global_oper_down' }, { name => 'total_port' } ], - output_template => 'OperStatus Down : %s', output_error_template => 'OperStatus Down : %s', - output_use => 'global_oper_down_absolute', threshold_use => 'global_oper_down_absolute', - perfdatas => [ - { label => 'global_oper_down', value => 'global_oper_down_absolute', template => '%s', - min => 0, max => 'total_port_absolute' }, - ], - } - }; - $self->{maps_counters}->{global}->{'005_total-link-up'} = { filter => 'add_global', - set => { - key_values => [ { name => 'global_link_up' }, { name => 'total_port' } ], - output_template => 'LinkStatus Up : %s', output_error_template => 'LinkStatus Up : %s', - output_use => 'global_link_up_absolute', threshold_use => 'global_link_up_absolute', - perfdatas => [ - { label => 'total_link_up', value => 'global_link_up_absolute', template => '%s', - min => 0, max => 'total_port_absolute' }, - ], - } - }; - $self->{maps_counters}->{global}->{'006_total-link-down'} = { filter => 'add_global', - set => { - key_values => [ { name => 'global_link_down' }, { name => 'total_port' } ], - output_template => 'LinkStatus Down : %s', output_error_template => 'LinkStatus Down : %s', - output_use => 'global_link_down_absolute', threshold_use => 'global_link_down_absolute', - perfdatas => [ - { label => 'total_link_down', value => 'global_link_down_absolute', template => '%s', - min => 0, max => 'total_port_absolute' }, - ], - } - }; - - $self->{maps_counters}->{int}->{'000_status'} = { filter => 'add_status', threshold => 0, - set => { - key_values => $self->set_key_values_status(), - 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_threshold_output'), - } - }; - if ($self->{no_traffic} == 0 && $self->{no_set_traffic} == 0) { - $self->{maps_counters}->{int}->{'020_in-traffic'} = { filter => 'add_traffic', - set => { - key_values => $self->set_key_values_in_traffic(), - per_second => 1, - closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'in' }, - closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic In : %s', - closure_custom_perfdata => $self->can('custom_traffic_perfdata'), - closure_custom_threshold_check => $self->can('custom_traffic_threshold'), - } - }; - $self->{maps_counters}->{int}->{'021_out-traffic'} = { filter => 'add_traffic', - set => { - key_values => $self->set_key_values_out_traffic(), - per_second => 1, - closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'out' }, - closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic Out : %s', - closure_custom_perfdata => $self->can('custom_traffic_perfdata'), - closure_custom_threshold_check => $self->can('custom_traffic_threshold'), - } - }; - } - if ($self->{no_cast} == 0 && $self->{no_set_cast} == 0) { - $self->{maps_counters}->{int}->{'060_in-ucast'} = { filter => 'add_cast', - set => { - key_values => [ { name => 'iucast', diff => 1 }, { name => 'imcast', diff => 1 }, { name => 'ibcast', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], - closure_custom_calc => $self->can('custom_cast_calc'), closure_custom_calc_extra_options => { label_ref => 'iucast', total_ref1 => 'ibcast', total_ref2 => 'imcast' }, - output_template => 'In Ucast : %.2f %%', output_error_template => 'In Ucast : %s', - output_use => 'iucast_prct', threshold_use => 'iucast_prct', + + $self->SUPER::set_counters_global(%options); + + push @{$self->{maps_counters}->{global}}, + { label => 'total-link-up', filter => 'add_global', nlabel => 'total.interfaces.link.up.count', set => { + key_values => [ { name => 'global_link_up' }, { name => 'total_port' } ], + output_template => 'LinkStatus Up : %s', output_error_template => 'LinkStatus Up : %s', + output_use => 'global_link_up_absolute', threshold_use => 'global_link_up_absolute', perfdatas => [ - { value => 'iucast_prct', template => '%.2f', - unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }, + { label => 'total_link_up', value => 'global_link_up_absolute', template => '%s', + min => 0, max => 'total_port_absolute' }, ], } - }; - $self->{maps_counters}->{int}->{'061_in-bcast'} = { filter => 'add_cast', - set => { - key_values => [ { name => 'iucast', diff => 1 }, { name => 'imcast', diff => 1 }, { name => 'ibcast', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], - closure_custom_calc => $self->can('custom_cast_calc'), closure_custom_calc_extra_options => { label_ref => 'ibcast', total_ref1 => 'iucast', total_ref2 => 'imcast' }, - output_template => 'In Bcast : %.2f %%', output_error_template => 'In Bcast : %s', - output_use => 'ibcast_prct', threshold_use => 'ibcast_prct', + }, + { label => 'total-link-down', filter => 'add_global', nlabel => 'total.interfaces.link.down.count', set => { + key_values => [ { name => 'global_link_down' }, { name => 'total_port' } ], + output_template => 'LinkStatus Down : %s', output_error_template => 'LinkStatus Down : %s', + output_use => 'global_link_down_absolute', threshold_use => 'global_link_down_absolute', perfdatas => [ - { value => 'ibcast_prct', template => '%.2f', - unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }, - ], + { label => 'total_link_down', value => 'global_link_down_absolute', template => '%s', + min => 0, max => 'total_port_absolute' }, + ], } - }; - $self->{maps_counters}->{int}->{'062_in-mcast'} = { filter => 'add_cast', - set => { - key_values => [ { name => 'iucast', diff => 1 }, { name => 'imcast', diff => 1 }, { name => 'ibcast', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], - closure_custom_calc => $self->can('custom_cast_calc'), closure_custom_calc_extra_options => { label_ref => 'imcast', total_ref1 => 'iucast', total_ref2 => 'ibcast' }, - output_template => 'In Mcast : %.2f %%', output_error_template => 'In Mcast : %s', - output_use => 'imcast_prct', threshold_use => 'imcast_prct', - perfdatas => [ - { value => 'imcast_prct', template => '%.2f', - unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }, - ], + }, + ; +} + +sub set_counters_errors { + my ($self, %options) = @_; + + push @{$self->{maps_counters}->{int}}, + { label => 'in-crc', filter => 'add_errors', nlabel => 'interface.packets.in.crc.count', set => { + key_values => [ { name => 'incrc', diff => 1 }, { name => 'total_in_packets', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], + closure_custom_calc => $self->can('custom_errors_calc'), closure_custom_calc_extra_options => { label_ref1 => 'in', label_ref2 => 'crc' }, + closure_custom_output => $self->can('custom_errors_output'), output_error_template => 'Packets In Crc : %s', + closure_custom_perfdata => $self->can('custom_errors_perfdata'), + closure_custom_threshold_check => $self->can('custom_errors_threshold'), } - }; - $self->{maps_counters}->{int}->{'063_out-ucast'} = { filter => 'add_cast', - set => { - key_values => [ { name => 'oucast', diff => 1 }, { name => 'omcast', diff => 1 }, { name => 'obcast', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], - closure_custom_calc => $self->can('custom_cast_calc'), closure_custom_calc_extra_options => { label_ref => 'oucast', total_ref1 => 'omcast', total_ref2 => 'obcast' }, - output_template => 'Out Ucast : %.2f %%', output_error_template => 'Out Ucast : %s', - output_use => 'oucast_prct', threshold_use => 'oucast_prct', - perfdatas => [ - { value => 'oucast_prct', template => '%.2f', - unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }, - ], - } - }; - $self->{maps_counters}->{int}->{'064_out-bcast'} = { filter => 'add_cast', - set => { - key_values => [ { name => 'oucast', diff => 1 }, { name => 'omcast', diff => 1 }, { name => 'obcast', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], - closure_custom_calc => $self->can('custom_cast_calc'), closure_custom_calc_extra_options => { label_ref => 'obcast', total_ref1 => 'omcast', total_ref2 => 'oucast' }, - output_template => 'Out Bcast : %.2f %%', output_error_template => 'Out Bcast : %s', - output_use => 'obcast_prct', threshold_use => 'obcast_prct', - perfdatas => [ - { value => 'obcast_prct', template => '%.2f', - unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }, - ], - } - }; - $self->{maps_counters}->{int}->{'065_out-mcast'} = { filter => 'add_cast', - set => { - key_values => [ { name => 'oucast', diff => 1 }, { name => 'omcast', diff => 1 }, { name => 'obcast', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], - closure_custom_calc => $self->can('custom_cast_calc'), closure_custom_calc_extra_options => { label_ref => 'omcast', total_ref1 => 'oucast', total_ref2 => 'obcast' }, - output_template => 'Out Mcast : %.2f %%', output_error_template => 'Out Mcast : %s', - output_use => 'omcast_prct', threshold_use => 'omcast_prct', - perfdatas => [ - { value => 'omcast_prct', template => '%.2f', - unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }, - ], - } - }; - } - if ($self->{no_speed} == 0 && $self->{no_set_speed} == 0) { - $self->{maps_counters}->{int}->{'080_speed'} = { filter => 'add_speed', - set => { - key_values => [ { name => 'speed' }, { name => 'display' } ], - closure_custom_calc => $self->can('custom_speed_calc'), - output_template => 'Speed : %s%s/s', output_error_template => 'Speed : %s%s/s', - output_change_bytes => 2, - output_use => 'speed', threshold_use => 'speed', - perfdatas => [ - { value => 'speed', template => '%s', - unit => 'b/s', min => 0, label_extra_instance => 1, instance_use => 'display' }, - ], - } - }; - } - if ($self->{no_volume} == 0 && $self->{no_set_volume} == 0) { - $self->{maps_counters}->{int}->{'090_in-volume'} = { filter => 'add_volume', threshold => 0, - set => { - key_values => [ { name => 'in_volume', diff => 1 }, { name => 'display' } ], - output_template => 'Volume In : %.2f %s', - output_change_bytes => 1, - perfdatas => [ - { label => 'volume_in', value => 'in_volume_absolute', template => '%s', - unit => 'B', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }; - $self->{maps_counters}->{int}->{'091_out-volume'} = { filter => 'add_volume', threshold => 0, - set => { - key_values => [ { name => 'out_volume', diff => 1 }, { name => 'display' } ], - output_template => 'Volume Out : %.2f %s', - output_change_bytes => 1, - perfdatas => [ - { label => 'volume_out', value => 'out_volume_absolute', template => '%s', - unit => 'B', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }; - } + }, + ; } sub set_key_values_status { my ($self, %options) = @_; - return [ { name => 'linkstatus' }, { name => 'opstatus' }, { name => 'admstatus' }, { name => 'display' } ]; + return [ { name => 'linkstatus' }, { name => 'opstatus' }, { name => 'admstatus' }, { name => 'duplexstatus' }, { name => 'display' } ]; } sub set_oids_label { my ($self, %options) = @_; $self->{oids_label} = { - 'ifdesc' => '.1.3.6.1.2.1.2.2.1.2', - 'ifalias' => '.1.3.6.1.2.1.31.1.1.1.18', - 'ifname' => '.1.3.6.1.2.1.31.1.1.1.1', + 'ifdesc' => { oid => '.1.3.6.1.2.1.2.2.1.2', cache => 'reload_cache_index_value' }, + 'ifalias' => { oid => '.1.3.6.1.2.1.31.1.1.1.18', cache => 'reload_cache_index_value' }, + 'ifname' => { oid => '.1.3.6.1.2.1.31.1.1.1.1', cache => 'reload_cache_index_value', }, + 'ipaddr' => { oid => '.1.3.6.1.2.1.4.20.1.2', cache => 'reload_cache_values_index', }, }; } @@ -307,6 +127,11 @@ sub set_oids_status { 16 => 'isolatedByDot1agOverRate', 17 => 'isolatedByLacpOverRate', 18 => 'isolatedByAhOverRate', 19 => 'isolatedByUdld', 20 => 'isolatedByShdslLinkDown', }; + + $self->{oid_duplexstatus} = '.1.3.6.1.4.1.6926.2.1.2.1.9'; + $self->{oid_duplexstatus_mapping} = { + 1 => 'other', 3 => 'fullDuplex', 4 => 'halfDuplex', + }; } sub set_oids_traffic { @@ -323,6 +148,12 @@ sub set_oids_speed { $self->{oid_speed64} = '.1.3.6.1.4.1.6926.2.1.2.1.7'; # in Mb/s } +sub set_oids_errors { + my ($self, %options) = @_; + + $self->{oid_ifInCrc} = '.1.3.6.1.4.1.6926.2.1.5.1.13'; # osPortCntRecvCRCorAlignmentErrs +} + sub set_oids_cast { my ($self, %options) = @_; @@ -390,14 +221,13 @@ sub default_global_oper_down_rule { sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_errors => 1); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_set_errors => 1); bless $self, $class; - $options{options}->add_options(arguments => - { - "global-link-up-rule:s" => { name => 'global_link_up_rule', default => $self->default_global_link_up_rule() }, - "global-link-down-rule:s" => { name => 'global_link_down_rule', default => $self->default_global_link_down_rule() }, - }); + $options{options}->add_options(arguments => { + "global-link-up-rule:s" => { name => 'global_link_up_rule', default => $self->default_global_link_up_rule() }, + "global-link-down-rule:s" => { name => 'global_link_down_rule', default => $self->default_global_link_down_rule() }, + }); return $self; } @@ -406,7 +236,12 @@ sub load_status { my ($self, %options) = @_; $self->set_oids_status(); - $self->{snmp}->load(oids => [$self->{oid_linkstatus}, $self->{oid_adminstatus}, $self->{oid_opstatus}], instances => $self->{array_interface_selected}); + my $oids = [$self->{oid_linkstatus}, $self->{oid_adminstatus}, $self->{oid_opstatus}]; + if (defined($self->{option_results}->{add_duplex_status})) { + push @$oids, $self->{oid_duplexstatus}; + } + + $self->{snmp}->load(oids => $oids, instances => $self->{array_interface_selected}); } sub load_traffic { @@ -440,6 +275,18 @@ sub load_cast { instances => $self->{array_interface_selected}); } +sub load_errors { + my ($self, %options) = @_; + + $self->set_oids_errors(); + $self->{snmp}->load( + oids => [ + $self->{oid_ifInCrc} + ], + instances => $self->{array_interface_selected} + ); +} + sub load_speed { my ($self, %options) = @_; @@ -499,56 +346,66 @@ sub add_result_global { sub add_result_status { my ($self, %options) = @_; - $self->{interface_selected}->{$options{instance}}->{linkstatus} = defined($self->{results}->{$self->{oid_linkstatus} . '.' . $options{instance}}) ? $self->{oid_linkstatus_mapping}->{$self->{results}->{$self->{oid_linkstatus} . '.' . $options{instance}}} : undef; - $self->{interface_selected}->{$options{instance}}->{opstatus} = defined($self->{results}->{$self->{oid_opstatus} . '.' . $options{instance}}) ? $self->{oid_opstatus_mapping}->{$self->{results}->{$self->{oid_opstatus} . '.' . $options{instance}}} : undef; - $self->{interface_selected}->{$options{instance}}->{admstatus} = defined($self->{results}->{$self->{oid_adminstatus} . '.' . $options{instance}}) ? $self->{oid_adminstatus_mapping}->{$self->{results}->{$self->{oid_adminstatus} . '.' . $options{instance}}} : undef; + $self->{int}->{$options{instance}}->{linkstatus} = defined($self->{results}->{$self->{oid_linkstatus} . '.' . $options{instance}}) ? $self->{oid_linkstatus_mapping}->{$self->{results}->{$self->{oid_linkstatus} . '.' . $options{instance}}} : undef; + $self->{int}->{$options{instance}}->{opstatus} = defined($self->{results}->{$self->{oid_opstatus} . '.' . $options{instance}}) ? $self->{oid_opstatus_mapping}->{$self->{results}->{$self->{oid_opstatus} . '.' . $options{instance}}} : undef; + $self->{int}->{$options{instance}}->{admstatus} = defined($self->{results}->{$self->{oid_adminstatus} . '.' . $options{instance}}) ? $self->{oid_adminstatus_mapping}->{$self->{results}->{$self->{oid_adminstatus} . '.' . $options{instance}}} : undef; + $self->{int}->{$options{instance}}->{duplexstatus} = defined($self->{results}->{$self->{oid_duplexstatus} . '.' . $options{instance}}) ? $self->{oid_duplexstatus_mapping}->{$self->{results}->{$self->{oid_duplexstatus} . '.' . $options{instance}}} : 'n/a'; } sub add_result_traffic { my ($self, %options) = @_; - $self->{interface_selected}->{$options{instance}}->{mode_traffic} = 64; - $self->{interface_selected}->{$options{instance}}->{in} = $self->{results}->{$self->{oid_in64} . '.' . $options{instance}}; - $self->{interface_selected}->{$options{instance}}->{out} = $self->{results}->{$self->{oid_out64} . '.' . $options{instance}}; - $self->{interface_selected}->{$options{instance}}->{in} *= 8 if (defined($self->{interface_selected}->{$options{instance}}->{in})); - $self->{interface_selected}->{$options{instance}}->{out} *= 8 if (defined($self->{interface_selected}->{$options{instance}}->{out})); - $self->{interface_selected}->{$options{instance}}->{speed_in} = 0; - $self->{interface_selected}->{$options{instance}}->{speed_out} = 0; + $self->{int}->{$options{instance}}->{mode_traffic} = 64; + $self->{int}->{$options{instance}}->{in} = $self->{results}->{$self->{oid_in64} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{out} = $self->{results}->{$self->{oid_out64} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{in} *= 8 if (defined($self->{int}->{$options{instance}}->{in})); + $self->{int}->{$options{instance}}->{out} *= 8 if (defined($self->{int}->{$options{instance}}->{out})); + $self->{int}->{$options{instance}}->{speed_in} = 0; + $self->{int}->{$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->{int}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed} * 1000000; + $self->{int}->{$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 ''); + $self->{int}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed_in} * 1000000 if (defined($self->{option_results}->{speed_in}) && $self->{option_results}->{speed_in} ne ''); + $self->{int}->{$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_speed64} . "." . $options{instance}} * 1000000; - $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 ''); + $self->{int}->{$options{instance}}->{speed_in} = $interface_speed; + $self->{int}->{$options{instance}}->{speed_out} = $interface_speed; + $self->{int}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed_in} * 1000000 if (defined($self->{option_results}->{speed_in}) && $self->{option_results}->{speed_in} ne ''); + $self->{int}->{$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_cast { my ($self, %options) = @_; - my $iucast = $self->{results}->{$self->{oid_ifHCInUcastPkts} . '.' . $options{instance}}; if (defined($iucast) && $iucast =~ /[1-9]/) { - $self->{interface_selected}->{$options{instance}}->{iucast} = $iucast; - $self->{interface_selected}->{$options{instance}}->{imcast} = defined($self->{results}->{$self->{oid_ifHCInMulticastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCInMulticastPkts} . '.' . $options{instance}} : 0; - $self->{interface_selected}->{$options{instance}}->{ibcast} = defined($self->{results}->{$self->{oid_ifHCInBroadcastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCInBroadcastPkts} . '.' . $options{instance}} : 0; - $self->{interface_selected}->{$options{instance}}->{oucast} = $self->{results}->{$self->{oid_ifHCOutUcastPkts} . '.' . $options{instance}}; - $self->{interface_selected}->{$options{instance}}->{omcast} = defined($self->{results}->{$self->{oid_ifHCOutMulticastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCOutMulticastPkts} . '.' . $options{instance}} : 0; - $self->{interface_selected}->{$options{instance}}->{obcast} = defined($self->{results}->{$self->{oid_ifHCOutBroadcastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCOutBroadcastPkts} . '.' . $options{instance}} : 0; - $self->{interface_selected}->{$options{instance}}->{mode_cast} = 64; + $self->{int}->{$options{instance}}->{iucast} = $iucast; + $self->{int}->{$options{instance}}->{imcast} = defined($self->{results}->{$self->{oid_ifHCInMulticastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCInMulticastPkts} . '.' . $options{instance}} : 0; + $self->{int}->{$options{instance}}->{ibcast} = defined($self->{results}->{$self->{oid_ifHCInBroadcastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCInBroadcastPkts} . '.' . $options{instance}} : 0; + $self->{int}->{$options{instance}}->{oucast} = $self->{results}->{$self->{oid_ifHCOutUcastPkts} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{omcast} = defined($self->{results}->{$self->{oid_ifHCOutMulticastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCOutMulticastPkts} . '.' . $options{instance}} : 0; + $self->{int}->{$options{instance}}->{obcast} = defined($self->{results}->{$self->{oid_ifHCOutBroadcastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCOutBroadcastPkts} . '.' . $options{instance}} : 0; + $self->{int}->{$options{instance}}->{mode_cast} = 64; } - foreach (('iucast', 'imcast', 'ibcast', 'oucast', 'omcast', 'omcast')) { - $self->{interface_selected}->{$options{instance}}->{$_} = 0 if (!defined($self->{interface_selected}->{$options{instance}}->{$_})); - }} + foreach (('iucast', 'imcast', 'ibcast', 'oucast', 'omcast', 'obcast')) { + $self->{int}->{$options{instance}}->{$_} = 0 if (!defined($self->{int}->{$options{instance}}->{$_})); + } + + $self->{int}->{$options{instance}}->{total_in_packets} = $self->{int}->{$options{instance}}->{iucast} + $self->{int}->{$options{instance}}->{imcast} + $self->{int}->{$options{instance}}->{ibcast}; + $self->{int}->{$options{instance}}->{total_out_packets} = $self->{int}->{$options{instance}}->{oucast} + $self->{int}->{$options{instance}}->{omcast} + $self->{int}->{$options{instance}}->{obcast}; +} + +sub add_result_errors { + my ($self, %options) = @_; + + $self->{int}->{$options{instance}}->{incrc} = $self->{results}->{$self->{oid_ifInCrc} . '.' . $options{instance}}; +} sub add_result_speed { my ($self, %options) = @_; @@ -556,14 +413,14 @@ sub add_result_speed { my $interface_speed = 0; $interface_speed = $self->{results}->{$self->{oid_speed64} . "." . $options{instance}} * 1000000; - $self->{interface_selected}->{$options{instance}}->{speed} = $interface_speed; + $self->{int}->{$options{instance}}->{speed} = $interface_speed; } sub add_result_volume { my ($self, %options) = @_; - $self->{interface_selected}->{$options{instance}}->{in_volume} = $self->{results}->{$self->{oid_in64} . '.' . $options{instance}}; - $self->{interface_selected}->{$options{instance}}->{out_volume} = $self->{results}->{$self->{oid_out64} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{in_volume} = $self->{results}->{$self->{oid_in64} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{out_volume} = $self->{results}->{$self->{oid_out64} . '.' . $options{instance}}; } 1; @@ -584,10 +441,18 @@ Check global port statistics. Check interface status (By default if no --add-* option is set). +=item B<--add-duplex-status> + +Check duplex status (with --warning-status and --critical-status). + =item B<--add-traffic> Check interface traffic. +=item B<--add-errors> + +Check interface errors. + =item B<--add-cast> Check interface cast. @@ -603,25 +468,25 @@ Check interface data volume between two checks (not supposed to be graphed, usef =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{linkstatus}, %{admstatus}, %{opstatus}, %{display} +Can used special variables like: %{linkstatus}, %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "enable" and %{opstatus} eq "enabled" and %{linkstatus} ne "true"'). -Can used special variables like: %{linkstatus}, %{admstatus}, %{opstatus}, %{display} +Can used special variables like: %{linkstatus}, %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> Threshold warning. Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down', 'total-link-up', 'total-link-down', -'in-traffic', 'out-traffic', 'in-ucast' (%), 'in-bcast' (%), 'in-mcast' (%), 'out-ucast' (%), 'out-bcast' (%), 'out-mcast' (%), +'in-traffic', 'out-traffic', 'in-crc', 'in-ucast' (%), 'in-bcast' (%), 'in-mcast' (%), 'out-ucast' (%), 'out-bcast' (%), 'out-mcast' (%), 'speed' (b/s). =item B<--critical-*> Threshold critical. Can be: 'total-port', 'total-admin-up', 'total-admin-down', 'total-oper-up', 'total-oper-down', 'total-link-up', 'total-link-down', -'in-traffic', 'out-traffic', 'in-ucast' (%), 'in-bcast' (%), 'in-mcast' (%), 'out-ucast' (%), 'out-bcast' (%), 'out-mcast' (%), +'in-traffic', 'out-traffic', 'in-crc', 'in-ucast' (%), 'in-bcast' (%), 'in-mcast' (%), 'out-ucast' (%), 'out-bcast' (%), 'out-mcast' (%), 'speed' (b/s). =item B<--units-traffic> diff --git a/network/mrv/optiswitch/snmp/mode/memory.pm b/network/mrv/optiswitch/snmp/mode/memory.pm new file mode 100644 index 000000000..56a1df201 --- /dev/null +++ b/network/mrv/optiswitch/snmp/mode/memory.pm @@ -0,0 +1,92 @@ +# +# Copyright 2019 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::mrv::optiswitch::snmp::mode::memory; + +use base qw(snmp_standard::mode::memory); + +use strict; +use warnings; + +sub memory_calc { + my ($self, %options) = @_; + + my $available = ($options{result}->{memTotalFree}) ? $options{result}->{memTotalFree} * 1024 : 0; + my $total = ($options{result}->{memTotalReal}) ? $options{result}->{memTotalReal} * 1024 : 0; + my $buffer = ($options{result}->{memBuffer}) ? $options{result}->{memBuffer} * 1024 : 0; + my $cached = ($options{result}->{memCached}) ? $options{result}->{memCached} * 1024 : 0; + my ($used, $free, $prct_used, $prct_free) = (0, 0, 0, 0); + + if ($total != 0) { + $used = $total - $available - $buffer - $cached; + $free = $total - $used; + $prct_used = $used * 100 / $total; + $prct_free = 100 - $prct_used; + } + + $self->{ram} = { + total => $total, + used => $used, + free => $free, + prct_used => $prct_used, + prct_free => $prct_free, + memShared => ($options{result}->{memShared}) ? $options{result}->{memShared} * 1024 : 0, + memBuffer => $buffer, + memCached => $cached, + }; +} + +1; + +__END__ + +=head1 MODE + +Check memory usage (UCD-SNMP-MIB). + +=over 8 + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'absolute'). + +=item B<--free> + +Thresholds are on free space left. + +=item B<--swap> + +Check swap also. + +=item B<--warning-*> + +Threshold warning. +Can be: 'usage', 'swap', 'buffer' (absolute), +'cached' (absolute), 'shared' (absolute). + +=item B<--critical-*> + +Threshold critical. +Can be: 'usage', 'swap', 'buffer' (absolute), +'cached' (absolute), 'shared' (absolute). + +=back + +=cut diff --git a/network/mrv/optiswitch/snmp/plugin.pm b/network/mrv/optiswitch/snmp/plugin.pm index 5937816a5..8d385efff 100644 --- a/network/mrv/optiswitch/snmp/plugin.pm +++ b/network/mrv/optiswitch/snmp/plugin.pm @@ -31,11 +31,14 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'environment' => 'network::mrv::optiswitch::snmp::mode::environment', - 'interfaces' => 'network::mrv::optiswitch::snmp::mode::interfaces', - 'list-interfaces' => 'network::mrv::optiswitch::snmp::mode::listinterfaces', - 'uptime' => 'snmp_standard::mode::uptime', - ); + 'cpu-detailed' => 'snmp_standard::mode::cpudetailed', + 'environment' => 'network::mrv::optiswitch::snmp::mode::environment', + 'interfaces' => 'network::mrv::optiswitch::snmp::mode::interfaces', + 'list-interfaces' => 'network::mrv::optiswitch::snmp::mode::listinterfaces', + 'load' => 'snmp_standard::mode::loadaverage', + 'memory' => 'network::mrv::optiswitch::snmp::mode::memory', + 'uptime' => 'snmp_standard::mode::uptime', + ); return $self; } diff --git a/network/netgear/mseries/snmp/mode/components/fan.pm b/network/netgear/mseries/snmp/mode/components/fan.pm index 0a0905641..955e6c54b 100644 --- a/network/netgear/mseries/snmp/mode/components/fan.pm +++ b/network/netgear/mseries/snmp/mode/components/fan.pm @@ -75,11 +75,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '%s' is '%s' rpm", $instance, $result->{boxServicesFanSpeed})); } - $self->{output}->perfdata_add(label => 'fan_' . $instance, unit => 'rpm', - value => $result->{boxServicesFanSpeed}, - warning => $warn, - critical => $crit, min => 0 - ); + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $instance, + value => $result->{boxServicesFanSpeed}, + warning => $warn, + critical => $crit, min => 0 + ); } } diff --git a/network/netgear/mseries/snmp/mode/components/temperature.pm b/network/netgear/mseries/snmp/mode/components/temperature.pm index 43ce7a728..819ac979e 100644 --- a/network/netgear/mseries/snmp/mode/components/temperature.pm +++ b/network/netgear/mseries/snmp/mode/components/temperature.pm @@ -75,11 +75,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is '%s' rpm", $instance, $result->{boxServicesTempSensorTemperature})); } - $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', - value => $result->{boxServicesTempSensorTemperature}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $instance, + value => $result->{boxServicesTempSensorTemperature}, + warning => $warn, + critical => $crit, + ); } } diff --git a/network/nokia/timos/snmp/mode/hardware.pm b/network/nokia/timos/snmp/mode/hardware.pm index 872a7a746..93bf0cb1d 100644 --- a/network/nokia/timos/snmp/mode/hardware.pm +++ b/network/nokia/timos/snmp/mode/hardware.pm @@ -201,11 +201,14 @@ sub check { short_msg => sprintf("%s '%s' temperature is '%s' C", $result->{tmnxHwClass}, $result->{tmnxHwName}, $result->{tmnxHwTemperature})); } - $self->{output}->perfdata_add(label => 'temperature_' . $result->{tmnxHwName}, unit => 'C', - value => $result->{tmnxHwTemperature}, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'temperature' . , unit => 'C', + nlabel => 'hardware.entity.temperature.celsius', + instances => $result->{tmnxHwName}, + value => $result->{tmnxHwTemperature}, + warning => $warn, + critical => $crit + ); } } diff --git a/network/nortel/standard/snmp/mode/components/fan.pm b/network/nortel/standard/snmp/mode/components/fan.pm index 57110c90d..d511e9363 100644 --- a/network/nortel/standard/snmp/mode/components/fan.pm +++ b/network/nortel/standard/snmp/mode/components/fan.pm @@ -67,12 +67,15 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Fan temperature '%s' is %s degree centigrade", $instance, $result->{rcChasFanAmbientTemperature})); } - $self->{output}->perfdata_add(label => 'fan_temp_' . $instance, unit => 'C', - value => $result->{rcChasFanAmbientTemperature}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'fan_temp', unit => 'C', + nlabel => 'hardware.fan.temperature.celsius', + instances => $instance, + value => $result->{rcChasFanAmbientTemperature}, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1; diff --git a/network/nortel/standard/snmp/mode/components/temperature.pm b/network/nortel/standard/snmp/mode/components/temperature.pm index 378757df2..9b4c6e791 100644 --- a/network/nortel/standard/snmp/mode/components/temperature.pm +++ b/network/nortel/standard/snmp/mode/components/temperature.pm @@ -59,12 +59,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s degree centigrade", $result->{slHdwTempSensorName}, $result->{s5ChasTmpSnrTmpValue})); } - $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', - value => $result->{s5ChasTmpSnrTmpValue}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $instance, + value => $result->{s5ChasTmpSnrTmpValue}, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1; diff --git a/network/oracle/infiniband/snmp/mode/infinibandusage.pm b/network/oracle/infiniband/snmp/mode/infinibandusage.pm index 7fe8d590a..20dbe18e0 100644 --- a/network/oracle/infiniband/snmp/mode/infinibandusage.pm +++ b/network/oracle/infiniband/snmp/mode/infinibandusage.pm @@ -141,25 +141,23 @@ sub custom_status_calc { sub custom_ib_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 ($self->{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); + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); } elsif ($self->{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}); + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}); } - $self->{output}->perfdata_add(label => 'traffic_' . $self->{result_values}->{label} . $extra_label, unit => 'b/s', - value => sprintf("%.2f", $self->{result_values}->{traffic}), - warning => $warning, - critical => $critical, - min => 0, max => $self->{result_values}->{speed}); + $self->{output}->perfdata_add( + label => 'traffic_' . $self->{result_values}->{label}, unit => 'b/s', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{traffic}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed} + ); } sub custom_ib_threshold { @@ -167,9 +165,9 @@ sub custom_ib_threshold { my $exit = 'ok'; if ($self->{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' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } elsif ($self->{instance_mode}->{option_results}->{units_traffic} eq 'b/s') { - $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } return $exit; } @@ -215,18 +213,17 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-ib-name:s" => { name => 'filter_ib_name' }, - "filter-ibgw-name:s" => { name => 'filter_ibgw_name' }, - "warning-ib-status:s" => { name => 'warning_ib_status', default => '' }, - "critical-ib-status:s" => { name => 'critical_ib_status', default => '%{status} !~ /active/i' }, - "warning-ibgw-status:s" => { name => 'warning_ibgw_status', default => '' }, - "critical-ibgw-status:s" => { name => 'critical_ibgw_status', default => '%{status} !~ /up/i' }, - "speed-in:s" => { name => 'speed_in' }, - "speed-out:s" => { name => 'speed_out' }, - "units-traffic:s" => { name => 'units_traffic', default => '%' }, - }); + $options{options}->add_options(arguments => { + "filter-ib-name:s" => { name => 'filter_ib_name' }, + "filter-ibgw-name:s" => { name => 'filter_ibgw_name' }, + "warning-ib-status:s" => { name => 'warning_ib_status', default => '' }, + "critical-ib-status:s" => { name => 'critical_ib_status', default => '%{status} !~ /active/i' }, + "warning-ibgw-status:s" => { name => 'warning_ibgw_status', default => '' }, + "critical-ibgw-status:s" => { name => 'critical_ibgw_status', default => '%{status} !~ /up/i' }, + "speed-in:s" => { name => 'speed_in' }, + "speed-out:s" => { name => 'speed_out' }, + "units-traffic:s" => { name => 'units_traffic', default => '%' }, + }); return $self; } diff --git a/network/peplink/balance/snmp/mode/cpu.pm b/network/peplink/balance/snmp/mode/cpu.pm index 569c734cb..28d6cc279 100644 --- a/network/peplink/balance/snmp/mode/cpu.pm +++ b/network/peplink/balance/snmp/mode/cpu.pm @@ -1,5 +1,5 @@ # -# Copyright 2019 Centreon (http://www.centreon.com/) +# Copyright 2018 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -96,5 +96,4 @@ Threshold critical in percent. =back -=cut - +=cut \ No newline at end of file diff --git a/network/peplink/balance/snmp/mode/memory.pm b/network/peplink/balance/snmp/mode/memory.pm index fdc4555f3..9d3de922e 100644 --- a/network/peplink/balance/snmp/mode/memory.pm +++ b/network/peplink/balance/snmp/mode/memory.pm @@ -1,5 +1,5 @@ # -# Copyright 2019 Centreon (http://www.centreon.com/) +# Copyright 2018 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -111,5 +111,4 @@ Threshold critical in percent. =back -=cut - +=cut \ No newline at end of file diff --git a/network/peplink/balance/snmp/plugin.pm b/network/peplink/balance/snmp/plugin.pm index 7ecd7737e..5cadf2ab4 100644 --- a/network/peplink/balance/snmp/plugin.pm +++ b/network/peplink/balance/snmp/plugin.pm @@ -1,5 +1,5 @@ # -# Copyright 2019 Centreon (http://www.centreon.com/) +# Copyright 2018 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -48,4 +48,4 @@ __END__ Check Peplink loadbalancer in SNMP. -=cut +=cut \ No newline at end of file diff --git a/network/peplink/pepwave/snmp/mode/cpu.pm b/network/peplink/pepwave/snmp/mode/cpu.pm new file mode 100644 index 000000000..c32d575ec --- /dev/null +++ b/network/peplink/pepwave/snmp/mode/cpu.pm @@ -0,0 +1,90 @@ +# +# Copyright 2019 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::peplink::pepwave::snmp::mode::cpu; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + $self->{maps_counters}->{global} = [ + { label => 'usage', set => { + key_values => [ { name => 'cpu_load' } ], + output_template => 'CPU Load %.2f %%', + perfdatas => [ + { label => 'cpu_load', value => 'cpu_load_absolute', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} + +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 => { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_deviceCpuLoad = '.1.3.6.1.4.1.27662.200.1.1.1.3.1.0'; + + my $result = $options{snmp}->get_leef(oids => [$oid_deviceCpuLoad], + nothing_quit => 1); + $self->{global} = { + cpu_load => $result->{$oid_deviceCpuLoad} + }; +} + +1; + +__END__ + +=head1 MODE + +Check CPU load. + +=over 8 + +=item B<--warning-usage> + +Threshold warning. + +=item B<--critical-usage> + +Threshold critical. + +=back + +=cut diff --git a/network/peplink/pepwave/snmp/mode/memory.pm b/network/peplink/pepwave/snmp/mode/memory.pm new file mode 100644 index 000000000..4585b1951 --- /dev/null +++ b/network/peplink/pepwave/snmp/mode/memory.pm @@ -0,0 +1,135 @@ +# +# Copyright 2019 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::peplink::pepwave::snmp::mode::memory; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => 'used', unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + + my $msg = sprintf("Memory Usage Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'usage', set => { + key_values => [ { name => 'used' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +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 => { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_deviceTotalMemory = '.1.3.6.1.4.1.27662.200.1.1.1.3.2.0'; + my $oid_deviceMemoryUsage = '.1.3.6.1.4.1.27662.200.1.1.1.3.3.0'; + + my $result = $options{snmp}->get_leef(oids => [$oid_deviceTotalMemory, $oid_deviceMemoryUsage], + nothing_quit => 1); + $self->{global} = { + total => $result->{$oid_deviceTotalMemory} * 1024, + used => $result->{$oid_deviceMemoryUsage} * 1024, + }; +} + +1; + +__END__ + +=head1 MODE + +Check memory usage. + +=over 8 + +=item B<--warning-usage> + +Threshold warning (in percent). + +=item B<--critical-usage> + +Threshold critical (in percent). + +=back + +=cut diff --git a/network/peplink/pepwave/snmp/mode/wanusage.pm b/network/peplink/pepwave/snmp/mode/wanusage.pm new file mode 100644 index 000000000..521196154 --- /dev/null +++ b/network/peplink/pepwave/snmp/mode/wanusage.pm @@ -0,0 +1,222 @@ +# +# Copyright 2019 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::peplink::pepwave::snmp::mode::wanusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf('health status : %s', $self->{result_values}->{health_status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{health_status} = $options{new_datas}->{$self->{instance} . '_health_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'wan', type => 1, cb_prefix_output => 'prefix_wan_output', message_multiple => 'All WANs are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{wan} = [ + { label => 'health-status', threshold => 0, set => { + key_values => [ { name => 'health_status' }, { 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 => \&catalog_status_threshold, + } + }, + { label => 'signal', set => { + key_values => [ { name => 'signal' }, { name => 'display' } ], + output_template => 'Signal Strength : %s dBm', + perfdatas => [ + { label => 'signal', value => 'signal_absolute', template => '%s', unit => 'dBm', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-in', set => { + key_values => [ { name => 'traffic_in', diff => 1 }, { name => 'display' } ], + output_template => 'Traffic In : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'traffic_in', value => 'traffic_in_per_second', template => '%d', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-out', set => { + key_values => [ { name => 'traffic_out', diff => 1 }, { name => 'display' } ], + output_template => 'Traffic Out : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'traffic_out', value => 'traffic_out_per_second', template => '%d', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_wan_output { + my ($self, %options) = @_; + + return "WAN '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "warning-health-status:s" => { name => 'warning_health_status', default => '' }, + "critical-health-status:s" => { name => 'critical_health_status', default => '%{health_status} =~ /fail/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_health_status', 'critical_health_status']); +} + +my %mapping_health = ( + 0 => 'fail', + 1 => 'success', +); + +my $mapping = { + wanName => { oid => '.1.3.6.1.4.1.27662.2.1.2.1.2' }, + wanHealthCheckState => { oid => '.1.3.6.1.4.1.27662.2.1.2.1.4', map => \%mapping_health }, + wanSignal => { oid => '.1.3.6.1.4.1.27662.2.1.2.1.5' }, +}; +my $mapping2 = { + wanDataUsageTxByte => { oid => '.1.3.6.1.4.1.27662.2.1.4.1.2' }, + wanDataUsageRxByte => { oid => '.1.3.6.1.4.1.27662.2.1.4.1.3' }, +}; +my $oid_wanEntry = '.1.3.6.1.4.1.27662.2.1.2.1'; +my $oid_wanDataUsageEntry = '.1.3.6.1.4.1.27662.2.1.4.1'; + +sub manage_selection { + my ($self, %options) = @_; + + if ($options{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); + $self->{output}->option_exit(); + } + + $self->{wan} = {}; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_wanEntry, start => $mapping->{wanName}->{oid}, end => $mapping->{wanSignal}->{oid} }, + { oid => $oid_wanDataUsageEntry }, + ], nothing_quit => 1); + foreach my $oid (keys %{$snmp_result->{$oid_wanEntry}}) { + next if ($oid !~ /^$mapping->{wanName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result->{$oid_wanEntry}, instance => $instance); + my $result2 = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result->{$oid_wanDataUsageEntry}, instance => $instance . '.3'); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{wanName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{wanName} . "': no matching filter.", debug => 1); + next; + } + + $self->{wan}->{$instance} = { display => $result->{wanName}, + health_status => $result->{wanHealthCheckState}, + signal => $result->{wanSignal} != -9999 ? $result->{wanSignal} : undef, + traffic_in => $result2->{wanDataUsageRxByte} * 1024 * 1024 * 8, + traffic_out => $result2->{wanDataUsageTxByte} * 1024 * 1024 * 8, + }; + } + + if (scalar(keys %{$self->{wan}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No wan found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "peplink_" . $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')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check wan usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^traffic-in$' + +=item B<--filter-name> + +Filter wan name (can be a regexp). + +=item B<--warning-health-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{health_status}, %{display} + +=item B<--critical-health-status> + +Set critical threshold for status (Default: '%{health_status} =~ /fail/'). +Can used special variables like: %{health_status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'traffic-in', 'traffic-out'. + +=item B<--critical-*> + +Threshold critical. +Can be: Can be: 'traffic-in', 'traffic-out'. + +=back + +=cut diff --git a/network/peplink/pepwave/snmp/plugin.pm b/network/peplink/pepwave/snmp/plugin.pm new file mode 100644 index 000000000..cc4632368 --- /dev/null +++ b/network/peplink/pepwave/snmp/plugin.pm @@ -0,0 +1,52 @@ +# +# Copyright 2019 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::peplink::pepwave::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}} = ( + 'cpu' => 'network::peplink::pepwave::snmp::mode::cpu', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::peplink::pepwave::snmp::mode::memory', + 'wan-usage' => 'network::peplink::pepwave::snmp::mode::wanusage', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Peplink Pepwave equipments in SNMP. + +=cut diff --git a/network/rad/airmux/snmp/mode/alarms.pm b/network/rad/airmux/snmp/mode/alarms.pm new file mode 100644 index 000000000..096db6bc0 --- /dev/null +++ b/network/rad/airmux/snmp/mode/alarms.pm @@ -0,0 +1,190 @@ +# +# Copyright 2018 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::rad::airmux::snmp::mode::alarms; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use POSIX; +use centreon::plugins::misc; +use centreon::plugins::statefile; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("alarm [severity: %s] [source: %s] [text: %s] %s", $self->{result_values}->{severity}, + $self->{result_values}->{source}, $self->{result_values}->{text}, $self->{result_values}->{generation_time}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{source} = $options{new_datas}->{$self->{instance} . '_radwllMilOduAgnLastEventsIfIndex'}; + $self->{result_values}->{text} = $options{new_datas}->{$self->{instance} . '_radwllMilOduAgnLastEventsText'}; + $self->{result_values}->{severity} = $options{new_datas}->{$self->{instance} . '_radwllMilOduAgnLastEventsSeverity'}; + $self->{result_values}->{since} = $options{new_datas}->{$self->{instance} . '_since'}; + $self->{result_values}->{generation_time} = $options{new_datas}->{$self->{instance} . '_radwllMilOduAgnLastEventsTimeT'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'alarms', type => 2, message_multiple => '0 problem(s) detected', display_counter_problem => { label => 'alerts', min => 0 }, + group => [ { name => 'alarm', skipped_code => { -11 => 1 } } ] + } + ]; + + $self->{maps_counters}->{alarm} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'radwllMilOduAgnLastEventsIfIndex' }, { name => 'radwllMilOduAgnLastEventsText' }, + { name => 'since' }, { name => 'radwllMilOduAgnLastEventsSeverity' }, { name => 'radwllMilOduAgnLastEventsTimeT' } ], + 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 => \&catalog_status_threshold, + } + }, + ]; +} + +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-msg:s" => { name => 'filter_msg' }, + "warning-status:s" => { name => 'warning_status', default => '%{severity} =~ /minor|warning/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{severity} =~ /critical|major/i' }, + "memory" => { name => 'memory' }, + }); + + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'Date::Parse', + error_msg => "Cannot load module 'Date::Parse'."); + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status']); + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->check_options(%options); + } +} + +my %map_severity = (1 => 'event', 2 => 'normal', 4 => 'warning', 8 => 'minor', + 16 => 'major', 32 => 'critical'); + +my $mapping = { + radwllMilOduAgnLastEventsIfIndex => { oid => '.1.3.6.1.4.1.4458.1000.1.7.4.2.1.3' }, + radwllMilOduAgnLastEventsText => { oid => '.1.3.6.1.4.1.4458.1000.1.7.4.2.1.5' }, + radwllMilOduAgnLastEventsTimeT => { oid => '.1.3.6.1.4.1.4458.1000.1.7.4.2.1.4' }, #timestamp in second + radwllMilOduAgnLastEventsSeverity => { oid => '.1.3.6.1.4.1.4458.1000.1.7.4.2.1.2', map => \%map_severity }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{alarms}->{global} = { alarm => {} }; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{radwllMilOduAgnLastEventsIfIndex}->{oid} }, + { oid => $mapping->{radwllMilOduAgnLastEventsText}->{oid} }, + { oid => $mapping->{radwllMilOduAgnLastEventsTimeT}->{oid} }, + { oid => $mapping->{radwllMilOduAgnLastEventsSeverity}->{oid} }, + ], return_type => 1); + + my $last_time; + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->read(statefile => "cache_rad_airmux_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port(). '_' . $self->{mode}); + $last_time = $self->{statefile_cache}->get(name => 'last_time'); + } + + my ($i, $current_time) = (1, time()); + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{radwllMilOduAgnLastEventsSeverity}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + my $create_time = $result->{radwllMilOduAgnLastEventsTimeT}; + $result->{radwllMilOduAgnLastEventsTimeT} = strftime("%d/%m/%Y %H:%M:%S",localtime($result->{radwllMilOduAgnLastEventsTimeT})); + if (!defined($create_time)) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't get date '" . $result->{radwllMilOduAgnLastEventsTimeT} . "'"); + next; + } + + next if (defined($self->{option_results}->{memory}) && defined($last_time) && $last_time > $create_time); + if (defined($self->{option_results}->{filter_msg}) && $self->{option_results}->{filter_msg} ne '' && + $result->{radwllMilOduAgnLastEventsText} !~ /$self->{option_results}->{filter_msg}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{radwllMilOduAgnLastEventsText} . "': no matching filter.", debug => 1); + next; + } + + my $diff_time = $current_time - $create_time; + $self->{alarms}->{global}->{alarm}->{$i} = { %$result, since => $diff_time }; + $i++; + } + + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->write(data => { last_time => $current_time }); + } +} + +1; + +__END__ + +=head1 MODE + +Check alarms. + +=over 8 + +=item B<--filter-msg> + +Filter by message (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{severity} =~ /minor|warning/i') +Can used special variables like: %{severity}, %{text}, %{source}, %{since} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{severity} =~ /critical|major/i'). +Can used special variables like: %{severity}, %{text}, %{source}, %{since} + +=item B<--memory> + +Only check new alarms. + +=back + +=cut diff --git a/network/rad/airmux/snmp/mode/radiostatus.pm b/network/rad/airmux/snmp/mode/radiostatus.pm new file mode 100644 index 000000000..5e56eb0a3 --- /dev/null +++ b/network/rad/airmux/snmp/mode/radiostatus.pm @@ -0,0 +1,139 @@ +# +# Copyright 2018 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::rad::airmux::snmp::mode::radiostatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub custom_badframes_calc { + my ($self, %options) = @_; + + my $delta_value = $options{new_datas}->{$self->{instance} . '_bad_frames'} - $options{old_datas}->{$self->{instance} . '_bad_frames'}; + my $delta_total = $options{new_datas}->{$self->{instance} . '_total_frames'} - $options{old_datas}->{$self->{instance} . '_total_frames'}; + + $self->{result_values}->{bad_prct} = 0; + if ($delta_total > 0) { + $self->{result_values}->{bad_prct} = $delta_value * 100 / $delta_total; + } + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + $self->{maps_counters}->{global} = [ + { label => 'rx-power', set => { + key_values => [ { name => 'rx_power' } ], + output_template => 'Received signal strength: %s Dbm', + perfdatas => [ + { label => 'rx_power', value => 'rx_power_absolute', template => '%s', min => 0 , unit => 'Dbm' }, + ], + } + }, + { label => 'tx-power', set => { + key_values => [ { name => 'tx_power' } ], + output_template => 'Current transmit power: %s Dbm', + perfdatas => [ + { label => 'tx_power', value => 'tx_power_absolute', template => '%s', min => 0 , unit => 'Dbm' }, + ], + } + }, + { label => 'bad-frames', set => { + key_values => [ { name => 'total_frames', diff => 1 }, { name => 'bad_frames', diff => 1 } ], + closure_custom_calc => $self->can('custom_badframes_calc'), + output_template => 'Bad frames: %.2f %%', output_use => 'bad_prct', threshold_use => 'bad_prct', + perfdatas => [ + { label => 'bad_frames', value => 'bad_prct', template => '%.2f', min => 0, max => 100, + unit => '%' }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_radwllMilOduAirCurrentTxPower = '.1.3.6.1.4.1.4458.1000.1.5.12.0'; + my $oid_radwllMilOduAirRxPower = '.1.3.6.1.4.1.4458.1000.1.5.9.1.0'; + my $oid_radwllMilOduAirBadFrames = '.1.3.6.1.4.1.4458.1000.1.5.9.3.0'; + my $oid_radwllMilOduAirTotalFrames = '.1.3.6.1.4.1.4458.1000.1.5.9.2.0'; + my $result = $options{snmp}->get_leef(oids => [ + $oid_radwllMilOduAirCurrentTxPower, $oid_radwllMilOduAirRxPower, $oid_radwllMilOduAirBadFrames, $oid_radwllMilOduAirTotalFrames + ], nothing_quit => 1); + + $self->{cache_name} = "rad_airmux_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + $self->{global} = { + tx_power => $result->{$oid_radwllMilOduAirCurrentTxPower}, + rx_power => $result->{$oid_radwllMilOduAirRxPower}, + bad_frames => $result->{$oid_radwllMilOduAirBadFrames}, + total_frames => $result->{$oid_radwllMilOduAirTotalFrames}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check radio signal. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='rx-power' + +=item B<--warning-*> + +Threshold warning. +Can be: 'tx-power', 'rx-power', 'bad-frames'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'tx-power', 'rx-power', 'bad-frames'. + +=back + +=cut diff --git a/network/rad/airmux/snmp/plugin.pm b/network/rad/airmux/snmp/plugin.pm new file mode 100644 index 000000000..1dbeb8b92 --- /dev/null +++ b/network/rad/airmux/snmp/plugin.pm @@ -0,0 +1,52 @@ +# +# Copyright 2018 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::rad::airmux::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}} = ( + 'alarms' => 'network::rad::airmux::snmp::mode::alarms', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'radio-status' => 'network::rad::airmux::snmp::mode::radiostatus', + 'uptime' => 'snmp_standard::mode::uptime', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Rad Airmux (200, 400) in SNMP + +=cut diff --git a/network/raisecom/snmp/mode/components/fan.pm b/network/raisecom/snmp/mode/components/fan.pm index a9dd9abca..504658f9c 100644 --- a/network/raisecom/snmp/mode/components/fan.pm +++ b/network/raisecom/snmp/mode/components/fan.pm @@ -69,11 +69,15 @@ sub check { short_msg => sprintf("Fan speed '%s' is %s rpm", $instance, $result->{raisecomFanSpeedValue})); } - $self->{output}->perfdata_add(label => 'fan_' . $instance, unit => 'rpm', - value => $result->{raisecomFanSpeedValue}, - warning => $warn, - critical => $crit, - min => 0); + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $instance, + value => $result->{raisecomFanSpeedValue}, + warning => $warn, + critical => $crit, + min => 0 + ); } } diff --git a/network/raisecom/snmp/mode/components/temperature.pm b/network/raisecom/snmp/mode/components/temperature.pm index 3df90e1c0..37eb7dfe4 100644 --- a/network/raisecom/snmp/mode/components/temperature.pm +++ b/network/raisecom/snmp/mode/components/temperature.pm @@ -72,11 +72,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %.2f C", $instance, $result->{raisecomTemperatureValue})); } - $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', - value => $result->{raisecomTemperatureValue}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $instance, + value => $result->{raisecomTemperatureValue}, + warning => $warn, + critical => $crit, + ); } } diff --git a/network/raisecom/snmp/mode/components/voltage.pm b/network/raisecom/snmp/mode/components/voltage.pm index 3fc6a55fa..c7670ecf7 100644 --- a/network/raisecom/snmp/mode/components/voltage.pm +++ b/network/raisecom/snmp/mode/components/voltage.pm @@ -72,11 +72,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Voltage '%s' is %.2f mV", $instance, $result->{raisecomVoltValue})); } - $self->{output}->perfdata_add(label => 'volt_' . $instance, unit => 'mV', - value => $result->{raisecomVoltValue}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'volt', unit => 'mV', + nlabel => 'hardware.voltage.volt', + instances => $instance, + value => $result->{raisecomVoltValue}, + warning => $warn, + critical => $crit, + ); } } diff --git a/network/redback/snmp/mode/components/temperature.pm b/network/redback/snmp/mode/components/temperature.pm index 53c2143b9..9b1de5e36 100644 --- a/network/redback/snmp/mode/components/temperature.pm +++ b/network/redback/snmp/mode/components/temperature.pm @@ -60,11 +60,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %sC", $result->{rbnEntityTempDescr}, $result->{rbnEntityTempCurrent})); } - $self->{output}->perfdata_add(label => "temp_" . $instance, unit => 'C', - value => $result->{rbnEntityTempCurrent}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "temp", unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $instance, + value => $result->{rbnEntityTempCurrent}, + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/network/redback/snmp/mode/components/voltage.pm b/network/redback/snmp/mode/components/voltage.pm index 689f5c29f..38395d0ec 100644 --- a/network/redback/snmp/mode/components/voltage.pm +++ b/network/redback/snmp/mode/components/voltage.pm @@ -60,11 +60,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Voltage '%s' is %s mV", $result->{rbnVoltageDescr}, $result->{rbnVoltageCurrent})); } - $self->{output}->perfdata_add(label => "volt_" . $instance, unit => 'mV', - value => $result->{rbnVoltageCurrent}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "volt", unit => 'mV', + nlabel => 'hardware.voltage.millivolt', + instances => $instance, + value => $result->{rbnVoltageCurrent}, + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/network/redback/snmp/mode/disk.pm b/network/redback/snmp/mode/disk.pm index d216a8352..99d682cd0 100644 --- a/network/redback/snmp/mode/disk.pm +++ b/network/redback/snmp/mode/disk.pm @@ -27,22 +27,21 @@ use warnings; sub custom_usage_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -103,10 +102,9 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); return $self; } diff --git a/network/redback/snmp/mode/memory.pm b/network/redback/snmp/mode/memory.pm index 473aa7e99..2d524f79c 100644 --- a/network/redback/snmp/mode/memory.pm +++ b/network/redback/snmp/mode/memory.pm @@ -27,22 +27,21 @@ use warnings; sub custom_usage_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } diff --git a/network/riverbed/interceptor/snmp/mode/neighborconnections.pm b/network/riverbed/interceptor/snmp/mode/neighborconnections.pm new file mode 100644 index 000000000..9ed4794ce --- /dev/null +++ b/network/riverbed/interceptor/snmp/mode/neighborconnections.pm @@ -0,0 +1,125 @@ +# +# Copyright 2019 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::riverbed::interceptor::snmp::mode::neighborconnections; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'neighbor', type => 1, cb_prefix_output => 'prefix_neighbor_output', + message_multiple => 'All neighbor connections count are ok' }, + ]; + + $self->{maps_counters}->{neighbor} = [ + { label => 'connection', set => { + key_values => [ { name => 'neighborConnectionCount' }, { name => 'display' } ], + output_template => 'Optimized Connections Count: %d', + perfdatas => [ + { label => 'connections', value => 'neighborConnectionCount_absolute', template => '%d', min => 0, + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_neighbor_output { + my ($self, %options) = @_; + + return "Neighbor '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + $options{options}->add_options(arguments => { + }); + return $self; +} + +my $mappings = { + int => { + neighborName => { oid => '.1.3.6.1.4.1.17163.1.3.2.6.1.3' }, + neighborConnectionCount => { oid => '.1.3.6.1.4.1.17163.1.3.2.6.1.4' }, + }, +}; + +my $oids = { + int => '.1.3.6.1.4.1.17163.1.3.2.6', +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oids->{int}, + start => $mappings->{int}->{neighborName}->{oid}, + end => $mappings->{int}->{neighborConnectionCount}->{oid} } + ] + ); + + foreach my $equipment (keys %{$oids}) { + next if (!%{$results->{$oids->{$equipment}}}); + foreach my $oid (keys %{$results->{$oids->{$equipment}}}) { + next if ($oid !~ /^$mappings->{$equipment}->{neighborName}->{oid}\.(\d+)/); + my $instance = $1; + + my $result = $options{snmp}->map_instance(mapping => $mappings->{$equipment}, + results => $results->{$oids->{$equipment}}, instance => $instance); + + $self->{neighbor}->{$result->{neighborName}} = { + display => $result->{neighborName}, + neighborConnectionCount => $result->{neighborConnectionCount} + }; + } + } +} + +1; + +__END__ + +=head1 MODE + +Check neighbor optimized connections count. + +=over 8 + +=item B<--warning-connection> + +Threshold warning. + +=item B<--critical-connection> + +Threshold critical. + +=back + +=cut diff --git a/network/riverbed/interceptor/snmp/plugin.pm b/network/riverbed/interceptor/snmp/plugin.pm new file mode 100644 index 000000000..560c12d70 --- /dev/null +++ b/network/riverbed/interceptor/snmp/plugin.pm @@ -0,0 +1,60 @@ +# +# Copyright 2019 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::riverbed::interceptor::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} = '0.1'; + + %{$self->{modes}} = ( + 'cpu' => 'snmp_standard::mode::cpu', + 'cpu-detailed' => 'snmp_standard::mode::cpudetailed', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'load' => 'snmp_standard::mode::loadaverage', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-storages' => 'snmp_standard::mode::liststorages', + 'memory' => 'snmp_standard::mode::memory', + 'neighbor-connections' => 'network::riverbed::interceptor::snmp::mode::neighborconnections', + 'status' => 'centreon::common::riverbed::steelhead::snmp::mode::status', + 'storage' => 'snmp_standard::mode::storage', + 'uptime' => 'snmp_standard::mode::uptime', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Riverbed SteelHead Interceptor using SNMP. + +=cut \ No newline at end of file diff --git a/network/riverbed/steelhead/snmp/mode/diskutilization.pm b/network/riverbed/steelhead/snmp/mode/diskutilization.pm deleted file mode 100644 index b978a1fc0..000000000 --- a/network/riverbed/steelhead/snmp/mode/diskutilization.pm +++ /dev/null @@ -1,106 +0,0 @@ -# -# Copyright 2019 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::riverbed::steelhead::snmp::mode::diskutilization; - -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} = '0.1'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - }); - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - # STEELHEAD-MIB - my $oid_dsAveDiskUtilization = '.1.3.6.1.4.1.17163.1.1.5.4.4.0'; # in % - # STEELHEAD-EX-MIB - my $oid_ex_dsAveDiskUtilization = '.1.3.6.1.4.1.17163.1.51.5.4.4.0'; # in % - - my $result = $self->{snmp}->get_leef(oids => [$oid_dsAveDiskUtilization, $oid_ex_dsAveDiskUtilization], nothing_quit => 1); - my $disk_usage = defined($result->{$oid_dsAveDiskUtilization}) ? $result->{$oid_dsAveDiskUtilization} : $result->{$oid_ex_dsAveDiskUtilization}; - - my $exit = $self->{perfdata}->threshold_check(value => $disk_usage, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Datastore usage: %d %%", - $disk_usage)); - - $self->{output}->perfdata_add(label => "used", unit => '%', - value => $disk_usage, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0, max => 100 - ); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Average disk utilization, a more accurate measurement of the underlying disk activities, -and correlates directly to disk pressure (STEELHEAD-MIB & STEELHEAD-EX-MIB). - -=over 8 - -=item B<--warning> - -Threshold warning in %. - -=item B<--critical> - -Threshold critical in %. - -=back - -=cut diff --git a/network/riverbed/steelhead/snmp/mode/health.pm b/network/riverbed/steelhead/snmp/mode/health.pm deleted file mode 100644 index e365adc56..000000000 --- a/network/riverbed/steelhead/snmp/mode/health.pm +++ /dev/null @@ -1,126 +0,0 @@ -# -# Copyright 2019 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::riverbed::steelhead::snmp::mode::health; - -use base qw(centreon::plugins::templates::counter); - -use strict; -use warnings; -use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); - -sub custom_status_output { - my ($self, %options) = @_; - my $msg = "System health: '" . $self->{result_values}->{state} . "' "; - return $msg; -} - -sub custom_status_calc { - my ($self, %options) = @_; - $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; - return 0; -} - -sub set_counters { - my ($self, %options) = @_; - - $self->{maps_counters_type} = [ - { name => 'health', type => 0 }, - ]; - $self->{maps_counters}->{health} = [ - { label => 'status', threshold => 0, set => { - key_values => [ { name => 'state' } ], - 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 => \&catalog_status_threshold, - } - }, - ]; -} - -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 => '%{state} =~ /degraded/' }, - "critical-status:s" => { name => 'critical_status', default => '%{state} =~ /(critical|admission)/' }, - }); - - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $self->change_macros(macros => ['warning_status', 'critical_status'); -} - -my %map_status = ( - 10000 => 'healthy', - 30000 => 'degraded', - 31000 => 'admissionControl', - 50000 => 'critical', -); - -sub manage_selection { - my ($self, %options) = @_; - - $self->{health} = {}; - - # STEELHEAD-MIB - my $oid_optSystemHealth = '.1.3.6.1.4.1.17163.1.1.2.7.0'; - # STEELHEAD-EX-MIB - my $oid_ex_optSystemHealth = '.1.3.6.1.4.1.17163.1.51.2.7.0'; - - my $result = $options{snmp}->get_leef(oids => [ $oid_optSystemHealth, $oid_ex_optSystemHealth ], nothing_quit => 1); - my $status = defined($result->{$oid_optSystemHealth}) ? $result->{$oid_optSystemHealth} : $result->{$oid_ex_optSystemHealth} ; - - $self->{health} = { state => $map_status{$status} }; -} - -1; - -__END__ - -=head1 MODE - -Check the global system health (STEELHEAD-MIB and STEELHEAD-EX-MIB). - -=over 8 - -=item B<--warning-status> - -Set warning threshold for status (Default: '%{state} =~ /degraded/'). -Special var is %{state} - -=item B<--critical-status> - -Set critical threshold for status (Default: '%{state} !~ /(critical|admission)/'). -Special var is %{state} - -=back - -=cut diff --git a/network/riverbed/steelhead/snmp/mode/loadaverage.pm b/network/riverbed/steelhead/snmp/mode/loadaverage.pm deleted file mode 100644 index 58ead79e2..000000000 --- a/network/riverbed/steelhead/snmp/mode/loadaverage.pm +++ /dev/null @@ -1,169 +0,0 @@ -# -# Copyright 2019 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. -# - -# -# Copyright 2019 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::riverbed::steelhead::snmp::mode::loadaverage; - -use base qw(centreon::plugins::templates::counter); - -use strict; -use warnings; - -sub set_counters { - my ($self, %options) = @_; - - $self->{maps_counters_type} = [ - { name => 'load', type => 0, cb_prefix_output => 'prefix_load_output' }, - ]; - - $self->{maps_counters}->{load} = [ - { label => 'average', set => { - key_values => [ { name => 'cpuUtil1' } ], - output_template => 'average: %d%%', - perfdatas => [ - { label => 'total_cpu_avg', value => 'cpuUtil1_absolute', template => '%d', - min => 0, max => 100, unit => '%' }, - ], - } - }, - { label => '1min', set => { - key_values => [ { name => 'cpuLoad1' } ], - output_template => '1 min: %d%%', - perfdatas => [ - { label => 'load1', value => 'cpuLoad1_absolute', template => '%d', - min => 0, max => 100, unit => '%' }, - ], - } - }, - { label => '5min', set => { - key_values => [ { name => 'cpuLoad5' } ], - output_template => '5 min: %d%%', - perfdatas => [ - { label => 'load5', value => 'cpuLoad5_absolute', template => '%d', - min => 0, max => 100, unit => "%" }, - ], - } - }, - { label => '15min', set => { - key_values => [ { name => 'cpuLoad15' } ], - output_template => '15 min: %d%%', - perfdatas => [ - { label => 'load15', value => 'cpuLoad15_absolute', template => '%d', - min => 0, max => 100, unit => '%' }, - ], - } - }, - ]; -} - -sub prefix_load_output { - my ($self, %options) = @_; - - return "Load "; -} - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; - - $self->{version} = '0.1'; - $options{options}->add_options(arguments => - { - }); - return $self; -} - -sub manage_selection { - my ($self, %options) = @_; - - # STEELHEAD-MIB - my $oids = { - cpuLoad1 => '.1.3.6.1.4.1.17163.1.1.5.1.1.0', - cpuLoad5 => '.1.3.6.1.4.1.17163.1.1.5.1.2.0', - cpuLoad15 => '.1.3.6.1.4.1.17163.1.1.5.1.3.0', - cpuUtil1 => '.1.3.6.1.4.1.17163.1.1.5.1.4.0', - }; - - # STEELHEAD-EX-MIB - my $oids_ex = { - cpuLoad1 => '.1.3.6.1.4.1.17163.1.51.5.1.1.0', - cpuLoad5 => '.1.3.6.1.4.1.17163.1.51.5.1.2.0', - cpuLoad15 => '.1.3.6.1.4.1.17163.1.51.5.1.3.0', - cpuUtil1 => '.1.3.6.1.4.1.17163.1.51.5.1.4.0', - }; - - my $snmp_result = $options{snmp}->get_leef(oids => [ values %{$oids}, values %{$oids_ex} ], nothing_quit => 1); - - $self->{load} = {}; - - if (defined($snmp_result->{$oids->{cpuUtil1}})) { - foreach (keys %{$oids}) { - $self->{load}->{$_} = $snmp_result->{$oids->{$_}}; - } - } else { - foreach (keys %{$oids}) { - $self->{load}->{$_} = $snmp_result->{$oids_ex->{$_}}; - } - } -} - -1; - -__END__ - -=head1 MODE - -Check system load-average. - -=over 8 - -=item B<--warning-*> - -Warning thresholds -Can be --warning-(average|1m|5m|15m) - -=item B<--critical-*> - -Critical thresholds -Can be --critical-(average|1m|5m|15m) - -=back - -=cut diff --git a/network/riverbed/steelhead/snmp/mode/servicestatus.pm b/network/riverbed/steelhead/snmp/mode/servicestatus.pm deleted file mode 100644 index e2164deaa..000000000 --- a/network/riverbed/steelhead/snmp/mode/servicestatus.pm +++ /dev/null @@ -1,131 +0,0 @@ -# -# Copyright 2019 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::riverbed::steelhead::snmp::mode::servicestatus; - -use base qw(centreon::plugins::templates::counter); - -use strict; -use warnings; -use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); - -sub custom_status_output { - my ($self, %options) = @_; - my $msg = "Optimization service state: '" . $self->{result_values}->{state} . "' "; - return $msg; -} - -sub custom_status_calc { - my ($self, %options) = @_; - $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; - return 0; -} - -sub set_counters { - my ($self, %options) = @_; - - $self->{maps_counters_type} = [ - { name => 'opt_service', type => 0 }, - ]; - $self->{maps_counters}->{opt_service} = [ - { label => 'status', threshold => 0, set => { - key_values => [ { name => 'state' } ], - 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 => \&catalog_status_threshold, - } - }, - ]; -} - -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 => '%{state} !~ /running/' }, - }); - - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $self->change_macros(macros => ['warning_status', 'critical_status']); -} - -my %map_status = ( - 0 => 'none', - 1 => 'unmanaged', - 2 => 'running', - 3 => 'sentCom1', - 4 => 'sentTerm1', - 5 => 'sentTerm2', - 6 => 'sentTerm3', - 7 => 'pending', - 8 => 'stopped', -); - -sub manage_selection { - my ($self, %options) = @_; - - $self->{opt_service} = {}; - - # STEELHEAD-MIB - my $oid_optServiceStatus = '.1.3.6.1.4.1.17163.1.1.2.8.0'; - # STEELHEAD-EX-MIB - my $oid_ex_optServiceStatus = '.1.3.6.1.4.1.17163.1.51.2.8.0'; - - my $result = $options{snmp}->get_leef(oids => [ $oid_optServiceStatus, $oid_ex_optServiceStatus ], nothing_quit => 1); - my $status = defined($result->{$oid_optServiceStatus}) ? $result->{$oid_optServiceStatus} : $result->{$oid_ex_optServiceStatus} ; - - $self->{opt_service} = { state => $map_status{$status} }; -} - -1; - -__END__ - -=head1 MODE - -Check the current status of the optimization service (STEELHEAD-MIB and STEELHEAD-EX-MIB). - -=over 8 - -=item B<--warning-status> - -Set warning threshold for status (Default: ''). -Special var is %{state} - -=item B<--critical-status> - -Set critical threshold for status (Default: '%{state} !~ /running/'). -Special var is %{state} - -=back - -=cut diff --git a/network/riverbed/steelhead/snmp/mode/serviceuptime.pm b/network/riverbed/steelhead/snmp/mode/serviceuptime.pm deleted file mode 100644 index 0b99825d7..000000000 --- a/network/riverbed/steelhead/snmp/mode/serviceuptime.pm +++ /dev/null @@ -1,110 +0,0 @@ -# -# Copyright 2019 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::riverbed::steelhead::snmp::mode::serviceuptime; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use centreon::plugins::misc; - -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:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - "seconds" => { name => 'seconds', } - }); - - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - # STEELHEAD-MIB - my $oid_serviceUptime = '.1.3.6.1.4.1.17163.1.1.2.4.0'; - # STEELHEAD-EX-MIB - my $oid_ex_serviceUptime = '.1.3.6.1.4.1.17163.1.51.2.4.0'; - - my $result = $self->{snmp}->get_leef(oids => [ $oid_serviceUptime, $oid_ex_serviceUptime ], nothing_quit => 1); - my $value = defined($result->{$oid_serviceUptime}) ? $result->{$oid_serviceUptime} : $result->{$oid_ex_serviceUptime}; - - my $exit_code = $self->{perfdata}->threshold_check(value => sprintf("%d", $value / 100), - threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{output}->perfdata_add(label => 'uptime', unit => 's', - value => sprintf("%d", $value / 100), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); - - $self->{output}->output_add(severity => $exit_code, - short_msg => sprintf("Service uptime is: %s", centreon::plugins::misc::change_seconds(value => $value / 100))); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Uptime of the optimization service (STEELHEAD-MIB and STEELHEAD-EX-MIB). - -=over 8 - -=item B<--warning> - -Threshold warning in seconds. - -=item B<--critical> - -Threshold critical in seconds. - -=item B<--seconds> - -Display uptime in seconds. - -=back - -=cut diff --git a/network/riverbed/steelhead/snmp/mode/temperature.pm b/network/riverbed/steelhead/snmp/mode/temperature.pm deleted file mode 100644 index 163a9377b..000000000 --- a/network/riverbed/steelhead/snmp/mode/temperature.pm +++ /dev/null @@ -1,104 +0,0 @@ -# -# Copyright 2019 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::riverbed::steelhead::snmp::mode::temperature; - -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 => - { - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - }); - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - # STEELHEAD-MIB - my $oid_systemTemperature = '.1.3.6.1.4.1.17163.1.1.2.9.0'; # in Celsius - # STEELHEAD-EX-MIB - my $oid_ex_systemTemperature = '.1.3.6.1.4.1.17163.1.51.2.9.0'; # in Celsius - - my $result = $self->{snmp}->get_leef(oids => [$oid_systemTemperature, $oid_ex_systemTemperature], nothing_quit => 1); - my $temp = defined($result->{$oid_systemTemperature}) ? $result->{$oid_systemTemperature} : $result->{$oid_ex_systemTemperature}; - - my $exit = $self->{perfdata}->threshold_check(value => $temp, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Device Temperature is %d C degrees", - $temp)); - - $self->{output}->perfdata_add(label => "temperature", unit => 'C', - value => $temp, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - ); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check the temperature of the system in Celcius (STEELHEAD-MIB AND STEELHEAD-EX-MIB). - -=over 8 - -=item B<--warning> - -Threshold warning for temperature in Celsius. - -=item B<--critical> - -Threshold critical for temperature in Celsius. - -=back - -=cut diff --git a/network/riverbed/steelhead/snmp/plugin.pm b/network/riverbed/steelhead/snmp/plugin.pm index ef47a9a41..96737822d 100644 --- a/network/riverbed/steelhead/snmp/plugin.pm +++ b/network/riverbed/steelhead/snmp/plugin.pm @@ -30,21 +30,25 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - # Plugin version $self->{version} = '0.1'; - # Modes association %{$self->{modes}} = ( - 'temperature' => 'network::riverbed::steelhead::snmp::mode::temperature', - 'service-uptime' => 'network::riverbed::steelhead::snmp::mode::serviceuptime', - 'health' => 'network::riverbed::steelhead::snmp::mode::health', - 'service-status' => 'network::riverbed::steelhead::snmp::mode::servicestatus', - 'load-average' => 'network::riverbed::steelhead::snmp::mode::loadaverage', - 'bandwidth-passthrough' => 'network::riverbed::steelhead::snmp::mode::bwpassthrough', - 'bandwidth-optimization' => 'network::riverbed::steelhead::snmp::mode::bwoptimization', - 'disk-utilization' => 'network::riverbed::steelhead::snmp::mode::diskutilization', - 'connections' => 'network::riverbed::steelhead::snmp::mode::connections', - ); + 'bandwidth-optimization' => 'centreon::common::riverbed::steelhead::snmp::mode::bwoptimization', + 'bandwidth-passthrough' => 'centreon::common::riverbed::steelhead::snmp::mode::bwpassthrough', + 'connections' => 'centreon::common::riverbed::steelhead::snmp::mode::connections', + 'cpu' => 'snmp_standard::mode::cpu', + 'cpu-detailed' => 'snmp_standard::mode::cpudetailed', + 'disk-utilization' => 'centreon::common::riverbed::steelhead::snmp::mode::diskutilization', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-storages' => 'snmp_standard::mode::liststorages', + 'load-average' => 'centreon::common::riverbed::steelhead::snmp::mode::loadaverage', + 'memory' => 'snmp_standard::mode::memory', + 'status' => 'centreon::common::riverbed::steelhead::snmp::mode::status', + 'storage' => 'snmp_standard::mode::storage', + 'temperature' => 'centreon::common::riverbed::steelhead::snmp::mode::temperature', + 'uptime' => 'snmp_standard::mode::uptime', + ); return $self; } diff --git a/network/ruggedcom/mode/temperature.pm b/network/ruggedcom/mode/temperature.pm index bfddf5f42..76b33e03d 100644 --- a/network/ruggedcom/mode/temperature.pm +++ b/network/ruggedcom/mode/temperature.pm @@ -24,7 +24,6 @@ use base qw(centreon::plugins::mode); use strict; use warnings; -use Data::Dumper; sub new { my ($class, %options) = @_; diff --git a/network/sonicwall/snmp/plugin.pm b/network/sonicwall/snmp/plugin.pm index dabe71517..89167cc5f 100644 --- a/network/sonicwall/snmp/plugin.pm +++ b/network/sonicwall/snmp/plugin.pm @@ -31,11 +31,13 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'cpu' => 'network::sonicwall::snmp::mode::cpu', - 'memory' => 'network::sonicwall::snmp::mode::memory', - 'connections' => 'network::sonicwall::snmp::mode::connections', - 'vpn' => 'network::sonicwall::snmp::mode::vpn', - ); + 'connections' => 'network::sonicwall::snmp::mode::connections', + 'cpu' => 'network::sonicwall::snmp::mode::cpu', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::sonicwall::snmp::mode::memory', + 'vpn' => 'network::sonicwall::snmp::mode::vpn', + ); return $self; } diff --git a/network/stonesoft/snmp/mode/connections.pm b/network/stonesoft/snmp/mode/connections.pm index 7f45c9a38..5d88a85d1 100644 --- a/network/stonesoft/snmp/mode/connections.pm +++ b/network/stonesoft/snmp/mode/connections.pm @@ -20,147 +20,71 @@ package network::stonesoft::snmp::mode::connections; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -use centreon::plugins::statefile; +use Digest::MD5 qw(md5_hex); -my $maps_counters = { - '000_connections' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'fwConnNumber', diff => 1 }, - ], - output_template => 'Connections : %s', - perfdatas => [ - { label => 'connections', value => 'fwConnNumber_absolute', template => '%s', - unit => 'con', min => 0 }, - ], - } - }, - '001_rate-connections' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'fwConnNumber', diff => 1 }, - ], - per_second => 1, - output_template => 'Rate Connections : %.2f /s', - perfdatas => [ - { label => 'rate_connections', value => 'fwConnNumber_per_second', template => '%.2f', - unit => 'con/s', min => 0 }, - ], - } - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'connections', nlabel => 'connections.total.count', set => { + key_values => [ { name => 'fwConnNumber', diff => 1 } ], + output_template => 'Connections : %s', + perfdatas => [ + { label => 'connections', value => 'fwConnNumber_absolute', template => '%s', + unit => 'con', min => 0 }, + ], + } + }, + { label => 'rate-connections', nlabel => 'connections.total.persecond', set => { + key_values => [ { name => 'fwConnNumber', diff => 1 } ], + per_second => 1, + output_template => 'Rate Connections : %.2f /s', + perfdatas => [ + { label => 'rate_connections', value => 'fwConnNumber_per_second', template => '%.2f', + unit => 'con/s', min => 0 }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); + $options{options}->add_options(arguments => { + }); - foreach (keys %{$maps_counters}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$_}->{threshold}) || $maps_counters->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - if ($self->{snmp}->is_snmpv1()) { - $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); - $self->{output}->option_exit(); - } - - $self->manage_selection(); - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "stonesoft_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode}); - $self->{new_datas}->{last_timestamp} = time(); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => 'global'); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{global}, - new_datas => $self->{new_datas}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{$_}->{obj}->perfdata(); - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "$short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "$long_msg"); - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; + if ($options{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); + $self->{output}->option_exit(); + } + my $oid_fwConnNumber = '.1.3.6.1.4.1.1369.5.2.1.4.0'; - $self->{results} = $self->{snmp}->get_leef(oids => [$oid_fwConnNumber], - nothing_quit => 1); - $self->{global} = { fwConnNumber => $self->{results}->{$oid_fwConnNumber} }; + my $snmp_result = $options{snmp}->get_leef( + oids => [$oid_fwConnNumber], + nothing_quit => 1 + ); + $self->{global} = { fwConnNumber => $snmp_result->{$oid_fwConnNumber} }; + + $self->{cache_name} = "stonesoft_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; diff --git a/network/stonesoft/snmp/mode/memory.pm b/network/stonesoft/snmp/mode/memory.pm index 19f8fc5b4..ddf6689fa 100644 --- a/network/stonesoft/snmp/mode/memory.pm +++ b/network/stonesoft/snmp/mode/memory.pm @@ -24,7 +24,6 @@ use base qw(centreon::plugins::mode); use strict; use warnings; -use Data::Dumper; sub new { my ($class, %options) = @_; diff --git a/network/stormshield/local/mode/qosusage.pm b/network/stormshield/local/mode/qosusage.pm index eb2b8d768..1144270ba 100644 --- a/network/stormshield/local/mode/qosusage.pm +++ b/network/stormshield/local/mode/qosusage.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -76,36 +74,34 @@ sub set_counters { sub custom_qos_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}); + if ($self->{instance_mode}->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); + } elsif ($self->{instance_mode}->{option_results}->{units_traffic} eq 'b/s') { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}); } - $self->{output}->perfdata_add(label => 'traffic_' . $self->{result_values}->{label} . $extra_label, unit => 'b/s', - value => sprintf("%.2f", $self->{result_values}->{traffic}), - warning => $warning, - critical => $critical, - min => 0, max => $self->{result_values}->{speed}); + $self->{output}->perfdata_add( + label => 'traffic_' . $self->{result_values}->{label}, unit => 'b/s', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{traffic}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed} + ); } sub custom_qos_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}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + if ($self->{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->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); + } elsif ($self->{instance_mode}->{option_results}->{units_traffic} eq 'b/s') { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } return $exit; } @@ -135,9 +131,9 @@ sub custom_qos_calc { if ($options{new_datas}->{$self->{instance} . '_speed_' . $self->{result_values}->{label}} > 0) { $self->{result_values}->{speed} = $options{new_datas}->{$self->{instance} . '_speed_' . $self->{result_values}->{label}} * 1000 * 1000; $self->{result_values}->{traffic_prct} = $self->{result_values}->{traffic} * 100 / $self->{result_values}->{speed}; - } elsif (defined($instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}}) && $instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} =~ /[0-9]/) { - $self->{result_values}->{traffic_prct} = $self->{result_values}->{traffic} * 100 / ($instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000); - $self->{result_values}->{speed} = $instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000; + } elsif (defined($self->{instance_mode}->{option_results}->{'speed_' . $self->{result_values}->{label}}) && $self->{instance_mode}->{option_results}->{'speed_' . $self->{result_values}->{label}} =~ /[0-9]/) { + $self->{result_values}->{traffic_prct} = $self->{result_values}->{traffic} * 100 / ($self->{instance_mode}->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000); + $self->{result_values}->{speed} = $self->{instance_mode}->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000; } return 0; } @@ -148,25 +144,24 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "filter-vlan:s" => { name => 'filter_vlan' }, - "speed-in:s" => { name => 'speed_in' }, - "speed-out:s" => { name => 'speed_out' }, - "units-traffic:s" => { name => 'units_traffic', default => '%' }, - "hostname:s" => { name => 'hostname' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'tail' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '-1 /log/l_monitor' }, - "config-speed-file:s" => { name => 'config_speed_file' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "filter-vlan:s" => { name => 'filter_vlan' }, + "speed-in:s" => { name => 'speed_in' }, + "speed-out:s" => { name => 'speed_out' }, + "units-traffic:s" => { name => 'units_traffic', default => '%' }, + "hostname:s" => { name => 'hostname' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'tail' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-1 /log/l_monitor' }, + "config-speed-file:s" => { name => 'config_speed_file' }, + }); + return $self; } @@ -180,9 +175,7 @@ sub check_options { $self->{hostname} = $self->{option_results}->{hostname}; if (!defined($self->{hostname})) { $self->{hostname} = 'me'; - } - - $instance_mode = $self; + } } sub prefix_qos_output { diff --git a/network/stormshield/snmp/mode/vpnstatus.pm b/network/stormshield/snmp/mode/vpnstatus.pm index 7e6f81139..3c9c47860 100644 --- a/network/stormshield/snmp/mode/vpnstatus.pm +++ b/network/stormshield/snmp/mode/vpnstatus.pm @@ -20,53 +20,16 @@ package network::stormshield::snmp::mode::vpnstatus; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); -my $thresholds = { - vpn => [ - ['larval', 'WARNING'], - ['mature', 'OK'], - ['dying', 'CRITICAL'], - ['dead', 'CRITICAL'], - ], -}; -my $instance_mode; - -my $maps_counters = { - vpn => { - '000_status' => { set => { - key_values => [ { name => 'ntqVPNState' } ], - closure_custom_calc => \&custom_status_calc, - output_template => 'Status : %s', output_error_template => 'Status : %s', - output_use => 'ntqVPNState', - closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&custom_threshold_output, - } - }, - '001_traffic' => { set => { - key_values => [ { name => 'ntqVPNBytes', diff => 1 }, { name => 'num' } ], - per_second => 1, output_change_bytes => 2, - output_template => 'Traffic: %s %s/s', - perfdatas => [ - { label => 'traffic', value => 'ntqVPNBytes_per_second', template => '%s', - unit => 'b/s', min => 0, label_extra_instance => 1, cast_int => 1, instance_use => 'num_absolute' }, - ], - } - }, - }, -}; - - sub custom_threshold_output { my ($self, %options) = @_; - return $instance_mode->get_severity(section => 'vpn', value => $self->{result_values}->{ntqVPNState}); + return $self->{instance_mode}->get_severity(section => 'vpn', value => $self->{result_values}->{ntqVPNState}); } sub custom_status_calc { @@ -76,54 +39,71 @@ sub custom_status_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'vpn', type => 1, cb_prefix_output => 'prefix_vpn_output', message_multiple => 'All vpn are ok' } + ]; + + $self->{maps_counters}->{vpn} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'ntqVPNState' } ], + closure_custom_calc => $self->can('custom_status_calc'), + output_template => 'status: %s', output_error_template => 'Status : %s', + output_use => 'ntqVPNState', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_threshold_output'), + } + }, + { label => 'traffic', nlabel => 'vpn.traffic.bitspersecond', set => { + key_values => [ { name => 'ntqVPNBytes', diff => 1 }, { name => 'num' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'traffic: %s %s/s', + perfdatas => [ + { label => 'traffic', value => 'ntqVPNBytes_per_second', template => '%s', + unit => 'b/s', min => 0, label_extra_instance => 1, cast_int => 1, instance_use => 'num_absolute' }, + ], + } + }, + ]; +} + +sub prefix_vpn_output { + my ($self, %options) = @_; + + return "VPN '$options{instance_value}->{num}/$options{instance_value}->{ntqVPNIPSrc}/$options{instance_value}->{ntqVPNIPDst}' "; +} + +my $thresholds = { + vpn => [ + ['larval', 'WARNING'], + ['mature', 'OK'], + ['dying', 'CRITICAL'], + ['dead', 'CRITICAL'], + ], +}; + sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-id:s" => { name => 'filter_id' }, - "filter-src-ip:s" => { name => 'filter_src_ip' }, - "filter-dst-ip:s" => { name => 'filter_dst_ip' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - }); + $options{options}->add_options(arguments => { + "filter-id:s" => { name => 'filter_id' }, + "filter-src-ip:s" => { name => 'filter_src_ip' }, + "filter-dst-ip:s" => { name => 'filter_dst_ip' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - - foreach my $key (('vpn')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('vpn')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - $instance_mode = $self; - $self->{statefile_value}->check_options(%options); - + $self->SUPER::check_options(%options); + $self->{overload_th} = {}; foreach my $val (@{$self->{option_results}->{threshold_overload}}) { if ($val !~ /^(.*?),(.*?),(.*)$/) { @@ -140,80 +120,6 @@ sub check_options { } } -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{vpn}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All VPN are ok'); - } - - my $matching = ''; - foreach (('filter_id', 'filter_src_ip', 'filter_dst_ip')) { - $matching .= defined($self->{option_results}->{$_}) ? $self->{option_results}->{$_} : 'all'; - } - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "stormshield_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode} . '_' . md5_hex($matching)); - $self->{new_datas}->{last_timestamp} = time(); - - foreach my $id (sort keys %{$self->{vpn}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{vpn}}) { - my $obj = $maps_counters->{vpn}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{vpn}->{$id}, - new_datas => $self->{new_datas}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{vpn}->{$_}->{obj}->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "VPN '$self->{vpn}->{$id}->{num}/$self->{vpn}->{$id}->{ntqVPNIPSrc}/$self->{vpn}->{$id}->{ntqVPNIPDst}' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "VPN '$self->{vpn}->{$id}->{num}/$self->{vpn}->{$id}->{ntqVPNIPSrc}/$self->{vpn}->{$id}->{ntqVPNIPDst}' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "VPN '$self->{vpn}->{$id}->{num}/$self->{vpn}->{$id}->{ntqVPNIPSrc}/$self->{vpn}->{$id}->{ntqVPNIPDst}' $long_msg"); - } - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - sub get_severity { my ($self, %options) = @_; my $status = 'UNKNOWN'; # default @@ -244,61 +150,60 @@ my %map_state = ( ); my $mapping = { ntqVPNIPSrc => { oid => '.1.3.6.1.4.1.11256.1.1.1.1.2' }, -}; -my $mapping2 = { ntqVPNIPDst => { oid => '.1.3.6.1.4.1.11256.1.1.1.1.3' }, -}; -my $mapping3 = { ntqVPNState => { oid => '.1.3.6.1.4.1.11256.1.1.1.1.11', map => \%map_state }, -}; -my $mapping4 = { ntqVPNBytes => { oid => '.1.3.6.1.4.1.11256.1.1.1.1.13' }, }; sub manage_selection { my ($self, %options) = @_; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $mapping->{ntqVPNIPSrc}->{oid} }, - { oid => $mapping2->{ntqVPNIPDst}->{oid} }, - { oid => $mapping3->{ntqVPNState}->{oid} }, - { oid => $mapping4->{ntqVPNBytes}->{oid} }, - ], - , nothing_quit => 1); - + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $mapping->{ntqVPNIPSrc}->{oid} }, + { oid => $mapping->{ntqVPNIPDst}->{oid} }, + { oid => $mapping->{ntqVPNState}->{oid} }, + { oid => $mapping->{ntqVPNBytes}->{oid} }, + ], + return_type => 1, nothing_quit => 1 + ); + $self->{vpn} = {}; - foreach my $oid (keys %{$self->{results}->{$mapping3->{ntqVPNState}->{oid}}}) { - next if ($oid !~ /^$mapping3->{ntqVPNState}->{oid}\.(.*)$/); + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{ntqVPNState}->{oid}\.(.*)$/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{ntqVPNIPSrc}->{oid}}, instance => $instance); - my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{ntqVPNIPDst}->{oid}}, instance => $instance); - my $result3 = $self->{snmp}->map_instance(mapping => $mapping3, results => $self->{results}->{$mapping3->{ntqVPNState}->{oid}}, instance => $instance); - my $result4 = $self->{snmp}->map_instance(mapping => $mapping4, results => $self->{results}->{$mapping4->{ntqVPNBytes}->{oid}}, instance => $instance); - + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + if (defined($self->{option_results}->{filter_id}) && $self->{option_results}->{filter_id} ne '' && $instance !~ /$self->{option_results}->{filter_id}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $instance . "': no matching filter id."); + $self->{output}->output_add(long_msg => "skipping '" . $instance . "': no matching filter id."); next; } if (defined($self->{option_results}->{filter_src_ip}) && $self->{option_results}->{filter_src_ip} ne '' && $result->{ntqVPNIPSrc} !~ /$self->{option_results}->{filter_src_ip}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $result->{ntqVPNIPSrc} . "': no matching filter src-ip."); + $self->{output}->output_add(long_msg => "skipping '" . $result->{ntqVPNIPSrc} . "': no matching filter src-ip."); next; } if (defined($self->{option_results}->{filter_dst_ip}) && $self->{option_results}->{filter_dst_ip} ne '' && - $result2->{ntqVPNIPDst} !~ /$self->{option_results}->{filter_dst_ip}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $result2->{ntqVPNIPDst} . "': no matching filter dst-ip."); + $result->{ntqVPNIPDst} !~ /$self->{option_results}->{filter_dst_ip}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{ntqVPNIPDst} . "': no matching filter dst-ip."); next; } - $self->{vpn}->{$instance} = { num => $instance, %$result, %$result2, %$result3, %$result4}; + $self->{vpn}->{$instance} = { num => $instance, %$result }; $self->{vpn}->{$instance}->{ntqVPNBytes} *= 8 if (defined($self->{vpn}->{$instance}->{ntqVPNBytes})); } if (scalar(keys %{$self->{vpn}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No entry found."); + $self->{output}->add_option_msg(short_msg => "No vpn found."); $self->{output}->option_exit(); } + + $self->{cache_name} = "stormshield_" . $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')) . '_' . + (defined($self->{option_results}->{filter_id}) ? md5_hex($self->{option_results}->{filter_id}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_src_ip}) ? md5_hex($self->{option_results}->{filter_src_ip}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_dst_ip}) ? md5_hex($self->{option_results}->{filter_dst_ip}) : md5_hex('all')); } 1; diff --git a/notification/foxbox/mode/alert.pm b/notification/foxbox/mode/alert.pm index a883ec499..38749a61d 100644 --- a/notification/foxbox/mode/alert.pm +++ b/notification/foxbox/mode/alert.pm @@ -32,21 +32,19 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options( - arguments => { - "foxbox-username:s" => { name => 'foxbox_username', default => 'centreon' }, - "foxbox-password:s" => { name => 'foxbox_password' }, - "from:s" => { name => 'from', default => 'centreon' }, - "proto:s" => { name => 'proto', default => 'http' }, - "urlpath:s" => { name => 'url_path', default => '/source/send_sms.php' }, - "phonenumber:s" => { name => 'phonenumber' }, - "hostname:s" => { name => 'hostname' }, - "texto:s" => { name => 'texto' }, - "timeout:s" => { name => 'timeout', default => 10 }, - } - ); + $options{options}->add_options(arguments => { + "foxbox-username:s" => { name => 'foxbox_username', default => 'centreon' }, + "foxbox-password:s" => { name => 'foxbox_password' }, + "from:s" => { name => 'from', default => 'centreon' }, + "proto:s" => { name => 'proto', default => 'http' }, + "urlpath:s" => { name => 'url_path', default => '/source/send_sms.php' }, + "phonenumber:s" => { name => 'phonenumber' }, + "hostname:s" => { name => 'hostname' }, + "texto:s" => { name => 'texto' }, + "timeout:s" => { name => 'timeout', default => 10 }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } diff --git a/notification/highsms/mode/alert.pm b/notification/highsms/mode/alert.pm index 7ecf3deb2..34f5389c1 100644 --- a/notification/highsms/mode/alert.pm +++ b/notification/highsms/mode/alert.pm @@ -33,23 +33,19 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => 443 }, - "proto:s" => { name => 'proto', default => 'https' }, - "proxyurl:s" => { name => 'proxyurl' }, - "proxypac:s" => { name => 'proxypac' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "phonenumber:s" => { name => 'phonenumber' }, - "message:s" => { name => 'message' }, - "sender:s" => { name => 'sender', default => 'API_HIGHSMS' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', default => 443 }, + "proto:s" => { name => 'proto', default => 'https' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + "phonenumber:s" => { name => 'phonenumber' }, + "message:s" => { name => 'message' }, + "sender:s" => { name => 'sender', default => 'API_HIGHSMS' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -133,14 +129,6 @@ Port used by HighSMS API. (Default: 443) Specify http or https protocol. (Default: https) -=item B<--proxyurl> - -Proxy URL - -=item B<--proxypac> - -Proxy pac file (can be an url or local file) - =item B<--username> Specify username for API authentification. @@ -153,10 +141,6 @@ Specify password for API authentification. Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--phonenumber> Specify phone number. diff --git a/notification/ovhsms/mode/alert.pm b/notification/ovhsms/mode/alert.pm index fce312a7e..8ac832aba 100644 --- a/notification/ovhsms/mode/alert.pm +++ b/notification/ovhsms/mode/alert.pm @@ -33,28 +33,24 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname', default => 'www.ovh.com' }, - "port:s" => { name => 'port', default => 443 }, - "proto:s" => { name => 'proto', default => 'https' }, - "urlpath:s" => { name => 'url_path', default => "/cgi-bin/sms/http2sms.cgi" }, - "account:s" => { name => 'account' }, - "login:s" => { name => 'login' }, - "password:s" => { name => 'password' }, - "from:s" => { name => 'from'}, - "to:s" => { name => 'to' }, - "message:s" => { name => 'message' }, - "class:s" => { name => 'class', default => 1 }, - "nostop:s" => { name => 'nostop', default => 1 }, - "smscoding:s" => { name => 'smscoding', default => 1 }, - "proxyurl:s" => { name => 'proxyurl' }, - "proxypac:s" => { name => 'proxypac' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname', default => 'www.ovh.com' }, + "port:s" => { name => 'port', default => 443 }, + "proto:s" => { name => 'proto', default => 'https' }, + "urlpath:s" => { name => 'url_path', default => "/cgi-bin/sms/http2sms.cgi" }, + "account:s" => { name => 'account' }, + "login:s" => { name => 'login' }, + "password:s" => { name => 'password' }, + "from:s" => { name => 'from'}, + "to:s" => { name => 'to' }, + "message:s" => { name => 'message' }, + "class:s" => { name => 'class', default => 1 }, + "nostop:s" => { name => 'nostop', default => 1 }, + "smscoding:s" => { name => 'smscoding', default => 1 }, + "timeout:s" => { name => 'timeout' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -157,14 +153,6 @@ Specify https if needed (Default: 'https'). Set path to the SMS API (Default: '/cgi-bin/sms/http2sms.cgi'). -=item B<--proxyurl> - -Proxy URL if any. - -=item B<--proxypac> - -Proxy pac file (can be an url or local file). - =item B<--account> Specify SMS Account for API authentification. @@ -205,10 +193,6 @@ Specify the coding of message. (Default : '1'). Threshold for HTTP timeout -=item B<--ssl-opt> - -Set SSL options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =cut diff --git a/notification/slack/mode/alert.pm b/notification/slack/mode/alert.pm index 49b70cf76..aa1266ecc 100644 --- a/notification/slack/mode/alert.pm +++ b/notification/slack/mode/alert.pm @@ -45,36 +45,32 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "slack-url:s" => { name => 'slack_url' }, - "slack-channel:s" => { name => 'slack_channel' }, - "slack-username:s" => { name => 'slack_username' }, - "host-name:s" => { name => 'host_name' }, - "host-state:s" => { name => 'host_state' }, - "host-output:s" => { name => 'host_output' }, - "service-description:s" => { name => 'service_description' }, - "service-state:s" => { name => 'service_state' }, - "service-output:s" => { name => 'service_output' }, - "slack-color:s" => { name => 'slack_color' }, - "slack-emoji:s" => { name => 'slack_emoji', }, - "graph-url:s" => { name => 'graph_url' }, - "priority:s" => { name => 'priority' }, - "zone:s" => { name => 'zone' }, - "link-url:s" => { name => 'link_url' }, - "centreon-url:s" => { name => 'centreon_url' }, - "centreon-token:s" => { name => 'centreon_token' }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "ntlm" => { name => 'ntlm' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "proxypac:s" => { name => 'proxypac' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $options{options}->add_options(arguments => { + "slack-url:s" => { name => 'slack_url' }, + "slack-channel:s" => { name => 'slack_channel' }, + "slack-username:s" => { name => 'slack_username' }, + "host-name:s" => { name => 'host_name' }, + "host-state:s" => { name => 'host_state' }, + "host-output:s" => { name => 'host_output' }, + "service-description:s" => { name => 'service_description' }, + "service-state:s" => { name => 'service_state' }, + "service-output:s" => { name => 'service_output' }, + "slack-color:s" => { name => 'slack_color' }, + "slack-emoji:s" => { name => 'slack_emoji', }, + "graph-url:s" => { name => 'graph_url' }, + "priority:s" => { name => 'priority' }, + "zone:s" => { name => 'zone' }, + "link-url:s" => { name => 'link_url' }, + "centreon-url:s" => { name => 'centreon_url' }, + "centreon-token:s" => { name => 'centreon_token' }, + "credentials" => { name => 'credentials' }, + "basic" => { name => 'basic' }, + "ntlm" => { name => 'ntlm' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + }); + $self->{http} = centreon::plugins::http->new(%options); $self->{payload_attachment} = { fields => [] }; return $self; @@ -132,9 +128,9 @@ sub host_message { my ($self, %options) = @_; my $url_host = $self->{option_results}->{host_name}; + $self->{payload_attachment}->{fallback} = "Host " . $self->{option_results}->{host_name}; if (defined($self->{option_results}->{link_url}) && $self->{option_results}->{link_url} ne '') { $url_host = '<' . $self->{option_results}->{link_url} . '|' . $self->{option_results}->{host_name} . '>'; - $self->{payload_attachment}->{fallback} = "Host " . $self->{option_results}->{host_name}; } $self->{payload_attachment}->{text} = "Host " . $url_host; @@ -318,14 +314,6 @@ Specify the graph url (Example: %{centreon_url}/include/views/graphs/generateGra Specify the link url (Example: %{centreon_url}/main.php?p=20201&o=svc&host_search=%{host_name}&svc_search=%{service_description}) -=item B<--proxyurl> - -Proxy URL - -=item B<--proxypac> - -Proxy pac file (can be an url or local file) - =item B<--credentials> Specify this option if you access webpage with authentication @@ -350,10 +338,6 @@ Specify this option if you access webpage over hidden basic authentication or yo Threshold for HTTP timeout (Default: 5) -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =cut diff --git a/notification/telegram/mode/alert.pm b/notification/telegram/mode/alert.pm index fa241daf4..996991ec3 100644 --- a/notification/telegram/mode/alert.pm +++ b/notification/telegram/mode/alert.pm @@ -45,31 +45,27 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname', default => 'api.telegram.org' }, - "port:s" => { name => 'port', default => 443 }, - "proto:s" => { name => 'proto', default => 'https' }, - "urlpath:s" => { name => 'url_path', default => "/sendMessage" }, - "chat-id:s" => { name => 'chat_id' }, - "bot-token:s" => { name => 'bot_token' }, - "host-name:s" => { name => 'host_name' }, - "host-state:s" => { name => 'host_state' }, - "host-output:s" => { name => 'host_output' }, - "service-description:s" => { name => 'service_description' }, - "service-state:s" => { name => 'service_state' }, - "service-output:s" => { name => 'service_output' }, - "graph-url:s" => { name => 'graph_url' }, - "link-url:s" => { name => 'link_url' }, - "centreon-url:s" => { name => 'centreon_url' }, - "centreon-token:s" => { name => 'centreon_token' }, - "proxyurl:s" => { name => 'proxyurl' }, - "proxypac:s" => { name => 'proxypac' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname', default => 'api.telegram.org' }, + "port:s" => { name => 'port', default => 443 }, + "proto:s" => { name => 'proto', default => 'https' }, + "urlpath:s" => { name => 'url_path', default => "/sendMessage" }, + "chat-id:s" => { name => 'chat_id' }, + "bot-token:s" => { name => 'bot_token' }, + "host-name:s" => { name => 'host_name' }, + "host-state:s" => { name => 'host_state' }, + "host-output:s" => { name => 'host_output' }, + "service-description:s" => { name => 'service_description' }, + "service-state:s" => { name => 'service_state' }, + "service-output:s" => { name => 'service_output' }, + "graph-url:s" => { name => 'graph_url' }, + "link-url:s" => { name => 'link_url' }, + "centreon-url:s" => { name => 'centreon_url' }, + "centreon-token:s" => { name => 'centreon_token' }, + "timeout:s" => { name => 'timeout' }, + }); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -230,14 +226,6 @@ Use Telegram CLI for getting Chat ID Telegram Bot Token (Check Telegram Doc for Creating Bot) https://core.telegram.org/bots#3-how-do-i-create-a-bot -=item B<--proxyurl> - -Proxy URL if any. - -=item B<--proxypac> - -Proxy pac file (can be an url or local file). - =item B<--host-state> Specify host server state for the alert. @@ -282,10 +270,6 @@ Specify the link url (Example: %{centreon_url}/main.php?p=20201&o=svc&host_searc Threshold for HTTP timeout. -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =cut diff --git a/os/aix/local/mode/inodes.pm b/os/aix/local/mode/inodes.pm index c8f5fcfba..f078e3f02 100644 --- a/os/aix/local/mode/inodes.pm +++ b/os/aix/local/mode/inodes.pm @@ -58,24 +58,23 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'df' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '-i -v 2>&1' }, - "filter-fs:s" => { name => 'filter_fs', }, - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - }); - $self->{result} = {}; + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'df' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-i -v 2>&1' }, + "filter-fs:s" => { name => 'filter_fs', }, + "name:s" => { name => 'name' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + }); + return $self; } @@ -96,9 +95,18 @@ sub manage_selection { # Header not needed shift @lines; foreach my $line (@lines) { - next if ($line !~ /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/); - my ($fs, $size, $available, $percent, $iused, $ipercent, $mount) = ($1, $2, $3, $4, $5, $6, $7); + # Can be very different. + #Filesystem 512-blocks Used Free %Used Iused Ifree %Iused Mounted on + #/dev/hd4 1048576 118408 930168 12% 3699 104325 4% / + # + #Filesystem 512-blocks Free %Used Iused %Iused Mounted on + #/dev/hd0 19368 9976 48% 4714 5% / + next if ($line !~ /^(\S+)/); + my $fs = $1; + next if ($line !~ /(\d+)%\s+([^%]*?)$/); + my ($ipercent, $mount) = ($1, $2); + next if (defined($self->{option_results}->{filter_fs}) && $self->{option_results}->{filter_fs} ne '' && $fs !~ /$self->{option_results}->{filter_fs}/); @@ -109,9 +117,6 @@ sub manage_selection { next if (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $mount ne $self->{option_results}->{name}); - next if ($ifree !~ m/^\d+$/ || $iused !~ m/^\d+$/); - - $ipercent =~ s/%//g; $self->{inodes}->{$mount} = { display => $mount, used => $ipercent }; } diff --git a/os/aix/snmp/mode/swap.pm b/os/aix/snmp/mode/swap.pm index 2b0f592d7..0acd85dd4 100644 --- a/os/aix/snmp/mode/swap.pm +++ b/os/aix/snmp/mode/swap.pm @@ -20,44 +20,113 @@ package os::aix::snmp::mode::swap; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + my $msg = sprintf("Usage Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + return -10 if ($options{new_datas}->{$self->{instance} . '_total'} <= 0); + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, message_separator => ' - ', cb_init => 'skip_global', }, + { name => 'swap', type => 1, cb_prefix_output => 'prefix_swap_output', message_multiple => 'All Page spaces are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total-usage', nlabel => 'page.space.usage.bytes', set => { + key_values => [ { name => 'used' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + threshold_use => 'prct_used', + perfdatas => [ + { label => 'total_page_space', value => 'used', template => '%s', cast_int => 1, + unit => 'B', min => 0, max => 'total', threshold_total => 'total' }, + ], + } + }, + { label => 'total-active', nlabel => 'page.space.active.count', display_ok => 0, set => { + key_values => [ { name => 'nactive' }, { name => 'ntotal' } ], + output_template => 'Total page space active : %s', + perfdatas => [ + { label => 'total_active', value => 'nactive_absolute', template => '%s', + min => 0, max => 'ntotal' }, + ], + } + }, + ]; + + $self->{maps_counters}->{swap} = [ + { label => 'usage', nlabel => 'page.space.usage.bytes', set => { + key_values => [ { name => 'used' }, { name => 'total' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + threshold_use => 'prct_used', + perfdatas => [ + { label => 'page_space', value => 'used', template => '%s', cast_int => 1, + unit => 'B', min => 0, max => 'total', threshold_total => 'total', + label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + ]; +} + + +sub prefix_swap_output { + my ($self, %options) = @_; + + return "Page space '" . $options{instance_value}->{display} . "' "; +} + +sub skip_global { + my ($self, %options) = @_; + + scalar(keys %{$self->{swap}}) > 1 ? return(0) : return(1); +} + 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:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "paging-state-buggy" => { name => 'paging_state_buggy' }, - }); + $options{options}->add_options(arguments => { + "paging-state-buggy" => { name => 'paging_state_buggy' }, + }); return $self; } -sub check_options { +sub manage_selection { my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; # sysDescr values: # Aix 5.2: .*Base Operating System Runtime AIX version: 05.02.* @@ -74,13 +143,15 @@ sub run { my $aix_swap_index = ".1.3.6.1.4.1.2.6.191.2.4.2.1.8"; my @indexes = (); - my $results = $self->{snmp}->get_multiple_table(oids => [ - { oid => $aix_swap_pool }, - { oid => $oid_sysDescr }, - ]); + my $results = $options{snmp}->get_multiple_table( + oids => [ + { oid => $aix_swap_pool }, + { oid => $oid_sysDescr }, + ] + ); foreach my $key (keys %{$results->{$aix_swap_pool}}) { - if ($key =~ /^$aix_swap_index\.(.*)/ ) { + if ($key =~ /^$aix_swap_name\.(.*)/ ) { push @indexes, $1; } } @@ -106,50 +177,25 @@ sub run { $active_swap = 2; } } - - $self->{output}->output_add(severity => 'OK', - short_msg => 'All Page spaces are ok.'); - my $nactive = 0; - foreach (@indexes) { - - if ($results->{$aix_swap_pool}->{$aix_swap_status . "." . $_} == $active_swap) { - $nactive = 1; - my $swap_name = $results->{$aix_swap_pool}->{$aix_swap_name . "." . $_}; - my $swap_total = $results->{$aix_swap_pool}->{$aix_swap_total . "." . $_} * 1024 * 1024; - my $prct_used = $results->{$aix_swap_pool}->{$aix_swap_usage . "." . $_}; - my $total_used = $prct_used * $swap_total / 100; - my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $swap_total); - my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $total_used); - my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $swap_total - $total_used); - my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Page space '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $swap_name, - $total_size_value . " " . $total_size_unit, - $total_used_value . " " . $total_used_unit, $total_used * 100 / $swap_total, - $total_free_value . " " . $total_free_unit, 100 - ($total_used * 100 / $swap_total))); - } + $self->{global} = { nactive => 0, ntotal => 0, total => 0, used => 0 }; + $self->{swap} = {}; + foreach (@indexes) { + $self->{global}->{ntotal}++; + + if ($results->{$aix_swap_pool}->{$aix_swap_status . "." . $_} == $active_swap) { + $self->{global}->{nactive}++; - $self->{output}->output_add(long_msg => sprintf("Page space '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $swap_name, - $total_size_value . " " . $total_size_unit, - $total_used_value . " " . $total_used_unit, $total_used * 100 / $swap_total, - $total_free_value . " " . $total_free_unit, 100 - ($total_used * 100 / $swap_total))); - $self->{output}->perfdata_add(label => 'page_space_' . $swap_name, unit => 'B', - value => int($total_used), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_used, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_used, cast_int => 1), - min => 0, max => $swap_total); + my $swap_name = $results->{$aix_swap_pool}->{$aix_swap_name . "." . $_}; + $self->{swap}->{$swap_name} = { + display => $swap_name, + used => $results->{$aix_swap_pool}->{$aix_swap_usage . "." . $_}, + total => $results->{$aix_swap_pool}->{$aix_swap_total . "." . $_} * 1024 * 1024, + }; + $self->{global}->{used} += $self->{swap}->{$swap_name}->{used}; + $self->{global}->{total} += $self->{swap}->{$swap_name}->{total}; } } - - if ($nactive == 0) { - $self->{output}->output_add(severity => 'WARNING', - short_msg => 'No paging space active.'); - } - - $self->{output}->display(); - $self->{output}->exit(); } 1; @@ -162,14 +208,30 @@ Check AIX swap memory. =over 8 -=item B<--warning> +=item B<--warning-usage> Threshold warning in percent. -=item B<--critical> +=item B<--critical-usage> Threshold critical in percent. +=item B<--warning-total-usage> + +Threshold warning in percent. + +=item B<--critical-total-usage> + +Threshold critical in percent. + +=item B<--warning-total-active> + +Threshold warning total page space active. + +=item B<--critical-total-active> + +Threshold critical total page space active. + =item B<--paging-state-buggy> Paging state can be buggy. Please use the following option to swap state value. diff --git a/os/hpux/local/mode/storage.pm b/os/hpux/local/mode/storage.pm index bec96e5cd..491216d70 100644 --- a/os/hpux/local/mode/storage.pm +++ b/os/hpux/local/mode/storage.pm @@ -26,30 +26,30 @@ use strict; use warnings; use centreon::plugins::misc; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -57,12 +57,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -127,37 +127,30 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'bdf' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => ' 2>&1' }, - "filter-fs:s" => { name => 'filter_fs', }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - "space-reservation:s" => { name => 'space_reservation' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'bdf' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => ' 2>&1' }, + "filter-fs:s" => { name => 'filter_fs', }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "name:s" => { name => 'name' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + "space-reservation:s" => { name => 'space_reservation' }, + }); + $self->{result} = {}; return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/os/hpux/snmp/mode/storage.pm b/os/hpux/snmp/mode/storage.pm index e79c24194..c111898e3 100644 --- a/os/hpux/snmp/mode/storage.pm +++ b/os/hpux/snmp/mode/storage.pm @@ -25,30 +25,30 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -56,12 +56,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -116,23 +116,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub prefix_storage_output { my ($self, %options) = @_; diff --git a/os/linux/local/mode/discoverysnmp.pm b/os/linux/local/mode/discoverysnmp.pm new file mode 100644 index 000000000..bd1db6610 --- /dev/null +++ b/os/linux/local/mode/discoverysnmp.pm @@ -0,0 +1,222 @@ +# +# Copyright 2019 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 os::linux::local::mode::discoverysnmp; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::snmp; +use NetAddr::IP; +use JSON::XS; + +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 => { + "subnet:s" => { name => 'subnet' }, + "snmp-port:s" => { name => 'snmp_port', default => 161 }, + "snmp-version:s@" => { name => 'snmp_version' }, + "snmp-community:s@" => { name => 'snmp_community' }, + "snmp-timeout:s" => { name => 'snmp_timeout', default => 1 }, + "prettify" => { name => 'prettify' }, + }); + + $self->{snmp} = centreon::plugins::snmp->new(%options, noptions => 1); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{subnet}) || + $self->{option_results}->{subnet} !~ /(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)/) { + $self->{output}->add_option_msg(short_msg => "Need to specify --subnet option (/)."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{snmp_community}) || $self->{option_results}->{snmp_community} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --snmp-community option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{snmp_version}) || $self->{option_results}->{snmp_version} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --snmp-version option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{snmp_timeout}) || $self->{option_results}->{snmp_timeout} !~ /(\d+)/) { + $self->{output}->add_option_msg(short_msg => "Need to specify --snmp-timeout option."); + $self->{output}->option_exit(); + } + + $self->{snmp}->set_snmp_connect_params(Timeout => $self->{option_results}->{snmp_timeout} * (10**6)); + $self->{snmp}->set_snmp_connect_params(Retries => 0); + $self->{snmp}->set_snmp_params(subsetleef => 1); + $self->{snmp}->set_snmp_params(snmp_autoreduce => 0); + $self->{snmp}->set_snmp_params(snmp_errors_exit => 'unknown'); +} + +my $lookup_type = [ + { type => 'cisco standard', re => qr/Cisco IOS Software/i }, + { type => 'emc data domain', re => qr/Data Domain/i }, + { type => 'sonicwall', re => qr/SonicWALL/i }, + { type => 'silverpeak', re => qr/Silver Peak/i }, + { type => 'stonesoft', re => qr/Forcepoint/i }, + { type => 'redback', re => qr/Redback/i }, + { type => 'palo alto', re => qr/Palo Alto/i }, + { type => 'hp procurve', re => qr/HP ProCurve/i }, + { type => 'hp standard', re => qr/HPE Comware/i }, + { type => 'hp msl', re => qr/HP MSL/i }, + { type => 'mrv optiswitch', re => qr/OptiSwitch/i }, + { type => 'netapp', re => qr/Netapp/i }, + { type => 'linux', re => qr/linux/i }, + { type => 'windows', re => qr/windows/i }, + { type => 'macos', re => qr/Darwin/i }, + { type => 'hp-ux', re => qr/HP-UX/i }, + { type => 'freebsd', re => qr/FreeBSD/i }, +]; + +sub define_type { + my ($self, %options) = @_; + + foreach (@$lookup_type) { + if ($options{desc} =~ /$_->{re}/) { + return $_->{type}; + } + } + + return "unknown"; +} + +sub snmp_request { + my ($self, %options) = @_; + + $self->{snmp}->set_snmp_connect_params(DestHost => $options{ip}); + $self->{snmp}->set_snmp_connect_params(Community => $options{community}); + $self->{snmp}->set_snmp_connect_params(Version => $options{version}); + $self->{snmp}->set_snmp_connect_params(RemotePort => $options{port}); + $self->{snmp}->connect(); + return $self->{snmp}->get_leef(oids => [ $self->{oid_sysDescr}, $self->{oid_sysName} ], + nothing_quit => 0, dont_quit => 1); +} + +sub run { + my ($self, %options) = @_; + + $self->{oid_sysDescr} = ".1.3.6.1.2.1.1.1.0"; + $self->{oid_sysName} = ".1.3.6.1.2.1.1.5.0"; + + my @disco_data; + my $disco_stats; + + my $last_version; + my $last_community; + my $subnet = NetAddr::IP->new($self->{option_results}->{subnet}); + + $disco_stats->{start_time} = time(); + + foreach my $ip (@{$subnet->splitref($subnet->bits())}) { + my $result; + foreach my $community (@{$self->{option_results}->{snmp_community}}) { + foreach my $version (@{$self->{option_results}->{snmp_version}}) { + $result = $self->snmp_request(ip => $ip->addr, community => $community, version => $version, + port => $self->{option_results}->{snmp_port}); + $last_version = $version; + $last_community = $community; + last if (defined($result)); + } + } + next if (!defined($result) || $result eq ''); + + my %host; + $host{type} = $self->define_type(desc => $result->{$self->{oid_sysDescr}}); + $host{desc} = $result->{$self->{oid_sysDescr}}; + $host{ip} = $ip->addr; + $host{hostname} = $result->{$self->{oid_sysName}}; + $host{snmp_version} = $last_version; + $host{snmp_community} = $last_community; + $host{snmp_port} = $self->{option_results}->{snmp_port}; + push @disco_data, \%host; + } + + $disco_stats->{end_time} = time(); + $disco_stats->{duration} = $disco_stats->{end_time} - $disco_stats->{start_time}; + $disco_stats->{discovered_items} = @disco_data; + $disco_stats->{results} = \@disco_data; + + my $encoded_data; + eval { + if (defined($self->{option_results}->{prettify})) { + $encoded_data = JSON::XS->new->utf8->pretty->encode($disco_stats); + } else { + $encoded_data = JSON::XS->new->utf8->encode($disco_stats); + } + }; + if ($@) { + $encoded_data = '{"code":"encode_error","message":"Cannot encode discovered data into JSON format"}'; + } + + $self->{output}->output_add(short_msg => $encoded_data); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Resources discovery. + +=over 8 + +=item B<--subnet> + +Specify subnet from which discover +resources (Must be / format) (Mandatory). + +=item B<--snmp-port> + +Specify SNMP port (Default: 161). + +=item B<--snmp-version> + +Specify SNMP version (Can be multiple) (Mandatory). + +=item B<--snmp-community> + +Specify SNMP community (Can be multiple) (Mandatory). + +=item B<--snmp-timeout> + +Specify SNMP timeout in second (Default: 1). + +=item B<--prettify> + +Prettify JSON output. + +=back + +=cut diff --git a/os/linux/local/mode/listinterfaces.pm b/os/linux/local/mode/listinterfaces.pm index b0834715a..70b80e998 100644 --- a/os/linux/local/mode/listinterfaces.pm +++ b/os/linux/local/mode/listinterfaces.pm @@ -32,23 +32,23 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'ifconfig' }, - "command-path:s" => { name => 'command_path', default => '/sbin' }, - "command-options:s" => { name => 'command_options', default => '-a 2>&1' }, - "filter-name:s" => { name => 'filter_name', }, - "filter-state:s" => { name => 'filter_state', }, - "no-loopback" => { name => 'no_loopback', }, - "skip-novalues" => { name => 'skip_novalues', }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'ip' }, + "command-path:s" => { name => 'command_path', default => '/sbin' }, + "command-options:s" => { name => 'command_options', default => '-s addr 2>&1' }, + "filter-name:s" => { name => 'filter_name' }, + "filter-state:s" => { name => 'filter_state' }, + "no-loopback" => { name => 'no_loopback' }, + "skip-novalues" => { name => 'skip_novalues' }, + }); + $self->{result} = {}; return $self; } @@ -61,17 +61,36 @@ sub check_options { sub manage_selection { my ($self, %options) = @_; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - while ($stdout =~ /^(\S+)(.*?)(\n\n|\n$)/msg) { + my $stdout = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options} + ); + + my $mapping = { + ifconfig => { + get_interface => '^(\S+)(.*?)(\n\n|\n$)', + test => 'RX bytes:\S+.*?TX bytes:\S+', + }, + iproute => { + get_interface => '^\d+:\s+(\S+)(.*?)(?=\n\d|\Z$)', + test => 'RX:\s+bytes.*?\d+', + }, + }; + + my $type = 'ifconfig'; + if ($stdout =~ /^\d+:\s+\S+:\s+{$type}->{get_interface}/msg) { my ($interface_name, $values) = ($1, $2); $interface_name =~ s/:$//; my $states = ''; - $states .= 'R' if ($values =~ /RUNNING/ms); + $states .= 'R' if ($values =~ /RUNNING|LOWER_UP/ms); $states .= 'U' if ($values =~ /UP/ms); if (defined($self->{option_results}->{no_loopback}) && $values =~ /LOOPBACK/ms) { @@ -89,12 +108,12 @@ sub manage_selection { next; } - $values =~ /RX bytes:(\S+).*?TX bytes:(\S+)/msi; - if (defined($self->{option_results}->{skip_novalues}) && !defined($1)) { + if (defined($self->{option_results}->{skip_novalues}) && $values =~ /$mapping->{$type}->{test}/msi) { $self->{output}->output_add(long_msg => "Skipping interface '" . $interface_name . "': no values"); next; } - $self->{result}->{$interface_name} = {state => $states}; + + $self->{result}->{$interface_name} = { state => $states }; } } @@ -123,9 +142,10 @@ sub disco_show { $self->manage_selection(); foreach my $name (sort(keys %{$self->{result}})) { - $self->{output}->add_disco_entry(name => $name, - state => $self->{result}->{$name}->{state} - ); + $self->{output}->add_disco_entry( + name => $name, + state => $self->{result}->{$name}->{state} + ); } } @@ -169,7 +189,7 @@ Use 'sudo' to execute the command. =item B<--command> -Command to get information (Default: 'ifconfig'). +Command to get information (Default: 'ip'). Can be changed if you have output in a file. =item B<--command-path> @@ -178,7 +198,7 @@ Command path (Default: '/sbin'). =item B<--command-options> -Command options (Default: '-a 2>&1'). +Command options (Default: '-s addr 2>&1'). =item B<--filter-name> @@ -199,4 +219,4 @@ Filter interface without in/out byte values. =back -=cut \ No newline at end of file +=cut diff --git a/os/linux/local/mode/ntp.pm b/os/linux/local/mode/ntp.pm new file mode 100644 index 000000000..354b733da --- /dev/null +++ b/os/linux/local/mode/ntp.pm @@ -0,0 +1,402 @@ +# +# Copyright 2018 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 os::linux::local::mode::ntp; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); + +my %state_map_ntpq = ( + '' => 'discarded due to high stratum and/or failed sanity checks', + 'x' => 'designated falsticker by the intersection algorithm', + '.' => 'culled from the end of the candidate list', + '-' => 'discarded by the clustering algorithm', + '+' => 'included in the final selection set', + '#' => 'selected for synchronization but distance exceeds maximum', + '*' => 'selected for synchronization', + 'o' => 'selected for synchronization, PPS signal in use' +); + +my %type_map_ntpq = ( + 'l' => 'local', + 'u' => 'unicast', + 'm' => 'multicast', + 'b' => 'broadcast', + '-' => 'netaddr' +); + +my %state_map_chronyc = ( + 'x' => 'time may be in error', + '-' => 'not combined', + '+' => 'combined', + '?' => 'unreachable', + '*' => 'current synced', + '~' => 'time too variable' +); + +my %type_map_chronyc = ( + '^' => 'server', + '=' => 'peer', + '#' => 'local clock' +); + +my %unit_map_chronyc = ( + 'ns' => 0.000001, + 'us' => 0.001, + 'ms' => 1, + 's' => 1000 +); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("[type: %s] [reach: %s] [state: %s]", + $self->{result_values}->{type}, + $self->{result_values}->{reach}, + $self->{result_values}->{state} + ); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{rawtype} = $options{new_datas}->{$self->{instance} . '_type'}; + $self->{result_values}->{rawstate} = $options{new_datas}->{$self->{instance} . '_state'}; + if ($self->{instance_mode}->{option_results}->{command} eq 'ntpq') { + $self->{result_values}->{type} = $type_map_ntpq{$options{new_datas}->{$self->{instance} . '_type'}}; + } else { + $self->{result_values}->{type} = $type_map_chronyc{$options{new_datas}->{$self->{instance} . '_type'}}; + } + $self->{result_values}->{reach} = $options{new_datas}->{$self->{instance} . '_reach'}; + if ($self->{instance_mode}->{option_results}->{command} eq 'ntpq') { + $self->{result_values}->{state} = $state_map_ntpq{$options{new_datas}->{$self->{instance} . '_state'}}; + } else { + $self->{result_values}->{state} = $state_map_chronyc{$options{new_datas}->{$self->{instance} . '_state'}}; + } + return 0; +} + +sub custom_offset_perfdata { + my ($self, %options) = @_; + + if ($self->{result_values}->{state_absolute} ne '*') { + $self->{output}->perfdata_add( + label => 'offset', unit => 'ms', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display_absolute} : undef, + value => $self->{result_values}->{offset_absolute}, + min => 0 + ); + } else { + $self->{output}->perfdata_add( + label => 'offset', unit => 'ms', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display_absolute} : undef, + value => $self->{result_values}->{offset_absolute}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0 + ); + } +} + +sub custom_offset_threshold { + my ($self, %options) = @_; + + if ($self->{result_values}->{state_absolute} ne '*') { + return 'ok'; + } + return $self->{perfdata}->threshold_check(value => $self->{result_values}->{offset_absolute}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'peers', type => 1, cb_prefix_output => 'prefix_peer_output', message_multiple => 'All peers are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'peers', set => { + key_values => [ { name => 'peers' } ], + output_template => 'Number of ntp peers : %d', + perfdatas => [ + { label => 'peers', value => 'peers_absolute', template => '%d', + min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{peers} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'state' }, { name => 'type' }, { name => 'reach' }, { 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 => \&catalog_status_threshold, + } + }, + { label => 'offset', display_ok => 0, set => { + key_values => [ { name => 'offset' }, { name => 'state' }, { name => 'display' } ], + output_template => 'Offset : %s ms', + closure_custom_threshold_check => $self->can('custom_offset_threshold'), + closure_custom_perfdata => $self->can('custom_offset_perfdata'), + perfdatas => [ + { label => 'offset', value => 'offset_absolute', template => '%s', + min => 0, unit => 'ms', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'stratum', display_ok => 0, set => { + key_values => [ { name => 'stratum' }, { name => 'display' } ], + output_template => 'Stratum : %s', + perfdatas => [ + { label => 'stratum', value => 'stratum_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_peer_output { + my ($self, %options) = @_; + + return "Peer '" . $options{instance_value}->{display} . "' "; +} + +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 => { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'ntpq' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '' }, + "filter-name:s" => { name => 'filter_name' }, + "filter-state:s" => { name => 'filter_state' }, + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "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); + + if ($self->{option_results}->{command} eq 'ntpq') { + $self->{regex} = '^(\+|\*|\.|\-|\#|x|\|o)(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)'; + $self->{option_results}->{command_options} = '-p -n 2>&1'; + } elsif ($self->{option_results}->{command} eq 'chronyc') { + $self->{regex} = '^(.)(\+|\*|\.|\-|\#|x|\)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*?)(\d+)(\w+)$'; + $self->{option_results}->{command_options} = '-n sources 2>&1'; + } else { + $self->{output}->add_option_msg(short_msg => "command '" . $self->{option_results}->{command} . "' not implemented" ); + $self->{output}->option_exit(); + } + + $self->change_macros(macros => ['unknown_status', 'warning_status', 'critical_status']); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $stdout = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}, + ); + + $self->{global} = { peers => 0 }; + $self->{peers} = {}; + + my @lines = split /\n/, $stdout; + foreach my $line (@lines) { + if ($line =~ /Connection refused/) { + $self->{output}->add_option_msg(short_msg => "check ntp.conf and ntp daemon" ); + $self->{output}->option_exit(); + } + next if ($line !~ /$self->{regex}/); + + my ($remote_peer, $peer_fate) = (centreon::plugins::misc::trim($2), centreon::plugins::misc::trim($1)); + if ($self->{option_results}->{command} eq 'chronyc') { + $remote_peer = centreon::plugins::misc::trim($3); + $peer_fate = centreon::plugins::misc::trim($2); + } + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $remote_peer !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $remote_peer . "': no matching filter peer name.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_state}) && $self->{option_results}->{filter_state} ne '' && + $peer_fate !~ /$self->{option_results}->{filter_state}/) { + $self->{output}->output_add(long_msg => "skipping '" . $remote_peer . "': no matching filter peer state.", debug => 1); + next; + } + + if ($self->{option_results}->{command} eq 'ntpq') { + my ($refid, $stratum, $type, $last_time, $polling_intervall, $reach, $delay, $offset, $jitter) = ($3, $4, $5, $6, $7, $8, $9, $10, $11); + $self->{peers}->{$remote_peer} = { + display => $remote_peer, + state => $peer_fate, + stratum => centreon::plugins::misc::trim($stratum), + type => centreon::plugins::misc::trim($type), + reach => centreon::plugins::misc::trim($reach), + offset => centreon::plugins::misc::trim($offset) + }; + } elsif ($self->{option_results}->{command} eq 'chronyc') { + #210 Number of sources = 4 + #MS Name/IP address Stratum Poll Reach LastRx Last sample + #=============================================================================== + #^+ 212.83.187.62 2 9 377 179 -715us[ -731us] +/- 50ms + #^- 129.250.35.251 2 8 377 15 -82us[ -99us] +/- 96ms + + my ($type, $stratum, $poll, $reach, $lastRX, $offset) = ($1, $4, $5, $6, $7, $9); + $self->{peers}->{$remote_peer} = { + display => $remote_peer, + state => $peer_fate, + stratum => centreon::plugins::misc::trim($stratum), + type => centreon::plugins::misc::trim($type), + reach => centreon::plugins::misc::trim($reach), + offset => centreon::plugins::misc::trim($offset) * $unit_map_chronyc{centreon::plugins::misc::trim($10)}, + }; + } + + $self->{global}->{peers}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check ntp daemons. + +=over 8 + +=item B<--remote> + +Execute command remotely in 'ssh'. + +=item B<--hostname> + +Hostname to query (need --remote). + +=item B<--ssh-option> + +Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). + +=item B<--ssh-path> + +Specify ssh command path (default: none) + +=item B<--ssh-command> + +Specify ssh command (default: 'ssh'). Useful to use 'plink'. + +=item B<--timeout> + +Timeout in seconds for the command (Default: 30). + +=item B<--sudo> + +Use 'sudo' to execute the command. + +=item B<--command> + +Command to get information (Default: 'ntpq'). +Can also be 'chronyc'. + +=item B<--command-path> + +Command path (Default: none). + +=item B<--filter-name> + +Filter peer name (can be a regexp). + +=item B<--filter-name> + +Filter peer state (can be a regexp). + +=item B<--warning-peers> + +Threshold warning minimum Amount of NTP-Server + +=item B<--critical-peers> + +Threshold critical minimum Amount of NTP-Server + +=item B<--warning-offset> + +Threshold warning Offset deviation value in miliseconds + +=item B<--critical-offset> + +Threshold critical Offset deviation value in miliseconds + +=item B<--warning-stratum> + +Threshold warning. + +=item B<--critical-stratum> + +Threshold critical. + +=item B<--unknown-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{state}, %{rawstate}, %{type}, %{rawtype}, %{reach}, %{display} + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{state}, %{rawstate}, %{type}, %{rawtype}, %{reach}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{state}, %{rawstate}, %{type}, %{rawtype}, %{reach}, %{display} + +=back + +=cut diff --git a/os/linux/local/mode/packeterrors.pm b/os/linux/local/mode/packeterrors.pm index f1ab71df7..af5d1c856 100644 --- a/os/linux/local/mode/packeterrors.pm +++ b/os/linux/local/mode/packeterrors.pm @@ -20,121 +20,208 @@ package os::linux::local::mode::packeterrors; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::misc; -use centreon::plugins::statefile; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); use Digest::MD5 qw(md5_hex); +use centreon::plugins::misc; -my $maps_counters = { - packets_discard_in => { thresholds => { - warning_in_discard => { label => 'warning-in-discard', exit_value => 'warning' }, - critical_in_discard => { label => 'critical-in-discard', exit_value => 'critical' }, - }, - output_msg => 'In Discard : %.2f %% (%d)', - regexp => 'RX packets:\d+\s*?errors:\d+\s*?dropped:(\d+)', - total => 'total_in', - }, - packets_discard_out => { thresholds => { - warning_out_discard => { label => 'warning-out-discard', exit_value => 'warning' }, - critical_out_discard => { label => 'critical-out-discard', exit_value => 'critical' }, - }, - output_msg => 'Out Discard : %.2f %% (%d)', - regexp => 'TX packets:\d+\s*?errors:\d+\s*?dropped:(\d+)', - total => 'total_out', - }, - packets_error_in => { thresholds => { - warning_in_error => { label => 'warning-in-error', exit_value => 'warning' }, - critical_in_error => { label => 'critical-in-error', exit_value => 'critical' }, - }, - output_msg => 'In Error : %.2f %% (%d)', - regexp => 'RX packets:\d+\s*?errors:(\d+)', - total => 'total_in', - }, - packets_error_out => { thresholds => { - warning_out_error => { label => 'warning-out-error', exit_value => 'warning' }, - critical_out_error => { label => 'critical-out-error', exit_value => 'critical' }, - }, - output_msg => 'Out Error : %.2f %% (%d)', - regexp => 'TX packets:\d+\s*?errors:(\d+)', - total => 'total_out', - }, -}; +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf('status : %s', $self->{result_values}->{status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_packet_output { + my ($self, %options) = @_; + + my $msg = sprintf("Packet %s %s : %.2f %% (%s)", + ucfirst($self->{result_values}->{type}), + ucfirst($self->{result_values}->{label}), + $self->{result_values}->{result_prct}, + $self->{result_values}->{diff_value} + ); + return $msg; +} + +sub custom_packet_calc { + my ($self, %options) = @_; + + $self->{result_values}->{type} = $options{extra_options}->{type}; + $self->{result_values}->{label} = $options{extra_options}->{label_ref}; + $self->{result_values}->{diff_value} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{type} . '_' . $self->{result_values}->{label}} - + $options{old_datas}->{$self->{instance} . '_' . $self->{result_values}->{type} . '_' . $self->{result_values}->{label}}; + my $diff_total = $options{new_datas}->{$self->{instance} . '_total_' . $self->{result_values}->{label}} - + $options{old_datas}->{$self->{instance} . '_total_' . $self->{result_values}->{label}}; + + $self->{result_values}->{result_prct} = ($diff_total == 0) ? 0 : ($self->{result_values}->{diff_value} * 100 / $diff_total); + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'interface', type => 1, cb_prefix_output => 'prefix_interface_output', message_multiple => 'All interfaces are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{interface} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { 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 => \&catalog_status_threshold, + } + }, + { label => 'in-discard', set => { + key_values => [ { name => 'discard_in', diff => 1 }, { name => 'total_in', diff => 1 }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_packet_calc'), closure_custom_calc_extra_options => { type => 'discard', label_ref => 'in' }, + closure_custom_output => $self->can('custom_packet_output'), output_error_template => 'Discard In : %s', + threshold_use => 'result_prct', + perfdatas => [ + { label => 'packets_discard_in', value => 'result_prct', template => '%.2f', min => 0, max => 100, + unit => '%', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'out-discard', set => { + key_values => [ { name => 'discard_out', diff => 1 }, { name => 'total_out', diff => 1 }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_packet_calc'), closure_custom_calc_extra_options => { type => 'discard', label_ref => 'out' }, + closure_custom_output => $self->can('custom_packet_output'), output_error_template => 'Discard Out : %s', + threshold_use => 'result_prct', + perfdatas => [ + { label => 'packets_discard_out', value => 'result_prct', template => '%.2f', min => 0, max => 100, + unit => '%', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'in-error', set => { + key_values => [ { name => 'error_in', diff => 1 }, { name => 'total_in', diff => 1 }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_packet_calc'), closure_custom_calc_extra_options => { type => 'error', label_ref => 'in' }, + closure_custom_output => $self->can('custom_packet_output'), output_error_template => 'Error In : %s', + threshold_use => 'result_prct', + perfdatas => [ + { label => 'packets_error_in', value => 'result_prct', template => '%.2f', min => 0, max => 100, + unit => '%', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'out-error', set => { + key_values => [ { name => 'error_out', diff => 1 }, { name => 'total_out', diff => 1 }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_packet_calc'), closure_custom_calc_extra_options => { type => 'error', label_ref => 'out' }, + closure_custom_output => $self->can('custom_packet_output'), output_error_template => 'Error In : %s', + threshold_use => 'result_prct', + perfdatas => [ + { label => 'packets_error_out', value => 'result_prct', template => '%.2f', min => 0, max => 100, + unit => '%', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'ifconfig' }, - "command-path:s" => { name => 'command_path', default => '/sbin' }, - "command-options:s" => { name => 'command_options', default => '-a 2>&1' }, - "filter-state:s" => { name => 'filter_state', }, - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - "no-loopback" => { name => 'no_loopback', }, - "skip" => { name => 'skip' }, - }); - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - } - } - - $self->{result} = {}; - $self->{hostname} = undef; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'ip' }, + "command-path:s" => { name => 'command_path', default => '/sbin' }, + "command-options:s" => { name => 'command_options', default => '-s addr 2>&1' }, + "filter-state:s" => { name => 'filter_state', }, + "name:s" => { name => 'name' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + "no-loopback" => { name => 'no_loopback', }, + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} ne "RU"' }, + }); + return $self; } +sub prefix_interface_output { + my ($self, %options) = @_; + + return "Interface '" . $options{instance_value}->{display} . "' "; +} + sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - } - } - } + $self->SUPER::check_options(%options); - $self->{statefile_value}->check_options(%options); $self->{hostname} = $self->{option_results}->{hostname}; if (!defined($self->{hostname})) { $self->{hostname} = 'me'; } + + $self->change_macros(macros => ['unknown_status', 'warning_status', 'critical_status']); } -sub manage_selection { +sub do_selection { my ($self, %options) = @_; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - while ($stdout =~ /^(\S+)(.*?)(\n\n|\n$)/msg) { + my $stdout = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options} + ); + + my $mapping = { + ifconfig => { + get_interface => '^(\S+)(.*?)(\n\n|\n$)', + total => 'RX packets:(\d+).*?TX packets:(\d+)', + discard_in => 'RX packets:\d+\s+?errors:\d+\s+?dropped:(\d+)', + discard_out => 'TX packets:\d+\s+?errors:\d+\s+?dropped:(\d+)', + error_in => 'RX packets:\d+\s+?errors:(\d+)', + error_out => 'TX packets:\d+\s+?errors:(\d+)', + }, + iproute => { + get_interface => '^\d+:\s+(\S+)(.*?)(?=\n\d|\Z$)', + total => 'RX:\s+bytes\s+packets.*?\d+\s+(\d+).*?TX:\s+bytes\s+packets.*?\d+\s+(\d+)', + discard_in => 'RX:.*?dropped.*?\d+.*?\d+.*?\d+.*?(\d+)', + discard_out => 'TX:.*?dropped.*?\d+.*?\d+.*?\d+.*?(\d+)', + error_in => 'RX:.*?errors.*?\d+.*?\d+.*?(\d+)', + error_out => 'TX:.*?errors.*?\d+.*?\d+.*?(\d+)', + }, + }; + + my $type = 'ifconfig'; + if ($stdout =~ /^\d+:\s+\S+:\s+{interface} = {}; + while ($stdout =~ /$mapping->{$type}->{get_interface}/msg) { my ($interface_name, $values) = ($1, $2); my $states = ''; - $states .= 'R' if ($values =~ /RUNNING/ms); + $states .= 'R' if ($values =~ /RUNNING|LOWER_UP/ms); $states .= 'U' if ($values =~ /UP/ms); next if (defined($self->{option_results}->{no_loopback}) && $values =~ /LOOPBACK/ms); @@ -148,146 +235,35 @@ sub manage_selection { next if (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $interface_name ne $self->{option_results}->{name}); - $values =~ /RX packets:(\d+).*?TX packets:(\d+)/msi; - $self->{result}->{$interface_name} = {total_in => $1, total_out => $2, state => $states}; - foreach (keys %{$maps_counters}) { - $values =~ /$maps_counters->{$_}->{regexp}/msi; - $self->{result}->{$interface_name}->{$_} = $1; + $self->{interface}->{$interface_name} = { + display => $interface_name, + status => $states, + }; + if ($values =~ /$mapping->{$type}->{total}/msi) { + $self->{interface}->{$interface_name}->{total_in} = $1; + $self->{interface}->{$interface_name}->{total_out} = $2; + } + + foreach ('discard_in', 'discard_out', 'error_in', 'error_out') { + if ($values =~ /$mapping->{$type}->{$_}/msi) { + $self->{interface}->{$interface_name}->{$_} = $1; + } } } - if (scalar(keys %{$self->{result}}) <= 0) { - if (defined($self->{option_results}->{name})) { - $self->{output}->add_option_msg(short_msg => "No interface found for name '" . $self->{option_results}->{name} . "'."); - } else { - $self->{output}->add_option_msg(short_msg => "No interface found."); - } + if (scalar(keys %{$self->{interface}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No interface found."); $self->{output}->option_exit(); } } -sub run { +sub manage_selection { my ($self, %options) = @_; - - $self->manage_selection(); - my $new_datas = {}; - $self->{statefile_value}->read(statefile => "cache_linux_local_" . $self->{hostname} . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $new_datas->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All interfaces are ok.'); - } - - foreach my $name (sort(keys %{$self->{result}})) { - - if ($self->{result}->{$name}->{state} !~ /RU/) { - if (!defined($self->{option_results}->{skip})) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => "Interface '" . $name . "' is not up or/and running"); - } else { - # Avoid getting "buffer creation..." alone - if (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Interface '" . $name . "' is not up or/and running (normal state)"); - } - $self->{output}->output_add(long_msg => "Skip interface '" . $name . "': not up or/and running."); - } - next; - } - - # Some interface are running but not have bytes in/out - if (!defined($self->{result}->{$name}->{total_in})) { - if (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Interface '" . $name . "' is up and running but can't get packets (no values)"); - } - $self->{output}->output_add(long_msg => "Skip interface '" . $name . "': can't get packets."); - next; - } - - my $old_datas = {}; - my $next = 0; - foreach (keys %{$self->{result}->{$name}}) { - next if ($_ eq 'state'); - $new_datas->{$_ . '_' . $name} = $self->{result}->{$name}->{$_}; - $old_datas->{$_ . '_' . $name} = $self->{statefile_value}->get(name => $_ . '_' . $name); - if (!defined($old_datas->{$_ . '_' . $name})) { - $next = 1; - } elsif ($new_datas->{$_ . '_' . $name} < $old_datas->{$_ . '_' . $name}) { - # We set 0. has reboot - $old_datas->{$_ . '_' . $name} = 0; - } - } - - if (!defined($old_timestamp) || $next == 1) { - next; - } - - my $time_delta = $new_datas->{last_timestamp} - $old_timestamp; - if ($time_delta <= 0) { - # At least one second. two fast calls ;) - $time_delta = 1; - } - - ############ - - my $error_values = {}; - foreach (keys %{$maps_counters}) { - $error_values->{$_} = {} if (!defined($error_values->{$_})); - my $total_packets = $new_datas->{$maps_counters->{$_}->{total} . '_' . $name} - $old_datas->{$maps_counters->{$_}->{total} . '_' . $name}; - $error_values->{$_}->{per_sec} = ($new_datas->{$_ . '_' . $name} - $old_datas->{$_ . '_' . $name}) / $time_delta; - $error_values->{$_}->{prct} = ($total_packets == 0) ? 0 : ($new_datas->{$_ . '_' . $name} - $old_datas->{$_ .'_' . $name}) * 100 / $total_packets; - } - - ########### - # Manage Output - ########### - my @exits; - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - push @exits, $self->{perfdata}->threshold_check(value => $error_values->{$_}->{prct}, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - } - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - my $extra_label = ''; - $extra_label = '_' . $name if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})); - - my $str_output = "Interface '$name' Packets "; - my $str_append = ''; - foreach (keys %{$maps_counters}) { - $str_output .= $str_append . sprintf($maps_counters->{$_}->{output_msg}, $error_values->{$_}->{prct}, $new_datas->{$_ . '_' . $name} - $old_datas->{$_ . '_' . $name}); - $str_append = ', '; - my ($warning, $critical); - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - - $self->{output}->perfdata_add(label => $_ . $extra_label, unit => '%', - value => sprintf("%.2f", $error_values->{$_}->{prct}), - warning => $warning, - critical => $critical, - min => 0, max => 100); - } - $self->{output}->output_add(long_msg => $str_output); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp}))) { - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - } - } - - $self->{statefile_value}->write(data => $new_datas); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - } - - $self->{output}->display(); - $self->{output}->exit(); + $self->do_selection(); + $self->{cache_name} = "cache_linux_local_" . $self->{hostname} . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all')); } 1; @@ -330,7 +306,7 @@ Use 'sudo' to execute the command. =item B<--command> -Command to get information (Default: 'ifconfig'). +Command to get information (Default: 'ip'). Can be changed if you have output in a file. =item B<--command-path> @@ -339,7 +315,7 @@ Command path (Default: '/sbin'). =item B<--command-options> -Command options (Default: '-a 2>&1'). +Command options (Default: '-s addr 2>&1'). =item B<--warning-*> @@ -367,14 +343,10 @@ Allows to use regexp non case-sensitive (with --regexp). Filter filesystem type (regexp can be used). -=item B<--skip> - -Skip errors on interface status (not up and running). - =item B<--no-loopback> Don't display loopback interfaces. =back -=cut \ No newline at end of file +=cut diff --git a/os/linux/local/mode/paging.pm b/os/linux/local/mode/paging.pm index b53604647..f1af72ed4 100644 --- a/os/linux/local/mode/paging.pm +++ b/os/linux/local/mode/paging.pm @@ -20,207 +20,138 @@ package os::linux::local::mode::paging; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::statefile; -use centreon::plugins::values; +use Digest::MD5 qw(md5_hex); +use centreon::plugins::misc; -my $maps_counters = { - pgpgin => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'pgpgin', diff => 1 }, - ], - output_template => 'pgpgin : %s %s/s', per_second => 1, output_change_bytes => 1, - perfdatas => [ - { value => 'pgpgin_per_second', label => 'pgpgin', template => '%d', - unit => 'B/s', min => 0 }, - ], - } - }, - pgpgout => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'pgpgout', diff => 1 }, - ], - output_template => 'pgpgout : %s %s/s', per_second => 1, output_change_bytes => 1, - perfdatas => [ - { value => 'pgpgout_per_second', label => 'pgpgout', template => '%d', - unit => 'B/s', min => 0 }, - ], - } - }, - pswpin => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'pswpin', diff => 1 }, - ], - output_template => 'pswpin : %s %s/s', per_second => 1, output_change_bytes => 1, - perfdatas => [ - { value => 'pswpin_per_second', label => 'pswpin', template => '%d', - unit => 'B/s', min => 0 }, - ], - } - }, - pswpout => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'pswpout', diff => 1 }, - ], - output_template => 'pswpout : %s %s/s', per_second => 1, output_change_bytes => 1, - perfdatas => [ - { value => 'pswpout_per_second', label => 'pswpout', template => '%d', - unit => 'B/s', min => 0 }, - ], - } - }, - pgfault => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'pgfault', diff => 1 }, - ], - output_template => 'pgfault : %s %s/s', per_second => 1, output_change_bytes => 1, - perfdatas => [ - { value => 'pgfault_per_second', label => 'pgfault', template => '%d', - unit => 'B/s', min => 0 }, - ], - } - }, - pgmajfault => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'pgmajfault', diff => 1 }, - ], - output_template => 'pgmajfault : %s %s/s', per_second => 1, output_change_bytes => 1, - perfdatas => [ - { value => 'pgmajfault_per_second', label => 'pgmajfault', template => '%d', - unit => 'B/s', min => 0 }, - ], - } - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'pgpgin', nlabel => 'system.pgpin.usage.bytespersecond', set => { + key_values => [ { name => 'pgpgin', diff => 1 } ], + output_template => 'pgpgin : %s %s/s', per_second => 1, output_change_bytes => 1, + perfdatas => [ + { value => 'pgpgin_per_second', label => 'pgpgin', template => '%d', + unit => 'B/s', min => 0 }, + ], + } + }, + { label => 'pgpgout', nlabel => 'system.pgpgout.usage.bytespersecond', set => { + key_values => [ { name => 'pgpgout', diff => 1 } ], + output_template => 'pgpgout : %s %s/s', per_second => 1, output_change_bytes => 1, + perfdatas => [ + { value => 'pgpgout_per_second', label => 'pgpgout', template => '%d', + unit => 'B/s', min => 0 }, + ], + } + }, + { label => 'pswpin', nlabel => 'system.pswpin.usage.bytespersecond', set => { + key_values => [ { name => 'pswpin', diff => 1 } ], + output_template => 'pswpin : %s %s/s', per_second => 1, output_change_bytes => 1, + perfdatas => [ + { value => 'pswpin_per_second', label => 'pswpin', template => '%d', + unit => 'B/s', min => 0 }, + ], + } + }, + { label => 'pswpout', nlabel => 'system.pswpout.usage.bytespersecond', set => { + key_values => [ { name => 'pswpout', diff => 1 } ], + output_template => 'pswpout : %s %s/s', per_second => 1, output_change_bytes => 1, + perfdatas => [ + { value => 'pswpout_per_second', label => 'pswpout', template => '%d', + unit => 'B/s', min => 0 }, + ], + } + }, + { label => 'pgfault', nlabel => 'system.pgfault.usage.bytespersecond', set => { + key_values => [ { name => 'pgfault', diff => 1 } ], + output_template => 'pgfault : %s %s/s', per_second => 1, output_change_bytes => 1, + perfdatas => [ + { value => 'pgfault_per_second', label => 'pgfault', template => '%d', + unit => 'B/s', min => 0 }, + ], + } + }, + { label => 'pgmajfault', nlabel => 'system.pgmajfault.usage.bytespersecond', set => { + key_values => [ { name => 'pgmajfault', diff => 1 } ], + output_template => 'pgmajfault : %s %s/s', per_second => 1, output_change_bytes => 1, + perfdatas => [ + { value => 'pgmajfault_per_second', label => 'pgmajfault', template => '%d', + unit => 'B/s', min => 0 }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'cat' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '/proc/vmstat 2>&1' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'cat' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '/proc/vmstat 2>&1' }, + }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - - foreach (keys %{$maps_counters}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - return $self; } +sub prefix_global_output { + my ($self, %options) = @_; + + return 'Paging '; +} + sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } + $self->SUPER::check_options(%options); - $self->{statefile_value}->check_options(%options); $self->{hostname} = $self->{option_results}->{hostname}; if (!defined($self->{hostname})) { $self->{hostname} = 'me'; } } -sub run { - my ($self, %options) = @_; - - $self->{stdout} = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - $self->manage_selection(); - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "cache_linux_local_" . $self->{hostname} . '_' . $self->{mode}); - $self->{new_datas}->{last_timestamp} = time(); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => 'paging'); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{paging}, - new_datas => $self->{new_datas}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{$_}->{obj}->perfdata(); - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Paging $short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "Paging $long_msg"); - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; + + my ($stdout) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options} + ); - $self->{paging} = {}; - $self->{paging}->{pgpgin} = $self->{stdout} =~ /^pgpgin.*?(\d+)/msi ? $1 * 1024 : undef; - $self->{paging}->{pgpgout} = $self->{stdout} =~ /^pgpgout.*?(\d+)/msi ? $1 * 1024 : undef; - $self->{paging}->{pswpin} = $self->{stdout} =~ /^pswpin.*?(\d+)/msi ? $1 * 1024 : undef; - $self->{paging}->{pswpout} = $self->{stdout} =~ /^pswpout.*?(\d+)/msi ? $1 * 1024: undef; - $self->{paging}->{pgfault} = $self->{stdout} =~ /^pgfault.*?(\d+)/msi ? $1 * 1024: undef; - $self->{paging}->{pgmajfault} = $self->{stdout} =~ /^pgmajfault.*?(\d+)/msi ? $1 * 1014: undef; + $self->{global} = {}; + $self->{global}->{pgpgin} = $stdout =~ /^pgpgin.*?(\d+)/msi ? $1 * 1024 : undef; + $self->{global}->{pgpgout} = $stdout =~ /^pgpgout.*?(\d+)/msi ? $1 * 1024 : undef; + $self->{global}->{pswpin} = $stdout =~ /^pswpin.*?(\d+)/msi ? $1 * 1024 : undef; + $self->{global}->{pswpout} = $stdout =~ /^pswpout.*?(\d+)/msi ? $1 * 1024: undef; + $self->{global}->{pgfault} = $stdout =~ /^pgfault.*?(\d+)/msi ? $1 * 1024: undef; + $self->{global}->{pgmajfault} = $stdout =~ /^pgmajfault.*?(\d+)/msi ? $1 * 1014: undef; + + $self->{cache_name} = "cache_linux_local_" . $self->{hostname} . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; diff --git a/os/linux/local/mode/process.pm b/os/linux/local/mode/process.pm index 17db62ead..47c5e046f 100644 --- a/os/linux/local/mode/process.pm +++ b/os/linux/local/mode/process.pm @@ -33,7 +33,8 @@ my %state_map = ( T => 'stopped', S => 'InterruptibleSleep', R => 'running', - D => 'UninterrupibleSleep' + D => 'UninterrupibleSleep', + I => 'IdleKernelThread', ); sub new { @@ -42,27 +43,27 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'ps' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '-e -o etime,pid,ppid,state,comm,args -w 2>&1' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "warning-time:s" => { name => 'warning_time' }, - "critical-time:s" => { name => 'critical_time' }, - "filter-command:s" => { name => 'filter_command' }, - "filter-arg:s" => { name => 'filter_arg' }, - "filter-state:s" => { name => 'filter_state' }, - "filter-ppid:s" => { name => 'filter_ppid' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'ps' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-e -o state -o ===%t===%p===%P=== -o comm:50 -o ===%a -w 2>&1' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "warning-time:s" => { name => 'warning_time' }, + "critical-time:s" => { name => 'critical_time' }, + "filter-command:s" => { name => 'filter_command' }, + "filter-arg:s" => { name => 'filter_arg' }, + "filter-state:s" => { name => 'filter_state' }, + "filter-ppid:s" => { name => 'filter_ppid' }, + }); + $self->{result} = {}; return $self; } @@ -70,6 +71,7 @@ sub new { sub check_options { my ($self, %options) = @_; $self->SUPER::init(%options); + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); $self->{output}->option_exit(); @@ -98,22 +100,18 @@ sub parse_output { command_path => $self->{option_results}->{command_path}, command_options => $self->{option_results}->{command_options}); my @lines = split /\n/, $stdout; - # Header to manage output - # ELAPSED PID PPID S COMMAND COMMAND my $line = shift @lines; - $line =~ /^(\s*?\S+\s*?\S+\s*?\S+\s*?\S+\s*?)(\S+\s*?)\S+/; - my ($pos1, $pos2) = (length($1), length($1) + length($2)); foreach my $line (@lines) { - $line =~ /^(\s*?\S+\s*?)(\S+\s*?)(\S+\s*?)(\S+\s*?)/; - my ($elapsed, $pid, $ppid, $state) = ($1, $2, $3, $4); - my $cmd = substr($line, $pos1, $pos2 - $pos1); - my $args = substr($line, $pos2); + next if ($line !~ /^(.*?)===(.*?)===(.*?)===(.*?)===(.*?)===(.*)$/); + my ($state, $elapsed, $pid, $ppid, $cmd, $args) = ($1, $2, $3, $4, $5, $6); - $self->{result}->{centreon::plugins::misc::trim($pid)} = {ppid => centreon::plugins::misc::trim($ppid), - state => centreon::plugins::misc::trim($state), - elapsed => centreon::plugins::misc::trim($elapsed), - cmd => centreon::plugins::misc::trim($cmd), - args => centreon::plugins::misc::trim($args)}; + $self->{result}->{centreon::plugins::misc::trim($pid)} = { + ppid => centreon::plugins::misc::trim($ppid), + state => centreon::plugins::misc::trim($state), + elapsed => centreon::plugins::misc::trim($elapsed), + cmd => centreon::plugins::misc::trim($cmd), + args => centreon::plugins::misc::trim($args) + }; } } @@ -155,7 +153,7 @@ sub run { $self->{result}->{$pid}->{args} !~ /$self->{option_results}->{filter_arg}/); next if (defined($self->{option_results}->{filter_state}) && $self->{option_results}->{filter_state} ne '' && $state_map{$self->{result}->{$pid}->{state}} !~ /$self->{option_results}->{filter_state}/i); - next if (defined($self->{option_results}->{filter_ppid}) && $self->{option_results}->{filter_ppid} ne '' && + next if (defined($self->{option_results}->{filter_ppid}) && $self->{option_results}->{filter_ppid} ne '' && $self->{result}->{$pid}->{ppid} !~ /$self->{option_results}->{filter_ppid}/); $self->{output}->output_add(long_msg => 'Process: [command => ' . $self->{result}->{$pid}->{cmd} . @@ -228,7 +226,7 @@ Command path (Default: none). =item B<--command-options> -Command options (Default: '-e -o etime,pid,ppid,state,comm,args -w 2>&1'). +Command options (Default: '-e -o state -o ===%t===%p===%P=== -o comm:50 -o ===%a -w 2>&1'). =item B<--warning> diff --git a/os/linux/local/mode/quota.pm b/os/linux/local/mode/quota.pm index 45bb928c5..a1a3824b2 100644 --- a/os/linux/local/mode/quota.pm +++ b/os/linux/local/mode/quota.pm @@ -26,8 +26,6 @@ use strict; use warnings; use centreon::plugins::misc; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; @@ -83,8 +81,8 @@ sub custom_usage_calc { $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label_ref} . '_used'}; $self->{result_values}->{warn_label} = $self->{label}; - if (defined($instance_mode->{option_results}->{'warning-' . $self->{label}}) && $instance_mode->{option_results}->{'warning-' . $self->{label}} ne '') { - $self->{result_values}->{warn_limit} = $instance_mode->{option_results}->{'warning-' . $self->{label}}; + if (defined($self->{instance_mode}->{option_results}->{'warning-' . $self->{label}}) && $self->{instance_mode}->{option_results}->{'warning-' . $self->{label}} ne '') { + $self->{result_values}->{warn_limit} = $self->{instance_mode}->{option_results}->{'warning-' . $self->{label}}; } elsif ($options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label_ref} . '_soft'} > 0) { $self->{result_values}->{warn_limit} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label_ref} . '_soft'}; $self->{perfdata}->threshold_validate(label => 'warning-' . $self->{label} . '_' . $self->{result_values}->{display}, value => $self->{result_values}->{warn_limit}); @@ -92,8 +90,8 @@ sub custom_usage_calc { } $self->{result_values}->{crit_label} = $self->{label}; - if (defined($instance_mode->{option_results}->{'critical-' . $self->{label}}) && $instance_mode->{option_results}->{'critical-' . $self->{label}} ne '') { - $self->{result_values}->{crit_limit} = $instance_mode->{option_results}->{'critical-' . $self->{label}}; + if (defined($self->{instance_mode}->{option_results}->{'critical-' . $self->{label}}) && $self->{instance_mode}->{option_results}->{'critical-' . $self->{label}} ne '') { + $self->{result_values}->{crit_limit} = $self->{instance_mode}->{option_results}->{'critical-' . $self->{label}}; } elsif ($options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label_ref} . '_hard'} > 0) { $self->{result_values}->{crit_limit} = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label_ref} . '_hard'} - 1; $self->{perfdata}->threshold_validate(label => 'critical-' . $self->{label} . '_' . $self->{result_values}->{display}, value => $self->{result_values}->{crit_limit}); @@ -141,32 +139,25 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'repquota' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '-a -i 2>&1' }, - "filter-user:s" => { name => 'filter_user', }, - "filter-fs:s" => { name => 'filter_fs', }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'repquota' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-a -i 2>&1' }, + "filter-user:s" => { name => 'filter_user', }, + "filter-fs:s" => { name => 'filter_fs', }, + }); + $self->{result} = {}; return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/os/linux/local/mode/storage.pm b/os/linux/local/mode/storage.pm index 242a92140..1cc50e19e 100644 --- a/os/linux/local/mode/storage.pm +++ b/os/linux/local/mode/storage.pm @@ -26,30 +26,30 @@ use strict; use warnings; use centreon::plugins::misc; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -57,12 +57,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -127,38 +127,31 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'df' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '-P -k -T 2>&1' }, - "filter-type:s" => { name => 'filter_type', }, - "filter-fs:s" => { name => 'filter_fs', }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - "space-reservation:s" => { name => 'space_reservation' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'df' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-P -k -T 2>&1' }, + "filter-type:s" => { name => 'filter_type', }, + "filter-fs:s" => { name => 'filter_fs', }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "name:s" => { name => 'name' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + "space-reservation:s" => { name => 'space_reservation' }, + }); + $self->{result} = {}; return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; @@ -299,4 +292,4 @@ The value is in percent of total (Default: none). =back -=cut \ No newline at end of file +=cut diff --git a/os/linux/local/mode/traffic.pm b/os/linux/local/mode/traffic.pm index ce7eaab56..f8df4ee70 100644 --- a/os/linux/local/mode/traffic.pm +++ b/os/linux/local/mode/traffic.pm @@ -20,74 +20,181 @@ package os::linux::local::mode::traffic; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::misc; -use centreon::plugins::statefile; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); use Digest::MD5 qw(md5_hex); +use centreon::plugins::misc; + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf('status : %s', $self->{result_values}->{status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_traffic_perfdata { + my ($self, %options) = @_; + + my ($warning, $critical); + if ($self->{instance_mode}->{option_results}->{units} eq '%' && defined($self->{result_values}->{speed})) { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{speed}, cast_int => 1); + } elsif ($self->{instance_mode}->{option_results}->{units} eq 'b/s') { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}); + } + + $self->{output}->perfdata_add( + label => 'traffic_' . $self->{result_values}->{label}, unit => 'b/s', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + 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 ($self->{instance_mode}->{option_results}->{units} eq '%' && defined($self->{result_values}->{speed})) { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); + } elsif ($self->{instance_mode}->{option_results}->{units} eq 'b/s') { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_per_seconds}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); + } + return $exit; +} + +sub custom_traffic_output { + my ($self, %options) = @_; + + 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)", + ucfirst($self->{result_values}->{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}}); + + $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}} ne '' && + $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 set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'interface', type => 1, cb_prefix_output => 'prefix_interface_output', message_multiple => 'All interfaces are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{interface} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { 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 => \&catalog_status_threshold, + } + }, + { label => 'in', set => { + key_values => [ { name => 'in', 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' }, + closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic In : %s', + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }, + { label => 'out', set => { + key_values => [ { name => 'out', 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' }, + closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic Out : %s', + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }, + ]; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'ifconfig' }, - "command-path:s" => { name => 'command_path', default => '/sbin' }, - "command-options:s" => { name => 'command_options', default => '-a 2>&1' }, - "filter-state:s" => { name => 'filter_state', }, - "warning-in:s" => { name => 'warning_in' }, - "critical-in:s" => { name => 'critical_in' }, - "warning-out:s" => { name => 'warning_out' }, - "critical-out:s" => { name => 'critical_out' }, - "units:s" => { name => 'units', default => 'B' }, - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - "speed:s" => { name => 'speed' }, - "no-loopback" => { name => 'no_loopback', }, - "skip" => { name => 'skip' }, - }); - $self->{result} = {}; - $self->{hostname} = undef; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'ip' }, + "command-path:s" => { name => 'command_path', default => '/sbin' }, + "command-options:s" => { name => 'command_options', default => '-s addr 2>&1' }, + "filter-state:s" => { name => 'filter_state', }, + "units:s" => { name => 'units', default => 'b/s' }, + "name:s" => { name => 'name' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + "speed:s" => { name => 'speed' }, + "no-loopback" => { name => 'no_loopback', }, + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} ne "RU"' }, + }); + return $self; } +sub prefix_interface_output { + my ($self, %options) = @_; + + return "Interface '" . $options{instance_value}->{display} . "' "; +} + sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->SUPER::check_options(%options); - if (($self->{perfdata}->threshold_validate(label => 'warning-in', value => $self->{option_results}->{warning_in})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning 'in' threshold '" . $self->{option_results}->{warning_in} . "'."); - $self->{output}->option_exit(); + $self->{hostname} = $self->{option_results}->{hostname}; + if (!defined($self->{hostname})) { + $self->{hostname} = 'me'; } - if (($self->{perfdata}->threshold_validate(label => 'critical-in', value => $self->{option_results}->{critical_in})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical 'in' threshold '" . $self->{option_results}->{critical_in} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'warning-out', value => $self->{option_results}->{warning_out})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning 'out' threshold '" . $self->{option_results}->{warning_out} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical-out', value => $self->{option_results}->{critical_out})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical 'out' threshold '" . $self->{option_results}->{critical_out} . "'."); - $self->{output}->option_exit(); - } - if (defined($self->{option_results}->{speed}) && $self->{option_results}->{speed} ne '' && $self->{option_results}->{speed} !~ /^[0-9]+(\.[0-9]+){0,1}$/) { - $self->{output}->add_option_msg(short_msg => "Speed must be a positive number '" . $self->{option_results}->{speed} . "' (can be a float also)."); - $self->{output}->option_exit(); + if (defined($self->{option_results}->{speed}) && $self->{option_results}->{speed} ne '') { + if ($self->{option_results}->{speed} !~ /^[0-9]+(\.[0-9]+){0,1}$/) { + $self->{output}->add_option_msg(short_msg => "Speed must be a positive number '" . $self->{option_results}->{speed} . "' (can be a float also)."); + $self->{output}->option_exit(); + } else { + $self->{option_results}->{speed} *= 1000000; + } } if (defined($self->{option_results}->{units}) && $self->{option_results}->{units} eq '%' && (!defined($self->{option_results}->{speed}) || $self->{option_results}->{speed} eq '')) { @@ -95,27 +202,35 @@ sub check_options { $self->{output}->option_exit(); } - $self->{statefile_value}->check_options(%options); - $self->{hostname} = $self->{option_results}->{hostname}; - if (!defined($self->{hostname})) { - $self->{hostname} = 'me'; - } + $self->change_macros(macros => ['unknown_status', 'warning_status', 'critical_status']); } -sub manage_selection { +sub do_selection { my ($self, %options) = @_; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - while ($stdout =~ /^(\S+)(.*?)(\n\n|\n$)/msg) { + $self->{interface} = {}; + my $stdout = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options} + ); + + # ifconfig + my $interface_pattern = '^(\S+)(.*?)(\n\n|\n$)'; + if ($stdout =~ /^\d+:\s+\S+:\s+{option_results}->{no_loopback}) && $values =~ /LOOPBACK/ms); @@ -129,148 +244,36 @@ sub manage_selection { next if (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $interface_name ne $self->{option_results}->{name}); - if ($values =~ /RX bytes:(\S+).*?TX bytes:(\S+)/msi || $values =~ /RX packets\s+\d+\s+bytes\s+(\S+).*?TX packets\s+\d+\s+bytes\s+(\S+)/msi) { - $self->{result}->{$interface_name} = {state => $states, in => $1, out => $2}; + $self->{interface}->{$interface_name} = { + display => $interface_name, + status => $states, + speed_in => defined($self->{option_results}->{speed}) ? $self->{option_results}->{speed} : '', + speed_out => defined($self->{option_results}->{speed}) ? $self->{option_results}->{speed} : '', + }; + + # ip addr patterns + if ($values =~ /RX:\s+bytes.*?(\d+).*?TX: bytes.*?(\d+)/msi) { + $self->{interface}->{$interface_name}->{in} = $1; + $self->{interface}->{$interface_name}->{out} = $2; + } elsif ($values =~ /RX bytes:(\S+).*?TX bytes:(\S+)/msi || $values =~ /RX packets\s+\d+\s+bytes\s+(\S+).*?TX packets\s+\d+\s+bytes\s+(\S+)/msi) { + $self->{interface}->{$interface_name}->{in} = $1; + $self->{interface}->{$interface_name}->{out} = $2; } } - if (scalar(keys %{$self->{result}}) <= 0) { - if (defined($self->{option_results}->{name})) { - $self->{output}->add_option_msg(short_msg => "No interface found for name '" . $self->{option_results}->{name} . "'."); - } else { - $self->{output}->add_option_msg(short_msg => "No interface found."); - } + if (scalar(keys %{$self->{interface}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No interface found."); $self->{output}->option_exit(); } } -sub run { +sub manage_selection { my ($self, %options) = @_; - - $self->manage_selection(); - my $new_datas = {}; - $self->{statefile_value}->read(statefile => "cache_linux_local_" . $self->{hostname} . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $new_datas->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All traffic are ok.'); - } - - foreach my $name (sort(keys %{$self->{result}})) { - - if ($self->{result}->{$name}->{state} !~ /RU/) { - if (!defined($self->{option_results}->{skip})) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => "Interface '" . $name . "' is not up or/and running"); - } else { - # Avoid getting "buffer creation..." alone - if (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Interface '" . $name . "' is not up or/and running (normal state)"); - } - $self->{output}->output_add(long_msg => "Skip interface '" . $name . "': not up or/and running."); - } - next; - } - - # Some interface are running but not have bytes in/out - if (!defined($self->{result}->{$name}->{in})) { - if (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Interface '" . $name . "' is up and running but can't get traffic (no values)"); - } - $self->{output}->output_add(long_msg => "Skip interface '" . $name . "': can't get traffic."); - next; - } - - $new_datas->{'in_' . $name} = $self->{result}->{$name}->{in} * 8; - $new_datas->{'out_' . $name} = $self->{result}->{$name}->{out} * 8; - - my $old_in = $self->{statefile_value}->get(name => 'in_' . $name); - my $old_out = $self->{statefile_value}->get(name => 'out_' . $name); - if (!defined($old_timestamp) || !defined($old_in) || !defined($old_out)) { - next; - } - if ($new_datas->{'in_' . $name} < $old_in) { - # We set 0. Has reboot. - $old_in = 0; - } - if ($new_datas->{'out_' . $name} < $old_out) { - # We set 0. Has reboot. - $old_out = 0; - } - - my $time_delta = $new_datas->{last_timestamp} - $old_timestamp; - if ($time_delta <= 0) { - # At least one second. two fast calls ;) - $time_delta = 1; - } - my $in_absolute_per_sec = ($new_datas->{'in_' . $name} - $old_in) / $time_delta; - my $out_absolute_per_sec = ($new_datas->{'out_' . $name} - $old_out) / $time_delta; - - my ($exit, $interface_speed, $in_prct, $out_prct); - if (defined($self->{option_results}->{speed}) && $self->{option_results}->{speed} ne '') { - $interface_speed = $self->{option_results}->{speed} * 1000000; - $in_prct = $in_absolute_per_sec * 100 / ($self->{option_results}->{speed} * 1000000); - $out_prct = $out_absolute_per_sec * 100 / ($self->{option_results}->{speed} * 1000000); - if ($self->{option_results}->{units} eq '%') { - my $exit1 = $self->{perfdata}->threshold_check(value => $in_prct, threshold => [ { label => 'critical-in', 'exit_litteral' => 'critical' }, { label => 'warning-in', exit_litteral => 'warning' } ]); - my $exit2 = $self->{perfdata}->threshold_check(value => $out_prct, threshold => [ { label => 'critical-out', 'exit_litteral' => 'critical' }, { label => 'warning-out', exit_litteral => 'warning' } ]); - $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2 ]); - } - $in_prct = sprintf("%.2f", $in_prct); - $out_prct = sprintf("%.2f", $out_prct); - } else { - $in_prct = '-'; - $out_prct = '-'; - } - if ($self->{option_results}->{units} ne '%') { - my $exit1 = $self->{perfdata}->threshold_check(value => $in_absolute_per_sec, threshold => [ { label => 'critical-in', 'exit_litteral' => 'critical' }, { label => 'warning-in', exit_litteral => 'warning' } ]); - my $exit2 = $self->{perfdata}->threshold_check(value => $out_absolute_per_sec, threshold => [ { label => 'critical-out', 'exit_litteral' => 'critical' }, { label => 'warning-out', exit_litteral => 'warning' } ]); - $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2 ]); - } - - ########### - # Manage Output - ########### - - my ($in_value, $in_unit) = $self->{perfdata}->change_bytes(value => $in_absolute_per_sec, network => 1); - my ($out_value, $out_unit) = $self->{perfdata}->change_bytes(value => $out_absolute_per_sec, network => 1); - $self->{output}->output_add(long_msg => sprintf("Interface '%s' Traffic In : %s/s (%s %%), Out : %s/s (%s %%) ", $name, - $in_value . $in_unit, $in_prct, - $out_value . $out_unit, $out_prct)); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp}))) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Interface '%s' Traffic In : %s/s (%s %%), Out : %s/s (%s %%) ", $name, - $in_value . $in_unit, $in_prct, - $out_value . $out_unit, $out_prct)); - } - - my $extra_label = ''; - $extra_label = '_' . $name if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})); - $self->{output}->perfdata_add(label => 'traffic_in' . $extra_label, unit => 'b/s', - value => sprintf("%.2f", $in_absolute_per_sec), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-in', total => $interface_speed), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-in', total => $interface_speed), - min => 0, max => $interface_speed); - $self->{output}->perfdata_add(label => 'traffic_out' . $extra_label, unit => 'b/s', - value => sprintf("%.2f", $out_absolute_per_sec), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-out', total => $interface_speed), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-out', total => $interface_speed), - min => 0, max => $interface_speed); - } - - $self->{statefile_value}->write(data => $new_datas); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - } - - $self->{output}->display(); - $self->{output}->exit(); + $self->do_selection(); + $self->{cache_name} = "cache_linux_local_" . $self->{hostname} . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all')); } 1; @@ -313,7 +316,7 @@ Use 'sudo' to execute the command. =item B<--command> -Command to get information (Default: 'ifconfig'). +Command to get information (Default: 'ip'). Can be changed if you have output in a file. =item B<--command-path> @@ -322,7 +325,7 @@ Command path (Default: '/sbin'). =item B<--command-options> -Command options (Default: '-a 2>&1'). +Command options (Default: '-s addr 2>&1'). =item B<--warning-in> @@ -340,9 +343,24 @@ Threshold warning in percent for 'out' traffic. Threshold critical in percent for 'out' traffic. +=item B<--unknown-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=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} ne "RU"'). +Can used special variables like: %{status}, %{display} + =item B<--units> -Units of thresholds (Default: 'B') ('%', 'B'). +Units of thresholds (Default: 'b/s') ('%', 'b/s'). Percent can be used only if --speed is set. =item B<--name> @@ -361,10 +379,6 @@ Allows to use regexp non case-sensitive (with --regexp). Filter interfaces type (regexp can be used). -=item B<--skip> - -Skip errors on interface status (not up and running). - =item B<--speed> Set interface speed (in Mb). diff --git a/os/linux/local/plugin.pm b/os/linux/local/plugin.pm index 8e3780868..7fdb99f7e 100644 --- a/os/linux/local/plugin.pm +++ b/os/linux/local/plugin.pm @@ -31,32 +31,34 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'cpu' => 'os::linux::local::mode::cpu', - 'cpu-detailed' => 'os::linux::local::mode::cpudetailed', - 'cmd-return' => 'os::linux::local::mode::cmdreturn', - 'connections' => 'os::linux::local::mode::connections', - 'directlvm-usage' => 'os::linux::local::mode::directlvmusage', - 'diskio' => 'os::linux::local::mode::diskio', - 'files-size' => 'os::linux::local::mode::filessize', - 'files-date' => 'os::linux::local::mode::filesdate', - 'inodes' => 'os::linux::local::mode::inodes', - 'load' => 'os::linux::local::mode::loadaverage', - 'list-interfaces' => 'os::linux::local::mode::listinterfaces', - 'list-partitions' => 'os::linux::local::mode::listpartitions', - 'list-storages' => 'os::linux::local::mode::liststorages', - 'memory' => 'os::linux::local::mode::memory', - 'mountpoint' => 'os::linux::local::mode::mountpoint', - 'packet-errors' => 'os::linux::local::mode::packeterrors', - 'paging' => 'os::linux::local::mode::paging', - 'pending-updates' => 'os::linux::local::mode::pendingupdates', - 'process' => 'os::linux::local::mode::process', - 'quota' => 'os::linux::local::mode::quota', - 'storage' => 'os::linux::local::mode::storage', - 'swap' => 'os::linux::local::mode::swap', - 'systemd-sc-status' => 'os::linux::local::mode::systemdscstatus', - 'traffic' => 'os::linux::local::mode::traffic', - 'uptime' => 'os::linux::local::mode::uptime', - ); + 'cpu' => 'os::linux::local::mode::cpu', + 'cpu-detailed' => 'os::linux::local::mode::cpudetailed', + 'cmd-return' => 'os::linux::local::mode::cmdreturn', + 'connections' => 'os::linux::local::mode::connections', + 'directlvm-usage' => 'os::linux::local::mode::directlvmusage', + 'discovery-snmp' => 'os::linux::local::mode::discoverysnmp', + 'diskio' => 'os::linux::local::mode::diskio', + 'files-size' => 'os::linux::local::mode::filessize', + 'files-date' => 'os::linux::local::mode::filesdate', + 'inodes' => 'os::linux::local::mode::inodes', + 'load' => 'os::linux::local::mode::loadaverage', + 'list-interfaces' => 'os::linux::local::mode::listinterfaces', + 'list-partitions' => 'os::linux::local::mode::listpartitions', + 'list-storages' => 'os::linux::local::mode::liststorages', + 'memory' => 'os::linux::local::mode::memory', + 'mountpoint' => 'os::linux::local::mode::mountpoint', + 'ntp' => 'os::linux::local::mode::ntp', + 'packet-errors' => 'os::linux::local::mode::packeterrors', + 'paging' => 'os::linux::local::mode::paging', + 'pending-updates' => 'os::linux::local::mode::pendingupdates', + 'process' => 'os::linux::local::mode::process', + 'quota' => 'os::linux::local::mode::quota', + 'storage' => 'os::linux::local::mode::storage', + 'swap' => 'os::linux::local::mode::swap', + 'systemd-sc-status' => 'os::linux::local::mode::systemdscstatus', + 'traffic' => 'os::linux::local::mode::traffic', + 'uptime' => 'os::linux::local::mode::uptime', + ); return $self; } diff --git a/os/linux/snmp/plugin.pm b/os/linux/snmp/plugin.pm index 1ceb540f7..2f150a692 100644 --- a/os/linux/snmp/plugin.pm +++ b/os/linux/snmp/plugin.pm @@ -31,24 +31,24 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'cpu' => 'snmp_standard::mode::cpu', - 'cpu-detailed' => 'snmp_standard::mode::cpudetailed', - 'diskio' => 'snmp_standard::mode::diskio', - 'disk-usage' => 'snmp_standard::mode::diskusage', - 'inodes' => 'snmp_standard::mode::inodes', - 'interfaces' => 'snmp_standard::mode::interfaces', - 'load' => 'snmp_standard::mode::loadaverage', - 'list-diskspath' => 'snmp_standard::mode::listdiskspath', - 'list-interfaces' => 'snmp_standard::mode::listinterfaces', - 'list-storages' => 'snmp_standard::mode::liststorages', - 'memory' => 'snmp_standard::mode::memory', - 'processcount' => 'snmp_standard::mode::processcount', - 'storage' => 'snmp_standard::mode::storage', - 'swap' => 'snmp_standard::mode::swap', - 'time' => 'snmp_standard::mode::ntp', - 'tcpcon' => 'snmp_standard::mode::tcpcon', - 'uptime' => 'snmp_standard::mode::uptime', - ); + 'cpu' => 'snmp_standard::mode::cpu', + 'cpu-detailed' => 'snmp_standard::mode::cpudetailed', + 'diskio' => 'snmp_standard::mode::diskio', + 'disk-usage' => 'snmp_standard::mode::diskusage', + 'inodes' => 'snmp_standard::mode::inodes', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'load' => 'snmp_standard::mode::loadaverage', + 'list-diskspath' => 'snmp_standard::mode::listdiskspath', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-storages' => 'snmp_standard::mode::liststorages', + 'memory' => 'snmp_standard::mode::memory', + 'processcount' => 'snmp_standard::mode::processcount', + 'storage' => 'snmp_standard::mode::storage', + 'swap' => 'snmp_standard::mode::swap', + 'time' => 'snmp_standard::mode::ntp', + 'tcpcon' => 'snmp_standard::mode::tcpcon', + 'uptime' => 'snmp_standard::mode::uptime', + ); return $self; } diff --git a/os/windows/local/mode/ntp.pm b/os/windows/local/mode/ntp.pm index 07446ed19..dae5b5453 100644 --- a/os/windows/local/mode/ntp.pm +++ b/os/windows/local/mode/ntp.pm @@ -37,14 +37,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "ntp-hostname:s" => { name => 'ntp_hostname' }, - "ntp-port:s" => { name => 'ntp_port', default => 123 }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "timeout:s" => { name => 'timeout', default => 30 }, - }); + $options{options}->add_options(arguments => { + 'ntp-hostname:s' => { name => 'ntp_hostname' }, + 'ntp-port:s' => { name => 'ntp_port', default => 123 }, + 'warning:s' => { name => 'warning' }, + 'critical:s' => { name => 'critical' }, + 'timeout:s' => { name => 'timeout', default => 30 }, + }); + return $self; } @@ -53,12 +53,28 @@ sub check_options { $self->SUPER::init(%options); if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); } if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub check_ntp_query { + my ($self, %options) = @_; + + my ($stdout) = centreon::plugins::misc::windows_execute( + output => $self->{output}, + timeout => $self->{option_results}->{timeout}, + command => 'w32tm /query /status', + command_path => undef, + command_options => undef, + no_quit => 1 + ); + if ($stdout =~ /^Source:\s+(\S+)/mi) { + return $1; } } @@ -67,11 +83,13 @@ sub run { my $ntp_hostname = $self->{option_results}->{ntp_hostname}; if (!defined($ntp_hostname)) { - my ($stdout) = centreon::plugins::misc::windows_execute(output => $self->{output}, - timeout => $self->{option_results}->{timeout}, - command => 'w32tm /dumpreg /subkey:parameters', - command_path => undef, - command_options => undef); + my ($stdout) = centreon::plugins::misc::windows_execute( + output => $self->{output}, + timeout => $self->{option_results}->{timeout}, + command => 'w32tm /dumpreg /subkey:parameters', + command_path => undef, + command_options => undef + ); my ($type, $ntp_server); $stdout =~ /^Type\s+\S+\s+(\S+)/mi; $type = $1; @@ -85,16 +103,19 @@ sub run { # AllSync: The client synchronizes time from any available time source, including domain hierarchy and external time sources if ($type =~ /NoSync/i) { $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("No ntp configuration set. Please use --ntp-hostname or set windows ntp configuration.")); + short_msg => sprintf('No ntp configuration set. Please use --ntp-hostname or set windows ntp configuration.')); $self->{output}->display(); $self->{output}->exit(); + } elsif ($type =~ /NT5DS/i) { + $ntp_server = $self->check_ntp_query(); } if (!defined($ntp_server)) { $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("Cannot get ntp source configuration (it uses AD). Please use --ntp-hostname.")); + short_msg => sprintf('Cannot get ntp source configuration. Please use --ntp-hostname.')); $self->{output}->display(); $self->{output}->exit(); } + $ntp_hostname = $ntp_server; } @@ -117,13 +138,14 @@ sub run { my $exit = $self->{perfdata}->threshold_check(value => $diff, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Time offset %.3f second(s)", $diff)); + short_msg => sprintf('Time offset %.3f second(s)', $diff)); - $self->{output}->perfdata_add(label => 'offset', unit => 's', - value => sprintf("%.3f", $diff), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - ); + $self->{output}->perfdata_add( + label => 'offset', unit => 's', + value => sprintf("%.3f", $diff), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + ); $self->{output}->display(); $self->{output}->exit(); diff --git a/os/windows/snmp/mode/memory.pm b/os/windows/snmp/mode/memory.pm index 968640234..61fbb4bfc 100644 --- a/os/windows/snmp/mode/memory.pm +++ b/os/windows/snmp/mode/memory.pm @@ -25,25 +25,24 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; - my $label = 'used'; + my ($label, $nlabel) = ('used', $self->{nlabel}); my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { - $label = 'free'; + if (defined($self->{instance_mode}->{option_results}->{free})) { + ($label, $nlabel) = 'memory.free.bytes'; $value_perf = $self->{result_values}->{free}; } my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } $self->{output}->perfdata_add(label => $label, + nlabel => $self->{nlabel}, value => $value_perf, unit => 'B', warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), @@ -55,10 +54,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); return $exit; @@ -94,7 +93,7 @@ sub set_counters { ]; $self->{maps_counters}->{memory} = [ - { label => 'memory', set => { + { label => 'memory', nlabel => 'memory.usage.bytes', set => { key_values => [ { name => 'used' }, { name => 'total' } ], closure_custom_calc => \&custom_usage_calc, closure_custom_output => \&custom_usage_output, @@ -108,7 +107,7 @@ sub set_counters { sub prefix_memory_output { my ($self, %options) = @_; - return "RAM "; + return "Ram "; } sub new { @@ -117,22 +116,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/os/windows/snmp/mode/swap.pm b/os/windows/snmp/mode/swap.pm index b713b606b..f074bf3fd 100644 --- a/os/windows/snmp/mode/swap.pm +++ b/os/windows/snmp/mode/swap.pm @@ -123,6 +123,7 @@ sub run { $swap_free_value . " " . $swap_free_unit, 100 - $prct_used)); $self->{output}->perfdata_add(label => "used", unit => 'B', + nlabel => 'swap.usage.bytes', value => $swap_used, warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size, cast_int => 1), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size, cast_int => 1), diff --git a/snmp_standard/mode/cpu.pm b/snmp_standard/mode/cpu.pm index 802ce37c3..beed16c03 100644 --- a/snmp_standard/mode/cpu.pm +++ b/snmp_standard/mode/cpu.pm @@ -34,7 +34,7 @@ sub set_counters { ]; $self->{maps_counters}->{cpu_avg} = [ - { label => 'average', set => { + { label => 'average', nlabel => 'cpu.utilization.percentage', set => { key_values => [ { name => 'average' }, { name => 'count' } ], output_template => '%.2f %%', perfdatas => [ @@ -46,7 +46,7 @@ sub set_counters { ]; $self->{maps_counters}->{cpu_core} = [ - { label => 'core', set => { + { label => 'core', nlabel => 'core.cpu.utilization.percentage', set => { key_values => [ { name => 'cpu' }, { name => 'display' } ], output_template => 'usage : %.2f %%', perfdatas => [ @@ -77,9 +77,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } diff --git a/snmp_standard/mode/cpudetailed.pm b/snmp_standard/mode/cpudetailed.pm index 8c94dccc0..7264536dc 100644 --- a/snmp_standard/mode/cpudetailed.pm +++ b/snmp_standard/mode/cpudetailed.pm @@ -20,175 +20,234 @@ package snmp_standard::mode::cpudetailed; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::statefile; +use Digest::MD5 qw(md5_hex); -my $oids = { - '.1.3.6.1.4.1.2021.11.50' => { counter => 'user', output => 'User %.2f %%' }, # ssCpuRawUser - '.1.3.6.1.4.1.2021.11.51' => { counter => 'nice', output => 'Nice %.2f %%' }, # ssCpuRawNice - '.1.3.6.1.4.1.2021.11.52' => { counter => 'system', output => 'System %.2f %%' }, # ssCpuRawSystem - '.1.3.6.1.4.1.2021.11.53' => { counter => 'idle', output => 'Idle %.2f %%' }, # ssCpuRawIdle - '.1.3.6.1.4.1.2021.11.54' => { counter => 'wait', output => 'Wait %.2f %%' }, # ssCpuRawWait - '.1.3.6.1.4.1.2021.11.55' => { counter => 'kernel', output => 'Kernel %.2f %%' }, # ssCpuRawKernel - '.1.3.6.1.4.1.2021.11.56' => { counter => 'interrupt', output => 'Interrupt %.2f %%' }, # ssCpuRawInterrupt - '.1.3.6.1.4.1.2021.11.61' => { counter => 'softirq', output => 'Soft Irq %.2f %%' }, # ssCpuRawSoftIRQ - '.1.3.6.1.4.1.2021.11.64' => { counter => 'steal', output => 'Steal %.2f %%' }, # ssCpuRawSteal - '.1.3.6.1.4.1.2021.11.65' => { counter => 'guest', output => 'Guest %.2f %%' }, # ssCpuRawGuest - '.1.3.6.1.4.1.2021.11.66' => { counter => 'guestnice', output => 'Guest Nice %.2f %%' }, # ssCpuRawGuestNice -}; +sub custom_cpu_calc { + my ($self, %options) = @_; + + return -10 if (!defined($options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}})); + if (!defined($options{old_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}})) { + $self->{error_msg} = "Buffer creation"; + return -1; + } + + if (!defined($self->{instance_mode}->{total_cpu})) { + $self->{instance_mode}->{total_cpu} = 0; + foreach (keys %{$options{new_datas}}) { + if (/$self->{instance}_/) { + my $new_total = $options{new_datas}->{$_}; + next if (!defined($options{old_datas}->{$_})); + my $old_total = $options{old_datas}->{$_}; + + my $diff_total = $new_total - $old_total; + if ($diff_total < 0) { + $self->{instance_mode}->{total_cpu} += $old_total; + } else { + $self->{instance_mode}->{total_cpu} += $diff_total; + } + } + } + } + + if ($self->{instance_mode}->{total_cpu} <= 0) { + $self->{error_msg} = "counter not moved"; + return -12; + } + + if ($options{old_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}} > $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}}) { + $options{old_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}} = 0; + } + $self->{result_values}->{prct_used} = + ($options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}} - + $options{old_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}}) * 100 / + $self->{instance_mode}->{total_cpu}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_cpu_output', skipped_code => { -10 => 1 } }, + ]; + $self->{maps_counters}->{global} = [ + { label => 'user', nlabel => 'cpu.user.utilization.percentage', set => { + key_values => [], + closure_custom_calc => $self->can('custom_cpu_calc'), closure_custom_calc_extra_options => { label_ref => 'ssCpuRawUser' }, + manual_keys => 1, + threshold_use => 'prct_used', output_use => 'prct_used', + output_template => 'User %.2f %%', + perfdatas => [ + { value => 'prct_used', template => '%.2f', min => 0 , max => 100, unit => '%' }, + ], + } + }, + { label => 'nice', nlabel => 'cpu.nice.utilization.percentage', set => { + key_values => [], + closure_custom_calc => $self->can('custom_cpu_calc'), closure_custom_calc_extra_options => { label_ref => 'ssCpuRawNice' }, + manual_keys => 1, + threshold_use => 'prct_used', output_use => 'prct_used', + output_template => 'Nice %.2f %%', + perfdatas => [ + { value => 'prct_used', template => '%.2f', min => 0 , max => 100, unit => '%' }, + ], + } + }, + { label => 'system', nlabel => 'cpu.system.utilization.percentage', set => { + key_values => [], + closure_custom_calc => $self->can('custom_cpu_calc'), closure_custom_calc_extra_options => { label_ref => 'ssCpuRawSystem' }, + manual_keys => 1, + threshold_use => 'prct_used', output_use => 'prct_used', + output_template => 'System %.2f %%', + perfdatas => [ + { value => 'prct_used', template => '%.2f', min => 0 , max => 100, unit => '%' }, + ], + } + }, + { label => 'idle', nlabel => 'cpu.idle.utilization.percentage', set => { + key_values => [], + closure_custom_calc => $self->can('custom_cpu_calc'), closure_custom_calc_extra_options => { label_ref => 'ssCpuRawIdle' }, + manual_keys => 1, + threshold_use => 'prct_used', output_use => 'prct_used', + output_template => 'Idle %.2f %%', + perfdatas => [ + { value => 'prct_used', template => '%.2f', min => 0 , max => 100, unit => '%' }, + ], + } + }, + { label => 'wait', nlabel => 'cpu.wait.utilization.percentage', set => { + key_values => [], + closure_custom_calc => $self->can('custom_cpu_calc'), closure_custom_calc_extra_options => { label_ref => 'ssCpuRawWait' }, + manual_keys => 1, + threshold_use => 'prct_used', output_use => 'prct_used', + output_template => 'Wait %.2f %%', + perfdatas => [ + { value => 'prct_used', template => '%.2f', min => 0 , max => 100, unit => '%' }, + ], + } + }, + { label => 'kernel', nlabel => 'cpu.kernel.utilization.percentage', set => { + key_values => [], + closure_custom_calc => $self->can('custom_cpu_calc'), closure_custom_calc_extra_options => { label_ref => 'ssCpuRawKernel' }, + manual_keys => 1, + threshold_use => 'prct_used', output_use => 'prct_used', + output_template => 'Kernel %.2f %%', + perfdatas => [ + { value => 'prct_used', template => '%.2f', min => 0 , max => 100, unit => '%' }, + ], + } + }, + { label => 'interrupt', nlabel => 'cpu.interrupt.utilization.percentage', set => { + key_values => [], + closure_custom_calc => $self->can('custom_cpu_calc'), closure_custom_calc_extra_options => { label_ref => 'ssCpuRawInterrupt' }, + manual_keys => 1, + threshold_use => 'prct_used', output_use => 'prct_used', + output_template => 'Interrupt %.2f %%', + perfdatas => [ + { value => 'prct_used', template => '%.2f', min => 0 , max => 100, unit => '%' }, + ], + } + }, + { label => 'softirq', nlabel => 'cpu.softirq.utilization.percentage', set => { + key_values => [], + closure_custom_calc => $self->can('custom_cpu_calc'), closure_custom_calc_extra_options => { label_ref => 'ssCpuRawSoftIRQ' }, + manual_keys => 1, + threshold_use => 'prct_used', output_use => 'prct_used', + output_template => 'Soft Irq %.2f %%', + perfdatas => [ + { value => 'prct_used', template => '%.2f', min => 0 , max => 100, unit => '%' }, + ], + } + }, + { label => 'steal', nlabel => 'cpu.steal.utilization.percentage', set => { + key_values => [], + closure_custom_calc => $self->can('custom_cpu_calc'), closure_custom_calc_extra_options => { label_ref => 'ssCpuRawSteal' }, + manual_keys => 1, + threshold_use => 'prct_used', output_use => 'prct_used', + output_template => 'Steal %.2f %%', + perfdatas => [ + { value => 'prct_used', template => '%.2f', min => 0 , max => 100, unit => '%' }, + ], + } + }, + { label => 'guest', nlabel => 'cpu.guest.utilization.percentage', set => { + key_values => [], + closure_custom_calc => $self->can('custom_cpu_calc'), closure_custom_calc_extra_options => { label_ref => 'ssCpuRawGuest' }, + manual_keys => 1, + threshold_use => 'prct_used', output_use => 'prct_used', + output_template => 'Guest %.2f %%', + perfdatas => [ + { value => 'prct_used', template => '%.2f', min => 0 , max => 100, unit => '%' }, + ], + } + }, + { label => 'guestnice', nlabel => 'cpu.guestnice.utilization.percentage', set => { + key_values => [], + closure_custom_calc => $self->can('custom_cpu_calc'), closure_custom_calc_extra_options => { label_ref => 'ssCpuRawGuestNice' }, + manual_keys => 1, + threshold_use => 'prct_used', output_use => 'prct_used', + output_template => 'Guest Nice %.2f %%', + perfdatas => [ + { value => 'prct_used', template => '%.2f', min => 0 , max => 100, unit => '%' }, + ], + } + }, + ]; +} + +sub prefix_cpu_output { + my ($self, %options) = @_; + + return 'CPU Usage: '; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; - + $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); - foreach (keys %{$oids}) { - $options{options}->add_options(arguments => { - 'warning-' . $oids->{$_}->{counter} . ':s' => { name => 'warning_' . $oids->{$_}->{counter} }, - 'critical-' . $oids->{$_}->{counter} . ':s' => { name => 'critical_' . $oids->{$_}->{counter} }, - }); - } - $self->{statefile_value} = centreon::plugins::statefile->new(%options); + $options{options}->add_options(arguments => { + }); + return $self; } -sub check_options { +my $mapping = { + ssCpuRawUser => { oid => '.1.3.6.1.4.1.2021.11.50' }, + ssCpuRawNice => { oid => '.1.3.6.1.4.1.2021.11.51' }, + ssCpuRawSystem => { oid => '.1.3.6.1.4.1.2021.11.52' }, + ssCpuRawIdle => { oid => '.1.3.6.1.4.1.2021.11.53' }, + ssCpuRawWait => { oid => '.1.3.6.1.4.1.2021.11.54' }, + ssCpuRawKernel => { oid => '.1.3.6.1.4.1.2021.11.55' }, + ssCpuRawInterrupt => { oid => '.1.3.6.1.4.1.2021.11.56' }, + ssCpuRawSoftIRQ => { oid => '.1.3.6.1.4.1.2021.11.61' }, + ssCpuRawSteal => { oid => '.1.3.6.1.4.1.2021.11.64' }, + ssCpuRawGuest => { oid => '.1.3.6.1.4.1.2021.11.65' }, + ssCpuRawGuestNice => { oid => '.1.3.6.1.4.1.2021.11.66' }, +}; + +sub manage_selection { my ($self, %options) = @_; - $self->SUPER::init(%options); - foreach (keys %{$oids}) { - if (($self->{perfdata}->threshold_validate(label => 'warning-' . $oids->{$_}->{counter}, value => $self->{option_results}->{'warning_' . $oids->{$_}->{counter}})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning-" . $oids->{$_}->{counter} . " threshold '" . $self->{option_results}->{'warning_' . $oids->{$_}->{counter}} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical-' . $oids->{$_}->{counter}, value => $self->{option_results}->{'critical_' . $oids->{$_}->{counter}})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical-" . $oids->{$_}->{counter} . " threshold '" . $self->{option_results}->{'critical_' . $oids->{$_}->{counter}} . "'."); - $self->{output}->option_exit(); - } - } - $self->{statefile_value}->check_options(%options); -} + my $oid_systemStats = '.1.3.6.1.4.1.2021.11'; + my $snmp_result = $options{snmp}->get_table( + oid => $oid_systemStats, + start => $mapping->{ssCpuRawUser}->{oid}, + nothing_quit => 1 + ); -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - my $result = $self->{snmp}->get_table(oid => '.1.3.6.1.4.1.2021.11', - start => '.1.3.6.1.4.1.2021.11.50', - nothing_quit => 1); - - # construct values - my $info_indexes = {}; - my $new_datas = {}; - my $old_datas = {}; - $new_datas->{last_timestamp} = time(); - $self->{statefile_value}->read(statefile => "snmpstandard_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode}); - - foreach my $oid (keys %{$result}) { - $oid =~ /(.*)\.(\d+)$/; - my ($oid_base, $index) = ($1, $2); - # If not, we skip oid - next if (!defined($oids->{$oid_base})); - - $new_datas->{$oids->{$oid_base}->{counter} . '_' . $index} = $result->{$oid}; - $old_datas->{$oids->{$oid_base}->{counter} . '_' . $index} = $self->{statefile_value}->get(name => $oids->{$oid_base}->{counter} . '_' . $index); - $info_indexes->{$index} = { total => 0, old_total => 0, buffer_creation => 0 } if (!defined($info_indexes->{$index})); - if (!defined($old_datas->{$oids->{$oid_base}->{counter} . '_' . $index})) { - $info_indexes->{$index}->{buffer_creation} = 1; - next; - } - if ($new_datas->{$oids->{$oid_base}->{counter} . '_' . $index} < $old_datas->{$oids->{$oid_base}->{counter} . '_' . $index}) { - $info_indexes->{$index}->{buffer_creation} = 1; - next; - } - $info_indexes->{$index}->{total} += $new_datas->{$oids->{$oid_base}->{counter} . '_' . $index}; - $info_indexes->{$index}->{old_total} += $old_datas->{$oids->{$oid_base}->{counter} . '_' . $index}; - } - $self->{statefile_value}->write(data => $new_datas); - - my $multiple = 0; - if (scalar(keys %$info_indexes) > 1) { - $multiple = 1; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => "All CPU usage are ok."); - } - - # Manage output - foreach my $index (keys %$info_indexes) { - if ($info_indexes->{$index}->{buffer_creation} == 1) { - if ($multiple == 0) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - } else { - $self->{output}->output_add(long_msg => "CPU '$index': Buffer creation..."); - } - next; - } - if ($info_indexes->{$index}->{total} - $info_indexes->{$index}->{old_total} == 0) { - if ($multiple == 0) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Counter not moved. Have to wait."); - } else { - $self->{output}->output_add(long_msg => "CPU '$index': Counter not moved. Have to wait."); - } - next; - } - - my @exits = (); - foreach my $oid (keys %{$result}) { - $oid =~ /(.*)\.(\d+)$/; - my ($oid_base, $index2) = ($1, $2); - # If not, we skip oid - next if ($index2 != $index || !defined($oids->{$oid_base})); - my $value = (($new_datas->{$oids->{$oid_base}->{counter} . '_' . $index} - $old_datas->{$oids->{$oid_base}->{counter} . '_' . $index}) * 100) / ($info_indexes->{$index}->{total} - $info_indexes->{$index}->{old_total}); - push @exits, $self->{perfdata}->threshold_check(value => $value, threshold => [ { label => 'critical-' . $oids->{$oid_base}->{counter}, 'exit_litteral' => 'critical' }, { label => 'warning-' . $oids->{$oid_base}->{counter}, 'exit_litteral' => 'warning' }]); - } + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => '0'); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - my $str_output = "CPU Usage: "; - $str_output = "CPU '$index' Usage: " if ($multiple == 1); - my $str_append = ''; - foreach my $oid (keys %{$result}) { - $oid =~ /(.*)\.(\d+)$/; - my ($oid_base, $index2) = ($1, $2); - # If not, we skip oid - next if ($index2 != $index || !defined($oids->{$oid_base})); - - my $value = (($new_datas->{$oids->{$oid_base}->{counter} . '_' . $index} - $old_datas->{$oids->{$oid_base}->{counter} . '_' . $index}) * 100) / ($info_indexes->{$index}->{total} - $info_indexes->{$index}->{old_total}); - $str_output .= $str_append . sprintf($oids->{$oid_base}->{output}, $value); - $str_append = ', '; - my $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $oids->{$oid_base}->{counter}); - my $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $oids->{$oid_base}->{counter}); + $self->{cache_name} = "snmpstandard_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); - my $extra_perf_label = ''; - $extra_perf_label = $index if ($multiple == 1); - $self->{output}->perfdata_add(label => $oids->{$oid_base}->{counter} . $extra_perf_label, unit => '%', - value => sprintf("%.2f", $value), - warning => $warning, - critical => $critical, - min => 0, max => 100); - } - if ($multiple == 0) { - $self->{output}->output_add(severity => $exit, - short_msg => $str_output); - } - $self->{output}->output_add(long_msg => $str_output); - } - - $self->{output}->display(); - $self->{output}->exit(); + $self->{global} = { %$result }; } 1; diff --git a/snmp_standard/mode/diskusage.pm b/snmp_standard/mode/diskusage.pm index 2a76d433c..7841bd3af 100644 --- a/snmp_standard/mode/diskusage.pm +++ b/snmp_standard/mode/diskusage.pm @@ -27,30 +27,30 @@ use warnings; use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -58,12 +58,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -86,10 +86,10 @@ sub custom_usage_calc { $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_size'}; my $reserved_value = 0; - if (defined($instance_mode->{option_results}->{space_reservation})) { - $reserved_value = $instance_mode->{option_results}->{space_reservation} * $self->{result_values}->{total} / 100; + if (defined($self->{instance_mode}->{option_results}->{space_reservation})) { + $reserved_value = $self->{instance_mode}->{option_results}->{space_reservation} * $self->{result_values}->{total} / 100; } - + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used} - $reserved_value; $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / ($self->{result_values}->{total} - $reserved_value); @@ -110,7 +110,7 @@ sub set_counters { $self->{maps_counters_type} = [ { name => 'global', type => 0, cb_init => 'skip_global' }, - { name => 'diskpath', type => 1, cb_prefix_output => 'prefix_diskpath_output', message_multiple => 'All partitions are ok' }, + { name => 'diskpath', type => 1, cb_prefix_output => 'prefix_diskpath_output', message_multiple => 'All partitions are ok', skipped_code => { -10 => 1 } }, ]; $self->{maps_counters}->{global} = [ @@ -132,6 +132,15 @@ sub set_counters { closure_custom_threshold_check => $self->can('custom_usage_threshold'), } }, + { label => 'inodes', set => { + key_values => [ { name => 'inodes' }, { name => 'display' } ], + output_template => 'Inodes Used: %s %%', + perfdatas => [ + { label => 'inodes', value => 'inodes_absolute', template => '%d', + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, ]; } @@ -153,21 +162,19 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - "reload-cache-time:s" => { name => 'reload_cache_time', default => 180 }, - "name" => { name => 'use_name' }, - "diskpath:s" => { name => 'diskpath' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - "display-transform-src:s" => { name => 'display_transform_src' }, - "display-transform-dst:s" => { name => 'display_transform_dst' }, - "show-cache" => { name => 'show_cache' }, - "space-reservation:s" => { name => 'space_reservation' }, - "filter-counters:s" => { name => 'filter_counters', default => 'usage' }, - }); + $options{options}->add_options(arguments => { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "reload-cache-time:s" => { name => 'reload_cache_time', default => 180 }, + "name" => { name => 'use_name' }, + "diskpath:s" => { name => 'diskpath' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + "display-transform-src:s" => { name => 'display_transform_src' }, + "display-transform-dst:s" => { name => 'display_transform_dst' }, + "show-cache" => { name => 'show_cache' }, + "space-reservation:s" => { name => 'space_reservation' }, + }); $self->{diskpath_id_selected} = []; $self->{statefile_cache} = centreon::plugins::statefile->new(%options); @@ -179,6 +186,10 @@ sub check_options { my ($self, %options) = @_; $self->SUPER::check_options(%options); + # compatibility + if (!defined($self->{option_results}->{filter_counters})) { + $self->{option_results}->{filter_counters} = 'usage'; + } if (defined($self->{option_results}->{space_reservation}) && ($self->{option_results}->{space_reservation} < 0 || $self->{option_results}->{space_reservation} > 100)) { $self->{output}->add_option_msg(short_msg => "Space reservation argument must be between 0 and 100 percent."); @@ -186,7 +197,6 @@ sub check_options { } $self->{statefile_cache}->check_options(%options); - $instance_mode = $self; } sub manage_selection { @@ -199,9 +209,15 @@ sub manage_selection { my $oid_dskTotalHigh = '.1.3.6.1.4.1.2021.9.1.12'; # in kB my $oid_dskUsedLow = '.1.3.6.1.4.1.2021.9.1.15'; # in kB my $oid_dskUsedHigh = '.1.3.6.1.4.1.2021.9.1.16'; # in kB + my $oid_dskPercentNode = '.1.3.6.1.4.1.2021.9.1.10'; - $self->{snmp}->load(oids => [$oid_dskTotalLow, $oid_dskTotalHigh, $oid_dskUsedLow, $oid_dskUsedHigh], - instances => $self->{diskpath_id_selected}, nothing_quit => 1); + $self->{snmp}->load( + oids => [ + $oid_dskTotalLow, $oid_dskTotalHigh, $oid_dskUsedLow, $oid_dskUsedHigh, $oid_dskPercentNode + ], + instances => $self->{diskpath_id_selected}, + nothing_quit => 1 + ); my $result = $self->{snmp}->get_leef(); $self->{global}->{count} = 0; @@ -210,14 +226,14 @@ sub manage_selection { my $name_diskpath = $self->get_display_value(id => $_); if (!defined($result->{$oid_dskTotalHigh . "." . $_})) { - $self->{output}->add_option_msg(long_msg => sprintf("Skipping partition '%s': not found (need to reload the cache)", + $self->{output}->add_option_msg(long_msg => sprintf("skipping partition '%s': not found (need to reload the cache)", $name_diskpath)); next; } my $total_size = (($result->{$oid_dskTotalHigh . "." . $_} << 32) + $result->{$oid_dskTotalLow . "." . $_}) * 1024; if ($total_size == 0) { - $self->{output}->output_add(long_msg => sprintf("Skipping partition '%s' (total size is 0)", $name_diskpath)); + $self->{output}->output_add(long_msg => sprintf("skipping partition '%s' (total size is 0)", $name_diskpath)); next; } my $total_used = (($result->{$oid_dskUsedHigh . "." . $_} << 32) + $result->{$oid_dskUsedLow . "." . $_}) * 1024; @@ -226,6 +242,7 @@ sub manage_selection { display => $name_diskpath, size => $total_size, used => $total_used, + inodes => defined($result->{$oid_dskPercentNode . "." . $_}) ? $result->{$oid_dskPercentNode . "." . $_} : undef, }; $self->{global}->{count}++; } @@ -333,15 +350,15 @@ Need to enable "includeAllDisks 10%" on snmpd.conf. =item B<--filter-counters> -Filter counters to be displayed (Default: 'usage', Can be: 'usage', 'count'). +Filter counters to be displayed (Default: 'usage', Can be: 'usage', 'count', 'inodes'). =item B<--warning-*> -Threshold warning (Can be: 'usage', 'count'). +Threshold warning (Can be: 'usage', 'inodes', 'count'). =item B<--critical-*> -Threshold warning (Can be: 'usage', 'count'). +Threshold warning (Can be: 'usage', 'inodes', 'count'). =item B<--units> diff --git a/snmp_standard/mode/inodes.pm b/snmp_standard/mode/inodes.pm index 13244e7c9..cee88b73d 100644 --- a/snmp_standard/mode/inodes.pm +++ b/snmp_standard/mode/inodes.pm @@ -33,7 +33,7 @@ sub set_counters { ]; $self->{maps_counters}->{disk} = [ - { label => 'usage', set => { + { label => 'usage', nlabel => 'storage.inodes.usage.percentage', set => { key_values => [ { name => 'usage' }, { name => 'display' } ], output_template => 'Used: %s %%', output_error_template => "%s", perfdatas => [ @@ -57,16 +57,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "name" => { name => 'use_name' }, - "diskpath:s" => { name => 'diskpath' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - "filter-device:s" => { name => 'filter_device' }, - "display-transform-src:s" => { name => 'display_transform_src' }, - "display-transform-dst:s" => { name => 'display_transform_dst' }, - }); + $options{options}->add_options(arguments => { + 'name' => { name => 'use_name' }, + 'diskpath:s' => { name => 'diskpath' }, + 'regexp' => { name => 'use_regexp' }, + 'regexp-isensitive' => { name => 'use_regexpi' }, + 'filter-device:s' => { name => 'filter_device' }, + 'display-transform-src:s' => { name => 'display_transform_src' }, + 'display-transform-dst:s' => { name => 'display_transform_dst' }, + }); return $self; } @@ -129,12 +128,14 @@ sub manage_selection { } - $self->{disk}->{$result->{dskPath}} = { display => $result->{dskPath}, - usage => $result->{dskPercentNode} }; + $self->{disk}->{$result->{dskPath}} = { + display => $result->{dskPath}, + usage => $result->{dskPercentNode} + }; } if (scalar(keys %{$self->{disk}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No entry found."); + $self->{output}->add_option_msg(short_msg => 'No entry found.'); $self->{output}->option_exit(); } } diff --git a/snmp_standard/mode/interfaces.pm b/snmp_standard/mode/interfaces.pm index 25d4cdd79..d9301749e 100644 --- a/snmp_standard/mode/interfaces.pm +++ b/snmp_standard/mode/interfaces.pm @@ -20,11 +20,10 @@ package snmp_standard::mode::interfaces; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); @@ -63,6 +62,9 @@ sub custom_threshold_output { sub custom_status_output { my ($self, %options) = @_; my $msg = 'Status : ' . $self->{result_values}->{opstatus} . ' (admin: ' . $self->{result_values}->{admstatus} . ')'; + if (defined($self->{instance_mode}->{option_results}->{add_duplex_status})) { + $msg .= ' (duplex: ' . $self->{result_values}->{duplexstatus} . ')'; + } return $msg; } @@ -72,6 +74,7 @@ sub custom_status_calc { $self->{result_values}->{opstatus} = $options{new_datas}->{$self->{instance} . '_opstatus'}; $self->{result_values}->{admstatus} = $options{new_datas}->{$self->{instance} . '_admstatus'}; + $self->{result_values}->{duplexstatus} = $options{new_datas}->{$self->{instance} . '_duplexstatus'}; $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; return 0; } @@ -105,10 +108,6 @@ sub custom_cast_calc { 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}; - } if (defined($self->{instance_mode}->{option_results}->{nagvis_perfdata})) { $self->{result_values}->{traffic_per_seconds} /= 8; $self->{result_values}->{speed} /= 8 if (defined($self->{result_values}->{speed})); @@ -124,17 +123,24 @@ sub custom_traffic_perfdata { } if (defined($self->{instance_mode}->{option_results}->{nagvis_perfdata})) { - $self->{output}->perfdata_add(label => $self->{result_values}->{label} . $extra_label, - value => sprintf("%.2f", $self->{result_values}->{traffic_per_seconds}), - warning => $warning, - critical => $critical, - min => 0, max => $self->{result_values}->{speed}); + $self->{output}->perfdata_add( + label => $self->{result_values}->{label}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{traffic_per_seconds}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed} + ); } else { - $self->{output}->perfdata_add(label => 'traffic_' . $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}); + $self->{output}->perfdata_add( + label => 'traffic_' . $self->{result_values}->{label}, unit => 'b/s', + nlabel => $self->{nlabel}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{traffic_per_seconds}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed} + ); } } @@ -143,9 +149,9 @@ sub custom_traffic_threshold { my $exit = 'ok'; if ($self->{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' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } elsif ($self->{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' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_per_seconds}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } return $exit; } @@ -191,23 +197,27 @@ sub custom_traffic_calc { # Errors sub custom_errors_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } + if ($self->{instance_mode}->{option_results}->{units_errors} eq '%') { - $self->{output}->perfdata_add(label => 'packets_' . $self->{result_values}->{label2} . '_' . $self->{result_values}->{label1} . $extra_label, unit => '%', - value => sprintf("%.2f", $self->{result_values}->{prct}), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}), - min => 0, max => 100); + $self->{output}->perfdata_add( + label => 'packets_' . $self->{result_values}->{label2} . '_' . $self->{result_values}->{label1}, unit => '%', + nlabel => 'interface.packets.' . $self->{result_values}->{label1} . '.' . $self->{result_values}->{label2} . 's.percentage', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{prct}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}), + min => 0, max => 100 + ); } else { - $self->{output}->perfdata_add(label => 'packets_' . $self->{result_values}->{label2} . '_' . $self->{result_values}->{label1} . $extra_label, - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'packets_' . $self->{result_values}->{label2} . '_' . $self->{result_values}->{label1}, + nlabel => $self->{nlabel}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}), + min => 0, max => $self->{result_values}->{total} + ); } } @@ -216,9 +226,9 @@ sub custom_errors_threshold { my $exit = 'ok'; if ($self->{instance_mode}->{option_results}->{units_errors} eq '%') { - $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } else { - $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); } return $exit; } @@ -226,8 +236,8 @@ sub custom_errors_threshold { sub custom_errors_output { my ($self, %options) = @_; - my $msg = sprintf("Packets %s %s : %.2f%% (%s)", - ucfirst($self->{result_values}->{label1}), ucfirst($self->{result_values}->{label2}), + my $msg = sprintf("Packets %s : %.2f%% (%s)", + $self->{result_values}->{label}, $self->{result_values}->{prct}, $self->{result_values}->{used}); return $msg; } @@ -253,6 +263,11 @@ sub custom_errors_calc { $self->{result_values}->{prct} = $total == 0 ? 0 : $diff * 100 / $total; $self->{result_values}->{used} = $diff; $self->{result_values}->{total} = $total; + if (defined($options{extra_options}->{label})) { + $self->{result_values}->{label} = $options{extra_options}->{label}; + } else { + $self->{result_values}->{label} = ucfirst($options{extra_options}->{label_ref1}) . ' ' . ucfirst($options{extra_options}->{label_ref2}); + } $self->{result_values}->{label1} = $options{extra_options}->{label_ref1}; $self->{result_values}->{label2} = $options{extra_options}->{label_ref2}; $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; @@ -270,79 +285,86 @@ sub custom_speed_calc { ######################### # OIDs mapping functions ######################### -sub set_counters { + +sub set_counters_global { my ($self, %options) = @_; - - $self->{maps_counters} = { int => {}, global => {} } if (!defined($self->{maps_counters})); - - $self->{maps_counters}->{global}->{'000_total-port'} = { filter => 'add_global', - set => { - key_values => [ { name => 'total_port' } ], - output_template => 'Total port : %s', output_error_template => 'Total port : %s', - output_use => 'total_port_absolute', threshold_use => 'total_port_absolute', - perfdatas => [ - { label => 'total_port', value => 'total_port_absolute', template => '%s', - min => 0, max => 'total_port_absolute' }, - ], - } - }; - $self->{maps_counters}->{global}->{'001_global-admin-up'} = { filter => 'add_global', - set => { - key_values => [ { name => 'global_admin_up' }, { name => 'total_port' } ], - output_template => 'AdminStatus Up : %s', output_error_template => 'AdminStatus Up : %s', - output_use => 'global_admin_up_absolute', threshold_use => 'global_admin_up_absolute', - perfdatas => [ - { label => 'total_admin_up', value => 'global_admin_up_absolute', template => '%s', - min => 0, max => 'total_port_absolute' }, - ], - } - }; - $self->{maps_counters}->{global}->{'002_total-admin-down'} = { filter => 'add_global', - set => { - key_values => [ { name => 'global_admin_down' }, { name => 'total_port' } ], - output_template => 'AdminStatus Down : %s', output_error_template => 'AdminStatus Down : %s', - output_use => 'global_admin_down_absolute', threshold_use => 'global_admin_down_absolute', - perfdatas => [ - { label => 'total_admin_down', value => 'global_admin_down_absolute', template => '%s', - min => 0, max => 'total_port_absolute' }, - ], - } - }; - $self->{maps_counters}->{global}->{'003_total-oper-up'} = { filter => 'add_global', - set => { - key_values => [ { name => 'global_oper_up' }, { name => 'total_port' } ], - output_template => 'OperStatus Up : %s', output_error_template => 'OperStatus Up : %s', - output_use => 'global_oper_up_absolute', threshold_use => 'global_oper_up_absolute', - perfdatas => [ - { label => 'total_oper_up', value => 'global_oper_up_absolute', template => '%s', - min => 0, max => 'total_port_absolute' }, - ], - } - }; - $self->{maps_counters}->{global}->{'004_total-oper-down'} = { filter => 'add_global', - set => { - key_values => [ { name => 'global_oper_down' }, { name => 'total_port' } ], - output_template => 'OperStatus Down : %s', output_error_template => 'OperStatus Down : %s', - output_use => 'global_oper_down_absolute', threshold_use => 'global_oper_down_absolute', - perfdatas => [ - { label => 'global_oper_down', value => 'global_oper_down_absolute', template => '%s', - min => 0, max => 'total_port_absolute' }, - ], - } - }; - - $self->{maps_counters}->{int}->{'000_status'} = { filter => 'add_status', threshold => 0, - set => { - key_values => $self->set_key_values_status(), - 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_threshold_output'), - } - }; - if ($self->{no_traffic} == 0 && $self->{no_set_traffic} == 0) { - $self->{maps_counters}->{int}->{'020_in-traffic'} = { filter => 'add_traffic', - set => { + + push @{$self->{maps_counters}->{global}}, + { label => 'total-port', filter => 'add_global', nlabel => 'total.interfaces.count', set => { + key_values => [ { name => 'total_port' } ], + output_template => 'Total port : %s', output_error_template => 'Total port : %s', + output_use => 'total_port_absolute', threshold_use => 'total_port_absolute', + perfdatas => [ + { label => 'total_port', value => 'total_port_absolute', template => '%s', + min => 0, max => 'total_port_absolute' }, + ], + } + }, + { label => 'global-admin-up', filter => 'add_global', nlabel => 'total.interfaces.admin.up.count', set => { + key_values => [ { name => 'global_admin_up' }, { name => 'total_port' } ], + output_template => 'AdminStatus Up : %s', output_error_template => 'AdminStatus Up : %s', + output_use => 'global_admin_up_absolute', threshold_use => 'global_admin_up_absolute', + perfdatas => [ + { label => 'total_admin_up', value => 'global_admin_up_absolute', template => '%s', + min => 0, max => 'total_port_absolute' }, + ], + } + }, + { label => 'total-admin-down', filter => 'add_global', nlabel => 'total.interfaces.admin.down.count', set => { + key_values => [ { name => 'global_admin_down' }, { name => 'total_port' } ], + output_template => 'AdminStatus Down : %s', output_error_template => 'AdminStatus Down : %s', + output_use => 'global_admin_down_absolute', threshold_use => 'global_admin_down_absolute', + perfdatas => [ + { label => 'total_admin_down', value => 'global_admin_down_absolute', template => '%s', + min => 0, max => 'total_port_absolute' }, + ], + } + }, + { label => 'total-oper-up', filter => 'add_global', nlabel => 'total.interfaces.operational.up.count', set => { + key_values => [ { name => 'global_oper_up' }, { name => 'total_port' } ], + output_template => 'OperStatus Up : %s', output_error_template => 'OperStatus Up : %s', + output_use => 'global_oper_up_absolute', threshold_use => 'global_oper_up_absolute', + perfdatas => [ + { label => 'total_oper_up', value => 'global_oper_up_absolute', template => '%s', + min => 0, max => 'total_port_absolute' }, + ], + } + }, + { label => 'total-oper-down', filter => 'add_global', nlabel => 'total.interfaces.operational.down.count', set => { + key_values => [ { name => 'global_oper_down' }, { name => 'total_port' } ], + output_template => 'OperStatus Down : %s', output_error_template => 'OperStatus Down : %s', + output_use => 'global_oper_down_absolute', threshold_use => 'global_oper_down_absolute', + perfdatas => [ + { label => 'global_oper_down', value => 'global_oper_down_absolute', template => '%s', + min => 0, max => 'total_port_absolute' }, + ], + } + }, + ; +} + +sub set_counters_status { + my ($self, %options) = @_; + + push @{$self->{maps_counters}->{int}}, + { label => 'status', filter => 'add_status', threshold => 0, set => { + key_values => $self->set_key_values_status(), + 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_threshold_output'), + } + }, + ; +} + +sub set_counters_traffic { + my ($self, %options) = @_; + + return if ($self->{no_traffic} != 0 && $self->{no_set_traffic} != 0); + + push @{$self->{maps_counters}->{int}}, + { label => 'in-traffic', filter => 'add_traffic', nlabel => 'interface.traffic.in.bitspersecond', set => { key_values => $self->set_key_values_in_traffic(), per_second => 1, closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'in' }, @@ -350,9 +372,8 @@ sub set_counters { closure_custom_perfdata => $self->can('custom_traffic_perfdata'), closure_custom_threshold_check => $self->can('custom_traffic_threshold'), } - }; - $self->{maps_counters}->{int}->{'021_out-traffic'} = { filter => 'add_traffic', - set => { + }, + { label => 'out-traffic', filter => 'add_traffic', nlabel => 'interface.traffic.out.bitspersecond', set => { key_values => $self->set_key_values_out_traffic(), per_second => 1, closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'out' }, @@ -360,49 +381,58 @@ sub set_counters { closure_custom_perfdata => $self->can('custom_traffic_perfdata'), closure_custom_threshold_check => $self->can('custom_traffic_threshold'), } - }; - } - if ($self->{no_errors} == 0 && $self->{no_set_errors} == 0) { - $self->{maps_counters}->{int}->{'040_in-discard'} = { filter => 'add_errors', - set => { + }, + ; +} + +sub set_counters_errors { + my ($self, %options) = @_; + + return if ($self->{no_errors} != 0 && $self->{no_set_errors} != 0); + + push @{$self->{maps_counters}->{int}}, + { label => 'in-discard', filter => 'add_errors', nlabel => 'interface.packets.in.discards.count', set => { key_values => [ { name => 'indiscard', diff => 1 }, { name => 'total_in_packets', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], closure_custom_calc => $self->can('custom_errors_calc'), closure_custom_calc_extra_options => { label_ref1 => 'in', label_ref2 => 'discard' }, closure_custom_output => $self->can('custom_errors_output'), output_error_template => 'Packets In Discard : %s', closure_custom_perfdata => $self->can('custom_errors_perfdata'), closure_custom_threshold_check => $self->can('custom_errors_threshold'), } - }; - $self->{maps_counters}->{int}->{'041_in-error'} = { filter => 'add_errors', - set => { + }, + { label => 'in-error', filter => 'add_errors', nlabel => 'interface.packets.in.errors.count', set => { key_values => [ { name => 'inerror', diff => 1 }, { name => 'total_in_packets', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], closure_custom_calc => $self->can('custom_errors_calc'), closure_custom_calc_extra_options => { label_ref1 => 'in', label_ref2 => 'error' }, closure_custom_output => $self->can('custom_errors_output'), output_error_template => 'Packets In Error : %s', closure_custom_perfdata => $self->can('custom_errors_perfdata'), closure_custom_threshold_check => $self->can('custom_errors_threshold'), } - }; - $self->{maps_counters}->{int}->{'042_out-discard'} = { filter => 'add_errors', - set => { + }, + { label => 'out-discard', filter => 'add_errors', nlabel => 'interface.packets.out.discards.count', set => { key_values => [ { name => 'outdiscard', diff => 1 }, { name => 'total_out_packets', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], closure_custom_calc => $self->can('custom_errors_calc'), closure_custom_calc_extra_options => { label_ref1 => 'out', label_ref2 => 'discard' }, closure_custom_output => $self->can('custom_errors_output'), output_error_template => 'Packets Out Discard : %s', closure_custom_perfdata => $self->can('custom_errors_perfdata'), closure_custom_threshold_check => $self->can('custom_errors_threshold'), } - }; - $self->{maps_counters}->{int}->{'043_out-error'} = { filter => 'add_errors', - set => { + }, + { label => 'out-error', filter => 'add_errors', nlabel => 'interface.packets.out.errors.count', set => { key_values => [ { name => 'outerror', diff => 1 }, { name => 'total_out_packets', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], closure_custom_calc => $self->can('custom_errors_calc'), closure_custom_calc_extra_options => { label_ref1 => 'out', label_ref2 => 'error' }, closure_custom_output => $self->can('custom_errors_output'), output_error_template => 'Packets Out Error : %s', closure_custom_perfdata => $self->can('custom_errors_perfdata'), closure_custom_threshold_check => $self->can('custom_errors_threshold'), } - }; - } - if ($self->{no_cast} == 0 && $self->{no_set_cast} == 0) { - $self->{maps_counters}->{int}->{'060_in-ucast'} = { filter => 'add_cast', - set => { + }, + ; +} + +sub set_counters_cast { + my ($self, %options) = @_; + + return if ($self->{no_cast} != 0 && $self->{no_set_cast} != 0); + + push @{$self->{maps_counters}->{int}}, + { label => 'in-ucast', filter => 'add_cast', nlabel => 'interface.packets.in.unicast.count', set => { key_values => [ { name => 'iucast', diff => 1 }, { name => 'imcast', diff => 1 }, { name => 'ibcast', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], closure_custom_calc => \&custom_cast_calc, closure_custom_calc_extra_options => { label_ref => 'iucast', total_ref1 => 'ibcast', total_ref2 => 'imcast' }, output_template => 'In Ucast : %.2f %%', output_error_template => 'In Ucast : %s', @@ -412,9 +442,8 @@ sub set_counters { unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }, ], } - }; - $self->{maps_counters}->{int}->{'061_in-bcast'} = { filter => 'add_cast', - set => { + }, + { label => 'in-bcast', filter => 'add_cast', nlabel => 'interface.packets.in.broadcast.count', set => { key_values => [ { name => 'iucast', diff => 1 }, { name => 'imcast', diff => 1 }, { name => 'ibcast', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], closure_custom_calc => \&custom_cast_calc, closure_custom_calc_extra_options => { label_ref => 'ibcast', total_ref1 => 'iucast', total_ref2 => 'imcast' }, output_template => 'In Bcast : %.2f %%', output_error_template => 'In Bcast : %s', @@ -424,9 +453,8 @@ sub set_counters { unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }, ], } - }; - $self->{maps_counters}->{int}->{'062_in-mcast'} = { filter => 'add_cast', - set => { + }, + { label => 'in-mcast', filter => 'add_cast', nlabel => 'interface.packets.in.multicast.count', set => { key_values => [ { name => 'iucast', diff => 1 }, { name => 'imcast', diff => 1 }, { name => 'ibcast', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], closure_custom_calc => \&custom_cast_calc, closure_custom_calc_extra_options => { label_ref => 'imcast', total_ref1 => 'iucast', total_ref2 => 'ibcast' }, output_template => 'In Mcast : %.2f %%', output_error_template => 'In Mcast : %s', @@ -436,9 +464,8 @@ sub set_counters { unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }, ], } - }; - $self->{maps_counters}->{int}->{'063_out-ucast'} = { filter => 'add_cast', - set => { + }, + { label => 'out-ucast', filter => 'add_cast', nlabel => 'interface.packets.out.unicast.count', set => { key_values => [ { name => 'oucast', diff => 1 }, { name => 'omcast', diff => 1 }, { name => 'obcast', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], closure_custom_calc => \&custom_cast_calc, closure_custom_calc_extra_options => { label_ref => 'oucast', total_ref1 => 'omcast', total_ref2 => 'obcast' }, output_template => 'Out Ucast : %.2f %%', output_error_template => 'Out Ucast : %s', @@ -448,9 +475,8 @@ sub set_counters { unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }, ], } - }; - $self->{maps_counters}->{int}->{'064_out-bcast'} = { filter => 'add_cast', - set => { + }, + { label => 'out-bcast', filter => 'add_cast', nlabel => 'interface.packets.out.broadcast.count', set => { key_values => [ { name => 'oucast', diff => 1 }, { name => 'omcast', diff => 1 }, { name => 'obcast', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], closure_custom_calc => \&custom_cast_calc, closure_custom_calc_extra_options => { label_ref => 'obcast', total_ref1 => 'omcast', total_ref2 => 'oucast' }, output_template => 'Out Bcast : %.2f %%', output_error_template => 'Out Bcast : %s', @@ -460,9 +486,8 @@ sub set_counters { unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }, ], } - }; - $self->{maps_counters}->{int}->{'065_out-mcast'} = { filter => 'add_cast', - set => { + }, + { label => 'out-mcast', filter => 'add_cast', nlabel => 'interface.packets.out.multicast.count', set => { key_values => [ { name => 'oucast', diff => 1 }, { name => 'omcast', diff => 1 }, { name => 'obcast', diff => 1 }, { name => 'display' }, { name => 'mode_cast' } ], closure_custom_calc => \&custom_cast_calc, closure_custom_calc_extra_options => { label_ref => 'omcast', total_ref1 => 'oucast', total_ref2 => 'obcast' }, output_template => 'Out Mcast : %.2f %%', output_error_template => 'Out Mcast : %s', @@ -472,11 +497,17 @@ sub set_counters { unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }, ], } - }; - } - if ($self->{no_speed} == 0 && $self->{no_set_speed} == 0) { - $self->{maps_counters}->{int}->{'080_speed'} = { filter => 'add_speed', - set => { + }, + ; +} + +sub set_counters_speed { + my ($self, %options) = @_; + + return if ($self->{no_speed} != 0 && $self->{no_set_speed} != 0); + + push @{$self->{maps_counters}->{int}}, + { label => 'speed', filter => 'add_speed', nlabel => 'interface.speed.bitspersecond', set => { key_values => [ { name => 'speed' }, { name => 'display' } ], closure_custom_calc => $self->can('custom_speed_calc'), output_template => 'Speed : %s%s/s', output_error_template => 'Speed : %s%s/s', @@ -487,11 +518,17 @@ sub set_counters { unit => 'b/s', min => 0, label_extra_instance => 1, instance_use => 'display' }, ], } - }; - } - if ($self->{no_volume} == 0 && $self->{no_set_volume} == 0) { - $self->{maps_counters}->{int}->{'090_in-volume'} = { filter => 'add_volume', threshold => 0, - set => { + }, + ; +} + +sub set_counters_volume { + my ($self, %options) = @_; + + return if ($self->{no_volume} != 0 && $self->{no_set_volume} != 0); + + push @{$self->{maps_counters}->{int}}, + { label => 'in-volume', filter => 'add_volume', nlabel => 'interface.volume.in.bytes', set => { key_values => [ { name => 'in_volume', diff => 1 }, { name => 'display' } ], output_template => 'Volume In : %.2f %s', output_change_bytes => 1, @@ -500,9 +537,8 @@ sub set_counters { unit => 'B', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, ], } - }; - $self->{maps_counters}->{int}->{'091_out-volume'} = { filter => 'add_volume', threshold => 0, - set => { + }, + { label => 'out-volume', filter => 'add_volume', nlabel => 'interface.volume.out.bytes', set => { key_values => [ { name => 'out_volume', diff => 1 }, { name => 'display' } ], output_template => 'Volume Out : %.2f %s', output_change_bytes => 1, @@ -511,14 +547,61 @@ sub set_counters { unit => 'B', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, ], } - }; + }, + ; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_init => 'skip_global' }, + { name => 'int', type => 1, cb_init => 'skip_interface', cb_init_counters => 'skip_counters', cb_prefix_output => 'prefix_interface_output', message_multiple => 'All interfaces are ok', skipped_code => { -10 => 1 } }, + ]; + + foreach (('traffic', 'errors', 'cast', 'speed', 'volume')) { + $self->{'no_' . $_} = defined($options{'no_' . $_}) && $options{'no_' . $_} =~ /^[01]$/ ? $options{'no_' . $_} : 0; + $self->{'no_set_' . $_} = defined($options{'no_set_' . $_}) && $options{'no_set_' . $_} =~ /^[01]$/ ? $options{'no_set_' . $_} : 0; } + + $self->{maps_counters} = { int => [], global => [] } if (!defined($self->{maps_counters})); + $self->set_counters_global(); + $self->set_counters_status(); + $self->set_counters_traffic(); + $self->set_counters_errors(); + $self->set_counters_cast(); + $self->set_counters_speed(); + $self->set_counters_volume(); +} + +sub prefix_interface_output { + my ($self, %options) = @_; + + return "Interface '" . $options{instance_value}->{display} . "'$options{instance_value}->{extra_display} " +} + +sub skip_global { + my ($self, %options) = @_; + + return (defined($self->{option_results}->{add_global}) ? 0 : 1); +} + +sub skip_interface { + my ($self, %options) = @_; + + return ($self->{checking} =~ /cast|errors|traffic|status|volume/ ? 0 : 1); +} + +sub skip_counters { + my ($self, %options) = @_; + + return (defined($self->{option_results}->{$options{filter}})) ? 0 : 1; } sub set_key_values_status { my ($self, %options) = @_; - return [ { name => 'opstatus' }, { name => 'admstatus' }, { name => 'display' } ]; + return [ { name => 'opstatus' }, { name => 'admstatus' }, { name => 'duplexstatus' }, { name => 'display' } ]; } sub set_key_values_in_traffic { @@ -537,9 +620,10 @@ sub set_oids_label { my ($self, %options) = @_; $self->{oids_label} = { - 'ifdesc' => '.1.3.6.1.2.1.2.2.1.2', - 'ifalias' => '.1.3.6.1.2.1.31.1.1.1.18', - 'ifname' => '.1.3.6.1.2.1.31.1.1.1.1', + 'ifdesc' => { oid => '.1.3.6.1.2.1.2.2.1.2', cache => 'reload_cache_index_value' }, + 'ifalias' => { oid => '.1.3.6.1.2.1.31.1.1.1.18', cache => 'reload_cache_index_value' }, + 'ifname' => { oid => '.1.3.6.1.2.1.31.1.1.1.1', cache => 'reload_cache_index_value', }, + 'ipaddr' => { oid => '.1.3.6.1.2.1.4.20.1.2', cache => 'reload_cache_values_index', }, }; } @@ -554,6 +638,10 @@ sub set_oids_status { $self->{oid_opstatus_mapping} = { 1 => 'up', 2 => 'down', 3 => 'testing', 4 => 'unknown', 5 => 'dormant', 6 => 'notPresent', 7 => 'lowerLayerDown', }; + $self->{oid_duplexstatus} = '.1.3.6.1.2.1.10.7.2.1.19'; + $self->{oid_duplexstatus_mapping} = { + 1 => 'unknown', 2 => 'halfDuplex', 3 => 'fullDuplex', + }; } sub set_oids_errors { @@ -608,7 +696,7 @@ sub check_oids_label { foreach (('oid_filter', 'oid_display')) { $self->{option_results}->{$_} = lc($self->{option_results}->{$_}) if (defined($self->{option_results}->{$_})); - if (!defined($self->{oids_label}->{$self->{option_results}->{$_}})) { + if (!defined($self->{oids_label}->{$self->{option_results}->{$_}}->{oid})) { my $label = $_; $label =~ s/_/-/g; $self->{output}->add_option_msg(short_msg => "Unsupported oid in --" . $label . " option."); @@ -618,7 +706,7 @@ sub check_oids_label { if (defined($self->{option_results}->{oid_extra_display})) { $self->{option_results}->{oid_extra_display} = lc($self->{option_results}->{oid_extra_display}); - if (!defined($self->{oids_label}->{$self->{option_results}->{oid_extra_display}})) { + if (!defined($self->{oids_label}->{$self->{option_results}->{oid_extra_display}}->{oid})) { $self->{output}->add_option_msg(short_msg => "Unsupported oid in --oid-extra-display option."); $self->{output}->option_exit(); } @@ -681,122 +769,88 @@ sub default_oid_display_name { sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => defined($options{package}) ? $options{package} : __PACKAGE__, %options); + my $self = $class->SUPER::new(package => defined($options{package}) ? $options{package} : __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{no_oid_options} = defined($options{no_oid_options}) && $options{no_oid_options} =~ /^[01]$/ ? $options{no_oid_options} : 0; $self->{no_interfaceid_options} = defined($options{no_interfaceid_options}) && $options{no_interfaceid_options} =~ /^[01]$/ ? $options{no_interfaceid_options} : 0; - foreach (('traffic', 'errors', 'cast', 'speed', 'volume')) { - $self->{'no_' . $_} = defined($options{'no_' . $_}) && $options{'no_' . $_} =~ /^[01]$/ ? $options{'no_' . $_} : 0; - $self->{'no_set_' . $_} = defined($options{'no_set_' . $_}) && $options{'no_set_' . $_} =~ /^[01]$/ ? $options{'no_set_' . $_} : 0; - } - + $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "add-global" => { name => 'add_global' }, - "add-status" => { name => 'add_status' }, - "warning-status:s" => { name => 'warning_status', default => $self->default_warning_status() }, - "critical-status:s" => { name => 'critical_status', default => $self->default_critical_status() }, - "global-admin-up-rule:s" => { name => 'global_admin_up_rule', default => $self->default_global_admin_up_rule() }, - "global-oper-up-rule:s" => { name => 'global_oper_up_rule', default => $self->default_global_oper_up_rule() }, - "global-admin-down-rule:s" => { name => 'global_admin_down_rule', default => $self->default_global_admin_down_rule() }, - "global-oper-down-rule:s" => { name => 'global_oper_down_rule', default => $self->default_global_oper_down_rule() }, - "interface:s" => { name => 'interface' }, - "units-traffic:s" => { name => 'units_traffic', default => '%' }, - "units-errors:s" => { name => 'units_errors', default => '%' }, - "speed:s" => { name => 'speed' }, - "speed-in:s" => { name => 'speed_in' }, - "speed-out:s" => { name => 'speed_out' }, - "no-skipped-counters" => { name => 'no_skipped_counters' }, - "display-transform-src:s" => { name => 'display_transform_src' }, - "display-transform-dst:s" => { name => 'display_transform_dst' }, - "show-cache" => { name => 'show_cache' }, - "reload-cache-time:s" => { name => 'reload_cache_time', default => 180 }, - "nagvis-perfdata" => { name => 'nagvis_perfdata' }, - "force-counters32" => { name => 'force_counters32' }, - }); + $options{options}->add_options(arguments => { + 'add-global' => { name => 'add_global' }, + 'add-status' => { name => 'add_status' }, + 'add-duplex-status' => { name => 'add_duplex_status' }, + 'warning-status:s' => { name => 'warning_status', default => $self->default_warning_status() }, + 'critical-status:s' => { name => 'critical_status', default => $self->default_critical_status() }, + 'global-admin-up-rule:s' => { name => 'global_admin_up_rule', default => $self->default_global_admin_up_rule() }, + 'global-oper-up-rule:s' => { name => 'global_oper_up_rule', default => $self->default_global_oper_up_rule() }, + 'global-admin-down-rule:s' => { name => 'global_admin_down_rule', default => $self->default_global_admin_down_rule() }, + 'global-oper-down-rule:s' => { name => 'global_oper_down_rule', default => $self->default_global_oper_down_rule() }, + 'interface:s' => { name => 'interface' }, + 'units-traffic:s' => { name => 'units_traffic', default => '%' }, + 'units-errors:s' => { name => 'units_errors', default => '%' }, + 'speed:s' => { name => 'speed' }, + 'speed-in:s' => { name => 'speed_in' }, + 'speed-out:s' => { name => 'speed_out' }, + 'no-skipped-counters' => { name => 'no_skipped_counters' }, + 'display-transform-src:s' => { name => 'display_transform_src' }, + 'display-transform-dst:s' => { name => 'display_transform_dst' }, + 'show-cache' => { name => 'show_cache' }, + 'reload-cache-time:s' => { name => 'reload_cache_time', default => 180 }, + 'nagvis-perfdata' => { name => 'nagvis_perfdata' }, + 'force-counters32' => { name => 'force_counters32' }, + }); if ($self->{no_traffic} == 0) { - $options{options}->add_options(arguments => { "add-traffic" => { name => 'add_traffic' } }); + $options{options}->add_options(arguments => { 'add-traffic' => { name => 'add_traffic' } }); } if ($self->{no_errors} == 0) { - $options{options}->add_options(arguments => { "add-errors" => { name => 'add_errors' } }); + $options{options}->add_options(arguments => { 'add-errors' => { name => 'add_errors' } }); } if ($self->{no_cast} == 0) { - $options{options}->add_options(arguments => { "add-cast" => { name => 'add_cast' }, }); + $options{options}->add_options(arguments => { 'add-cast' => { name => 'add_cast' }, }); } if ($self->{no_speed} == 0) { - $options{options}->add_options(arguments => { "add-speed" => { name => 'add_speed' }, }); + $options{options}->add_options(arguments => { 'add-speed' => { name => 'add_speed' }, }); } if ($self->{no_volume} == 0) { - $options{options}->add_options(arguments => { "add-volume" => { name => 'add_volume' }, }); + $options{options}->add_options(arguments => { 'add-volume' => { name => 'add_volume' }, }); } if ($self->{no_oid_options} == 0) { - $options{options}->add_options(arguments => - { - "oid-filter:s" => { name => 'oid_filter', default => $self->default_oid_filter_name() }, - "oid-display:s" => { name => 'oid_display', default => $self->default_oid_display_name() }, - "oid-extra-display:s" => { name => 'oid_extra_display' }, - } - ); + $options{options}->add_options(arguments => { + 'oid-filter:s' => { name => 'oid_filter', default => $self->default_oid_filter_name() }, + 'oid-display:s' => { name => 'oid_display', default => $self->default_oid_display_name() }, + 'oid-extra-display:s' => { name => 'oid_extra_display' }, + }); } if ($self->{no_interfaceid_options} == 0) { - $options{options}->add_options(arguments => - { - "name" => { name => 'use_name' }, - } - ); + $options{options}->add_options(arguments => { + 'name' => { name => 'use_name' }, + }); } - $self->{statefile_value} = centreon::plugins::statefile->new(%options); $self->{statefile_cache} = centreon::plugins::statefile->new(%options); - $self->set_counters(); - - foreach my $key (('int', 'global')) { - foreach (keys %{$self->{maps_counters}->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($self->{maps_counters}->{$key}->{$_}->{threshold}) || $self->{maps_counters}->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $self->{maps_counters}->{$key}->{$_}->{obj} = centreon::plugins::values->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $self->{maps_counters}->{$key}->{$_}->{obj}->set(%{$self->{maps_counters}->{$key}->{$_}->{set}}); - $self->{maps_counters}->{$key}->{$_}->{obj}->{instance_mode} = $self; - } - } return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('int', 'global')) { - foreach (keys %{$self->{maps_counters}->{$key}}) { - $self->{maps_counters}->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } + $self->SUPER::check_options(%options); $self->set_oids_label(); $self->check_oids_label(); $self->{statefile_cache}->check_options(%options); - $self->{statefile_value}->check_options(%options); if (defined($self->{option_results}->{add_traffic}) && (!defined($self->{option_results}->{units_traffic}) || $self->{option_results}->{units_traffic} !~ /^(%|b\/s)$/)) { - $self->{output}->add_option_msg(short_msg => "Wrong option --units-traffic."); + $self->{output}->add_option_msg(short_msg => 'Wrong option --units-traffic.'); $self->{output}->option_exit(); } if (defined($self->{option_results}->{add_errors}) && (!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}->add_option_msg(short_msg => 'Wrong option --units-errors.'); $self->{output}->option_exit(); } @@ -806,7 +860,7 @@ sub check_options { (!defined($self->{option_results}->{speed_out}) || $self->{option_results}->{speed_out} eq ''))) { $self->{get_speed} = 1; } elsif (defined($self->{option_results}->{add_speed})) { - $self->{output}->add_option_msg(short_msg => "Cannot use option --add-speed with --speed, --speed-in or --speed-out options."); + $self->{output}->add_option_msg(short_msg => 'Cannot use option --add-speed with --speed, --speed-in or --speed-out options.'); $self->{output}->option_exit(); } @@ -823,139 +877,7 @@ sub check_options { } } - $self->change_macros(); -} - -sub run_global { - my ($self, %options) = @_; - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$self->{maps_counters}->{global}}) { - my $obj = $self->{maps_counters}->{global}->{$_}->{obj}; - - $obj->set(instance => 'global'); - - my ($value_check) = $obj->execute(values => $self->{global}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(); - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "$short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "$long_msg"); - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - $self->get_informations(); - - my $multiple = 1; - if (scalar(keys %{$self->{interface_selected}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1 && defined($self->{option_results}->{add_global})) { - $self->run_global(); - } - - if ($multiple == 1 && $self->{checking} =~ /cast|errors|traffic|status|volume/) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All interfaces are ok'); - } - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "snmpstandard_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode} . '_' . - (defined($self->{option_results}->{interface}) ? md5_hex($self->{option_results}->{interface}) : md5_hex('all')) . '_' . - md5_hex($self->{checking})); - $self->{new_datas}->{last_timestamp} = time(); - - foreach my $id (sort keys %{$self->{interface_selected}}) { - next if ($self->{checking} !~ /cast|errors|traffic|status|volume/); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$self->{maps_counters}->{int}}) { - my $obj = $self->{maps_counters}->{int}->{$_}->{obj}; - next if (!defined($self->{option_results}->{$self->{maps_counters}->{int}->{$_}->{filter}})); - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{interface_selected}->{$id}, - new_datas => $self->{new_datas}); - next if ($value_check == -10); # not running - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Interface '" . $self->{interface_selected}->{$id}->{display} . "'$self->{interface_selected}->{$id}->{extra_display} $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Interface '" . $self->{interface_selected}->{$id}->{display} . "'$self->{interface_selected}->{$id}->{extra_display} $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Interface '" . $self->{interface_selected}->{$id}->{display} . "'$self->{interface_selected}->{$id}->{extra_display} $long_msg"); - } - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - -sub change_macros { - my ($self, %options) = @_; - - foreach (('warning_status', 'critical_status')) { - if (defined($self->{option_results}->{$_})) { - $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; - } - } - + $self->change_macros(macros => ['warning_status', 'critical_status']); $self->{check_status} = $self->default_check_status(); $self->{check_status} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; } @@ -989,6 +911,32 @@ sub check_oids_options_change { return 0; } +sub reload_cache_index_value { + my ($self, %options) = @_; + + my $store_index = defined($options{store_index}) && $options{store_index} == 1 ? 1 : 0; + foreach ($self->{snmp}->oid_lex_sort(keys %{$options{result}->{ $self->{oids_label}->{$options{name}}->{oid} }})) { + /^$self->{oids_label}->{$options{name}}->{oid}\.(.*)$/; + push @{$options{datas}->{all_ids}}, $1 if ($store_index == 1); + $options{datas}->{$options{name} . "_" . $1} = $self->{output}->to_utf8($options{result}->{ $self->{oids_label}->{$options{name}}->{oid} }->{$_}); + } +} + +sub reload_cache_values_index { + my ($self, %options) = @_; + + my $store_index = defined($options{store_index}) && $options{store_index} == 1 ? 1 : 0; + foreach ($self->{snmp}->oid_lex_sort(keys %{$options{result}->{ $self->{oids_label}->{$options{name}}->{oid} }})) { + /^$self->{oids_label}->{$options{name}}->{oid}\.(.*)$/; + push @{$options{datas}->{all_ids}}, $options{result}->{ $self->{oids_label}->{$options{name}}->{oid} }->{$_} if ($store_index == 1); + if (defined($options{datas}->{$options{name} . "_" . $options{result}->{ $self->{oids_label}->{$options{name}}->{oid} }->{$_}})) { + $options{datas}->{$options{name} . "_" . $options{result}->{ $self->{oids_label}->{$options{name}}->{oid} }->{$_}} .= ', ' . $1; + } else { + $options{datas}->{$options{name} . "_" . $options{result}->{ $self->{oids_label}->{$options{name}}->{oid} }->{$_}} = $1; + } + } +} + sub reload_cache { my ($self) = @_; my $datas = {}; @@ -1000,22 +948,20 @@ sub reload_cache { $datas->{all_ids} = []; my $snmp_get = [ - { oid => $self->{oids_label}->{$self->{option_results}->{oid_filter}} }, + { oid => $self->{oids_label}->{$self->{option_results}->{oid_filter}}->{oid} }, ]; if ($self->{option_results}->{oid_filter} ne $self->{option_results}->{oid_display}) { - push @{$snmp_get}, { oid => $self->{oids_label}->{$self->{option_results}->{oid_display}} }; + push @{$snmp_get}, { oid => $self->{oids_label}->{$self->{option_results}->{oid_display}}->{oid} }; } if (defined($self->{option_results}->{oid_extra_display}) && $self->{option_results}->{oid_extra_display} ne $self->{option_results}->{oid_display} && $self->{option_results}->{oid_extra_display} ne $self->{option_results}->{oid_filter}) { - push @{$snmp_get}, { oid => $self->{oids_label}->{$self->{option_results}->{oid_extra_display}} }; + push @{$snmp_get}, { oid => $self->{oids_label}->{$self->{option_results}->{oid_extra_display}}->{oid} }; } my $result = $self->{snmp}->get_multiple_table(oids => $snmp_get); - foreach ($self->{snmp}->oid_lex_sort(keys %{$result->{$self->{oids_label}->{$self->{option_results}->{oid_filter}}}})) { - /^$self->{oids_label}->{$self->{option_results}->{oid_filter}}\.(.*)$/; - push @{$datas->{all_ids}}, $1; - $datas->{$self->{option_results}->{oid_filter} . "_" . $1} = $self->{output}->to_utf8($result->{$self->{oids_label}->{$self->{option_results}->{oid_filter}}}->{$_}); - } + + my $func = $self->can($self->{oids_label}->{$self->{option_results}->{oid_filter}}->{cache}); + $func->($self, result => $result, datas => $datas, name => $self->{option_results}->{oid_filter}, store_index => 1); if (scalar(@{$datas->{all_ids}}) <= 0) { $self->{output}->add_option_msg(short_msg => "Can't construct cache..."); @@ -1023,17 +969,13 @@ sub reload_cache { } if ($self->{option_results}->{oid_filter} ne $self->{option_results}->{oid_display}) { - foreach ($self->{snmp}->oid_lex_sort(keys %{$result->{$self->{oids_label}->{$self->{option_results}->{oid_display}}}})) { - /^$self->{oids_label}->{$self->{option_results}->{oid_display}}\.(.*)$/; - $datas->{$self->{option_results}->{oid_display} . "_" . $1} = $self->{output}->to_utf8($result->{$self->{oids_label}->{$self->{option_results}->{oid_display}}}->{$_}); - } + $func = $self->can($self->{oids_label}->{$self->{option_results}->{oid_display}}->{cache}); + $func->($self, result => $result, datas => $datas, name => $self->{option_results}->{oid_display}); } if (defined($self->{option_results}->{oid_extra_display}) && $self->{option_results}->{oid_extra_display} ne $self->{option_results}->{oid_display} && $self->{option_results}->{oid_extra_display} ne $self->{option_results}->{oid_filter}) { - foreach ($self->{snmp}->oid_lex_sort(keys %{$result->{$self->{oids_label}->{$self->{option_results}->{oid_extra_display}}}})) { - /^$self->{oids_label}->{$self->{option_results}->{oid_extra_display}}\.(.*)$/; - $datas->{$self->{option_results}->{oid_extra_display} . "_" . $1} = $self->{output}->to_utf8($result->{$self->{oids_label}->{$self->{option_results}->{oid_extra_display}}}->{$_}); - } + $func = $self->can($self->{oids_label}->{$self->{option_results}->{oid_extra_display}}->{cache}); + $func->($self, result => $result, datas => $datas, name => $self->{option_results}->{oid_extra_display}); } $self->{statefile_cache}->write(data => $datas); @@ -1042,9 +984,9 @@ sub reload_cache { sub add_selected_interface { my ($self, %options) = @_; - $self->{interface_selected}->{$options{id}} = { display => $self->get_display_value(id => $options{id}), extra_display => '' }; + $self->{int}->{$options{id}} = { display => $self->get_display_value(id => $options{id}), extra_display => '' }; if (defined($self->{option_results}->{oid_extra_display})) { - $self->{interface_selected}->{$options{id}}->{extra_display} = ' [ ' . $self->{statefile_cache}->get(name => $self->{option_results}->{oid_extra_display} . "_" . $options{id}) . ' ]'; + $self->{int}->{$options{id}}->{extra_display} = ' [ ' . $self->{statefile_cache}->get(name => $self->{option_results}->{oid_extra_display} . "_" . $options{id}) . ' ]'; } } @@ -1052,13 +994,13 @@ sub get_selection { my ($self, %options) = @_; # init cache file - my $has_cache_file = $self->{statefile_cache}->read(statefile => 'cache_snmpstandard_' . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode}); + my $has_cache_file = $self->{statefile_cache}->read(statefile => 'cache_snmpstandard_' . $self->{snmp}->get_hostname() . '_' . $self->{snmp}->get_port() . '_' . $self->{mode}); if (defined($self->{option_results}->{show_cache})) { $self->{output}->add_option_msg(long_msg => $self->{statefile_cache}->get_string_content()); $self->{output}->option_exit(); } - $self->{interface_selected} = {}; + $self->{int} = {}; my $timestamp_cache = $self->{statefile_cache}->get(name => 'last_timestamp'); if ($has_cache_file == 0 || $self->check_oids_options_change() || @@ -1089,7 +1031,7 @@ sub get_selection { } } - if (scalar(keys %{$self->{interface_selected}}) <= 0) { + if (scalar(keys %{$self->{int}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No entry found (maybe you should reload cache file)"); $self->{output}->option_exit(); } @@ -1099,7 +1041,12 @@ sub load_status { my ($self, %options) = @_; $self->set_oids_status(); - $self->{snmp}->load(oids => [$self->{oid_adminstatus}, $self->{oid_opstatus}], instances => $self->{array_interface_selected}); + my $oids = [$self->{oid_adminstatus}, $self->{oid_opstatus}]; + if (defined($self->{option_results}->{add_duplex_status})) { + push @$oids, $self->{oid_duplexstatus}; + } + + $self->{snmp}->load(oids => $oids, instances => $self->{array_interface_selected}); } sub load_traffic { @@ -1160,14 +1107,15 @@ sub load_volume { } } -sub get_informations { +sub manage_selection { my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; my $custom_load_method = $self->can('custom_load'); my $custom_add_result_method = $self->can('custom_add_result'); $self->get_selection(); - $self->{array_interface_selected} = [keys %{$self->{interface_selected}}]; + $self->{array_interface_selected} = [keys %{$self->{int}}]; $self->load_status() if (defined($self->{option_results}->{add_status}) || defined($self->{option_results}->{add_global})); $self->load_errors() if (defined($self->{option_results}->{add_errors})); $self->load_traffic() if (defined($self->{option_results}->{add_traffic})); @@ -1188,6 +1136,11 @@ sub get_informations { $self->add_result_volume(instance => $_) if (defined($self->{option_results}->{add_volume})); $self->$custom_add_result_method(instance => $_) if ($custom_add_result_method); } + + $self->{cache_name} = 'snmpstandard_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{interface}) ? md5_hex($self->{option_results}->{interface}) : md5_hex('all')) . '_' . + md5_hex($self->{checking}); } sub add_result_global { @@ -1222,45 +1175,46 @@ sub add_result_global { sub add_result_status { my ($self, %options) = @_; - $self->{interface_selected}->{$options{instance}}->{opstatus} = defined($self->{results}->{$self->{oid_opstatus} . '.' . $options{instance}}) ? $self->{oid_opstatus_mapping}->{$self->{results}->{$self->{oid_opstatus} . '.' . $options{instance}}} : undef; - $self->{interface_selected}->{$options{instance}}->{admstatus} = defined($self->{results}->{$self->{oid_adminstatus} . '.' . $options{instance}}) ? $self->{oid_adminstatus_mapping}->{$self->{results}->{$self->{oid_adminstatus} . '.' . $options{instance}}} : undef; + $self->{int}->{$options{instance}}->{opstatus} = defined($self->{results}->{$self->{oid_opstatus} . '.' . $options{instance}}) ? $self->{oid_opstatus_mapping}->{$self->{results}->{$self->{oid_opstatus} . '.' . $options{instance}}} : undef; + $self->{int}->{$options{instance}}->{admstatus} = defined($self->{results}->{$self->{oid_adminstatus} . '.' . $options{instance}}) ? $self->{oid_adminstatus_mapping}->{$self->{results}->{$self->{oid_adminstatus} . '.' . $options{instance}}} : undef; + $self->{int}->{$options{instance}}->{duplexstatus} = defined($self->{results}->{$self->{oid_duplexstatus} . '.' . $options{instance}}) ? $self->{oid_duplexstatus_mapping}->{$self->{results}->{$self->{oid_duplexstatus} . '.' . $options{instance}}} : 'n/a'; } sub add_result_errors { my ($self, %options) = @_; - $self->{interface_selected}->{$options{instance}}->{indiscard} = $self->{results}->{$self->{oid_ifInDiscards} . '.' . $options{instance}}; - $self->{interface_selected}->{$options{instance}}->{inerror} = $self->{results}->{$self->{oid_ifInErrors} . '.' . $options{instance}}; - $self->{interface_selected}->{$options{instance}}->{outdiscard} = $self->{results}->{$self->{oid_ifOutDiscards} . '.' . $options{instance}}; - $self->{interface_selected}->{$options{instance}}->{outerror} = $self->{results}->{$self->{oid_ifOutErrors} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{indiscard} = $self->{results}->{$self->{oid_ifInDiscards} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{inerror} = $self->{results}->{$self->{oid_ifInErrors} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{outdiscard} = $self->{results}->{$self->{oid_ifOutDiscards} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{outerror} = $self->{results}->{$self->{oid_ifOutErrors} . '.' . $options{instance}}; } sub add_result_traffic { my ($self, %options) = @_; - $self->{interface_selected}->{$options{instance}}->{mode_traffic} = 32; - $self->{interface_selected}->{$options{instance}}->{in} = $self->{results}->{$self->{oid_in32} . '.' . $options{instance}}; - $self->{interface_selected}->{$options{instance}}->{out} = $self->{results}->{$self->{oid_out32} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{mode_traffic} = 32; + $self->{int}->{$options{instance}}->{in} = $self->{results}->{$self->{oid_in32} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{out} = $self->{results}->{$self->{oid_out32} . '.' . $options{instance}}; if (!$self->{snmp}->is_snmpv1() && !defined($self->{option_results}->{force_counters32})) { if (defined($self->{results}->{$self->{oid_in64} . '.' . $options{instance}}) && $self->{results}->{$self->{oid_in64} . '.' . $options{instance}} ne '' && $self->{results}->{$self->{oid_in64} . '.' . $options{instance}} != 0) { - $self->{interface_selected}->{$options{instance}}->{mode_traffic} = 64; - $self->{interface_selected}->{$options{instance}}->{in} = $self->{results}->{$self->{oid_in64} . '.' . $options{instance}}; - $self->{interface_selected}->{$options{instance}}->{out} = $self->{results}->{$self->{oid_out64} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{mode_traffic} = 64; + $self->{int}->{$options{instance}}->{in} = $self->{results}->{$self->{oid_in64} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{out} = $self->{results}->{$self->{oid_out64} . '.' . $options{instance}}; } } - $self->{interface_selected}->{$options{instance}}->{in} *= 8 if (defined($self->{interface_selected}->{$options{instance}}->{in})); - $self->{interface_selected}->{$options{instance}}->{out} *= 8 if (defined($self->{interface_selected}->{$options{instance}}->{out})); + $self->{int}->{$options{instance}}->{in} *= 8 if (defined($self->{int}->{$options{instance}}->{in})); + $self->{int}->{$options{instance}}->{out} *= 8 if (defined($self->{int}->{$options{instance}}->{out})); - $self->{interface_selected}->{$options{instance}}->{speed_in} = 0; - $self->{interface_selected}->{$options{instance}}->{speed_out} = 0; + $self->{int}->{$options{instance}}->{speed_in} = 0; + $self->{int}->{$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->{int}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed} * 1000000; + $self->{int}->{$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 ''); + $self->{int}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed_in} * 1000000 if (defined($self->{option_results}->{speed_in}) && $self->{option_results}->{speed_in} ne ''); + $self->{int}->{$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; if (defined($self->{results}->{$self->{oid_speed64} . "." . $options{instance}}) && $self->{results}->{$self->{oid_speed64} . "." . $options{instance}} ne '') { @@ -1273,42 +1227,42 @@ sub add_result_traffic { $interface_speed = $self->{results}->{$self->{oid_speed32} . "." . $options{instance}}; } - $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 ''); + $self->{int}->{$options{instance}}->{speed_in} = $interface_speed; + $self->{int}->{$options{instance}}->{speed_out} = $interface_speed; + $self->{int}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed_in} * 1000000 if (defined($self->{option_results}->{speed_in}) && $self->{option_results}->{speed_in} ne ''); + $self->{int}->{$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_cast { my ($self, %options) = @_; - $self->{interface_selected}->{$options{instance}}->{mode_cast} = 32; - $self->{interface_selected}->{$options{instance}}->{iucast} = $self->{results}->{$self->{oid_ifInUcastPkts} . '.' . $options{instance}}; - $self->{interface_selected}->{$options{instance}}->{ibcast} = defined($self->{results}->{$self->{oid_ifInBroadcastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifInBroadcastPkts} . '.' . $options{instance}} : 0; - $self->{interface_selected}->{$options{instance}}->{imcast} = defined($self->{results}->{$self->{oid_ifInMulticastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifInMulticastPkts} . '.' . $options{instance}} : 0; - $self->{interface_selected}->{$options{instance}}->{oucast} = $self->{results}->{$self->{oid_ifOutUcastPkts} . '.' . $options{instance}}; - $self->{interface_selected}->{$options{instance}}->{omcast} = defined($self->{results}->{$self->{oid_ifOutMulticastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifOutMulticastPkts} . '.' . $options{instance}} : 0; - $self->{interface_selected}->{$options{instance}}->{obcast} = defined($self->{results}->{$self->{oid_ifOutBroadcastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifOutBroadcastPkts} . '.' . $options{instance}} : 0; + $self->{int}->{$options{instance}}->{mode_cast} = 32; + $self->{int}->{$options{instance}}->{iucast} = $self->{results}->{$self->{oid_ifInUcastPkts} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{ibcast} = defined($self->{results}->{$self->{oid_ifInBroadcastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifInBroadcastPkts} . '.' . $options{instance}} : 0; + $self->{int}->{$options{instance}}->{imcast} = defined($self->{results}->{$self->{oid_ifInMulticastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifInMulticastPkts} . '.' . $options{instance}} : 0; + $self->{int}->{$options{instance}}->{oucast} = $self->{results}->{$self->{oid_ifOutUcastPkts} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{omcast} = defined($self->{results}->{$self->{oid_ifOutMulticastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifOutMulticastPkts} . '.' . $options{instance}} : 0; + $self->{int}->{$options{instance}}->{obcast} = defined($self->{results}->{$self->{oid_ifOutBroadcastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifOutBroadcastPkts} . '.' . $options{instance}} : 0; if (!$self->{snmp}->is_snmpv1() && !defined($self->{option_results}->{force_counters32})) { my $iucast = $self->{results}->{$self->{oid_ifHCInUcastPkts} . '.' . $options{instance}}; if (defined($iucast) && $iucast =~ /[1-9]/) { - $self->{interface_selected}->{$options{instance}}->{iucast} = $iucast; - $self->{interface_selected}->{$options{instance}}->{imcast} = defined($self->{results}->{$self->{oid_ifHCInMulticastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCInMulticastPkts} . '.' . $options{instance}} : 0; - $self->{interface_selected}->{$options{instance}}->{ibcast} = defined($self->{results}->{$self->{oid_ifHCInBroadcastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCInBroadcastPkts} . '.' . $options{instance}} : 0; - $self->{interface_selected}->{$options{instance}}->{oucast} = $self->{results}->{$self->{oid_ifHCOutUcastPkts} . '.' . $options{instance}}; - $self->{interface_selected}->{$options{instance}}->{omcast} = defined($self->{results}->{$self->{oid_ifHCOutMulticastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCOutMulticastPkts} . '.' . $options{instance}} : 0; - $self->{interface_selected}->{$options{instance}}->{obcast} = defined($self->{results}->{$self->{oid_ifHCOutBroadcastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCOutBroadcastPkts} . '.' . $options{instance}} : 0; - $self->{interface_selected}->{$options{instance}}->{mode_cast} = 64; + $self->{int}->{$options{instance}}->{iucast} = $iucast; + $self->{int}->{$options{instance}}->{imcast} = defined($self->{results}->{$self->{oid_ifHCInMulticastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCInMulticastPkts} . '.' . $options{instance}} : 0; + $self->{int}->{$options{instance}}->{ibcast} = defined($self->{results}->{$self->{oid_ifHCInBroadcastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCInBroadcastPkts} . '.' . $options{instance}} : 0; + $self->{int}->{$options{instance}}->{oucast} = $self->{results}->{$self->{oid_ifHCOutUcastPkts} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{omcast} = defined($self->{results}->{$self->{oid_ifHCOutMulticastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCOutMulticastPkts} . '.' . $options{instance}} : 0; + $self->{int}->{$options{instance}}->{obcast} = defined($self->{results}->{$self->{oid_ifHCOutBroadcastPkts} . '.' . $options{instance}}) ? $self->{results}->{$self->{oid_ifHCOutBroadcastPkts} . '.' . $options{instance}} : 0; + $self->{int}->{$options{instance}}->{mode_cast} = 64; } } - foreach (('iucast', 'imcast', 'ibcast', 'oucast', 'omcast', 'omcast')) { - $self->{interface_selected}->{$options{instance}}->{$_} = 0 if (!defined($self->{interface_selected}->{$options{instance}}->{$_})); + foreach (('iucast', 'imcast', 'ibcast', 'oucast', 'omcast', 'obcast')) { + $self->{int}->{$options{instance}}->{$_} = 0 if (!defined($self->{int}->{$options{instance}}->{$_})); } - $self->{interface_selected}->{$options{instance}}->{total_in_packets} = $self->{interface_selected}->{$options{instance}}->{iucast} + $self->{interface_selected}->{$options{instance}}->{imcast} + $self->{interface_selected}->{$options{instance}}->{ibcast}; - $self->{interface_selected}->{$options{instance}}->{total_out_packets} = $self->{interface_selected}->{$options{instance}}->{oucast} + $self->{interface_selected}->{$options{instance}}->{omcast} + $self->{interface_selected}->{$options{instance}}->{obcast}; + $self->{int}->{$options{instance}}->{total_in_packets} = $self->{int}->{$options{instance}}->{iucast} + $self->{int}->{$options{instance}}->{imcast} + $self->{int}->{$options{instance}}->{ibcast}; + $self->{int}->{$options{instance}}->{total_out_packets} = $self->{int}->{$options{instance}}->{oucast} + $self->{int}->{$options{instance}}->{omcast} + $self->{int}->{$options{instance}}->{obcast}; } sub add_result_speed { @@ -1325,21 +1279,21 @@ sub add_result_speed { $interface_speed = $self->{results}->{$self->{oid_speed32} . "." . $options{instance}}; } - $self->{interface_selected}->{$options{instance}}->{speed} = $interface_speed; + $self->{int}->{$options{instance}}->{speed} = $interface_speed; } sub add_result_volume { my ($self, %options) = @_; - $self->{interface_selected}->{$options{instance}}->{mode_traffic} = 32; - $self->{interface_selected}->{$options{instance}}->{in_volume} = $self->{results}->{$self->{oid_in32} . '.' . $options{instance}}; - $self->{interface_selected}->{$options{instance}}->{out_volume} = $self->{results}->{$self->{oid_out32} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{mode_traffic} = 32; + $self->{int}->{$options{instance}}->{in_volume} = $self->{results}->{$self->{oid_in32} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{out_volume} = $self->{results}->{$self->{oid_out32} . '.' . $options{instance}}; if (!$self->{snmp}->is_snmpv1() && !defined($self->{option_results}->{force_counters32})) { if (defined($self->{results}->{$self->{oid_in64} . '.' . $options{instance}}) && $self->{results}->{$self->{oid_in64} . '.' . $options{instance}} ne '' && $self->{results}->{$self->{oid_in64} . '.' . $options{instance}} != 0) { - $self->{interface_selected}->{$options{instance}}->{mode_traffic} = 64; - $self->{interface_selected}->{$options{instance}}->{in_volume} = $self->{results}->{$self->{oid_in64} . '.' . $options{instance}}; - $self->{interface_selected}->{$options{instance}}->{out_volume} = $self->{results}->{$self->{oid_out64} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{mode_traffic} = 64; + $self->{int}->{$options{instance}}->{in_volume} = $self->{results}->{$self->{oid_in64} . '.' . $options{instance}}; + $self->{int}->{$options{instance}}->{out_volume} = $self->{results}->{$self->{oid_out64} . '.' . $options{instance}}; } } } @@ -1362,6 +1316,10 @@ Check global port statistics (By default if no --add-* option is set). Check interface status. +=item B<--add-duplex-status> + +Check duplex status (with --warning-status and --critical-status). + =item B<--add-traffic> Check interface traffic. @@ -1385,12 +1343,12 @@ Check interface data volume between two checks (not supposed to be graphed, usef =item B<--warning-status> Set warning threshold for status. -Can used special variables like: %{admstatus}, %{opstatus}, %{display} +Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). -Can used special variables like: %{admstatus}, %{opstatus}, %{display} +Can used special variables like: %{admstatus}, %{opstatus}, %{duplexstatus}, %{display} =item B<--warning-*> @@ -1454,11 +1412,11 @@ Time in minutes before reloading cache file (default: 180). =item B<--oid-filter> -Choose OID used to filter interface (default: ifName) (values: ifDesc, ifAlias, ifName). +Choose OID used to filter interface (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). =item B<--oid-display> -Choose OID used to display interface (default: ifName) (values: ifDesc, ifAlias, ifName). +Choose OID used to display interface (default: ifName) (values: ifDesc, ifAlias, ifName, IpAddr). =item B<--oid-extra-display> diff --git a/snmp_standard/mode/listinterfaces.pm b/snmp_standard/mode/listinterfaces.pm index da2a19873..7ee64092d 100644 --- a/snmp_standard/mode/listinterfaces.pm +++ b/snmp_standard/mode/listinterfaces.pm @@ -39,6 +39,7 @@ sub set_oids_status { $self->{oid_opstatus_mapping} = { 1 => 'up', 2 => 'down', 3 => 'testing', 4 => 'unknown', 5 => 'dormant', 6 => 'notPresent', 7 => 'lowerLayerDown', }; + $self->{oid_mac_address} = '.1.3.6.1.2.1.2.2.1.6'; } sub check_oids_label { @@ -94,23 +95,23 @@ sub new { $self->{no_speed} = defined($options{no_speed}) && $options{no_speed} =~ /^[01]$/ ? $options{no_speed} : 0; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "name" => { name => 'use_name' }, - "interface:s" => { name => 'interface' }, - "speed:s" => { name => 'speed' }, - "filter-status:s" => { name => 'filter_status' }, - "skip-speed0" => { name => 'skip_speed0' }, - "use-adminstatus" => { name => 'use_adminstatus' }, - "oid-filter:s" => { name => 'oid_filter', default => $self->default_oid_filter_name() }, - "oid-display:s" => { name => 'oid_display', default => $self->default_oid_display_name() }, - "display-transform-src:s" => { name => 'display_transform_src' }, - "display-transform-dst:s" => { name => 'display_transform_dst' }, - "add-extra-oid:s@" => { name => 'add_extra_oid' }, - }); + $options{options}->add_options(arguments => { + "name" => { name => 'use_name' }, + "interface:s" => { name => 'interface' }, + "speed:s" => { name => 'speed' }, + "filter-status:s" => { name => 'filter_status' }, + "skip-speed0" => { name => 'skip_speed0' }, + "use-adminstatus" => { name => 'use_adminstatus' }, + "oid-filter:s" => { name => 'oid_filter', default => $self->default_oid_filter_name() }, + "oid-display:s" => { name => 'oid_display', default => $self->default_oid_display_name() }, + "display-transform-src:s" => { name => 'display_transform_src' }, + "display-transform-dst:s" => { name => 'display_transform_dst' }, + "add-extra-oid:s@" => { name => 'add_extra_oid' }, + "add-mac-address" => { name => 'add_mac_address' }, + }); $self->{interface_id_selected} = []; - + return $self; } @@ -141,7 +142,6 @@ sub run { $self->manage_selection(); my $result = $self->get_additional_information(); - foreach (sort @{$self->{interface_id_selected}}) { my $display_value = $self->get_display_value(id => $_); @@ -170,7 +170,7 @@ sub run { next; } - my $extra_values = $self->get_extra_values_by_instance(instance => $_); + my $extra_values = $self->get_extra_values_by_instance(result => $result, instance => $_); my $extra_display = ''; foreach my $name (keys %{$extra_values}) { $extra_display .= ', ' . $name . ' = ' . $extra_values->{$name}; @@ -193,6 +193,7 @@ sub get_additional_information { my $oids = []; push @$oids, $self->{oid_adminstatus} if (defined($self->{oid_adminstatus})); push @$oids, $self->{oid_opstatus} if (defined($self->{oid_opstatus})); + push @$oids, $self->{oid_mac_address} if (defined($self->{option_results}->{add_mac_address})); push @$oids, $oid_speed32 if ($self->{no_speed} == 0); push @$oids, $oid_speed64 if (!$self->{snmp}->is_snmpv1() && $self->{no_speed} == 0); @@ -290,6 +291,13 @@ sub get_extra_values_by_instance { } } } + + if (defined($self->{option_results}->{add_mac_address})) { + my $macaddress = defined($options{result}->{$self->{oid_mac_address} . "." . $_}) ? unpack('H*', $options{result}->{$self->{oid_mac_address} . "." . $_}) : ''; + $macaddress =~ s/(..)(?=.)/$1:/g; + $extra_values->{macaddress} = $macaddress; + } + return $extra_values; } @@ -300,6 +308,10 @@ sub disco_format { if (scalar(keys %{$self->{extra_oids}}) > 0) { push @$names, keys %{$self->{extra_oids}}; } + if (defined($self->{option_results}->{add_mac_address})) { + push @$names, 'macaddress'; + } + $self->{output}->add_disco_format(elements => $names); } @@ -328,7 +340,7 @@ sub disco_show { $self->{oid_opstatus_mapping}->{$result->{$self->{oid_opstatus} . "." . $_}} !~ /$self->{option_results}->{filter_status}/i); next if ($self->is_admin_status_down(admin_status => $result->{$self->{oid_adminstatus} . "." . $_})); - my $extra_values = $self->get_extra_values_by_instance(instance => $_); + my $extra_values = $self->get_extra_values_by_instance(result => $result, instance => $_); $self->{output}->add_disco_entry(name => $display_value, total => $interface_speed, status => defined($result->{$self->{oid_opstatus} . "." . $_}) ? $self->{oid_opstatus_mapping}->{$result->{$self->{oid_opstatus} . "." . $_}} : '', @@ -391,6 +403,9 @@ Display an OID. Example: --add-extra-oid='alias,.1.3.6.1.2.1.31.1.1.1.18' or --add-extra-oid='vlan,.1.3.6.1.2.1.31.19,%{instance}\..*' +=item B<--add-mac-address> + +Display interface mac address. =back diff --git a/snmp_standard/mode/memory.pm b/snmp_standard/mode/memory.pm index 670299323..78849fb02 100644 --- a/snmp_standard/mode/memory.pm +++ b/snmp_standard/mode/memory.pm @@ -20,151 +20,245 @@ package snmp_standard::mode::memory; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +sub custom_usage_output { + my ($self, %options) = @_; + + my $msg = sprintf("Ram Total: %s %s Used (-buffers/cache): %s %s (%.2f%%) Free: %s %s (%.2f%%)", + $self->{perfdata}->change_bytes(value => $self->{result_values}->{total_absolute}), + $self->{perfdata}->change_bytes(value => $self->{result_values}->{used_absolute}), + $self->{result_values}->{prct_used_absolute}, + $self->{perfdata}->change_bytes(value => $self->{result_values}->{free_absolute}), + $self->{result_values}->{prct_free_absolute}); + return $msg; +} + +sub custom_swap_output { + my ($self, %options) = @_; + + my $msg = sprintf("Swap Total: %s %s Used: %s %s (%.2f%%) Free: %s %s (%.2f%%)", + $self->{perfdata}->change_bytes(value => $self->{result_values}->{total_absolute}), + $self->{perfdata}->change_bytes(value => $self->{result_values}->{used_absolute}), + $self->{result_values}->{prct_used_absolute}, + $self->{perfdata}->change_bytes(value => $self->{result_values}->{free_absolute}), + $self->{result_values}->{prct_free_absolute}); + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'ram', type => 0, skipped_code => { -10 => 1 } }, + { name => 'swap', type => 0, message_separator => ' - ', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{ram} = [ + { label => 'usage', nlabel => 'memory.usage.bytes', set => { + key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_usage_output'), + perfdatas => [ + { label => 'used', value => 'used_absolute', template => '%d', min => 0, max => 'total_absolute', + unit => 'B', cast_int => 1 }, + ], + } + }, + { label => 'usage-free', display_ok => 0, nlabel => 'memory.free.bytes', set => { + key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_usage_output'), + perfdatas => [ + { label => 'free', value => 'free_absolute', template => '%d', min => 0, max => 'total_absolute', + unit => 'B', cast_int => 1 }, + ], + } + }, + { label => 'usage-prct', display_ok => 0, nlabel => 'memory.usage.percentage', set => { + key_values => [ { name => 'prct_used' } ], + output_template => 'Used : %.2f %%', + perfdatas => [ + { label => 'used_prct', value => 'prct_used_absolute', template => '%.2f', min => 0, max => 0, + unit => '%' }, + ], + } + }, + { label => 'buffer', nlabel => 'memory.buffer.bytes', set => { + key_values => [ { name => 'memBuffer' } ], + output_template => 'Buffer: %s %s', + output_change_bytes => 1, + perfdatas => [ + { label => 'buffer', value => 'memBuffer_absolute', template => '%d', + min => 0, unit => 'B' }, + ], + } + }, + { label => 'cached', nlabel => 'memory.cached.bytes', set => { + key_values => [ { name => 'memCached' } ], + output_template => 'Cached: %s %s', + output_change_bytes => 1, + perfdatas => [ + { label => 'cached', value => 'memCached_absolute', template => '%d', + min => 0, unit => 'B' }, + ], + } + }, + { label => 'shared', nlabel => 'memory.shared.bytes', set => { + key_values => [ { name => 'memShared' } ], + output_template => 'Shared: %s %s', + output_change_bytes => 1, + perfdatas => [ + { label => 'shared', value => 'memShared_absolute', template => '%d', + min => 0, unit => 'B' }, + ], + } + }, + ]; + $self->{maps_counters}->{swap} = [ + { label => 'swap', nlabel => 'swap.usage.bytes', set => { + key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_swap_output'), + perfdatas => [ + { label => 'swap', value => 'used_absolute', template => '%d', min => 0, max => 'total_absolute', + unit => 'B', cast_int => 1 }, + ], + } + }, + { label => 'swap-free', display_ok => 0, nlabel => 'swap.free.bytes', set => { + key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_swap_output'), + perfdatas => [ + { label => 'swap_free', value => 'free_absolute', template => '%d', min => 0, max => 'total_absolute', + unit => 'B', cast_int => 1 }, + ], + } + }, + { label => 'swap-prct', display_ok => 0, nlabel => 'swap.usage.percentage', set => { + key_values => [ { name => 'prct_used' } ], + output_template => 'Used : %.2f %%', + perfdatas => [ + { label => 'swap_prct', value => 'prct_used_absolute', template => '%.2f', min => 0, max => 0, + unit => '%' }, + ], + } + }, + ]; +} + 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:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "swap" => { name => 'check_swap' }, - "warning-swap:s" => { name => 'warning_swap' }, - "critical-swap:s" => { name => 'critical_swap' }, - "no-swap:s" => { name => 'no_swap' }, - }); - $self->{no_swap} = 'critical'; + $options{options}->add_options(arguments => { + 'units:s' => { name => 'units', default => '%' }, + 'free' => { name => 'free' }, + 'swap' => { name => 'check_swap' }, + }); + return $self; } +sub compat_threshold_counter { + my ($self, %options) = @_; + + foreach ('warning', 'critical') { + next if (!defined($options{option_results}->{$_ . '-' . $options{compat}->{th}}) || $options{option_results}->{$_ . '-' . $options{compat}->{th}} eq ''); + if (defined($options{compat}->{free})) { + $options{option_results}->{$_ . '-' . $options{compat}->{th} . '-free'} = $options{option_results}->{$_ . '-' . $options{compat}->{th}}; + $options{option_results}->{$_ . '-' . $options{compat}->{th}} = undef; + } elsif (defined($options{compat}->{units}) && $options{compat}->{units} eq '%') { + $options{option_results}->{$_ . '-' . $options{compat}->{th} . '-prct'} = $options{option_results}->{$_ . '-' . $options{compat}->{th}}; + $options{option_results}->{$_ . '-' . $options{compat}->{th}} = undef; + } + } +} + sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } - if (defined($self->{option_results}->{check_swap})) { - if (($self->{perfdata}->threshold_validate(label => 'warning-swap', value => $self->{option_results}->{warning_swap})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning-swap threshold '" . $self->{option_results}->{warning_swap} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical-swap', value => $self->{option_results}->{critical_swap})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical-swap threshold '" . $self->{option_results}->{critical_swap} . "'."); - $self->{output}->option_exit(); - } - if (defined($self->{option_results}->{no_swap}) && $self->{option_results}->{no_swap} ne '') { - if ($self->{output}->is_litteral_status(status => $self->{option_results}->{no_swap}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong --no-swap status '" . $self->{option_results}->{no_swap} . "'."); - $self->{output}->option_exit(); - } - $self->{no_swap} = $self->{option_results}->{no_swap}; - } - } + # Compatibility + $self->compat_threshold_counter(%options, compat => { th => 'usage', units => $options{option_results}->{units}, free => $options{option_results}->{free}}); + $self->compat_threshold_counter(%options, compat => { th => 'swap', units => $options{option_results}->{units}, free => $options{option_results}->{free}}); + $self->SUPER::check_options(%options); } -sub run { +my $mapping = { + memTotalSwap => { oid => '.1.3.6.1.4.1.2021.4.3' }, + memAvailSwap => { oid => '.1.3.6.1.4.1.2021.4.4' }, + memTotalReal => { oid => '.1.3.6.1.4.1.2021.4.5' }, + memAvailReal => { oid => '.1.3.6.1.4.1.2021.4.6' }, + memTotalFree => { oid => '.1.3.6.1.4.1.2021.4.11' }, + memShared => { oid => '.1.3.6.1.4.1.2021.4.13' }, + memBuffer => { oid => '.1.3.6.1.4.1.2021.4.14' }, + memCached => { oid => '.1.3.6.1.4.1.2021.4.15' }, +}; + +my $oid_memory = '.1.3.6.1.4.1.2021.4'; + +sub memory_calc { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - my $oid_memTotalReal = '.1.3.6.1.4.1.2021.4.5.0'; - my $oid_memAvailReal = '.1.3.6.1.4.1.2021.4.6.0'; - my $oid_memShared = '.1.3.6.1.4.1.2021.4.13.0'; - my $oid_memBuffer = '.1.3.6.1.4.1.2021.4.14.0'; - my $oid_memCached = '.1.3.6.1.4.1.2021.4.15.0'; - my $oid_memTotalSwap = '.1.3.6.1.4.1.2021.4.3.0'; # KB - my $oid_memAvailSwap = '.1.3.6.1.4.1.2021.4.4.0'; # KB - - my $oids = [$oid_memTotalReal, $oid_memAvailReal, - $oid_memShared, $oid_memBuffer, $oid_memCached]; - if (defined($self->{option_results}->{check_swap})) { - push @$oids, ($oid_memTotalSwap, $oid_memAvailSwap); + my $available = ($options{result}->{memAvailReal}) ? $options{result}->{memAvailReal} * 1024 : 0; + my $total = ($options{result}->{memTotalReal}) ? $options{result}->{memTotalReal} * 1024 : 0; + my $buffer = ($options{result}->{memBuffer}) ? $options{result}->{memBuffer} * 1024 : 0; + my $cached = ($options{result}->{memCached}) ? $options{result}->{memCached} * 1024 : 0; + my ($used, $free, $prct_used, $prct_free) = (0, 0, 0, 0); + + if ($total != 0) { + $used = $total - $available - $buffer - $cached; + $free = $total - $used; + $prct_used = $used * 100 / $total; + $prct_free = 100 - $prct_used; } - my $result = $self->{snmp}->get_leef(oids => $oids, - nothing_quit => 1); + + $self->{ram} = { + total => $total, + used => $used, + free => $free, + prct_used => $prct_used, + prct_free => $prct_free, + memShared => ($options{result}->{memShared}) ? $options{result}->{memShared} * 1024 : 0, + memBuffer => $buffer, + memCached => $cached, + }; +} - my $shared_used = defined($result->{$oid_memShared}) ? $result->{$oid_memShared} * 1024 : 0; - my $cached_used = $result->{$oid_memCached} * 1024; - my $buffer_used = $result->{$oid_memBuffer} * 1024; - my $physical_used = ($result->{$oid_memTotalReal} * 1024) - ($result->{$oid_memAvailReal} * 1024); - my $nobuf_used = $physical_used - $buffer_used - $cached_used; - - my $total_size = $result->{$oid_memTotalReal} * 1024; - - my $prct_used = $nobuf_used * 100 / $total_size; - my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); +sub swap_calc { + my ($self, %options) = @_; - my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $total_size); - my ($nobuf_value, $nobuf_unit) = $self->{perfdata}->change_bytes(value => $nobuf_used); - my ($buffer_value, $buffer_unit) = $self->{perfdata}->change_bytes(value => $buffer_used); - my ($cached_value, $cached_unit) = $self->{perfdata}->change_bytes(value => $cached_used); - my ($shared_value, $shared_unit) = $self->{perfdata}->change_bytes(value => $shared_used); - - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Ram Total: %s, Used (-buffers/cache): %s (%.2f%%), Buffer: %s, Cached: %s, Shared: %s", - $total_value . " " . $total_unit, - $nobuf_value . " " . $nobuf_unit, $prct_used, - $buffer_value . " " . $buffer_unit, - $cached_value . " " . $cached_unit, - $shared_value . " " . $shared_unit)); - - $self->{output}->perfdata_add(label => "cached", unit => 'B', - value => $cached_used, - min => 0); - $self->{output}->perfdata_add(label => "buffer", unit => 'B', - value => $buffer_used, - min => 0); - $self->{output}->perfdata_add(label => "used", unit => 'B', - value => $nobuf_used, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size, cast_int => 1), - min => 0, max => $total_size); + my $free = ($options{result}->{memAvailSwap}) ? $options{result}->{memAvailSwap} * 1024 : 0; + my $total = ($options{result}->{memTotalSwap}) ? $options{result}->{memTotalSwap} * 1024 : 0; + my ($used, $prct_used, $prct_free) = (0, 0, 0, 0); - if (defined($self->{option_results}->{check_swap})) { - if ($result->{$oid_memTotalSwap} == 0) { - $self->{output}->output_add(severity => $self->{no_swap}, - short_msg => 'No active swap.'); - $self->{output}->display(); - $self->{output}->exit(); - } - - $total_size = $result->{$oid_memTotalSwap} * 1024; - my $swap_used = ($result->{$oid_memTotalSwap} - $result->{$oid_memAvailSwap}) * 1024; - - $prct_used = $swap_used * 100 / $total_size; - $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical-swap', 'exit_litteral' => 'critical' }, { label => 'warning-swap', exit_litteral => 'warning' } ]); - - my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $total_size); - my ($swap_used_value, $swap_used_unit) = $self->{perfdata}->change_bytes(value => $swap_used); - my ($swap_free_value, $swap_free_unit) = $self->{perfdata}->change_bytes(value => ($total_size - $swap_used)); - - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Swap Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", - $total_value . " " . $total_unit, - $swap_used_value . " " . $swap_used_unit, $prct_used, - $swap_free_value . " " . $swap_free_unit, (100 - $prct_used))); - - $self->{output}->perfdata_add(label => "swap", unit => 'B', - value => $swap_used, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-swap', total => $total_size, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-swap', total => $total_size, cast_int => 1), - min => 0, max => $total_size); + if ($total != 0) { + $used = $total - $free; + $prct_used = $used * 100 / $total; + $prct_free = 100 - $prct_used; + } + + $self->{swap} = { + total => $total, + used => $used, + free => $free, + prct_used => $prct_used, + prct_free => $prct_free, + }; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{snmp}->get_table(oid => $oid_memory, end => $mapping->{memCached}->{oid}); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => 0); + + $self->memory_calc(result => $result); + if (defined($self->{option_results}->{check_swap})) { + $self->swap_calc(result => $result); } - - $self->{output}->display(); - $self->{output}->exit(); } 1; @@ -173,33 +267,28 @@ __END__ =head1 MODE -Check physical memory (UCD-SNMP-MIB). +Check memory usage (UCD-SNMP-MIB). =over 8 -=item B<--warning> +=item B<--units> -Threshold warning in percent. +Units of thresholds (Default: '%') ('%', 'absolute') (Deprecated. Please use new counters directly) -=item B<--critical> +=item B<--free> -Threshold critical in percent. +Thresholds are on free space left (Deprecated. Please use new counters directly) =item B<--swap> Check swap also. -=item B<--warning-swap> +=item B<--warning-*> B<--critical-*> -Threshold warning in percent. - -=item B<--critical-swap> - -Threshold critical in percent. - -=item B<--no-swap> - -Threshold if no active swap (default: 'critical'). +Thresholds. +Can be: 'usage' (B), 'usage-free' (B), 'usage-prct' (%), +'swap' (B), 'swap-free' (B), 'swap-prct' (%), +'buffer' (B), 'cached' (B), 'shared' (B). =back diff --git a/snmp_standard/mode/ntp.pm b/snmp_standard/mode/ntp.pm index 7deabd372..03e340e72 100644 --- a/snmp_standard/mode/ntp.pm +++ b/snmp_standard/mode/ntp.pm @@ -68,13 +68,7 @@ sub run { my ($ref_time, $distant_time); my $oid_hrSystemDate = '.1.3.6.1.2.1.25.1.2.0'; - my $result = $self->{snmp}->get_leef(oids => [ $oid_hrSystemDate ]); - if (scalar(keys %$result) == 0) { - $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Cannot get 'hrSystemDate' information."); - $self->{output}->display(); - $self->{output}->exit(); - } + my $result = $self->{snmp}->get_leef(oids => [ $oid_hrSystemDate ], nothing_quit => 1); if (defined($self->{option_results}->{ntp_hostname}) && $self->{option_results}->{ntp_hostname} ne '') { my %ntp; diff --git a/snmp_standard/mode/printererror.pm b/snmp_standard/mode/printererror.pm index 00818a12c..10f060be4 100644 --- a/snmp_standard/mode/printererror.pm +++ b/snmp_standard/mode/printererror.pm @@ -20,29 +20,54 @@ package snmp_standard::mode::printererror; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); -my %errors_printer = ( - 0 => ["Printer is low paper", 'WARNING'], - 1 => ["Printer has no paper", 'WARNING'], - 2 => ["Printer is low toner", 'WARNING'], - 3 => ["Printer has no toner", 'WARNING'], - 4 => ["Printer has a door open", 'WARNING'], - 5 => ["Printer is jammed", 'WARNING'], - 6 => ["Printer is offline", 'WARNING'], - 7 => ["Printer needs service requested", 'WARNING'], - - 8 => ["Printer has input tray missing", 'WARNING'], - 9 => ["Printer has output tray missing", 'WARNING'], - 10 => ["Printer has maker supply missing", 'WARNING'], - 11 => ["Printer output is near full", 'WARNING'], - 12 => ["Printer output is full", 'WARNING'], - 13 => ["Printer has input tray empty", 'WARNING'], - 14 => ["Printer is 'overdue prevent maint'", 'WARNING'], -); +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'printer', type => 3, cb_prefix_output => 'prefix_printer_output', cb_long_output => 'printer_long_output', indent_long_output => ' ', message_multiple => 'All printers are ok', + group => [ + { name => 'errors', message_multiple => 'Printer is ok', type => 1, skipped_code => { -10 => 1 } }, + ] + } + ]; + + $self->{maps_counters}->{errors} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' } ], + closure_custom_calc => $self->can('custom_status_calc'), + output_template => "status is '%s'", + output_use => 'status', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + ]; +} + +sub prefix_printer_output { + my ($self, %options) = @_; + + return "Printer '" . $options{instance_value}->{display} . "' "; +} + +sub printer_long_output { + my ($self, %options) = @_; + + return "checking printer '" . $options{instance_value}->{display} . "'"; +} sub new { my ($class, %options) = @_; @@ -50,43 +75,68 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + "ok-status:s" => { name => 'ok_status', default => '%{status} =~ /ok/' }, + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /.*/' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + }); return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['ok_status', 'unknown_status', 'warning_status', 'critical_status']); } -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; +my %errors_printer = ( + 0 => 'low paper', + 1 => 'no paper', + 2 => 'low toner', + 3 => 'no toner', + 4 => 'door open', + 5 => 'jammed', + 6 => 'offline', + 7 => 'service requested', + 8 => 'input tray missing', + 9 => 'output tray missing', + 10 => 'maker supply missing', + 11 => 'output near full', + 12 => 'output full', + 13 => 'input tray empty', + 14 => 'overdue prevent maint', +); + +sub manage_selection { + my ($self, %options) = @_; - $self->{output}->output_add(severity => 'OK', - short_msg => "Printer is ok."); - my $oid_hrPrinterDetectedErrorState = '.1.3.6.1.2.1.25.3.5.1.2'; - my $result = $self->{snmp}->get_table(oid => $oid_hrPrinterDetectedErrorState, nothing_quit => 1); - + my $result = $options{snmp}->get_table(oid => $oid_hrPrinterDetectedErrorState, nothing_quit => 1); + + $self->{printer} = {}; foreach (keys %$result) { + /\.(\d+)$/; + my $instance = $1; # 16 bits value my $value = unpack('S', $result->{$_}); + $self->{printer}->{$instance} = { display => $instance, errors => {} }; + my $i = 0; foreach my $key (keys %errors_printer) { - if (($value & (1 << $key)) && - (!$self->{output}->is_status(value => ${$errors_printer{$key}}[1], compare => 'ok', litteral => 1))) { - $self->{output}->output_add(severity => ${$errors_printer{$key}}[1], - short_msg => sprintf(${$errors_printer{$key}}[0])); + if (($value & (1 << $key))) { + $self->{printer}->{$instance}->{errors}->{$i} = { status => $errors_printer{$key} }; + $i++; } } + + if ($i == 0) { + $self->{printer}->{$instance}->{errors}->{0} = { status => 'ok' }; + next; + } } - - $self->{output}->display(); - $self->{output}->exit(); } 1; @@ -99,6 +149,26 @@ Check printer errors (HOST-RESOURCES-MIB). =over 8 +=item B<--ok-status> + +Set warning threshold for status (Default: '%{status} =~ /ok/'). +Can used special variables like: %{status} + +=item B<--unknown-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status} + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{status} =~ /.*/'). +Can used special variables like: %{status} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{status} + =back =cut diff --git a/snmp_standard/mode/storage.pm b/snmp_standard/mode/storage.pm index 982f9a8fe..8ea8588cf 100644 --- a/snmp_standard/mode/storage.pm +++ b/snmp_standard/mode/storage.pm @@ -27,8 +27,6 @@ use warnings; use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); -my $instance_mode; - my %oids_hrStorageTable = ( 'hrstoragedescr' => '.1.3.6.1.2.1.25.2.3.1.3', 'hrfsmountpoint' => '.1.3.6.1.2.1.25.3.8.1.2', @@ -74,25 +72,28 @@ my %storage_types_manage = ( sub custom_usage_perfdata { my ($self, %options) = @_; - my $label = 'used'; + my ($label, $nlabel) = ('used', $self->{nlabel}); my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { - $label = 'free'; + if (defined($self->{instance_mode}->{option_results}->{free})) { + ($label, $nlabel) = ('free', 'storage.space.free.bytes'); $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + nlabel => $nlabel, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -100,12 +101,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -128,8 +129,8 @@ sub custom_usage_calc { $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_size'} * $options{new_datas}->{$self->{instance} . '_allocation_units'}; my $reserved_value = 0; - if (defined($instance_mode->{option_results}->{space_reservation})) { - $reserved_value = $instance_mode->{option_results}->{space_reservation} * $self->{result_values}->{total} / 100; + if (defined($self->{instance_mode}->{option_results}->{space_reservation})) { + $reserved_value = $self->{instance_mode}->{option_results}->{space_reservation} * $self->{result_values}->{total} / 100; } $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'} * $options{new_datas}->{$self->{instance} . '_allocation_units'}; @@ -147,15 +148,25 @@ sub custom_usage_calc { return 0; } +sub custom_access_output { + my ($self, %options) = @_; + + my $msg = sprintf("Access : %s", + $self->{result_values}->{access_absolute} == 1 ? 'readWrite' : 'readOnly' + ); + + return $msg; +} + sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'storage', type => 1, cb_prefix_output => 'prefix_storage_output', message_multiple => 'All storages are ok' }, + { name => 'storage', type => 1, cb_prefix_output => 'prefix_storage_output', message_multiple => 'All storages are ok', skipped_code => { -10 => 1 } }, ]; $self->{maps_counters}->{storage} = [ - { label => 'usage', set => { + { label => 'usage', nlabel => 'storage.space.usage.bytes', set => { key_values => [ { name => 'display' }, { name => 'used' }, { name => 'size' }, { name => 'allocation_units' } ], closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_output => $self->can('custom_usage_output'), @@ -163,6 +174,15 @@ sub set_counters { closure_custom_threshold_check => $self->can('custom_usage_threshold'), } }, + { label => 'access', nlabel => 'storage.access', set => { + key_values => [ { name => 'access' }, { name => 'display' } ], + closure_custom_output => $self->can('custom_access_output'), + perfdatas => [ + { label => 'access', value => 'access_absolute', template => '%d', min => 1, max => 2, + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, ]; } @@ -184,23 +204,23 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - "reload-cache-time:s" => { name => 'reload_cache_time', default => 180 }, - "name" => { name => 'use_name' }, - "storage:s" => { name => 'storage' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - "oid-filter:s" => { name => 'oid_filter', default => 'hrStorageDescr'}, - "oid-display:s" => { name => 'oid_display', default => 'hrStorageDescr'}, - "display-transform-src:s" => { name => 'display_transform_src' }, - "display-transform-dst:s" => { name => 'display_transform_dst' }, - "show-cache" => { name => 'show_cache' }, - "space-reservation:s" => { name => 'space_reservation' }, - "filter-storage-type:s" => { name => 'filter_storage_type', default => $self->default_storage_type() }, - }); + $options{options}->add_options(arguments => { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "reload-cache-time:s" => { name => 'reload_cache_time', default => 180 }, + "name" => { name => 'use_name' }, + "storage:s" => { name => 'storage' }, + "regexp" => { name => 'use_regexp' }, + "regexp-isensitive" => { name => 'use_regexpi' }, + "oid-filter:s" => { name => 'oid_filter', default => 'hrStorageDescr'}, + "oid-display:s" => { name => 'oid_display', default => 'hrStorageDescr'}, + "display-transform-src:s" => { name => 'display_transform_src' }, + "display-transform-dst:s" => { name => 'display_transform_dst' }, + "show-cache" => { name => 'show_cache' }, + "space-reservation:s" => { name => 'space_reservation' }, + "filter-storage-type:s" => { name => 'filter_storage_type', default => $self->default_storage_type() }, + "add-access" => { name => 'add_access' }, + }); $self->{storage_id_selected} = []; $self->{statefile_cache} = centreon::plugins::statefile->new(%options); @@ -230,7 +250,36 @@ sub check_options { } $self->{statefile_cache}->check_options(%options); - $instance_mode = $self; +} + +sub access_result { + my ($self, %options) = @_; + + return {} + if (!defined($self->{option_results}->{add_access})); + my $oid_hrFSAccess = '.1.3.6.1.2.1.25.3.8.1.5'; + my $relations = $self->{statefile_cache}->get(name => 'relation_storageindex_fsstorageindex'); + return {} if (!defined($relations) || scalar(keys %$relations) <= 0); + my @instances = []; + foreach (@{$self->{storage_id_selected}}) { + if (defined($relations->{$_})) { + push @instances, $relations->{$_}; + } + } + + $self->{snmp}->load( + oids => [$oid_hrFSAccess], + instances => \@instances, nothing_quit => 1 + ); + my $snmp_result = $self->{snmp}->get_leef(); + my $result = {}; + foreach (@{$self->{storage_id_selected}}) { + if (defined($snmp_result->{$oid_hrFSAccess . '.' . $relations->{$_}})) { + $result->{$_} = $snmp_result->{$oid_hrFSAccess . '.' . $relations->{$_}}; + } + } + + return $result; } sub manage_selection { @@ -243,10 +292,11 @@ sub manage_selection { my $oid_hrStorageSize = '.1.3.6.1.2.1.25.2.3.1.5'; my $oid_hrStorageUsed = '.1.3.6.1.2.1.25.2.3.1.6'; my $oid_hrStorageType = '.1.3.6.1.2.1.25.2.3.1.2'; - + $self->{snmp}->load(oids => [$oid_hrStorageAllocationUnits, $oid_hrStorageSize, $oid_hrStorageUsed], instances => $self->{storage_id_selected}, nothing_quit => 1); my $result = $self->{snmp}->get_leef(); + my $access_result = $self->access_result(); $self->{storage} = {}; foreach (sort @{$self->{storage_id_selected}}) { @@ -271,6 +321,7 @@ sub manage_selection { allocation_units => $result->{$oid_hrStorageAllocationUnits . "." . $_}, size => $result->{$oid_hrStorageSize . "." . $_}, used => $result->{$oid_hrStorageUsed . "." . $_}, + access => defined($access_result->{$_}) ? $access_result->{$_} : undef, }; } @@ -288,18 +339,26 @@ sub reload_cache { $datas->{oid_display} = $self->{option_results}->{oid_display}; $datas->{last_timestamp} = time(); $datas->{all_ids} = []; + $datas->{relation_storageindex_fsstorageindex} = {}; my $request = [ { oid => $oids_hrStorageTable{hrstoragetype} } ]; my $added = {}; + my $build_relation = 0; foreach (($self->{option_results}->{oid_filter}, $self->{option_results}->{oid_display} )) { next if (defined($added->{$_})); $added->{$_} = 1; if (/hrFSMountPoint/i) { push @{$request}, ({ oid => $oids_hrStorageTable{hrfsmountpoint} }, { oid => $oids_hrStorageTable{hrfsstorageindex} }); + $build_relation = 1; } else { push @{$request}, { oid => $oids_hrStorageTable{hrstoragedescr} }; } } + + if (defined($self->{option_results}->{add_access}) && !defined($added->{hrFSMountPoint})) { + push @{$request}, { oid => $oids_hrStorageTable{hrfsstorageindex} }; + $build_relation = 1; + } my $result = $self->{snmp}->get_multiple_table(oids => $request); foreach ((['filter', $self->{option_results}->{oid_filter}], ['display', $self->{option_results}->{oid_display}], ['type', 'hrstoragetype'])) { @@ -317,6 +376,13 @@ sub reload_cache { $datas->{$$_[1] . "_" . $storage_index} = $self->{output}->to_utf8($result->{ $oids_hrStorageTable{$$_[1]} }->{$key}); } } + + if ($build_relation == 1) { + foreach (keys %{$result->{ $oids_hrStorageTable{hrfsstorageindex} }}) { + /\.([0-9]+)$/; + $datas->{relation_storageindex_fsstorageindex}->{ $result->{ $oids_hrStorageTable{hrfsstorageindex} }->{$_} } = $1; + } + } if (scalar(@{$datas->{all_ids}}) <= 0) { $self->{output}->add_option_msg(short_msg => "Can't construct cache..."); @@ -416,6 +482,19 @@ Threshold warning. Threshold critical. +=item B<--warning-access> + +Threshold warning. + +=item B<--critical-access> + +Threshold critical. +Check if storage is readOnly: --critical-access=@2:2 + +=item B<--add-access> + +Check storage access (readOnly, readWrite). + =item B<--units> Units of thresholds (Default: '%') ('%', 'B'). diff --git a/snmp_standard/mode/swap.pm b/snmp_standard/mode/swap.pm index 21546d1c0..d2a2e59cd 100644 --- a/snmp_standard/mode/swap.pm +++ b/snmp_standard/mode/swap.pm @@ -20,87 +20,111 @@ package snmp_standard::mode::swap; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +sub custom_swap_output { + my ($self, %options) = @_; + + my $msg = sprintf("Swap Total: %s %s Used: %s %s (%.2f%%) Free: %s %s (%.2f%%)", + $self->{perfdata}->change_bytes(value => $self->{result_values}->{total_absolute}), + $self->{perfdata}->change_bytes(value => $self->{result_values}->{used_absolute}), + $self->{result_values}->{prct_used_absolute}, + $self->{perfdata}->change_bytes(value => $self->{result_values}->{free_absolute}), + $self->{result_values}->{prct_free_absolute}); + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'swap', type => 0, message_separator => ' - ', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{swap} = [ + { label => 'usage', nlabel => 'swap.usage.bytes', set => { + key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_swap_output'), + perfdatas => [ + { label => 'used', value => 'used_absolute', template => '%d', min => 0, max => 'total_absolute', + unit => 'B', cast_int => 1 }, + ], + } + }, + { label => 'usage-free', display_ok => 0, nlabel => 'swap.free.bytes', set => { + key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ], + closure_custom_output => $self->can('custom_swap_output'), + perfdatas => [ + { label => 'free', value => 'free_absolute', template => '%d', min => 0, max => 'total_absolute', + unit => 'B', cast_int => 1 }, + ], + } + }, + { label => 'usage-prct', display_ok => 0, nlabel => 'swap.usage.percentage', set => { + key_values => [ { name => 'prct_used' } ], + output_template => 'Used : %.2f %%', + perfdatas => [ + { label => 'used_prct', value => 'prct_used_absolute', template => '%.2f', min => 0, max => 0, + unit => '%' }, + ], + } + }, + ]; +} + 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:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "no-swap:s" => { name => 'no_swap' }, - }); - $self->{no_swap} = 'critical'; + $options{options}->add_options(arguments => { + 'no-swap:s' => { name => 'no_swap' }, + }); + return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->SUPER::check_options(%options); - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } + $self->{no_swap} = 'critical'; if (defined($self->{option_results}->{no_swap}) && $self->{option_results}->{no_swap} ne '') { if ($self->{output}->is_litteral_status(status => $self->{option_results}->{no_swap}) == 0) { $self->{output}->add_option_msg(short_msg => "Wrong --no-swap status '" . $self->{option_results}->{no_swap} . "'."); $self->{output}->option_exit(); } - $self->{no_swap} = $self->{option_results}->{no_swap}; + $self->{no_swap} = $self->{option_results}->{no_swap}; } } -sub run { +sub manage_selection { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; my $oid_memTotalSwap = '.1.3.6.1.4.1.2021.4.3.0'; # KB my $oid_memAvailSwap = '.1.3.6.1.4.1.2021.4.4.0'; # KB - my $result = $self->{snmp}->get_leef(oids => [$oid_memTotalSwap, $oid_memAvailSwap], nothing_quit => 1); + my $result = $options{snmp}->get_leef(oids => [$oid_memTotalSwap, $oid_memAvailSwap], nothing_quit => 1); if ($result->{$oid_memTotalSwap} == 0) { $self->{output}->output_add(severity => $self->{no_swap}, - short_msg => 'No active swap.'); - $self->{output}->display(); - $self->{output}->exit(); + short_msg => 'No active swap'); + return ; } - - my $total_size = $result->{$oid_memTotalSwap} * 1024; - my $swap_used = ($result->{$oid_memTotalSwap} - $result->{$oid_memAvailSwap}) * 1024; - - my $prct_used = $swap_used * 100 / $total_size; - my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $total_size); - my ($swap_used_value, $swap_used_unit) = $self->{perfdata}->change_bytes(value => $swap_used); - my ($swap_free_value, $swap_free_unit) = $self->{perfdata}->change_bytes(value => ($total_size - $swap_used)); - - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Swap Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", - $total_value . " " . $total_unit, - $swap_used_value . " " . $swap_used_unit, $prct_used, - $swap_free_value . " " . $swap_free_unit, (100 - $prct_used))); - - $self->{output}->perfdata_add(label => "used", unit => 'B', - value => $swap_used, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size, cast_int => 1), - min => 0, max => $total_size); - - $self->{output}->display(); - $self->{output}->exit(); + my $free = $result->{$oid_memAvailSwap} * 1024; + my $total = $result->{$oid_memTotalSwap} * 1024; + my $prct_used = ($total - $free) * 100 / $total; + $self->{swap} = { + total => $total, + used => $total - $free, + free => $free, + prct_used => $prct_used, + prct_free => 100 - $prct_used, + }; } 1; @@ -113,18 +137,15 @@ Check swap memory (UCD-SNMP-MIB). =over 8 -=item B<--warning> - -Threshold warning in percent. - -=item B<--critical> - -Threshold critical in percent. - =item B<--no-swap> Threshold if no active swap (default: 'critical'). +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'usage' (B), 'usage-free' (B), 'usage-prct' (%). + =back =cut diff --git a/snmp_standard/mode/uptime.pm b/snmp_standard/mode/uptime.pm index e1c2d1b29..17021d7df 100644 --- a/snmp_standard/mode/uptime.pm +++ b/snmp_standard/mode/uptime.pm @@ -35,18 +35,21 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "force-oid:s" => { name => 'force_oid' }, - "check-overload" => { name => 'check_overload' }, - }); + $options{options}->add_options(arguments => { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "force-oid:s" => { name => 'force_oid' }, + "check-overload" => { name => 'check_overload' }, + "reboot-window:s" => { name => 'reboot_window', default => 5000 }, + "unit:s" => { name => 'unit', default => 's' }, + }); $self->{statefile_cache} = centreon::plugins::statefile->new(%options); return $self; } +my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 }; + sub check_options { my ($self, %options) = @_; $self->SUPER::init(%options); @@ -59,6 +62,9 @@ sub check_options { $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); $self->{output}->option_exit(); } + if ($self->{option_results}->{unit} eq '' || !defined($unitdiv->{$self->{option_results}->{unit}})) { + $self->{option_results}->{unit} = 's'; + } $self->{statefile_cache}->check_options(%options); } @@ -69,25 +75,25 @@ sub check_overload { return $options{timeticks} if (!defined($self->{option_results}->{check_overload})); my $current_time = floor(time() * 100); - $self->{new_datas} = { last_time => $current_time, uptime => $options{timeticks}, overload => 0 }; + $self->{new_datas} = { last_time => $current_time, uptime => $options{timeticks} }; $self->{statefile_cache}->read(statefile => "cache_" . $self->{snmp}->get_hostname() . '_' . $self->{snmp}->get_port() . '_' . $self->{mode}); my $old_uptime = $self->{statefile_cache}->get(name => 'uptime'); my $last_time = $self->{statefile_cache}->get(name => 'last_time'); - my $overload = $self->{statefile_cache}->get(name => 'overload'); + $self->{new_datas}->{overload} = $self->{statefile_cache}->get(name => 'overload') || 0; - if (defined($old_uptime) && $old_uptime < $current_time) { + if (defined($old_uptime) && $options{timeticks} < $old_uptime) { my $diff_time = $current_time - $last_time; my $overflow = ($old_uptime + $diff_time) % 4294967296; my $division = ($old_uptime + $diff_time) / 4294967296; if ($division >= 1 && - $overflow >= ($options{timeticks} - 5000) && - $overflow <= ($options{timeticks} + 5000)) { - $overload++; + $overflow >= ($options{timeticks} - ($self->{option_results}->{reboot_window} / 2)) && + $overflow <= ($options{timeticks} + ($self->{option_results}->{reboot_window} / 2))) { + $self->{new_datas}->{overload}++; + } else { + $self->{new_datas}->{overload} = 0; } - - $options{timeticks} += ($overload * 4294967296); } - $self->{new_datas}->{overload} = $overload if (defined($overload)); + $options{timeticks} += ($self->{new_datas}->{overload} * 4294967296); $self->{statefile_cache}->write(data => $self->{new_datas}); return $options{timeticks}; @@ -118,10 +124,10 @@ sub run { $value = $self->check_overload(timeticks => $value); $value = floor($value / 100); - my $exit_code = $self->{perfdata}->threshold_check(value => $value, + my $exit_code = $self->{perfdata}->threshold_check(value => floor($value / $unitdiv->{$self->{option_results}->{unit}}), threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{output}->perfdata_add(label => 'uptime', unit => 's', - value => $value, + $self->{output}->perfdata_add(label => 'uptime', unit => $self->{option_results}->{unit}, + value => floor($value / $unitdiv->{$self->{option_results}->{unit}}), warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), min => 0); @@ -161,6 +167,16 @@ Can choose your oid (numeric format only). Uptime counter limit is 4294967296 and overflow. With that option, we manage the counter going back. But there is a few chance we can miss a reboot. +=item B<--reboot-window> + +To be used with check-overload option. Time in milliseconds (Default: 5000) +You increase the chance of not missing a reboot if you decrease that value. + +=item B<--unit> + +Select the unit for performance data and thresholds. May be 's' for seconds, 'm' for minutes, +'h' for hours, 'd' for days, 'w' for weeks. Default is seconds + =back =cut diff --git a/storage/avid/isis/snmp/mode/performance.pm b/storage/avid/isis/snmp/mode/performance.pm index 8e94fc979..d99604970 100644 --- a/storage/avid/isis/snmp/mode/performance.pm +++ b/storage/avid/isis/snmp/mode/performance.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_client_perfdata { my ($self, %options) = @_; @@ -41,7 +39,7 @@ sub custom_client_threshold { my ($self, %options) = @_; my ($exit, $threshold_value); - $threshold_value = defined($instance_mode->{option_results}->{percent}) ? $self->{result_values}->{prct_active} : $self->{result_values}->{active} ; + $threshold_value = defined($self->{instance_mode}->{option_results}->{percent}) ? $self->{result_values}->{prct_active} : $self->{result_values}->{active} ; $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); @@ -129,20 +127,13 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "percent" => { name => 'percent' }, - }); + $options{options}->add_options(arguments => { + "percent" => { name => 'percent' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - my $oid_ReadMegabytesPerSecond = '.1.3.6.1.4.1.526.20.3.2.0'; my $oid_WriteMegabytesPerSecond = '.1.3.6.1.4.1.526.20.3.3.0'; my $oid_MessagesPerSecond = '.1.3.6.1.4.1.526.20.3.4.0'; diff --git a/storage/avid/isis/snmp/mode/status.pm b/storage/avid/isis/snmp/mode/status.pm index 813df3061..726712463 100644 --- a/storage/avid/isis/snmp/mode/status.pm +++ b/storage/avid/isis/snmp/mode/status.pm @@ -74,11 +74,11 @@ sub new { 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} !~ /Online/i' }, - }); + $options{options}->add_options(arguments => { + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /Online/i' }, + }); + return $self; } @@ -86,8 +86,7 @@ sub check_options { my ($self, %options) = @_; $self->SUPER::check_options(%options); - $instance_mode = $self; - $self->change_macros('warning_status', 'critical_status'); + $self->change_macros(macros => ['warning_status', 'critical_status']); } my %map_status = ( diff --git a/storage/avid/isis/snmp/mode/usage.pm b/storage/avid/isis/snmp/mode/usage.pm index 480bd8370..2f43b5f67 100644 --- a/storage/avid/isis/snmp/mode/usage.pm +++ b/storage/avid/isis/snmp/mode/usage.pm @@ -25,19 +25,17 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{allocated}; $total_options{cast_int} = 1; } @@ -58,10 +56,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); @@ -152,21 +150,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - my $oid_TotalSystemMB = '.1.3.6.1.4.1.526.20.4.2.0'; my $oid_TotalAllocatedMB = '.1.3.6.1.4.1.526.20.4.3.0'; my $oid_TotalUsedMB = '.1.3.6.1.4.1.526.20.4.4.0'; diff --git a/storage/buffalo/terastation/snmp/mode/arrayusage.pm b/storage/buffalo/terastation/snmp/mode/arrayusage.pm new file mode 100644 index 000000000..46f2a1fdc --- /dev/null +++ b/storage/buffalo/terastation/snmp/mode/arrayusage.pm @@ -0,0 +1,161 @@ +# +# Copyright 2019 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 storage::buffalo::terastation::snmp::mode::arrayusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + + my $msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{prct_used} = $options{new_datas}->{$self->{instance} . '_nasArrayUsed'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_nasArrayCapacity'} * 1024 * 1024 * 1024; + $self->{result_values}->{used} = int($self->{result_values}->{prct_used} * $self->{result_values}->{total} / 100); + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'array', type => 1, cb_prefix_output => 'prefix_array_output', message_multiple => 'All arrays are ok' } + ]; + + $self->{maps_counters}->{array} = [ + { label => 'usage', nlabel => 'array.space.usage.bytes', set => { + key_values => [ { name => 'display' }, { name => 'nasArrayCapacity' }, { name => 'nasArrayUsed' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + threshold_use => 'prct_used', + perfdatas => [ + { label => 'used', value => 'used', template => '%s', + unit => 'B', min => 0, max => 'total', cast_int => 1 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub prefix_array_output { + my ($self, %options) = @_; + + return "Array '" . $options{instance_value}->{display} . "' "; +} + +my $mapping = { + nasArrayCapacity => { oid => '.1.3.6.1.4.1.5227.27.1.3.1.3' }, # in GB + nasArrayUsed => { oid => '.1.3.6.1.4.1.5227.27.1.3.1.4' }, # in % +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_nasArrayEntry = '.1.3.6.1.4.1.5227.27.1.3.1'; + my $snmp_result = $options{snmp}->get_table( + oid => $oid_nasArrayEntry, + start => $mapping->{nasArrayCapacity}->{oid}, + end => $mapping->{nasArrayUsed}->{oid}, + nothing_quit => 1 + ); + + $self->{array} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{nasArrayCapacity}->{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 '' && + $instance !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $instance . "': no matching array name.", debug => 1); + next; + } + if ($result->{nasArrayUsed} == -1) { + $self->{output}->output_add(long_msg => "skipping '" . $instance . "': array not used.", debug => 1); + next; + } + + $self->{array}->{$instance} = { display => $instance, %$result }; + } + + if (scalar(keys %{$self->{array}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No array found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check array usages. + +=over 8 + +=item B<--filter-name> + +Filter by name (regexp can be used). + +=item B<--warning-usage> + +Threshold warning (in percent). + +=item B<--critical-usage> + +Threshold critical (in percent). + +=back + +=cut diff --git a/storage/buffalo/terastation/snmp/mode/components/disk.pm b/storage/buffalo/terastation/snmp/mode/components/disk.pm new file mode 100644 index 000000000..e9df170b1 --- /dev/null +++ b/storage/buffalo/terastation/snmp/mode/components/disk.pm @@ -0,0 +1,70 @@ +# +# Copyright 2019 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 storage::buffalo::terastation::snmp::::mode::components::disk; + +use strict; +use warnings; + +my %map_disk_status = ( + 1 => 'notSupport', 1 => 'normal', 2 => 'array1', 3 => 'array2', + 4 => 'standby', 5 => 'degrade', 6 => 'remove', 7 => 'standbyRemoved', + 8 => 'degradeRemoved', 9 => 'removeRemoved', 10 => 'array3', + 11 => 'array4', 12 => 'mediaCartridge', 13 => 'array5', 14 => 'array6', +); + +my $mapping = { + nasDiskStatus => { oid => '.1.3.6.1.4.1.5227.27.1.2.1.2', map => \%map_disk_status }, +}; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping->{nasDiskStatus}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking disks"); + $self->{components}->{disk} = { name => 'disks', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'disk')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{ $mapping->{nasDiskStatus}->{oid} }})) { + $oid =~ /^$mapping->{nasDiskStatus}->{oid}\.(.*)$/; + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{ $mapping->{nasDiskStatus}->{oid} }, instance => $instance); + + next if ($self->check_filter(section => 'disk', instance => $instance)); + $self->{components}->{disk}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("disk '%s' status is '%s' [instance: %s].", + $instance, $result->{nasDiskStatus}, $instance + )); + my $exit = $self->get_severity(section => 'disk', value => $result->{nasDiskStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Disk '%s' status is '%s'", + $instance, $result->{nasDiskStatus})); + } + } +} + +1; diff --git a/storage/buffalo/terastation/snmp/mode/components/iscsi.pm b/storage/buffalo/terastation/snmp/mode/components/iscsi.pm new file mode 100644 index 000000000..f8162bc4a --- /dev/null +++ b/storage/buffalo/terastation/snmp/mode/components/iscsi.pm @@ -0,0 +1,69 @@ +# +# Copyright 2019 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 storage::buffalo::terastation::snmp::::mode::components::iscsi; + +use strict; +use warnings; + +my %map_iscsi_status = ( + 1 => 'unknown', 1 => 'connected', 2 => 'standing-by', +); + +my $mapping = { + nasISCSIName => { oid => '.1.3.6.1.4.1.5227.27.1.9.1.2' }, + nasISCSIStatus => { oid => '.1.3.6.1.4.1.5227.27.1.9.1.3', map => \%map_iscsi_status }, +}; +my $nasISCSIEntry = '.1.3.6.1.4.1.5227.27.1.9.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $nasISCSIEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking iscsi"); + $self->{components}->{iscsi} = { name => 'iscsi', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'iscsi')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{ $nasISCSIEntry }})) { + next if ($oid !~ /^$mapping->{nasISCSIStatus}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{ $nasISCSIEntry }, instance => $instance); + + next if ($self->check_filter(section => 'iscsi', instance => $instance, name => $result->{nasISCSIName})); + $self->{components}->{iscsi}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("iscsi '%s' status is '%s' [instance: %s].", + $result->{nasISCSIName}, $result->{nasISCSIStatus}, $instance + )); + my $exit = $self->get_severity(section => 'iscsi', value => $result->{nasISCSIStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Iscsi '%s' status is '%s'", + $result->{nasISCSIName}, $result->{nasISCSIStatus})); + } + } +} + +1; diff --git a/storage/buffalo/terastation/snmp/mode/components/psu.pm b/storage/buffalo/terastation/snmp/mode/components/psu.pm new file mode 100644 index 000000000..88ef41881 --- /dev/null +++ b/storage/buffalo/terastation/snmp/mode/components/psu.pm @@ -0,0 +1,67 @@ +# +# Copyright 2019 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 storage::buffalo::terastation::snmp::::mode::components::psu; + +use strict; +use warnings; + +my %map_psu_status = ( + -1 => 'unknown', 1 => 'fine', 2 => 'broken', +); + +my $mapping = { + nasRPSUStatus => { oid => '.1.3.6.1.4.1.5227.27.1.8.1.2', map => \%map_psu_status }, +}; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping->{nasRPSUStatus}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking redundant power supplies"); + $self->{components}->{psu} = { name => 'psu', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'psu')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{ $mapping->{nasRPSUStatus}->{oid} }})) { + $oid =~ /^$mapping->{nasRPSUStatus}->{oid}\.(.*)$/; + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{ $mapping->{nasRPSUStatus}->{oid} }, instance => $instance); + + next if ($self->check_filter(section => 'psu', instance => $instance)); + $self->{components}->{psu}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("redundant psu '%s' status is '%s' [instance: %s].", + $instance, $result->{nasRPSUStatus}, $instance + )); + my $exit = $self->get_severity(section => 'psu', value => $result->{nasRPSUStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Redundant psu '%s' status is '%s'", + $instance, $result->{nasRPSUStatus})); + } + } +} + +1; diff --git a/storage/buffalo/terastation/snmp/mode/hardware.pm b/storage/buffalo/terastation/snmp/mode/hardware.pm new file mode 100644 index 000000000..d6c53527e --- /dev/null +++ b/storage/buffalo/terastation/snmp/mode/hardware.pm @@ -0,0 +1,121 @@ +# +# Copyright 2019 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 storage::buffalo::terastation::snmp::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(disk|psu|iscsi)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + disk => [ + ['notSupport', 'WARNING'], + ['normal', 'OK'], + ['array1', 'OK'], + ['array2', 'OK'], + ['standby', 'OK'], + ['degrade', 'WARNING'], + ['remove', 'OK'], + ['standbyRemoved', 'OK'], + ['degradeRemoved', 'WARNING'], + ['removeRemoved', 'OK'], + ['array3', 'OK'], + ['array4', 'OK'], + ['mediaCartridge', 'OK'], + ['array5', 'OK'], + ['array6', 'OK'], + ], + iscsi => [ + ['unknown', 'WARNING'], + ['connected', 'OK'], + ['standing-by', 'OK'], + ], + psu => [ + ['unknown', 'WARNING'], + ['fine', 'OK'], + ['broken', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'storage::buffalo::terastation::snmp::::mode::components'; + $self->{components_module} = ['disk', 'psu', 'iscsi']; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1, no_performance => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); +} + +1; + +__END__ + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'disk', 'iscsi', 'psu'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=disk --filter=psu) +Can also exclude specific instance: --filter=psu,1 + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=item B<--threshold-overload> + +Set to overload default threshold values (syntax: section,status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='disk,OK,^(?!(degrade)$)' + +=back + +=cut diff --git a/storage/buffalo/terastation/snmp/plugin.pm b/storage/buffalo/terastation/snmp/plugin.pm new file mode 100644 index 000000000..e7f7e9125 --- /dev/null +++ b/storage/buffalo/terastation/snmp/plugin.pm @@ -0,0 +1,54 @@ +# +# Copyright 2019 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 storage::buffalo::terastation::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} = '0.1'; + %{$self->{modes}} = ( + 'array-usage' => 'storage::buffalo::terastation::snmp::mode::arrayusage', + 'cpu-detailed' => 'snmp_standard::mode::cpudetailed', + 'hardware' => 'storage::buffalo::terastation::snmp::mode::hardware', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'load' => 'snmp_standard::mode::loadaverage', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'memory' => 'snmp_standard::mode::memory', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Buffalo TeraStation in SNMP. + +=cut diff --git a/storage/dell/MD3000/cli/plugin.pm b/storage/dell/MD3000/cli/plugin.pm index aa55d079e..0aeb8614e 100644 --- a/storage/dell/MD3000/cli/plugin.pm +++ b/storage/dell/MD3000/cli/plugin.pm @@ -35,9 +35,16 @@ sub new { 'health-status' => 'centreon::common::smcli::mode::healthstatus', ); $self->{custom_modes}{smcli} = 'centreon::common::smcli::custom::custom'; - $self->{default} = { 'health-status' => { storage_command => 'show storageArray healthstatus;', - smcli_path => '/opt/dell/mdstoragemanager/client' }, }; - + $self->{default} = { + 'health-status' => { + storage_command => 'show storageArray healthstatus;', + } + }; + $self->{customdefault} = { + 'smcli' => { + smcli_path => '/opt/dell/mdstoragemanager/client', + } + }; return $self; } diff --git a/storage/dell/compellent/local/mode/volumeusage.pm b/storage/dell/compellent/local/mode/volumeusage.pm index 67c7b072f..fcf42410c 100644 --- a/storage/dell/compellent/local/mode/volumeusage.pm +++ b/storage/dell/compellent/local/mode/volumeusage.pm @@ -98,30 +98,30 @@ sub sc_init { return 0; } -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = $self->{result_values}->{type} . '_used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = $self->{result_values}->{type} . '_free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -129,12 +129,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -177,24 +177,24 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "cem-host:s" => { name => 'cem_host' }, - "cem-user:s" => { name => 'cem_user' }, - "cem-password:s" => { name => 'cem_password' }, - "cem-port:s" => { name => 'cem_port', default => 3033 }, - "sdk-path-dll:s" => { name => 'sdk_path_dll' }, - "timeout:s" => { name => 'timeout', default => 50 }, - "command:s" => { name => 'command', default => 'powershell.exe' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, - "no-ps" => { name => 'no_ps' }, - "ps-exec-only" => { name => 'ps_exec_only' }, - "ps-sc-filter:s" => { name => 'ps_sc_filter' }, - "ps-sc-volume:s" => { name => 'ps_sc_volume' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "cem-host:s" => { name => 'cem_host' }, + "cem-user:s" => { name => 'cem_user' }, + "cem-password:s" => { name => 'cem_password' }, + "cem-port:s" => { name => 'cem_port', default => 3033 }, + "sdk-path-dll:s" => { name => 'sdk_path_dll' }, + "timeout:s" => { name => 'timeout', default => 50 }, + "command:s" => { name => 'command', default => 'powershell.exe' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, + "no-ps" => { name => 'no_ps' }, + "ps-exec-only" => { name => 'ps_exec_only' }, + "ps-sc-filter:s" => { name => 'ps_sc_filter' }, + "ps-sc-volume:s" => { name => 'ps_sc_volume' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } @@ -209,9 +209,7 @@ sub check_options { $self->{output}->add_option_msg(short_msg => "Need to specify --" . $label_opt . " option."); $self->{output}->option_exit(); } - } - - $instance_mode = $self; + } } sub manage_selection { diff --git a/storage/dell/compellent/snmp/mode/components/ctrlfan.pm b/storage/dell/compellent/snmp/mode/components/ctrlfan.pm index 5ec0aff79..dd4d0213b 100644 --- a/storage/dell/compellent/snmp/mode/components/ctrlfan.pm +++ b/storage/dell/compellent/snmp/mode/components/ctrlfan.pm @@ -90,13 +90,16 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Controller fan '%s' is %s rpm", $result->{scCtlrFanName}, $result->{scCtlrFanCurrentRpm})); } - $self->{output}->perfdata_add(label => 'ctrlfan_' . $instance, unit => 'rpm', - value => $result->{scCtlrFanCurrentRpm}, - warning => $warn, - critical => $crit, - min => 0 - ); + $self->{output}->perfdata_add( + label => 'ctrlfan', unit => 'rpm', + nlabel => 'hardware.controller.fan.speed.rpm', + instances => $instance, + value => $result->{scCtlrFanCurrentRpm}, + warning => $warn, + critical => $crit, + min => 0 + ); } } -1; \ No newline at end of file +1; diff --git a/storage/dell/compellent/snmp/mode/components/ctrltemp.pm b/storage/dell/compellent/snmp/mode/components/ctrltemp.pm index da3dc2e83..da573ae08 100644 --- a/storage/dell/compellent/snmp/mode/components/ctrltemp.pm +++ b/storage/dell/compellent/snmp/mode/components/ctrltemp.pm @@ -90,12 +90,15 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Controller temperature '%s' is %s C", $result->{scCtlrTempName}, $result->{scCtlrTempCurrentC})); } - $self->{output}->perfdata_add(label => 'ctrltemp_' . $instance, unit => 'C', - value => $result->{scCtlrTempCurrentC}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'ctrltemp', unit => 'C', + nlabel => 'hardware.controller.temperature.celsius', + instances => $instance, + value => $result->{scCtlrTempCurrentC}, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1; diff --git a/storage/dell/compellent/snmp/mode/components/ctrlvoltage.pm b/storage/dell/compellent/snmp/mode/components/ctrlvoltage.pm index 3bb137eaa..769eaf54a 100644 --- a/storage/dell/compellent/snmp/mode/components/ctrlvoltage.pm +++ b/storage/dell/compellent/snmp/mode/components/ctrlvoltage.pm @@ -90,12 +90,15 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Controller voltage '%s' is %s V", $result->{scCtlrVoltageName}, $result->{scCtlrVoltageCurrentV})); } - $self->{output}->perfdata_add(label => 'ctrlvoltage_' . $instance, unit => 'V', - value => $result->{scCtlrVoltageCurrentV}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'ctrlvoltage', unit => 'V', + nlabel => 'hardware.controller.voltage.volt', + instances => $instance, + value => $result->{scCtlrVoltageCurrentV}, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1; diff --git a/storage/dell/compellent/snmp/mode/components/encltemp.pm b/storage/dell/compellent/snmp/mode/components/encltemp.pm index b528bd6c9..8239a80da 100644 --- a/storage/dell/compellent/snmp/mode/components/encltemp.pm +++ b/storage/dell/compellent/snmp/mode/components/encltemp.pm @@ -71,12 +71,15 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Enclosure temperature '%s' is %s C", $result->{scEnclTempLocation}, $result->{scEnclTempCurrentC})); } - $self->{output}->perfdata_add(label => 'encltemp_' . $instance, unit => 'C', - value => $result->{scEnclTempCurrentC}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'encltemp', unit => 'C', + nlabel => 'hardware.enclosure.temperature.celsius', + instances => $instance, + value => $result->{scEnclTempCurrentC}, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1; diff --git a/storage/dell/equallogic/snmp/mode/arraystats.pm b/storage/dell/equallogic/snmp/mode/arraystats.pm deleted file mode 100644 index 54797cfb6..000000000 --- a/storage/dell/equallogic/snmp/mode/arraystats.pm +++ /dev/null @@ -1,348 +0,0 @@ -# -# Copyright 2019 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 storage::dell::equallogic::snmp::mode::arraystats; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use centreon::plugins::values; -use centreon::plugins::statefile; - -my $maps_counters = { - '000_connections' => { set => { - key_values => [ { name => 'eqlMemberNumberOfConnections' }, { name => 'display' } ], - output_template => 'iSCSI connections : %s', - perfdatas => [ - { label => 'connections', value => 'eqlMemberNumberOfConnections_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '001_ext-connections' => { set => { - key_values => [ { name => 'eqlMemberNumberOfExtConnections' }, { name => 'display' } ], - output_template => 'External iSCSI connections : %s', - perfdatas => [ - { label => 'ext_connections', value => 'eqlMemberNumberOfExtConnections_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '002_global-read-avg-latency' => { set => { - key_values => [ { name => 'eqlMemberReadAvgLatency' }, { name => 'display' } ], - output_template => 'Global read average latency : %s ms', - perfdatas => [ - { label => 'global_read_avg_latency', value => 'eqlMemberReadAvgLatency_absolute', template => '%s', - unit => 'ms', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '003_global-write-avg-latency' => { set => { - key_values => [ { name => 'eqlMemberWriteAvgLatency' }, { name => 'display' } ], - output_template => 'Global write average latency : %s ms', - perfdatas => [ - { label => 'global_write_avg_latency', value => 'eqlMemberWriteAvgLatency_absolute', template => '%s', - unit => 'ms', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '005_read-avg-latency' => { set => { - key_values => [ { name => 'eqlMemberReadLatency', diff => 1 }, { name => 'eqlMemberReadOpCount', diff => 1 }, { name => 'display' } ], - output_template => 'Read average latency : %.2f ms', threshold_use => 'read_avg_latency', output_use => 'read_avg_latency', - closure_custom_calc => \&custom_read_avg_latency_calc, - perfdatas => [ - { label => 'read_avg_latency', value => 'read_avg_latency', template => '%.2f', - unit => 'ms', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '006_write-avg-latency' => { set => { - key_values => [ { name => 'eqlMemberWriteLatency', diff => 1 }, { name => 'eqlMemberWriteOpCount', diff => 1 }, { name => 'display' } ], - output_template => 'Write average latency : %.2f ms', threshold_use => 'write_avg_latency', output_use => 'write_avg_latency', - closure_custom_calc => \&custom_write_avg_latency_calc, - perfdatas => [ - { label => 'write_avg_latency', value => 'write_avg_latency', template => '%.2f', - unit => 'ms', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '007_read-iops' => { set => { - key_values => [ { name => 'eqlMemberReadOpCount', diff => 1 }, { name => 'display' } ], - per_second => 1, - output_template => 'Read IOPs : %.2f', - perfdatas => [ - { label => 'read_iops', template => '%.2f', value => 'eqlMemberReadOpCount_per_second', - unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '008_write-iops' => { set => { - key_values => [ { name => 'eqlMemberWriteOpCount', diff => 1 }, { name => 'display' } ], - per_second => 1, - output_template => 'Write IOPs : %.2f', - perfdatas => [ - { label => 'write_iops', template => '%.2f', value => 'eqlMemberWriteOpCount_per_second', - unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - - '010_traffic-in' => { set => { - key_values => [ { name => 'eqlMemberRxData', diff => 1 }, { name => 'display' } ], - per_second => 1, output_change_bytes => 2, - output_template => 'Traffic In : %s %s/s', - perfdatas => [ - { label => 'traffic_in', value => 'eqlMemberRxData_per_second', template => '%s', - unit => 'b/s', min => 0, cast_int => 1, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '011_traffic-out' => { set => { - key_values => [ { name => 'eqlMemberTxData', diff => 1 }, { name => 'display' } ], - per_second => 1, output_change_bytes => 2, - output_template => 'Traffic Out : %s %s/s', - perfdatas => [ - { label => 'traffic_out', value => 'eqlMemberTxData_per_second', template => '%s', - unit => 'b/s', min => 0, cast_int => 1, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, -}; - -sub custom_write_avg_latency_calc { - my ($self, %options) = @_; - - $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; - my $diff_op = $options{new_datas}->{$self->{instance} . '_eqlMemberWriteOpCount'} - $options{old_datas}->{$self->{instance} . '_eqlMemberWriteOpCount'}; - my $diff_latency = $options{new_datas}->{$self->{instance} . '_eqlMemberWriteLatency'} - $options{old_datas}->{$self->{instance} . '_eqlMemberWriteLatency'}; - if ($diff_op == 0) { - $self->{result_values}->{write_avg_latency} = 0; - } else { - $self->{result_values}->{write_avg_latency} = $diff_latency / $diff_op; - } - - return 0; -} - -sub custom_read_avg_latency_calc { - my ($self, %options) = @_; - - $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; - my $diff_op = $options{new_datas}->{$self->{instance} . '_eqlMemberReadOpCount'} - $options{old_datas}->{$self->{instance} . '_eqlMemberReadOpCount'}; - my $diff_latency = $options{new_datas}->{$self->{instance} . '_eqlMemberReadLatency'} - $options{old_datas}->{$self->{instance} . '_eqlMemberReadLatency'}; - if ($diff_op == 0) { - $self->{result_values}->{read_avg_latency} = 0; - } else { - $self->{result_values}->{read_avg_latency} = $diff_latency / $diff_op; - } - return 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 => - { - "filter-name:s" => { name => 'filter_name' }, - }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - - foreach (keys %{$maps_counters}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$_}->{threshold}) || $maps_counters->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$_}->{obj} = centreon::plugins::values->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{member_selected}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All array statistics are ok'); - } - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "dell_equallogic_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode}); - $self->{new_datas}->{last_timestamp} = time(); - - foreach my $id (sort keys %{$self->{member_selected}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => $id); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(new_datas => $self->{new_datas}, - values => $self->{member_selected}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{$_}->{obj}->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "'" . $self->{member_selected}->{$id}->{display} . "' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "'" . $self->{member_selected}->{$id}->{display} . "' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "'" . $self->{member_selected}->{$id}->{display} . "' $long_msg"); - } - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - -my $mapping = { - eqlMemberNumberOfConnections => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.1' }, - eqlMemberReadLatency => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.2' }, - eqlMemberWriteLatency => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.3' }, - eqlMemberReadAvgLatency => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.4' }, - eqlMemberWriteAvgLatency => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.5' }, - eqlMemberReadOpCount => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.6' }, - eqlMemberWriteOpCount => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.7' }, - eqlMemberTxData => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.8' }, - eqlMemberRxData => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.9' }, - eqlMemberNumberOfExtConnections => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.10' }, -}; - -sub manage_selection { - my ($self, %options) = @_; - - my $oid_eqlMemberName = '.1.3.6.1.4.1.12740.2.1.1.1.9'; - my $oid_eqlMemberConnEntry = '.1.3.6.1.4.1.12740.2.1.12.1'; - - $self->{member_selected} = {}; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_eqlMemberName }, - { oid => $oid_eqlMemberConnEntry }, - ], - nothing_quit => 1); - - foreach my $oid (keys %{$self->{results}->{$oid_eqlMemberConnEntry}}) { - next if ($oid !~ /^$mapping->{eqlMemberNumberOfConnections}->{oid}\.(\d+\.\d+)/); - my $member_instance = $1; - next if (!defined($self->{results}->{$oid_eqlMemberName}->{$oid_eqlMemberName . '.' . $member_instance})); - my $member_name = $self->{results}->{$oid_eqlMemberName}->{$oid_eqlMemberName . '.' . $member_instance}; - - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_eqlMemberConnEntry}, instance => $member_instance); - if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $member_name !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $member_name . "': no matching filter."); - next; - } - - $self->{member_selected}->{$member_name} = { display => $member_name, - %{$result} - }; - $self->{member_selected}->{$member_name}->{eqlMemberTxData} *= 8 if (defined($self->{member_selected}->{$member_name}->{eqlMemberTxData})); - $self->{member_selected}->{$member_name}->{eqlMemberRxData} *= 8 if (defined($self->{member_selected}->{$member_name}->{eqlMemberRxData})); - } - - if (scalar(keys %{$self->{member_selected}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No entry found."); - $self->{output}->option_exit(); - } -} - -1; - -__END__ - -=head1 MODE - -Check global array statistics. - -=over 8 - -=item B<--warning-*> - -Threshold warning. -Can be: 'connections', 'ext-connections', 'global-read-avg-latency' (ms), 'global-write-avg-latency' (ms), -'read-avg-latency' (ms), 'write-avg-latency' (ms), 'read-iops' (iops), 'write-iops (iops), 'traffic-in' (b/s), 'traffic-out' (b/s). - -=item B<--critical-*> - -Threshold critical. -Can be: 'connections', 'ext-connections', 'global-read-avg-latency' (ms), 'global-write-avg-latency' (ms), -'read-avg-latency' (ms), 'write-avg-latency' (ms), 'read-iops' (iops), 'write-iops (iops), 'traffic-in' (b/s), 'traffic-out' (b/s). - -=item B<--filter-name> - -Filter disk name (can be a regexp). - -=back - -=cut diff --git a/storage/dell/equallogic/snmp/mode/arrayusage.pm b/storage/dell/equallogic/snmp/mode/arrayusage.pm new file mode 100644 index 000000000..8b7a521b2 --- /dev/null +++ b/storage/dell/equallogic/snmp/mode/arrayusage.pm @@ -0,0 +1,362 @@ +# +# Copyright 2019 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 storage::dell::equallogic::snmp::mode::arrayusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub custom_write_avg_latency_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + my $diff_op = $options{new_datas}->{$self->{instance} . '_eqlMemberWriteOpCount'} - $options{old_datas}->{$self->{instance} . '_eqlMemberWriteOpCount'}; + my $diff_latency = $options{new_datas}->{$self->{instance} . '_eqlMemberWriteLatency'} - $options{old_datas}->{$self->{instance} . '_eqlMemberWriteLatency'}; + if ($diff_op == 0) { + $self->{result_values}->{write_avg_latency} = 0; + } else { + $self->{result_values}->{write_avg_latency} = $diff_latency / $diff_op; + } + + return 0; +} + +sub custom_read_avg_latency_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + my $diff_op = $options{new_datas}->{$self->{instance} . '_eqlMemberReadOpCount'} - $options{old_datas}->{$self->{instance} . '_eqlMemberReadOpCount'}; + my $diff_latency = $options{new_datas}->{$self->{instance} . '_eqlMemberReadLatency'} - $options{old_datas}->{$self->{instance} . '_eqlMemberReadLatency'}; + if ($diff_op == 0) { + $self->{result_values}->{read_avg_latency} = 0; + } else { + $self->{result_values}->{read_avg_latency} = $diff_latency / $diff_op; + } + return 0; +} + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + + my $msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_eqlMemberTotalStorage'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_eqlMemberUsedStorage'}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'array', type => 1, cb_prefix_output => 'prefix_array_output', message_multiple => 'All array usages are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{array} = [ + { label => 'used', set => { + key_values => [ { name => 'display' }, { name => 'eqlMemberTotalStorage' }, { name => 'eqlMemberUsedStorage' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + { label => 'snapshot', set => { + key_values => [ { name => 'eqlMemberSnapStorage' }, { name => 'display' } ], + output_change_bytes => 1, + output_template => 'Snapshot usage : %s %s', + perfdatas => [ + { label => 'snapshost', value => 'eqlMemberSnapStorage_absolute', template => '%s', + unit => 'B', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'replication', set => { + key_values => [ { name => 'eqlMemberReplStorage' }, { name => 'display' } ], + output_change_bytes => 1, + output_template => 'Replication usage : %s %s', + perfdatas => [ + { label => 'replication', value => 'eqlMemberReplStorage_absolute', template => '%s', + unit => 'B', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'connections', set => { + key_values => [ { name => 'eqlMemberNumberOfConnections' }, { name => 'display' } ], + output_template => 'iSCSI connections : %s', + perfdatas => [ + { label => 'connections', value => 'eqlMemberNumberOfConnections_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'ext-connections', display_ok => 0, set => { + key_values => [ { name => 'eqlMemberNumberOfExtConnections' }, { name => 'display' } ], + output_template => 'External iSCSI connections : %s', + perfdatas => [ + { label => 'ext_connections', value => 'eqlMemberNumberOfExtConnections_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'global-read-avg-latency', display_ok => 0, set => { + key_values => [ { name => 'eqlMemberReadAvgLatency' }, { name => 'display' } ], + output_template => 'Global read average latency : %s ms', + perfdatas => [ + { label => 'global_read_avg_latency', value => 'eqlMemberReadAvgLatency_absolute', template => '%s', + unit => 'ms', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'global-write-avg-latency', display_ok => 0, set => { + key_values => [ { name => 'eqlMemberWriteAvgLatency' }, { name => 'display' } ], + output_template => 'Global write average latency : %s ms', + perfdatas => [ + { label => 'global_write_avg_latency', value => 'eqlMemberWriteAvgLatency_absolute', template => '%s', + unit => 'ms', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'read-avg-latency', set => { + key_values => [ { name => 'eqlMemberReadLatency', diff => 1 }, { name => 'eqlMemberReadOpCount', diff => 1 }, { name => 'display' } ], + output_template => 'Read average latency : %.2f ms', threshold_use => 'read_avg_latency', output_use => 'read_avg_latency', + closure_custom_calc => $self->can('custom_read_avg_latency_calc'), + perfdatas => [ + { label => 'read_avg_latency', value => 'read_avg_latency', template => '%.2f', + unit => 'ms', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-avg-latency', display_ok => 0, set => { + key_values => [ { name => 'eqlMemberWriteLatency', diff => 1 }, { name => 'eqlMemberWriteOpCount', diff => 1 }, { name => 'display' } ], + output_template => 'Write average latency : %.2f ms', threshold_use => 'write_avg_latency', output_use => 'write_avg_latency', + closure_custom_calc => $self->can('custom_write_avg_latency_calc'), + perfdatas => [ + { label => 'write_avg_latency', value => 'write_avg_latency', template => '%.2f', + unit => 'ms', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'read-iops', set => { + key_values => [ { name => 'eqlMemberReadOpCount', diff => 1 }, { name => 'display' } ], + per_second => 1, + output_template => 'Read IOPs : %.2f', + perfdatas => [ + { label => 'read_iops', template => '%.2f', value => 'eqlMemberReadOpCount_per_second', + unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-iops', set => { + key_values => [ { name => 'eqlMemberWriteOpCount', diff => 1 }, { name => 'display' } ], + per_second => 1, + output_template => 'Write IOPs : %.2f', + perfdatas => [ + { label => 'write_iops', template => '%.2f', value => 'eqlMemberWriteOpCount_per_second', + unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-in', display_ok => 0, set => { + key_values => [ { name => 'eqlMemberRxData', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic In : %s %s/s', + perfdatas => [ + { label => 'traffic_in', value => 'eqlMemberRxData_per_second', template => '%s', + unit => 'b/s', min => 0, cast_int => 1, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-out', display_ok => 0, set => { + key_values => [ { name => 'eqlMemberTxData', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic Out : %s %s/s', + perfdatas => [ + { label => 'traffic_out', value => 'eqlMemberTxData_per_second', template => '%s', + unit => 'b/s', min => 0, cast_int => 1, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_array_output { + my ($self, %options) = @_; + + return "Array '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +my $mapping = { + eqlMemberTotalStorage => { oid => '.1.3.6.1.4.1.12740.2.1.10.1.1' }, # MB + eqlMemberUsedStorage => { oid => '.1.3.6.1.4.1.12740.2.1.10.1.2' }, # MB + eqlMemberSnapStorage => { oid => '.1.3.6.1.4.1.12740.2.1.10.1.3' }, # MB + eqlMemberReplStorage => { oid => '.1.3.6.1.4.1.12740.2.1.10.1.4' }, # MB + + eqlMemberNumberOfConnections => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.1' }, + eqlMemberReadLatency => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.2' }, + eqlMemberWriteLatency => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.3' }, + eqlMemberReadAvgLatency => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.4' }, + eqlMemberWriteAvgLatency => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.5' }, + eqlMemberReadOpCount => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.6' }, + eqlMemberWriteOpCount => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.7' }, + eqlMemberTxData => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.8' }, + eqlMemberRxData => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.9' }, + eqlMemberNumberOfExtConnections => { oid => '.1.3.6.1.4.1.12740.2.1.12.1.10' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + if ($options{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); + $self->{output}->option_exit(); + } + + my $oid_eqlMemberName = '.1.3.6.1.4.1.12740.2.1.1.1.9'; + + $self->{array} = {}; + my $snmp_result = $options{snmp}->get_table(oid => $oid_eqlMemberName, nothing_quit => 1); + foreach my $oid (keys %{$snmp_result}) { + $oid =~ /^$oid_eqlMemberName\.(.*)$/; + my $instance = $1; + my $name = $snmp_result->{$oid_eqlMemberName . '.' . $instance}; + + 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 array '" . $name . "'.", debug => 1); + next; + } + + $self->{array}->{$instance} = { display => $name }; + } + + if (scalar(keys %{$self->{array}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No entry found."); + $self->{output}->option_exit(); + } + + $options{snmp}->load(oids => [ + map($_->{oid}, values(%$mapping)) + ], + instances => [keys %{$self->{array}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{array}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + + $result->{eqlMemberTxData} *= 8 if (defined($result->{eqlMemberTxData})); + $result->{eqlMemberRxData} *= 8 if (defined($result->{eqlMemberRxData})); + + $result->{eqlMemberTotalStorage} *= 1024 * 1024; + $result->{eqlMemberUsedStorage} *= 1024 * 1024; + $result->{eqlMemberSnapStorage} *= 1024 * 1024; + $result->{eqlMemberReplStorage} *= 1024 * 1024; + + $self->{array}->{$_} = { %{$self->{array}->{$_}}, %$result }; + } + + $self->{cache_name} = "dell_equallogic_" . $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')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check array member usage. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'used' (%), 'snapshot' (B), 'replication' (B), +'connections', 'ext-connections', 'global-read-avg-latency' (ms), 'global-write-avg-latency' (ms), +'read-avg-latency' (ms), 'write-avg-latency' (ms), 'read-iops' (iops), 'write-iops (iops), 'traffic-in' (b/s), 'traffic-out' (b/s). + +=item B<--critical-*> + +Threshold critical. +Can be: 'used' (%), 'snapshot' (B), 'replication' (B), +'connections', 'ext-connections', 'global-read-avg-latency' (ms), 'global-write-avg-latency' (ms), +'read-avg-latency' (ms), 'write-avg-latency' (ms), 'read-iops' (iops), 'write-iops (iops), 'traffic-in' (b/s), 'traffic-out' (b/s). + +=item B<--filter-name> + +Filter array name (can be a regexp). + +=back + +=cut diff --git a/storage/dell/equallogic/snmp/mode/components/fan.pm b/storage/dell/equallogic/snmp/mode/components/fan.pm index 89c284ad5..cc7b8a818 100644 --- a/storage/dell/equallogic/snmp/mode/components/fan.pm +++ b/storage/dell/equallogic/snmp/mode/components/fan.pm @@ -89,13 +89,17 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Fan '%s/%s' speed is %s rpm", $member_name, $result->{eqlMemberHealthDetailsFanName}, $result->{eqlMemberHealthDetailsFanValue})); } - $self->{output}->perfdata_add(label => "fan_" . $member_name . "_" . $instance, unit => 'rpm', - value => $result->{eqlMemberHealthDetailsFanValue}, - warning => $warn, - critical => $crit, - min => 0); + $self->{output}->perfdata_add( + label => "fan", unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => [$member_name, $instance], + value => $result->{eqlMemberHealthDetailsFanValue}, + warning => $warn, + critical => $crit, + min => 0 + ); } } } -1; \ No newline at end of file +1; diff --git a/storage/dell/equallogic/snmp/mode/components/temperature.pm b/storage/dell/equallogic/snmp/mode/components/temperature.pm index 8cca1c9d2..6169ccdbd 100644 --- a/storage/dell/equallogic/snmp/mode/components/temperature.pm +++ b/storage/dell/equallogic/snmp/mode/components/temperature.pm @@ -89,12 +89,16 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Temperature '%s/%s' is %s degree centigrade", $member_name, $result->{eqlMemberHealthDetailsTemperatureName}, $result->{eqlMemberHealthDetailsTemperatureValue})); } - $self->{output}->perfdata_add(label => "temp_" . $member_name . "_" . $instance, unit => 'C', - value => $result->{eqlMemberHealthDetailsTemperatureValue}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "temp", unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => [$member_name, $instance], + value => $result->{eqlMemberHealthDetailsTemperatureValue}, + warning => $warn, + critical => $crit + ); } } } -1; \ No newline at end of file +1; diff --git a/storage/dell/equallogic/snmp/mode/diskusage.pm b/storage/dell/equallogic/snmp/mode/diskusage.pm index 6b1aa6544..224eeab98 100644 --- a/storage/dell/equallogic/snmp/mode/diskusage.pm +++ b/storage/dell/equallogic/snmp/mode/diskusage.pm @@ -20,231 +20,178 @@ package storage::dell::equallogic::snmp::mode::diskusage; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use Digest::MD5 qw(md5_hex); -my $maps_counters = { - '000_used' => { set => { - key_values => [ { name => 'display' }, { name => 'total' }, { name => 'used' } ], - closure_custom_calc => \&custom_usage_calc, - closure_custom_output => \&custom_usage_output, - closure_custom_perfdata => \&custom_usage_perfdata, - closure_custom_threshold_check => \&custom_usage_threshold, - } - }, - '001_snapshot' => { set => { - key_values => [ { name => 'snap' }, { name => 'display' } ], - output_change_bytes => 1, - output_template => 'Snapshot usage : %s %s', - perfdatas => [ - { label => 'snapshost', value => 'snap_absolute', template => '%s', - unit => 'B', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '002_replication' => { set => { - key_values => [ { name => 'repl' }, { name => 'display' } ], - output_change_bytes => 1, - output_template => 'Replication usage : %s %s', - perfdatas => [ - { label => 'replication', value => 'repl_absolute', template => '%s', - unit => 'B', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, -}; - -sub custom_usage_perfdata { +sub custom_status_output { my ($self, %options) = @_; - - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); -} -sub custom_usage_threshold { - my ($self, %options) = @_; - - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); - return $exit; -} - -sub custom_usage_output { - my ($self, %options) = @_; - - my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); - my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); - my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); - - my $msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", - $total_size_value . " " . $total_size_unit, - $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, - $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + my $msg = 'status : ' . $self->{result_values}->{status} . ' [smart health: ' . $self->{result_values}->{health} . ']'; return $msg; } -sub custom_usage_calc { +sub custom_status_calc { my ($self, %options) = @_; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_eqlDiskStatus'}; + $self->{result_values}->{health} = $options{new_datas}->{$self->{instance} . '_eqlDiskHealth'}; $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; - $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; - $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; - $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; - $self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total}; - $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'disk', type => 1, cb_prefix_output => 'prefix_disk_output', message_multiple => 'All disk usages are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{disk} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'eqlDiskHealth' }, { name => 'eqlDiskStatus' }, { 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 => \&catalog_status_threshold, + } + }, + { label => 'read', set => { + key_values => [ { name => 'eqlDiskStatusBytesRead', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 1, + output_template => 'read : %s %s/s', + perfdatas => [ + { label => 'read_iops', template => '%.2f', value => 'eqlDiskStatusBytesRead_per_second', + unit => 'B/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write', set => { + key_values => [ { name => 'eqlDiskStatusBytesWritten', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 1, + output_template => 'write : %s %s/s', + perfdatas => [ + { label => 'write', template => '%.2f', value => 'eqlDiskStatusBytesWritten_per_second', + unit => 'B/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'busy-time', set => { + key_values => [ { name => 'eqlDiskStatusBusyTime', diff => 1 }, { name => 'display' } ], + output_template => 'time busy : %s sec', + perfdatas => [ + { label => 'busy_time', template => '%s', value => 'eqlDiskStatusBusyTime_absolute', + unit => 's', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_disk_output { + my ($self, %options) = @_; + + return "Disk '" . $options{instance_value}->{display} . "' "; +} + sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; - + $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - }); - - foreach (keys %{$maps_counters}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$_}->{threshold}) || $maps_counters->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /on-line|spare|off-line/i' }, + }); + return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status', 'unknown_status']); } -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; +my $map_disk_status = { + 1 => 'on-line', 2 => 'spare', 3 => 'failed', 4 => 'off-line', + 5 => 'alt-sig', 6 => 'too-small', 7 => 'history-of-failures', + 8 => 'unsupported-version', 9 => 'unhealthy', 10 => 'replacement', + 11 => 'encrypted', 12 => 'notApproved', 13 => 'preempt-failed', +}; - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{member_selected}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All disk usages are ok'); - } - - foreach my $id (sort keys %{$self->{member_selected}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => $id); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{member_selected}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{$_}->{obj}->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Disk '" . $self->{member_selected}->{$id}->{display} . "' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Disk '" . $self->{member_selected}->{$id}->{display} . "' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Disk '" . $self->{member_selected}->{$id}->{display} . "' $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} +my $map_disk_health = { + 0 => 'smart-status-not-available', + 1 => 'smart-ok', + 2 => 'smart-tripped', +}; my $mapping = { - eqlMemberTotalStorage => { oid => '.1.3.6.1.4.1.12740.2.1.10.1.1' }, # MB - eqlMemberUsedStorage => { oid => '.1.3.6.1.4.1.12740.2.1.10.1.2' }, # MB - eqlMemberSnapStorage => { oid => '.1.3.6.1.4.1.12740.2.1.10.1.3' }, # MB - eqlMemberReplStorage => { oid => '.1.3.6.1.4.1.12740.2.1.10.1.4' }, # MB + eqlDiskHealth => { oid => '.1.3.6.1.4.1.12740.3.1.1.1.17', map => $map_disk_health }, + eqlDiskStatusBytesRead => { oid => '.1.3.6.1.4.1.12740.3.1.2.1.2' }, # MB + eqlDiskStatusBytesWritten => { oid => '.1.3.6.1.4.1.12740.3.1.2.1.3' }, # MB + eqlDiskStatusBusyTime => { oid => '.1.3.6.1.4.1.12740.3.1.2.1.4' }, # in seconds }; sub manage_selection { my ($self, %options) = @_; - - my $oid_eqlMemberName = '.1.3.6.1.4.1.12740.2.1.1.1.9'; - my $oid_eqlMemberStorageEntry = '.1.3.6.1.4.1.12740.2.1.10.1'; - $self->{member_selected} = {}; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_eqlMemberName }, - { oid => $oid_eqlMemberStorageEntry }, - ], - nothing_quit => 1); - foreach my $oid (keys %{$self->{results}->{$oid_eqlMemberStorageEntry}}) { - next if ($oid !~ /^$mapping->{eqlMemberTotalStorage}->{oid}\.(\d+\.\d+)/); - my $member_instance = $1; - next if (!defined($self->{results}->{$oid_eqlMemberName}->{$oid_eqlMemberName . '.' . $member_instance})); - my $member_name = $self->{results}->{$oid_eqlMemberName}->{$oid_eqlMemberName . '.' . $member_instance}; - - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_eqlMemberStorageEntry}, instance => $member_instance); - if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $member_name !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $member_name . "': no matching filter."); - next; - } - - $self->{member_selected}->{$member_name} = { display => $member_name, - total => $result->{eqlMemberTotalStorage} * 1024 * 1024, - used => $result->{eqlMemberUsedStorage} * 1024 * 1024, - snap => $result->{eqlMemberSnapStorage} * 1024 * 1024, - repl => $result->{eqlMemberReplStorage} * 1024 * 1024 - }; + if ($options{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); + $self->{output}->option_exit(); } - if (scalar(keys %{$self->{member_selected}}) <= 0) { + my $oid_eqlMemberName = '.1.3.6.1.4.1.12740.2.1.1.1.9'; + my $oid_eqlDiskStatus = '.1.3.6.1.4.1.12740.3.1.1.1.8'; + + $self->{disk} = {}; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [{ oid => $oid_eqlMemberName }, { oid => $oid_eqlDiskStatus }], return_type => 1, nothing_quit => 1); + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$oid_eqlDiskStatus\.(\d+)\.(\d+)\.(\d+)$/); + my $instance = $1 . '.' . $2 . '.' . $3; + my $array_name = $snmp_result->{$oid_eqlMemberName . '.' . $1 . '.' . $2}; + my $name = $array_name . '.' . $3; + + 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 disk '" . $name . "'.", debug => 1); + next; + } + + $self->{disk}->{$instance} = { display => $name, eqlDiskStatus => $map_disk_status->{$snmp_result->{$oid}} }; + } + + if (scalar(keys %{$self->{disk}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No entry found."); $self->{output}->option_exit(); } + + $options{snmp}->load(oids => [ + map($_->{oid}, values(%$mapping)) + ], + instances => [keys %{$self->{disk}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{disk}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + + $result->{eqlDiskStatusBytesRead} *= 1024 * 1024; + $result->{eqlDiskStatusBytesWritten} *= 1024 * 1024; + $result->{eqlDiskHealth} = 'n/a' if (!defined($result->{eqlDiskHealth})); + + $self->{disk}->{$_} = { %{$self->{disk}->{$_}}, %$result }; + } + + $self->{cache_name} = "dell_equallogic_" . $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')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); } 1; @@ -253,24 +200,39 @@ __END__ =head1 MODE -Check disk usages. +Check disk usage. =over 8 -=item B<--warning-*> - -Threshold warning. -Can be: 'used' (%), 'snapshot' (B), 'replication' (B). - -=item B<--critical-*> - -Threshold critical. -Can be: 'used' (%), 'snapshot' (B), 'replication' (B). - =item B<--filter-name> Filter disk name (can be a regexp). +=item B<--unknown-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{health}, %{status}, %{display} + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{health}, %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /on-line|spare|off-line/i'). +Can used special variables like: %{health}, %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'busy-time' (s), 'read-iops' (iops), 'write-iops (iops). + +=item B<--critical-*> + +Threshold critical. +Can be: 'busy-time' (s), 'read-iops' (iops), 'write-iops (iops). + =back =cut diff --git a/storage/dell/equallogic/snmp/mode/poolusage.pm b/storage/dell/equallogic/snmp/mode/poolusage.pm index 7dd00403d..9274305f8 100644 --- a/storage/dell/equallogic/snmp/mode/poolusage.pm +++ b/storage/dell/equallogic/snmp/mode/poolusage.pm @@ -20,41 +20,28 @@ package storage::dell::equallogic::snmp::mode::poolusage; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; - -my $maps_counters = { - '000_used' => { set => { - key_values => [ { name => 'display' }, { name => 'total' }, { name => 'used' } ], - closure_custom_calc => \&custom_usage_calc, - closure_custom_output => \&custom_usage_output, - closure_custom_perfdata => \&custom_usage_perfdata, - closure_custom_threshold_check => \&custom_usage_threshold, - } - }, -}; sub custom_usage_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -84,153 +71,97 @@ sub custom_usage_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'pool', type => 1, cb_prefix_output => 'prefix_pool_output', message_multiple => 'All Pool usages are ok' } + ]; + + $self->{maps_counters}->{pool} = [ + { label => 'used', set => { + key_values => [ { name => 'display' }, { name => 'total' }, { name => 'used' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +sub prefix_pool_output { + my ($self, %options) = @_; + + return "Pool '" . $options{instance_value}->{display} . "' "; +} + 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' }, - }); - - foreach (keys %{$maps_counters}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$_}->{threshold}) || $maps_counters->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{pool_selected}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All Pool usages are ok'); - } - - foreach my $id (sort keys %{$self->{pool_selected}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => $id); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{pool_selected}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{$_}->{obj}->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Pool '" . $self->{pool_selected}->{$id}->{display} . "' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Pool '" . $self->{pool_selected}->{$id}->{display} . "' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Pool '" . $self->{pool_selected}->{$id}->{display} . "' $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} - my $mapping = { - eqlStoragePoolStatsSpace => { oid => '.1.3.6.1.4.1.12740.16.1.2.1.1' }, # MB + eqlStoragePoolStatsSpace => { oid => '.1.3.6.1.4.1.12740.16.1.2.1.1' }, # MB eqlStoragePoolStatsSpaceUsed => { oid => '.1.3.6.1.4.1.12740.16.1.2.1.2' }, # MB }; sub manage_selection { my ($self, %options) = @_; - - my $oid_eqlStoragePoolName = '.1.3.6.1.4.1.12740.16.1.1.1.3'; - my $oid_eqlStoragePoolStatsEntry = '.1.3.6.1.4.1.12740.16.1.2.1'; - if ($self->{snmp}->is_snmpv1()) { + if ($options{snmp}->is_snmpv1()) { $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); $self->{output}->option_exit(); } - $self->{pool_selected} = {}; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_eqlStoragePoolName }, - { oid => $oid_eqlStoragePoolStatsEntry, start => $mapping->{eqlStoragePoolStatsSpace}->{oid}, end => $mapping->{eqlStoragePoolStatsSpaceUsed}->{oid}}, - ], - nothing_quit => 1); + my $oid_eqlStoragePoolName = '.1.3.6.1.4.1.12740.16.1.1.1.3'; - foreach my $oid (keys %{$self->{results}->{$oid_eqlStoragePoolStatsEntry}}) { - next if ($oid !~ /^$mapping->{eqlStoragePoolStatsSpace}->{oid}\.(\d+\.\d+)/); - my $pool_instance = $1; - next if (!defined($self->{results}->{$oid_eqlStoragePoolName}->{$oid_eqlStoragePoolName . '.' . $pool_instance})); - my $pool_name = $self->{results}->{$oid_eqlStoragePoolName}->{$oid_eqlStoragePoolName . '.' . $pool_instance}; - - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_eqlStoragePoolStatsEntry}, instance => $pool_instance); + $self->{pool} = {}; + my $snmp_result = $options{snmp}->get_table(oid => $oid_eqlStoragePoolName, nothing_quit => 1); + foreach my $oid (keys %{$snmp_result}) { + $oid =~ /^$oid_eqlStoragePoolName\.(.*)$/; + my $instance = $1; + my $name = $snmp_result->{$oid_eqlStoragePoolName . '.' . $instance}; + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $pool_name !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $pool_name . "': no matching filter."); + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping pool '" . $name . "'.", debug => 1); next; } - if ($result->{eqlStoragePoolStatsSpace} == 0) { - $self->{output}->output_add(long_msg => "Skipping '" . $pool_name . "': total size is 0."); - next; - } - - $self->{pool_selected}->{$pool_name} = { display => $pool_name, - total => $result->{eqlStoragePoolStatsSpace} * 1024 * 1024, - used => $result->{eqlStoragePoolStatsSpaceUsed} * 1024 * 1024, - }; + + $self->{pool}->{$instance} = { display => $name }; } - - if (scalar(keys %{$self->{pool_selected}}) <= 0) { + + if (scalar(keys %{$self->{pool}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No entry found."); $self->{output}->option_exit(); } + + $options{snmp}->load(oids => [ + $mapping->{eqlStoragePoolStatsSpace}->{oid}, $mapping->{eqlStoragePoolStatsSpaceUsed}->{oid}, + ], + instances => [keys %{$self->{pool}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{pool}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + + if ($result->{eqlStoragePoolStatsSpace} == 0) { + $self->{output}->output_add(long_msg => "skipping pool '" . $_ . "'. Total size is 0", debug => 1); + next; + } + + $self->{pool}->{$_}->{total} = $result->{eqlStoragePoolStatsSpace} * 1024 * 1024; + $self->{pool}->{$_}->{used} = $result->{eqlStoragePoolStatsSpaceUsed} * 1024 * 1024; + } } 1; diff --git a/storage/dell/equallogic/snmp/plugin.pm b/storage/dell/equallogic/snmp/plugin.pm index 56a413f21..adc1e2fea 100644 --- a/storage/dell/equallogic/snmp/plugin.pm +++ b/storage/dell/equallogic/snmp/plugin.pm @@ -31,13 +31,13 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'array-stats' => 'storage::dell::equallogic::snmp::mode::arraystats', - 'disk-usage' => 'storage::dell::equallogic::snmp::mode::diskusage', - 'hardware' => 'storage::dell::equallogic::snmp::mode::hardware', - 'interfaces' => 'snmp_standard::mode::interfaces', - 'list-interfaces' => 'snmp_standard::mode::listinterfaces', - 'pool-usage' => 'storage::dell::equallogic::snmp::mode::poolusage', - ); + 'array-usage' => 'storage::dell::equallogic::snmp::mode::arrayusage', + 'disk-usage' => 'storage::dell::equallogic::snmp::mode::diskusage', + 'hardware' => 'storage::dell::equallogic::snmp::mode::hardware', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'pool-usage' => 'storage::dell::equallogic::snmp::mode::poolusage', + ); return $self; } diff --git a/storage/dell/fluidfs/snmp/mode/volumeusage.pm b/storage/dell/fluidfs/snmp/mode/volumeusage.pm index 1ec933150..c3c1d885f 100644 --- a/storage/dell/fluidfs/snmp/mode/volumeusage.pm +++ b/storage/dell/fluidfs/snmp/mode/volumeusage.pm @@ -25,30 +25,30 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -56,12 +56,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -117,23 +117,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub prefix_volume_output { my ($self, %options) = @_; diff --git a/storage/dell/me4/custom/api.pm b/storage/dell/me4/custom/api.pm new file mode 100644 index 000000000..2b0df6e5b --- /dev/null +++ b/storage/dell/me4/custom/api.pm @@ -0,0 +1,270 @@ +# +# Copyright 2019 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 storage::dell::me4::custom::api; + +use strict; +use warnings; +use DateTime; +use centreon::plugins::http; +use centreon::plugins::statefile; +use JSON::XS; +use URI::Encode; +use Digest::MD5 qw(md5_hex); + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + "api-username:s" => { name => 'api_username' }, + "api-password:s" => { name => 'api_password' }, + "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port' }, + "proto:s" => { name => 'proto' }, + "timeout:s" => { name => 'timeout' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{http} = centreon::plugins::http->new(%options); + $self->{cache} = centreon::plugins::statefile->new(%options); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : ''; + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 443; + $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'https'; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; + $self->{api_username} = (defined($self->{option_results}->{api_username})) ? $self->{option_results}->{api_username} : ''; + $self->{api_password} = (defined($self->{option_results}->{api_password})) ? $self->{option_results}->{api_password} : ''; + + if (!defined($self->{hostname}) || $self->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --hostname option."); + $self->{output}->option_exit(); + } + if (!defined($self->{api_username}) || $self->{api_username} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --api-username option."); + $self->{output}->option_exit(); + } + if (!defined($self->{api_password}) || $self->{api_password} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --api-password option."); + $self->{output}->option_exit(); + } + + $self->{cache}->check_options(option_results => $self->{option_results}); + + return 0; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{warning_status} = ''; + $self->{option_results}->{critical_status} = ''; + $self->{option_results}->{unknown_status} = '%{http_code} < 200 or %{http_code} > 400'; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->add_header(key => 'Accept', value => 'application/json'); + $self->{http}->add_header(key => 'datatype', value => 'json'); + if (defined($self->{session_key})) { + $self->{http}->add_header(key => 'sessionKey', value => $self->{session_key}); + } + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub get_hostname { + my ($self, %options) = @_; + + return $self->{hostname}; +} + +sub get_session_key { + my ($self, %options) = @_; + + my $has_cache_file = $options{statefile}->read(statefile => 'dell_me4_api_' . md5_hex($self->{hostname}) . '_' . md5_hex($self->{api_username})); + my $expires_on = $options{statefile}->get(name => 'expires_on'); + my $session_key = $options{statefile}->get(name => 'session_key'); + + if ($has_cache_file == 0 || !defined($session_key) || (($expires_on - time()) < 10)) { + my $digest_data = $self->{api_username} . '_' . $self->{api_password}; + my $digest_hash = md5_hex($digest_data); + + $self->settings(); + + my $content = $self->{http}->request( + method => 'GET', + url_path => '/api/login/' . $digest_hash + ); + + if (!defined($content) || $content eq '') { + $self->{output}->add_option_msg(short_msg => "Login endpoint returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->output_add(long_msg => $content, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + if ($decoded->{status}[0]->{'response-type'} ne 'Success') { + $self->{output}->add_option_msg(short_msg => "Login endpoint returns an error: '" . $decoded->{status}[0]->{response} . "'"); + $self->{output}->option_exit(); + } + + $session_key = $decoded->{status}[0]->{response}; + my $datas = { last_timestamp => time(), session_key => $decoded->{status}[0]->{response}, expires_on => 3600 }; + $options{statefile}->write(data => $datas); + } + + return $session_key; +} + +sub request_api { + my ($self, %options) = @_; + + if (!defined($self->{session_key})) { + $self->{session_key} = $self->get_session_key(statefile => $self->{cache}); + } + + $self->settings(); + + my $lang = $self->{http}->request(method => 'GET', url_path => '/api/set/cli-parameters/locale/English'); + + $self->{output}->output_add(long_msg => "URL: '" . $self->{proto} . '://' . $self->{hostname} . ':' . $self->{port} . + $options{url_path} . "'", debug => 1); + + my $content = $self->{http}->request(%options); + + if (!defined($content) || $content eq '') { + $self->{output}->add_option_msg(short_msg => "API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']"); + $self->{output}->option_exit(); + } + + my $decoded; + eval { + $decoded = JSON::XS->new->utf8->decode($content); + }; + if ($@) { + $self->{output}->output_add(long_msg => $content, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)"); + $self->{output}->option_exit(); + } + + return $decoded; +} + +1; + +__END__ + +=head1 NAME + +Dell ME4 Rest API + +=head1 REST API OPTIONS + +Dell ME4 Rest API + +=over 8 + +=item B<--hostname> + +Dell ME4 hostname. + +=item B<--port> + +Port used (Default: 443) + +=item B<--proto> + +Specify https if needed (Default: 'https') + +=item B<--api-username> + +Dell ME4 API username. + +=item B<--api-password> + +Dell ME4 API password. + +=item B<--timeout> + +Set timeout in seconds (Default: 10). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/storage/dell/me4/mode/components/controller.pm b/storage/dell/me4/mode/components/controller.pm new file mode 100644 index 000000000..c0727a830 --- /dev/null +++ b/storage/dell/me4/mode/components/controller.pm @@ -0,0 +1,68 @@ +# +# Copyright 2019 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 storage::dell::me4::mode::components::controller; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{json_results}->{controllers} = $self->{custom}->request_api(method => 'GET', url_path => '/api/show/controllers'); +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking controllers"); + $self->{components}->{controller} = {name => 'controllers', total => 0, skip => 0}; + return if ($self->check_filter(section => 'controller')); + return if (!defined($self->{json_results}->{controllers})); + + foreach my $result (@{$self->{json_results}->{controllers}->{controllers}}) { + my $instance = $result->{'durable-id'}; + + next if ($self->check_filter(section => 'controller', instance => $instance)); + + $self->{components}->{controller}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Controller '%s' status is '%s', health is '%s', redundancy status is '%s'", + $result->{'durable-id'}, $result->{status}, $result->{health}, $result->{'redundancy-status'})); + + my $exit1 = $self->get_severity(section => 'controller', value => $result->{status}); + if (!$self->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit1, + short_msg => sprintf("Controller '%s' status is '%s'", $result->{'durable-id'}, $result->{status})); + } + my $exit2 = $self->get_severity(section => 'controller', value => $result->{health}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Controller '%s' health is '%s'", $result->{'durable-id'}, $result->{health})); + } + my $exit3 = $self->get_severity(section => 'controller', value => $result->{health}); + if (!$self->{output}->is_status(value => $exit3, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit3, + short_msg => sprintf("Controller '%s' redundancy status is '%s'", $result->{'redundancy-status'}, $result->{health})); + } + } +} + +1; diff --git a/storage/dell/me4/mode/components/disk.pm b/storage/dell/me4/mode/components/disk.pm new file mode 100644 index 000000000..be7faf39a --- /dev/null +++ b/storage/dell/me4/mode/components/disk.pm @@ -0,0 +1,85 @@ +# +# Copyright 2019 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 storage::dell::me4::mode::components::disk; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{json_results}->{disks} = $self->{custom}->request_api(method => 'GET', url_path => '/api/show/disks'); +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking disks"); + $self->{components}->{disk} = {name => 'disks', total => 0, skip => 0}; + return if ($self->check_filter(section => 'disk')); + return if (!defined($self->{json_results}->{disks})); + + foreach my $result (@{$self->{json_results}->{disks}->{drives}}) { + my $instance = $result->{'durable-id'}; + + next if ($self->check_filter(section => 'disk', instance => $instance)); + + $self->{components}->{disk}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Disk '%s' status is '%s', health is '%s', state is '%s' [instance = %s] [temperature = %s C]", + $result->{'serial-number'}, $result->{status}, $result->{health}, $result->{state}, $instance, + $result->{'temperature-numeric'})); + + my $exit1 = $self->get_severity(section => 'disk', value => $result->{status}); + if (!$self->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit1, + short_msg => sprintf("Disk '%s' status is '%s'", $result->{'serial-number'}, $result->{status})); + } + my $exit2 = $self->get_severity(section => 'disk', value => $result->{health}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Disk '%s' health is '%s'", $result->{'serial-number'}, $result->{health})); + } + my $exit3 = $self->get_severity(section => 'disk', value => $result->{state}); + if (!$self->{output}->is_status(value => $exit3, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit3, + short_msg => sprintf("Disk '%s' state is '%s'", $result->{'serial-number'}, $result->{state})); + } + + next if ($result->{'temperature-numeric'} !~ /[0-9]/); + my ($exit4, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'disk', instance => $instance, value => $result->{'temperature-numeric'}); + if (!$self->{output}->is_status(value => $exit4, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit4, + short_msg => sprintf("Disk '%s' temperature is %s C", $result->{'serial-number'}, $result->{'temperature-numeric'})); + } + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.disk.temperature.celsius', + instances => $instance, + value => $result->{'temperature-numeric'}, + warning => $warn, + critical => $crit, + min => 0 + ); + } +} + +1; diff --git a/storage/dell/me4/mode/components/fan.pm b/storage/dell/me4/mode/components/fan.pm new file mode 100644 index 000000000..81e915a71 --- /dev/null +++ b/storage/dell/me4/mode/components/fan.pm @@ -0,0 +1,80 @@ +# +# Copyright 2019 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 storage::dell::me4::mode::components::fan; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{json_results}->{fans} = $self->{custom}->request_api(method => 'GET', url_path => '/api/show/fans'); +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fans"); + $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; + return if ($self->check_filter(section => 'fan')); + return if (!defined($self->{json_results}->{fans})); + + foreach my $result (@{$self->{json_results}->{fans}->{fan}}) { + my $instance = $result->{'durable-id'}; + + next if ($self->check_filter(section => 'fan', instance => $instance)); + + $self->{components}->{fan}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Fan '%s' status is '%s', health is '%s' [instance = %s] [speed = %s rpm]", + $result->{name}, $result->{status}, $result->{health}, $instance, + $result->{speed})); + + my $exit1 = $self->get_severity(section => 'fan', value => $result->{status}); + if (!$self->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit1, + short_msg => sprintf("Fan '%s' status is '%s'", $result->{name}, $result->{status})); + } + my $exit2 = $self->get_severity(section => 'fan', value => $result->{health}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Fan '%s' health is '%s'", $result->{name}, $result->{health})); + } + + next if ($result->{speed} !~ /[0-9]/); + my ($exit3, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $result->{speed}); + if (!$self->{output}->is_status(value => $exit3, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit3, + short_msg => sprintf("Fan '%s' speed is %s rpm", $result->{name}, $result->{speed})); + } + $self->{output}->perfdata_add( + label => 'speed', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $instance, + value => $result->{speed}, + warning => $warn, + critical => $crit, + min => 0 + ); + } +} + +1; diff --git a/storage/dell/me4/mode/components/fru.pm b/storage/dell/me4/mode/components/fru.pm new file mode 100644 index 000000000..f9f964c61 --- /dev/null +++ b/storage/dell/me4/mode/components/fru.pm @@ -0,0 +1,58 @@ +# +# Copyright 2019 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 storage::dell::me4::mode::components::fru; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{json_results}->{frus} = $self->{custom}->request_api(method => 'GET', url_path => '/api/show/frus'); +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking FRUs"); + $self->{components}->{fru} = {name => 'frus', total => 0, skip => 0}; + return if ($self->check_filter(section => 'fru')); + return if (!defined($self->{json_results}->{frus})); + + foreach my $result (@{$self->{json_results}->{frus}->{'enclosure-fru'}}) { + my $instance = $result->{name}; + + next if ($self->check_filter(section => 'fru', instance => $instance)); + + $self->{components}->{fru}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("FRU '%s' status is '%s'", + $result->{name}, $result->{'fru-status'})); + + my $exit1 = $self->get_severity(section => 'fru', value => $result->{'fru-status'}); + if (!$self->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit1, + short_msg => sprintf("FRU '%s' status is '%s'", $result->{name}, $result->{'fru-status'})); + } + } +} + +1; diff --git a/storage/dell/me4/mode/components/psu.pm b/storage/dell/me4/mode/components/psu.pm new file mode 100644 index 000000000..c131a8e1d --- /dev/null +++ b/storage/dell/me4/mode/components/psu.pm @@ -0,0 +1,63 @@ +# +# Copyright 2019 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 storage::dell::me4::mode::components::psu; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{json_results}->{psus} = $self->{custom}->request_api(method => 'GET', url_path => '/api/show/power-supplies'); +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; + return if ($self->check_filter(section => 'psu')); + return if (!defined($self->{json_results}->{psus})); + + foreach my $result (@{$self->{json_results}->{psus}->{'power-supplies'}}) { + my $instance = $result->{'durable-id'}; + + next if ($self->check_filter(section => 'psu', instance => $instance)); + + $self->{components}->{psu}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Power supply '%s' status is '%s', health is '%s' [instance = %s]", + $result->{name}, $result->{status}, $result->{health}, $instance)); + + my $exit1 = $self->get_severity(section => 'psu', value => $result->{status}); + if (!$self->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit1, + short_msg => sprintf("Power supply '%s' status is '%s'", $result->{name}, $result->{status})); + } + my $exit2 = $self->get_severity(section => 'psu', value => $result->{health}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Power supply '%s' health is '%s'", $result->{name}, $result->{health})); + } + } +} + +1; diff --git a/storage/dell/me4/mode/components/sensor.pm b/storage/dell/me4/mode/components/sensor.pm new file mode 100644 index 000000000..47e0d4913 --- /dev/null +++ b/storage/dell/me4/mode/components/sensor.pm @@ -0,0 +1,104 @@ +# +# Copyright 2019 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 storage::dell::me4::mode::components::sensor; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{json_results}->{sensors} = $self->{custom}->request_api(method => 'GET', url_path => '/api/show/sensor-status'); +} + +my %mapping = ( + 'Voltage' => { + unit => 'V', + nlabel => 'voltage', + nunit => 'volt', + regexp => qr/(\d+)/ + }, + 'Current' => { + unit => 'A', + nlabel => 'current', + nunit => 'ampere', + regexp => qr/(\d+)/ + }, + 'Temperature' => { + unit => 'C', + nlabel => 'temperature', + nunit => 'celsius', + regexp => qr/(\d+)\sC/ + }, + 'Charge Capacity' => { + unit => '%', + nlabel => 'capacity', + nunit => 'percentage', + regexp => qr/(\d+)%/ + }, +); + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking sensors"); + $self->{components}->{sensor} = {name => 'sensors', total => 0, skip => 0}; + return if ($self->check_filter(section => 'sensor')); + return if (!defined($self->{json_results}->{sensors})); + + foreach my $result (@{$self->{json_results}->{sensors}->{sensors}}) { + my $instance = $result->{'durable-id'}; + + next if ($self->check_filter(section => 'sensor', instance => $instance)); + + $self->{components}->{sensor}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Sensor '%s' status is '%s' [instance = %s] [value = %s]", + $result->{'sensor-name'}, $result->{status}, $instance, + $result->{value})); + + my $exit1 = $self->get_severity(section => 'sensor', value => $result->{status}); + if (!$self->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit1, + short_msg => sprintf("sensor '%s' status is '%s'", $result->{'sensor-name'}, $result->{status})); + } + + next if (!defined($mapping{$result->{'sensor-type'}})); + next if ($result->{value} !~ $mapping{$result->{'sensor-type'}}->{regexp}); + my $value = $1; + my ($exit3, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'sensor', instance => $instance, value => $value); + if (!$self->{output}->is_status(value => $exit3, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit3, + short_msg => sprintf("Sensor '%s' value is %s %s", $result->{'sensor-name'}, $value, $mapping{$result->{'sensor-type'}}->{nunit})); + } + $self->{output}->perfdata_add( + label => 'sensor', unit => $mapping{$result->{'sensor-type'}}->{unit}, + nlabel => 'hardware.sensor.' . $mapping{$result->{'sensor-type'}}->{nlabel} . '.' . $mapping{$result->{'sensor-type'}}->{nunit}, + instances => $instance, + value => $value, + warning => $warn, + critical => $crit, + min => 0 + ); + } +} + +1; diff --git a/storage/dell/me4/mode/components/volume.pm b/storage/dell/me4/mode/components/volume.pm new file mode 100644 index 000000000..10317beb3 --- /dev/null +++ b/storage/dell/me4/mode/components/volume.pm @@ -0,0 +1,58 @@ +# +# Copyright 2019 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 storage::dell::me4::mode::components::volume; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{json_results}->{volumes} = $self->{custom}->request_api(method => 'GET', url_path => '/api/show/volumes'); +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking volumes"); + $self->{components}->{volume} = {name => 'volumes', total => 0, skip => 0}; + return if ($self->check_filter(section => 'volume')); + return if (!defined($self->{json_results}->{volumes})); + + foreach my $result (@{$self->{json_results}->{volumes}->{volumes}}) { + my $instance = $result->{'durable-id'}; + + next if ($self->check_filter(section => 'volume', instance => $instance)); + + $self->{components}->{volume}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Volume '%s' health is '%s' [instance = %s]", + $result->{'volume-name'}, $result->{health}, $instance)); + + my $exit1 = $self->get_severity(section => 'volume', value => $result->{health}); + if (!$self->{output}->is_status(value => $exit1, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit1, + short_msg => sprintf("Volume '%s' health is '%s'", $result->{'volume-name'}, $result->{health})); + } + } +} + +1; diff --git a/storage/dell/me4/mode/controllerstatistics.pm b/storage/dell/me4/mode/controllerstatistics.pm new file mode 100644 index 000000000..97b3d6443 --- /dev/null +++ b/storage/dell/me4/mode/controllerstatistics.pm @@ -0,0 +1,263 @@ +# +# Copyright 2019 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 storage::dell::me4::mode::controllerstatistics; + +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 => 'controllers', type => 1, cb_prefix_output => 'prefix_output', message_multiple => 'All controllers statistics are ok' } + ]; + + $self->{maps_counters}->{controllers} = [ + { label => 'data-read', nlabel => 'controller.data.read.bytespersecond', set => { + key_values => [ { name => 'data-read-numeric', diff => 1 }, { name => 'display'} ], + output_template => 'Data Read: %s%s/s', + output_change_bytes => 1, + per_second => 1, + perfdatas => [ + { label => 'data_read', value => 'data-read-numeric_per_second', + template => '%s', min => 0, unit => 'B/s', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'data-written', nlabel => 'controller.data.written.bytespersecond', set => { + key_values => [ { name => 'data-written-numeric', diff => 1 }, { name => 'display'} ], + output_template => 'Data Written: %s%s/s', + output_change_bytes => 1, + per_second => 1, + perfdatas => [ + { label => 'data_written', value => 'data-written-numeric_per_second', + template => '%s', min => 0, unit => 'B/s', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'reads', nlabel => 'controller.reads.count', set => { + key_values => [ { name => 'number-of-reads', diff => 1 }, { name => 'display'} ], + output_template => 'Reads: %s/s', + per_second => 1, + perfdatas => [ + { label => 'reads', value => 'number-of-reads_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'writes', nlabel => 'controller.writes.count', set => { + key_values => [ { name => 'number-of-writes', diff => 1 }, { name => 'display'} ], + output_template => 'Writes: %s/s', + per_second => 1, + perfdatas => [ + { label => 'writes', value => 'number-of-writes_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'data-transfer', nlabel => 'controller.data.transfer.bytespersecond', set => { + key_values => [ { name => 'bytes-per-second-numeric'}, { name => 'display'} ], + output_template => 'Data Transfer: %s%s/s', + output_change_bytes => 1, + perfdatas => [ + { label => 'data_transfer', value => 'bytes-per-second-numeric_absolute', + template => '%s', min => 0, unit => 'B/s', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'iops', nlabel => 'controller.iops.ops', set => { + key_values => [ { name => 'iops'}, { name => 'display'} ], + output_template => 'IOPS: %d ops', + perfdatas => [ + { label => 'iops', value => 'iops_absolute', + template => '%d', min => 0, unit => 'ops', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'forwarded-cmds', nlabel => 'controller.commands.forwarded.count', set => { + key_values => [ { name => 'num-forwarded-cmds'}, { name => 'display'} ], + output_template => 'Forwarded Commands: %d', + perfdatas => [ + { label => 'forwarded_cmds', value => 'num-forwarded-cmds_absolute', + template => '%d', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-cache-used', nlabel => 'controller.cache.write.usage.percentage', set => { + key_values => [ { name => 'write-cache-used'}, { name => 'display'} ], + output_template => 'Cache Write Usage: %s%%', + perfdatas => [ + { label => 'write_cache_used', value => 'write-cache-used_absolute', + template => '%d', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-cache-hits', nlabel => 'controller.cache.write.hits.count', set => { + key_values => [ { name => 'write-cache-hits', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Write Hits: %s/s', + per_second => 1, + perfdatas => [ + { label => 'write_cache_hits', value => 'write-cache-hits_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-cache-misses', nlabel => 'controller.cache.write.misses.count', set => { + key_values => [ { name => 'write-cache-misses', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Write Misses: %s/s', + per_second => 1, + perfdatas => [ + { label => 'write_cache_misses', value => 'write-cache-misses_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'read-cache-hits', nlabel => 'controller.cache.read.hits.count', set => { + key_values => [ { name => 'read-cache-hits', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Read Hits: %s/s', + per_second => 1, + perfdatas => [ + { label => 'read_cache_hits', value => 'read-cache-hits_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'read-cache-misses', nlabel => 'controller.cache.read.misses.count', set => { + key_values => [ { name => 'read-cache-misses', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Read Misses: %s/s', + per_second => 1, + perfdatas => [ + { label => 'read_cache_misses', value => 'read-cache-misses_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'cpu-utilization', nlabel => 'controller.cpu.utilization.percentage', set => { + key_values => [ { name => 'cpu-load'}, { name => 'display'} ], + output_template => 'CPU Utilization: %.2f%%', + perfdatas => [ + { label => 'cpu_utilization', value => 'cpu-load_absolute', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Controller '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->request_api(method => 'GET', url_path => '/api/show/controller-statistics'); + + $self->{controllers} = {}; + + foreach my $controller (@{$results->{'controller-statistics'}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $controller->{'durable-id'} !~ /$self->{option_results}->{filter_name}/); + + $self->{controllers}->{$controller->{'durable-id'}} = { display => $controller->{'durable-id'}, %{$controller} }; + } + + if (scalar(keys %{$self->{controllers}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No controllers found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "dell_me4_" . $self->{mode} . '_' . $options{custom}->get_hostname() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); + +} + +1; + +__END__ + +=head1 MODE + +Check controllers statistics. + +=over 8 + +=item B<--filter-name> + +Filter controller name (Can be a regexp). + +=item B<--warning-instance-*> + +Threshold warning. +Can be: 'controller-data-read-bytespersecond', 'controller-data-written-bytespersecond', +'controller-reads-count', 'controller-writes-count', +'controller-data-transfer-bytespersecond', 'controller-iops-ops', +'controller-commands-forwarded-count', +'controller-cache-write-usage-percentage', 'controller-cache-write-hits-count', +'controller-cache-write-misses-count', 'controller-cache-read-hits-count', +'controller-cache-read-misses-count', 'controller-cpu-utilization-percentage'. + +=item B<--critical-instance-*> + +Threshold critical. +Can be: 'controller-data-read-bytespersecond', 'controller-data-written-bytespersecond', +'controller-reads-count', 'controller-writes-count', +'controller-data-transfer-bytespersecond', 'controller-iops-ops', +'controller-commands-forwarded-count', +'controller-cache-write-usage-percentage', 'controller-cache-write-hits-count', +'controller-cache-write-misses-count', 'controller-cache-read-hits-count', +'controller-cache-read-misses-count', 'controller-cpu-utilization-percentage'. + +=back + +=cut diff --git a/storage/dell/me4/mode/hardware.pm b/storage/dell/me4/mode/hardware.pm new file mode 100644 index 000000000..fd5620ee4 --- /dev/null +++ b/storage/dell/me4/mode/hardware.pm @@ -0,0 +1,186 @@ +# +# Copyright 2019 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 storage::dell::me4::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(controller|disk|fan|fru|psu|sensor|volume)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(fan|disk|sensor)$'; + + $self->{cb_hook1} = 'init_custom'; + + $self->{thresholds} = { + controller => [ + ['OK', 'OK'], + ['Operational', 'OK'], + ['Redundant', 'OK'], + ['Redundant with independent cache', 'OK'], + ['Degraded', 'WARNING'], + ['Operational but not redundant', 'WARNING'], + ['Fault', 'CRITICAL'], + ['Down', 'CRITICAL'], + ['N/A', 'UNKNOWN'], + ['Unknown', 'UNKNOWN'], + ['Not Installed', 'UNKNOWN'], + ], + disk => [ + ['OK', 'OK'], + ['Up', 'OK'], + ['AVAIL', 'OK'], + ['LINEAR POOL', 'OK'], + ['LINEAR POOLVRSC', 'OK'], + ['DEDICATED SP', 'OK'], + ['GLOBAL SP', 'OK'], + ['LEFTOVR', 'OK'], + ['VDISK', 'OK'], + ['VDISK SP', 'OK'], + ['VIRTUAL POOL', 'OK'], + ['Degraded', 'WARNING'], + ['Warning', 'WARNING'], + ['Unsupported', 'WARNING'], + ['Fault', 'CRITICAL'], + ['Spun Down', 'CRITICAL'], + ['Error', 'CRITICAL'], + ['Unrecoverable', 'CRITICAL'], + ['Unavailable', 'CRITICAL'], + ['FAILED', 'CRITICAL'], + ['UNUSABLE', 'CRITICAL'], + ['N/A', 'UNKNOWN'], + ['Unknown', 'UNKNOWN'], + ['Not Present', 'UNKNOWN'], + ], + fan => [ + ['OK', 'OK'], + ['Up', 'OK'], + ['Degraded', 'WARNING'], + ['Error', 'CRITICAL'], + ['Fault', 'CRITICAL'], + ['Missing', 'UNKNOWN'], + ['Off', 'UNKNOWN'], + ['N/A', 'UNKNOWN'], + ['Unknown', 'UNKNOWN'], + ], + fru => [ + ['OK', 'OK'], + ['Fault', 'CRITICAL'], + ['Invalid Data', 'CRITICAL'], + ['Power OFF', 'UNKNOWN'], + ['Absent', 'UNKNOWN'], + ], + psu => [ + ['OK', 'OK'], + ['Up', 'OK'], + ['Degraded', 'WARNING'], + ['Error', 'CRITICAL'], + ['Fault', 'CRITICAL'], + ['Missing', 'UNKNOWN'], + ['Off', 'UNKNOWN'], + ['N/A', 'UNKNOWN'], + ['Unknown', 'UNKNOWN'], + ], + sensor => [ + ['OK', 'OK'], + ['Warning', 'WARNING'], + ['Critical', 'CRITICAL'], + ['Unavailable', 'CRITICAL'], + ['Unrecoverable', 'UNKNOWN'], + ['Not Installed', 'UNKNOWN'], + ['Unsupported', 'UNKNOWN'], + ['Unknown', 'UNKNOWN'], + ], + volume => [ + ['OK', 'OK'], + ['Degraded', 'WARNING'], + ['Fault', 'CRITICAL'], + ['N/A', 'UNKNOWN'], + ['Unknown', 'UNKNOWN'], + ], + }; + + $self->{components_path} = 'storage::dell::me4::mode::components'; + $self->{components_module} = ['controller', 'disk', 'fan', 'fru', 'psu', 'sensor', 'volume']; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub init_custom { + my ($self, %options) = @_; + + $self->{custom} = $options{custom}; +} + +1; + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'controller', 'disk', 'fan', 'fru', 'psu', 'sensor', 'volume'. + +=item B<--filter> + +Exclude some parts (comma seperated list) +Can also exclude specific instance: --filter='sensor,Overall Sensor' + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=item B<--threshold-overload> + +Set to overload default threshold values (syntax: section,[instance,]status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='controller,OK,Operational but not redundant' + +=item B<--warning> + +Set warning threshold for 'temperature' (syntax: type,regexp,threshold) +Example: --warning='temperature,.*,40' + +=item B<--critical> + +Set critical threshold for 'temperature' (syntax: type,regexp,threshold) +Example: --critical='temperature,.*,50' + +=back + +=cut diff --git a/storage/dell/me4/mode/listcontrollers.pm b/storage/dell/me4/mode/listcontrollers.pm new file mode 100644 index 000000000..74f004cb0 --- /dev/null +++ b/storage/dell/me4/mode/listcontrollers.pm @@ -0,0 +1,104 @@ +# +# Copyright 2019 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 storage::dell::me4::mode::listcontrollers; + +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' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{result} = $options{custom}->request_api(method => 'GET', url_path => '/api/show/controllers'); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $controller (@{$self->{result}->{controllers}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $controller->{'durable-id'} !~ /$self->{option_results}->{filter_name}/); + + $self->{output}->output_add(long_msg => sprintf("[name = %s]", + $controller->{'durable-id'}, + )); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List controllers:'); + $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']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $controller (@{$self->{controllers}}) { + $self->{output}->add_disco_entry( + name => $controller->{'durable-id'}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List controllers. + +=over 8 + +=item B<--filter-name> + +Filter controller name (Can be a regexp). + +=back + +=cut diff --git a/storage/dell/me4/mode/listvolumes.pm b/storage/dell/me4/mode/listvolumes.pm new file mode 100644 index 000000000..a500bc1a8 --- /dev/null +++ b/storage/dell/me4/mode/listvolumes.pm @@ -0,0 +1,106 @@ +# +# Copyright 2019 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 storage::dell::me4::mode::listvolumes; + +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' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{result} = $options{custom}->request_api(method => 'GET', url_path => '/api/show/volumes'); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $volume (@{$self->{result}->{volumes}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $volume->{'volume-name'} !~ /$self->{option_results}->{filter_name}/); + + $self->{output}->output_add(long_msg => sprintf("[name = %s][volumegroup = %s]", + $volume->{'volume-name'}, + $volume->{'volume-group'}, + )); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List volumes:'); + $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', 'volumegroup']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $volume (@{$self->{volumes}}) { + $self->{output}->add_disco_entry( + name => $volume->{'volume-name'}, + volumegroup => $volume->{'volume-group'}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List volumes. + +=over 8 + +=item B<--filter-name> + +Filter volume name (Can be a regexp). + +=back + +=cut diff --git a/storage/dell/me4/mode/volumestatistics.pm b/storage/dell/me4/mode/volumestatistics.pm new file mode 100644 index 000000000..e91444ae7 --- /dev/null +++ b/storage/dell/me4/mode/volumestatistics.pm @@ -0,0 +1,241 @@ +# +# Copyright 2019 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 storage::dell::me4::mode::volumestatistics; + +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 => 'volumes', type => 1, cb_prefix_output => 'prefix_output', message_multiple => 'All volumes statistics are ok' } + ]; + + $self->{maps_counters}->{volumes} = [ + { label => 'data-read', nlabel => 'volume.data.read.bytespersecond', set => { + key_values => [ { name => 'data-read-numeric', diff => 1 }, { name => 'display'} ], + output_template => 'Data Read: %s%s/s', + output_change_bytes => 1, + per_second => 1, + perfdatas => [ + { label => 'data_read', value => 'data-read-numeric_per_second', + template => '%s', min => 0, unit => 'B/s', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'data-written', nlabel => 'volume.data.written.bytespersecond', set => { + key_values => [ { name => 'data-written-numeric', diff => 1 }, { name => 'display'} ], + output_template => 'Data Written: %s%s/s', + output_change_bytes => 1, + per_second => 1, + perfdatas => [ + { label => 'data_written', value => 'data-written-numeric_per_second', + template => '%s', min => 0, unit => 'B/s', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'reads', nlabel => 'volume.reads.count', set => { + key_values => [ { name => 'number-of-reads', diff => 1 }, { name => 'display'} ], + output_template => 'Reads: %s/s', + per_second => 1, + perfdatas => [ + { label => 'reads', value => 'number-of-reads_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'writes', nlabel => 'volume.writes.count', set => { + key_values => [ { name => 'number-of-writes', diff => 1 }, { name => 'display'} ], + output_template => 'Writes: %s/s', + per_second => 1, + perfdatas => [ + { label => 'writes', value => 'number-of-writes_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'data-transfer', nlabel => 'volume.data.transfer.bytespersecond', set => { + key_values => [ { name => 'bytes-per-second-numeric'}, { name => 'display'} ], + output_template => 'Data Transfer: %s%s/s', + output_change_bytes => 1, + perfdatas => [ + { label => 'data_transfer', value => 'bytes-per-second-numeric_absolute', + template => '%s', min => 0, unit => 'B/s', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'iops', nlabel => 'volume.iops.ops', set => { + key_values => [ { name => 'iops'}, { name => 'display'} ], + output_template => 'IOPS: %d ops', + perfdatas => [ + { label => 'iops', value => 'iops_absolute', + template => '%d', min => 0, unit => 'ops', label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-cache-percent', nlabel => 'volume.cache.write.usage.percentage', set => { + key_values => [ { name => 'write-cache-percent'}, { name => 'display'} ], + output_template => 'Cache Write Usage: %s%%', + perfdatas => [ + { label => 'write_cache_used', value => 'write-cache-percent_absolute', + template => '%d', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-cache-hits', nlabel => 'volume.cache.write.hits.count', set => { + key_values => [ { name => 'write-cache-hits', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Write Hits: %s/s', + per_second => 1, + perfdatas => [ + { label => 'write_cache_hits', value => 'write-cache-hits_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-cache-misses', nlabel => 'volume.cache.write.misses.count', set => { + key_values => [ { name => 'write-cache-misses', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Write Misses: %s/s', + per_second => 1, + perfdatas => [ + { label => 'write_cache_misses', value => 'write-cache-misses_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'read-cache-hits', nlabel => 'volume.cache.read.hits.count', set => { + key_values => [ { name => 'read-cache-hits', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Read Hits: %s/s', + per_second => 1, + perfdatas => [ + { label => 'read_cache_hits', value => 'read-cache-hits_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + { label => 'read-cache-misses', nlabel => 'volume.cache.read.misses.count', set => { + key_values => [ { name => 'read-cache-misses', diff => 1 }, { name => 'display'} ], + output_template => 'Cache Read Misses: %s/s', + per_second => 1, + perfdatas => [ + { label => 'read_cache_misses', value => 'read-cache-misses_per_second', + template => '%s', min => 0, label_extra_instance => 1, + instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Volume '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->request_api(method => 'GET', url_path => '/api/show/volume-statistics'); + + $self->{volumes} = {}; + + foreach my $volume (@{$results->{'volume-statistics'}}) { + next if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' + && $volume->{'volume-name'} !~ /$self->{option_results}->{filter_name}/); + + $self->{volumes}->{$volume->{'volume-name'}} = { display => $volume->{'volume-name'}, %{$volume} }; + } + + if (scalar(keys %{$self->{volumes}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No volumes found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "dell_me4_" . $self->{mode} . '_' . $options{custom}->get_hostname() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); + +} + +1; + +__END__ + +=head1 MODE + +Check volumes statistics. + +=over 8 + +=item B<--filter-name> + +Filter volume name (Can be a regexp). + +=item B<--warning-instance-*> + +Threshold warning. +Can be: 'volume-data-read-bytespersecond', 'volume-data-written-bytespersecond', +'volume-reads-count', 'volume-writes-count', +'volume-data-transfer-bytespersecond', 'volume-iops-ops', +'volume-cache-write-usage-percentage', 'volume-cache-write-hits-count', +'volume-cache-write-misses-count', 'volume-cache-read-hits-count', +'volume-cache-read-misses-count'. + +=item B<--critical-instance-*> + +Threshold critical. +Can be: 'volume-data-read-bytespersecond', 'volume-data-written-bytespersecond', +'volume-reads-count', 'volume-writes-count', +'volume-data-transfer-bytespersecond', 'volume-iops-ops', +'volume-cache-write-usage-percentage', 'volume-cache-write-hits-count', +'volume-cache-write-misses-count', 'volume-cache-read-hits-count', +'volume-cache-read-misses-count'. + +=back + +=cut diff --git a/storage/dell/me4/plugin.pm b/storage/dell/me4/plugin.pm new file mode 100644 index 000000000..fb9ac2cd9 --- /dev/null +++ b/storage/dell/me4/plugin.pm @@ -0,0 +1,53 @@ +# +# Copyright 2019 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 storage::dell::me4::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ( $class, %options ) = @_; + my $self = $class->SUPER::new( package => __PACKAGE__, %options ); + bless $self, $class; + + $self->{version} = '0.1'; + %{ $self->{modes} } = ( + 'controller-statistics' => 'storage::dell::me4::mode::controllerstatistics', + 'hardware' => 'storage::dell::me4::mode::hardware', + 'list-controllers' => 'storage::dell::me4::mode::listcontrollers', + 'list-volumes' => 'storage::dell::me4::mode::listvolumes', + 'volume-statistics' => 'storage::dell::me4::mode::volumestatistics', + ); + + $self->{custom_modes}{api} = 'storage::dell::me4::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Dell ME4 series using API. + +=cut diff --git a/storage/emc/DataDomain/mode/components/battery.pm b/storage/emc/DataDomain/mode/components/battery.pm index f685ffcd1..128b6e39a 100644 --- a/storage/emc/DataDomain/mode/components/battery.pm +++ b/storage/emc/DataDomain/mode/components/battery.pm @@ -79,14 +79,17 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Nvram battery '%s' charge is %s %%", $instance, $batt_value)); } - $self->{output}->perfdata_add(label => 'nvram_battery_' . $instance, unit => '%', - value => $batt_value, - warning => $warn, - critical => $crit, - min => 0, max => 100 - ); + $self->{output}->perfdata_add( + label => 'nvram_battery', unit => '%', + nlabel => 'hardware.battery.nvram.charge.percentage', + instances => $instance, + value => $batt_value, + warning => $warn, + critical => $crit, + min => 0, max => 100 + ); } } } -1; \ No newline at end of file +1; diff --git a/storage/emc/DataDomain/mode/components/temperature.pm b/storage/emc/DataDomain/mode/components/temperature.pm index 533f3358f..c36d61dc7 100644 --- a/storage/emc/DataDomain/mode/components/temperature.pm +++ b/storage/emc/DataDomain/mode/components/temperature.pm @@ -83,13 +83,16 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s degree centigrade", $temp_descr, $temp_value)); } - $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', - value => $temp_value, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $instance, + value => $temp_value, + warning => $warn, + critical => $crit, + ); } } } -1; \ No newline at end of file +1; diff --git a/storage/emc/DataDomain/mode/filesystem.pm b/storage/emc/DataDomain/mode/filesystem.pm index 030e950bb..c0d7eb9d6 100644 --- a/storage/emc/DataDomain/mode/filesystem.pm +++ b/storage/emc/DataDomain/mode/filesystem.pm @@ -86,13 +86,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "name" => { name => 'use_name' }, - "filesystem:s" => { name => 'filesystem' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - }); + $options{options}->add_options(arguments => { + 'name' => { name => 'use_name' }, + 'filesystem:s' => { name => 'filesystem' }, + 'regexp' => { name => 'use_regexp' }, + 'regexp-isensitive' => { name => 'use_regexpi' }, + }); return $self; } @@ -113,11 +112,13 @@ sub add_result { sub manage_selection { my ($self, %options) = @_; - $self->{results} = $options{snmp}->get_multiple_table(oids => [ - { oid => $oid_sysDescr }, - { oid => $oid_fileSystemSpaceEntry }, - ], - nothing_quit => 1); + $self->{results} = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oid_sysDescr }, + { oid => $oid_fileSystemSpaceEntry }, + ], + nothing_quit => 1 + ); if (!($self->{os_version} = storage::emc::DataDomain::lib::functions::get_version(value => $self->{results}->{$oid_sysDescr}->{$oid_sysDescr . '.0'}))) { $self->{output}->output_add(severity => 'UNKNOWN', short_msg => 'Cannot get DataDomain OS version.'); @@ -165,10 +166,10 @@ sub manage_selection { if (defined($self->{option_results}->{device})) { $self->{output}->add_option_msg(short_msg => "No filesystem found '" . $self->{option_results}->{filesystem} . "'."); } else { - $self->{output}->add_option_msg(short_msg => "No filesystem found."); + $self->{output}->add_option_msg(short_msg => 'No filesystem found.'); } $self->{output}->option_exit(); - } + } } sub disco_format { @@ -183,8 +184,10 @@ sub disco_show { $self->{snmp} = $options{snmp}; $self->manage_selection(disco => 1); foreach (sort keys %{$self->{fs}}) { - $self->{output}->add_disco_entry(name => $self->{fs}->{$_}->{display}, - deviceid => $_); + $self->{output}->add_disco_entry( + name => $self->{fs}->{$_}->{display}, + deviceid => $_ + ); } } diff --git a/storage/emc/DataDomain/mode/replication.pm b/storage/emc/DataDomain/mode/replication.pm index dcc613d01..1e6695d73 100644 --- a/storage/emc/DataDomain/mode/replication.pm +++ b/storage/emc/DataDomain/mode/replication.pm @@ -25,6 +25,7 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use storage::emc::DataDomain::lib::functions; sub custom_status_calc { my ($self, %options) = @_; @@ -77,12 +78,11 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "unknown-status:s" => { name => 'unknown_status', default => '' }, - "warning-status:s" => { name => 'warning_status', default => '%{state} =~ /initializing|recovering/i' }, - "critical-status:s" => { name => 'critical_status', default => '%{state} =~ /disabledNeedsResync|uninitialized/i' }, - }); + $options{options}->add_options(arguments => { + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status', default => '%{state} =~ /initializing|recovering/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{state} =~ /disabledNeedsResync|uninitialized/i' }, + }); return $self; } diff --git a/storage/emc/isilon/snmp/mode/components/fan.pm b/storage/emc/isilon/snmp/mode/components/fan.pm index cc257bfdb..c55c8529f 100644 --- a/storage/emc/isilon/snmp/mode/components/fan.pm +++ b/storage/emc/isilon/snmp/mode/components/fan.pm @@ -62,12 +62,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '%s' is %s rpm", $result->{fanName}, $result->{fanSpeed})); } - $self->{output}->perfdata_add(label => 'speed_' . $result->{fanName}, unit => 'rpm', - value => $result->{fanSpeed}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'speed', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $result->{fanName}, + value => $result->{fanSpeed}, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1; diff --git a/storage/emc/isilon/snmp/mode/components/power.pm b/storage/emc/isilon/snmp/mode/components/power.pm index c9e81095f..a3d1f78ba 100644 --- a/storage/emc/isilon/snmp/mode/components/power.pm +++ b/storage/emc/isilon/snmp/mode/components/power.pm @@ -62,12 +62,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Power '%s' sensor is %s (Volt or Amp)", $result->{powerSensorName}, $result->{powerSensorValue})); } - $self->{output}->perfdata_add(label => 'power_' . $result->{powerSensorName}, - value => $result->{powerSensorValue}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'power', + nlabel => 'hardware.power.sensor.count', + instances => $result->{powerSensorName}, + value => $result->{powerSensorValue}, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1; diff --git a/storage/emc/isilon/snmp/mode/components/temperature.pm b/storage/emc/isilon/snmp/mode/components/temperature.pm index 9d6ecb87d..3835fd488 100644 --- a/storage/emc/isilon/snmp/mode/components/temperature.pm +++ b/storage/emc/isilon/snmp/mode/components/temperature.pm @@ -62,12 +62,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s C", $result->{tempSensorName}, $result->{tempSensorValue})); } - $self->{output}->perfdata_add(label => 'temperature_' . $result->{tempSensorName}, unit => 'C', - value => $result->{tempSensorValue}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $result->{tempSensorName}, + value => $result->{tempSensorValue}, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1; diff --git a/storage/emc/symmetrix/dmx34/local/mode/components/disk.pm b/storage/emc/symmetrix/dmx34/local/mode/components/disk.pm index 793e91e07..984e2770b 100644 --- a/storage/emc/symmetrix/dmx34/local/mode/components/disk.pm +++ b/storage/emc/symmetrix/dmx34/local/mode/components/disk.pm @@ -108,10 +108,13 @@ sub check { $total - $used - $not_ready, $total)); } - $self->{output}->perfdata_add(label => "disk_spare_available", - value => $total - $used - $not_ready, - warning => $warn, - critical => $crit, min => 0, max => $total); + $self->{output}->perfdata_add( + label => "disk_spare_available", + nlabel => 'hardware.disk.spare.available.count', + value => $total - $used - $not_ready, + warning => $warn, + critical => $crit, min => 0, max => $total + ); } 1; diff --git a/storage/emc/symmetrix/vmax/local/mode/components/sparedisk.pm b/storage/emc/symmetrix/vmax/local/mode/components/sparedisk.pm index d855b21ad..6cdcad95e 100644 --- a/storage/emc/symmetrix/vmax/local/mode/components/sparedisk.pm +++ b/storage/emc/symmetrix/vmax/local/mode/components/sparedisk.pm @@ -53,10 +53,13 @@ sub check { $value)); } - $self->{output}->perfdata_add(label => "disk_spare_non_available", - value => $value, - warning => $warn, - critical => $crit, min => 0); + $self->{output}->perfdata_add( + label => "disk_spare_non_available", + nlabel => 'hardware.sparedisk.unavailable.count', + value => $value, + warning => $warn, + critical => $crit, min => 0 + ); } 1; diff --git a/storage/emc/vplex/restapi/custom/vplexapi.pm b/storage/emc/vplex/restapi/custom/vplexapi.pm index 0dbb29e10..8566866de 100644 --- a/storage/emc/vplex/restapi/custom/vplexapi.pm +++ b/storage/emc/vplex/restapi/custom/vplexapi.pm @@ -44,21 +44,18 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s@" => { name => 'hostname' }, - "vplex-username:s@" => { name => 'vplex_username' }, - "vplex-password:s@" => { name => 'vplex_password' }, - "proxyurl:s@" => { name => 'proxyurl' }, - "timeout:s@" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s@" => { name => 'hostname' }, + "vplex-username:s@" => { name => 'vplex_username' }, + "vplex-password:s@" => { name => 'vplex_password' }, + "timeout:s@" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; @@ -100,7 +97,6 @@ sub check_options { $self->{vplex_username} = (defined($self->{option_results}->{vplex_username})) ? shift(@{$self->{option_results}->{vplex_username}}) : ''; $self->{vplex_password} = (defined($self->{option_results}->{vplex_password})) ? shift(@{$self->{option_results}->{vplex_password}}) : ''; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef; if (!defined($self->{hostname})) { $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); @@ -121,7 +117,6 @@ sub build_options_for_httplib { $self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{port} = 443; $self->{option_results}->{proto} = 'https'; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; } sub settings { @@ -213,18 +208,10 @@ Vplex username. Vplex password. -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/storage/emc/xtremio/restapi/custom/xtremioapi.pm b/storage/emc/xtremio/restapi/custom/xtremioapi.pm index 19ae0f1b3..414918145 100644 --- a/storage/emc/xtremio/restapi/custom/xtremioapi.pm +++ b/storage/emc/xtremio/restapi/custom/xtremioapi.pm @@ -41,22 +41,19 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s@" => { name => 'hostname' }, - "xtremio-username:s@" => { name => 'xtremio_username' }, - "xtremio-password:s@" => { name => 'xtremio_password' }, - "proxyurl:s@" => { name => 'proxyurl' }, - "timeout:s@" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "reload-cache-time:s" => { name => 'reload_cache_time' }, - }); + $options{options}->add_options(arguments => { + "hostname:s@" => { name => 'hostname' }, + "xtremio-username:s@" => { name => 'xtremio_username' }, + "xtremio-password:s@" => { name => 'xtremio_password' }, + "timeout:s@" => { name => 'timeout' }, + "reload-cache-time:s" => { name => 'reload_cache_time' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); $self->{statefile_cache_cluster} = centreon::plugins::statefile->new(%options); return $self; @@ -92,7 +89,6 @@ sub check_options { $self->{xtremio_username} = (defined($self->{option_results}->{xtremio_username})) ? shift(@{$self->{option_results}->{xtremio_username}}) : ''; $self->{xtremio_password} = (defined($self->{option_results}->{xtremio_password})) ? shift(@{$self->{option_results}->{xtremio_password}}) : ''; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef; $self->{reload_cache_time} = (defined($self->{option_results}->{reload_cache_time})) ? shift(@{$self->{option_results}->{reload_cache_time}}) : 180; if (!defined($self->{hostname})) { @@ -121,7 +117,6 @@ sub build_options_for_httplib { $self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{port} = 443; $self->{option_results}->{proto} = 'https'; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; } sub settings { @@ -277,18 +272,10 @@ Xtremio username. Xtremio password. -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--reload-cache-time> Time in seconds before reloading cache file (default: 180). diff --git a/storage/emc/xtremio/restapi/mode/ssdiops.pm b/storage/emc/xtremio/restapi/mode/ssdiops.pm index 1f57e8f23..db12f5cc5 100644 --- a/storage/emc/xtremio/restapi/mode/ssdiops.pm +++ b/storage/emc/xtremio/restapi/mode/ssdiops.pm @@ -20,43 +20,79 @@ package storage::emc::xtremio::restapi::mode::ssdiops; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -my $maps_counters = { - ssd => { - '000_global' => { set => { +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'ssd', type => 1, cb_prefix_output => 'prefix_ssd_output', message_multiple => 'All SSDs usages are ok' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total', set => { + key_values => [ { name => 'total' } ], + output_template => 'Total : %s iops', + perfdatas => [ + { label => 'total', value => 'total_absolute', template => '%s', + min => 0, unit => 'iops' }, + ], + } + }, + { label => 'total-read', set => { + key_values => [ { name => 'total_read' } ], + output_template => 'Total read : %s iops', + perfdatas => [ + { label => 'total_read', value => 'total_read_absolute', template => '%s', + min => 0, unit => 'iops' }, + ], + } + }, + { label => 'total-write', set => { + key_values => [ { name => 'total_write' } ], + output_template => 'Total write : %s iops', + perfdatas => [ + { label => 'total_write', value => 'total_write_absolute', template => '%s', + min => 0, unit => 'iops' }, + ], + } + }, + ]; + + $self->{maps_counters}->{ssd} = [ + { label => 'global', set => { key_values => [ { name => 'global_iops' }, { name => 'display' }, ], - output_template => 'Global IOPs : %s', + output_template => 'Global : %s iops', perfdatas => [ - { label => 'global_iops', value => 'global_iops_absolute', template => '%s', + { label => 'global', value => 'global_iops_absolute', template => '%s', min => 0, unit => 'iops', label_extra_instance => 1, instance_use => 'display_absolute' }, ], } }, - '001_read' => { set => { + { label => 'read', set => { key_values => [ { name => 'read_iops' }, { name => 'display' }, ], - output_template => 'Read IOPs : %s', + output_template => 'Read : %s iops', perfdatas => [ - { label => 'read_iops', value => 'read_iops_absolute', template => '%s', + { label => 'read', value => 'read_iops_absolute', template => '%s', min => 0, unit => 'iops', label_extra_instance => 1, instance_use => 'display_absolute' }, ], } }, - '002_write' => { set => { + { label => 'write', set => { key_values => [ { name => 'write_iops' }, { name => 'display' }, ], - output_template => 'Write IOPs : %s', + output_template => 'Write : %s iopss', perfdatas => [ - { label => 'write_iops', value => 'write_iops_absolute', template => '%s', + { label => 'write', value => 'write_iops_absolute', template => '%s', min => 0, unit => 'iops', label_extra_instance => 1, instance_use => 'display_absolute' }, ], } }, - }, -}; + ]; +} sub new { my ($class, %options) = @_; @@ -64,122 +100,52 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); - foreach my $key (('ssd')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - return $self; } -sub check_options { +sub prefix_ssd_output { my ($self, %options) = @_; - $self->SUPER::init(%options); - foreach my $key (('ssd')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } -} - -sub run { - my ($self, %options) = @_; - $self->{xtremio} = $options{custom}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{ssd}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All SSDs usages are ok'); - } - - foreach my $id (sort keys %{$self->{ssd}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{ssd}}) { - my $obj = $maps_counters->{ssd}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{ssd}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "SSD '" . $self->{ssd}->{$id}->{display} . "' Usage $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "SSD '" . $self->{ssd}->{$id}->{display} . "' Usage $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "SSD '" . $self->{ssd}->{$id}->{display} . "' Usage $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); + return "SSD '" . $options{instance_value}->{display} . "' Usage "; } sub manage_selection { my ($self, %options) = @_; - $self->{ssd} = {}; my $urlbase = '/api/json/types/'; - my @items = $self->{xtremio}->get_items(url => $urlbase, - obj => 'ssds'); + my @items = $options{custom}->get_items( + url => $urlbase, + obj => 'ssds' + ); + + $self->{ssd} = {}; + $self->{global} = { total => 0, total_read => 0, total_write => 0 }; foreach my $item (@items) { if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $item !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $item . "': no matching name.", debug => 1); + $self->{output}->output_add(long_msg => "skipping '" . $item . "': no matching name.", debug => 1); next; } - my $details = $self->{xtremio}->get_details(url => $urlbase, - obj => 'ssds', - name => $item); - - $self->{ssd}->{$item} = { display => $item, global_iops => $details->{iops}, - read_iops => $details->{'rd-iops'}, write_iops => $details->{'wr-iops'} }; + my $details = $options{custom}->get_details( + url => $urlbase, + obj => 'ssds', + name => $item + ); + + $self->{global}->{total} += $details->{iops}; + $self->{global}->{total_read} += $details->{'rd-iops'}; + $self->{global}->{total_write} += $details->{'wr-iops'}; + $self->{ssd}->{$item} = { + display => $item, + global_iops => $details->{iops}, + read_iops => $details->{'rd-iops'}, + write_iops => $details->{'wr-iops'}, + }; } if (scalar(keys %{$self->{ssd}}) <= 0) { @@ -194,18 +160,15 @@ __END__ =head1 MODE -Check IOPS (Global, Read, Write) on each SSDs. +Check SSDs usage. =over 8 -=item B<--warning-*> +=item B<--warning-*> B<--critical-*> Threshold warning (number of iops) -Can be: 'global', 'read', 'write'. - -=item B<--critical-*> -Threshold critical (number of iops) -Can be: 'global', 'read', 'write'. +Can be: 'total', 'total-read', 'total-write', +'global', 'read', 'write'. =item B<--filter-name> diff --git a/storage/fujitsu/eternus/dx/ssh/mode/cpu.pm b/storage/fujitsu/eternus/dx/ssh/mode/cpu.pm index cd5c0b99e..3f5b77760 100644 --- a/storage/fujitsu/eternus/dx/ssh/mode/cpu.pm +++ b/storage/fujitsu/eternus/dx/ssh/mode/cpu.pm @@ -20,26 +20,37 @@ package storage::fujitsu::eternus::dx::ssh::mode::cpu; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; +use centreon::plugins::misc; -my $maps_counters = { - cpu => { - '001_usage' => { - set => { +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'cpu', type => 1, cb_prefix_output => 'prefix_cpu_output', message_multiple => 'All CPUs are ok' } + ]; + + $self->{maps_counters}->{cpu} = [ + { label => 'usage', nlabel => 'cpu.utilization.percentage', set => { key_values => [ { name => 'usage' }, { name => 'display' } ], output_template => 'Usage : %d %%', perfdatas => [ { label => 'cpu', value => 'usage_absolute', template => '%d', unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - } -}; + ]; +} + +sub prefix_cpu_output { + my ($self, %options) = @_; + + return "CPU '" . $options{instance_value}->{display} . "' "; +} sub new { my ($class, %options) = @_; @@ -47,132 +58,41 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "command:s" => { name => 'command', default => 'show' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => 'performance -type cm' }, - "no-component:s" => { name => 'no_component' }, - "filter-name:s" => { name => 'filter_name' }, - }); - $self->{no_components} = undef; - - foreach my $key (('cpu')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "command:s" => { name => 'command', default => 'show' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => 'performance -type cm' }, + "filter-name:s" => { name => 'filter_name' }, + }); + return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->SUPER::check_options(%options); if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') { $self->{option_results}->{remote} = 1; } - - foreach my $key (('cpu')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } -} - -sub run { - my ($self, %options) = @_; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{cpu}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All CPUs are ok'); - } - - foreach my $id (sort keys %{$self->{cpu}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{cpu}}) { - my $obj = $maps_counters->{cpu}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{cpu}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "CPU '$self->{cpu}->{$id}->{display}' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "CPU '$self->{cpu}->{$id}->{display}' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "CPU '$self->{cpu}->{$id}->{display}' $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); } sub manage_selection { my ($self, %options) = @_; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - ssh_pipe => 1, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); + my $stdout = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + ssh_pipe => 1, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options} + ); # Can have 4 columns also. #Location Busy Rate(%) Copy Residual Quantity(MB) @@ -191,16 +111,16 @@ sub manage_selection { if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $cpu_name !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $cpu_name . "': no matching filter name."); + $self->{output}->output_add(long_msg => "skipping '" . $cpu_name . "': no matching filter name."); next; } $self->{cpu}->{$cpu_name} = { display => $cpu_name, usage => $cpu_value }; } - + if (scalar(keys %{$self->{cpu}}) <= 0) { - $self->{output}->output_add(severity => defined($self->{no_components}) ? $self->{no_components} : 'unknown', - short_msg => 'No components are checked.'); + $self->{output}->add_option_msg(short_msg => "No component found."); + $self->{output}->option_exit(); } } @@ -247,10 +167,6 @@ Command path (Default: none). Command options (Default: 'performance -type cm'). -=item B<--no-component> - -Set the threshold where no components (Default: 'unknown' returns). - =item B<--filter-name> Filter by name (regexp can be used). diff --git a/storage/fujitsu/eternus/dx/ssh/mode/portstats.pm b/storage/fujitsu/eternus/dx/ssh/mode/portstats.pm index e9f752fa1..3ca8cf100 100644 --- a/storage/fujitsu/eternus/dx/ssh/mode/portstats.pm +++ b/storage/fujitsu/eternus/dx/ssh/mode/portstats.pm @@ -20,56 +20,64 @@ package storage::fujitsu::eternus::dx::ssh::mode::portstats; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; +use centreon::plugins::misc; -my $maps_counters = { - port => { - '000_read-iops' => { - set => { +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'port', type => 1, cb_prefix_output => 'prefix_port_output', message_multiple => 'All ports are ok' } + ]; + + $self->{maps_counters}->{port} = [ + { label => 'read-iops', nlabel => 'port.io.read.usage.iops', set => { key_values => [ { name => 'read_iops' }, { name => 'display' } ], output_template => 'Read IOPS : %d', perfdatas => [ { label => 'read_iops', value => 'read_iops_absolute', template => '%d', unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '001_write-iops' => { - set => { + { label => 'write-iops', nlabel => 'port.io.write.usage.iops', set => { key_values => [ { name => 'write_iops' }, { name => 'display' } ], output_template => 'Write IOPS : %d', perfdatas => [ { label => 'write_iops', value => 'write_iops_absolute', template => '%d', unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '002_read-traffic' => { - set => { + { label => 'read-traffic', nlabel => 'port.traffic.read.usage.bitspersecond', set => { key_values => [ { name => 'read_traffic' }, { name => 'display' } ], output_template => 'Read Traffic : %s %s/s', output_change_bytes => 2, perfdatas => [ { label => 'read_traffic', value => 'read_traffic_absolute', template => '%d', unit => 'b/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '003_write-traffic' => { - set => { + { label => 'write-traffic', nlabel => 'port.traffic.write.usage.bitspersecond', set => { key_values => [ { name => 'write_traffic' }, { name => 'display' } ], output_template => 'Write Traffic : %s %s/s', output_change_bytes => 2, perfdatas => [ { label => 'write_traffic', value => 'write_traffic_absolute', template => '%d', unit => 'b/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - } -}; + ]; +} + +sub prefix_port_output { + my ($self, %options) = @_; + + return "Port '" . $options{instance_value}->{display} . "' "; +} sub new { my ($class, %options) = @_; @@ -77,132 +85,41 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "command:s" => { name => 'command', default => 'show' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => 'performance -type port' }, - "no-component:s" => { name => 'no_component' }, - "filter-name:s" => { name => 'filter_name' }, - }); - $self->{no_components} = undef; - - foreach my $key (('port')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "command:s" => { name => 'command', default => 'show' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => 'performance -type port' }, + "filter-name:s" => { name => 'filter_name' }, + }); + return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->SUPER::check_options(%options); if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') { $self->{option_results}->{remote} = 1; } - - foreach my $key (('port')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } -} - -sub run { - my ($self, %options) = @_; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{port}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All Ports are ok'); - } - - foreach my $id (sort keys %{$self->{port}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{port}}) { - my $obj = $maps_counters->{port}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{port}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Port '$self->{port}->{$id}->{display}' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Port '$self->{port}->{$id}->{display}' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Port '$self->{port}->{$id}->{display}' $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); } sub manage_selection { my ($self, %options) = @_; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - ssh_pipe => 1, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); + my $stdout = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + ssh_pipe => 1, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options} + ); #Location IOPS(IOPS) Throughput(MB/s) # Read / Write Read / Write @@ -221,16 +138,17 @@ sub manage_selection { next; } - $self->{port}->{$port_name} = { display => $port_name, - read_iops => $port_read_iops, write_iops => $port_write_iops, - read_traffic => $port_read_traffic * 1000 * 1000 * 8, - write_traffic => $port_write_traffic * 1000 * 1000 * 8 - }; + $self->{port}->{$port_name} = { + display => $port_name, + read_iops => $port_read_iops, write_iops => $port_write_iops, + read_traffic => $port_read_traffic * 1000 * 1000 * 8, + write_traffic => $port_write_traffic * 1000 * 1000 * 8 + }; } - + if (scalar(keys %{$self->{port}}) <= 0) { - $self->{output}->output_add(severity => defined($self->{no_components}) ? $self->{no_components} : 'unknown', - short_msg => 'No components are checked.'); + $self->{output}->add_option_msg(short_msg => "No port found."); + $self->{output}->option_exit(); } } @@ -277,10 +195,6 @@ Command path (Default: none). Command options (Default: 'performance -type port'). -=item B<--no-component> - -Set the threshold where no components (Default: 'unknown' returns). - =item B<--filter-name> Filter by name (regexp can be used). diff --git a/storage/fujitsu/eternus/dx/ssh/mode/raidgroups.pm b/storage/fujitsu/eternus/dx/ssh/mode/raidgroups.pm index 2a069a96a..cc191b1be 100644 --- a/storage/fujitsu/eternus/dx/ssh/mode/raidgroups.pm +++ b/storage/fujitsu/eternus/dx/ssh/mode/raidgroups.pm @@ -20,48 +20,16 @@ package storage::fujitsu::eternus::dx::ssh::mode::raidgroups; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; - -my $thresholds = { - rg => [ - ['Available', 'OK'], - ['Spare in Use', 'WARNING'], - ], -}; -my $instance_mode; - -my $maps_counters = { - rg => { - '000_status' => { - set => { threshold => 0, - key_values => [ { name => 'status' } ], - closure_custom_calc => \&custom_status_calc, - output_template => 'Status : %s', output_error_template => 'Status : %s', - output_use => 'status', - closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&custom_threshold_output, - } - }, - '001_usage' => { - set => { - key_values => [ { name => 'display' }, { name => 'total' }, { name => 'used' } ], - closure_custom_calc => \&custom_usage_calc, - closure_custom_output => \&custom_usage_output, - closure_custom_perfdata => \&custom_usage_perfdata, - closure_custom_threshold_check => \&custom_usage_threshold, - }, - }, - } -}; +use centreon::plugins::misc; sub custom_threshold_output { my ($self, %options) = @_; - return $instance_mode->get_severity(section => 'rg', value => $self->{result_values}->{status}); + return $self->{instance_mode}->get_severity(section => 'rg', value => $self->{result_values}->{status}); } sub custom_status_calc { @@ -73,22 +41,22 @@ sub custom_status_calc { sub custom_usage_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + nlabel => $self->{nlabel}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -118,61 +86,70 @@ sub custom_usage_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'rg', type => 1, cb_prefix_output => 'prefix_rg_output', message_multiple => 'All raid groups are ok' } + ]; + + $self->{maps_counters}->{rg} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' } ], + closure_custom_calc => $self->can('custom_status_calc'), + output_template => 'Status : %s', output_error_template => 'Status : %s', + output_use => 'status', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_threshold_output'), + } + }, + { label => 'usage', nlabel => 'raidgroup.space.usage.bytes', set => { + key_values => [ { name => 'display' }, { name => 'total' }, { name => 'used' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +sub prefix_rg_output { + my ($self, %options) = @_; + + return "Raid Group '" . $options{instance_value}->{display} . "' "; +} + 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 => - { - "hostname:s" => { name => 'hostname' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "command:s" => { name => 'command', default => 'show' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => 'raid-groups -csv' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "no-component:s" => { name => 'no_component' }, - "filter-name:s" => { name => 'filter_name' }, - "filter-level:s" => { name => 'filter_level' }, - }); - $self->{no_components} = undef; - - foreach my $key (('rg')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "command:s" => { name => 'command', default => 'show' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => 'raid-groups -csv' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + "filter-name:s" => { name => 'filter_name' }, + "filter-level:s" => { name => 'filter_level' }, + }); + return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->SUPER::check_options(%options); if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') { $self->{option_results}->{remote} = 1; } - - foreach my $key (('rg')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - $instance_mode = $self; $self->{overload_th} = {}; foreach my $val (@{$self->{option_results}->{threshold_overload}}) { @@ -188,86 +165,19 @@ sub check_options { $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status}; } - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } -} - -sub run { - my ($self, %options) = @_; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{rg}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All Raid Groups are ok'); - } - - foreach my $id (sort keys %{$self->{rg}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{rg}}) { - my $obj = $maps_counters->{rg}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{rg}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Raid Group '$self->{rg}->{$id}->{display}' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Raid Group '$self->{rg}->{$id}->{display}' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Raid Group '$self->{rg}->{$id}->{display}' $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); } sub manage_selection { my ($self, %options) = @_; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - ssh_pipe => 1, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); + my $stdout = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + ssh_pipe => 1, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options} + ); #[RAID Group No.],[RAID Group Name],[RAID Level],[Assigned CM],[Status],[Total Capacity(MB)],[Free Capacity(MB)] #1,RAIDGROUP001,RAID1+0,CM#0,Spare in Use,134656,132535 @@ -290,17 +200,26 @@ sub manage_selection { next; } - $self->{rg}->{$raid_num} = { status => $raid_status, total => $raid_total * 1024 * 1024, - used => ($raid_total * 1024 * 1024) - ($raid_free * 1024 * 1024), - display => $raid_name }; + $self->{rg}->{$raid_num} = { + status => $raid_status, total => $raid_total * 1024 * 1024, + used => ($raid_total * 1024 * 1024) - ($raid_free * 1024 * 1024), + display => $raid_name + }; } - + if (scalar(keys %{$self->{rg}}) <= 0) { - $self->{output}->output_add(severity => defined($self->{no_components}) ? $self->{no_components} : 'unknown', - short_msg => 'No components are checked.'); + $self->{output}->add_option_msg(short_msg => "No raid group found."); + $self->{output}->option_exit(); } } +my $thresholds = { + rg => [ + ['Available', 'OK'], + ['Spare in Use', 'WARNING'], + ], +}; + sub get_severity { my ($self, %options) = @_; my $status = 'UNKNOWN'; # default @@ -372,10 +291,6 @@ Set to overload default threshold values (syntax: section,status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='rg,CRITICAL,^(?!(Available|Spare)$)' -=item B<--no-component> - -Set the threshold where no components (Default: 'unknown' returns). - =item B<--filter-name> Filter by name (regexp can be used). diff --git a/storage/fujitsu/eternus/dx/ssh/mode/volumestats.pm b/storage/fujitsu/eternus/dx/ssh/mode/volumestats.pm index fef91db88..4a7774eb6 100644 --- a/storage/fujitsu/eternus/dx/ssh/mode/volumestats.pm +++ b/storage/fujitsu/eternus/dx/ssh/mode/volumestats.pm @@ -20,116 +20,118 @@ package storage::fujitsu::eternus::dx::ssh::mode::volumestats; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; +use centreon::plugins::misc; -my $maps_counters = { - vol => { - '000_read-iops' => { - set => { +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'volume', type => 1, cb_prefix_output => 'prefix_volume_output', message_multiple => 'All Volumes are ok' } + ]; + + $self->{maps_counters}->{volume} = [ + { label => 'read-iops', nlabel => 'volume.io.read.usage.iops', set => { key_values => [ { name => 'read_iops' }, { name => 'display' } ], output_template => 'Read IOPS : %d', perfdatas => [ { label => 'read_iops', value => 'read_iops_absolute', template => '%d', unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '001_write-iops' => { - set => { + { label => 'write-iops', nlabel => 'volume.io.write.usage.iops', set => { key_values => [ { name => 'write_iops' }, { name => 'display' } ], output_template => 'Write IOPS : %d', perfdatas => [ { label => 'write_iops', value => 'write_iops_absolute', template => '%d', unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '002_read-traffic' => { - set => { + { label => 'read-traffic', nlabel => 'volume.traffic.read.usage.bitspersecond', set => { key_values => [ { name => 'read_throughput' }, { name => 'display' } ], output_template => 'Read Traffic : %s %s/s', output_change_bytes => 2, perfdatas => [ { label => 'read_throughput', value => 'read_throughput_absolute', template => '%d', unit => 'b/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '003_write-traffic' => { - set => { + { label => 'write-traffic', nlabel => 'volume.traffic.write.usage.bitspersecond', set => { key_values => [ { name => 'write_throughput' }, { name => 'display' } ], output_template => 'Write Traffic : %s %s/s', output_change_bytes => 2, perfdatas => [ { label => 'write_throughput', value => 'write_throughput_absolute', template => '%d', unit => 'b/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '004_read-response-time' => { - set => { + { label => 'read-response-time', nlabel => 'volume.io.read.time.response.milliseconds', set => { key_values => [ { name => 'read_response_time' }, { name => 'display' } ], output_template => 'Read Response Time : %d ms', perfdatas => [ { label => 'read_response_time', value => 'read_response_time_absolute', template => '%d', unit => 'ms', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '005_write-response-time' => { - set => { + { label => 'write-response-time', nlabel => 'volume.io.write.time.response.milliseconds', set => { key_values => [ { name => 'write_response_time' }, { name => 'display' } ], output_template => 'Write Response Time : %d ms', perfdatas => [ { label => 'write_response_time', value => 'write_response_time_absolute', template => '%d', unit => 'ms', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '006_read-processing-time' => { - set => { + { label => 'read-processing-time', nlabel => 'volume.io.read.time.processing.milliseconds', set => { key_values => [ { name => 'read_processing_time' }, { name => 'display' } ], output_template => 'Read Processing Time : %d ms', perfdatas => [ { label => 'read_processing_time', value => 'read_processing_time_absolute', template => '%d', unit => 'ms', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '007_write-processing-time' => { - set => { + { label => 'write-processing-time', nlabel => 'volume.io.write.time.processing.milliseconds', set => { key_values => [ { name => 'write_processing_time' }, { name => 'display' } ], output_template => 'Write Processing Time : %d ms', perfdatas => [ { label => 'write_processing_time', value => 'write_processing_time_absolute', template => '%d', unit => 'ms', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '008_read-cache-hit-rate' => { - set => { + { label => 'read-cache-hit-rate', nlabel => 'volume.io.read.cache.hits.percentage', set => { key_values => [ { name => 'read_cache_hit_rate' }, { name => 'display' } ], output_template => 'Read Cache Hit Rate : %d %%', perfdatas => [ { label => 'read_cache_hit_rate', value => 'read_cache_hit_rate_absolute', template => '%d', unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '009_write-cache-hit-rate' => { - set => { + { label => 'write-cache-hit-rate', nlabel => 'volume.io.write.cache.hits.percentage', set => { key_values => [ { name => 'write_cache_hit_rate' }, { name => 'display' } ], output_template => 'Write Cache Hit Rate : %d %%', perfdatas => [ { label => 'write_cache_hit_rate', value => 'write_cache_hit_rate_absolute', template => '%d', unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - } -}; + ]; +} + +sub prefix_volume_output { + my ($self, %options) = @_; + + return "Volume '" . $options{instance_value}->{display} . "' "; +} sub new { my ($class, %options) = @_; @@ -137,132 +139,41 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "command:s" => { name => 'command', default => 'show' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => ' performance -type host-io' }, - "no-component:s" => { name => 'no_component' }, - "filter-name:s" => { name => 'filter_name' }, - }); - $self->{no_components} = undef; - - foreach my $key (('vol')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "command:s" => { name => 'command', default => 'show' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => ' performance -type host-io' }, + "filter-name:s" => { name => 'filter_name' }, + }); + return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->SUPER::check_options(%options); if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') { $self->{option_results}->{remote} = 1; } - - foreach my $key (('vol')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } -} - -sub run { - my ($self, %options) = @_; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{vol}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All Volumes are ok'); - } - - foreach my $id (sort keys %{$self->{vol}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{vol}}) { - my $obj = $maps_counters->{vol}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{vol}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Volume '$self->{vol}->{$id}->{display}' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Volume '$self->{vol}->{$id}->{display}' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Volume '$self->{vol}->{$id}->{display}' $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); } sub manage_selection { my ($self, %options) = @_; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - ssh_pipe => 1, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); + my $stdout = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + ssh_pipe => 1, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options} + ); #Volume IOPS(IOPS) Throughput(MB/s) Response Time(msec.) Processing Time(msec.) Cache Hit Rate(%) #No. Name Read / Write Read / Write Read / Write Read / Write Read / Write / Prefetch @@ -270,7 +181,7 @@ sub manage_selection { # 1 VOL001 6621 5192 589 379 17055 12056 10025 10010 41 37 36 # 2 VOL002 7791 6608 613 292 12148 11045 10005 10007 41 37 36 - $self->{vol} = {}; + $self->{volume} = {}; my %template_label = (cache_hit_rate => { labels => ['read', 'write', 'prefetch'] }); my @template_values = (); foreach (split /\n/, $stdout) { @@ -307,14 +218,15 @@ sub manage_selection { $counters{read_throughput} *= 1000 * 1000 * 8 if (defined($counters{read_throughput})); $counters{write_throughput} *= 1000 * 1000 * 8 if (defined($counters{write_throughput})); - $self->{vol}->{$matches[0]} = { display => $matches[1], - %counters - }; + $self->{volume}->{$matches[0]} = { + display => $matches[1], + %counters + }; } - if (scalar(keys %{$self->{vol}}) <= 0) { - $self->{output}->output_add(severity => defined($self->{no_components}) ? $self->{no_components} : 'unknown', - short_msg => 'No components are checked.'); + if (scalar(keys %{$self->{volume}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No volume found."); + $self->{output}->option_exit(); } } @@ -361,10 +273,6 @@ Command path (Default: none). Command options (Default: 'performance -type host-io'). -=item B<--no-component> - -Set the threshold where no components (Default: 'unknown' returns). - =item B<--filter-name> Filter by name (regexp can be used). diff --git a/storage/hp/3par/7000/mode/battery.pm b/storage/hp/3par/7000/mode/battery.pm deleted file mode 100644 index e569f9112..000000000 --- a/storage/hp/3par/7000/mode/battery.pm +++ /dev/null @@ -1,157 +0,0 @@ -# -# Copyright 2019 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 storage::hp::3par::7000::mode::battery; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my %states = ( - 'ok' => 'OK', - 'new' => 'OK', - 'degraded' => 'WARNING', - 'failed' => 'CRITICAL', -); - -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 => - { - "hostname:s" => { name => 'hostname' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "no-component:s" => { name => 'no_component' }, - }); - $self->{components} = {}; - $self->{no_components} = undef; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Need to specify a hostname."); - $self->{output}->option_exit(); - } - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } -} - -sub run { - my ($self, %options) = @_; - - $self->{option_results}->{remote} = 1; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => "showbattery", - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - - - my $total_components = 0; - my @batteries = split("\n",$stdout); - foreach my $battery (@batteries) { - if ($battery =~ /\d+\s+(\d+)\s+(\d+)\s+\S+\s+(\S+)\s+(\d+)/) { - $total_components++; - my $psuId = $1; - my $batteryId = $2; - my $batteryState = $3; - my $batteryChrgLvl = $4; - - $self->{output}->output_add(long_msg => sprintf("Battery '%d' on power supply '%d' is '%s' [Battery charge level: '%d%%']", $batteryId, $psuId, $batteryState, $batteryChrgLvl)); - if ($states{lc($batteryState)} ne 'OK'){ - $self->{output}->output_add(severity => $states{lc($batteryState)}, - short_msg => sprintf("Battery '%d' on power supply '%d' state is '%s' [Battery charge level: '%d%%']", $batteryId, $psuId, $batteryState, $batteryChrgLvl)); - } - } - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %d batteries are ok.", $total_components)); - - if (defined($self->{option_results}->{no_component}) && $total_components == 0) { - $self->{output}->output_add(severity => $self->{no_components}, - short_msg => 'No components are checked.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check batteries. - -=over 8 - -=item B<--hostname> - -Hostname to query. - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--ssh-path> - -Specify ssh command path (default: none) - -=item B<--ssh-command> - -Specify ssh command (default: 'ssh'). - -=item B<--sudo> - -Use sudo. - -=item B<--timeout> - -Timeout in seconds for the command (Default: 30). - -=item B<--no-component> - -Return an error if no compenents are checked. -If total (with skipped) is 0. (Default: 'critical' returns). - -=back - -=cut \ No newline at end of file diff --git a/storage/hp/3par/7000/mode/cim.pm b/storage/hp/3par/7000/mode/cim.pm deleted file mode 100644 index 6abbe9c9a..000000000 --- a/storage/hp/3par/7000/mode/cim.pm +++ /dev/null @@ -1,155 +0,0 @@ -# -# Copyright 2019 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 storage::hp::3par::7000::mode::cim; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "no-cim:s" => { name => 'no_cim' }, - }); - $self->{no_cim} = undef; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Need to specify a hostname."); - $self->{output}->option_exit(); - } - - if (defined($self->{option_results}->{no_cim})) { - if ($self->{option_results}->{no_cim} ne '') { - $self->{no_cim} = $self->{option_results}->{no_cim}; - } else { - $self->{no_cim} = 'critical'; - } - } -} - -sub run { - my ($self, %options) = @_; - - $self->{option_results}->{remote} = 1; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => "showcim", - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - - - my @results = split("\n",$stdout); - my $total_cim = 0; - foreach my $result (@results) { - if ($result =~ /(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\S+)\s+(\d+)\s+(\S+)\s+(\d+)\s+\S+/) { - $total_cim++; - my $serviceStatus = $1; - my $serviceState = $2; - my $slpState = $3; - my $slpPort = $4; - my $httpState = $5; - my $httpPort = $6; - my $httpsState = $7; - my $httpsPort = $8; - - $self->{output}->output_add(long_msg => sprintf("CIM service is '%s' and '%s' [SLP on port %d is %s] [HTTP on port %d is %s] [HTTPS on port %d is %s]", - $serviceStatus, $serviceState, $slpPort, $slpState, $httpPort, $httpState, $httpsPort ,$httpsState)); - if ((lc($serviceStatus) ne 'enabled') || (lc($serviceState) ne 'active')){ - $self->{output}->output_add(severity => 'critical', - short_msg => sprintf("CIM service is '%s' and '%s' [SLP on port %d is %s] [HTTP on port %d is %s] [HTTPS on port %d is %s]", - $serviceStatus, $serviceState, $slpPort, $slpState, $httpPort, $httpState, $httpsPort ,$httpsState)); - } - } - } - - $self->{output}->output_add(severity => 'OK', - short_msg => 'CIM service is ok.'); - - if (defined($self->{option_results}->{no_cim}) && $total_cim == 0) { - $self->{output}->output_add(severity => $self->{no_cim}, - short_msg => 'No CIM service is checked.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check CIM service status. - -=over 8 - -=item B<--hostname> - -Hostname to query. - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--ssh-path> - -Specify ssh command path (default: none) - -=item B<--ssh-command> - -Specify ssh command (default: 'ssh'). - -=item B<--sudo> - -Use sudo. - -=item B<--timeout> - -Timeout in seconds for the command (Default: 30). - -=item B<--no-cim> - -Return an error if no CIM are checked. -If total (with skipped) is 0. (Default: 'critical' returns). - -=back - -=cut \ No newline at end of file diff --git a/storage/hp/3par/7000/mode/iscsi.pm b/storage/hp/3par/7000/mode/iscsi.pm deleted file mode 100644 index c947fbe0d..000000000 --- a/storage/hp/3par/7000/mode/iscsi.pm +++ /dev/null @@ -1,156 +0,0 @@ -# -# Copyright 2019 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 storage::hp::3par::7000::mode::iscsi; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my %states = ( - 'ready' => 'OK', - 'loss_sync' => 'WARNING', - 'offline' => 'CRITICAL', -); - -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 => - { - "hostname:s" => { name => 'hostname' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "no-component:s" => { name => 'no_component' }, - }); - $self->{components} = {}; - $self->{no_components} = undef; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Need to specify a hostname."); - $self->{output}->option_exit(); - } - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } -} - -sub run { - my ($self, %options) = @_; - - $self->{option_results}->{remote} = 1; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => "showport", - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - - - my $total_components = 0; - my @iscsis = split("\n",$stdout); - foreach my $iscsi (@iscsis) { - if ($iscsi =~ /(\S+)\s+\S+\s+(\S+)\s+\S+\s+\S+\s+(\S+)/) { - my $iscsiNsp = $1; - my $iscsiState = $2; - my $iscsiType = $3; - if($iscsiType eq 'iscsi') { - $self->{output}->output_add(long_msg => sprintf("Interface '%s' is '%s'", $iscsiNsp, $iscsiState)); - if ($states{lc($iscsiState)} ne 'OK'){ - $self->{output}->output_add(severity => $states{lc($iscsiState)}, - short_msg => sprintf("Interface '%s' is '%s'", $iscsiNsp, $iscsiState)); - } - $total_components++; - } - } - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %d ISCSIs are ok.", $total_components)); - - if (defined($self->{option_results}->{no_component}) && $total_components == 0) { - $self->{output}->output_add(severity => $self->{no_components}, - short_msg => 'No components are checked.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check ISCSIs. - -=over 8 - -=item B<--hostname> - -Hostname to query. - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--ssh-path> - -Specify ssh command path (default: none) - -=item B<--ssh-command> - -Specify ssh command (default: 'ssh'). - -=item B<--sudo> - -Use sudo. - -=item B<--timeout> - -Timeout in seconds for the command (Default: 30). - -=item B<--no-component> - -Return an error if no compenents are checked. -If total (with skipped) is 0. (Default: 'critical' returns). - -=back - -=cut \ No newline at end of file diff --git a/storage/hp/3par/7000/mode/node.pm b/storage/hp/3par/7000/mode/node.pm deleted file mode 100644 index a0e0fb5d5..000000000 --- a/storage/hp/3par/7000/mode/node.pm +++ /dev/null @@ -1,156 +0,0 @@ -# -# Copyright 2019 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 storage::hp::3par::7000::mode::node; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my %states = ( - 'ok' => 'OK', - 'new' => 'OK', - 'degraded' => 'WARNING', - 'failed' => 'CRITICAL', -); - -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 => - { - "hostname:s" => { name => 'hostname' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "no-component:s" => { name => 'no_component' }, - }); - $self->{components} = {}; - $self->{no_components} = undef; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Need to specify a hostname."); - $self->{output}->option_exit(); - } - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } -} - -sub run { - my ($self, %options) = @_; - - $self->{option_results}->{remote} = 1; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => "shownode -s", - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - - - my $total_components = 0; - my @nodes = split("\n",$stdout); - foreach my $node (@nodes) { - if ($node =~ /(\d+)\s+(\S+)\s+(\S+)/) { - $total_components++; - my $nodeId = $1; - my $nodeState = $2; - my $detailNodeState = $3; - - $self->{output}->output_add(long_msg => sprintf("Node '%d' state is '%s' [Detailed State: %s]", $nodeId, $nodeState, $detailNodeState)); - if ($states{lc($nodeState)} ne 'OK'){ - $self->{output}->output_add(severity => $states{lc($nodeState)}, - short_msg => sprintf("Node '%d' state is '%s' [Detailed State: %s]", $nodeId, $nodeState, $detailNodeState)); - } - } - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %d nodes are ok.", $total_components)); - - if (defined($self->{option_results}->{no_component}) && $total_components == 0) { - $self->{output}->output_add(severity => $self->{no_components}, - short_msg => 'No components are checked.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check nodes. - -=over 8 - -=item B<--hostname> - -Hostname to query. - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--ssh-path> - -Specify ssh command path (default: none) - -=item B<--ssh-command> - -Specify ssh command (default: 'ssh'). - -=item B<--sudo> - -Use sudo. - -=item B<--timeout> - -Timeout in seconds for the command (Default: 30). - -=item B<--no-component> - -Return an error if no compenents are checked. -If total (with skipped) is 0. (Default: 'critical' returns). - -=back - -=cut \ No newline at end of file diff --git a/storage/hp/3par/7000/mode/physicaldisk.pm b/storage/hp/3par/7000/mode/physicaldisk.pm deleted file mode 100644 index 4cece31c1..000000000 --- a/storage/hp/3par/7000/mode/physicaldisk.pm +++ /dev/null @@ -1,155 +0,0 @@ -# -# Copyright 2019 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 storage::hp::3par::7000::mode::physicaldisk; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my %states = ( - 'normal' => 'OK', - 'new' => 'OK', - 'degraded' => 'WARNING', - 'failed' => 'CRITICAL', -); - -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 => - { - "hostname:s" => { name => 'hostname' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "no-component:s" => { name => 'no_component' }, - }); - $self->{components} = {}; - $self->{no_components} = undef; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Need to specify a hostname."); - $self->{output}->option_exit(); - } - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } -} - -sub run { - my ($self, %options) = @_; - - $self->{option_results}->{remote} = 1; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => "showpd -showcols Id,State", - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - - - my $total_components = 0; - my @disks = split("\n",$stdout); - foreach my $disk (@disks) { - if ($disk =~ /(\d+)\s+(\S+)/) { - $total_components++; - my $diskId = $1; - my $diskState = $2; - - $self->{output}->output_add(long_msg => sprintf("Physical Disk '%d' state is '%s'", $diskId, $diskState)); - if ($states{$diskState} ne 'OK'){ - $self->{output}->output_add(severity => $states{$diskState}, - short_msg => sprintf("Physical Disk '%d' state is '%s'.", $diskId, $diskState)); - } - } - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %d physical disks are ok.", $total_components)); - - if (defined($self->{option_results}->{no_component}) && $total_components == 0) { - $self->{output}->output_add(severity => $self->{no_components}, - short_msg => 'No components are checked.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check Physical disks. - -=over 8 - -=item B<--hostname> - -Hostname to query. - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--ssh-path> - -Specify ssh command path (default: none) - -=item B<--ssh-command> - -Specify ssh command (default: 'ssh'). - -=item B<--sudo> - -Use sudo. - -=item B<--timeout> - -Timeout in seconds for the command (Default: 30). - -=item B<--no-component> - -Return an error if no compenents are checked. -If total (with skipped) is 0. (Default: 'critical' returns). - -=back - -=cut \ No newline at end of file diff --git a/storage/hp/3par/7000/mode/psu.pm b/storage/hp/3par/7000/mode/psu.pm deleted file mode 100644 index 6217aa352..000000000 --- a/storage/hp/3par/7000/mode/psu.pm +++ /dev/null @@ -1,157 +0,0 @@ -# -# Copyright 2019 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 storage::hp::3par::7000::mode::psu; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my %states = ( - 'ok' => 'OK', - 'new' => 'OK', - 'degraded' => 'WARNING', - 'failed' => 'CRITICAL', -); - -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 => - { - "hostname:s" => { name => 'hostname' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "no-component:s" => { name => 'no_component' }, - }); - $self->{components} = {}; - $self->{no_components} = undef; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Need to specify a hostname."); - $self->{output}->option_exit(); - } - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } -} - -sub run { - my ($self, %options) = @_; - - $self->{option_results}->{remote} = 1; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => "shownode -ps", - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - - - my $total_components = 0; - my @psus = split("\n",$stdout); - foreach my $psu (@psus) { - if ($psu =~ /\S+\s+(\d+)\s+\S+\s+\S+\s+(\S+)\s+(\S+)\s+(\S+)/) { - $total_components++; - my $psuId = $1; - my $ACState = $2; - my $DCState = $3; - my $psuState = $4; - - $self->{output}->output_add(long_msg => sprintf("Power Suppply '%d' state is '%s' [AC: %s] [DC: %s]", $psuId, $psuState, $ACState ,$DCState)); - if ($states{lc($psuState)} ne 'OK'){ - $self->{output}->output_add(severity => $states{lc($psuState)}, - short_msg => sprintf("Power Suppply '%d' state is '%s' [AC: %s] [DC: %s]", $psuId, $psuState, $ACState ,$DCState)); - } - } - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %d power supplies are ok.", $total_components)); - - if (defined($self->{option_results}->{no_component}) && $total_components == 0) { - $self->{output}->output_add(severity => $self->{no_components}, - short_msg => 'No components are checked.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check power supplies. - -=over 8 - -=item B<--hostname> - -Hostname to query. - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--ssh-path> - -Specify ssh command path (default: none) - -=item B<--ssh-command> - -Specify ssh command (default: 'ssh'). - -=item B<--sudo> - -Use sudo. - -=item B<--timeout> - -Timeout in seconds for the command (Default: 30). - -=item B<--no-component> - -Return an error if no compenents are checked. -If total (with skipped) is 0. (Default: 'critical' returns). - -=back - -=cut \ No newline at end of file diff --git a/storage/hp/3par/7000/mode/storage.pm b/storage/hp/3par/7000/mode/storage.pm deleted file mode 100644 index 9ff5c9d18..000000000 --- a/storage/hp/3par/7000/mode/storage.pm +++ /dev/null @@ -1,172 +0,0 @@ -# -# Copyright 2019 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 storage::hp::3par::7000::mode::storage; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "filter-type:s" => { name => 'filter_type' }, - "disk:s" => { name => 'disk' }, - "regexp" => { name => 'regexp' }, - }); - $self->{components} = {}; - $self->{no_components} = undef; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Need to specify a hostname."); - $self->{output}->option_exit(); - } - - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } -} - -sub run { - my ($self, %options) = @_; - - $self->{option_results}->{remote} = 1; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => "showpd", - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - - - my $total_disks = 0; - my @disks = split("\n",$stdout); - foreach my $disk (@disks) { - if ($disk =~ /(\d+)\s+\S+\s+(\S+)\s+\d+\s+\S+\s+(\d+)\s+(\d+)\s+\S+\s+\S+\s+\d+/) { - $total_disks++; - my $diskId = $1; - my $diskType = $2; - my $diskSize = $3 * 1024 * 1024; - my $diskFree = $4 * 1024 * 1024; - my $diskUsed = $diskSize - $diskFree; - my $percentUsed = ($diskUsed / $diskSize) * 100; - my $percentFree = ($diskFree / $diskSize) * 100; - - next if (defined($self->{option_results}->{filter_type}) && ($diskType !~ /$self->{option_results}->{filter_type}/i)); - next if (defined($self->{option_results}->{disk}) && defined($self->{option_results}->{regexp}) && ($diskId !~ /$self->{option_results}->{disk}/i)); - next if (defined($self->{option_results}->{disk}) && !defined($self->{option_results}->{regexp}) && ($diskId != $self->{option_results}->{disk})); - - my ($diskSizeValue, $diskSizeUnit) = $self->{perfdata}->change_bytes(value => $diskSize); - my ($diskUsedValue, $diskUsedUnit) = $self->{perfdata}->change_bytes(value => $diskUsed); - my ($diskFreeValue, $diskFreeUnit) = $self->{perfdata}->change_bytes(value => $diskFree); - - $self->{output}->output_add(long_msg => sprintf("Disk '%d' Total: %.2f%s Used: %.2f%s (%.2f%%) Free: %.2f%s (%.2f%%)", - $diskId, $diskSizeValue, $diskSizeUnit, $diskUsedValue, $diskUsedUnit, $percentUsed, $diskFreeValue, $diskFreeUnit, $percentFree)); - my $exit = $self->{perfdata}->threshold_check(value => $percentUsed, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Disk '%d' Total: %.2f%s Used: %.2f%s (%.2f%%) Free: %.2f%s (%.2f%%)", - $diskId, $diskSizeValue, $diskSizeUnit, $diskUsedValue, $diskUsedUnit, $percentUsed, $diskFreeValue, $diskFreeUnit, $percentFree)); - } - $self->{output}->perfdata_add(label => 'disk_'.$diskId, - unit => 'B', - value => $diskUsed, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $diskSize, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $diskSize, cast_int => 1), - min => 0, - max => $diskSize); - } - } - - $self->{output}->output_add(severity => 'OK', - short_msg => 'All disks are ok.'); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check Physical disks. - -=over 8 - -=item B<--hostname> - -Hostname to query. - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--ssh-path> - -Specify ssh command path (default: none) - -=item B<--ssh-command> - -Specify ssh command (default: 'ssh'). - -=item B<--sudo> - -Use sudo. - -=item B<--timeout> - -Timeout in seconds for the command (Default: 30). - -=item B<--no-component> - -Return an error if no compenents are checked. -If total (with skipped) is 0. (Default: 'critical' returns). - -=back - -=cut \ No newline at end of file diff --git a/storage/hp/3par/7000/mode/temperature.pm b/storage/hp/3par/7000/mode/temperature.pm deleted file mode 100644 index 0c64f2c66..000000000 --- a/storage/hp/3par/7000/mode/temperature.pm +++ /dev/null @@ -1,167 +0,0 @@ -# -# Copyright 2019 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 storage::hp::3par::7000::mode::temperature; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "no-component:s" => { name => 'no_component' }, - "sensor:s" => { name => 'sensor' }, - "regexp" => { name => 'regexp' }, - }); - $self->{components} = {}; - $self->{no_components} = undef; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Need to specify a hostname."); - $self->{output}->option_exit(); - } - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } -} - -sub run { - my ($self, %options) = @_; - - $self->{option_results}->{remote} = 1; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => "shownodeenv", - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - - - my $total_components = 0; - my $nodeID = 0; - my @temperatures = split(/\n/,$stdout); - foreach my $temperature (@temperatures) { - if ($temperature =~ /^Node\s(\d+)$/) { - $nodeID = $1; - } - if ($temperature =~ /^(.+)\s(\d+)\sC\s+(\d+)\sC\s+(\d+)/) { - my $measurement = $1; - my $readTemp = $2; - my $loTemp = $3; - my $hiTemp= $4; - $measurement =~ s/^\s+//; - $measurement =~ s/\s+$//; - $total_components++; - - next if (defined($self->{option_results}->{sensor}) && defined($self->{option_results}->{regexp}) && ($measurement !~ /$self->{option_results}->{sensor}/i)); - next if (defined($self->{option_results}->{sensor}) && !defined($self->{option_results}->{regexp}) && ($measurement != $self->{option_results}->{sensor})); - - $self->{output}->output_add(long_msg => sprintf("Temperature '%s' on node '%d' is '%dC' [Max temperature: '%dC'] [Min temperature: '%dC'", $measurement, $nodeID, $readTemp, $hiTemp, $loTemp)); - if (($readTemp > $hiTemp) || ($readTemp < $loTemp)){ - $self->{output}->output_add(severity => 'critical', - short_msg => sprintf("Temperature '%s' on node '%d' is '%dC' [Max temperature: '%dC'] [Min temperature: '%dC'", $measurement, $nodeID, $readTemp, $hiTemp, $loTemp)); - } - $self->{output}->perfdata_add(label => $measurement.'_temperature', - unit => 'C', - value => $readTemp); - } - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %d temperatures are ok.", $total_components)); - - if (defined($self->{option_results}->{no_component}) && $total_components == 0) { - $self->{output}->output_add(severity => $self->{no_components}, - short_msg => 'No components are checked.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check temperature. - -=over 8 - -=item B<--hostname> - -Hostname to query. - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--ssh-path> - -Specify ssh command path (default: none) - -=item B<--ssh-command> - -Specify ssh command (default: 'ssh'). - -=item B<--sudo> - -Use sudo. - -=item B<--timeout> - -Timeout in seconds for the command (Default: 30). - -=item B<--no-component> - -Return an error if no compenents are checked. -If total (with skipped) is 0. (Default: 'critical' returns). - -=back - -=cut - - diff --git a/storage/hp/3par/7000/mode/volume.pm b/storage/hp/3par/7000/mode/volume.pm deleted file mode 100644 index 583c28eb6..000000000 --- a/storage/hp/3par/7000/mode/volume.pm +++ /dev/null @@ -1,201 +0,0 @@ -# -# Copyright 2019 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 storage::hp::3par::7000::mode::volume; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "filter-type:s" => { name => 'filter_type' }, - "volume:s" => { name => 'volume' }, - "name" => { name => 'name' }, - "regexp" => { name => 'regexp' }, - }); - $self->{components} = {}; - $self->{no_components} = undef; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Need to specify a hostname."); - $self->{output}->option_exit(); - } - - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } -} - -sub run { - my ($self, %options) = @_; - - $self->{option_results}->{remote} = 1; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => "showvv -showcols Id,Name,VSize_MB,Snp_Rsvd_MB,Snp_Used_MB,Adm_Rsvd_MB,Adm_Used_MB,Usr_Rsvd_MB,Usr_Used_MB", - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - - - my $total_volumes = 0; - my @volumes = split("\n",$stdout); - foreach my $volume (@volumes) { - if ($volume =~ /(\d+)\s+(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/) { - $total_volumes++; - my $volumeId = $1; - my $volumeName = $2; - my $volumeSize = $3 * 1024 * 1024; - my $volumeSnpSize = $4 * 1024 * 1024; - my $volumeSnpUsed = $5 * 1024 * 1024; - my $volumeAdmSize = $6 * 1024 * 1024; - my $volumeAdmUsed = $7 * 1024 * 1024; - my $volumeUsrSize = $8 * 1024 * 1024; - my $volumeUsrUsed = $9 * 1024 * 1024; - my $volumeUsed = $volumeSnpUsed + $volumeAdmUsed + $volumeUsrUsed; - my $volumeFree = $volumeSize - $volumeUsed; - my $percentUsed = ($volumeUsed / $volumeSize) * 100; - my $percentFree = 100 - $percentUsed; - - my $string_to_compare = $volumeId; - if (defined($self->{option_results}->{name})) { - $string_to_compare = $volumeName; - } - - next if (defined($self->{option_results}->{volume}) && defined($self->{option_results}->{regexp}) && ($string_to_compare !~ /$self->{option_results}->{volume}/i)); - next if (defined($self->{option_results}->{volume}) && !defined($self->{option_results}->{regexp}) && ($string_to_compare ne $self->{option_results}->{volume})); - - my ($volumeSizeValue, $volumeSizeUnit) = $self->{perfdata}->change_bytes(value => $volumeSize); - my ($volumeUsedValue, $volumeUsedUnit) = $self->{perfdata}->change_bytes(value => $volumeUsed); - my ($volumeFreeValue, $volumeFreeUnit) = $self->{perfdata}->change_bytes(value => $volumeFree); - my ($volumeSnpSizeValue, $volumeSnpSizeUnit) = $self->{perfdata}->change_bytes(value => $volumeSnpSize); - my ($volumeSnpUsedValue, $volumeSnpUsedUnit) = $self->{perfdata}->change_bytes(value => $volumeSnpUsed); - my ($volumeAdmSizeValue, $volumeAdmSizeUnit) = $self->{perfdata}->change_bytes(value => $volumeAdmSize); - my ($volumeAdmUsedValue, $volumeAdmUsedUnit) = $self->{perfdata}->change_bytes(value => $volumeAdmUsed); - my ($volumeUsrSizeValue, $volumeUsrSizeUnit) = $self->{perfdata}->change_bytes(value => $volumeUsrSize); - my ($volumeUsrUsedValue, $volumeUsrUsedUnit) = $self->{perfdata}->change_bytes(value => $volumeUsrUsed); - - $self->{output}->output_add(long_msg => sprintf("Volume %d '%s' Total: %.2f%s Used: %.2f%s (%.2f%%) Free: %.2f%s (%.2f%%) Usr: %.2f%s Adm: %.2f%s Snp: %.2f%s", - $volumeId, $volumeName, $volumeSizeValue, $volumeSizeUnit, - $volumeUsedValue, $volumeUsedUnit, $percentUsed, - $volumeFreeValue, $volumeFreeUnit, $percentFree, - $volumeUsrUsedValue, $volumeUsrUsedUnit, - $volumeAdmUsedValue, $volumeAdmUsedUnit, - $volumeSnpUsedValue, $volumeSnpUsedUnit,)); - my $exit = $self->{perfdata}->threshold_check(value => $percentUsed, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Volume %d '%s' Total: %.2f%s Used: %.2f%s (%.2f%%) Free: %.2f%s (%.2f%%) Usr: %.2f%s Adm: %.2f%s Snp: %.2f%s", - $volumeId, $volumeName, $volumeSizeValue, $volumeSizeUnit, - $volumeUsedValue, $volumeUsedUnit, $percentUsed, - $volumeFreeValue, $volumeFreeUnit, $percentFree, - $volumeUsrUsedValue, $volumeUsrUsedUnit, - $volumeAdmUsedValue, $volumeAdmUsedUnit, - $volumeSnpUsedValue, $volumeSnpUsedUnit,)); - } - $self->{output}->perfdata_add(label => 'volume_'.$volumeName, - unit => 'B', - value => $volumeUsed, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $volumeSize, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $volumeSize, cast_int => 1), - min => 0, - max => $volumeSize); - } - } - - $self->{output}->output_add(severity => 'OK', - short_msg => 'All volumes are ok.'); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check Physical disks. - -=over 8 - -=item B<--hostname> - -Hostname to query. - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--ssh-path> - -Specify ssh command path (default: none) - -=item B<--ssh-command> - -Specify ssh command (default: 'ssh'). - -=item B<--sudo> - -Use sudo. - -=item B<--timeout> - -Timeout in seconds for the command (Default: 30). - -=item B<--no-component> - -Return an error if no compenents are checked. -If total (with skipped) is 0. (Default: 'critical' returns). - -=back - -=cut - - diff --git a/storage/hp/3par/7000/mode/wsapi.pm b/storage/hp/3par/7000/mode/wsapi.pm deleted file mode 100644 index 0933b849f..000000000 --- a/storage/hp/3par/7000/mode/wsapi.pm +++ /dev/null @@ -1,153 +0,0 @@ -# -# Copyright 2019 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 storage::hp::3par::7000::mode::wsapi; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "no-wsapi:s" => { name => 'no_wsapi' }, - }); - $self->{no_wsapi} = undef; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Need to specify a hostname."); - $self->{output}->option_exit(); - } - - if (defined($self->{option_results}->{no_wsapi})) { - if ($self->{option_results}->{no_wsapi} ne '') { - $self->{no_wsapi} = $self->{option_results}->{no_wsapi}; - } else { - $self->{no_wsapi} = 'critical'; - } - } -} - -sub run { - my ($self, %options) = @_; - - $self->{option_results}->{remote} = 1; - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - sudo => $self->{option_results}->{sudo}, - command => "showwsapi", - command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - - - my @results = split("\n",$stdout); - my $total_wsapi = 0; - foreach my $result (@results) { - if ($result =~ /(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\S+)\s+(\d+)\s+\S+/) { - $total_wsapi++; - my $serviceStatus = $1; - my $serviceState = $2; - my $httpState = $3; - my $httpPort = $4; - my $httpsState = $5; - my $httpsPort = $6; - - $self->{output}->output_add(long_msg => sprintf("WSAPI service is '%s' and '%s' [HTTP on port %d is %s] [HTTPS on port %d is %s]", - $serviceStatus, $serviceState, $httpPort, $httpState, $httpsPort ,$httpsState)); - if ((lc($serviceStatus) ne 'enabled') || (lc($serviceState) ne 'active')){ - $self->{output}->output_add(severity => 'critical', - short_msg => sprintf("WSAPI service is '%s' and '%s' [HTTP on port %d is %s] [HTTPS on port %d is %s]", - $serviceStatus, $serviceState, $httpPort, $httpState, $httpsPort ,$httpsState)); - } - } - } - - $self->{output}->output_add(severity => 'OK', - short_msg => 'WSAPI service is ok.'); - - if (defined($self->{option_results}->{no_wsapi}) && $total_wsapi == 0) { - $self->{output}->output_add(severity => $self->{no_wsapi}, - short_msg => 'No WSAPI service is checked.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check WSAPI service status. - -=over 8 - -=item B<--hostname> - -Hostname to query. - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--ssh-path> - -Specify ssh command path (default: none) - -=item B<--ssh-command> - -Specify ssh command (default: 'ssh'). - -=item B<--sudo> - -Use sudo. - -=item B<--timeout> - -Timeout in seconds for the command (Default: 30). - -=item B<--no-wsapi> - -Return an error if no WSAPI are checked. -If total (with skipped) is 0. (Default: 'critical' returns). - -=back - -=cut \ No newline at end of file diff --git a/storage/hp/3par/ssh/custom/custom.pm b/storage/hp/3par/ssh/custom/custom.pm new file mode 100644 index 000000000..aa0b39945 --- /dev/null +++ b/storage/hp/3par/ssh/custom/custom.pm @@ -0,0 +1,173 @@ +# +# Copyright 2019 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 storage::hp::3par::ssh::custom::custom; + +use strict; +use warnings; +use centreon::plugins::misc; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => { + 'hostname:s' => { name => 'hostname' }, + 'ssh-option:s@' => { name => 'ssh_option' }, + 'ssh-path:s' => { name => 'ssh_path' }, + 'ssh-command:s' => { name => 'ssh_command', default => 'ssh' }, + 'timeout:s' => { name => 'timeout', default => 45 }, + 'command:s' => { name => 'command' }, + 'command-path:s' => { name => 'command_path' }, + 'command-options:s' => { name => 'command_options' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'SSH OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + + $self->{option_results}->{remote} = 1; + if (defined($self->{option_results}->{command}) && $self->{option_results}->{command} ne '') { + $self->{option_results}->{remote} = undef; + } elsif (!defined($self->{option_results}->{hostname}) || $self->{option_results}->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to set hostname option."); + $self->{output}->option_exit(); + } + + return 0; +} + +############## +# Specific methods +############## +sub execute_command { + my ($self, %options) = @_; + + $self->{ssh_commands} = ''; + my $append = ''; + foreach (@{$options{commands}}) { + $self->{ssh_commands} .= $append . " $_"; + $append = ';'; + } + + return centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + command => defined($self->{option_results}->{command}) && $self->{option_results}->{command} ne '' ? $self->{option_results}->{command} : $self->{ssh_commands} . "; exit\n", + command_path => $self->{option_results}->{command_path}, + command_options => defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne '' ? $self->{option_results}->{command_options} : undef + ); +} + +1; + +__END__ + +=head1 NAME + +ssh + +=head1 SYNOPSIS + +my ssh + +=head1 SSH OPTIONS + +=over 8 + +=item B<--hostname> + +Hostname to query. + +=item B<--ssh-option> + +Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). + +=item B<--ssh-path> + +Specify ssh command path (default: none) + +=item B<--ssh-command> + +Specify ssh command (default: 'ssh'). Useful to use 'plink'. + +=item B<--timeout> + +Timeout in seconds for the command (Default: 45). + +=item B<--command> + +Command to get information. Used it you have output in a file. + +=item B<--command-path> + +Command path. + +=item B<--command-options> + +Command options. + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/storage/hp/3par/ssh/mode/components/battery.pm b/storage/hp/3par/ssh/mode/components/battery.pm new file mode 100644 index 000000000..9c819f7e2 --- /dev/null +++ b/storage/hp/3par/ssh/mode/components/battery.pm @@ -0,0 +1,83 @@ +# +# Copyright 2019 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 storage::hp::3par::ssh::mode::components::battery; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + +# Node PS Bat Assem_Serial -State- ChrgLvl(%) -ExpDate- Expired Testing +# 0,1 0 0 6CQUBA1HN5065R OK 100 n/a No No +# 0,1 1 0 6CQUBA1HN5063G OK 100 n/a No No +# 2,3 0 0 6CQUBA1HN484RB OK 100 n/a No No +# 2,3 1 0 6CQUBA1HN484R9 OK 100 n/a No No + push @{$self->{commands}}, 'echo "===showbattery===', 'showbattery'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking batteries"); + $self->{components}->{battery} = { name => 'batteries', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'battery')); + + return if ($self->{results} !~ /===showbattery===.*?\n(.*?)(===|\Z)/msi); + my @results = split /\n/, $1; + + foreach (@results) { + next if (!/^\s*\S+\s+(\d+)\s+(\d+)\s+\S+\s+(\S+)\s+(\d+)/); + my ($psu_id, $battery_id, $battery_state, $battery_chrg_lvl) = ($1, $2, $3, $4); + my $instance = $psu_id . '.' . $battery_id; + + next if ($self->check_filter(section => 'battery', instance => $instance)); + $self->{components}->{battery}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("battery '%s' on power supply '%s' status is '%s' [instance: %s, charge level: %d%%]", + $psu_id, $battery_id, $battery_state, $instance, $battery_chrg_lvl) + ); + my $exit = $self->get_severity(label => 'default', section => 'battery', value => $battery_state); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Battery '%s' on power supply '%s' status is '%s'", + $psu_id, $battery_id, $battery_state, $instance)); + } + + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'battery.charge', instance => $instance, value => $battery_chrg_lvl); + + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Battery '%s' on power supply '%s' charge level is %s %%", $psu_id, $battery_id, $battery_chrg_lvl)); + } + $self->{output}->perfdata_add( + label => 'battery_charge', unit => '%', + nlabel => 'hardware.battery.charge.percentage', + instances => ['psu' . $psu_id, 'battery' . $battery_id], + value => $battery_chrg_lvl, + warning => $warn, + critical => $crit, + min => 0, max => 100, + ); + } +} + +1; diff --git a/storage/hp/3par/ssh/mode/components/cim.pm b/storage/hp/3par/ssh/mode/components/cim.pm new file mode 100644 index 000000000..7187b63d5 --- /dev/null +++ b/storage/hp/3par/ssh/mode/components/cim.pm @@ -0,0 +1,73 @@ +# +# Copyright 2019 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 storage::hp::3par::ssh::mode::components::cim; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + #-Service- -State- --SLP-- SLPPort -HTTP-- HTTPPort -HTTPS- HTTPSPort PGVer CIMVer + #Enabled Active Enabled 427 Enabled 5988 Enabled 5989 2.9.1 3.2.2 + push @{$self->{commands}}, 'echo "===showcim===', 'showcim'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking cim"); + $self->{components}->{cim} = { name => 'cim', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'cim')); + + return if ($self->{results} !~ /===showcim===.*?\n(.*?)(===|\Z)/msi); + my @results = split /\n/, $1; + + my $instance = 0; + foreach (@results) { + next if (!/^(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\S+)\s+(\d+)\s+(\S+)\s+(\d+)\s+\S+/); + $instance++; + my ($service_status, $service_state, $slp_state, $slp_port, $http_state, + $http_port, $https_state, $https_port) = ($1, $2, $3, $4, $5, $6, $7, $8); + + next if ($self->check_filter(section => 'cim', instance => $instance)); + $self->{components}->{cim}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("cim service state is '%s' [status: '%s'] [SLP on port %d is %s] [HTTP on port %d is %s] [HTTPS on port %d is %s] [instance: %s]", + $service_state, $service_status, $slp_port, $slp_state, $http_port, $http_state, $https_port ,$https_state, $instance) + ); + my $exit = $self->get_severity(label => 'default.state', section => 'cim.state', value => $service_state); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("cim service state is '%s' [instance: %s]", + $service_state, $instance)); + } + + $exit = $self->get_severity(label => 'default.status', section => 'cim.status', value => $service_status); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("cim service status is '%s' [instance: %s]", + $service_status, $instance)); + } + } +} + +1; diff --git a/storage/hp/3par/ssh/mode/components/disk.pm b/storage/hp/3par/ssh/mode/components/disk.pm new file mode 100644 index 000000000..5fc080bff --- /dev/null +++ b/storage/hp/3par/ssh/mode/components/disk.pm @@ -0,0 +1,68 @@ +# +# Copyright 2019 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 storage::hp::3par::ssh::mode::components::disk; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + # Id State + # 0 normal + # 1 normal + # 2 normal + #... + # 10 normal + # 11 normal + push @{$self->{commands}}, 'echo "===showdisk===', 'showpd -showcols Id,State'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking disks"); + $self->{components}->{disk} = { name => 'disks', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'disk')); + + return if ($self->{results} !~ /===showdisk===.*?\n(.*?)(===|\Z)/msi); + my @results = split /\n/, $1; + + foreach (@results) { + next if (!/^\s*(\d+)\s+(\S+)/); + my ($instance, $state) = ($1, $2); + + next if ($self->check_filter(section => 'disk', instance => $instance)); + $self->{components}->{disk}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("disk '%s' state is '%s' [instance: '%s']", + $instance, $state, $instance) + ); + my $exit = $self->get_severity(label => 'default', section => 'disk', value => $state); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Disk '%s' state is '%s'", + $instance, $state)); + } + } +} + +1; diff --git a/storage/hp/3par/ssh/mode/components/node.pm b/storage/hp/3par/ssh/mode/components/node.pm new file mode 100644 index 000000000..e5275fccc --- /dev/null +++ b/storage/hp/3par/ssh/mode/components/node.pm @@ -0,0 +1,66 @@ +# +# Copyright 2019 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 storage::hp::3par::ssh::mode::components::node; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + #Node -State- -Detailed_State- + #0 OK OK + #1 OK OK + #2 OK OK + #3 OK OK + push @{$self->{commands}}, 'echo "===shownode===', 'shownode -state'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking nodes"); + $self->{components}->{node} = { name => 'nodes', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'node')); + + return if ($self->{results} !~ /===shownode===.*?\n(.*?)(===|\Z)/msi); + my @results = split /\n/, $1; + + foreach (@results) { + next if (!/^\s*(\d+)\s+(\S+)\s+(\S+)/); + my ($instance, $state, $detail_state) = ($1, $2, $3); + + next if ($self->check_filter(section => 'node', instance => $instance)); + $self->{components}->{node}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("node '%s' state is '%s' [instance: '%s'] [detailed state: %s]", + $instance, $state, $instance, $detail_state) + ); + my $exit = $self->get_severity(label => 'default', section => 'node', value => $state); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Node '%s' state is '%s'", + $instance, $state)); + } + } +} + +1; diff --git a/storage/hp/3par/ssh/mode/components/port.pm b/storage/hp/3par/ssh/mode/components/port.pm new file mode 100644 index 000000000..3d4d759d0 --- /dev/null +++ b/storage/hp/3par/ssh/mode/components/port.pm @@ -0,0 +1,74 @@ +# +# Copyright 2019 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 storage::hp::3par::ssh::mode::components::port; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + #N:S:P Mode State ----Node_WWN---- -Port_WWN/HW_Addr- Type Protocol Label Partner FailoverState + #0:0:1 initiator ready 50002ACFF70047C0 50002AC0010047C0 disk SAS DP-1 - - + #0:0:2 initiator ready 50002ACFF70047C0 50002AC0020047C0 disk SAS DP-2 - - + #0:1:1 target ready 2FF70002AC0047C0 20110002AC0047C0 host FC - 1:1:1 none + #0:1:2 target ready 2FF70002AC0047C0 20120002AC0047C0 host FC - 1:1:2 none + #0:2:1 initiator ready 2FF70002AC0047C0 20210002AC0047C0 rcfc FC - - - + #0:2:2 target ready 2FF70002AC0047C0 20220002AC0047C0 host FC - - - + #0:2:3 target ready 2FF70002AC0047C0 20230002AC0047C0 host FC - 1:2:3 none + #0:2:4 target ready 2FF70002AC0047C0 20240002AC0047C0 host FC - 1:2:4 none + #0:3:1 peer offline - B4B52FA71D43 free IP IP0 - - + #1:0:1 initiator ready 50002ACFF70047C0 50002AC1010047C0 disk SAS DP-1 - - + #1:0:2 initiator ready 50002ACFF70047C0 50002AC1020047C0 disk SAS DP-2 - - + push @{$self->{commands}}, 'echo "===showport===', 'showport'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking ports"); + $self->{components}->{port} = { name => 'ports', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'port')); + + return if ($self->{results} !~ /===showport===.*?\n(.*?)(===|\Z)/msi); + my @results = split /\n/, $1; + + foreach (@results) { + next if (!/^(\d+:\d+:\d+)\s+\S+\s+(\S+)\s+\S+\s+\S+\s+(\S+)/); + my ($nsp, $state, $type) = ($1, $2, $3); + my $instance = $type . '.' . $nsp; + + next if ($self->check_filter(section => 'port', instance => $instance)); + $self->{components}->{port}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("port '%s' state is '%s' [instance: '%s']", + $nsp, $state, $instance) + ); + my $exit = $self->get_severity(section => 'port', value => $state); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("port '%s' state is '%s'", + $nsp, $state)); + } + } +} + +1; diff --git a/storage/hp/3par/ssh/mode/components/psu.pm b/storage/hp/3par/ssh/mode/components/psu.pm new file mode 100644 index 000000000..c1295eca9 --- /dev/null +++ b/storage/hp/3par/ssh/mode/components/psu.pm @@ -0,0 +1,66 @@ +# +# Copyright 2019 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 storage::hp::3par::ssh::mode::components::psu; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + #Node PS -Assem_Part- -Assem_Serial- ACState DCState PSState + # 0,1 0 682372-001 5CQLQA1433H0B8 OK OK OK + # 0,1 1 682372-001 5CQLQA1434W2ED OK OK OK + # 2,3 0 682372-001 5CQLQA1433Y0KS OK OK OK + # 2,3 1 682372-001 5CQLQX1XX3E056 OK OK OK + push @{$self->{commands}}, 'echo "===showpsu===', 'shownode -ps'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + $self->{components}->{psu} = { name => 'psus', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'psu')); + + return if ($self->{results} !~ /===showpsu===.*?\n(.*?)(===|\Z)/msi); + my @results = split /\n/, $1; + + foreach (@results) { + next if (!/^\s*(\S+)\s+(\d+)\s+\S+\s+\S+\s+(\S+)\s+(\S+)\s+(\S+)/); + my ($instance, $ac_state, $dc_state, $psu_state) = ('node' . $1 . '.psu' . $2, $3, $4, $5); + + next if ($self->check_filter(section => 'psu', instance => $instance)); + $self->{components}->{psu}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("power supply '%s' state is '%s' [instance: '%s'] [ac state: %s] [dc state: %s]", + $instance, $psu_state, $instance, $ac_state, $dc_state) + ); + my $exit = $self->get_severity(label => 'default', section => 'psu', value => $psu_state); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Power supply '%s' state is '%s'", + $instance, $psu_state)); + } + } +} + +1; diff --git a/storage/hp/3par/ssh/mode/components/sensor.pm b/storage/hp/3par/ssh/mode/components/sensor.pm new file mode 100644 index 000000000..3e41af3d8 --- /dev/null +++ b/storage/hp/3par/ssh/mode/components/sensor.pm @@ -0,0 +1,113 @@ +# +# Copyright 2019 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 storage::hp::3par::ssh::mode::components::sensor; + +use strict; +use warnings; +use centreon::plugins::misc; + +sub load { + my ($self) = @_; + + #Node 0 + #--------- + # + #------Measurement------ -Reading- -Lo_Limit- -Hi_Limit- -----Status----- + # Ambient 21 C 5 C 40 C Within Tolerance + # Midplane 23 C 10 C 50 C Within Tolerance + # PCM 0 inlet 27 C 10 C 50 C Within Tolerance + # SBB Canister 1 memory 42 C 5 C 82 C Within Tolerance + # PCM 0 (5V) 5.19 V --- --- Within Tolerance + # PCM 0 (40A Max) 2.77 A --- --- Within Tolerance + # + #Node 1 + #--------- + # + #------Measurement------ -Reading- -Lo_Limit- -Hi_Limit- -----Status----- + # Ambient 21 C 5 C 40 C Within Tolerance + # Midplane 23 C 10 C 50 C Within Tolerance + # PCM 0 inlet 27 C 10 C 50 C Within Tolerance + # PCM 0 hotspot 21 C 10 C 65 C Within Tolerance + # Node Input PWR 87.6 W 0.0 W 264.0 W Within Tolerance + push @{$self->{commands}}, 'echo "===shownodeenv===', 'shownodeenv'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking sensors"); + $self->{components}->{sensor} = { name => 'sensors', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'sensor')); + + return if ($self->{results} !~ /===shownodeenv===.*?\n(.*?)(===|\Z)/msi); + my $content = $1; + my $unit_new_perf = { A => 'current.ampere', V => 'voltage.volt', W => 'power.watt', C => 'temperature.celsius' }; + + while ($content =~ /^Node\s+(\d+)(.*?)(?=\nNode|\Z$)/msg) { + my ($node_id, $measures) = ($1, $2); + + my @lines = split /\n/, $measures; + foreach (@lines) { + next if (!/^(.*?)\s+(\S+)\s+([CWAV])\s+(\S+\s+[CWAV]|---)\s+(\S+\s+[CWAV]|---)\s+/); + my ($name, $reading, $unit, $lo_limit, $hi_limit) = (centreon::plugins::misc::trim($1), $2, $3, $4, $5); + my $instance = 'node' . $node_id . '.' . $name; + + next if ($self->check_filter(section => 'sensor', instance => $instance)); + $self->{components}->{sensor}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("sensor '%s' on node '%s' is %s %s [instance: %s]", + $name, $node_id, $reading, $unit, $instance) + ); + + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'sensor', instance => $instance, value => $reading); + $lo_limit = ($lo_limit =~ s/.*?(\d+(\.\d+)?).*/$1/) ? $lo_limit : undef; + $hi_limit = ($hi_limit =~ s/.*?(\d+(\.\d+)?).*/$1/) ? $hi_limit : undef; + if ($checked == 0 && (defined($lo_limit) || defined($hi_limit))) { + my $warn_th = ''; + my $crit_th = (defined($lo_limit) ? $lo_limit : '~') . ':' . (defined($hi_limit) ? $hi_limit : '~'); + $self->{perfdata}->threshold_validate(label => 'warning-sensor-instance-' . $instance, value => $warn_th); + $self->{perfdata}->threshold_validate(label => 'critical-sensor-instance-' . $instance, value => $crit_th); + + $exit = $self->{perfdata}->threshold_check( + value => $reading, + threshold => [ { label => 'critical-sensor-instance-' . $instance, exit_litteral => 'critical' }, + { label => 'warning-sensor-instance-' . $instance, exit_litteral => 'warning' } ]); + $warn = $self->{perfdata}->get_perfdata_for_output(label => 'warning-sensor-instance-' . $instance); + $crit = $self->{perfdata}->get_perfdata_for_output(label => 'critical-sensor-instance-' . $instance) + } + + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Sensor '%s' on node '%s' is %s %s ", $name, $node_id, $reading, $unit)); + } + $self->{output}->perfdata_add( + label => 'sensor', unit => $unit, + nlabel => 'hardware.sensor.' . $unit_new_perf->{$unit}, + instances => ['node' . $node_id, $name], + value => $reading, + warning => $warn, + critical => $crit, + ); + } + } +} + +1; diff --git a/storage/hp/3par/ssh/mode/components/wsapi.pm b/storage/hp/3par/ssh/mode/components/wsapi.pm new file mode 100644 index 000000000..f7db4f896 --- /dev/null +++ b/storage/hp/3par/ssh/mode/components/wsapi.pm @@ -0,0 +1,73 @@ +# +# Copyright 2019 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 storage::hp::3par::ssh::mode::components::wsapi; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + #-Service- -State- -HTTP_State- HTTP_Port -HTTPS_State- HTTPS_Port -Version- -----------------API_URL------------------ + #Enabled Active Disabled 8008 Enabled 8080 1.5.3 https://xxxx:8080/api/v1 + push @{$self->{commands}}, 'echo "===showwsapi===', 'showwsapi'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking wsapi"); + $self->{components}->{wsapi} = { name => 'wsapi', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'wsapi')); + + return if ($self->{results} !~ /===showwsapi===.*?\n(.*?)(===|\Z)/msi); + my @results = split /\n/, $1; + + my $instance = 0; + foreach (@results) { + next if (!/^(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\S+)\s+(\d+)\s+\S+/); + $instance++; + my ($service_status, $service_state, $http_state, + $http_port, $https_state, $https_port) = ($1, $2, $3, $4, $5, $6); + + next if ($self->check_filter(section => 'wsapi', instance => $instance)); + $self->{components}->{wsapi}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("wsapi service state is '%s' [status: '%s'] [HTTP on port %d is %s] [HTTPS on port %d is %s] [instance: %s]", + $service_state, $service_status, $http_port, $http_state, $https_port ,$https_state, $instance) + ); + my $exit = $self->get_severity(label => 'default.state', section => 'wsapi.state', value => $service_state); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("wsapi service state is '%s' [instance: %s]", + $service_state, $instance)); + } + + $exit = $self->get_severity(label => 'default.status', section => 'wsapi.status', value => $service_status); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("wsapi service status is '%s' [instance: %s]", + $service_status, $instance)); + } + } +} + +1; diff --git a/storage/hp/3par/ssh/mode/diskusage.pm b/storage/hp/3par/ssh/mode/diskusage.pm new file mode 100644 index 000000000..731f9ab99 --- /dev/null +++ b/storage/hp/3par/ssh/mode/diskusage.pm @@ -0,0 +1,198 @@ +# +# Copyright 2019 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 storage::hp::3par::ssh::mode::diskusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold catalog_status_calc); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'status : ' . $self->{result_values}->{status}; + return $msg; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total_absolute}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used_absolute}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free_absolute}); + my $msg = sprintf("Usage Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used_absolute}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free_absolute}); + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'disk', type => 1, cb_prefix_output => 'prefix_disk_output', message_multiple => 'All disks are ok', sort_method => 'num' }, + ]; + + $self->{maps_counters}->{disk} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'display' } ], + closure_custom_calc => \&catalog_status_calc, + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + { label => 'usage', nlabel => 'disk.space.usage.bytes', set => { + key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' }, { name => 'display' }, ], + closure_custom_output => $self->can('custom_usage_output'), + perfdatas => [ + { label => 'used', value => 'used_absolute', template => '%d', min => 0, max => 'total_absolute', + unit => 'B', cast_int => 1, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'usage-free', display_ok => 0, nlabel => 'disk.space.free.bytes', set => { + key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' }, { name => 'display' }, ], + closure_custom_output => $self->can('custom_usage_output'), + perfdatas => [ + { label => 'free', value => 'free_absolute', template => '%d', min => 0, max => 'total_absolute', + unit => 'B', cast_int => 1, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'usage-prct', display_ok => 0, nlabel => 'disk.space.usage.percentage', set => { + key_values => [ { name => 'prct_used' }, { name => 'display' } ], + output_template => 'Used : %.2f %%', + perfdatas => [ + { label => 'used_prct', value => 'prct_used_absolute', template => '%d', min => 0, max => 0, + unit => '%', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /normal/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status']); +} + +sub prefix_disk_output { + my ($self, %options) = @_; + + return "Disk '" . $options{instance_value}->{display} . "' "; +} + +sub manage_selection { + my ($self, %options) = @_; + + my ($result, $exit) = $options{custom}->execute_command(commands => ['showpd -showcols Id,State,Type,Size_MB,Free_MB']); + + #Id State Type Size_MB Free_MB + # 0 normal FC 838656 133120 + # 1 normal FC 838656 101376 + # 2 normal FC 838656 133120 + + $self->{disk} = {}; + my @lines = split /\n/, $result; + foreach (@lines) { + next if (!/^\s*(\d+)\s+(\S+)\s+\S+\s+(\d+)\s+(\d+)/); + my ($disk_id, $status, $total, $free) = ($1, $2, $3 * 1024 * 1024, $4 * 1024 * 1024); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $disk_id !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping disk '" . $disk_id . "': no matching filter.", debug => 1); + next; + } + + $self->{disk}->{$disk_id} = { + display => $disk_id, + status => $status, + total => $total, + used => $total - $free, + free => $free, + prct_used => ($total - $free) * 100 / $total, + prct_free => 100 - (($total - $free) * 100 / $total), + }; + } + + if (scalar(keys %{$self->{disk}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No disk found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check disk usages. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^status$' + +=item B<--filter-name> + +Filter disk name (can be a regexp). + +=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} !~ /normal/i'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> B<--critical-*> + +Threshold warning. +Can be: 'usage' (B), 'usage-free' (B), 'usage-prct' (%). + +=back + +=cut diff --git a/storage/hp/3par/ssh/mode/hardware.pm b/storage/hp/3par/ssh/mode/hardware.pm new file mode 100644 index 000000000..3561052a5 --- /dev/null +++ b/storage/hp/3par/ssh/mode/hardware.pm @@ -0,0 +1,126 @@ +# +# Copyright 2019 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 storage::hp::3par::ssh::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = + '^(battery|cim|port|node|disk|psu|sensor)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(battery\.charge|sensor)$'; + + $self->{cb_hook2} = 'ssh_execute'; + + $self->{thresholds} = { + default => [ + ['normal', 'OK'], # disk only + ['ok', 'OK'], + ['new', 'OK'], + ['degraded', 'WARNING'], + ['failed', 'CRITICAL'], + ], + 'default.status' => [ + ['enabled', 'OK'], + ['.*', 'CRITICAL'], + ], + 'default.state' => [ + ['active', 'OK'], + ['.*', 'CRITICAL'], + ], + port => [ + ['ready', 'OK'], + ['loss_sync', 'WARNING'], + ['offline', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'storage::hp::3par::ssh::mode::components'; + $self->{components_module} = ['battery', 'cim', 'port', 'node', 'disk', 'psu', 'sensor', 'wsapi']; +} + +sub ssh_execute { + my ($self, %options) = @_; + + ($self->{results}, $self->{exit_code}) = $options{custom}->execute_command(commands => $self->{commands}); +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + $self->{commands} = []; + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check components. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'battery'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=battery --filter=cim) +Can also exclude specific instance: --filter=port,free + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=item B<--threshold-overload> + +Set to overload default threshold values (syntax: section,[instance,]status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='battery,OK,degraded' + +=item B<--warning> + +Set warning threshold for 'battery.charge' (syntax: type,regexp,threshold) +Example: --warning='battery.charge,.*,30' + +=item B<--critical> + +Set critical threshold for 'battery.charge' (syntax: type,regexp,threshold) +Example: --critical='battery.charge,.*,50' + +=back + +=cut diff --git a/storage/hp/3par/ssh/mode/volumeusage.pm b/storage/hp/3par/ssh/mode/volumeusage.pm new file mode 100644 index 000000000..18bbcf013 --- /dev/null +++ b/storage/hp/3par/ssh/mode/volumeusage.pm @@ -0,0 +1,165 @@ +# +# Copyright 2019 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 storage::hp::3par::ssh::mode::volumeusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total_absolute}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used_absolute}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free_absolute}); + my $msg = sprintf("Usage Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used_absolute}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free_absolute}); + return $msg; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'volume', type => 1, cb_prefix_output => 'prefix_volume_output', message_multiple => 'All volumes are ok' }, + ]; + + $self->{maps_counters}->{volume} = [ + { label => 'usage', nlabel => 'volume.space.usage.bytes', set => { + key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' }, { name => 'display' }, ], + closure_custom_output => $self->can('custom_usage_output'), + perfdatas => [ + { label => 'used', value => 'used_absolute', template => '%d', min => 0, max => 'total_absolute', + unit => 'B', cast_int => 1, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'usage-free', display_ok => 0, nlabel => 'volume.space.free.bytes', set => { + key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' }, { name => 'display' }, ], + closure_custom_output => $self->can('custom_usage_output'), + perfdatas => [ + { label => 'free', value => 'free_absolute', template => '%d', min => 0, max => 'total_absolute', + unit => 'B', cast_int => 1, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'usage-prct', display_ok => 0, nlabel => 'volume.space.usage.percentage', set => { + key_values => [ { name => 'prct_used' }, { name => 'display' } ], + output_template => 'Used : %.2f %%', + perfdatas => [ + { label => 'used_prct', value => 'prct_used_absolute', template => '%d', min => 0, max => 0, + unit => '%', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub prefix_volume_output { + my ($self, %options) = @_; + + return "Volume '" . $options{instance_value}->{display} . "' "; +} + +sub manage_selection { + my ($self, %options) = @_; + + my ($result, $exit) = $options{custom}->execute_command(commands => ['showvv -showcols Id,Name,VSize_MB,Snp_Rsvd_MB,Snp_Used_MB,Adm_Rsvd_MB,Adm_Used_MB,Usr_Rsvd_MB,Usr_Used_MB']); + + # Id Name VSize_MB Snp_Rsvd_MB Snp_Used_MB Adm_Rsvd_MB Adm_Used_MB Usr_Rsvd_MB Usr_Used_MB + #2056 .srdata 81920 0 0 0 0 81920 81920 + # 0 admin 10240 0 0 0 0 10240 10240 + # 494 DFS_DATA01 4608000 0 0 2560 2032 3156864 3147727 + # 495 DFS_DATA02 1126400 0 0 1024 612 979072 966739 + # 496 DFS_DATA03 16777216 0 0 10240 9576 15281920 15281185 + + $self->{volume} = {}; + my @lines = split /\n/, $result; + foreach (@lines) { + next if (!/^\s*\d+\s+(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/); + my ($name, $total, $snap_used, $adm_used, $usr_used) = ($1, $2 * 1024 * 1024, $4 * 1024 * 1024, $6 * 1024 * 1024, $8 * 1024 * 1024); + + 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 volume '" . $name . "': no matching filter.", debug => 1); + next; + } + + my $used = $snap_used + $adm_used + $usr_used; + $self->{volume}->{$name} = { + display => $name, + total => $total, + used => $used, + free => ($total - $used) >= 0 ? ($total - $used) : 0, + prct_used => $used * 100 / $total, + prct_free => (100 - ($used * 100 / $total) >= 0) ? (100 - ($used * 100 / $total)) : 0, + }; + } + + if (scalar(keys %{$self->{volume}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No volume found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check volume usages. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^usage$' + +=item B<--filter-name> + +Filter volume name (can be a regexp). + +=item B<--warning-*> B<--critical-*> + +Threshold warning. +Can be: 'usage' (B), 'usage-free' (B), 'usage-prct' (%). + +=back + +=cut diff --git a/storage/hp/3par/ssh/plugin.pm b/storage/hp/3par/ssh/plugin.pm new file mode 100644 index 000000000..c05008d96 --- /dev/null +++ b/storage/hp/3par/ssh/plugin.pm @@ -0,0 +1,51 @@ +# +# Copyright 2019 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 storage::hp::3par::ssh::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'components' => 'storage::hp::3par::ssh::mode::hardware', + 'disk-usage' => 'storage::hp::3par::ssh::mode::diskusage', + 'volume-usage' => 'storage::hp::3par::ssh::mode::volumeusage', + ); + + $self->{custom_modes}{ssh} = 'storage::hp::3par::ssh::custom::custom'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check HP 3par in SSH. + +=cut diff --git a/storage/hp/eva/cli/mode/components/fan.pm b/storage/hp/eva/cli/mode/components/fan.pm index 8173714e0..0901c0632 100644 --- a/storage/hp/eva/cli/mode/components/fan.pm +++ b/storage/hp/eva/cli/mode/components/fan.pm @@ -71,12 +71,15 @@ sub fan_ctrl { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Fan '%s' is %s rpm", $instance, $result->{speed})); } - $self->{output}->perfdata_add(label => 'fan_' . $instance, unit => 'rpm', - value => $result->{speed}, - warning => $warn, - critical => $crit, - min => 0 - ); + $self->{output}->perfdata_add( + label => 'fan_' . $instance, unit => 'rpm', + nlabel => 'hardware.fan.controller.speed.rpm', + instances => $instance, + value => $result->{speed}, + warning => $warn, + critical => $crit, + min => 0 + ); } } } diff --git a/storage/hp/eva/cli/mode/components/psu.pm b/storage/hp/eva/cli/mode/components/psu.pm index afd0053b8..e1937e163 100644 --- a/storage/hp/eva/cli/mode/components/psu.pm +++ b/storage/hp/eva/cli/mode/components/psu.pm @@ -122,11 +122,14 @@ sub psu_diskshelf { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Power supply '%s' is %s V", $instance, $voltage->{current})); } - $self->{output}->perfdata_add(label => 'voltage_' . $instance . '/' . $voltage->{type}, unit => 'V', - value => $voltage->{current}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'voltage', unit => 'V', + nlabel => 'hardware.powersupply.diskshelf.voltage.volt', + instances => [$instance, $voltage->{type}], + value => $voltage->{current}, + warning => $warn, + critical => $crit, + ); } } } diff --git a/storage/hp/eva/cli/mode/components/temperature.pm b/storage/hp/eva/cli/mode/components/temperature.pm index fa9f3a0a7..e82cd41d0 100644 --- a/storage/hp/eva/cli/mode/components/temperature.pm +++ b/storage/hp/eva/cli/mode/components/temperature.pm @@ -64,11 +64,14 @@ sub temp_ctrl { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s C", $instance, $result->{tempc})); } - $self->{output}->perfdata_add(label => 'temperature_' . $instance, unit => 'C', - value => $result->{tempc}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.temperature.controller.celsius', + instances => $instance, + value => $result->{tempc}, + warning => $warn, + critical => $crit, + ); } } } @@ -118,11 +121,14 @@ sub temp_diskshelf { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Temperature '%s' is %s C", $instance, $result->{tempc})); } - $self->{output}->perfdata_add(label => 'temperature_' . $instance, unit => 'C', - value => $result->{tempc}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.temperature.diskshelf.celsius', + instances => $instance, + value => $result->{tempc}, + warning => $warn, + critical => $crit, + ); } } } diff --git a/storage/hp/eva/cli/mode/storageusage.pm b/storage/hp/eva/cli/mode/storageusage.pm index 9c55b59f5..a30a974be 100644 --- a/storage/hp/eva/cli/mode/storageusage.pm +++ b/storage/hp/eva/cli/mode/storageusage.pm @@ -43,19 +43,17 @@ sub set_counters { ]; } -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } @@ -72,10 +70,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); return $exit; @@ -115,21 +113,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/storage/hp/eva/cli/plugin.pm b/storage/hp/eva/cli/plugin.pm index e9d80b572..d076e3b6f 100644 --- a/storage/hp/eva/cli/plugin.pm +++ b/storage/hp/eva/cli/plugin.pm @@ -31,9 +31,9 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'hardware' => 'storage::hp::eva::cli::mode::hardware', - 'storage-usage' => 'storage::hp::eva::cli::mode::storageusage', - ); + 'hardware' => 'storage::hp::eva::cli::mode::hardware', + 'storage-usage' => 'storage::hp::eva::cli::mode::storageusage', + ); $self->{custom_modes}{api} = 'storage::hp::eva::cli::custom::api'; return $self; diff --git a/storage/hp/lefthand/snmp/mode/components/device.pm b/storage/hp/lefthand/snmp/mode/components/device.pm index 28dda79c2..a0e187168 100644 --- a/storage/hp/lefthand/snmp/mode/components/device.pm +++ b/storage/hp/lefthand/snmp/mode/components/device.pm @@ -97,13 +97,16 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("storage device '%s' temperature is %s C", $result->{storageDeviceName}, $result->{storageDeviceTemperature})); } - $self->{output}->perfdata_add(label => 'temp_' . $result->{storageDeviceName}, unit => 'C', - value => $result->{storageDeviceTemperature}, - warning => $warn, - critical => $crit, - max => $result->{storageDeviceTemperatureLimit}, - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.device.temperature.celsius', + instances => $result->{storageDeviceName}, + value => $result->{storageDeviceTemperature}, + warning => $warn, + critical => $crit, + max => $result->{storageDeviceTemperatureLimit}, + ); } } -1; \ No newline at end of file +1; diff --git a/storage/hp/lefthand/snmp/mode/components/fan.pm b/storage/hp/lefthand/snmp/mode/components/fan.pm index f23a6533a..0c545f3b9 100644 --- a/storage/hp/lefthand/snmp/mode/components/fan.pm +++ b/storage/hp/lefthand/snmp/mode/components/fan.pm @@ -85,13 +85,16 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("fan '%s' speed is %s rpm", $result->{infoFanName}, $result->{infoFanSpeed})); } - $self->{output}->perfdata_add(label => 'fan_' . $result->{infoFanName}, unit => 'rpm', - value => $result->{infoFanSpeed}, - warning => $warn, - critical => $crit, - min => 0 - ); + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $result->{infoFanName}, + value => $result->{infoFanSpeed}, + warning => $warn, + critical => $crit, + min => 0 + ); } } -1; \ No newline at end of file +1; diff --git a/storage/hp/lefthand/snmp/mode/components/temperature.pm b/storage/hp/lefthand/snmp/mode/components/temperature.pm index 4d67e4cbb..3b384f09f 100644 --- a/storage/hp/lefthand/snmp/mode/components/temperature.pm +++ b/storage/hp/lefthand/snmp/mode/components/temperature.pm @@ -86,13 +86,16 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("temperature sensor '%s' is %s C", $result->{infoTemperatureSensorName}, $result->{infoTemperatureSensorValue})); } - $self->{output}->perfdata_add(label => 'temp_' . $result->{infoTemperatureSensorName}, unit => 'C', - value => $result->{infoTemperatureSensorValue}, - warning => $warn, - critical => $crit, - max => $result->{infoTemperatureSensorLimit} - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $result->{infoTemperatureSensorName}, + value => $result->{infoTemperatureSensorValue}, + warning => $warn, + critical => $crit, + max => $result->{infoTemperatureSensorLimit} + ); } } -1; \ No newline at end of file +1; diff --git a/storage/hp/lefthand/snmp/mode/components/voltage.pm b/storage/hp/lefthand/snmp/mode/components/voltage.pm index e49dc89cf..b4304abdb 100644 --- a/storage/hp/lefthand/snmp/mode/components/voltage.pm +++ b/storage/hp/lefthand/snmp/mode/components/voltage.pm @@ -86,13 +86,16 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("voltage sensor '%s' is %s V", $result->{infoVoltageSensorName}, $result->{infoVoltageSensorValue})); } - $self->{output}->perfdata_add(label => 'voltage_' . $result->{infoVoltageSensorName}, unit => 'V', - value => $result->{infoVoltageSensorValue}, - warning => $warn, - critical => $crit, - min => 0 - ); + $self->{output}->perfdata_add( + label => 'voltage', unit => 'V', + nlabel => 'hardware.voltage.volt', + instances => $result->{infoVoltageSensorName}, + value => $result->{infoVoltageSensorValue}, + warning => $warn, + critical => $crit, + min => 0 + ); } } -1; \ No newline at end of file +1; diff --git a/storage/hp/lefthand/snmp/mode/volumeusage.pm b/storage/hp/lefthand/snmp/mode/volumeusage.pm index 02b59f9ef..4823b86ec 100644 --- a/storage/hp/lefthand/snmp/mode/volumeusage.pm +++ b/storage/hp/lefthand/snmp/mode/volumeusage.pm @@ -51,19 +51,21 @@ sub custom_usage_perfdata { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -76,7 +78,7 @@ sub custom_usage_threshold { $threshold_value = $self->{result_values}->{prct_used}; $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -197,15 +199,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "warning-replication-status:s" => { name => 'warning_replication_status', default => '' }, - "critical-replication-status:s" => { name => 'critical_replication_status', default => '%{status} !~ /normal/i' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "warning-replication-status:s" => { name => 'warning_replication_status', default => '' }, + "critical-replication-status:s" => { name => 'critical_replication_status', default => '%{status} !~ /normal/i' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } diff --git a/storage/hp/lefthand/snmp/plugin.pm b/storage/hp/lefthand/snmp/plugin.pm index 320377c3b..194cc3572 100644 --- a/storage/hp/lefthand/snmp/plugin.pm +++ b/storage/hp/lefthand/snmp/plugin.pm @@ -31,9 +31,9 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'hardware' => 'storage::hp::lefthand::snmp::mode::hardware', - 'volume-usage' => 'storage::hp::lefthand::snmp::mode::volumeusage', - ); + 'hardware' => 'storage::hp::lefthand::snmp::mode::hardware', + 'volume-usage' => 'storage::hp::lefthand::snmp::mode::volumeusage', + ); return $self; } diff --git a/storage/hp/msl/snmp/plugin.pm b/storage/hp/msl/snmp/plugin.pm index 7e383b362..0c950fb43 100644 --- a/storage/hp/msl/snmp/plugin.pm +++ b/storage/hp/msl/snmp/plugin.pm @@ -31,8 +31,8 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'hardware' => 'storage::hp::msl::snmp::mode::hardware', - ); + 'hardware' => 'storage::hp::msl::snmp::mode::hardware', + ); return $self; } diff --git a/storage/hp/p2000/xmlapi/custom.pm b/storage/hp/p2000/xmlapi/custom.pm index 765959de8..92de80eda 100644 --- a/storage/hp/p2000/xmlapi/custom.pm +++ b/storage/hp/p2000/xmlapi/custom.pm @@ -30,10 +30,6 @@ sub new { my ($class, %options) = @_; my $self = {}; bless $self, $class; - # $options{options} = options object - # $options{output} = output object - # $options{exit_value} = integer - # $options{noptions} = integer if (!defined($options{output})) { print "Class Custom: Need to specify 'output' argument.\n"; @@ -45,21 +41,20 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s@" => { name => 'hostname' }, - "port:s@" => { name => 'port' }, - "proto:s@" => { name => 'proto' }, - "urlpath:s@" => { name => 'url_path' }, - "proxyurl:s@" => { name => 'proxyurl' }, - "username:s@" => { name => 'username' }, - "password:s@" => { name => 'password' }, - "timeout:s@" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + 'hostname:s@' => { name => 'hostname' }, + 'port:s@' => { name => 'port' }, + 'proto:s@' => { name => 'proto' }, + 'urlpath:s@' => { name => 'url_path' }, + 'username:s@' => { name => 'username' }, + 'password:s@' => { name => 'password' }, + 'timeout:s@' => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'P2000 OPTIONS', once => 1); + $self->{http} = centreon::plugins::http->new(%options); + $self->{output} = $options{output}; $self->{mode} = $options{mode}; @@ -69,20 +64,15 @@ sub new { return $self; } -# Method to manage multiples sub set_options { my ($self, %options) = @_; - # options{options_result} $self->{option_results} = $options{option_results}; } -# Method to manage multiples sub set_defaults { my ($self, %options) = @_; - # options{default} - - # Manage default value + foreach (keys %{$options{default}}) { if ($_ eq $self->{mode}) { for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { @@ -98,8 +88,6 @@ sub set_defaults { sub check_options { my ($self, %options) = @_; - # return 1 = ok still hostname - # return 0 = no hostname left $self->{hostname} = (defined($self->{option_results}->{hostname})) ? shift(@{$self->{option_results}->{hostname}}) : undef; $self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : undef; @@ -108,10 +96,9 @@ sub check_options { $self->{port} = (defined($self->{option_results}->{port})) ? shift(@{$self->{option_results}->{port}}) : undef; $self->{proto} = (defined($self->{option_results}->{proto})) ? shift(@{$self->{option_results}->{proto}}) : 'http'; $self->{url_path} = (defined($self->{option_results}->{url_path})) ? shift(@{$self->{option_results}->{url_path}}) : '/api/'; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef; if (!defined($self->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); + $self->{output}->add_option_msg(short_msg => 'Need to specify hostname option.'); $self->{output}->option_exit(); } if (!defined($self->{username}) || !defined($self->{password})) { @@ -134,7 +121,6 @@ sub build_options_for_httplib { $self->{option_results}->{port} = $self->{port}; $self->{option_results}->{proto} = $self->{proto}; $self->{option_results}->{url_path} = $self->{url_path}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; } sub check_login { @@ -187,12 +173,13 @@ sub DESTROY { sub get_infos { my ($self, %options) = @_; my ($xpath, $nodeset); - + + $self->login(); my $cmd = $options{cmd}; $cmd =~ s/ /\//g; - my $response =$self->{http}->request(url_path => $self->{url_path} . $cmd, - header => ['Cookie: wbisessionkey=' . $self->{session_id} . '; wbiusername=' . $self->{username}, - 'dataType: api', 'sessionKey: '. $self->{session_id}]); + my $response = $self->{http}->request(url_path => $self->{url_path} . $cmd, + header => ['Cookie: wbisessionkey=' . $self->{session_id} . '; wbiusername=' . $self->{username}, + 'dataType: api', 'sessionKey: '. $self->{session_id}]); eval { $xpath = XML::XPath->new(xml => $response); @@ -218,7 +205,8 @@ sub get_infos { if ($return_code != 0) { $nodestatus = $xpath->find("//OBJECT[\@basetype='status']//PROPERTY[\@name='response']"); @nodes = $nodestatus->get_nodelist(); - $node = shift @nodes; + $node = shift @nodes; + return ({}, 0, $node->string_value) if (defined($options{no_quit}) && $options{no_quit} == 1); $self->{output}->add_option_msg(short_msg => $node->string_value); $self->{output}->option_exit(); } @@ -242,7 +230,7 @@ sub get_infos { } } - return $results; + return ($results, 1); } ############## @@ -250,9 +238,10 @@ sub get_infos { ############## sub login { my ($self, %options) = @_; - + + return if ($self->{logon} == 1); + $self->build_options_for_httplib(); - $self->{http} = centreon::plugins::http->new(output => $self->{output}); $self->{http}->set_options(%{$self->{option_results}}); # Login First @@ -285,10 +274,6 @@ HP p2000 Hostname. Port used -=item B<--proxyurl> - -Proxy URL if any - =item B<--proto> Specify https if needed @@ -309,14 +294,10 @@ Password to connect. Set HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION B. -=cut \ No newline at end of file +=cut diff --git a/storage/hp/p2000/xmlapi/mode/components/disk.pm b/storage/hp/p2000/xmlapi/mode/components/disk.pm index 1a0349e4f..078bb430a 100644 --- a/storage/hp/p2000/xmlapi/mode/components/disk.pm +++ b/storage/hp/p2000/xmlapi/mode/components/disk.pm @@ -23,12 +23,6 @@ package storage::hp::p2000::xmlapi::mode::components::disk; use strict; use warnings; -my @conditions = ( - ['^degraded$' => 'WARNING'], - ['^failed$' => 'CRITICAL'], - ['^(unknown|not available)$' => 'UNKNOWN'], -); - my %health = ( 0 => 'ok', 1 => 'degraded', @@ -41,32 +35,32 @@ sub check { my ($self) = @_; $self->{output}->output_add(long_msg => "Checking disks"); - $self->{components}->{disk} = {name => 'disks', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'disk')); - - my $results = $self->{p2000}->get_infos(cmd => 'show disks', - base_type => 'drives', - key => 'durable-id', - properties_name => '^health-numeric$'); + $self->{components}->{disk} = { name => 'disks', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'disk')); + my ($results) = $self->{custom}->get_infos( + cmd => 'show disks', + base_type => 'drives', + key => 'durable-id', + properties_name => '^health-numeric$', + no_quit => 1 + ); + foreach my $disk_id (keys %$results) { - next if ($self->check_exclude(section => 'disk', instance => $disk_id)); + next if ($self->check_filter(section => 'disk', instance => $disk_id)); $self->{components}->{disk}->{total}++; my $state = $health{$results->{$disk_id}->{'health-numeric'}}; - $self->{output}->output_add(long_msg => sprintf("Disk '%s' status is %s.", - $disk_id, $state) + $self->{output}->output_add(long_msg => sprintf("disk '%s' status is %s [instance: %s]", + $disk_id, $state, $disk_id) ); - foreach (@conditions) { - if ($state =~ /$$_[0]/i) { - $self->{output}->output_add(severity => $$_[1], - short_msg => sprintf("Disk '%s' status is %s", - $disk_id, $state)); - last; - } + my $exit = $self->get_severity(label => 'default', section => 'disk', value => $state); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Disk '%s' status is '%s'", $disk_id, $state)); } } } -1; \ No newline at end of file +1; diff --git a/storage/hp/p2000/xmlapi/mode/components/enclosure.pm b/storage/hp/p2000/xmlapi/mode/components/enclosure.pm index b818484b1..032380ea4 100644 --- a/storage/hp/p2000/xmlapi/mode/components/enclosure.pm +++ b/storage/hp/p2000/xmlapi/mode/components/enclosure.pm @@ -23,12 +23,6 @@ package storage::hp::p2000::xmlapi::mode::components::enclosure; use strict; use warnings; -my @conditions = ( - ['^degraded$' => 'WARNING'], - ['^failed$' => 'CRITICAL'], - ['^(unknown|not available)$' => 'UNKNOWN'], -); - my %health = ( 0 => 'ok', 1 => 'degraded', @@ -42,30 +36,30 @@ sub check { $self->{output}->output_add(long_msg => "Checking enclosures"); $self->{components}->{enclosure} = {name => 'enclosures', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'enclosure')); + return if ($self->check_filter(section => 'enclosure')); - my $results = $self->{p2000}->get_infos(cmd => 'show enclosures', - base_type => 'enclosures', - key => 'durable-id', - properties_name => '^health-numeric|health-reason$'); + my ($results) = $self->{custom}->get_infos( + cmd => 'show enclosures', + base_type => 'enclosures', + key => 'durable-id', + properties_name => '^health-numeric|health-reason$', + no_quit => 1 + ); foreach my $enc_id (keys %$results) { - next if ($self->check_exclude(section => 'enclosure', instance => $enc_id)); + next if ($self->check_filter(section => 'enclosure', instance => $enc_id)); $self->{components}->{enclosure}->{total}++; my $state = $health{$results->{$enc_id}->{'health-numeric'}}; - $self->{output}->output_add(long_msg => sprintf("enclosure '%s' status is %s.", - $enc_id, $state) + $self->{output}->output_add(long_msg => sprintf("enclosure '%s' status is %s [instance: %s] [reason: %s]", + $enc_id, $state, $enc_id, $health{$results->{$enc_id}->{'health-reason'}}) ); - foreach (@conditions) { - if ($state =~ /$$_[0]/i) { - $self->{output}->output_add(severity => $$_[1], - short_msg => sprintf("enclosure '%s' status is %s (reason: %s)", - $enc_id, $state, $health{$results->{$enc_id}->{'health-reason'}})); - last; - } + my $exit = $self->get_severity(label => 'default', section => 'enclosure', value => $state); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Enclosure '%s' status is '%s'", $enc_id, $state)); } } } -1; \ No newline at end of file +1; diff --git a/storage/hp/p2000/xmlapi/mode/components/fru.pm b/storage/hp/p2000/xmlapi/mode/components/fru.pm index f91caf362..ad7645c39 100644 --- a/storage/hp/p2000/xmlapi/mode/components/fru.pm +++ b/storage/hp/p2000/xmlapi/mode/components/fru.pm @@ -23,43 +23,37 @@ package storage::hp::p2000::xmlapi::mode::components::fru; use strict; use warnings; -my @conditions = ( - ['^absent$' => 'WARNING'], - ['^fault$' => 'CRITICAL'], - ['^not available$' => 'UNKNOWN'], -); - sub check { my ($self) = @_; $self->{output}->output_add(long_msg => "Checking frus"); $self->{components}->{fru} = {name => 'frus', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fru')); + return if ($self->check_filter(section => 'fru')); - my $results = $self->{p2000}->get_infos(cmd => 'show frus', - base_type => 'enclosure-fru', - key => 'part-number', - properties_name => '^(fru-status|fru-location)$'); + my ($results) = $self->{custom}->get_infos( + cmd => 'show frus', + base_type => 'enclosure-fru', + key => 'part-number', + properties_name => '^(fru-status|fru-location)$', + no_quit => 1, + ); foreach my $part_number (keys %$results) { my $instance = $results->{$part_number}->{'fru-location'}; - next if ($self->check_exclude(section => 'fru', instance => $instance)); + next if ($self->check_filter(section => 'fru', instance => $instance)); $self->{components}->{fru}->{total}++; my $state = $results->{$part_number}->{'fru-status'}; - $self->{output}->output_add(long_msg => sprintf("fru '%s' status is %s.", - $instance, $state) + $self->{output}->output_add(long_msg => sprintf("fru '%s' status is %s [instance: %s]", + $instance, $state, $instance) ); - foreach (@conditions) { - if ($state =~ /$$_[0]/i) { - $self->{output}->output_add(severity => $$_[1], - short_msg => sprintf("fru '%s' status is %s", - $instance, $state)); - last; - } + my $exit = $self->get_severity(section => 'fru', value => $state); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Fru '%s' status is '%s'", $instance, $state)); } } } -1; \ No newline at end of file +1; diff --git a/storage/hp/p2000/xmlapi/mode/components/sensors.pm b/storage/hp/p2000/xmlapi/mode/components/sensor.pm similarity index 54% rename from storage/hp/p2000/xmlapi/mode/components/sensors.pm rename to storage/hp/p2000/xmlapi/mode/components/sensor.pm index 8b2a8a94e..c5983c119 100644 --- a/storage/hp/p2000/xmlapi/mode/components/sensors.pm +++ b/storage/hp/p2000/xmlapi/mode/components/sensor.pm @@ -18,36 +18,38 @@ # limitations under the License. # -package storage::hp::p2000::xmlapi::mode::components::sensors; +package storage::hp::p2000::xmlapi::mode::components::sensor; use strict; use warnings; -my @conditions = ( - ['^warning|not installed|unavailable$' => 'WARNING'], - ['^error|unrecoverable$' => 'CRITICAL'], - ['^unknown|unsupported$' => 'UNKNOWN'], -); - my %sensor_type = ( # 2 it's other. Can be ok or '%'. Need to regexp - 3 => { unit => 'C' }, - 6 => { unit => 'V' }, - 9 => { unit => 'V' }, + 3 => { unit => 'C', nunit => 'celsius', type => 'temperature' }, + 6 => { unit => 'V', nunit => 'volt', type => 'voltage' }, + 9 => { unit => 'V', nunit => 'volt', type => 'voltage' }, +); +my %units = ( + C => { long => 'celsius', type => 'temperature' }, + V => { long => 'volt', type => 'voltage' }, + '' => { long => undef, type => 'misc' }, + '%' => { long => 'percentage', type => 'misc' }, ); sub check { my ($self) = @_; - $self->{output}->output_add(long_msg => "Checking sensors"); - $self->{components}->{sensor} = {name => 'sensors', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'sensor')); + $self->{output}->output_add(long_msg => "Checking sensor"); + $self->{components}->{sensor} = {name => 'sensor', total => 0, skip => 0}; + return if ($self->check_filter(section => 'sensor')); # We don't use status-numeric. Values are buggy !!!??? - my $results = $self->{p2000}->get_infos(cmd => 'show sensor-status', - base_type => 'sensors', - key => 'sensor-name', - properties_name => '^(value|sensor-type|status)$'); + my ($results) = $self->{custom}->get_infos( + cmd => 'show sensor-status', + base_type => 'sensors', + key => 'sensor-name', + properties_name => '^(value|sensor-type|status)$' + ); # # Capacitor Charge-Ctlr B @@ -60,32 +62,44 @@ sub check { # Warning # foreach my $sensor_id (keys %$results) { - next if ($self->check_exclude(section => 'sensor', instance => $sensor_id)); - $self->{components}->{sensor}->{total}++; - - my $state = $results->{$sensor_id}->{status}; - my ($value, $unit); ($value, $unit) = ($1, $2) if ($results->{$sensor_id}->{value} =~ /\s*([0-9\.,]+)\s*(\S*)\s*/); if (defined($results->{$sensor_id}->{'sensor-type'}) && defined($sensor_type{$results->{$sensor_id}->{'sensor-type'}})) { $unit = $sensor_type{$results->{$sensor_id}->{'sensor-type'}}->{unit}; } + my $type = $units{$unit}->{type}; + + next if ($self->check_filter(section => 'sensor', instance => $type . '.' . $sensor_id)); + $self->{components}->{sensor}->{total}++; - $self->{output}->output_add(long_msg => sprintf("sensor '%s' status is %s (value: %s %s).", + my $state = $results->{$sensor_id}->{status}; + + $self->{output}->output_add(long_msg => sprintf("sensor '%s' status is %s (value: %s %s)", $sensor_id, $state, defined($value) ? $value : '-', defined($unit) ? $unit : '-') ); - foreach (@conditions) { - if ($state =~ /$$_[0]/i) { - $self->{output}->output_add(severity => $$_[1], - short_msg => sprintf("sensor '%s' status is %s", - $sensor_id, $state)); - last; - } + my $exit = $self->get_severity(section => 'sensor', value => $state); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("sensor '%s' status is '%s'", $sensor_id, $state)); } - - $self->{output}->perfdata_add(label => $sensor_id, unit => $unit, - value => $value) if (defined($value)); + + next if (!defined($value)); + + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'sensor', instance => $type . '.' . $sensor_id, value => $value); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Sensor '%s' is %s %s", $sensor_id, $value, defined($unit) ? $unit : '-')); + } + + $self->{output}->perfdata_add( + label => 'sensor', unit => $unit, + nlabel => 'hardware.sensor.' . $type . (defined($units{$unit}->{long}) ? $units{$unit}->{long} : ''), + instances => $sensor_id, + value => $value, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1; diff --git a/storage/hp/p2000/xmlapi/mode/components/vdisk.pm b/storage/hp/p2000/xmlapi/mode/components/vdisk.pm index 12b5b30ab..2eebaca4e 100644 --- a/storage/hp/p2000/xmlapi/mode/components/vdisk.pm +++ b/storage/hp/p2000/xmlapi/mode/components/vdisk.pm @@ -23,12 +23,6 @@ package storage::hp::p2000::xmlapi::mode::components::vdisk; use strict; use warnings; -my @conditions = ( - ['^degraded$' => 'WARNING'], - ['^failed$' => 'CRITICAL'], - ['^(unknown|not available)$' => 'UNKNOWN'], -); - my %health = ( 0 => 'ok', 1 => 'degraded', @@ -37,36 +31,51 @@ my %health = ( 4 => 'not available', ); -sub check { - my ($self) = @_; +sub check_vdisk { + my ($self, %options) = @_; - $self->{output}->output_add(long_msg => "Checking vdisks"); - $self->{components}->{vdisk} = {name => 'vdisks', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'vdisk')); - - my $results = $self->{p2000}->get_infos(cmd => 'show vdisks', - base_type => 'virtual-disks', - key => 'name', - properties_name => '^health-numeric$'); - - foreach my $vdisk_id (keys %$results) { - next if ($self->check_exclude(section => 'vdisk', instance => $vdisk_id)); + foreach my $vdisk_id (keys %{$options{results}}) { + next if ($self->check_filter(section => 'vdisk', instance => $vdisk_id)); $self->{components}->{vdisk}->{total}++; - my $state = $health{$results->{$vdisk_id}->{'health-numeric'}}; + my $state = $health{$options{results}->{$vdisk_id}->{'health-numeric'}}; - $self->{output}->output_add(long_msg => sprintf("vdisk '%s' status is %s.", - $vdisk_id, $state) + $self->{output}->output_add(long_msg => sprintf("vdisk '%s' status is %s [instance: %s]", + $vdisk_id, $state, $vdisk_id) ); - foreach (@conditions) { - if ($state =~ /$$_[0]/i) { - $self->{output}->output_add(severity => $$_[1], - short_msg => sprintf("vdisk '%s' status is %s", - $vdisk_id, $state)); - last; - } + my $exit = $self->get_severity(label => 'default', section => 'vdisk', value => $state); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Vdisk '%s' status is '%s'", $vdisk_id, $state)); } } } -1; \ No newline at end of file +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking vdisks"); + $self->{components}->{vdisk} = { name => 'vdisks', total => 0, skip => 0 }; + return if ($self->check_filter(section => 'vdisk')); + + my ($results, $code) = $self->{custom}->get_infos( + cmd => 'show vdisks', + base_type => 'virtual-disks', + key => 'name', + properties_name => '^health-numeric$', + no_quit => 1, + ); + if ($code == 0) { + ($results) = $self->{custom}->get_infos( + cmd => 'show disk-groups', + base_type => 'disk-groups', + key => 'name', + properties_name => '^health-numeric$', + no_quit => 1, + ); + } + + check_vdisk($self, results => $results); +} + +1; diff --git a/storage/hp/p2000/xmlapi/mode/health.pm b/storage/hp/p2000/xmlapi/mode/health.pm index 98d298903..5314177fe 100644 --- a/storage/hp/p2000/xmlapi/mode/health.pm +++ b/storage/hp/p2000/xmlapi/mode/health.pm @@ -20,122 +20,63 @@ package storage::hp::p2000::xmlapi::mode::health; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -use storage::hp::p2000::xmlapi::mode::components::disk; -use storage::hp::p2000::xmlapi::mode::components::vdisk; -use storage::hp::p2000::xmlapi::mode::components::sensors; -use storage::hp::p2000::xmlapi::mode::components::fru; -use storage::hp::p2000::xmlapi::mode::components::enclosure; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = + '^(disk|enclosure|fru|sensor|vdisk)$'; + $self->{regexp_threshold_numeric_check_section_option} = + '^(sensor)$'; + + $self->{cb_hook1} = 'init_health'; + + $self->{thresholds} = { + # disk, enclosure, vdisk + default => [ + ['degraded', 'WARNING'], + ['failed', 'CRITICAL'], + ['unknown|not available', 'UNKNOWN'], + ], + fru => [ + ['absent', 'WARNING'], + ['fault', 'CRITICAL'], + ['not available', 'UNKNOWN'], + ], + sensor => [ + ['warning|not installed|unavailable', 'WARNING'], + ['error|unrecoverable', 'CRITICAL'], + ['nknown|unsupported', 'UNKNOWN'], + ], + }; + + $self->{components_exec_load} = 0; + $self->{components_path} = 'storage::hp::p2000::xmlapi::mode::components'; + $self->{components_module} = ['disk', 'enclosure', 'fru', 'sensor', 'vdisk']; +} + +sub init_health { + my ($self, %options) = @_; + + $self->{custom} = $options{custom}; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "exclude:s" => { name => 'exclude' }, - "component:s" => { name => 'component', default => 'all' }, - "no-component:s" => { name => 'no_component' }, - }); + $options{options}->add_options(arguments => { + }); - $self->{components} = {}; - $self->{no_components} = undef; - return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } -} - -sub component { - my ($self, %options) = @_; - - if ($self->{option_results}->{component} eq 'all') { - storage::hp::p2000::xmlapi::mode::components::disk::check($self); - storage::hp::p2000::xmlapi::mode::components::vdisk::check($self); - storage::hp::p2000::xmlapi::mode::components::sensors::check($self); - storage::hp::p2000::xmlapi::mode::components::fru::check($self); - storage::hp::p2000::xmlapi::mode::components::enclosure::check($self); - } elsif ($self->{option_results}->{component} eq 'disk') { - storage::hp::p2000::xmlapi::mode::components::disk::check($self); - } elsif ($self->{option_results}->{component} eq 'vdisk') { - storage::hp::p2000::xmlapi::mode::components::vdisk::check($self); - } elsif ($self->{option_results}->{component} eq 'sensor') { - storage::hp::p2000::xmlapi::mode::components::sensors::check($self); - } elsif ($self->{option_results}->{component} eq 'fru') { - storage::hp::p2000::xmlapi::mode::components::fru::check($self); - } elsif ($self->{option_results}->{component} eq 'enclosure') { - storage::hp::p2000::xmlapi::mode::components::enclosure::check($self); - } else { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - - my $total_components = 0; - my $display_by_component = ''; - my $display_by_component_append = ''; - foreach my $comp (sort(keys %{$self->{components}})) { - # Skipping short msg when no components - next if ($self->{components}->{$comp}->{total} == 0 && $self->{components}->{$comp}->{skip} == 0); - $total_components += $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $self->{components}->{$comp}->{skip} . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components [%s] are ok.", - $total_components, - $display_by_component) - ); - - if (defined($self->{option_results}->{no_component}) && $total_components == 0) { - $self->{output}->output_add(severity => $self->{no_components}, - short_msg => 'No components are checked.'); - } -} - -sub run { - my ($self, %options) = @_; - $self->{p2000} = $options{custom}; - - $self->{p2000}->login(); - $self->component(); - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub check_exclude { - my ($self, %options) = @_; - - if (defined($options{instance})) { - if (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)${options{section}}[^,]*#\Q$options{instance}\E#/) { - $self->{components}->{$options{section}}->{skip}++; - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); - return 1; - } - } elsif (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)$options{section}(\s|,|$)/) { - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); - return 1; - } - return 0; -} - 1; __END__ @@ -148,19 +89,35 @@ Check health status of storage. =item B<--component> -Which component to check (Default: 'all'). -Can be: 'disk', 'vdisk', 'sensor', 'enclosure', 'fru'. +Which component to check (Default: '.*'). +Can be: 'disk', 'enclosure', 'fru', 'sensor', 'vdisk'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=fru) -Can also exclude specific instance: --exclude=disk#disk_1.4#,sensor#Temperature Loc: lower-IOM B# +Exclude some parts (comma seperated list) (Example: --filter=fru --filter=enclosure) +Can also exclude specific instance: --filter=disk,1 =item B<--no-component> Return an error if no compenents are checked. If total (with skipped) is 0. (Default: 'critical' returns). +=item B<--threshold-overload> + +Set to overload default threshold values (syntax: section,[instance,]status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='disk,OK,unknown' + +=item B<--warning> + +Set warning threshold for 'sensor' (syntax: type,instance,threshold) +Example: --warning='sensor,temperature.*,30' + +=item B<--critical> + +Set warning threshold for 'sensors' (syntax: type,instance,threshold) +Example: --warning='sensor,temperature.*,30' + =back -=cut \ No newline at end of file +=cut diff --git a/storage/hp/p2000/xmlapi/mode/listvolumes.pm b/storage/hp/p2000/xmlapi/mode/listvolumes.pm index 7407b0e07..839796534 100644 --- a/storage/hp/p2000/xmlapi/mode/listvolumes.pm +++ b/storage/hp/p2000/xmlapi/mode/listvolumes.pm @@ -31,12 +31,12 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - "filter-type:s" => { name => 'filter_type' }, - }); + $options{options}->add_options(arguments => { + 'name:s' => { name => 'name' }, + 'regexp" => { name => 'use_regexp' }, + 'filter-type:s' => { name => 'filter_type' }, + }); + $self->{volume_name_selected} = []; return $self; @@ -50,10 +50,12 @@ sub check_options { sub manage_selection { my ($self, %options) = @_; - $self->{results} = $self->{p2000}->get_infos(cmd => 'show volumes', - base_type => 'volumes', - key => 'volume-name', - properties_name => '^volume-type$'); + ($self->{results}) = $self->{p2000}->get_infos( + cmd => 'show volumes', + base_type => 'volumes', + key => 'volume-name', + properties_name => '^volume-type$' + ); foreach my $name (keys %{$self->{results}}) { my $volume_type = $self->{results}->{$name}->{'volume-type'}; @@ -146,4 +148,4 @@ Available types are: =back =cut - \ No newline at end of file + diff --git a/storage/hp/p2000/xmlapi/mode/volumesstats.pm b/storage/hp/p2000/xmlapi/mode/volumesstats.pm index 66a272141..2b0a8954c 100644 --- a/storage/hp/p2000/xmlapi/mode/volumesstats.pm +++ b/storage/hp/p2000/xmlapi/mode/volumesstats.pm @@ -20,85 +20,11 @@ package storage::hp::p2000::xmlapi::mode::volumesstats; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::statefile; -use centreon::plugins::values; - -my $maps_counters = { - read => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'data-read-numeric', diff => 1 }, - ], - per_second => 1, - output_template => 'Read I/O : %s %s/s', - output_change_bytes => 1, - perfdatas => [ - { value => 'data-read-numeric_per_second', template => '%d', - unit => 'B/s', min => 0, label_extra_instance => 1 }, - ], - } - }, - write => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'data-written-numeric', diff => 1 }, - ], - per_second => 1, - output_template => 'Write I/O : %s %s/s', - output_change_bytes => 1, - perfdatas => [ - { value => 'data-written-numeric_per_second', template => '%d', - unit => 'B/s', min => 0, label_extra_instance => 1 }, - ], - } - }, - 'write-cache-hits' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'write-cache-hits', diff => 1 }, - { name => 'write-cache-misses', diff => 1 }, - ], - closure_custom_calc => \&custom_write_cache_calc, - output_template => 'Write Cache Hits : %.2f %%', - output_use => 'write-cache-hits_prct', threshold_use => 'write-cache-hits_prct', - perfdatas => [ - { value => 'write-cache-hits_prct', template => '%.2f', - unit => '%', min => 0, max => 100, label_extra_instance => 1 }, - ], - } - }, - 'read-cache-hits' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'read-cache-hits', diff => 1 }, - { name => 'read-cache-misses', diff => 1 }, - ], - closure_custom_calc => \&custom_read_cache_calc, - output_template => 'Read Cache Hits : %.2f %%', - output_use => 'read-cache-hits_prct', threshold_use => 'read-cache-hits_prct', - perfdatas => [ - { value => 'read-cache-hits_prct', template => '%.2f', - unit => '%', min => 0, max => 100, label_extra_instance => 1 }, - ], - } - }, - iops => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'iops' }, - ], - output_template => 'IOPs : %s', - perfdatas => [ - { value => 'iops_absolute', - unit => 'iops', min => 0, label_extra_instance => 1 }, - ], - } - }, -}; +use Digest::MD5 qw(md5_hex); sub custom_write_cache_calc { my ($self, %options) = @_; @@ -130,141 +56,122 @@ sub custom_read_cache_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'volume', type => 1, cb_prefix_output => 'prefix_volume_output', message_multiple => 'All volumes statistics are ok', skipped_code => { -2 => 1, -10 => 1 } }, + ]; + + $self->{maps_counters}->{volume} = [ + { label => 'read', nlabel => 'volume.io.read.usage.bytespersecond', set => { + key_values => [ { name => 'data-read-numeric', diff => 1 } ], + per_second => 1, + output_template => 'Read I/O : %s %s/s', + output_change_bytes => 1, + perfdatas => [ + { value => 'data-read-numeric_per_second', template => '%d', + unit => 'B/s', min => 0, label_extra_instance => 1 }, + ], + } + }, + { label => 'write', nlabel => 'volume.io.write.usage.bytespersecond', set => { + key_values => [ { name => 'data-written-numeric', diff => 1 } ], + per_second => 1, + output_template => 'Write I/O : %s %s/s', + output_change_bytes => 1, + perfdatas => [ + { value => 'data-written-numeric_per_second', template => '%d', + unit => 'B/s', min => 0, label_extra_instance => 1 }, + ], + } + }, + { label => 'read-cache-hits', nlabel => 'volume.cache.read.hits.percentage', set => { + key_values => [ { name => 'read-cache-hits', diff => 1 }, { name => 'read-cache-misses', diff => 1 } ], + closure_custom_calc => $self->can('custom_read_cache_calc'), + output_template => 'Read Cache Hits : %.2f %%', + output_use => 'read-cache-hits_prct', threshold_use => 'read-cache-hits_prct', + perfdatas => [ + { value => 'read-cache-hits_prct', template => '%.2f', + unit => '%', min => 0, max => 100, label_extra_instance => 1 }, + ], + } + }, + { label => 'write-cache-hits', nlabel => 'volume.cache.write.hits.percentage', set => { + key_values => [ { name => 'write-cache-hits', diff => 1 }, { name => 'write-cache-misses', diff => 1 } ], + closure_custom_calc => $self->can('custom_write_cache_calc'), + output_template => 'Write Cache Hits : %.2f %%', + output_use => 'write-cache-hits_prct', threshold_use => 'write-cache-hits_prct', + perfdatas => [ + { value => 'write-cache-hits_prct', template => '%.2f', + unit => '%', min => 0, max => 100, label_extra_instance => 1 }, + ], + } + }, + { label => 'iops', nlabel => 'volume.io.usage.iops', set => { + key_values => [ { name => 'iops' } ], + output_template => 'IOPs : %s', + perfdatas => [ + { value => 'iops_absolute', + unit => 'iops', min => 0, label_extra_instance => 1 }, + ], + } + }, + ]; +} + sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - }); - $self->{volume_name_selected} = []; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - - foreach (keys %{$maps_counters}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } + $options{options}->add_options(arguments => { + 'name:s' => { name => 'name' }, + 'regexp' => { name => 'use_regexp' }, + }); return $self; } -sub check_options { +sub prefix_volume_output { my ($self, %options) = @_; - $self->SUPER::init(%options); - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - - $self->{statefile_value}->check_options(%options); + return "Volume '" . $options{instance_value}->{display} . "' "; } sub manage_selection { my ($self, %options) = @_; - $self->{results} = $self->{p2000}->get_infos(cmd => 'show volume-statistics', - base_type => 'volume-statistics', - key => 'volume-name', - properties_name => '^data-read-numeric|data-written-numeric|write-cache-hits|write-cache-misses|read-cache-hits|read-cache-misses|iops$'); - foreach my $name (sort keys %{$self->{results}}) { - # Get all without a name - if (!defined($self->{option_results}->{name})) { - push @{$self->{volume_name_selected}}, $name; - next; - } - - if (!defined($self->{option_results}->{use_regexp}) && $name eq $self->{option_results}->{name}) { - push @{$self->{volume_name_selected}}, $name; - next; - } - if (defined($self->{option_results}->{use_regexp}) && $name =~ /$self->{option_results}->{name}/) { - push @{$self->{volume_name_selected}}, $name; - next; - } - } + my ($result) = $options{custom}->get_infos( + cmd => 'show volume-statistics', + base_type => 'volume-statistics', + key => 'volume-name', + properties_name => '^data-read-numeric|data-written-numeric|write-cache-hits|write-cache-misses|read-cache-hits|read-cache-misses|iops$' + ); - if (scalar(@{$self->{volume_name_selected}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No volume found for name '" . $self->{option_results}->{name} . "'."); - $self->{output}->option_exit(); - } -} - -sub run { - my ($self, %options) = @_; - $self->{p2000} = $options{custom}; - - $self->{p2000}->login(); - $self->manage_selection(); - - my $multiple = 1; - if (scalar(@{$self->{volume_name_selected}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All volumes statistics are ok.'); - } - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "cache_hp_p2000_" . $self->{p2000}->{hostname} . '_' . $self->{mode}); - $self->{new_datas}->{last_timestamp} = time(); - - foreach my $name (sort @{$self->{volume_name_selected}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => $name); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{results}->{$name}, - new_datas => $self->{new_datas}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; + $self->{volume} = {}; + foreach my $name (keys %$result) { + if (defined($self->{option_results}->{name}) && $self->{option_results}->{name} ne '') { + if ((!defined($self->{option_results}->{use_regexp}) && $name ne $self->{option_results}->{name}) | + (defined($self->{option_results}->{use_regexp}) && $name !~ /$self->{option_results}->{name}/) + ) { + $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching volume name.", debug => 1); next; } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{$_}->{obj}->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Volume '$name' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Volume '$name' $short_msg" - ); } - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Volume '$name' $long_msg"); - } + $self->{volume}->{$name} = { display => $name, %{$result->{$name}} }; + } + + if (scalar(keys %{$self->{volume}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No volume found.'); + $self->{output}->option_exit(); } - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); + $self->{cache_name} = 'hp_p2000_' . $options{custom}->{hostname} . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); } 1; diff --git a/storage/hp/p2000/xmlapi/plugin.pm b/storage/hp/p2000/xmlapi/plugin.pm index 37ff01a17..327229683 100644 --- a/storage/hp/p2000/xmlapi/plugin.pm +++ b/storage/hp/p2000/xmlapi/plugin.pm @@ -32,21 +32,15 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'health' => 'storage::hp::p2000::xmlapi::mode::health', - 'list-volumes' => 'storage::hp::p2000::xmlapi::mode::listvolumes', - 'volume-stats' => 'storage::hp::p2000::xmlapi::mode::volumesstats', - ); + 'health' => 'storage::hp::p2000::xmlapi::mode::health', + 'list-volumes' => 'storage::hp::p2000::xmlapi::mode::listvolumes', + 'volume-stats' => 'storage::hp::p2000::xmlapi::mode::volumesstats', + ); $self->{custom_modes}{p2000xml} = 'storage::hp::p2000::xmlapi::custom'; return $self; } -sub init { - my ($self, %options) = @_; - - $self->SUPER::init(%options); -} - 1; __END__ diff --git a/storage/hp/storeonce/restapi/custom/api.pm b/storage/hp/storeonce/restapi/custom/api.pm index 76dc0fd08..53418404c 100644 --- a/storage/hp/storeonce/restapi/custom/api.pm +++ b/storage/hp/storeonce/restapi/custom/api.pm @@ -40,21 +40,18 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s@" => { name => 'hostname' }, - "username:s@" => { name => 'username' }, - "password:s@" => { name => 'password' }, - "proxyurl:s@" => { name => 'proxyurl' }, - "timeout:s@" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s@" => { name => 'hostname' }, + "username:s@" => { name => 'username' }, + "password:s@" => { name => 'password' }, + "timeout:s@" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; @@ -89,7 +86,6 @@ sub check_options { $self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : ''; $self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{password}}) : ''; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef; if (!defined($self->{hostname})) { $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); @@ -110,7 +106,6 @@ sub build_options_for_httplib { $self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{port} = 443; $self->{option_results}->{proto} = 'https'; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; $self->{option_results}->{credentials} = 1; $self->{option_results}->{basic} = 1; $self->{option_results}->{username} = $self->{username}; @@ -131,6 +126,7 @@ sub get { $self->settings(); my $response = $self->{http}->request(url_path => '/storeonceservices' . $options{path}, critical_status => '', warning_status => ''); + my $content; eval { $content = XMLin($response, ForceArray => $options{ForceArray}, KeyAttr => []); @@ -171,18 +167,10 @@ Storeonce username. Storeonce password. -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/storage/hp/storeonce/restapi/mode/clusterusage.pm b/storage/hp/storeonce/restapi/mode/clusterusage.pm index 05b4a3260..d1e27e4eb 100644 --- a/storage/hp/storeonce/restapi/mode/clusterusage.pm +++ b/storage/hp/storeonce/restapi/mode/clusterusage.pm @@ -50,19 +50,21 @@ sub custom_usage_perfdata { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -75,7 +77,7 @@ sub custom_usage_threshold { $threshold_value = $self->{result_values}->{prct_used}; $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -138,7 +140,6 @@ sub set_counters { ], } }, - ]; } @@ -148,15 +149,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "warning-status:s" => { name => 'warning_status', default => '%{health} =~ /warning/' }, - "critical-status:s" => { name => 'critical_status', default => '%{health} =~ /critical/' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '%{health} =~ /warning/' }, + "critical-status:s" => { name => 'critical_status', default => '%{health} =~ /critical/' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } @@ -194,15 +194,16 @@ sub manage_selection { next; } - my $total = (defined($entry->{properties}->{capacity})) ? $entry->{properties}->{capacity} * 1024 * 1024 * 1024 : $entry->{properties}->{localCapacityBytes}; - my $used = $total - (defined($entry->{properties}->{freeSpace})) ? $entry->{properties}->{freeSpace} * 1024 * 1024 * 1024 : $entry->{properties}->{localFreeBytes}; + my $total = defined($entry->{properties}->{capacity}) ? $entry->{properties}->{capacity} * 1024 * 1024 * 1024 : $entry->{properties}->{localCapacityBytes}; + my $used = $total - (defined($entry->{properties}->{freeSpace}) ? $entry->{properties}->{freeSpace} * 1024 * 1024 * 1024 : $entry->{properties}->{localFreeBytes}); $self->{cluster}->{$entry->{properties}->{serialNumber}} = { display => $entry->{properties}->{applianceName}, health => $mapping_health_level{$entry->{properties}->{healthLevel}}, total => $total, used => $used, - dedup => $entry->{properties}->{dedupeRatio} }; + dedup => $entry->{properties}->{dedupeRatio} + }; } } @@ -233,7 +234,7 @@ Filter cluster name (can be a regexp). =item B<--warning-status> -Set warning threshold for status (Default: '%{health} =~ /warning/). +Set warning threshold for status (Default: '%{health} =~ /warning/'). Can used special variables like: %{health}, %{display} =item B<--critical-status> diff --git a/storage/hp/storeonce/restapi/mode/fcsusage.pm b/storage/hp/storeonce/restapi/mode/fcsusage.pm index 2c0487144..714de7392 100644 --- a/storage/hp/storeonce/restapi/mode/fcsusage.pm +++ b/storage/hp/storeonce/restapi/mode/fcsusage.pm @@ -95,12 +95,11 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "warning-status:s" => { name => 'warning_status', default => '%{is_online} == 1 and %{health} =~ /warning/i' }, - "critical-status:s" => { name => 'critical_status', default => '%{is_online} == 1 and %{health} =~ /critical/i' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '%{is_online} == 1 and %{health} =~ /warning/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{is_online} == 1 and %{health} =~ /critical/i' }, + }); return $self; } @@ -155,7 +154,8 @@ sub manage_selection { is_online => $entry->{properties}->{isOnline} eq 'true' ? 1 : 0, used => $entry->{properties}->{diskBytes}, dedup => $entry->{properties}->{dedupeRatio}, - num_items => $entry->{properties}->{numItems} }; + num_items => $entry->{properties}->{numItems} + }; } } diff --git a/storage/hp/storeonce/restapi/mode/nasusage.pm b/storage/hp/storeonce/restapi/mode/nasusage.pm index 9306468f0..cb5d2c9de 100644 --- a/storage/hp/storeonce/restapi/mode/nasusage.pm +++ b/storage/hp/storeonce/restapi/mode/nasusage.pm @@ -95,15 +95,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "warning-nas-status:s" => { name => 'warning_nas_status', default => '%{health} =~ /warning/i' }, - "critical-nas-status:s" => { name => 'critical_nas_status', default => '%{health} =~ /critical/i' }, - "warning-share-status:s" => { name => 'warning_share_status', default => '%{health} =~ /warning/i' }, - "critical-share-status:s" => { name => 'critical_share_status', default => '%{health} =~ /critical/i' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "warning-nas-status:s" => { name => 'warning_nas_status', default => '%{health} =~ /warning/i' }, + "critical-nas-status:s" => { name => 'critical_nas_status', default => '%{health} =~ /critical/i' }, + "warning-share-status:s" => { name => 'warning_share_status', default => '%{health} =~ /warning/i' }, + "critical-share-status:s" => { name => 'critical_share_status', default => '%{health} =~ /critical/i' }, + }); + return $self; } diff --git a/storage/hp/storeonce/restapi/mode/servicesetusage.pm b/storage/hp/storeonce/restapi/mode/servicesetusage.pm index e5580fbda..4c1a33279 100644 --- a/storage/hp/storeonce/restapi/mode/servicesetusage.pm +++ b/storage/hp/storeonce/restapi/mode/servicesetusage.pm @@ -53,19 +53,21 @@ sub custom_usage_perfdata { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -78,7 +80,7 @@ sub custom_usage_threshold { $threshold_value = $self->{result_values}->{prct_used}; $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -151,15 +153,14 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "warning-status:s" => { name => 'warning_status', default => '%{health} =~ /warning/' }, - "critical-status:s" => { name => 'critical_status', default => '%{health} =~ /critical/' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '%{health} =~ /warning/' }, + "critical-status:s" => { name => 'critical_status', default => '%{health} =~ /critical/' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } @@ -167,7 +168,6 @@ sub check_options { my ($self, %options) = @_; $self->SUPER::check_options(%options); - $instance_mode = $self; $self->change_macros(macros => ['warning_status', 'critical_status']); } @@ -205,7 +205,8 @@ sub manage_selection { replication_health => $mapping_health_level{$entry->{properties}->{repHealthLevel}}, total => $entry->{properties}->{capacityBytes}, used => $entry->{properties}->{capacityBytes} - $entry->{properties}->{freeBytes}, - dedup => $entry->{properties}->{dedupeRatio} }; + dedup => $entry->{properties}->{dedupeRatio} + }; } } diff --git a/storage/ibm/DS3000/cli/plugin.pm b/storage/ibm/DS3000/cli/plugin.pm index 1487153a5..af5d8bc38 100644 --- a/storage/ibm/DS3000/cli/plugin.pm +++ b/storage/ibm/DS3000/cli/plugin.pm @@ -32,11 +32,20 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'health-status' => 'centreon::common::smcli::mode::healthstatus', - ); + 'health-status' => 'centreon::common::smcli::mode::healthstatus', + ); $self->{custom_modes}{smcli} = 'centreon::common::smcli::custom::custom'; - $self->{default} = { 'health-status' => { storage_command => 'show storageSubsystem healthstatus;', - smcli_path => '/opt/IBM_DS/client' }, }; + + $self->{default} = { + 'health-status' => { + storage_command => 'show storageSubsystem healthstatus;', + } + }; + $self->{customdefault} = { + 'smcli' => { + smcli_path => '/opt/IBM_DS/client', + } + }; return $self; } diff --git a/storage/ibm/DS4000/cli/plugin.pm b/storage/ibm/DS4000/cli/plugin.pm index 0aa8db903..d50165ded 100644 --- a/storage/ibm/DS4000/cli/plugin.pm +++ b/storage/ibm/DS4000/cli/plugin.pm @@ -32,11 +32,20 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'health-status' => 'centreon::common::smcli::mode::healthstatus', - ); + 'health-status' => 'centreon::common::smcli::mode::healthstatus', + ); $self->{custom_modes}{smcli} = 'centreon::common::smcli::custom::custom'; - $self->{default} = { 'health-status' => { storage_command => 'show storageSubsystem healthstatus;', - smcli_path => '/opt/IBM_DS/client' }, }; + + $self->{default} = { + 'health-status' => { + storage_command => 'show storageSubsystem healthstatus;', + } + }; + $self->{customdefault} = { + 'smcli' => { + smcli_path => '/opt/IBM_DS/client', + } + }; return $self; } diff --git a/storage/ibm/DS5000/cli/plugin.pm b/storage/ibm/DS5000/cli/plugin.pm index f2fa79a27..283d70621 100644 --- a/storage/ibm/DS5000/cli/plugin.pm +++ b/storage/ibm/DS5000/cli/plugin.pm @@ -32,11 +32,20 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'health-status' => 'centreon::common::smcli::mode::healthstatus', - ); + 'health-status' => 'centreon::common::smcli::mode::healthstatus', + ); $self->{custom_modes}{smcli} = 'centreon::common::smcli::custom::custom'; - $self->{default} = { 'health-status' => { storage_command => 'show storageSubsystem healthstatus;', - smcli_path => '/opt/IBM_DS/client' }, }; + + $self->{default} = { + 'health-status' => { + storage_command => 'show storageSubsystem healthstatus;', + } + }; + $self->{customdefault} = { + 'smcli' => { + smcli_path => '/opt/IBM_DS/client', + } + }; return $self; } diff --git a/storage/ibm/fs900/snmp/mode/arraysusage.pm b/storage/ibm/fs900/snmp/mode/arraysusage.pm index ea0f6e1ea..05d019c91 100644 --- a/storage/ibm/fs900/snmp/mode/arraysusage.pm +++ b/storage/ibm/fs900/snmp/mode/arraysusage.pm @@ -28,25 +28,22 @@ use warnings; sub custom_usage_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - - $self->{output}->perfdata_add(label => "used" . $extra_label, - unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-usage'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-usage'), - min => 0, - max => $self->{result_values}->{total}, - ); + $self->{output}->perfdata_add( + label => "used", unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0, max => $self->{result_values}->{total}, + ); } sub custom_usage_threshold { my ($self, %options) = @_; my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{used_prct}, - threshold => [ { label => 'critical-usage', exit_litteral => 'critical' }, - { label => 'warning-usage', exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } diff --git a/storage/ibm/fs900/snmp/mode/components/battery.pm b/storage/ibm/fs900/snmp/mode/components/battery.pm index f2f84e488..193fd9c92 100644 --- a/storage/ibm/fs900/snmp/mode/components/battery.pm +++ b/storage/ibm/fs900/snmp/mode/components/battery.pm @@ -70,13 +70,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Battery '%s' cell '%s' voltage is %s mV", $instance, lc($pretty_cell), $result->{$cell})); } - $self->{output}->perfdata_add(label => 'battery_voltage_' . $instance . '_' . lc($pretty_cell), - unit => 'mV', - value => $result->{$cell}, - warning => $warn, - critical => $crit, - min => 0, - ); + $self->{output}->perfdata_add( + label => 'battery_voltage', unit => 'mV', + nlabel => 'hardware.battery.voltage.millivolt', + instances => [$instance, lc($pretty_cell)], + value => $result->{$cell}, + warning => $warn, + critical => $crit, + min => 0, + ); } } @@ -86,12 +88,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Battery '%s' current is %s", $instance, $result->{batteryChgCurr})); } - $self->{output}->perfdata_add(label => 'battery_current_' . $instance, - value => $result->{batteryChgCurr}, - warning => $warn, - critical => $crit, - min => 0, - ); + $self->{output}->perfdata_add( + label => 'battery_current', + nlabel => 'hardware.battery.current.count', + instances => $instance, + value => $result->{batteryChgCurr}, + warning => $warn, + critical => $crit, + min => 0, + ); } if (defined($result->{batteryRmngCap}) && $result->{batteryRmngCap} =~ /[0-9]/ && defined($result->{batteryFullCap}) && $result->{batteryFullCap} =~ /[0-9]/) { @@ -100,15 +105,17 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Battery '%s' capacity is %s on %s", $instance, $result->{batteryRmngCap}, $result->{batteryFullCap})); } - $self->{output}->perfdata_add(label => 'battery_capacity_' . $instance, - value => $result->{batteryRmngCap}, - warning => $warn, - critical => $crit, - min => 0, - max => $result->{batteryFullCap}, - ); + $self->{output}->perfdata_add( + label => 'battery_capacity', + nlabel => 'hardware.battery.capacity.count', + instances => $instance, + value => $result->{batteryRmngCap}, + warning => $warn, + critical => $crit, + min => 0, max => $result->{batteryFullCap}, + ); } } } -1; \ No newline at end of file +1; diff --git a/storage/ibm/fs900/snmp/mode/components/fan.pm b/storage/ibm/fs900/snmp/mode/components/fan.pm index c0698d9f8..c4a6bfa1e 100644 --- a/storage/ibm/fs900/snmp/mode/components/fan.pm +++ b/storage/ibm/fs900/snmp/mode/components/fan.pm @@ -66,14 +66,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan module '%s' PWM is %s%", $instance, $result->{fanPWM})); } - $self->{output}->perfdata_add(label => 'fan_pwm_' . $instance, - unit => '%', - value => $result->{fanPWM}, - warning => $warn, - critical => $crit, - min => 0, - max => 100, - ); + $self->{output}->perfdata_add( + label => 'fan_pwm', unit => '%', + nlabel => 'hardware.fan.pwm.percentage', + instances => $instance, + value => $result->{fanPWM}, + warning => $warn, + critical => $crit, + min => 0, max => 100, + ); } if (defined($result->{fanTemp}) && $result->{fanTemp} =~ /[0-9]/) { @@ -82,13 +83,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan module '%s' temperature is %s degree centigrade", $instance, $result->{fanTemp} / 10)); } - $self->{output}->perfdata_add(label => 'fan_temp_' . $instance, - unit => 'C', - value => $result->{fanTemp} / 10, - warning => $warn, - critical => $crit, - min => 0, - ); + $self->{output}->perfdata_add( + label => 'fan_temp', unit => 'C', + nlabel => 'hardware.fan.temperature.celsius', + instances => $instance, + value => $result->{fanTemp} / 10, + warning => $warn, + critical => $crit, + min => 0, + ); } foreach my $fan ('fan0', 'fan1', 'fan2', 'fan3') { @@ -98,17 +101,18 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan module '%s' fan '%s' speed is %s%%", $instance, $fan, $result->{$fan})); } - $self->{output}->perfdata_add(label => 'fan_speed_' . $instance . '_' . $fan, - unit => '%', - value => $result->{$fan}, - warning => $warn, - critical => $crit, - min => 0, - max => 100, - ); + $self->{output}->perfdata_add( + label => 'fan_speed', unit => '%', + nlabel => 'hardware.fan.speed.percentage', + instances => [$instance, $fan], + value => $result->{$fan}, + warning => $warn, + critical => $crit, + min => 0, max => 100, + ); } } } } -1; \ No newline at end of file +1; diff --git a/storage/ibm/fs900/snmp/mode/components/flashcard.pm b/storage/ibm/fs900/snmp/mode/components/flashcard.pm index 88c5f701d..3f44cea99 100644 --- a/storage/ibm/fs900/snmp/mode/components/flashcard.pm +++ b/storage/ibm/fs900/snmp/mode/components/flashcard.pm @@ -70,13 +70,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Flashcard '%s' temperature '%s' is %sC", $instance, uc($pretty_temp), $result->{$temp} / 10)); } - $self->{output}->perfdata_add(label => 'flashcard_temperature_' . $instance . '_' . lc($pretty_temp), unit => 'C', - value => $result->{$temp} / 10, - warning => $warn, - critical => $crit, - unit => 'C', - min => 0, - ); + $self->{output}->perfdata_add( + label => 'flashcard_temperature', unit => 'C', + nlabel => 'hardware.flashcard.temperature.celsius', + instances => [$instance, lc($pretty_temp)], + value => $result->{$temp} / 10, + warning => $warn, + critical => $crit, + min => 0, + ); } } @@ -86,13 +88,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Flashcard '%s' power is %sW", $instance, $result->{flashPower})); } - $self->{output}->perfdata_add(label => 'flashcard_power_' . $instance, - unit => 'W', - value => $result->{flashPower}, - warning => $warn, - critical => $crit, - min => 0, - ); + $self->{output}->perfdata_add( + label => 'flashcard_power', unit => 'W', + nlabel => 'hardware.flashcard.power.watt', + instances => $instance, + value => $result->{flashPower}, + warning => $warn, + critical => $crit, + min => 0, + ); } if (defined($result->{flashOverallHealth}) && $result->{flashOverallHealth} =~ /[0-9]/) { @@ -101,16 +105,17 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Flashcard '%s' overall health is %s%%", $instance, $result->{flashOverallHealth})); } - $self->{output}->perfdata_add(label => 'flashcard_overallhealth_' . $instance, - unit => '%', - value => $result->{flashOverallHealth}, - warning => $warn, - critical => $crit, - min => 0, - max => 100, - ); + $self->{output}->perfdata_add( + label => 'flashcard_overallhealth', unit => '%', + nlabel => 'hardware.flashcard.overallhealth.percentage', + instances => $instance, + value => $result->{flashOverallHealth}, + warning => $warn, + critical => $crit, + min => 0, max => 100, + ); } } } -1; \ No newline at end of file +1; diff --git a/storage/ibm/fs900/snmp/mode/components/psu.pm b/storage/ibm/fs900/snmp/mode/components/psu.pm index dac240b63..dec0ba193 100644 --- a/storage/ibm/fs900/snmp/mode/components/psu.pm +++ b/storage/ibm/fs900/snmp/mode/components/psu.pm @@ -89,15 +89,17 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Psu '%s' fan speed is %s rpm", $instance, $result->{psuFan})); } - $self->{output}->perfdata_add(label => 'psu_fan_' . $instance, - unit => 'rpm', - value => $result->{psuFan}, - warning => $warn, - critical => $crit, - min => 0, - ); + $self->{output}->perfdata_add( + label => 'psu_fan', unit => 'rpm', + nlabel => 'hardware.psu.fan.speed.rpm', + instances => $instance, + value => $result->{psuFan}, + warning => $warn, + critical => $crit, + min => 0, + ); } } } -1; \ No newline at end of file +1; diff --git a/storage/ibm/fs900/snmp/mode/fcusage.pm b/storage/ibm/fs900/snmp/mode/fcusage.pm index 8a88a67f1..ddd8eefa9 100644 --- a/storage/ibm/fs900/snmp/mode/fcusage.pm +++ b/storage/ibm/fs900/snmp/mode/fcusage.pm @@ -28,23 +28,22 @@ use warnings; sub custom_bandwidth_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - - $self->{output}->perfdata_add(label => lc($self->{result_values}->{type}) . "_bandwidth" . $extra_label, - unit => 'B/s', - value => $self->{result_values}->{bandwidth}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . lc($self->{result_values}->{type}) . '-bandwidth'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . lc($self->{result_values}->{type}) . '-bandwidth'), - ); + $self->{output}->perfdata_add( + label => lc($self->{result_values}->{type}) . "_bandwidth", unit => 'B/s', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{bandwidth}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0 + ); } sub custom_bandwidth_threshold { my ($self, %options) = @_; my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{bandwidth}, - threshold => [ { label => 'critical-' . lc($self->{result_values}->{type}) . '-bandwidth', exit_litteral => 'critical' }, - { label => 'warning-' . lc($self->{result_values}->{type}) . '-bandwidth', exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -62,7 +61,7 @@ sub custom_bandwidth_calc { $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_fcObject'}; $self->{result_values}->{type} = $options{extra_options}->{type}; - $self->{result_values}->{bandwidth} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{bandwidth}} *1024 * 1024; + $self->{result_values}->{bandwidth} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{bandwidth}} * 1024 * 1024; return 0; } diff --git a/storage/ibm/storwize/ssh/mode/components/systemstats.pm b/storage/ibm/storwize/ssh/mode/components/systemstats.pm index eba14f9e0..bb47e1e39 100644 --- a/storage/ibm/storwize/ssh/mode/components/systemstats.pm +++ b/storage/ibm/storwize/ssh/mode/components/systemstats.pm @@ -53,11 +53,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("System stat '%s' value is '%s'", $_->{stat_name}, $_->{stat_current})); } - $self->{output}->perfdata_add(label => "sstat_" . $_->{stat_name}, - value => $_->{stat_current}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "sstat", + nlabel => 'hardware.systemstats.current.count', + instances => $_->{stat_name}, + value => $_->{stat_current}, + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/storage/ibm/storwize/ssh/mode/poolusage.pm b/storage/ibm/storwize/ssh/mode/poolusage.pm index c3a6a1040..91b032193 100644 --- a/storage/ibm/storwize/ssh/mode/poolusage.pm +++ b/storage/ibm/storwize/ssh/mode/poolusage.pm @@ -50,19 +50,21 @@ sub custom_usage_perfdata { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -75,7 +77,7 @@ sub custom_usage_threshold { $threshold_value = $self->{result_values}->{prct_used}; $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -138,23 +140,22 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /degraded/i' }, - "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /offline/i' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - "hostname:s" => { name => 'hostname' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /degraded/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /offline/i' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "hostname:s" => { name => 'hostname' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options' }, + }); return $self; } @@ -166,7 +167,6 @@ sub check_options { if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') { $self->{option_results}->{remote} = 1; } - $instance_mode = $self; $self->change_macros(macros => ['warning_status', 'critical_status']); } diff --git a/storage/kaminario/restapi/custom/api.pm b/storage/kaminario/restapi/custom/api.pm index c4353f967..acfd96278 100644 --- a/storage/kaminario/restapi/custom/api.pm +++ b/storage/kaminario/restapi/custom/api.pm @@ -40,22 +40,19 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s@" => { name => 'hostname' }, - "username:s@" => { name => 'username' }, - "password:s@" => { name => 'password' }, - "proxyurl:s@" => { name => 'proxyurl' }, - "timeout:s@" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "resolution:s@" => { name => 'resolution' }, - }); + $options{options}->add_options(arguments => { + "hostname:s@" => { name => 'hostname' }, + "username:s@" => { name => 'username' }, + "password:s@" => { name => 'password' }, + "timeout:s@" => { name => 'timeout' }, + "resolution:s@" => { name => 'resolution' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; @@ -90,7 +87,6 @@ sub check_options { $self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : ''; $self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{password}}) : ''; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef; $self->{resolution} = (defined($self->{option_results}->{resolution})) ? shift(@{$self->{option_results}->{resolution}}) : '5m'; if (!defined($self->{hostname})) { @@ -112,7 +108,6 @@ sub build_options_for_httplib { $self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{port} = 443; $self->{option_results}->{proto} = 'https'; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; $self->{option_results}->{credentials} = 1; $self->{option_results}->{basic} = 1; $self->{option_results}->{username} = $self->{username}; @@ -133,7 +128,6 @@ sub get_performance { $self->settings(); my $content = $self->{http}->request(url_path => '/api/v2' . $options{path} . '&__resolution=' . $self->{resolution}, critical_status => '', warning_status => ''); - my $response = $self->{http}->get_response(); my $decoded; eval { @@ -144,7 +138,7 @@ sub get_performance { $self->{output}->option_exit(); } - if ($response->code() != 200) { + if ($self->{http}->get_code() != 200) { $self->{output}->add_option_msg(short_msg => "Connection issue: " . $decoded->{message}); $self->{output}->option_exit(); } @@ -180,18 +174,10 @@ Kaminario username. Kaminario password. -=item B<--proxyurl> - -Proxy URL if any. - =item B<--timeout> Set HTTP timeout in seconds (Default: '10'). -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--resolution> Selected data performance resolution (Default: '5m'). diff --git a/storage/kaminario/restapi/mode/systemusage.pm b/storage/kaminario/restapi/mode/systemusage.pm index dbc63d79f..760146c97 100644 --- a/storage/kaminario/restapi/mode/systemusage.pm +++ b/storage/kaminario/restapi/mode/systemusage.pm @@ -120,9 +120,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } diff --git a/storage/kaminario/restapi/mode/volumeusage.pm b/storage/kaminario/restapi/mode/volumeusage.pm index f54477f7a..ab4815de1 100644 --- a/storage/kaminario/restapi/mode/volumeusage.pm +++ b/storage/kaminario/restapi/mode/volumeusage.pm @@ -79,10 +79,9 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); return $self; } diff --git a/storage/kaminario/restapi/plugin.pm b/storage/kaminario/restapi/plugin.pm index 9c1aefd55..72744a4fd 100644 --- a/storage/kaminario/restapi/plugin.pm +++ b/storage/kaminario/restapi/plugin.pm @@ -31,9 +31,9 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'system-usage' => 'storage::kaminario::restapi::mode::systemusage', - 'volume-usage' => 'storage::kaminario::restapi::mode::volumeusage', - ); + 'system-usage' => 'storage::kaminario::restapi::mode::systemusage', + 'volume-usage' => 'storage::kaminario::restapi::mode::volumeusage', + ); $self->{custom_modes}{api} = 'storage::kaminario::restapi::custom::api'; return $self; diff --git a/storage/netapp/restapi/custom/restapi.pm b/storage/netapp/restapi/custom/restapi.pm index 099b01511..c35eb7353 100644 --- a/storage/netapp/restapi/custom/restapi.pm +++ b/storage/netapp/restapi/custom/restapi.pm @@ -41,25 +41,21 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s@" => { name => 'hostname' }, - "url-path:s@" => { name => 'url_path' }, - "port:s@" => { name => 'port' }, - "proto:s@" => { name => 'proto' }, - "username:s@" => { name => 'username' }, - "password:s@" => { name => 'password' }, - "proxyurl:s@" => { name => 'proxyurl' }, - "timeout:s@" => { name => 'timeout' }, - "ssl:s@" => { name => 'ssl' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - }); + $options{options}->add_options(arguments => { + "hostname:s@" => { name => 'hostname' }, + "url-path:s@" => { name => 'url_path' }, + "port:s@" => { name => 'port' }, + "proto:s@" => { name => 'proto' }, + "username:s@" => { name => 'username' }, + "password:s@" => { name => 'password' }, + "timeout:s@" => { name => 'timeout' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; @@ -97,8 +93,6 @@ sub check_options { $self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : ''; $self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{password}}) : ''; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef; - $self->{ssl} = (defined($self->{option_results}->{ssl})) ? shift(@{$self->{option_results}->{ssl}}) : 'tlsv1'; if (!defined($self->{hostname})) { $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); @@ -120,12 +114,10 @@ sub build_options_for_httplib { $self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{port} = $self->{port}; $self->{option_results}->{proto} = $self->{proto}; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; $self->{option_results}->{credentials} = 1; $self->{option_results}->{basic} = 1; $self->{option_results}->{username} = $self->{username}; $self->{option_results}->{password} = $self->{password}; - $self->{option_results}->{ssl} = $self->{ssl}; $self->{option_results}->{warning_status} = ''; $self->{option_results}->{critical_status} = ''; } @@ -244,18 +236,10 @@ OnCommand API username. OnCommand API password. -=item B<--proxyurl> - -Proxy URL if any - =item B<--timeout> Set HTTP timeout -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =back =head1 DESCRIPTION diff --git a/storage/netapp/restapi/mode/aggregateusage.pm b/storage/netapp/restapi/mode/aggregateusage.pm index 099dff090..0fad8190e 100644 --- a/storage/netapp/restapi/mode/aggregateusage.pm +++ b/storage/netapp/restapi/mode/aggregateusage.pm @@ -25,20 +25,17 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - $self->{output}->perfdata_add(label => 'used' . $extra_label, - unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -46,14 +43,14 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, - threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, - { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -93,16 +90,15 @@ sub custom_usage_calc { sub custom_snapshot_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - $self->{output}->perfdata_add(label => 'snapshot' . $extra_label, - unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'snapshot', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_snapshot_threshold { @@ -110,14 +106,14 @@ sub custom_snapshot_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, - threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, - { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -194,25 +190,17 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "filter-node:s" => { name => 'filter_node' }, - "filter-cluster:s" => { name => 'filter_cluster' }, - "filter-state:s" => { name => 'filter_state' }, - "filter-type:s" => { name => 'filter_type' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); - - return $self; -} + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "filter-node:s" => { name => 'filter_node' }, + "filter-cluster:s" => { name => 'filter_cluster' }, + "filter-state:s" => { name => 'filter_state' }, + "filter-type:s" => { name => 'filter_type' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; + return $self; } sub manage_selection { diff --git a/storage/netapp/restapi/mode/lunusage.pm b/storage/netapp/restapi/mode/lunusage.pm index 94a7abd62..367d6cac3 100644 --- a/storage/netapp/restapi/mode/lunusage.pm +++ b/storage/netapp/restapi/mode/lunusage.pm @@ -25,20 +25,17 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - - $self->{output}->perfdata_add(label => 'used' . $extra_label, - unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -46,14 +43,14 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, - threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, - { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -122,23 +119,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/storage/netapp/restapi/mode/volumeusage.pm b/storage/netapp/restapi/mode/volumeusage.pm index 6ec718b1c..dd161f07f 100644 --- a/storage/netapp/restapi/mode/volumeusage.pm +++ b/storage/netapp/restapi/mode/volumeusage.pm @@ -25,20 +25,17 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - $self->{output}->perfdata_add(label => 'used' . $extra_label, - unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -46,14 +43,14 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, - threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, - { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -94,23 +91,22 @@ sub custom_usage_calc { sub custom_inode_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - - $self->{output}->perfdata_add(label => 'inodes' . $extra_label, - unit => '%', - value => sprintf("%.2f", $self->{result_values}->{prct_used}), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}), - min => 0, max => 100); + $self->{output}->perfdata_add( + label => 'inodes', unit => '%', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => sprintf("%.2f", $self->{result_values}->{prct_used}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0, max => 100 + ); } sub custom_inode_threshold { my ($self, %options) = @_; my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, - threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, - { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -140,15 +136,14 @@ sub custom_inode_calc { sub custom_snapshot_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - - $self->{output}->perfdata_add(label => 'snapshot' . $extra_label, - unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'snapshot', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_snapshot_threshold { @@ -156,14 +151,14 @@ sub custom_snapshot_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, - threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, - { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -199,15 +194,13 @@ sub custom_snapshot_calc { sub custom_compression_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - - $self->{output}->perfdata_add(label => 'compresssaved' . $extra_label, - unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'compresssaved', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total}); } sub custom_compression_threshold { @@ -215,10 +208,10 @@ sub custom_compression_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, @@ -259,15 +252,14 @@ sub custom_compression_calc { sub custom_deduplication_perfdata { my ($self, %options) = @_; - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); - - $self->{output}->perfdata_add(label => 'dedupsaved' . $extra_label, - unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => 'dedupsaved', unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_deduplication_threshold { @@ -275,14 +267,14 @@ sub custom_deduplication_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, - threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, - { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -379,26 +371,18 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "filter-state:s" => { name => 'filter_state' }, - "filter-style:s" => { name => 'filter_style' }, - "filter-type:s" => { name => 'filter_type' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "filter-state:s" => { name => 'filter_state' }, + "filter-style:s" => { name => 'filter_style' }, + "filter-type:s" => { name => 'filter_type' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub manage_selection { my ($self, %options) = @_; diff --git a/storage/netapp/snmp/mode/aggregatestate.pm b/storage/netapp/snmp/mode/aggregatestate.pm index ef3cb4810..5c6c3fe4e 100644 --- a/storage/netapp/snmp/mode/aggregatestate.pm +++ b/storage/netapp/snmp/mode/aggregatestate.pm @@ -20,52 +20,15 @@ package storage::netapp::snmp::mode::aggregatestate; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; - -my $thresholds = { - state => [ - ['online', 'OK'], - ['offline', 'CRITICAL'], - ], - status => [ - ['normal', 'OK'], - ['mirrored', 'OK'], - ['.*', 'CRITICAL'], - ], -}; -my $instance_mode; - -my $maps_counters = { - agg => { - '000_state' => { set => { - key_values => [ { name => 'aggrState' } ], - closure_custom_calc => \&custom_state_calc, - output_template => "State : '%s'", output_error_template => "State : '%s'", - output_use => 'aggrState', - closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&custom_state_threshold, - } - }, - '001_status' => { set => { - key_values => [ { name => 'aggrStatus' } ], - closure_custom_calc => \&custom_status_calc, - output_template => "Status : '%s'", output_error_template => "Status : '%s'", - output_use => 'aggrStatus', - closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&custom_status_threshold, - } - }, - }, -}; sub custom_state_threshold { my ($self, %options) = @_; - return $instance_mode->get_severity(section => 'state', value => $self->{result_values}->{aggrState}); + return $self->{instance_mode}->get_severity(section => 'state', value => $self->{result_values}->{aggrState}); } sub custom_state_calc { @@ -78,7 +41,7 @@ sub custom_state_calc { sub custom_status_threshold { my ($self, %options) = @_; - return $instance_mode->get_severity(section => 'status', value => $self->{result_values}->{aggrStatus}); + return $self->{instance_mode}->get_severity(section => 'status', value => $self->{result_values}->{aggrStatus}); } sub custom_status_calc { @@ -88,48 +51,59 @@ sub custom_status_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'agg', type => 1, cb_prefix_output => 'prefix_agg_output', message_multiple => 'All aggregates are ok' }, + ]; + + $self->{maps_counters}->{agg} = [ + { label => 'state', set => { + key_values => [ { name => 'aggrState' } ], + closure_custom_calc => $self->can('custom_state_calc'), + output_template => "State : '%s'", output_error_template => "State : '%s'", + output_use => 'aggrState', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_state_threshold'), + } + }, + { label => 'status', set => { + key_values => [ { name => 'aggrStatus' } ], + closure_custom_calc => $self->can('custom_status_calc'), + output_template => "Status : '%s'", output_error_template => "Status : '%s'", + output_use => 'aggrStatus', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; +} + +sub prefix_agg_output { + my ($self, %options) = @_; + + return "Aggregate '" . $options{instance_value}->{aggrName} . "' "; +} + sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - }); - - foreach my $key (('agg')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); + return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('agg')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - $instance_mode = $self; - + $self->SUPER::check_options(%options); + $self->{overload_th} = {}; foreach my $val (@{$self->{option_results}->{threshold_overload}}) { if ($val !~ /^(.*?),(.*?),(.*)$/) { @@ -146,67 +120,17 @@ sub check_options { } } -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{agg}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All aggregates status are ok'); - } - - foreach my $id (sort keys %{$self->{agg}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{agg}}) { - my $obj = $maps_counters->{agg}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{agg}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{agg}->{$_}->{obj}->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Aggregate '$self->{agg}->{$id}->{aggrName}' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Aggregate '$self->{agg}->{$id}->{aggrName}' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Aggregate '$self->{agg}->{$id}->{aggrName}' Usage $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} +my $thresholds = { + state => [ + ['online', 'OK'], + ['offline', 'CRITICAL'], + ], + status => [ + ['normal', 'OK'], + ['mirrored', 'OK'], + ['.*', 'CRITICAL'], + ], +}; sub get_severity { my ($self, %options) = @_; @@ -236,28 +160,30 @@ sub manage_selection { my $oid_aggrName = '.1.3.6.1.4.1.789.1.5.11.1.2'; my $oid_aggrState = '.1.3.6.1.4.1.789.1.5.11.1.5'; my $oid_aggrStatus = '.1.3.6.1.4.1.789.1.5.11.1.6'; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_aggrName }, - { oid => $oid_aggrState }, - { oid => $oid_aggrStatus }, - ], - , nothing_quit => 1); - + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $oid_aggrName }, + { oid => $oid_aggrState }, + { oid => $oid_aggrStatus }, + ], + nothing_quit => 1 + ); + $self->{agg} = {}; - foreach my $oid (keys %{$self->{results}->{$oid_aggrState}}) { + foreach my $oid (keys %{$snmp_result->{$oid_aggrState}}) { next if ($oid !~ /^$oid_aggrState\.(.*)$/); my $instance = $1; - my $name = $self->{results}->{$oid_aggrName}->{$oid_aggrName . '.' . $instance}; - my $state = $self->{results}->{$oid_aggrState}->{$oid_aggrState . '.' . $instance}; - my $status = $self->{results}->{$oid_aggrStatus}->{$oid_aggrStatus . '.' . $instance}; + my $name = $snmp_result->{$oid_aggrName}->{$oid_aggrName . '.' . $instance}; + my $state = $snmp_result->{$oid_aggrState}->{$oid_aggrState . '.' . $instance}; + my $status = $snmp_result->{$oid_aggrStatus}->{$oid_aggrStatus . '.' . $instance}; if (!defined($state) || $state eq '') { - $self->{output}->output_add(long_msg => "Skipping '" . $name . "': state value not set."); + $self->{output}->output_add(long_msg => "skipping '" . $name . "': state value not set."); next; } 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 name."); + $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter name."); next; } diff --git a/storage/netapp/snmp/mode/components/fan.pm b/storage/netapp/snmp/mode/components/fan.pm index f4a510ec0..7c2110490 100644 --- a/storage/netapp/snmp/mode/components/fan.pm +++ b/storage/netapp/snmp/mode/components/fan.pm @@ -78,11 +78,15 @@ sub check { short_msg => sprintf("Shelve '%s' Fan '%s' speed is '%s'", $shelf_addr, $num, $current_value)); } - $self->{output}->perfdata_add(label => "speed_" . $shelf_addr . "_" . $num, unit => 'rpm', - value => $current_value, - warning => $warn, - critical => $crit, - min => 0); + $self->{output}->perfdata_add( + label => "speed", unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => [$shelf_addr, $num], + value => $current_value, + warning => $warn, + critical => $crit, + min => 0 + ); } } } diff --git a/storage/netapp/snmp/mode/components/temperature.pm b/storage/netapp/snmp/mode/components/temperature.pm index b66a73235..0eac269f2 100644 --- a/storage/netapp/snmp/mode/components/temperature.pm +++ b/storage/netapp/snmp/mode/components/temperature.pm @@ -127,10 +127,14 @@ sub check { $shelf_addr, $num, $current_value)); } - $self->{output}->perfdata_add(label => "temp_" . $shelf_addr . "_" . $num, unit => 'C', - value => $current_value, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "temp", unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => [$shelf_addr, $num], + value => $current_value, + warning => $warn, + critical => $crit + ); } } } diff --git a/storage/netapp/snmp/mode/components/voltage.pm b/storage/netapp/snmp/mode/components/voltage.pm index 149786905..eb1d10474 100644 --- a/storage/netapp/snmp/mode/components/voltage.pm +++ b/storage/netapp/snmp/mode/components/voltage.pm @@ -122,12 +122,16 @@ sub check { $shelf_addr, $num, $current_value)); } - $self->{output}->perfdata_add(label => "volt_" . $shelf_addr . "_" . $num, unit => 'mV', - value => $current_value, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "volt", unit => 'mV', + nlabel => 'hardware.voltage.millivolt', + instances => [$shelf_addr, $num], + value => $current_value, + warning => $warn, + critical => $crit + ); } } } -1; \ No newline at end of file +1; diff --git a/storage/netapp/snmp/mode/cpstatistics.pm b/storage/netapp/snmp/mode/cpstatistics.pm index c52f74444..0dbae0fed 100644 --- a/storage/netapp/snmp/mode/cpstatistics.pm +++ b/storage/netapp/snmp/mode/cpstatistics.pm @@ -20,114 +20,122 @@ package storage::netapp::snmp::mode::cpstatistics; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::statefile; -use centreon::plugins::values; +use Digest::MD5 qw(md5_hex); -my $maps_counters = { - timer => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'timer', diff => 1 }, ], - output_template => 'CP timer : %s', - perfdatas => [ - { value => 'timer_absolute', template => '%d', min => 0 }, - ], - } - }, - snapshot => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'snapshot', diff => 1 }, ], - output_template => 'CP snapshot : %s', - perfdatas => [ - { value => 'snapshot_absolute', template => '%d', min => 0 }, - ], - } - }, - lowerwater => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'lowerwater', diff => 1 }, ], - output_template => 'CP low water mark : %s', - perfdatas => [ - { value => 'lowerwater_absolute', template => '%d', min => 0 }, - ], - } - }, - highwater => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'highwater', diff => 1 }, ], - output_template => 'CP high water mark : %s', - perfdatas => [ - { value => 'highwater_absolute', template => '%d', min => 0 }, - ], - } - }, - logfull => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'logfull', diff => 1 }, ], - output_template => 'CP nv-log full : %s', - perfdatas => [ - { value => 'logfull_absolute', template => '%d', min => 0 }, - ], - } - }, - back => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'back', diff => 1 }, ], - output_template => 'CP back-to-back : %s', - perfdatas => [ - { value => 'back_absolute', template => '%d', min => 0 }, - ], - } - }, - flush => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'flush', diff => 1 }, ], - output_template => 'CP flush unlogged write data : %s', - perfdatas => [ - { value => 'flush_absolute', template => '%d', min => 0 }, - ], - } - }, - sync => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'sync', diff => 1 }, ], - output_template => 'CP sync requests : %s', - perfdatas => [ - { value => 'sync_absolute', template => '%d', min => 0 }, - ], - } - }, - lowvbuf => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'lowvbuf', diff => 1 }, ], - output_template => 'CP low virtual buffers : %s', - perfdatas => [ - { value => 'lowvbuf_absolute', template => '%d', min => 0 }, - ], - } - }, - deferred => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'deferred', diff => 1 }, ], - output_template => 'CP deferred : %s', - perfdatas => [ - { value => 'deferred_absolute', template => '%d', min => 0 }, - ], - } - }, - lowdatavecs => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'lowdatavecs', diff => 1 }, ], - output_template => 'CP low datavecs : %s', - perfdatas => [ - { value => 'lowdatavecs_absolute', template => '%d', min => 0 }, - ], - } - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1, -11 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'timer', nlabel => 'storage.cp.timer.operations.count', display_ok => 0, set => { + key_values => [ { name => 'timer', diff => 1 }, ], + output_template => 'CP timer : %s', + perfdatas => [ + { value => 'timer_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'snapshot', nlabel => 'storage.cp.snapshot.operations.count', display_ok => 0, set => { + key_values => [ { name => 'snapshot', diff => 1 }, ], + output_template => 'CP snapshot : %s', + perfdatas => [ + { value => 'snapshot_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'lowerwater', nlabel => 'storage.cp.lowerwatermark.operations.count', display_ok => 0, set => { + key_values => [ { name => 'lowerwater', diff => 1 }, ], + output_template => 'CP low water mark : %s', + perfdatas => [ + { value => 'lowerwater_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'highwater', nlabel => 'storage.cp.highwatermark.operations.count', display_ok => 0, set => { + key_values => [ { name => 'highwater', diff => 1 }, ], + output_template => 'CP high water mark : %s', + perfdatas => [ + { value => 'highwater_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'logfull', nlabel => 'storage.cp.logfull.operations.count', display_ok => 0, set => { + key_values => [ { name => 'logfull', diff => 1 }, ], + output_template => 'CP nv-log full : %s', + perfdatas => [ + { value => 'logfull_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'back', nlabel => 'storage.cp.back2back.operations.count', display_ok => 0, set => { + key_values => [ { name => 'back', diff => 1 }, ], + output_template => 'CP back-to-back : %s', + perfdatas => [ + { value => 'back_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'flush', nlabel => 'storage.cp.flushunlog.operations.count', display_ok => 0, set => { + key_values => [ { name => 'flush', diff => 1 }, ], + output_template => 'CP flush unlogged write data : %s', + perfdatas => [ + { value => 'flush_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'sync', nlabel => 'storage.cp.syncrequests.operations.count', display_ok => 0, set => { + key_values => [ { name => 'sync', diff => 1 }, ], + output_template => 'CP sync requests : %s', + perfdatas => [ + { value => 'sync_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'lowvbuf', nlabel => 'storage.cp.lowvirtualbuffers.operations.count', display_ok => 0, set => { + key_values => [ { name => 'lowvbuf', diff => 1 }, ], + output_template => 'CP low virtual buffers : %s', + perfdatas => [ + { value => 'lowvbuf_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'deferred', nlabel => 'storage.cp.deferred.operations.count', display_ok => 0, set => { + key_values => [ { name => 'deferred', diff => 1 }, ], + output_template => 'CP deferred : %s', + perfdatas => [ + { value => 'deferred_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'lowdatavecs', nlabel => 'storage.cp.lowdatavecs.operations.count', display_ok => 0, set => { + key_values => [ { name => 'lowdatavecs', diff => 1 }, ], + output_template => 'CP low datavecs : %s', + perfdatas => [ + { value => 'lowdatavecs_absolute', template => '%d', min => 0 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} my $oid_cpFromTimerOps = '.1.3.6.1.4.1.789.1.2.6.2.0'; my $oid_cpFromSnapshotOps = '.1.3.6.1.4.1.789.1.2.6.3.0'; @@ -142,122 +150,40 @@ my $oid_cpFromLowVbufOps = '.1.3.6.1.4.1.789.1.2.6.11.0'; my $oid_cpFromCpDeferredOps = '.1.3.6.1.4.1.789.1.2.6.12.0'; my $oid_cpFromLowDatavecsOps = '.1.3.6.1.4.1.789.1.2.6.13.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 => - { - }); - - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - foreach (keys %{$maps_counters}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - $self->manage_selection(); - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "cache_netapp_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode}); - $self->{new_datas}->{last_timestamp} = time(); - - $self->{output}->output_add(severity => 'OK', - short_msg => 'All CP statistics are ok'); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => 'global'); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{global}, - new_datas => $self->{new_datas}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $self->{output}->output_add(long_msg => $output); - $maps_counters->{$_}->{obj}->perfdata(); - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "$short_msg" - ); - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; + + my $request = [ + $oid_cpFromTimerOps, $oid_cpFromSnapshotOps, + $oid_cpFromLowWaterOps, $oid_cpFromHighWaterOps, + $oid_cpFromLogFullOps, $oid_cpFromCpOps, + $oid_cpTotalOps, $oid_cpFromFlushOps, + $oid_cpFromSyncOps, $oid_cpFromLowVbufOps, + $oid_cpFromCpDeferredOps, $oid_cpFromLowDatavecsOps + ]; - my $request = [$oid_cpFromTimerOps, $oid_cpFromSnapshotOps, - $oid_cpFromLowWaterOps, $oid_cpFromHighWaterOps, - $oid_cpFromLogFullOps, $oid_cpFromCpOps, - $oid_cpTotalOps, $oid_cpFromFlushOps, - $oid_cpFromSyncOps, $oid_cpFromLowVbufOps, - $oid_cpFromCpDeferredOps, $oid_cpFromLowDatavecsOps]; - - $self->{results} = $self->{snmp}->get_leef(oids => $request, nothing_quit => 1); - + my $snmp_result = $options{snmp}->get_leef(oids => $request, nothing_quit => 1); + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'All CP statistics are ok' + ); + $self->{global} = {}; - $self->{global}->{timer} = defined($self->{results}->{$oid_cpFromTimerOps}) ? $self->{results}->{$oid_cpFromTimerOps} : 0; - $self->{global}->{snapshot} = defined($self->{results}->{$oid_cpFromSnapshotOps}) ? $self->{results}->{$oid_cpFromSnapshotOps} : 0; - $self->{global}->{lowerwater} = defined($self->{results}->{$oid_cpFromLowWaterOps}) ? $self->{results}->{$oid_cpFromLowWaterOps} : 0; - $self->{global}->{highwater} = defined($self->{results}->{$oid_cpFromHighWaterOps}) ? $self->{results}->{$oid_cpFromHighWaterOps} : 0; - $self->{global}->{logfull} = defined($self->{results}->{$oid_cpFromLogFullOps}) ? $self->{results}->{$oid_cpFromLogFullOps} : 0; - $self->{global}->{back} = defined($self->{results}->{$oid_cpFromCpOps}) ? $self->{results}->{$oid_cpFromCpOps} : 0; - $self->{global}->{flush} = defined($self->{results}->{$oid_cpFromFlushOps}) ? $self->{results}->{$oid_cpFromFlushOps} : 0; - $self->{global}->{sync} = defined($self->{results}->{$oid_cpFromSyncOps}) ? $self->{results}->{$oid_cpFromSyncOps} : 0; - $self->{global}->{lowvbuf} = defined($self->{results}->{$oid_cpFromLowVbufOps}) ? $self->{results}->{$oid_cpFromLowVbufOps} : 0; - $self->{global}->{deferred} = defined($self->{results}->{$oid_cpFromCpDeferredOps}) ? $self->{results}->{$oid_cpFromCpDeferredOps} : 0; - $self->{global}->{lowdatavecs} = defined($self->{results}->{$oid_cpFromLowDatavecsOps}) ? $self->{results}->{$oid_cpFromLowDatavecsOps} : 0; + $self->{global}->{timer} = defined($snmp_result->{$oid_cpFromTimerOps}) ? $snmp_result->{$oid_cpFromTimerOps} : undef; + $self->{global}->{snapshot} = defined($snmp_result->{$oid_cpFromSnapshotOps}) ? $snmp_result->{$oid_cpFromSnapshotOps} : undef; + $self->{global}->{lowerwater} = defined($snmp_result->{$oid_cpFromLowWaterOps}) ? $snmp_result->{$oid_cpFromLowWaterOps} : undef; + $self->{global}->{highwater} = defined($snmp_result->{$oid_cpFromHighWaterOps}) ? $snmp_result->{$oid_cpFromHighWaterOps} : undef; + $self->{global}->{logfull} = defined($snmp_result->{$oid_cpFromLogFullOps}) ? $snmp_result->{$oid_cpFromLogFullOps} : undef; + $self->{global}->{back} = defined($snmp_result->{$oid_cpFromCpOps}) ? $snmp_result->{$oid_cpFromCpOps} : undef; + $self->{global}->{flush} = defined($snmp_result->{$oid_cpFromFlushOps}) ? $snmp_result->{$oid_cpFromFlushOps} : undef; + $self->{global}->{sync} = defined($snmp_result->{$oid_cpFromSyncOps}) ? $snmp_result->{$oid_cpFromSyncOps} : undef; + $self->{global}->{lowvbuf} = defined($snmp_result->{$oid_cpFromLowVbufOps}) ? $snmp_result->{$oid_cpFromLowVbufOps} : undef; + $self->{global}->{deferred} = defined($snmp_result->{$oid_cpFromCpDeferredOps}) ? $snmp_result->{$oid_cpFromCpDeferredOps} : undef; + $self->{global}->{lowdatavecs} = defined($snmp_result->{$oid_cpFromLowDatavecsOps}) ? $snmp_result->{$oid_cpFromLowDatavecsOps} : undef; + + $self->{cache_name} = "cache_netapp_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; @@ -285,4 +211,4 @@ Can be: 'timer', 'snapshot', 'lowerwater', 'highwater', =back =cut - \ No newline at end of file + diff --git a/storage/netapp/snmp/mode/filesys.pm b/storage/netapp/snmp/mode/filesys.pm index bb86a9bd5..5afa3674b 100644 --- a/storage/netapp/snmp/mode/filesys.pm +++ b/storage/netapp/snmp/mode/filesys.pm @@ -71,31 +71,31 @@ sub set_counters { ]; } -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; return if ($self->{result_values}->{total} <= 0); my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -104,12 +104,12 @@ sub custom_usage_threshold { return 'ok' if ($self->{result_values}->{total} <= 0); my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -166,21 +166,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - "filter-name:s" => { name => 'filter_name' }, - "filter-type:s" => { name => 'filter_type' }, - }); - return $self; -} + $options{options}->add_options(arguments => { + 'units:s' => { name => 'units', default => '%' }, + 'free' => { name => 'free' }, + 'filter-name:s' => { name => 'filter_name' }, + 'filter-type:s' => { name => 'filter_type' }, + 'filter-vserver:s' => { name => 'filter_vserver' }, + }); -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; + return $self; } my %map_types = ( @@ -200,6 +194,7 @@ my $mapping2 = { dfPerCentInodeCapacity => { oid => '.1.3.6.1.4.1.789.1.5.4.1.9' }, df64TotalKBytes => { oid => '.1.3.6.1.4.1.789.1.5.4.1.29' }, df64UsedKBytes => { oid => '.1.3.6.1.4.1.789.1.5.4.1.30' }, + dfVserver => { oid => '.1.3.6.1.4.1.789.1.5.4.1.34' }, dfCompressSavedPercent => { oid => '.1.3.6.1.4.1.789.1.5.4.1.38' }, dfDedupeSavedPercent => { oid => '.1.3.6.1.4.1.789.1.5.4.1.40' }, }; @@ -213,6 +208,7 @@ sub manage_selection { $mapping2->{dfPerCentInodeCapacity}->{oid}, $mapping2->{dfCompressSavedPercent}->{oid}, $mapping2->{dfDedupeSavedPercent}->{oid}, + $mapping2->{dfVserver}->{oid}, ); if (!$options{snmp}->is_snmpv1()) { push @oids, $mapping2->{df64TotalKBytes}->{oid}; @@ -222,7 +218,14 @@ sub manage_selection { my $results; if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '') { - $results = $options{snmp}->get_multiple_table(oids => [{oid => $mapping->{dfType}->{oid}}, {oid => $mapping2->{dfFileSys}->{oid}}], return_type => 1, nothing_quit => 1); + $results = $options{snmp}->get_multiple_table( + oids => [ + { oid => $mapping->{dfType}->{oid} }, + { oid => $mapping2->{dfFileSys}->{oid} } + ], + return_type => 1, + nothing_quit => 1 + ); } else { $results = $options{snmp}->get_table(oid => $mapping2->{dfFileSys}->{oid}, nothing_quit => 1); } @@ -251,19 +254,25 @@ sub manage_selection { $self->{fs} = {}; $options{snmp}->load(oids => \@oids, instances => \@fs_selected); - my $result2 = $options{snmp}->get_leef(nothing_quit => 1); + my $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); foreach my $instance (sort @fs_selected) { - $self->{fs}->{$instance} = { display => $results->{$mapping2->{dfFileSys}->{oid} . '.' . $instance}}; - $self->{fs}->{$instance}->{total} = $result2->{$mapping2->{dfKBytesTotal}->{oid} . '.' . $instance} * 1024; - $self->{fs}->{$instance}->{used} = $result2->{$mapping2->{dfKBytesUsed}->{oid} . '.' . $instance} * 1024; - if (defined($result2->{$mapping2->{df64TotalKBytes}->{oid} . '.' . $instance}) && $result2->{$mapping2->{df64TotalKBytes}->{oid} . '.' . $instance} > 0) { - $self->{fs}->{$instance}->{total} = $result2->{$mapping2->{df64TotalKBytes}->{oid} . '.' . $instance} * 1024; - $self->{fs}->{$instance}->{used} = $result2->{$mapping2->{df64UsedKBytes}->{oid} . '.' . $instance} * 1024; + my $result2 = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result, instance => $instance); + + $self->{fs}->{$instance} = { + display => defined($result2->{dfVserver}) && $result2->{dfVserver} ne '' ? + $result2->{dfVserver} . ':' . $results->{$mapping2->{dfFileSys}->{oid} . '.' . $instance} : + $results->{$mapping2->{dfFileSys}->{oid} . '.' . $instance} + }; + $self->{fs}->{$instance}->{total} = $result2->{dfKBytesTotal} * 1024; + $self->{fs}->{$instance}->{used} = $result2->{dfKBytesUsed} * 1024; + if (defined($result2->{df64TotalKBytes}) && $result2->{df64TotalKBytes} > 0) { + $self->{fs}->{$instance}->{total} = $result2->{df64TotalKBytes} * 1024; + $self->{fs}->{$instance}->{used} = $result2->{df64UsedKBytes} * 1024; } - $self->{fs}->{$instance}->{dfCompressSavedPercent} = $result2->{$mapping2->{dfCompressSavedPercent}->{oid} . '.' . $instance}; - $self->{fs}->{$instance}->{dfDedupeSavedPercent} = $result2->{$mapping2->{dfDedupeSavedPercent}->{oid} . '.' . $instance}; + $self->{fs}->{$instance}->{dfCompressSavedPercent} = $result2->{dfCompressSavedPercent}; + $self->{fs}->{$instance}->{dfDedupeSavedPercent} = $result2->{dfDedupeSavedPercent}; if ($self->{fs}->{$instance}->{total} > 0) { - $self->{fs}->{$instance}->{dfPerCentInodeCapacity} = $result2->{$mapping2->{dfPerCentInodeCapacity}->{oid} . '.' . $instance}; + $self->{fs}->{$instance}->{dfPerCentInodeCapacity} = $result2->{dfPerCentInodeCapacity}; } } } @@ -300,6 +309,10 @@ Thresholds are on free space left. Filter by filesystem name (can be a regexp). +=item B<--filter-vserver> + +Filter by vserver name (can be a regexp). + =item B<--filter-type> Filter filesystem type (can be a regexp. Example: 'flexibleVolume|aggregate'). diff --git a/storage/netapp/snmp/mode/globalstatus.pm b/storage/netapp/snmp/mode/globalstatus.pm index 2ab9bfc62..cb26ba1c4 100644 --- a/storage/netapp/snmp/mode/globalstatus.pm +++ b/storage/netapp/snmp/mode/globalstatus.pm @@ -20,43 +20,56 @@ package storage::netapp::snmp::mode::globalstatus; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::statefile; -use centreon::plugins::values; +use Digest::MD5 qw(md5_hex); -my $maps_counters = { - read => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'read', diff => 1 }, - ], - per_second => 1, - output_template => 'Read I/O : %s %s/s', - output_change_bytes => 1, - perfdatas => [ - { value => 'read_per_second', template => '%d', - unit => 'B/s', min => 0 }, - ], - } - }, - write => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'write', diff => 1 }, - ], - per_second => 1, - output_template => 'Write I/O : %s %s/s', - output_change_bytes => 1, - perfdatas => [ - { value => 'write_per_second', template => '%d', - unit => 'B/s', min => 0 }, - ], - } - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'read', nlabel => 'storage.io.read.usage.bytespersecond', set => { + key_values => [ { name => 'read', diff => 1 } ], + per_second => 1, + output_template => 'Read I/O : %s %s/s', + output_change_bytes => 1, + perfdatas => [ + { value => 'read_per_second', template => '%d', + unit => 'B/s', min => 0 }, + ], + } + }, + { label => 'write', nlabel => 'storage.io.write.usage.bytespersecond', set => { + key_values => [ { name => 'write', diff => 1 } ], + per_second => 1, + output_template => 'Write I/O : %s %s/s', + output_change_bytes => 1, + perfdatas => [ + { value => 'write_per_second', template => '%d', + unit => 'B/s', min => 0 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} my %states = ( 1 => ['other', 'WARNING'], @@ -83,126 +96,40 @@ my $oid_miscLowDiskReadBytes = '.1.3.6.1.4.1.789.1.2.2.16.0'; my $oid_miscHighDiskWriteBytes = '.1.3.6.1.4.1.789.1.2.2.17.0'; my $oid_miscLowDiskWriteBytes = '.1.3.6.1.4.1.789.1.2.2.18.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 => - { - }); - - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - foreach (keys %{$maps_counters}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - $self->manage_selection(); - - $self->{results}->{$oid_miscGlobalStatusMessage} =~ s/\n//g; - $self->{output}->output_add(severity => ${$states{$self->{results}->{$oid_miscGlobalStatus}}}[1], - short_msg => sprintf("Overall global status is '%s' [message: '%s']", - ${$states{$self->{results}->{$oid_miscGlobalStatus}}}[0], $self->{results}->{$oid_miscGlobalStatusMessage})); - $self->{results}->{$oid_fsStatusMessage} =~ s/\n//g; - $self->{output}->output_add(severity => ${$fs_states{$self->{results}->{$oid_fsOverallStatus}}}[1], - short_msg => sprintf("Overall file system status is '%s' [message: '%s']", - ${$fs_states{$self->{results}->{$oid_fsOverallStatus}}}[0], $self->{results}->{$oid_fsStatusMessage})); - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "cache_netapp_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode}); - $self->{new_datas}->{last_timestamp} = time(); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => 'global'); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{global}, - new_datas => $self->{new_datas}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{$_}->{obj}->perfdata(); - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "$short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "$long_msg"); - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; - my $request = [$oid_fsOverallStatus, $oid_fsStatusMessage, - $oid_miscGlobalStatus, $oid_miscGlobalStatusMessage, - $oid_miscHighDiskReadBytes, $oid_miscLowDiskReadBytes, - $oid_miscHighDiskWriteBytes, $oid_miscLowDiskWriteBytes]; - if (!$self->{snmp}->is_snmpv1()) { + my $request = [ + $oid_fsOverallStatus, $oid_fsStatusMessage, + $oid_miscGlobalStatus, $oid_miscGlobalStatusMessage, + $oid_miscHighDiskReadBytes, $oid_miscLowDiskReadBytes, + $oid_miscHighDiskWriteBytes, $oid_miscLowDiskWriteBytes + ]; + if (!$options{snmp}->is_snmpv1()) { push @{$request}, ($oid_misc64DiskReadBytes, $oid_misc64DiskWriteBytes); } - $self->{results} = $self->{snmp}->get_leef(oids => $request, nothing_quit => 1); + my $snmp_result = $options{snmp}->get_leef(oids => $request, nothing_quit => 1); $self->{global} = {}; - $self->{global}->{read} = defined($self->{results}->{$oid_misc64DiskReadBytes}) ? - $self->{results}->{$oid_misc64DiskReadBytes} : - ($self->{results}->{$oid_miscHighDiskReadBytes} << 32) + $self->{results}->{$oid_miscLowDiskReadBytes}; - $self->{global}->{write} = defined($self->{results}->{$oid_misc64DiskWriteBytes}) ? - $self->{results}->{$oid_misc64DiskWriteBytes} : - ($self->{results}->{$oid_miscHighDiskWriteBytes} << 32) + $self->{results}->{$oid_miscLowDiskWriteBytes}; + $self->{global}->{read} = defined($snmp_result->{$oid_misc64DiskReadBytes}) ? + $snmp_result->{$oid_misc64DiskReadBytes} : + ($snmp_result->{$oid_miscHighDiskReadBytes} << 32) + $snmp_result->{$oid_miscLowDiskReadBytes}; + $self->{global}->{write} = defined($snmp_result->{$oid_misc64DiskWriteBytes}) ? + $snmp_result->{$oid_misc64DiskWriteBytes} : + ($snmp_result->{$oid_miscHighDiskWriteBytes} << 32) + $snmp_result->{$oid_miscLowDiskWriteBytes}; + $snmp_result->{$oid_miscGlobalStatusMessage} =~ s/\n//g; + $self->{output}->output_add(severity => ${$states{$snmp_result->{$oid_miscGlobalStatus}}}[1], + short_msg => sprintf("Overall global status is '%s' [message: '%s']", + ${$states{$snmp_result->{$oid_miscGlobalStatus}}}[0], $snmp_result->{$oid_miscGlobalStatusMessage})); + $snmp_result->{$oid_fsStatusMessage} =~ s/\n//g; + $self->{output}->output_add(severity => ${$fs_states{$snmp_result->{$oid_fsOverallStatus}}}[1], + short_msg => sprintf("Overall file system status is '%s' [message: '%s']", + ${$fs_states{$snmp_result->{$oid_fsOverallStatus}}}[0], $snmp_result->{$oid_fsStatusMessage})); + + $self->{cache_name} = "cache_netapp_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; @@ -229,4 +156,4 @@ Can be: 'read', 'write'. =back =cut - \ No newline at end of file + diff --git a/storage/netapp/snmp/mode/listfilesys.pm b/storage/netapp/snmp/mode/listfilesys.pm index c862d4944..3829e04e2 100644 --- a/storage/netapp/snmp/mode/listfilesys.pm +++ b/storage/netapp/snmp/mode/listfilesys.pm @@ -25,33 +25,17 @@ use base qw(centreon::plugins::mode); use strict; use warnings; -my $oid_dfFileSys = '.1.3.6.1.4.1.789.1.5.4.1.2'; -my $oid_dfType = '.1.3.6.1.4.1.789.1.5.4.1.23'; -my $oid_dfKBytesTotal = '.1.3.6.1.4.1.789.1.5.4.1.3'; -my $oid_df64TotalKBytes = '.1.3.6.1.4.1.789.1.5.4.1.29'; - -my %map_types = ( - 1 => 'traditionalVolume', - 2 => 'flexibleVolume', - 3 => 'aggregate', - 4 => 'stripedAggregate', - 5 => 'stripedVolume' -); - 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 => - { - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - "type:s" => { name => 'type' }, - "skip-total-zero" => { name => 'skip_total_zero' }, - }); - $self->{filesys_id_selected} = []; + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' }, + 'filter-type:s' => { name => 'filter_type' }, + 'skip-total-zero' => { name => 'skip_total_zero' }, + }); return $self; } @@ -61,71 +45,75 @@ sub check_options { $self->SUPER::init(%options); } +my %map_types = ( + 1 => 'traditionalVolume', + 2 => 'flexibleVolume', + 3 => 'aggregate', + 4 => 'stripedAggregate', + 5 => 'stripedVolume' +); + +my $mapping = { + dfFileSys => { oid => '.1.3.6.1.4.1.789.1.5.4.1.2' }, + dfKBytesTotal => { oid => '.1.3.6.1.4.1.789.1.5.4.1.3' }, + dfType => { oid => '.1.3.6.1.4.1.789.1.5.4.1.23', map => \%map_types }, + df64TotalKBytes => { oid => '.1.3.6.1.4.1.789.1.5.4.1.29' }, + dfVserver => { oid => '.1.3.6.1.4.1.789.1.5.4.1.34' }, +}; + sub manage_selection { my ($self, %options) = @_; - $self->{result_names} = $self->{snmp}->get_table(oid => $oid_dfFileSys, nothing_quit => 1); - $self->{result_types} = $self->{snmp}->get_table(oid => $oid_dfType, nothing_quit => 1); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{result_names}})) { - next if ($oid !~ /\.([0-9]+)$/); + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $mapping->{dfFileSys}->{oid} }, + { oid => $mapping->{dfKBytesTotal}->{oid} }, + { oid => $mapping->{dfType}->{oid} }, + { oid => $mapping->{df64TotalKBytes}->{oid} }, + { oid => $mapping->{dfVserver}->{oid} }, + ], + return_type => 1, + nothing_quit => 1 + ); + + $self->{fs} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{dfFileSys}->{oid}\.(.*)$/); my $instance = $1; - my $type = $map_types{$self->{result_types}->{$oid_dfType . '.' . $instance}}; - - # Get all without a name - if (!defined($self->{option_results}->{name})) { - push @{$self->{filesys_id_selected}}, $instance; + 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->{dfFileSys} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{dfFileSys} . "': no matching filter.", debug => 1); next; } - - if (defined($self->{option_results}->{type}) && $type !~ /$self->{option_results}->{type}/i) { - $self->{output}->output_add(long_msg => "Skipping filesys '" . $self->{result_names}->{$oid} . "': no matching filter type"); + if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && + $result->{dfType} !~ /$self->{option_results}->{filter_type}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{dfFileSys} . "': no matching filter.", debug => 1); next; } - if (!defined($self->{option_results}->{use_regexp}) && $self->{result_names}->{$oid} ne $self->{option_results}->{name}) { - $self->{output}->output_add(long_msg => "Skipping filesys '" . $self->{result_names}->{$oid} . "': no matching filter name"); - next; - } - if (defined($self->{option_results}->{use_regexp}) && $self->{result_names}->{$oid} !~ /$self->{option_results}->{name}/) { - $self->{output}->output_add(long_msg => "Skipping filesys '" . $self->{result_names}->{$oid} . "': no matching filter name (regexp)"); - next; - } - - push @{$self->{filesys_id_selected}}, $instance; + $self->{fs}->{$instance} = { + name => $result->{dfFileSys}, + total => defined($result->{df64TotalKBytes}) ? $result->{df64TotalKBytes} * 1024 : $result->{dfKBytesTotal} * 1024, + type => $result->{dfType}, + vserver => $result->{dfVserver} + }; } } -sub get_additional_information { - my ($self, %options) = @_; - - return if (scalar(@{$self->{filesys_id_selected}}) <= 0); - $self->{snmp}->load(oids => [$oid_dfKBytesTotal], instances => $self->{filesys_id_selected}); - if (!$self->{snmp}->is_snmpv1()) { - $self->{snmp}->load(oids => [$oid_df64TotalKBytes], instances => $self->{filesys_id_selected}); - } - return $self->{snmp}->get_leef(); -} - sub run { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->manage_selection(); - my $result = $self->get_additional_information(); - - foreach my $instance (sort @{$self->{filesys_id_selected}}) { - my $name = $self->{result_names}->{$oid_dfFileSys . '.' . $instance}; - my $type = $self->{result_types}->{$oid_dfType . '.' . $instance}; - my $total_size = $result->{$oid_dfKBytesTotal . '.' . $instance} * 1024; - if (defined($result->{$oid_df64TotalKBytes . '.' . $instance}) && $result->{$oid_df64TotalKBytes . '.' . $instance} != 0) { - $total_size = $result->{$oid_df64TotalKBytes . '.' . $instance} * 1024; - } - if (defined($self->{option_results}->{skip_total_zero}) && $total_size == 0) { - $self->{output}->output_add(long_msg => "Skipping filesys '" . $name . "': total size is 0 and option --skip-total-zero is set"); - next; - } - - $self->{output}->output_add(long_msg => "'" . $name . "' [total_size = $total_size B] [type = " . $map_types{$type} . "]"); + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{fs}}) { + next if (defined($self->{option_results}->{skip_total_zero}) && $self->{fs}->{$instance}->{total} == 0); + + $self->{output}->output_add(long_msg => '[instance = ' . $instance . '] ' . + "[name = '" . $self->{fs}->{$instance}->{name} . "'] " . + "[type = '" . $self->{fs}->{$instance}->{type} . "'] " . + "[vserver = '" . $self->{fs}->{$instance}->{vserver} . "'] " . + "[total = '" . $self->{fs}->{$instance}->{total} . "']"); } $self->{output}->output_add(severity => 'OK', @@ -137,27 +125,17 @@ sub run { sub disco_format { my ($self, %options) = @_; - $self->{output}->add_disco_format(elements => ['name', 'total', 'type']); + $self->{output}->add_disco_format(elements => ['name', 'total', 'type', 'vserver']); } sub disco_show { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->manage_selection(); - my $result = $self->get_additional_information(); - foreach my $instance (sort @{$self->{filesys_id_selected}}) { - my $name = $self->{result_names}->{$oid_dfFileSys . '.' . $instance}; - my $type = $self->{result_types}->{$oid_dfType . '.' . $instance}; - my $total_size = $result->{$oid_dfKBytesTotal . '.' . $instance} * 1024; - if (defined($result->{$oid_df64TotalKBytes . '.' . $instance}) && $result->{$oid_df64TotalKBytes . '.' . $instance} != 0) { - $total_size = $result->{$oid_df64TotalKBytes . '.' . $instance} * 1024; - } - next if (defined($self->{option_results}->{skip_total_zero}) && $total_size == 0); - - $self->{output}->add_disco_entry(name => $name, - total => $total_size, - type => $map_types{$type}); + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{fs}}) { + next if (defined($self->{option_results}->{skip_total_zero}) && $self->{fs}->{$instance}->{total} == 0); + + $self->{output}->add_disco_entry(%{$self->{fs}->{$instance}}); } } @@ -171,15 +149,11 @@ List filesystems (volumes and aggregates also). =over 8 -=item B<--name> +=item B<--filter-name> -Set the filesystem name. +Filter the filesystem name. -=item B<--regexp> - -Allows to use regexp to filter filesystem name (with option --name). - -=item B<--type> +=item B<--filter-type> Filter filesystem type (a regexp. Example: 'flexibleVolume|aggregate'). @@ -190,4 +164,4 @@ Don't display filesys with total equals 0. =back =cut - \ No newline at end of file + diff --git a/storage/netapp/snmp/mode/listsnapvault.pm b/storage/netapp/snmp/mode/listsnapvault.pm new file mode 100644 index 000000000..c939442d9 --- /dev/null +++ b/storage/netapp/snmp/mode/listsnapvault.pm @@ -0,0 +1,133 @@ +# +# Copyright 2019 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 storage::netapp::snmp::mode::listsnapvault; + +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 => { + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my $map_status = { + 1 => 'idle', 2 => 'transferring', 3 => 'pending', + 4 => 'aborting', 6 => 'quiescing', 7 => 'resyncing', + 12 => 'paused', +}; +my $map_state = { + 1 => 'uninitialized', 2 => 'snapvaulted', + 3 => 'brokenOff', 4 => 'quiesced', + 5 => 'source', 6 => 'unknown', 7 => 'restoring', +}; + +my $oid_snapvaultStatusTable = '.1.3.6.1.4.1.789.1.19.11'; +my $mapping = { + svSrc => { oid => '.1.3.6.1.4.1.789.1.19.11.1.2' }, + svDst => { oid => '.1.3.6.1.4.1.789.1.19.11.1.3' }, + svStatus => { oid => '.1.3.6.1.4.1.789.1.19.11.1.4', map => $map_status }, + svState => { oid => '.1.3.6.1.4.1.789.1.19.11.1.5', map => $map_state }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table( + oid => $oid_snapvaultStatusTable, start => $mapping->{svSrc}->{oid}, end => $mapping->{svState}->{oid}, + nothing_quit => 1 + ); + + $self->{snapvault} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{svSrc}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $self->{snapvault}->{$instance} = { %$result }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{snapvault}}) { + $self->{output}->output_add(long_msg => '[src = ' . $self->{snapvault}->{$instance}->{svSrc} . + '] [dst = ' . $self->{snapvault}->{$instance}->{svDst} . + '] [status = ' . $self->{snapvault}->{$instance}->{svStatus} . + '] [state = ' . $self->{snapvault}->{$instance}->{svState} . ']' + ); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List snapvaults:'); + $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 => ['src', 'dst', 'status', 'state']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{snapvault}}) { + $self->{output}->add_disco_entry( + src => $self->{snapvault}->{$instance}->{svSrc}, + dst => $self->{snapvault}->{$instance}->{svDst}, + status => $self->{snapvault}->{$instance}->{svStatus}, + state => $self->{snapvault}->{$instance}->{svState} + ); + } +} + +1; + +__END__ + +=head1 MODE + +List snapvaults. + +=over 8 + +=back + +=cut + diff --git a/storage/netapp/snmp/mode/qtreeusage.pm b/storage/netapp/snmp/mode/qtreeusage.pm index 2a170cfa2..76b2a12d7 100644 --- a/storage/netapp/snmp/mode/qtreeusage.pm +++ b/storage/netapp/snmp/mode/qtreeusage.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub set_counters { my ($self, %options) = @_; @@ -51,38 +49,40 @@ sub custom_usage_perfdata { my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if ($self->{result_values}->{total} > 0 && defined($instance_mode->{option_results}->{free})) { + if ($self->{result_values}->{total} > 0 && defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{name} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($self->{result_values}->{total} > 0 && $instance_mode->{option_results}->{units} eq '%') { + if ($self->{result_values}->{total} > 0 && $self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{name} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { my ($self, %options) = @_; # cannot use '%' or free option with unlimited system - return 'ok' if ($self->{result_values}->{total} <= 0 && ($instance_mode->{option_results}->{units} eq '%' || $instance_mode->{option_results}->{free})); + return 'ok' if ($self->{result_values}->{total} <= 0 && ($self->{instance_mode}->{option_results}->{units} eq '%' || $self->{instance_mode}->{option_results}->{free})); my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -136,26 +136,18 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - "filter-vserver:s" => { name => 'filter_vserver' }, - "filter-volume:s" => { name => 'filter_volume' }, - "filter-qtree:s" => { name => 'filter_qtree' }, - "not-kbytes" => { name => 'not_kbytes' }, - }); + $options{options}->add_options(arguments => { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "filter-vserver:s" => { name => 'filter_vserver' }, + "filter-volume:s" => { name => 'filter_volume' }, + "filter-qtree:s" => { name => 'filter_qtree' }, + "not-kbytes" => { name => 'not_kbytes' }, + }); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - my $mapping = { qrV2Tree => { oid => '.1.3.6.1.4.1.789.1.4.6.1.14' }, qrV264KBytesUsed => { oid => '.1.3.6.1.4.1.789.1.4.6.1.25' }, diff --git a/storage/netapp/snmp/mode/sharecalls.pm b/storage/netapp/snmp/mode/sharecalls.pm index ebf0c315d..f96cd111c 100644 --- a/storage/netapp/snmp/mode/sharecalls.pm +++ b/storage/netapp/snmp/mode/sharecalls.pm @@ -20,35 +20,52 @@ package storage::netapp::snmp::mode::sharecalls; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::statefile; -use centreon::plugins::values; +use Digest::MD5 qw(md5_hex); -my $maps_counters = { - cifs => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'cifs', diff => 1 }, ], - per_second => 1, - output_template => 'CIFS : %s calls/s', - perfdatas => [ - { value => 'cifs_per_second', template => '%d', min => 0 }, - ], - } - }, - nfs => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'nfs', diff => 1 }, ], - per_second => 1, - output_template => 'NFS : %s calls/s', - perfdatas => [ - { value => 'nfs_per_second', template => '%d', min => 0 }, - ], - } - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'cifs', nlabel => 'storage.cifs.calls.persecond', set => { + key_values => [ { name => 'cifs', diff => 1 }, ], + per_second => 1, + output_template => 'CIFS : %s calls/s', + perfdatas => [ + { value => 'cifs_per_second', template => '%d', min => 0 }, + ], + } + }, + { label => 'nfs', nlabel => 'storage.nfs.calls.persecond', set => { + key_values => [ { name => 'nfs', diff => 1 }, ], + per_second => 1, + output_template => 'NFS : %s calls/s', + perfdatas => [ + { value => 'nfs_per_second', template => '%d', min => 0 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + }); + + return $self; +} my $oid_miscHighNfsOps = '.1.3.6.1.4.1.789.1.2.2.5.0'; my $oid_miscLowNfsOps = '.1.3.6.1.4.1.789.1.2.2.6.0'; @@ -57,114 +74,29 @@ my $oid_miscLowCifsOps = '.1.3.6.1.4.1.789.1.2.2.8.0'; my $oid_misc64NfsOps = '.1.3.6.1.4.1.789.1.2.2.27.0'; my $oid_misc64CifsOps = '.1.3.6.1.4.1.789.1.2.2.28.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 => - { - }); - - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - foreach (keys %{$maps_counters}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - $self->manage_selection(); - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "cache_netapp_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode}); - $self->{new_datas}->{last_timestamp} = time(); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => 'global'); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{global}, - new_datas => $self->{new_datas}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{$_}->{obj}->perfdata(); - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "$short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "$long_msg"); - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; - my $request = [$oid_miscHighNfsOps, $oid_miscLowNfsOps, - $oid_miscHighCifsOps, $oid_miscLowCifsOps]; - if (!$self->{snmp}->is_snmpv1()) { + my $request = [ + $oid_miscHighNfsOps, $oid_miscLowNfsOps, + $oid_miscHighCifsOps, $oid_miscLowCifsOps + ]; + if (!$options{snmp}->is_snmpv1()) { push @{$request}, ($oid_misc64NfsOps, $oid_misc64CifsOps); } - $self->{results} = $self->{snmp}->get_leef(oids => $request, nothing_quit => 1); + my $snmp_result = $options{snmp}->get_leef(oids => $request, nothing_quit => 1); $self->{global} = {}; - $self->{global}->{cifs} = defined($self->{results}->{$oid_misc64CifsOps}) ? - $self->{results}->{$oid_misc64CifsOps} : - ($self->{results}->{$oid_miscHighCifsOps} << 32) + $self->{results}->{$oid_miscLowCifsOps}; - $self->{global}->{nfs} = defined($self->{results}->{$oid_misc64NfsOps}) ? - $self->{results}->{$oid_misc64NfsOps} : - ($self->{results}->{$oid_miscHighNfsOps} << 32) + $self->{results}->{$oid_miscLowNfsOps}; + $self->{global}->{cifs} = defined($snmp_result->{$oid_misc64CifsOps}) ? + $snmp_result->{$oid_misc64CifsOps} : + ($snmp_result->{$oid_miscHighCifsOps} << 32) + $snmp_result->{$oid_miscLowCifsOps}; + $self->{global}->{nfs} = defined($snmp_result->{$oid_misc64NfsOps}) ? + $snmp_result->{$oid_misc64NfsOps} : + ($snmp_result->{$oid_miscHighNfsOps} << 32) + $snmp_result->{$oid_miscLowNfsOps}; + + $self->{cache_name} = "cache_netapp_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; @@ -191,4 +123,4 @@ Can be: 'cifs', 'nfs'. =back =cut - \ No newline at end of file + diff --git a/storage/netapp/snmp/mode/snapmirrorlag.pm b/storage/netapp/snmp/mode/snapmirrorlag.pm index 3ba1c5b43..034531b5e 100644 --- a/storage/netapp/snmp/mode/snapmirrorlag.pm +++ b/storage/netapp/snmp/mode/snapmirrorlag.pm @@ -20,118 +20,152 @@ package storage::netapp::snmp::mode::snapmirrorlag; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); -my $oid_snapmirrorOn = '.1.3.6.1.4.1.789.1.9.1.0'; -my $oid_snapmirrorSrc = '.1.3.6.1.4.1.789.1.9.20.1.2'; -my $oid_snapmirrorLag = '.1.3.6.1.4.1.789.1.9.20.1.6'; # hundreth of seconds +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'snapmirror', type => 1, cb_prefix_output => 'prefix_snapmirror_output', message_multiple => 'All snapmirrors lags are ok' }, + ]; + + $self->{maps_counters}->{snapmirror} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'display' } ], + output_template => "status is '%s'", + output_use => 'status', + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + { label => 'lag', set => { + key_values => [ { name => 'lag' }, { name => 'display' } ], + output_template => 'lag: %s seconds', + perfdatas => [ + { label => 'lag', value => 'lag_absolute', template => '%s', min => 0, unit => 's', + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_snapmirror_output { + my ($self, %options) = @_; + + return "Snapmirror '" . $options{instance_value}->{display} . "' "; +} 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:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - }); - $self->{snapmirrors_id_selected} = []; + $options{options}->add_options(arguments => { + "filter-status:s" => { name => 'filter_status' }, + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /quiesced/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /unknown|brokenOff|uninitialized/i' }, + }); return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['warning_status', 'critical_status', 'unknown_status']); } sub manage_selection { my ($self, %options) = @_; - my $result = $self->{snmp}->get_leef(oids => [$oid_snapmirrorOn]); + my $oid_snapmirrorOn = '.1.3.6.1.4.1.789.1.9.1.0'; + my $oid_snapmirrorSrc = '.1.3.6.1.4.1.789.1.9.20.1.2'; + + my $result = $options{snmp}->get_leef(oids => [$oid_snapmirrorOn]); if (!defined($result->{$oid_snapmirrorOn}) || $result->{$oid_snapmirrorOn} != 2) { $self->{output}->add_option_msg(short_msg => "Snapmirror is not turned on."); $self->{output}->option_exit(); } - $self->{result_names} = $self->{snmp}->get_table(oid => $oid_snapmirrorSrc, nothing_quit => 1); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{result_names}})) { + my $id_selected = []; + my $snmp_result_name = $options{snmp}->get_table(oid => $oid_snapmirrorSrc, nothing_quit => 1); + foreach my $oid (keys %{$snmp_result_name}) { next if ($oid !~ /\.([0-9]+)$/); my $instance = $1; # Get all without a name if (!defined($self->{option_results}->{name})) { - push @{$self->{snapmirrors_id_selected}}, $instance; + push @{$id_selected}, $instance; next; } - if (!defined($self->{option_results}->{use_regexp}) && $self->{result_names}->{$oid} eq $self->{option_results}->{name}) { - push @{$self->{snapmirrors_id_selected}}, $instance; + if (!defined($self->{option_results}->{use_regexp}) && $snmp_result_name->{$oid} eq $self->{option_results}->{name}) { + push @{$id_selected}, $instance; } - if (defined($self->{option_results}->{use_regexp}) && $self->{result_names}->{$oid} =~ /$self->{option_results}->{name}/) { - push @{$self->{snapmirrors_id_selected}}, $instance; + if (defined($self->{option_results}->{use_regexp}) && $snmp_result_name->{$oid} =~ /$self->{option_results}->{name}/) { + push @{$id_selected}, $instance; } } - if (scalar(@{$self->{snapmirrors_id_selected}}) <= 0) { + if (scalar(@{$id_selected}) <= 0) { $self->{output}->add_option_msg(short_msg => "No snapmirrors found for name '" . $self->{option_results}->{name} . "'."); $self->{output}->option_exit(); } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - $self->{snmp}->load(oids => [$oid_snapmirrorLag], instances => $self->{snapmirrors_id_selected}); - my $result = $self->{snmp}->get_leef(nothing_quit => 1); - if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All snapmirrors lags are ok.'); - } - - foreach my $instance (sort @{$self->{snapmirrors_id_selected}}) { - my $name = $self->{result_names}->{$oid_snapmirrorSrc . '.' . $instance}; - my $lag = int($result->{$oid_snapmirrorLag . '.' . $instance} / 100); - - my $exit = $self->{perfdata}->threshold_check(value => $lag, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - - $self->{output}->output_add(long_msg => sprintf("Snapmirror '%s' lag: %s seconds", $name, $lag)); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp}))) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Snapmirror '%s' lag: %s seconds", $name, $lag)); + my %map_state = ( + 1 => 'uninitialized', + 2 => 'snapmirrored', + 3 => 'brokenOff', + 4 => 'quiesced', + 5 => 'source', + 6 => 'unknown', + ); + my $mapping = { + snapmirrorState => { oid => '.1.3.6.1.4.1.789.1.9.20.1.5', map => \%map_state }, + snapmirrorLag => { oid => '.1.3.6.1.4.1.789.1.9.20.1.6' }, + }; + + $options{snmp}->load(oids => [$mapping->{snapmirrorState}->{oid}, $mapping->{snapmirrorLag}->{oid}], instances => $id_selected); + my $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + $self->{snapmirror} = {}; + + foreach (@{$id_selected}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + if (defined($self->{option_results}->{filter_status}) && $self->{option_results}->{filter_status} ne '' && + $result->{snapmirrorState} !~ /$self->{option_results}->{filter_status}/) { + $self->{output}->output_add(long_msg => "skipping '" . $snmp_result_name->{$oid_snapmirrorSrc . '.' . $_} . "': no matching filter.", debug => 1); + next; } - - my $extra_label = ''; - $extra_label = '_' . $name if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})); - my %total_options = (); - $self->{output}->perfdata_add(label => 'lag' . $extra_label, unit => 's', - value => $lag, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + + $self->{snapmirror}->{$_} = { + display => $snmp_result_name->{$oid_snapmirrorSrc . '.' . $_}, + status => $result->{snapmirrorState}, + lag => int($result->{snapmirrorLag} / 100), + }; } - $self->{output}->display(); - $self->{output}->exit(); + if (scalar(keys %{$self->{snapmirror}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No snapmirrors found."); + $self->{output}->option_exit(); + } } 1; @@ -140,18 +174,10 @@ __END__ =head1 MODE -Check snapmirrors lag. +Check snapmirrors status and lag. =over 8 -=item B<--warning> - -Threshold warning in seconds. - -=item B<--critical> - -Threshold critical in seconds. - =item B<--name> Set the snapmirror name. @@ -160,6 +186,38 @@ Set the snapmirror name. Allows to use regexp to filter snampmirror name (with option --name). +=item B<--filter-status> + +Filter on status (can be a regexp). + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^status$' + +=item B<--unknown-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{status} =~ /quiesced/i'). +Can used special variables like: %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /unknown|brokenOff|uninitialized/i'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-lag> + +Threshold warning. + +=item B<--critical-lag> + +Threshold critical. + =back =cut diff --git a/storage/netapp/snmp/mode/snapvaultusage.pm b/storage/netapp/snmp/mode/snapvaultusage.pm new file mode 100644 index 000000000..84e2f9bff --- /dev/null +++ b/storage/netapp/snmp/mode/snapvaultusage.pm @@ -0,0 +1,244 @@ +# +# Copyright 2019 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 storage::netapp::snmp::mode::snapvaultusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use Digest::MD5 qw(md5_hex); + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'status : ' . $self->{result_values}->{status} . ' [state : ' . $self->{result_values}->{state} . ']'; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_svStatus'}; + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_svState'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'snapvault', type => 1, cb_prefix_output => 'prefix_snapvault_output', message_multiple => 'All snapvault usages are ok', skipped_code => { -10 => 1, -11 => 1 } } + ]; + + $self->{maps_counters}->{snapvault} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'svState' }, { name => 'svStatus' }, { 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 => \&catalog_status_threshold, + } + }, + { label => 'lag', set => { + key_values => [ { name => 'svLag' }, { name => 'display' } ], + output_template => 'lag : %s seconds', + perfdatas => [ + { label => 'lag', value => 'svLag_absolute', template => '%s', min => 0, unit => 's', + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'transfer-traffic', set => { + key_values => [ { name => 'svTotalTransMBs', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 1, + output_template => 'transfer traffic : %s %s/s', + perfdatas => [ + { label => 'transfer_traffic', template => '%.2f', value => 'svTotalTransMBs_per_second', + unit => 'B/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'transfer-succeed', displa_ok => 0, set => { + key_values => [ { name => 'svTotalSuccesses' }, { name => 'display' } ], + output_template => 'transfer succeed : %s', + perfdatas => [ + { label => 'transfer_succeed', value => 'svTotalSuccesses_absolute', template => '%s', min => 0, + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'transfer-failed', displa_ok => 0, set => { + key_values => [ { name => 'svTotalFailures' }, { name => 'display' } ], + output_template => 'transfer failed : %s', + perfdatas => [ + { label => 'transfer_failed', value => 'svTotalFailures_absolute', template => '%s', min => 0, + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_snapvault_output { + my ($self, %options) = @_; + + return "Snapvault '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "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); + + $self->change_macros(macros => ['warning_status', 'critical_status', 'unknown_status']); +} + +my $map_status = { + 1 => 'idle', 2 => 'transferring', 3 => 'pending', + 4 => 'aborting', 6 => 'quiescing', 7 => 'resyncing', + 12 => 'paused', +}; + +my $map_state = { + 1 => 'uninitialized', 2 => 'snapvaulted', + 3 => 'brokenOff', 4 => 'quiesced', + 5 => 'source', 6 => 'unknown', 7 => 'restoring', +}; + +my $mapping = { + svStatus => { oid => '.1.3.6.1.4.1.789.1.19.11.1.4', map => $map_status }, + svState => { oid => '.1.3.6.1.4.1.789.1.19.11.1.5', map => $map_state }, + svLag => { oid => '.1.3.6.1.4.1.789.1.19.11.1.6' }, # timeticks + svTotalSuccesses => { oid => '.1.3.6.1.4.1.789.1.19.11.1.7' }, + svTotalFailures => { oid => '.1.3.6.1.4.1.789.1.19.11.1.9' }, + svTotalTransMBs => { oid => '.1.3.6.1.4.1.789.1.19.11.1.11' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_svOn = '.1.3.6.1.4.1.789.1.19.1.0'; + + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_svOn]); + if (!defined($snmp_result->{$oid_svOn}) || $snmp_result->{$oid_svOn} != 2) { + $self->{output}->add_option_msg(short_msg => "snapvault is not turned on."); + $self->{output}->option_exit(); + } + + my $oid_svSrc = '.1.3.6.1.4.1.789.1.19.11.1.2'; + my $oid_svDst = '.1.3.6.1.4.1.789.1.19.11.1.3'; + + $self->{snapvault} = {}; + $snmp_result = $options{snmp}->get_multiple_table(oids => [{ oid => $oid_svSrc }, { oid => $oid_svDst }], return_type => 1, nothing_quit => 1); + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$oid_svSrc\.(.*)$/); + my $instance = $1; + my $name = $snmp_result->{$oid_svSrc . '.' . $instance} . '.' . $snmp_result->{$oid_svDst . '.' . $instance}; + + 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 snapvault '" . $name . "'.", debug => 1); + next; + } + + $self->{snapvault}->{$instance} = { display => $name }; + } + + if (scalar(keys %{$self->{snapvault}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No entry found."); + $self->{output}->option_exit(); + } + + $options{snmp}->load(oids => [ + map($_->{oid}, values(%$mapping)) + ], + instances => [keys %{$self->{snapvault}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{snapvault}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + + $result->{svTotalTransMBs} *= 1024 * 1024; + $result->{svLag} = int($result->{svLag} / 100); + + $self->{snapvault}->{$_} = { %{$self->{snapvault}->{$_}}, %$result }; + } + + $self->{cache_name} = "netapp_" . $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')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check snapvault usage. + +=over 8 + +=item B<--filter-name> + +Filter snapvault name (can be a regexp). + +=item B<--unknown-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{state}, %{status}, %{display} + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{state}, %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{state}, %{status}, %{display} + +=item B<--warning-*> B<--critical-*> + +Threshold warning. +Can be: 'lag' (s), 'transfer-traffic' (B/s), 'transfer-succeed', +'transfer-failed'. + +=back + +=cut diff --git a/storage/netapp/snmp/mode/volumeoptions.pm b/storage/netapp/snmp/mode/volumeoptions.pm index 4785274bd..4498bfc8c 100644 --- a/storage/netapp/snmp/mode/volumeoptions.pm +++ b/storage/netapp/snmp/mode/volumeoptions.pm @@ -20,13 +20,84 @@ package storage::netapp::snmp::mode::volumeoptions; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); -my $oid_volName = '.1.3.6.1.4.1.789.1.5.8.1.2'; -my $oid_volOptions = '.1.3.6.1.4.1.789.1.5.8.1.7'; +sub custom_options_threshold { + my ($self, %options) = @_; + + my $status = catalog_status_threshold($self, %options); + if (!$self->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { + $self->{instance_mode}->{global}->{failed}++; + } + return $status; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_options_calc { + my ($self, %options) = @_; + + $self->{result_values}->{options} = $options{new_datas}->{$self->{instance} . '_options'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'volumes', type => 1, cb_prefix_output => 'prefix_volume_output', message_multiple => 'All volumes are ok', skipped_code => { -10 => 1 } }, + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{volumes} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'display' } ], + output_template => "status is '%s'", + output_use => 'status', + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + }, + { label => 'options', threshold => 0, set => { + key_values => [ { name => 'options' }, { name => 'display' } ], + output_template => "options: '%s'", + output_use => 'options', + closure_custom_calc => $self->can('custom_options_calc'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_options_threshold'), + } + }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'failed', display_ok => 0, set => { + key_values => [ { name => 'failed' } ], + output_template => 'Failed: %s', + perfdatas => [ + { label => 'failed', value => 'failed_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; +} + +sub prefix_volume_output { + my ($self, %options) = @_; + + return "Volume '" . $options{instance_value}->{display} . "' "; +} sub new { my ($class, %options) = @_; @@ -34,104 +105,88 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "warn" => { name => 'warn' }, - "crit" => { name => 'crit' }, - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - "option:s" => { name => 'option' }, - }); - $self->{volume_id_selected} = []; - $self->{status} = 'OK'; + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "filter-status:s" => { name => 'filter_status' }, + "unknown-status:s" => { name => 'unknown_status', default => '' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + "unknown-options:s" => { name => 'unknown_options', default => '' }, + "warning-options:s" => { name => 'warning_options', default => '' }, + "critical-options:s" => { name => 'critical_options', default => '' }, + }); return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (defined($self->{option_results}->{warn})) { - $self->{status} = 'WARNING'; - } - if (defined($self->{option_results}->{crit})) { - $self->{status} = 'CRITICAL'; + $self->SUPER::check_options(%options); + + $self->{test_option} = 0; + foreach ('warning', 'unknown', 'critical') { + $self->{test_option} = 1 if (defined($self->{option_results}->{$_ . '_options'}) && $self->{option_results}->{$_ . '_options'} ne ''); } + $self->change_macros(macros => ['warning_options', 'critical_options', 'unknown_options', + 'warning_status', 'critical_status', 'unknown_status']); } sub manage_selection { my ($self, %options) = @_; - $self->{result_names} = $self->{snmp}->get_table(oid => $oid_volName, nothing_quit => 1); - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{result_names}})) { + my $oid_volName = '.1.3.6.1.4.1.789.1.5.8.1.2'; + my $id_selected = []; + my $snmp_result_name = $options{snmp}->get_table(oid => $oid_volName, nothing_quit => 1); + foreach my $oid (keys %{$snmp_result_name}) { next if ($oid !~ /\.([0-9]+)$/); my $instance = $1; - # Get all without a name - if (!defined($self->{option_results}->{name})) { - push @{$self->{volume_id_selected}}, $instance; + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $snmp_result_name->{oid} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $snmp_result_name->{oid} . "': no matching filter.", debug => 1); + next; + } + push @{$id_selected}, $instance; + } + + if (scalar(@{$id_selected}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No volume found for name '" . $self->{option_results}->{filter_name} . "'."); + $self->{output}->option_exit(); + } + + my $mapping = { + volState => { oid => '.1.3.6.1.4.1.789.1.5.8.1.5' }, + volOptions => { oid => '.1.3.6.1.4.1.789.1.5.8.1.7' }, + }; + + my $load_oids = [$mapping->{volState}->{oid}]; + push @$load_oids, $mapping->{volOptions}->{oid} if ($self->{test_option} == 1); + $options{snmp}->load(oids => $load_oids, instances => $id_selected); + my $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + $self->{global} = { failed => 0 }; + $self->{volumes} = {}; + foreach (@{$id_selected}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + if (defined($self->{option_results}->{filter_status}) && $self->{option_results}->{filter_status} ne '' && + $result->{volState} !~ /$self->{option_results}->{filter_status}/) { + $self->{output}->output_add(long_msg => "skipping '" . $snmp_result_name->{$oid_volName . '.' . $_} . "': no matching filter.", debug => 1); next; } - if (!defined($self->{option_results}->{use_regexp}) && $self->{result_names}->{$oid} eq $self->{option_results}->{name}) { - push @{$self->{volume_id_selected}}, $instance; - } - if (defined($self->{option_results}->{use_regexp}) && $self->{result_names}->{$oid} =~ /$self->{option_results}->{name}/) { - push @{$self->{volume_id_selected}}, $instance; - } + $self->{volumes}->{$_} = { + display => $snmp_result_name->{$oid_volName . '.' . $_}, + status => $result->{volState}, + options => $result->{volOptions}, + }; } - - if (scalar(@{$self->{volume_id_selected}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No volume found for name '" . $self->{option_results}->{name} . "'."); + + if (scalar(keys %{$self->{volumes}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No volume found."); $self->{output}->option_exit(); } } -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - $self->{snmp}->load(oids => [$oid_volOptions], instances => $self->{volume_id_selected}); - my $result = $self->{snmp}->get_leef(); - - if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All volume options are ok.'); - } - - my $failed = 0; - foreach my $instance (sort @{$self->{volume_id_selected}}) { - my $name = $self->{result_names}->{$oid_volName . '.' . $instance}; - my $option = $result->{$oid_volOptions . '.' . $instance}; - - $self->{output}->output_add(long_msg => sprintf("Volume '%s' options: %s", $name, $option)); - - my $status; - if (defined($self->{option_results}->{option}) && $option !~ /$self->{option_results}->{option}/) { - $status = $self->{status}; - $failed++; - } - - # Can be 'ok' if we don't set a threshold option '--warn', '--crit' - if (defined($status)) { - $self->{output}->output_add(severity => $status, - short_msg => sprintf("Volume '%s' pattern '%s' is not matching", $name, $self->{option_results}->{option})); - } elsif (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => $status, - short_msg => sprintf("Volume '%s' option is ok", $name)); - } - } - - $self->{output}->perfdata_add(label => 'failed', - value => $failed, - min => 0); - - $self->{output}->display(); - $self->{output}->exit(); -} - 1; __END__ @@ -142,27 +197,45 @@ Check options from volumes. =over 8 -=item B<--warn> +=item B<--filter-name> -Return Warning (need '--option' also). +Filter on volume name (can be a regexp). -=item B<--critical> +=item B<--filter-status> -Return Critical (need '--option' also). +Filter on volume status (can be a regexp). -=item B<--name> +=item B<--unknown-status> -Set the volume name. +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} -=item B<--regexp> +=item B<--warning-status> -Allows to use regexp to filter volume name (with option --name). +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} -=item B<--option> +=item B<--critical-status> -Options to check (Example: if 'nosnap=off' not maching, returns Warning or Critical for the volume). +Set critical threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=item B<--unknown-options> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{options}, %{display} + +=item B<--warning-options> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{options}, %{display} + +=item B<--critical-options> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{options}, %{display} =back =cut - \ No newline at end of file + diff --git a/storage/netapp/snmp/plugin.pm b/storage/netapp/snmp/plugin.pm index a31cd819c..6c50add2d 100644 --- a/storage/netapp/snmp/plugin.pm +++ b/storage/netapp/snmp/plugin.pm @@ -31,28 +31,30 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'aggregatestate' => 'storage::netapp::snmp::mode::aggregatestate', - 'cp-statistics' => 'storage::netapp::snmp::mode::cpstatistics', - 'cpuload' => 'storage::netapp::snmp::mode::cpuload', - 'diskfailed' => 'storage::netapp::snmp::mode::diskfailed', - 'fan' => 'storage::netapp::snmp::mode::fan', - 'filesys' => 'storage::netapp::snmp::mode::filesys', - 'list-filesys' => 'storage::netapp::snmp::mode::listfilesys', - 'global-status' => 'storage::netapp::snmp::mode::globalstatus', - 'ndmpsessions' => 'storage::netapp::snmp::mode::ndmpsessions', - 'nvram' => 'storage::netapp::snmp::mode::nvram', - 'partnerstatus' => 'storage::netapp::snmp::mode::partnerstatus', - 'psu' => 'storage::netapp::snmp::mode::psu', - 'qtree-usage' => 'storage::netapp::snmp::mode::qtreeusage', - 'share-calls' => 'storage::netapp::snmp::mode::sharecalls', - 'shelf' => 'storage::netapp::snmp::mode::shelf', - 'snapmirrorlag' => 'storage::netapp::snmp::mode::snapmirrorlag', - 'snapshotage' => 'storage::netapp::snmp::mode::snapshotage', - 'temperature' => 'storage::netapp::snmp::mode::temperature', - 'volumeoptions' => 'storage::netapp::snmp::mode::volumeoptions', - 'cache-age' => 'storage::netapp::snmp::mode::cacheage', - 'uptime' => 'snmp_standard::mode::uptime', - ); + 'aggregatestate' => 'storage::netapp::snmp::mode::aggregatestate', + 'cache-age' => 'storage::netapp::snmp::mode::cacheage', + 'cp-statistics' => 'storage::netapp::snmp::mode::cpstatistics', + 'cpuload' => 'storage::netapp::snmp::mode::cpuload', + 'diskfailed' => 'storage::netapp::snmp::mode::diskfailed', + 'fan' => 'storage::netapp::snmp::mode::fan', + 'filesys' => 'storage::netapp::snmp::mode::filesys', + 'list-filesys' => 'storage::netapp::snmp::mode::listfilesys', + 'list-snapvault' => 'storage::netapp::snmp::mode::listsnapvault', + 'global-status' => 'storage::netapp::snmp::mode::globalstatus', + 'ndmpsessions' => 'storage::netapp::snmp::mode::ndmpsessions', + 'nvram' => 'storage::netapp::snmp::mode::nvram', + 'partnerstatus' => 'storage::netapp::snmp::mode::partnerstatus', + 'psu' => 'storage::netapp::snmp::mode::psu', + 'qtree-usage' => 'storage::netapp::snmp::mode::qtreeusage', + 'share-calls' => 'storage::netapp::snmp::mode::sharecalls', + 'shelf' => 'storage::netapp::snmp::mode::shelf', + 'snapmirrorlag' => 'storage::netapp::snmp::mode::snapmirrorlag', + 'snapshotage' => 'storage::netapp::snmp::mode::snapshotage', + 'snapvault-usage' => 'storage::netapp::snmp::mode::snapvaultusage', + 'temperature' => 'storage::netapp::snmp::mode::temperature', + 'uptime' => 'snmp_standard::mode::uptime', + 'volumeoptions' => 'storage::netapp::snmp::mode::volumeoptions', + ); return $self; } diff --git a/storage/netgear/readynas/snmp/mode/components/fan.pm b/storage/netgear/readynas/snmp/mode/components/fan.pm index 26dbe5cea..ed7719803 100644 --- a/storage/netgear/readynas/snmp/mode/components/fan.pm +++ b/storage/netgear/readynas/snmp/mode/components/fan.pm @@ -84,10 +84,14 @@ sub check_v4 { short_msg => sprintf("fan '%s' rpm is %s", $instance, $fanrpm)); } - $self->{output}->perfdata_add(label => "fan_" . $instance, unit => 'rpm', - value => $fanrpm, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => "fan", unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $instance, + value => $fanrpm, + warning => $warn, + critical => $crit + ); } } diff --git a/storage/netgear/readynas/snmp/mode/components/temperature.pm b/storage/netgear/readynas/snmp/mode/components/temperature.pm index 5dc783626..b5e8f39fc 100644 --- a/storage/netgear/readynas/snmp/mode/components/temperature.pm +++ b/storage/netgear/readynas/snmp/mode/components/temperature.pm @@ -80,10 +80,14 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Temperature '%s' is %s%s", $instance, $result->{temperatureValue}, $temperatureMax_unit)); } - $self->{output}->perfdata_add(label => "temp_" . $instance, unit => $temperatureMax_unit, - value => $result->{temperatureValue}, - warning => $warn, - critical => $crit); + $self->{output}->perfdata_add( + label => 'temp', unit => $temperatureMax_unit, + nlabel => 'hardware.temperature.' . (($temperatureMax_unit eq 'C') ? 'celsius' : 'fahrenheit'), + instances => $instance, + value => $result->{temperatureValue}, + warning => $warn, + critical => $crit + ); } } diff --git a/storage/nimble/snmp/mode/globalstats.pm b/storage/nimble/snmp/mode/globalstats.pm index 8138291c8..8975119ea 100644 --- a/storage/nimble/snmp/mode/globalstats.pm +++ b/storage/nimble/snmp/mode/globalstats.pm @@ -20,17 +20,21 @@ package storage::nimble::snmp::mode::globalstats; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; use Digest::MD5 qw(md5_hex); -use centreon::plugins::values; -use centreon::plugins::statefile; -my $maps_counters = { - global => { - '000_read' => { set => { +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'read', nlabel => 'system.io.read.usage.bytespersecond', set => { key_values => [ { name => 'read', diff => 1 } ], per_second => 1, output_template => 'Read I/O : %s %s/s', output_error_template => "Read I/O : %s", @@ -41,7 +45,7 @@ my $maps_counters = { ], } }, - '001_write' => { set => { + { label => 'write', nlabel => 'system.io.write.usage.bytespersecond', set => { key_values => [ { name => 'write', diff => 1 } ], per_second => 1, output_template => 'Write I/O : %s %s/s', output_error_template => "Write I/O : %s", @@ -52,7 +56,7 @@ my $maps_counters = { ], } }, - '002_read-iops' => { set => { + { label => 'read-iops', nlabel => 'system.io.read.usage.iops', set => { key_values => [ { name => 'read_iops', diff => 1 } ], per_second => 1, output_template => 'Read IOPs : %.2f', output_error_template => "Read IOPs : %s", @@ -62,7 +66,7 @@ my $maps_counters = { ], } }, - '003_write-iops' => { set => { + { label => 'write-iops', nlabel => 'system.io.write.usage.iops', set => { key_values => [ { name => 'write_iops', diff => 1 } ], per_second => 1, output_template => 'Write IOPs : %.2f', output_error_template => "Write IOPs : %s", @@ -72,7 +76,7 @@ my $maps_counters = { ], } }, - '004_read-time' => { set => { + { label => 'read-time', nlabel => 'system.io.read.time.seconds', set => { key_values => [ { name => 'read_time', diff => 1 } ], output_template => 'Read Time : %.3f s', output_error_template => "Read Time : %s", perfdatas => [ @@ -81,7 +85,7 @@ my $maps_counters = { ], } }, - '005_write-time' => { set => { + { label => 'write-time', nlabel => 'system.io.write.time.seconds', set => { key_values => [ { name => 'write_time', diff => 1 } ], output_template => 'Write Time : %.3f s', output_error_template => "Write Time : %s", perfdatas => [ @@ -90,119 +94,21 @@ my $maps_counters = { ], } }, - }, -}; + ]; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-counters:s" => { name => 'filter_counters' }, - }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); + $options{options}->add_options(arguments => { + }); - foreach my $key (('global')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(statefile => $self->{statefile_value}, - output => $self->{output}, - perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('global')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - $self->{statefile_value}->check_options(%options); -} - -sub run_global { - my ($self, %options) = @_; - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters->{global}}) { - if (defined($self->{option_results}->{filter_counters}) && $self->{option_results}->{filter_counters} ne '' && - $_ !~ /$self->{option_results}->{filter_counters}/) { - $self->{output}->output_add(long_msg => "skipping counter $_", debug => 1); - next; - } - - my $obj = $maps_counters->{global}->{$_}->{obj}; - - $obj->set(instance => 'global'); - - my ($value_check) = $obj->execute(new_datas => $self->{new_datas}, - values => $self->{global}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(); - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "$short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "$long_msg"); - } -} - -sub run { - my ($self, %options) = @_; - - $self->manage_selection(%options); - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => $self->{cache_name}); - $self->{new_datas}->{last_timestamp} = time(); - - $self->run_global(); - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; @@ -222,8 +128,10 @@ sub manage_selection { my $oid_ioWrites = '.1.3.6.1.4.1.37447.1.3.4.0'; my $oid_ioWriteBytes = '.1.3.6.1.4.1.37447.1.3.10.0'; my $oid_ioWriteTimeMicrosec = '.1.3.6.1.4.1.37447.1.3.7.0'; - my $result = $options{snmp}->get_table(oid => $oid_globalStats, - nothing_quit => 1); + my $result = $options{snmp}->get_table( + oid => $oid_globalStats, + nothing_quit => 1 + ); $self->{global}->{read} = defined($result->{$oid_ioReadBytes}) ? $result->{$oid_ioReadBytes} : undef; $self->{global}->{read_iops} = defined($result->{$oid_ioReads}) ? $result->{$oid_ioReads} : undef; $self->{global}->{read_time} = defined($result->{$oid_ioReadTimeMicrosec}) ? $result->{$oid_ioReadTimeMicrosec} / 1000000 : undef; diff --git a/storage/nimble/snmp/mode/volumeusage.pm b/storage/nimble/snmp/mode/volumeusage.pm index 1ece8361b..a906ffc14 100644 --- a/storage/nimble/snmp/mode/volumeusage.pm +++ b/storage/nimble/snmp/mode/volumeusage.pm @@ -20,46 +20,29 @@ package storage::nimble::snmp::mode::volumeusage; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; - -my $instance_mode; - -my $maps_counters = { - vol => { - '000_usage' => { - set => { - key_values => [ { name => 'display' }, { name => 'total' }, { name => 'used' } ], - closure_custom_calc => \&custom_usage_calc, - closure_custom_output => \&custom_usage_output, - closure_custom_perfdata => \&custom_usage_perfdata, - closure_custom_threshold_check => \&custom_usage_threshold, - }, - }, - } -}; sub custom_usage_perfdata { my ($self, %options) = @_; - - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', - value => $self->{result_values}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), - min => 0, max => $self->{result_values}->{total}); + + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + nlabel => $self->{nlabel}, + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -89,111 +72,42 @@ sub custom_usage_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'volume', type => 1, cb_prefix_output => 'prefix_volume_output', message_multiple => 'All volumes are ok' } + ]; + + $self->{maps_counters}->{volume} = [ + { label => 'usage', nlabel => 'volume.space.usage.bytes', set => { + key_values => [ { name => 'display' }, { name => 'used' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + 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' }, - }); - - foreach my $key (('vol')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('vol')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - $instance_mode = $self; -} - -sub run_instances { +sub prefix_volume_output { my ($self, %options) = @_; - my $multiple = 1; - if (scalar(keys %{$self->{vol}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All volume usages are ok'); - } - - foreach my $id (sort keys %{$self->{vol}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{vol}}) { - my $obj = $maps_counters->{vol}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{vol}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $obj->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $obj->threshold_check(); - push @exits, $exit2; - - my $output = $obj->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $obj->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Volume '$self->{vol}->{$id}->{display}' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Volume '$self->{vol}->{$id}->{display}' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Volume '$self->{vol}->{$id}->{display}' $long_msg"); - } - } -} - -sub run { - my ($self, %options) = @_; - - $self->manage_selection(%options); - $self->run_instances(); - - $self->{output}->display(); - $self->{output}->exit(); + return "Volume '" . $options{instance_value}->{display} . "' "; } my $mapping = { @@ -208,26 +122,27 @@ sub manage_selection { my ($self, %options) = @_; my $oid_volEntry = '.1.3.6.1.4.1.37447.1.2.1'; - my $results = $options{snmp}->get_table(oid => $oid_volEntry, nothing_quit => 1); - $self->{vol} = {}; - foreach my $oid (keys %{$results}) { + my $snmp_result = $options{snmp}->get_table(oid => $oid_volEntry, nothing_quit => 1); + + $self->{volume} = {}; + foreach my $oid (keys %{$snmp_result}) { next if ($oid !~ /^$mapping->{volName}->{oid}\.(.*)/); my $instance = $1; - my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance); + 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->{volName} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $result->{volName} . "': no matching vserver name.", debug => 1); + $self->{output}->output_add(long_msg => "skipping '" . $result->{volName} . "': no matching volume name.", debug => 1); next; } my $total = (($result->{volSizeHigh} << 32) + $result->{volSizeLow}) * 1024 * 1024; my $used = (($result->{volUsageHigh} << 32) + $result->{volUsageLow}) * 1024 * 1024; - $self->{vol}->{$instance} = { display => $result->{volName}, used => $used, total => $total }; + $self->{volume}->{$instance} = { display => $result->{volName}, used => $used, total => $total }; } - if (scalar(keys %{$self->{vol}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No entry found."); + if (scalar(keys %{$self->{volume}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No volume found."); $self->{output}->option_exit(); } } diff --git a/storage/oracle/zs/snmp/mode/shareusage.pm b/storage/oracle/zs/snmp/mode/shareusage.pm index 38c7adf47..a5542e0a3 100644 --- a/storage/oracle/zs/snmp/mode/shareusage.pm +++ b/storage/oracle/zs/snmp/mode/shareusage.pm @@ -25,30 +25,30 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = $self->{result_values}->{label} . '_used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = $self->{result_values}->{label} . '_free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -56,12 +56,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -128,24 +128,16 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "filter-project:s" => { name => 'filter_project' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "filter-project:s" => { name => 'filter_project' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub prefix_share_output { my ($self, %options) = @_; diff --git a/storage/panzura/snmp/mode/ratios.pm b/storage/panzura/snmp/mode/ratios.pm index dde8ca613..5886cd51e 100644 --- a/storage/panzura/snmp/mode/ratios.pm +++ b/storage/panzura/snmp/mode/ratios.pm @@ -20,45 +20,45 @@ package storage::panzura::snmp::mode::ratios; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -my $maps_counters = { - dedup => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'dedup' }, ], - output_template => 'Deduplication ratio : %.2f', - perfdatas => [ - { value => 'dedup_absolute', template => '%.2f', min => 0 }, - ], - } - }, - comp => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'comp' }, ], - output_template => 'Compression ratio : %.2f', - perfdatas => [ - { value => 'comp_absolute', template => '%.2f', min => 0 }, - ], - } - }, - save => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'save' }, ], - output_template => 'Save ratio : %.2f', - perfdatas => [ - { value => 'save_absolute', template => '%.2f', min => 0 }, - ], - } - }, -}; - -my $oid_dedupRatio = '.1.3.6.1.4.1.32853.1.3.1.5.1.0'; -my $oid_compRatio = '.1.3.6.1.4.1.32853.1.3.1.6.1.0'; -my $oid_saveRatio = '.1.3.6.1.4.1.32853.1.3.1.7.1.0'; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'dedup', nlabel => 'system.deduplication.ratio.count', set => { + key_values => [ { name => 'dedup' }, ], + output_template => 'Deduplication ratio : %.2f', + perfdatas => [ + { value => 'dedup_absolute', template => '%.2f', min => 0 }, + ], + } + }, + { label => 'comp', nlabel => 'system.compression.ratio.count', set => { + key_values => [ { name => 'comp' }, ], + output_template => 'Compression ratio : %.2f', + perfdatas => [ + { value => 'comp_absolute', template => '%.2f', min => 0 }, + ], + } + }, + { label => 'save', nlabel => 'system.save.ratio.count', set => { + key_values => [ { name => 'save' }, ], + output_template => 'Save ratio : %.2f', + perfdatas => [ + { value => 'save_absolute', template => '%.2f', min => 0 }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; @@ -66,92 +66,29 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); - foreach (keys %{$maps_counters}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - $self->{output}->output_add(severity => 'OK', - short_msg => 'All ratios are ok'); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => 'global'); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{global}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $self->{output}->output_add(long_msg => $output); - $maps_counters->{$_}->{obj}->perfdata(); - } - - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "$short_msg" - ); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; + + my $oid_dedupRatio = '.1.3.6.1.4.1.32853.1.3.1.5.1.0'; + my $oid_compRatio = '.1.3.6.1.4.1.32853.1.3.1.6.1.0'; + my $oid_saveRatio = '.1.3.6.1.4.1.32853.1.3.1.7.1.0'; + + my $snmp_result = $options{snmp}->get_leef( + oids => [$oid_dedupRatio, $oid_compRatio, $oid_saveRatio], + nothing_quit => 1 + ); - my $request = [$oid_dedupRatio, $oid_compRatio, $oid_saveRatio]; - - $self->{results} = $self->{snmp}->get_leef(oids => $request, nothing_quit => 1); - - $self->{global} = {}; - $self->{global}->{dedup} = defined($self->{results}->{$oid_dedupRatio}) ? $self->{results}->{$oid_dedupRatio} / 100 : 0; - $self->{global}->{comp} = defined($self->{results}->{$oid_compRatio}) ? $self->{results}->{$oid_compRatio} / 100 : 0; - $self->{global}->{save} = defined($self->{results}->{$oid_saveRatio}) ? $self->{results}->{$oid_saveRatio} / 100 : 0; + $self->{global} = { + dedup => defined($snmp_result->{$oid_dedupRatio}) ? $snmp_result->{$oid_dedupRatio} / 100 : undef, + comp => defined($snmp_result->{$oid_compRatio}) ? $snmp_result->{$oid_compRatio} / 100 : undef, + save => defined($snmp_result->{$oid_saveRatio}) ? $snmp_result->{$oid_saveRatio} / 100 : undef, + }; } 1; @@ -177,4 +114,4 @@ Can be: 'dedup', 'comp', 'save'. =back =cut - \ No newline at end of file + diff --git a/storage/purestorage/restapi/custom/api.pm b/storage/purestorage/restapi/custom/api.pm index d9cf59023..5a478e0af 100644 --- a/storage/purestorage/restapi/custom/api.pm +++ b/storage/purestorage/restapi/custom/api.pm @@ -40,22 +40,19 @@ sub new { } if (!defined($options{noptions})) { - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "proxyurl:s" => { name => 'proxyurl' }, - "timeout:s" => { name => 'timeout' }, - "ssl-opt:s@" => { name => 'ssl_opt' }, - "api-path:s" => { name => 'api_path' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + "api-path:s" => { name => 'api_path' }, + }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{http} = centreon::plugins::http->new(%options); return $self; } @@ -89,7 +86,6 @@ sub check_options { $self->{username} = (defined($self->{option_results}->{username})) ? $self->{option_results}->{username} : undef; $self->{password} = (defined($self->{option_results}->{password})) ? $self->{option_results}->{password} : undef; $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; - $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? $self->{option_results}->{proxyurl} : undef; $self->{api_path} = (defined($self->{option_results}->{api_path})) ? $self->{option_results}->{api_path} : '/api/1.11'; if (!defined($self->{hostname})) { @@ -121,7 +117,6 @@ sub build_options_for_httplib { $self->{option_results}->{timeout} = $self->{timeout}; $self->{option_results}->{port} = 443; $self->{option_results}->{proto} = 'https'; - $self->{option_results}->{proxyurl} = $self->{proxyurl}; } sub settings { @@ -141,7 +136,7 @@ sub request_api { my $content = $self->{http}->request(method => $options{method}, url_path => $options{url_path}, query_form_post => $options{query_form_post}, critical_status => '', warning_status => '', unknown_status => ''); - my $response = $self->{http}->get_response(); + my $decoded; eval { $decoded = decode_json($content); @@ -151,7 +146,7 @@ sub request_api { $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); $self->{output}->option_exit(); } - if ($response->code() != 200) { + if ($self->{http}->get_code() != 200) { $self->{output}->add_option_msg(short_msg => "Connection issue: " . $decoded->{msg}); $self->{output}->option_exit(); } @@ -197,8 +192,7 @@ sub get_session { $self->settings(); my $decoded = $self->request_api(method => 'POST', url_path => $self->{api_path} . '/auth/session', query_form_post => $encoded); - my $headers = $self->{http}->get_header(); - my $cookie = $headers->header('Set-Cookie'); + my ($cookie) = $self->{http}->get_header(name => 'Set-Cookie'); if (!defined($cookie)) { $self->{output}->add_option_msg(short_msg => "Cannot get session"); $self->{output}->option_exit(); @@ -262,18 +256,10 @@ Pure Storage username. Pure Storage password. -=item B<--proxyurl> - -Proxy URL if any. - =item B<--timeout> Set HTTP timeout in seconds (Default: '10'). -=item B<--ssl-opt> - -Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). - =item B<--api-path> API base url path (Default: '/api/1.11'). diff --git a/storage/purestorage/restapi/mode/hardware.pm b/storage/purestorage/restapi/mode/hardware.pm index 85a955d1e..926bfe0f6 100644 --- a/storage/purestorage/restapi/mode/hardware.pm +++ b/storage/purestorage/restapi/mode/hardware.pm @@ -150,11 +150,14 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("entity '%s' temperature is %s C", $entry->{name}, $entry->{temperature})); } - $self->{output}->perfdata_add(label => 'temperature_' . $entry->{name}, unit => 'C', - value => $entry->{temperature}, - warning => $warn, - critical => $crit, min => 0 - ); + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.entity.temperature.celsius', + instances => $entry->{name}, + value => $entry->{temperature}, + warning => $warn, + critical => $crit, min => 0 + ); } } } diff --git a/storage/purestorage/restapi/mode/pgroupreplication.pm b/storage/purestorage/restapi/mode/pgroupreplication.pm index 8acb9648f..5f70c2ef0 100644 --- a/storage/purestorage/restapi/mode/pgroupreplication.pm +++ b/storage/purestorage/restapi/mode/pgroupreplication.pm @@ -130,7 +130,7 @@ sub manage_selection { } $entry->{created} =~ /^(\d+)-(\d+)-(\d+)T(\d+)[:\/](\d+)[:\/](\d+)Z$/; - my $dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6, %tz); + my $dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6, %$tz); my $created_time = $dt->epoch; my $creation_seconds = time() - $created_time; diff --git a/storage/purestorage/restapi/mode/volumeusage.pm b/storage/purestorage/restapi/mode/volumeusage.pm index 29ac22217..595aaa3a6 100644 --- a/storage/purestorage/restapi/mode/volumeusage.pm +++ b/storage/purestorage/restapi/mode/volumeusage.pm @@ -25,30 +25,30 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; my $label = 'used'; my $value_perf = $self->{result_values}->{used}; - if (defined($instance_mode->{option_results}->{free})) { + if (defined($self->{instance_mode}->{option_results}->{free})) { $label = 'free'; $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($instance_mode->{option_results}->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; $total_options{cast_int} = 1; } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -56,12 +56,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -144,23 +144,15 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "filter-name:s" => { name => 'filter_name' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $instance_mode = $self; -} - sub prefix_volume_output { my ($self, %options) = @_; diff --git a/storage/qnap/snmp/mode/components/disk.pm b/storage/qnap/snmp/mode/components/disk.pm index 4d2acb7cf..afe041ad3 100644 --- a/storage/qnap/snmp/mode/components/disk.pm +++ b/storage/qnap/snmp/mode/components/disk.pm @@ -89,11 +89,14 @@ sub check { $self->{output}->output_add(severity => $exit2, short_msg => sprintf("Disk '%s' temperature is %s degree centigrade", $result->{HdDescr}, $disk_temp)); } - $self->{output}->perfdata_add(label => 'temp_disk_' . $instance, unit => 'C', - value => $disk_temp - ); + $self->{output}->perfdata_add( + label => 'temp_disk', unit => 'C', + nlabel => 'hardware.disk.temperature.celsius', + instances => $instance, + value => $disk_temp + ); } } } -1; \ No newline at end of file +1; diff --git a/storage/qnap/snmp/mode/components/fan.pm b/storage/qnap/snmp/mode/components/fan.pm index 749496b9b..d0b1638d5 100644 --- a/storage/qnap/snmp/mode/components/fan.pm +++ b/storage/qnap/snmp/mode/components/fan.pm @@ -51,7 +51,7 @@ sub check { next if ($self->check_filter(section => 'fan', instance => $instance)); $self->{components}->{fan}->{total}++; - $self->{output}->output_add(long_msg => sprintf("Fan '%s' [instance: %s] speed is '%s'.", + $self->{output}->output_add(long_msg => sprintf("fan '%s' [instance: %s] speed is '%s'.", $fan_descr, $instance, $fan_speed)); if ($fan_speed =~ /([0-9]+)\s*rpm/i) { @@ -61,11 +61,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fan '%s' speed is %s rpm", $fan_descr, $fan_speed_value)); } - $self->{output}->perfdata_add(label => 'fan_' . $instance, unit => 'rpm', - value => $fan_speed_value, min => 0 - ); + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => $instance, + value => $fan_speed_value, min => 0 + ); } } } -1; \ No newline at end of file +1; diff --git a/storage/qnap/snmp/mode/components/raid.pm b/storage/qnap/snmp/mode/components/raid.pm new file mode 100644 index 000000000..3f1b2ce19 --- /dev/null +++ b/storage/qnap/snmp/mode/components/raid.pm @@ -0,0 +1,60 @@ +# +# Copyright 2019 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 storage::qnap::snmp::mode::components::raid; + +use strict; +use warnings; + +# In MIB 'NAS.mib' +my $oid_raidStatus = '.1.3.6.1.4.1.24681.1.4.1.1.1.2.1.2.1.5'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_raidStatus }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking raids"); + $self->{components}->{raid} = {name => 'raids', total => 0, skip => 0}; + return if ($self->check_filter(section => 'raid')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_raidStatus}})) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + + next if ($self->check_filter(section => 'raid', instance => $instance)); + + my $status = $self->{results}->{$oid_raidStatus}->{$oid}; + $self->{components}->{raid}->{total}++; + $self->{output}->output_add(long_msg => sprintf("raid '%s' status is %s [instance: %s]", + $instance, $status, $instance)); + my $exit = $self->get_severity(section => 'raid', value => $status); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Raid '%s' status is %s.", $instance, $status)); + } + } +} + +1; diff --git a/storage/qnap/snmp/mode/components/temperature.pm b/storage/qnap/snmp/mode/components/temperature.pm index 6ce95ca05..a8fed6bc1 100644 --- a/storage/qnap/snmp/mode/components/temperature.pm +++ b/storage/qnap/snmp/mode/components/temperature.pm @@ -47,16 +47,19 @@ sub check { if ($cpu_temp =~ /([0-9]+)\s*C/ && !$self->check_filter(section => 'temperature', instance => 'cpu')) { my $value = $1; $self->{components}->{temperature}->{total}++; - $self->{output}->output_add(long_msg => sprintf("CPU Temperature is '%s' degree centigrade", + $self->{output}->output_add(long_msg => sprintf("cpu temperature is '%s' degree centigrade", $value)); my ($exit, $warn, $crit) = $self->get_severity_numeric(section => 'temperature', instance => 'cpu', value => $value); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("CPU Temperature is '%s' degree centigrade", $value)); } - $self->{output}->perfdata_add(label => 'temp_cpu', unit => 'C', - value => $value - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => 'cpu', + value => $value + ); } my $system_temp = defined($self->{results}->{$oid_SystemTemperature_entry}->{$oid_SystemTemperature}) ? @@ -71,10 +74,13 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("System Temperature is '%s' degree centigrade", $value)); } - $self->{output}->perfdata_add(label => 'temp_system', unit => 'C', - value => $value - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => 'system', + value => $value + ); } } -1; \ No newline at end of file +1; diff --git a/storage/qnap/snmp/mode/hardware.pm b/storage/qnap/snmp/mode/hardware.pm index fe269f6aa..52e253b58 100644 --- a/storage/qnap/snmp/mode/hardware.pm +++ b/storage/qnap/snmp/mode/hardware.pm @@ -28,7 +28,7 @@ use warnings; sub set_system { my ($self, %options) = @_; - $self->{regexp_threshold_overload_check_section_option} = '^(temperature|disk|smartdisk|fan)$'; + $self->{regexp_threshold_overload_check_section_option} = '^(temperature|disk|smartdisk|fan|raid)$'; $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|disk|smartdisk|fan)$'; $self->{cb_hook2} = 'snmp_execute'; @@ -47,10 +47,15 @@ sub set_system { ['--', 'OK'], ['.*', 'CRITICAL'], ], + raid => [ + ['Ready', 'OK'], + ['degraded', 'WARNING'], + ['.*', 'CRITICAL'], + ], }; $self->{components_path} = 'storage::qnap::snmp::mode::components'; - $self->{components_module} = ['temperature', 'disk', 'fan']; + $self->{components_module} = ['temperature', 'disk', 'fan', 'raid']; } sub snmp_execute { @@ -66,9 +71,8 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - }); + $options{options}->add_options(arguments => { + }); return $self; } @@ -79,14 +83,14 @@ __END__ =head1 MODE -Check hardware (NAS.mib) (Fans, Temperatures, Disks). +Check hardware (NAS.mib) (Fans, Temperatures, Disks, Raid). =over 8 =item B<--component> Which component to check (Default: '.*'). -Can be: 'fan', 'disk', 'temperature'. +Can be: 'fan', 'disk', 'temperature', 'raid'. =item B<--filter> @@ -121,4 +125,4 @@ Example: --critical='temperature,system,40' --critical='disk,.*,40' =back -=cut \ No newline at end of file +=cut diff --git a/storage/qnap/snmp/mode/memory.pm b/storage/qnap/snmp/mode/memory.pm index 7928f07a7..5be2e608f 100644 --- a/storage/qnap/snmp/mode/memory.pm +++ b/storage/qnap/snmp/mode/memory.pm @@ -81,8 +81,11 @@ sub run { my $oid_SystemTotalMem = '.1.3.6.1.4.1.24681.1.2.2.0'; my $oid_SystemFreeMem = '.1.3.6.1.4.1.24681.1.2.3.0'; - my $result = $self->{snmp}->get_leef(oids => [ $oid_SystemTotalMem, $oid_SystemFreeMem ], - nothing_quit => 1); + my $result = $self->{snmp}->get_leef( + oids => [ $oid_SystemTotalMem, $oid_SystemFreeMem ], + nothing_quit => 1 + ); + my $total_size = $self->convert_bytes(value => $result->{$oid_SystemTotalMem}); my $memory_free = $self->convert_bytes(value => $result->{$oid_SystemFreeMem}); my $memory_used = $total_size - $memory_free; @@ -101,11 +104,14 @@ sub run { $used_value . " " . $used_unit, $prct_used, $free_value . " " . $free_unit, $prct_free)); - $self->{output}->perfdata_add(label => "used", unit => 'B', - value => int($memory_used), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size, cast_int => 1), - min => 0, max => int($total_size)); + $self->{output}->perfdata_add( + label => 'used', unit => 'B', + nlabel => 'memory.usage.bytes', + value => int($memory_used), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size, cast_int => 1), + min => 0, max => int($total_size) + ); $self->{output}->display(); $self->{output}->exit(); diff --git a/storage/qnap/snmp/mode/volumeusage.pm b/storage/qnap/snmp/mode/volumeusage.pm index 07e6beb85..6956ceff9 100644 --- a/storage/qnap/snmp/mode/volumeusage.pm +++ b/storage/qnap/snmp/mode/volumeusage.pm @@ -20,49 +20,36 @@ package storage::qnap::snmp::mode::volumeusage; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; - -my $plugin_options; - -my $maps_counters = { - '000_usage' => { set => { - key_values => [ - { name => 'display' }, { name => 'free' }, { name => 'used' }, - ], - closure_custom_calc => \&custom_usage_calc, - closure_custom_output => \&custom_usage_output, - closure_custom_perfdata => \&custom_usage_perfdata, - closure_custom_threshold_check => \&custom_usage_threshold, - } - }, -}; sub custom_usage_perfdata { my ($self, %options) = @_; - - my $label = 'used'; + + my ($label, $nlabel) = ('used', $self->{nlabel}); my $value_perf = $self->{result_values}->{used}; - if (defined($plugin_options->{free})) { - $label = 'free'; + if (defined($self->{instance_mode}->{option_results}->{free})) { + ($label, $nlabel) = ('free', 'volume.space.free.bytes'); $value_perf = $self->{result_values}->{free}; } - my $extra_label = ''; - $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); - if ($plugin_options->{units} eq '%') { + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $total_options{total} = $self->{result_values}->{total}; - $total_options{cast_int} = 1; + $total_options{cast_int} = 1; } - - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), - min => 0, max => $self->{result_values}->{total}); + + $self->{output}->perfdata_add( + label => $label, unit => 'B', + instances => $self->use_instances(extra_instance => $options{extra_instance}) ? $self->{result_values}->{display} : undef, + nlabel => $nlabel, + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}, %total_options), + min => 0, max => $self->{result_values}->{total} + ); } sub custom_usage_threshold { @@ -70,12 +57,12 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($plugin_options->{free})); - if ($plugin_options->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($plugin_options->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } ]); return $exit; } @@ -105,106 +92,46 @@ sub custom_usage_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'volume', type => 1, cb_prefix_output => 'prefix_volume_output', message_multiple => 'All volumes are ok' }, + ]; + + $self->{maps_counters}->{volume} = [ + { label => 'usage', nlabel => 'volume.space.usage.bytes', set => { + key_values => [ { name => 'display' }, { name => 'used' }, { name => 'free' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +sub prefix_volume_output { + my ($self, %options) = @_; + + return "Volume '" . $options{instance_value}->{display} . "' "; +} + 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' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); - - foreach (sort keys %{$maps_counters}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$_}->{threshold}) || $maps_counters->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - + $options{options}->add_options(arguments => { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - $plugin_options = $self->{option_results}; -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{volumes_selected}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All volume usages are ok'); - } - - foreach my $id (sort keys %{$self->{volumes_selected}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => $id); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{volumes_selected}->{$id}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{obj}->output(); - $long_msg .= $long_msg_append . $output; - $long_msg_append = ', '; - - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= $short_msg_append . $output; - $short_msg_append = ', '; - } - - $maps_counters->{$_}->{obj}->perfdata(level => 1, extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Volume '" . $self->{volumes_selected}->{$id}->{display} . "' $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Volume '" . $self->{volumes_selected}->{$id}->{display} . "' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Volume '" . $self->{volumes_selected}->{$id}->{display} . "' $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} - my $mapping = { SysVolumeDescr => { oid => '.1.3.6.1.4.1.24681.1.2.17.1.2' }, SysVolumeFS => { oid => '.1.3.6.1.4.1.24681.1.2.17.1.3' }, @@ -215,34 +142,38 @@ my $mapping = { sub manage_selection { my ($self, %options) = @_; - $self->{volumes_selected} = {}; + $self->{volume} = {}; my $oid_SysVolumeEntry = '.1.3.6.1.4.1.24681.1.2.17.1'; - $self->{results} = $self->{snmp}->get_table(oid => $oid_SysVolumeEntry, - start => $mapping->{SysVolumeDescr}->{oid}, - end => $mapping->{SysVolumeFreeSize}->{oid}, - nothing_quit => 1); - foreach my $oid (keys %{$self->{results}}) { + my $snmp_result = $options{snmp}->get_table( + oid => $oid_SysVolumeEntry, + start => $mapping->{SysVolumeDescr}->{oid}, + end => $mapping->{SysVolumeFreeSize}->{oid}, + nothing_quit => 1 + ); + foreach my $oid (keys %$snmp_result) { next if ($oid !~ /^$mapping->{SysVolumeDescr}->{oid}\.(\d+)/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); + 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->{SysVolumeDescr} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $result->{SysVolumeDescr} . "': no matching filter."); + $self->{output}->output_add(long_msg => "skipping '" . $result->{SysVolumeDescr} . "': no matching filter."); next; } my $free = $self->convert_bytes(value => $result->{SysVolumeFreeSize}); my $total = $self->convert_bytes(value => $result->{SysVolumeTotalSize}); if ($total == 0) { - $self->{output}->output_add(long_msg => "Skipping '" . $result->{SysVolumeDescr} . "': total size is 0."); + $self->{output}->output_add(long_msg => "skipping '" . $result->{SysVolumeDescr} . "': total size is 0."); next; } - $self->{volumes_selected}->{$instance} = { display => $result->{SysVolumeDescr}, - free => $free, used => $total - $free }; + $self->{volume}->{$instance} = { + display => $result->{SysVolumeDescr}, + free => $free, used => $total - $free + }; } - if (scalar(keys %{$self->{volumes_selected}}) <= 0) { + if (scalar(keys %{$self->{volume}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No entry found."); $self->{output}->option_exit(); } diff --git a/storage/qsan/nas/snmp/mode/components/disk.pm b/storage/qsan/nas/snmp/mode/components/disk.pm index f6b088415..6846aa0a8 100644 --- a/storage/qsan/nas/snmp/mode/components/disk.pm +++ b/storage/qsan/nas/snmp/mode/components/disk.pm @@ -69,12 +69,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Disk '%s' is '%s' C", $result->{pd_location}, $result->{hdd_temperature})); } - $self->{output}->perfdata_add(label => 'disk_temperature_' . $result->{pd_location}, unit => 'C', - value => $result->{hdd_temperature}, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'disk_temperature', unit => 'C', + nlabel => 'hardware.disk.temperature.celsius', + instances => $result->{pd_location}, + value => $result->{hdd_temperature}, + warning => $warn, + critical => $crit + ); } } -1; \ No newline at end of file +1; diff --git a/storage/qsan/nas/snmp/mode/components/fan.pm b/storage/qsan/nas/snmp/mode/components/fan.pm index 28fbec3e2..ccde0f4e3 100644 --- a/storage/qsan/nas/snmp/mode/components/fan.pm +++ b/storage/qsan/nas/snmp/mode/components/fan.pm @@ -69,11 +69,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("fan '%s' is '%s' rpm", $result->{ems_item}, $value)); } - $self->{output}->perfdata_add(label => 'fan_' . $result->{ems_item} . '_' . $instance, unit => 'rpm', - value => $value, - warning => $warn, - critical => $crit, min => 0 - ); + $self->{output}->perfdata_add( + label => 'fan', unit => 'rpm', + nlabel => 'hardware.fan.speed.rpm', + instances => [$result->{ems_item}, $instance], + value => $value, + warning => $warn, + critical => $crit, min => 0 + ); } } diff --git a/storage/qsan/nas/snmp/mode/components/temperature.pm b/storage/qsan/nas/snmp/mode/components/temperature.pm index e0b54047a..5a6e3dcfe 100644 --- a/storage/qsan/nas/snmp/mode/components/temperature.pm +++ b/storage/qsan/nas/snmp/mode/components/temperature.pm @@ -68,11 +68,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is '%s' C", $result->{ems_item}, $value)); } - $self->{output}->perfdata_add(label => 'temperature_' . $result->{ems_item} . '_' . $instance, unit => 'C', - value => $value, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'temperature', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => [$result->{ems_item}, $instance], + value => $value, + warning => $warn, + critical => $crit + ); } } diff --git a/storage/qsan/nas/snmp/mode/components/voltage.pm b/storage/qsan/nas/snmp/mode/components/voltage.pm index 20b5cfea6..0e14e5c49 100644 --- a/storage/qsan/nas/snmp/mode/components/voltage.pm +++ b/storage/qsan/nas/snmp/mode/components/voltage.pm @@ -68,11 +68,14 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("voltage '%s' is '%s' V", $result->{ems_item}, $value)); } - $self->{output}->perfdata_add(label => 'voltage_' . $result->{ems_item} . '_' . $instance, unit => 'V', - value => $value, - warning => $warn, - critical => $crit - ); + $self->{output}->perfdata_add( + label => 'voltage', unit => 'V', + nlabel => 'hardware.voltage.volt', + instances => [$result->{ems_item}, $instance], + value => $value, + warning => $warn, + critical => $crit + ); } } diff --git a/storage/quantum/dxi/ssh/mode/diskusage.pm b/storage/quantum/dxi/ssh/mode/diskusage.pm index 664d61816..6693b70c4 100644 --- a/storage/quantum/dxi/ssh/mode/diskusage.pm +++ b/storage/quantum/dxi/ssh/mode/diskusage.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; @@ -43,10 +41,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, @@ -71,8 +69,8 @@ sub custom_usage_output { sub custom_usage_calc { my ($self, %options) = @_; - $self->{result_values}->{total} = $instance_mode->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_disk_capacity'}); - $self->{result_values}->{used} = $instance_mode->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_used_disk_space'}); + $self->{result_values}->{total} = $self->{instance_mode}->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_disk_capacity'}); + $self->{result_values}->{used} = $self->{instance_mode}->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_used_disk_space'}); if ($self->{result_values}->{total} != 0) { $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; @@ -116,8 +114,8 @@ sub custom_volume_output { sub custom_volume_calc { my ($self, %options) = @_; - $self->{result_values}->{volume} = $instance_mode->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}}); - $self->{result_values}->{total} = $instance_mode->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_disk_capacity'}); + $self->{result_values}->{volume} = $self->{instance_mode}->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}}); + $self->{result_values}->{total} = $self->{instance_mode}->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_disk_capacity'}); $self->{result_values}->{display} = $options{extra_options}->{display_ref}; $self->{result_values}->{label} = $options{extra_options}->{label_ref}; @@ -219,20 +217,19 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'syscli' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '--get diskusage' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'syscli' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '--get diskusage' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); return $self; } @@ -243,9 +240,7 @@ sub check_options { if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') { $self->{option_results}->{remote} = 1; - } - - $instance_mode = $self; + } } sub manage_selection { diff --git a/storage/quantum/dxi/ssh/mode/memory.pm b/storage/quantum/dxi/ssh/mode/memory.pm index 4b41ea623..e2108c692 100644 --- a/storage/quantum/dxi/ssh/mode/memory.pm +++ b/storage/quantum/dxi/ssh/mode/memory.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_usage_perfdata { my ($self, %options) = @_; @@ -43,10 +41,10 @@ sub custom_usage_threshold { my ($exit, $threshold_value); $threshold_value = $self->{result_values}->{used}; - $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); - if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{free} if (defined($self->{instance_mode}->{option_results}->{free})); + if ($self->{instance_mode}->{option_results}->{units} eq '%') { $threshold_value = $self->{result_values}->{prct_used}; - $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + $threshold_value = $self->{result_values}->{prct_free} if (defined($self->{instance_mode}->{option_results}->{free})); } $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, @@ -71,8 +69,8 @@ sub custom_usage_output { sub custom_usage_calc { my ($self, %options) = @_; - $self->{result_values}->{total} = $instance_mode->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_total'}); - $self->{result_values}->{free} = $instance_mode->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_free'}); + $self->{result_values}->{total} = $self->{instance_mode}->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_total'}); + $self->{result_values}->{free} = $self->{instance_mode}->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_free'}); if ($self->{result_values}->{total} != 0) { $self->{result_values}->{used} = $self->{result_values}->{total} - $self->{result_values}->{free}; @@ -129,20 +127,19 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'syscli' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '--getstatus systemmemory' }, - "units:s" => { name => 'units', default => '%' }, - "free" => { name => 'free' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'syscli' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '--getstatus systemmemory' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); return $self; } @@ -153,9 +150,7 @@ sub check_options { if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') { $self->{option_results}->{remote} = 1; - } - - $instance_mode = $self; + } } sub manage_selection { diff --git a/storage/quantum/dxi/ssh/mode/reduction.pm b/storage/quantum/dxi/ssh/mode/reduction.pm index f9308de93..aeb2ab7a8 100644 --- a/storage/quantum/dxi/ssh/mode/reduction.pm +++ b/storage/quantum/dxi/ssh/mode/reduction.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_volume_perfdata { my ($self, %options) = @_; @@ -56,7 +54,7 @@ sub custom_volume_output { sub custom_volume_calc { my ($self, %options) = @_; - $self->{result_values}->{volume} = $instance_mode->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}}); + $self->{result_values}->{volume} = $self->{instance_mode}->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}}); $self->{result_values}->{display} = $options{extra_options}->{display_ref}; $self->{result_values}->{label} = $options{extra_options}->{label_ref}; @@ -196,18 +194,17 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'syscli' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '--get datareductionstat' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'syscli' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '--get datareductionstat' }, + }); return $self; } @@ -218,9 +215,7 @@ sub check_options { if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') { $self->{option_results}->{remote} = 1; - } - - $instance_mode = $self; + } } sub manage_selection { diff --git a/storage/quantum/dxi/ssh/mode/throughput.pm b/storage/quantum/dxi/ssh/mode/throughput.pm index 220ffd571..50d96c596 100644 --- a/storage/quantum/dxi/ssh/mode/throughput.pm +++ b/storage/quantum/dxi/ssh/mode/throughput.pm @@ -25,8 +25,6 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -my $instance_mode; - sub custom_volume_perfdata { my ($self, %options) = @_; @@ -56,7 +54,7 @@ sub custom_volume_output { sub custom_volume_calc { my ($self, %options) = @_; - $self->{result_values}->{volume} = $instance_mode->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}}); + $self->{result_values}->{volume} = $self->{instance_mode}->convert_to_bytes(raw_value => $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}}); $self->{result_values}->{display} = $options{extra_options}->{display_ref}; $self->{result_values}->{label} = $options{extra_options}->{label_ref}; @@ -115,18 +113,17 @@ sub new { bless $self, $class; $self->{version} = '1.0'; - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'syscli' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '--get ingestrate' }, - }); + $options{options}->add_options(arguments => { + "hostname:s" => { name => 'hostname' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'syscli' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '--get ingestrate' }, + }); return $self; } @@ -138,8 +135,6 @@ sub check_options { if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') { $self->{option_results}->{remote} = 1; } - - $instance_mode = $self; } sub manage_selection { diff --git a/storage/storagetek/sl/snmp/mode/components/temperature.pm b/storage/storagetek/sl/snmp/mode/components/temperature.pm index 96f440e85..e33a0eef2 100644 --- a/storage/storagetek/sl/snmp/mode/components/temperature.pm +++ b/storage/storagetek/sl/snmp/mode/components/temperature.pm @@ -73,12 +73,15 @@ sub check { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Temperature '%s' is %s degree centigrade", $result->{slHdwTempSensorName}, $result->{slHdwTempSensorCurrentTemp})); } - $self->{output}->perfdata_add(label => 'temp_' . $result->{slHdwTempSensorName}, unit => 'C', - value => $result->{slHdwTempSensorCurrentTemp}, - warning => $warn, - critical => $crit, - ); + $self->{output}->perfdata_add( + label => 'temp', unit => 'C', + nlabel => 'hardware.temperature.celsius', + instances => $result->{slHdwTempSensorName}, + value => $result->{slHdwTempSensorCurrentTemp}, + warning => $warn, + critical => $crit, + ); } } -1; \ No newline at end of file +1;