diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 3a4edf690..000000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/apps/elasticsearch/mode/cluster.pm b/apps/elasticsearch/mode/cluster.pm index a72dedd5f..b11d9b85e 100644 --- a/apps/elasticsearch/mode/cluster.pm +++ b/apps/elasticsearch/mode/cluster.pm @@ -44,9 +44,9 @@ sub new { $options{options}->add_options(arguments => { "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '9200'}, + "port:s" => { name => 'port', default => 9200 }, "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path' }, + "urlpath:s" => { name => 'url_path', default => '/_cluster/health' }, "credentials" => { name => 'credentials' }, "username:s" => { name => 'username' }, "password:s" => { name => 'password' }, @@ -77,7 +77,6 @@ sub check_options { push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status}; } - $self->{option_results}->{url_path} = $self->{option_results}->{url_path} . "_cluster/health/"; $self->{http}->set_options(%{$self->{option_results}}); } @@ -176,7 +175,7 @@ Specify https if needed (Default: 'http') =item B<--urlpath> -Set path to get Elasticsearch information (Default: '/') +Set path to get Elasticsearch information (Default: '/_cluster/health') =item B<--credentials> diff --git a/apps/elasticsearch/mode/indices.pm b/apps/elasticsearch/mode/indices.pm index 42c4e5b63..0d510a2a1 100644 --- a/apps/elasticsearch/mode/indices.pm +++ b/apps/elasticsearch/mode/indices.pm @@ -51,9 +51,9 @@ sub new { $options{options}->add_options(arguments => { "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '9200'}, + "port:s" => { name => 'port', default => 9200 }, "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path' }, + "urlpath:s" => { name => 'url_path', default => '/_cluster/health' }, "credentials" => { name => 'credentials' }, "username:s" => { name => 'username' }, "password:s" => { name => 'password' }, @@ -84,8 +84,7 @@ sub check_options { push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status}; } - $self->{option_results}->{url_path} = $self->{option_results}->{url_path} . "_cluster/health"; - $self->{option_results}->{get_param} = ['level=indices']; + $self->{option_results}->{get_param} = [ 'level=indices' ]; $self->{http}->set_options(%{$self->{option_results}}); } @@ -172,7 +171,7 @@ Specify https if needed (Default: 'http') =item B<--urlpath> -Set path to get Elasticsearch information (Default: '/') +Set path to get Elasticsearch information (Default: '/_cluster/health') =item B<--credentials> diff --git a/apps/elasticsearch/mode/nodescount.pm b/apps/elasticsearch/mode/nodescount.pm index d55e25f3c..1babb409a 100644 --- a/apps/elasticsearch/mode/nodescount.pm +++ b/apps/elasticsearch/mode/nodescount.pm @@ -36,9 +36,9 @@ sub new { $options{options}->add_options(arguments => { "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => '9200'}, + "port:s" => { name => 'port', default => 9200 }, "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path' }, + "urlpath:s" => { name => 'url_path', default => '/_cluster/stats' }, "credentials" => { name => 'credentials' }, "username:s" => { name => 'username' }, "password:s" => { name => 'password' }, @@ -64,7 +64,6 @@ sub check_options { $self->{output}->option_exit(); } - $self->{option_results}->{url_path} = $self->{option_results}->{url_path} . "_cluster/stats/"; $self->{http}->set_options(%{$self->{option_results}}); } @@ -141,7 +140,7 @@ Specify https if needed (Default: 'http') =item B<--urlpath> -Set path to get Elasticsearch information (Default: '/') +Set path to get Elasticsearch information (Default: '_cluster/stats') =item B<--credentials> diff --git a/apps/github/mode/issues.pm b/apps/github/mode/issues.pm index 0b081cad2..f2c2f7f2f 100644 --- a/apps/github/mode/issues.pm +++ b/apps/github/mode/issues.pm @@ -73,12 +73,10 @@ sub check_options { $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); $self->{output}->option_exit(); } - - $self->{option_results}->{url_path} = "/repos/" . $self->{option_results}->{owner} . "/" . $self->{option_results}->{repository} . "/issues"; + + $self->{option_results}->{url_path} = "/search/issues?q=state:open+repo:" . $self->{option_results}->{owner} . "/" . $self->{option_results}->{repository}; if (defined($self->{option_results}->{label}) && $self->{option_results}->{label} ne '') { - $self->{option_results}->{get_param} = ['state=open', 'labels=' . $self->{option_results}->{label}, 'per_page=1000']; - } else { - $self->{option_results}->{get_param} = ['state=open', 'per_page=1000']; + $self->{option_results}->{url_path} .= "+label:" . $self->{option_results}->{label}; } $self->{http}->set_options(%{$self->{option_results}}); } @@ -86,6 +84,7 @@ sub check_options { sub run { my ($self, %options) = @_; + my $jsoncontent = $self->{http}->request(); my $json = JSON->new; @@ -98,9 +97,8 @@ sub run { $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); $self->{output}->option_exit(); } - - # Number of issues is array length - my $nb_issues = @{$webcontent}; + + my $nb_issues = $webcontent->{total_count}; my $exit = $self->{perfdata}->threshold_check(value => $nb_issues, threshold => [ { label => 'critical', exit_litteral => 'critical' }, , { label => 'warning', exit_litteral => 'warning' } ]); diff --git a/apps/github/mode/stats.pm b/apps/github/mode/stats.pm new file mode 100644 index 000000000..957a06a14 --- /dev/null +++ b/apps/github/mode/stats.pm @@ -0,0 +1,153 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package apps::github::mode::stats; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::http; +use JSON; +use Data::Dumper; + +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', default => 'api.github.com' }, + "port:s" => { name => 'port', default => '443'}, + "proto:s" => { name => 'proto', default => 'https' }, + "credentials" => { name => 'credentials' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "timeout:s" => { name => 'timeout' }, + "owner:s" => { name => 'owner' }, + "repository:s" => { name => 'repository' }, + }); + + $self->{http} = centreon::plugins::http->new(output => $self->{output}); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{repository})) { + $self->{output}->add_option_msg(short_msg => "Please set the repository option"); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{owner})) { + $self->{output}->add_option_msg(short_msg => "Please set the owner option"); + $self->{output}->option_exit(); + } + + $self->{option_results}->{url_path} = "/repos/" . $self->{option_results}->{owner} . "/" . $self->{option_results}->{repository}; + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub run { + my ($self, %options) = @_; + + my $jsoncontent = $self->{http}->request(); + + my $json = JSON->new; + my $webcontent; + eval { + $webcontent = $json->decode($jsoncontent); + }; + + 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(); + } + + my $watchers = $webcontent->{subscribers_count}; + my $forks = $webcontent->{forks_count}; + my $stars = $webcontent->{watchers_count}; + + $self->{output}->output_add(severity => "OK", + short_msg => sprintf("%d forks - %d watchers - %d stars", $forks, $watchers, $stars)); + + $self->{output}->perfdata_add(label => 'forks', + value => $forks, + min => 0); + $self->{output}->perfdata_add(label => 'watchers', + value => $watchers, + min => 0); + $self->{output}->perfdata_add(label => 'stars', + value => $stars, + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check GitHub's statistics + +=over 8 + +=item B<--hostname> + +IP Addr/FQDN of the GitHub's status website (Default: status.github.com) + +=item B<--port> + +Port used by GitHub's status website (Default: '443') + +=item B<--proto> + +Specify https if needed (Default: 'https') + +=item B<--urlpath> + +Set path to get GitHub's status information (Default: '/repo/:owner/:repository') + +=item B<--credentials> + +Specify this option if you access webpage over basic authentification + +=item B<--username> + +Specify username + +=item B<--password> + +Specify password + +=item B<--timeout> + +Threshold for HTTP timeout (Default: 5) + +=back + +=cut diff --git a/apps/github/plugin.pm b/apps/github/plugin.pm index ca0c4cc34..748e1973d 100644 --- a/apps/github/plugin.pm +++ b/apps/github/plugin.pm @@ -36,6 +36,7 @@ sub new { 'issues' => 'apps::github::mode::issues', 'commits' => 'apps::github::mode::commits', 'pullrequests' => 'apps::github::mode::pullrequests', + 'stats' => 'apps::github::mode::stats', ); return $self; } diff --git a/apps/kayako/api/mode/ticketcount.pm b/apps/kayako/api/mode/ticketcount.pm index 36770e3de..15ba28222 100644 --- a/apps/kayako/api/mode/ticketcount.pm +++ b/apps/kayako/api/mode/ticketcount.pm @@ -140,7 +140,7 @@ sub reload_cache { my $salt = ''; $salt .= int(rand(10)) for 1..10; my $digest = hmac_sha256_base64 ($salt, $self->{option_results}->{kayako_secret_key}); - my $webcontent = $self->{http}->request(url_path => $url_original_path . "/Base/Department&apikey=" . $self->{option_results}->{kayako_api_key} . "&salt=" . $salt . "&signature=" . $digest . "=";); + my $webcontent = $self->{http}->request(url_path => $url_original_path . "/Base/Department&apikey=" . $self->{option_results}->{kayako_api_key} . "&salt=" . $salt . "&signature=" . $digest . "="); my $xp = XML::XPath->new($webcontent); my $nodes = $xp->find('departments/department'); diff --git a/apps/protocols/http/mode/jsoncontent.pm b/apps/protocols/http/mode/jsoncontent.pm index 0987fa4ed..372082276 100644 --- a/apps/protocols/http/mode/jsoncontent.pm +++ b/apps/protocols/http/mode/jsoncontent.pm @@ -343,11 +343,11 @@ Threshold critical if the string match =item B<--warning-time> -Threshold warning in ms of webservice response time +Threshold warning in seconds of webservice response time =item B<--critical-time> -Threshold critical in ms of webservice response time +Threshold critical in seconds of webservice response time =back diff --git a/apps/protocols/http/mode/soapcontent.pm b/apps/protocols/http/mode/soapcontent.pm index 2b02b790e..068c2b216 100644 --- a/apps/protocols/http/mode/soapcontent.pm +++ b/apps/protocols/http/mode/soapcontent.pm @@ -356,11 +356,11 @@ Threshold critical if the string match =item B<--warning-time> -Threshold warning in ms of webservice response time +Threshold warning in seconds of webservice response time =item B<--critical-time> -Threshold critical in ms of webservice response time +Threshold critical in seconds of webservice response time =back diff --git a/apps/protocols/x509/mode/validity.pm b/apps/protocols/x509/mode/validity.pm index 754aa220e..430ac5e43 100644 --- a/apps/protocols/x509/mode/validity.pm +++ b/apps/protocols/x509/mode/validity.pm @@ -33,11 +33,12 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.3'; + $self->{version} = '1.4'; $options{options}->add_options(arguments => { "hostname:s" => { name => 'hostname' }, "port:s" => { name => 'port' }, + "servername:s" => { name => 'servername' }, "validity-mode:s" => { name => 'validity_mode' }, "warning-date:s" => { name => 'warning' }, "critical-date:s" => { name => 'critical' }, @@ -77,104 +78,76 @@ sub check_options { sub run { my ($self, %options) = @_; - #Global variables - my ($connection, $ctx, $ssl, $cert); + # Global variables + my ($cert, $client); - #Create Socket connection - $connection = IO::Socket::INET->new(PeerAddr => $self->{option_results}->{hostname}, - PeerPort => $self->{option_results}->{port}, - Timeout => $self->{option_results}->{timeout}, - ); - if (!defined($connection)) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("%s", $!)); - $self->{output}->display(); - $self->{output}->exit(); - } else { - #Create SSL context - eval { $ctx = Net::SSLeay::CTX_new() }; - if ($@) { + eval { $client = IO::Socket::SSL->new( + PeerHost => $self->{option_results}->{hostname}, + PeerPort => $self->{option_results}->{port}, + $self->{option_results}->{servername} ? ( SSL_hostname => $self->{option_results}->{servername} ):(), + ) }; + if ($@) { $self->{output}->output_add(severity => 'CRITICAL', short_msg => sprintf ("%s", $!)); $self->{output}->display(); $self->{output}->exit() - } + } - #Create SSL connection - Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL); - - eval { $ssl = Net::SSLeay::new($ctx) }; - if ($@) { + #Retrieve Certificat + eval { $cert = $client->peer_certificate() }; + if ($@) { $self->{output}->output_add(severity => 'CRITICAL', short_msg => sprintf("%s", $!)); $self->{output}->display(); $self->{output}->exit() - } + } - eval { Net::SSLeay::set_fd($ssl, fileno($connection)) }; - if ($@) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("%s", $!)); - - $self->{output}->display(); - $self->{output}->exit() - } - - eval { Net::SSLeay::connect($ssl) }; - if ($@) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("%s", $!)); - - $self->{output}->display(); - $self->{output}->exit() - } - - #Retrieve Certificat - $cert = Net::SSLeay::get_peer_certificate($ssl); - - #Expiration Date - if ($self->{option_results}->{validity_mode} eq 'expiration') { - (my $notafterdate = Net::SSLeay::P_ASN1_UTCTIME_put2string(Net::SSLeay::X509_get_notAfter($cert))) =~ s/ GMT//; - my $daysbefore = int((&UnixDate(&ParseDate($notafterdate),"%s") - time) / 86400); - my $exit = $self->{perfdata}->threshold_check(value => $daysbefore, - threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Certificate expiration days: %s - Validity Date: %s", $daysbefore, $notafterdate)); - - $self->{output}->display(); - $self->{output}->exit() - - #Subject Name - } elsif ($self->{option_results}->{validity_mode} eq 'subject') { - my $subject_name = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_subject_name($cert)); + #Expiration Date + if ($self->{option_results}->{validity_mode} eq 'expiration') { + (my $notafterdate = Net::SSLeay::P_ASN1_UTCTIME_put2string(Net::SSLeay::X509_get_notAfter($cert))) =~ s/ GMT//; + my $daysbefore = int((&UnixDate(&ParseDate($notafterdate),"%s") - time) / 86400); + my $exit = $self->{perfdata}->threshold_check(value => $daysbefore, + threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Certificate expiration days: %s - Validity Date: %s", $daysbefore, $notafterdate)); + #Subject Name + } elsif ($self->{option_results}->{validity_mode} eq 'subject') { + my @subject_matched = (); + my @subject_name = Net::SSLeay::X509_get_subjectAltNames($cert); + foreach my $subject_name (@subject_name) { if ($subject_name =~ /$self->{option_results}->{subjectname}/mi) { - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("Subject Name '%s' is present in Certificate: %s", $self->{option_results}->{subjectname}, $subject_name)); + push @subject_matched, $subject_name; } else { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Subject Name '%s' is not present in Certificate: %s", $self->{option_results}->{subjectname}, $subject_name)); + if ($subject_name =~ /[\w\-]+(\.[\w\-]+)*\.\w+/) { + $self->{output}->output_add(long_msg => sprintf("Subject Name '%s' is also present in Certificate", $subject_name), debug => 1); + } } + } - $self->{output}->display(); - $self->{output}->exit() + if (@subject_matched == 0) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => sprintf("No Subject Name matched '%s' in Certificate", $self->{option_results}->{subjectname})); + } else { + $self->{output}->output_add(severity => 'OK', + short_msg => sprintf("Subject Name [%s] is present in Certificate", join(', ', @subject_matched))); + } - #Issuer Name - } elsif ($self->{option_results}->{validity_mode} eq 'issuer') { - my $issuer_name = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_issuer_name($cert)); - if ($issuer_name =~ /$self->{option_results}->{issuername}/mi) { - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("Issuer Name '%s' is present in Certificate: %s", $self->{option_results}->{issuername}, $issuer_name)); - } else { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Issuer Name '%s' is not present in Certificate: %s", $self->{option_results}->{issuername}, $issuer_name)); - } - - $self->{output}->display(); - $self->{output}->exit() + #Issuer Name + } elsif ($self->{option_results}->{validity_mode} eq 'issuer') { + my $issuer_name = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_issuer_name($cert)); + if ($issuer_name =~ /$self->{option_results}->{issuername}/mi) { + $self->{output}->output_add(severity => 'OK', + short_msg => sprintf("Issuer Name '%s' is present in Certificate: %s", $self->{option_results}->{issuername}, $issuer_name)); + } else { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => sprintf("Issuer Name '%s' is not present in Certificate: %s", $self->{option_results}->{issuername}, $issuer_name)); } } + + $self->{output}->display(); + $self->{output}->exit(); } 1; @@ -183,7 +156,7 @@ __END__ =head1 MODE -Check X509's certificate validity +Check X509's certificate validity (for SMTPS, POPS, IMAPS, HTTPS) =over 8 @@ -191,9 +164,13 @@ Check X509's certificate validity IP Addr/FQDN of the host +=item B<--servername> + +Servername of the host for SNI support (only with IO::Socket::SSL >= 1.56) (eg: foo.bar.com) + =item B<--port> -Port used by Server (Default: '443') +Port used by Server =item B<--validity-mode> @@ -210,7 +187,7 @@ Threshold critical in days (Days before expiration, eg: '30:' for 30 days before =item B<--subjectname> -Subject Name pattern +Subject Name pattern (support alternative subject name) =item B<--issuername> diff --git a/apps/selenium/mode/scenario.pm b/apps/selenium/mode/scenario.pm index dd41cc2cd..27ead607b 100644 --- a/apps/selenium/mode/scenario.pm +++ b/apps/selenium/mode/scenario.pm @@ -91,7 +91,7 @@ sub check_options { alarm($self->{option_results}->{timeout}); } if (!defined($self->{option_results}->{scenario})) { - $self->{output}->add_option_msg(short_msg => "Please specify a scenario name" . $self->{option_results}->{scenario} . "."); + $self->{output}->add_option_msg(short_msg => "Please specify a scenario name."); $self->{output}->option_exit(); } } @@ -124,6 +124,7 @@ sub run { my $step = $listActionNode->get_nodelist; my $temp_step = 0; my $stepOk = 0; + my ($last_echo_msg, $last_cmd); my $exit1 = 'UNKNOWN'; foreach my $actionNode ($listActionNode->get_nodelist) { ($action, $filter, $value) = $xp->find('./td', $actionNode)->get_nodelist; @@ -142,11 +143,18 @@ sub run { sleep($sleepTime / 1000); $stepOk++; $self->{output}->output_add(long_msg => "Step " . $temp_step . " - Pause : " . $sleepTime . "ms"); + # It's an echo command => do not send it to Selenium server + # and store the associated string so that it can be displayed + # in case of a failure as an info message } elsif ($trim_action eq 'echo'){ - next; + $last_echo_msg = $trim_filter; + # Prevent output breakage in case of echo message contains invalid chars + $last_echo_msg =~ s/\||\n/ - /msg; + $stepOk += 1; } else { my $exit_command; + $last_cmd = $trim_action . ' ' . $trim_filter . ' ' . $trim_value; eval { $exit_command = $sel->do_command($trim_action, $trim_filter, $trim_value); }; @@ -172,8 +180,17 @@ sub run { my $exit2 = $self->{perfdata}->threshold_check(value => $timeelapsed, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2 ]); - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("%d/%d steps (%.3fs)", $stepOk, $step, $timeelapsed)); + if ($exit eq 'OK') { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("%d/%d steps (%.3fs)", $stepOk, $step, $timeelapsed)); + } else { + my $extra_info = $last_cmd; + if (defined($last_echo_msg)) { + $extra_info .= " - $last_echo_msg"; + } + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("%d/%d steps (%.3fs) - %s", $stepOk, $step, $timeelapsed, $extra_info)); + } $self->{output}->perfdata_add(label => "time", unit => 's', value => sprintf('%.3f', $timeelapsed), min => 0, diff --git a/centreon/common/airespace/snmp/mode/apchannelinterference.pm b/centreon/common/airespace/snmp/mode/apchannelinterference.pm index 87f7cd341..ee3b1d882 100644 --- a/centreon/common/airespace/snmp/mode/apchannelinterference.pm +++ b/centreon/common/airespace/snmp/mode/apchannelinterference.pm @@ -20,38 +20,44 @@ package centreon::common::airespace::snmp::mode::apchannelinterference; -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_interference-power' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'interference_power' }, { name => 'label_perfdata' }, - ], - output_template => 'Interference Power : %s', - perfdatas => [ - { label => 'interference_power', value => 'interference_power_absolute', template => '%s', - label_extra_instance => 1, instance_use => 'label_perfdata_absolute' }, - ], - } - }, - '001_interference-util' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'interference_util' }, { name => 'label_perfdata' }, - ], - output_template => 'Interference Utilization : %s %%', - perfdatas => [ - { label => 'interference_util', value => 'interference_util_absolute', template => '%s', - unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'label_perfdata_absolute' }, - ], - } - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'ap', type => 1, cb_prefix_output => 'prefix_ap_output', message_multiple => 'All AP interference statistics are ok' }, + ]; + $self->{maps_counters}->{ap} = [ + { label => 'interference-power', set => { + key_values => [ { name => 'interference_power' }, { name => 'label_perfdata' } ], + output_template => 'Interference Power : %s', + perfdatas => [ + { label => 'interference_power', value => 'interference_power_absolute', template => '%s', + label_extra_instance => 1, instance_use => 'label_perfdata_absolute' }, + ], + } + }, + { label => 'interference-util', set => { + key_values => [ { name => 'interference_util' }, { name => 'label_perfdata' } ], + output_template => 'Interference Utilization : %s %%', + perfdatas => [ + { label => 'interference_util', value => 'interference_util_absolute', template => '%s', + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'label_perfdata_absolute' }, + ], + } + }, + ]; +} + +sub prefix_ap_output { + my ($self, %options) = @_; + + return $options{instance_value}->{display} . " "; +} sub new { my ($class, %options) = @_; @@ -64,97 +70,10 @@ sub new { "filter-name:s" => { name => 'filter_name' }, "filter-channel:s" => { name => 'filter_channel' }, }); - - 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(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}); - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $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->{ap_selected}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All AP interference statistics are ok'); - } - - foreach my $id ($self->{snmp}->oid_lex_sort(keys %{$self->{ap_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->{ap_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(extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => $self->{ap_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->{ap_selected}->{$id}->{display} . " $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => $self->{ap_selected}->{$id}->{display} . " $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} - my $oid_bsnAPName = '.1.3.6.1.4.1.14179.2.2.1.1.3'; my $oid_bsnAPIfInterferencePower = '.1.3.6.1.4.1.14179.2.2.14.1.2'; my $oid_bsnAPIfInterferenceUtilization = '.1.3.6.1.4.1.14179.2.2.14.1.22'; @@ -162,8 +81,8 @@ my $oid_bsnAPIfInterferenceUtilization = '.1.3.6.1.4.1.14179.2.2.14.1.22'; sub manage_selection { my ($self, %options) = @_; - $self->{ap_selected} = {}; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ { oid => $oid_bsnAPName }, + $self->{ap} = {}; + $self->{results} = $options{snmp}->get_multiple_table(oids => [ { oid => $oid_bsnAPName }, { oid => $oid_bsnAPIfInterferencePower }, { oid => $oid_bsnAPIfInterferenceUtilization }, ], @@ -187,7 +106,7 @@ sub manage_selection { next; } - $self->{ap_selected}->{$instance_mac . '.' . $instance_end} = { + $self->{ap}->{$instance_mac . '.' . $instance_end} = { display => "AP '" . $self->{results}->{$oid_bsnAPName}->{$oid} . "' Slot $1 Channel $2", label_perfdata => $self->{results}->{$oid_bsnAPName}->{$oid} . "_$1_$2", interference_power => $self->{results}->{$oid_bsnAPIfInterferencePower}->{$oid_bsnAPIfInterferencePower . '.' . $instance_mac . '.' . $instance_end}, @@ -197,7 +116,7 @@ sub manage_selection { } } - if (scalar(keys %{$self->{ap_selected}}) <= 0) { + if (scalar(keys %{$self->{ap}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No entry found."); $self->{output}->option_exit(); } @@ -213,6 +132,11 @@ Check AP Channel Interference. =over 8 +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='interference-util' + =item B<--warning-*> Threshold warning. diff --git a/centreon/common/airespace/snmp/mode/apchannelnoise.pm b/centreon/common/airespace/snmp/mode/apchannelnoise.pm index 4accb7bc1..2dbce5b9d 100644 --- a/centreon/common/airespace/snmp/mode/apchannelnoise.pm +++ b/centreon/common/airespace/snmp/mode/apchannelnoise.pm @@ -20,26 +20,35 @@ package centreon::common::airespace::snmp::mode::apchannelnoise; -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_noise-power' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'noise_power' }, { name => 'label_perfdata' } - ], - output_template => 'Noise Power : %s dBm', - perfdatas => [ - { label => 'noise_power', value => 'noise_power_absolute', template => '%s', - unit => 'dBm', label_extra_instance => 1, instance_use => 'label_perfdata_absolute' }, - ], - } - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'ap', type => 1, cb_prefix_output => 'prefix_ap_output', message_multiple => 'All AP noise statistics are ok' }, + ]; + $self->{maps_counters}->{ap} = [ + { label => 'noise-power', set => { + key_values => [ { name => 'noise_power' }, { name => 'label_perfdata' } ], + output_template => 'Noise Power : %s dBm', + perfdatas => [ + { label => 'noise_power', value => 'noise_power_absolute', template => '%s', + unit => 'dBm', label_extra_instance => 1, instance_use => 'label_perfdata_absolute' }, + ], + } + }, + ]; +} + +sub prefix_ap_output { + my ($self, %options) = @_; + + return $options{instance_value}->{display} . " "; +} sub new { my ($class, %options) = @_; @@ -53,107 +62,18 @@ sub new { "filter-channel:s" => { name => 'filter_channel' }, }); - 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(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}); - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $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->{ap_selected}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All AP noise statistics are ok'); - } - - foreach my $id ($self->{snmp}->oid_lex_sort(keys %{$self->{ap_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->{ap_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(extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => $self->{ap_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->{ap_selected}->{$id}->{display} . " $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => $self->{ap_selected}->{$id}->{display} . " $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} - my $oid_bsnAPName = '.1.3.6.1.4.1.14179.2.2.1.1.3'; my $oid_bsnAPIfDBNoisePower = '.1.3.6.1.4.1.14179.2.2.15.1.21'; sub manage_selection { my ($self, %options) = @_; - $self->{ap_selected} = {}; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ { oid => $oid_bsnAPName }, - { oid => $oid_bsnAPIfDBNoisePower }, - ], - nothing_quit => 1); + $self->{ap} = {}; + $self->{results} = $options{snmp}->get_multiple_table(oids => [ { oid => $oid_bsnAPName }, { oid => $oid_bsnAPIfDBNoisePower } ], + nothing_quit => 1); foreach my $oid (keys %{$self->{results}->{$oid_bsnAPName}}) { $oid =~ /^$oid_bsnAPName\.(.*)$/; my $instance_mac = $1; @@ -173,7 +93,7 @@ sub manage_selection { next; } - $self->{ap_selected}->{$instance_mac . '.' . $instance_end} = { + $self->{ap}->{$instance_mac . '.' . $instance_end} = { display => "AP '" . $self->{results}->{$oid_bsnAPName}->{$oid} . "' Slot $1 Channel $2", label_perfdata => $self->{results}->{$oid_bsnAPName}->{$oid} . "_$1_$2", noise_power => $self->{results}->{$oid_bsnAPIfDBNoisePower}->{$oid_bsnAPIfDBNoisePower . '.' . $instance_mac . '.' . $instance_end} @@ -182,7 +102,7 @@ sub manage_selection { } } - if (scalar(keys %{$self->{ap_selected}}) <= 0) { + if (scalar(keys %{$self->{ap}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No entry found."); $self->{output}->option_exit(); } diff --git a/centreon/common/airespace/snmp/mode/apstatus.pm b/centreon/common/airespace/snmp/mode/apstatus.pm index c3e230234..9fe95a357 100644 --- a/centreon/common/airespace/snmp/mode/apstatus.pm +++ b/centreon/common/airespace/snmp/mode/apstatus.pm @@ -20,64 +20,35 @@ package centreon::common::airespace::snmp::mode::apstatus; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -my $maps_counters = { - '0_status' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'opstatus' }, { name => 'admstatus' }, - ], - threshold => 0, - closure_custom_calc => \&custom_status_calc, - closure_custom_output => \&custom_status_output, - closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&custom_threshold_output, - } - }, -}; -my $thresholds = { - ap => [ - ['associated', 'OK'], - ['disassociating', 'CRITICAL'], - ['downloading', 'WARNING'], - ], -}; -my $overload_th; - -sub get_severity { - my (%options) = @_; - my $status = 'UNKNOWN'; # default - - if (defined($overload_th->{$options{section}})) { - foreach (@{$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; -} +my $instance_mode; sub custom_threshold_output { - my ($self, %options) = @_; + my ($self, %options) = @_; + my $status = 'ok'; + my $message; - if ($self->{result_values}->{admstatus} eq 'disabled') { - return 'ok'; + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); } - return get_severity(section => 'ap', value => $self->{result_values}->{opstatus}); + + return $status; } sub custom_status_output { @@ -98,9 +69,59 @@ 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}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_init => 'skip_global', }, + { name => 'ap', type => 1, cb_prefix_output => 'prefix_ap_output', message_multiple => 'All AP status are ok' } + ]; + $self->{maps_counters}->{global} = [ + { label => 'total', set => { + key_values => [ { name => 'total' } ], + output_template => 'Total ap : %s', + perfdatas => [ + { label => 'total', value => 'total_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'total-associated', set => { + key_values => [ { name => 'associated' } ], + output_template => 'Total ap associated : %s', + perfdatas => [ + { label => 'total_associated', value => 'associated_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'total-disassociating', set => { + key_values => [ { name => 'disassociating' } ], + output_template => 'Total ap disassociating : %s', + perfdatas => [ + { label => 'total_disassociating', value => 'disassociating_absolute', template => '%s', + min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{ap} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'opstatus' }, { name => 'admstatus' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_threshold_output'), + } + }, + ]; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -110,22 +131,9 @@ sub new { $options{options}->add_options(arguments => { "filter-name:s" => { name => 'filter_name' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - }); - - 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(output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{admstatus} eq "enable" and %{opstatus} !~ /associated|downloading/' }, + }); return $self; } @@ -133,86 +141,31 @@ sub new { sub check_options { my ($self, %options) = @_; $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } - $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) = ('ap', $1, $2); - 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(); - } - $overload_th->{$section} = [] if (!defined($overload_th->{$section})); - push @{$overload_th->{$section}}, {filter => $filter, status => $status}; - } + + $instance_mode = $self; + $self->change_macros(); } -sub run { +sub skip_global { my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - my $multiple = 1; - if (scalar(keys %{$self->{ap_selected}}) <= 1) { - $multiple = 0; - } + scalar(keys %{$self->{ap}}) > 1 ? return(0) : return(1); +} + +sub prefix_ap_output { + my ($self, %options) = @_; - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All AP status are ok'); - } + return "AP '" . $options{instance_value}->{display} . "' "; +} + +sub change_macros { + my ($self, %options) = @_; - foreach my $id ($self->{snmp}->oid_lex_sort(keys %{$self->{ap_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->{ap_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(extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "AP '" . $self->{ap_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 => "AP '" . $self->{ap_selected}->{$id}->{display} . "' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "AP '" . $self->{ap_selected}->{$id}->{display} . "' $long_msg"); + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; } } - - $self->{output}->display(); - $self->{output}->exit(); } my %map_admin_status = ( @@ -233,14 +186,14 @@ my $mapping2 = { my $mapping3 = { bsnAPAdminStatus => { oid => '.1.3.6.1.4.1.14179.2.2.1.1.37', map => \%map_admin_status }, }; - my $oid_agentInventoryMachineModel = '.1.3.6.1.4.1.14179.1.1.1.3'; sub manage_selection { my ($self, %options) = @_; - $self->{ap_selected} = {}; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ { oid => $oid_agentInventoryMachineModel }, + $self->{ap} = {}; + $self->{global} = { total => 0, associated => 0, disassociating => 0, downloading => 0 }; + $self->{results} = $options{snmp}->get_multiple_table(oids => [ { oid => $oid_agentInventoryMachineModel }, { oid => $mapping->{bsnAPName}->{oid} }, { oid => $mapping2->{bsnAPOperationStatus}->{oid} }, { oid => $mapping3->{bsnAPAdminStatus}->{oid} }, @@ -250,20 +203,23 @@ sub manage_selection { foreach my $oid (keys %{$self->{results}->{ $mapping->{bsnAPName}->{oid} }}) { $oid =~ /^$mapping->{bsnAPName}->{oid}\.(.*)$/; my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{ $mapping->{bsnAPName}->{oid} }, instance => $instance); - my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{ $mapping2->{bsnAPOperationStatus}->{oid} }, instance => $instance); - my $result3 = $self->{snmp}->map_instance(mapping => $mapping3, results => $self->{results}->{ $mapping3->{bsnAPAdminStatus}->{oid} }, instance => $instance); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{ $mapping->{bsnAPName}->{oid} }, instance => $instance); + my $result2 = $options{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{ $mapping2->{bsnAPOperationStatus}->{oid} }, instance => $instance); + my $result3 = $options{snmp}->map_instance(mapping => $mapping3, results => $self->{results}->{ $mapping3->{bsnAPAdminStatus}->{oid} }, instance => $instance); if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $result->{bsnAPName} !~ /$self->{option_results}->{filter_name}/) { $self->{output}->output_add(long_msg => "Skipping '" . $result->{bsnAPName} . "': no matching filter.", debug => 1); next; } - $self->{ap_selected}->{$instance} = { display => $result->{bsnAPName}, - opstatus => $result2->{bsnAPOperationStatus}, admstatus => $result3->{bsnAPAdminStatus}}; + $self->{global}->{total}++; + $self->{global}->{$result2->{bsnAPOperationStatus}}++; + + $self->{ap}->{$instance} = { display => $result->{bsnAPName}, + opstatus => $result2->{bsnAPOperationStatus}, admstatus => $result3->{bsnAPAdminStatus}}; } - if (scalar(keys %{$self->{ap_selected}}) <= 0) { + if (scalar(keys %{$self->{ap}}) <= 0) { $self->{output}->output_add(severity => 'OK', short_msg => 'No AP associated (can be: slave wireless controller or your filter)'); } @@ -279,15 +235,34 @@ Check AP status. =over 8 +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^total-disassociating|total-associated$' + =item B<--filter-name> Filter AP name (can be a regexp). -=item B<--threshold-overload> +=item B<--warning-status> -Set to overload default ap threshold values (syntax: status,regexp) -It used before default thresholds (order stays). -Example: --threshold-overload='CRITICAL,^(?!(associated)$)' +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 "enable" and %{opstatus} !~ /associated|downloading/'). +Can used special variables like: %{admstatus}, %{opstatus}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total', 'total-associated', 'total-disassociating'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total', 'total-associated', 'total-disassociating'. =back diff --git a/centreon/common/airespace/snmp/mode/apusers.pm b/centreon/common/airespace/snmp/mode/apusers.pm index 63834926b..cc11527a1 100644 --- a/centreon/common/airespace/snmp/mode/apusers.pm +++ b/centreon/common/airespace/snmp/mode/apusers.pm @@ -20,105 +20,129 @@ package centreon::common::airespace::snmp::mode::apusers; -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_total' => { set => { - key_values => [ { name => 'total' } ], - output_template => 'Total Users : %s', - perfdatas => [ - { label => 'total', value => 'total_absolute', template => '%s', - unit => 'users', min => 0 }, - ], - } - }, - '001_total-idle' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ { name => 'total_idle' } ], - output_template => 'Total Idle Users : %s', - perfdatas => [ - { label => 'total_idle', value => 'total_idle_absolute', template => '%s', - unit => 'users', min => 0 }, - ], - } - }, - '002_total-aaapending' => { set => { - key_values => [ { name => 'total_aaapending' } ], - output_template => 'Total AaaPending Users : %s', - perfdatas => [ - { label => 'total_aaapending', value => 'total_aaapending_absolute', template => '%s', - unit => 'users', min => 0 }, - ], - } - }, - '003_total-authenticated' => { set => { - key_values => [ { name => 'total_authenticated' } ], - output_template => 'Total Authenticated Users : %s', - perfdatas => [ - { label => 'total_authenticated', value => 'total_authenticated_absolute', template => '%s', - unit => 'users', min => 0 }, - ], - } - }, - '004_total-associated' => { set => { - key_values => [ { name => 'total_associated' } ], - output_template => 'Total Associated Users : %s', - perfdatas => [ - { label => 'total_associated', value => 'total_associated_absolute', template => '%s', - unit => 'users', min => 0 }, - ], - } - }, - '005_total-powersave' => { set => { - key_values => [ { name => 'total_powersave' } ], - output_template => 'Total Powersave Users : %s', - perfdatas => [ - { label => 'total_powersave', value => 'total_powersave_absolute', template => '%s', - unit => 'users', min => 0 }, - ], - } - }, - '006_total-disassociated' => { set => { - key_values => [ { name => 'total_disassociated' } ], - output_template => 'Total Disassociated Users : %s', - perfdatas => [ - { label => 'total_disassociated', value => 'total_disassociated_absolute', template => '%s', - unit => 'users', min => 0 }, - ], - } - }, - '007_total-tobedeleted' => { set => { - key_values => [ { name => 'total_tobedeleted' } ], - output_template => 'Total ToBeDeleted Users : %s', - perfdatas => [ - { label => 'total_tobedeleted', value => 'total_tobedeleted_absolute', template => '%s', - unit => 'users', min => 0 }, - ], - } - }, - '008_total-probing' => { set => { - key_values => [ { name => 'total_probing' } ], - output_template => 'Total Probing Users : %s', - perfdatas => [ - { label => 'total_probing', value => 'total_probing_absolute', template => '%s', - unit => 'users', min => 0 }, - ], - } - }, - '009_total-blacklisted' => { set => { - key_values => [ { name => 'total_blacklisted' } ], - output_template => 'Total Blacklisted Users : %s', - perfdatas => [ - { label => 'total_blacklisted', value => 'total_blacklisted_absolute', template => '%s', - unit => 'users', min => 0 }, - ], - } - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { 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 => { + key_values => [ { name => 'total' } ], + output_template => 'Total Users : %s', + perfdatas => [ + { label => 'total', value => 'total_absolute', template => '%s', + unit => 'users', min => 0 }, + ], + } + }, + { label => 'total-idle', set => { + key_values => [ { name => 'total_idle' } ], + output_template => 'Total Idle Users : %s', + perfdatas => [ + { label => 'total_idle', value => 'total_idle_absolute', template => '%s', + unit => 'users', min => 0 }, + ], + } + }, + { label => 'total-aaapending', set => { + key_values => [ { name => 'total_aaapending' } ], + output_template => 'Total AaaPending Users : %s', + perfdatas => [ + { label => 'total_aaapending', value => 'total_aaapending_absolute', template => '%s', + unit => 'users', min => 0 }, + ], + } + }, + { label => 'total-authenticated', set => { + key_values => [ { name => 'total_authenticated' } ], + output_template => 'Total Authenticated Users : %s', + perfdatas => [ + { label => 'total_authenticated', value => 'total_authenticated_absolute', template => '%s', + unit => 'users', min => 0 }, + ], + } + }, + { label => 'total-associated', set => { + key_values => [ { name => 'total_aaapending' } ], + output_template => 'Total AaaPending Users : %s', + perfdatas => [ + { label => 'total_aaapending', value => 'total_aaapending_absolute', template => '%s', + unit => 'users', min => 0 }, + ], + } + }, + { label => 'total-powersave', set => { + key_values => [ { name => 'total_powersave' } ], + output_template => 'Total Powersave Users : %s', + perfdatas => [ + { label => 'total_powersave', value => 'total_powersave_absolute', template => '%s', + unit => 'users', min => 0 }, + ], + } + }, + { label => 'total-disassociated', set => { + key_values => [ { name => 'total_disassociated' } ], + output_template => 'Total Disassociated Users : %s', + perfdatas => [ + { label => 'total_disassociated', value => 'total_disassociated_absolute', template => '%s', + unit => 'users', min => 0 }, + ], + } + }, + { label => 'total-tobedeleted', set => { + key_values => [ { name => 'total_tobedeleted' } ], + output_template => 'Total ToBeDeleted Users : %s', + perfdatas => [ + { label => 'total_tobedeleted', value => 'total_tobedeleted_absolute', template => '%s', + unit => 'users', min => 0 }, + ], + } + }, + { label => 'total-probing', set => { + key_values => [ { name => 'total_probing' } ], + output_template => 'Total Probing Users : %s', + perfdatas => [ + { label => 'total_probing', value => 'total_probing_absolute', template => '%s', + unit => 'users', min => 0 }, + ], + } + }, + { label => 'total-blacklisted', set => { + key_values => [ { name => 'total_blacklisted' } ], + output_template => 'Total Blacklisted Users : %s', + perfdatas => [ + { label => 'total_blacklisted', value => 'total_blacklisted_absolute', template => '%s', + unit => 'users', min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{ssid} = [ + { label => 'ssid', set => { + key_values => [ { name => 'total' }, { name => 'display' } ], + output_template => 'users : %s', + perfdatas => [ + { label => 'ssid', value => 'total_absolute', template => '%s', + unit => 'users', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_ssid_output { + my ($self, %options) = @_; + + return "SSID '" . $options{instance_value}->{display} . "' "; +} sub new { my ($class, %options) = @_; @@ -130,79 +154,10 @@ sub new { { "filter-ssid:s" => { name => 'filter_ssid' }, }); - - 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}}); - } 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) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - 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 = ', '; - } - - $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->{output}->display(); - $self->{output}->exit(); -} - my %map_station_status = ( 0 => 'idle', 1 => 'aaapending', @@ -220,8 +175,12 @@ my $mapping = { my $mapping2 = { bsnMobileStationSsid => { oid => '.1.3.6.1.4.1.14179.2.1.4.1.7' }, }; +my $mapping3 = { + bsnDot11EssNumberOfMobileStations => { oid => '.1.3.6.1.4.1.14179.2.1.1.1.38' }, +}; my $oid_agentInventoryMachineModel = '.1.3.6.1.4.1.14179.1.1.1.3'; +my $oid_bsnDot11EssSsid = '.1.3.6.1.4.1.14179.2.1.1.1.2'; sub manage_selection { my ($self, %options) = @_; @@ -229,25 +188,44 @@ sub manage_selection { $self->{global} = { total => 0, total_idle => 0, total_aaapending => 0, total_authenticated => 0, total_associated => 0, total_powersave => 0, total_disassociated => 0, total_tobedeleted => 0, total_probing => 0, total_blacklisted => 0}; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ { oid => $oid_agentInventoryMachineModel }, + $self->{results} = $options{snmp}->get_multiple_table(oids => [ { oid => $oid_agentInventoryMachineModel }, { oid => $mapping->{bsnMobileStationStatus}->{oid} }, { oid => $mapping2->{bsnMobileStationSsid}->{oid} }, + { oid => $oid_bsnDot11EssSsid }, + { oid => $mapping3->{bsnDot11EssNumberOfMobileStations}->{oid} }, ], nothing_quit => 1); $self->{output}->output_add(long_msg => "Model: " . $self->{results}->{$oid_agentInventoryMachineModel}->{$oid_agentInventoryMachineModel . '.0'}); foreach my $oid (keys %{$self->{results}->{ $mapping->{bsnMobileStationStatus}->{oid} }}) { $oid =~ /^$mapping->{bsnMobileStationStatus}->{oid}\.(.*)$/; my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{ $mapping->{bsnMobileStationStatus}->{oid} }, instance => $instance); - my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{ $mapping2->{bsnMobileStationSsid}->{oid} }, instance => $instance); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{ $mapping->{bsnMobileStationStatus}->{oid} }, instance => $instance); + my $result2 = $options{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{ $mapping2->{bsnMobileStationSsid}->{oid} }, instance => $instance); if (defined($self->{option_results}->{filter_ssid}) && $self->{option_results}->{filter_ssid} ne '' && $result2->{bsnMobileStationSsid} !~ /$self->{option_results}->{filter_ssid}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $result2->{bsnMobileStationSsid} . "': no matching filter."); + $self->{output}->output_add(long_msg => "Skipping '" . $result2->{bsnMobileStationSsid} . "': no matching filter.", debug => 1); next; } $self->{global}->{total}++; $self->{global}->{'total_' . $result->{bsnMobileStationStatus}}++; } + + # check by ssid + $self->{ssid} = {}; + foreach my $oid (keys %{$self->{results}->{ $oid_bsnDot11EssSsid }}) { + $oid =~ /^$oid_bsnDot11EssSsid\.(.*)$/; + my $instance = $1; + my $ssid_name = $self->{results}->{ $oid_bsnDot11EssSsid }->{$oid}; + my $result = $options{snmp}->map_instance(mapping => $mapping3, results => $self->{results}->{ $mapping3->{bsnDot11EssNumberOfMobileStations}->{oid} }, instance => $instance); + if (defined($self->{option_results}->{filter_ssid}) && $self->{option_results}->{filter_ssid} ne '' && + $ssid_name !~ /$self->{option_results}->{filter_ssid}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $ssid_name . "': no matching filter.", debug => 1); + next; + } + + $self->{ssid}->{$ssid_name} = { display => $ssid_name, total => 0 } if (!defined($self->{ssid}->{$ssid_name})); + $self->{ssid}->{$ssid_name}->{total} += $result->{bsnDot11EssNumberOfMobileStations}; + } } 1; @@ -260,19 +238,24 @@ Check total users connected and status on AP. =over 8 +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^total|total-idle$' + =item B<--warning-*> Threshold warning. Can be: 'total', 'total-idle', 'total-aaapending', 'total-authenticated', 'total-associated', 'total-powersave', 'total-disassociated', 'total-tobedeleted', -'total-probing', 'total-blacklisted'. +'total-probing', 'total-blacklisted', 'ssid'. =item B<--critical-*> Threshold critical. Can be: 'total', 'total-idle', 'total-aaapending', 'total-authenticated', 'total-associated', 'total-powersave', 'total-disassociated', 'total-tobedeleted', -'total-probing', 'total-blacklisted'. +'total-probing', 'total-blacklisted', 'ssid'. =item B<--filter-ssid> diff --git a/centreon/common/airespace/snmp/mode/components/psu.pm b/centreon/common/airespace/snmp/mode/components/psu.pm index 156eef1c8..2700763f0 100644 --- a/centreon/common/airespace/snmp/mode/components/psu.pm +++ b/centreon/common/airespace/snmp/mode/components/psu.pm @@ -32,9 +32,9 @@ my %map_psu_status = ( my $oid_agentSwitchInfoGroup = '.1.3.6.1.4.1.14179.1.1.3'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_agentSwitchInfoGroup }; + push @{$self->{request}}, { oid => $oid_agentSwitchInfoGroup }; } sub check { @@ -42,14 +42,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking power supplies"); $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'psu')); + return if ($self->check_filter(section => 'psu')); foreach my $instances ([1, 3], [2, 5]) { next if (!defined($self->{results}->{$oid_agentSwitchInfoGroup}->{ $oid_agentSwitchInfoGroup . '.' . $$instances[1] . '.0' })); my $present = $self->{results}->{$oid_agentSwitchInfoGroup}->{ $oid_agentSwitchInfoGroup . '.' . ($$instances[1] - 1) . '.0' }; my $operational = $map_psu_status{ $self->{results}->{$oid_agentSwitchInfoGroup}->{ $oid_agentSwitchInfoGroup . '.' . $$instances[1] . '.0' } }; - next if ($self->check_exclude(section => 'psu', instance => $$instances[0])); + next if ($self->check_filter(section => 'psu', instance => $$instances[0])); next if ($present =~ /0/i && $self->absent_problem(section => 'psu', instance => $$instances[0])); $self->{components}->{psu}->{total}++; diff --git a/centreon/common/airespace/snmp/mode/hardware.pm b/centreon/common/airespace/snmp/mode/hardware.pm index c083363a7..a9818172b 100644 --- a/centreon/common/airespace/snmp/mode/hardware.pm +++ b/centreon/common/airespace/snmp/mode/hardware.pm @@ -20,154 +20,49 @@ package centreon::common::airespace::snmp::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -my $thresholds = { - psu => [ - ['not operational', 'CRITICAL'], - ['operational', 'OK'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(psu)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + psu => [ + ['not operational', 'CRITICAL'], + ['operational', 'OK'], + ], + }; + + $self->{components_path} = 'centreon::common::airespace::snmp::mode::components'; + $self->{components_module} = ['psu']; +} + +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); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_performance => 1); bless $self, $class; $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "exclude:s" => { name => 'exclude' }, - "absent-problem:s" => { name => 'absent' }, - "component:s" => { name => 'component', default => '.*' }, - "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}->{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) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('psu'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "centreon::common::airespace::snmp::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "centreon::common::airespace::snmp::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $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; -} - -sub absent_problem { - my ($self, %options) = @_; - - if (defined($self->{option_results}->{absent}) && - $self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - } - - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); - $self->{components}->{$options{section}}->{skip}++; - return 1; -} - -sub get_severity { - my ($self, %options) = @_; - my $status = 'UNKNOWN'; # default - - foreach (@{$thresholds->{$options{section}}}) { - if ($options{value} =~ /$$_[0]/i) { - $status = $$_[1]; - return $status; - } - } - - return $status; -} - 1; __END__ @@ -183,21 +78,27 @@ Check Hardware (Power Supplies). Which component to check (Default: '.*'). Can be: 'psu'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=psu) -Can also exclude specific instance: --exclude=psu#1# +Exclude some parts (comma seperated list) (Example: --filter=psu) +Can also exclude specific instance: --filter=psu,1 =item B<--absent-problem> Return an error if an entity is not 'present' (default is skipping) (comma seperated list) -Can be specific or global: --absent-problem=psu#1# +Can be specific or global: --absent-problem=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='psu,WARNING,not operational' + =back =cut \ No newline at end of file diff --git a/centreon/common/aruba/snmp/mode/apusers.pm b/centreon/common/aruba/snmp/mode/apusers.pm index 1e5933fb4..d3ad95c87 100644 --- a/centreon/common/aruba/snmp/mode/apusers.pm +++ b/centreon/common/aruba/snmp/mode/apusers.pm @@ -401,15 +401,17 @@ sub manage_selection { my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_wlsxUserEntry}, instance => $instance); my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{nUserApBSSID}->{oid}}, instance => $instance); + # security + next if (!defined($result2->{nUserApBSSID})); my $bssid = join('.', unpack('C*', $result2->{nUserApBSSID})); next if (defined($self->{option_results}->{filter_ip_address}) && $self->{option_results}->{filter_ip_address} ne '' && $map_ap{$bssid}->{ip} !~ /$self->{option_results}->{filter_ip_address}/); next if (defined($self->{option_results}->{filter_ip_address}) && $self->{option_results}->{filter_ip_address} ne '' && $map_ap{$bssid}->{essid} !~ /$self->{option_results}->{filter_essid}/); - + $self->{ap_selected}->{$bssid} = { users => 0, bssid => $bssid } if (!defined($self->{ap_selected}->{$bssid})); $self->{ap_selected}->{$bssid}->{users}++; - + $self->{essid_selected}->{$map_ap{$bssid}->{essid}} = { users => 0, essid => $map_ap{$bssid}->{essid} } if (!defined($self->{essid_selected}->{$map_ap{$bssid}->{essid}})); $self->{essid_selected}->{$map_ap{$bssid}->{essid}}->{users}++; diff --git a/centreon/common/aruba/snmp/mode/components/fan.pm b/centreon/common/aruba/snmp/mode/components/fan.pm index 14942b192..8a573f3f6 100644 --- a/centreon/common/aruba/snmp/mode/components/fan.pm +++ b/centreon/common/aruba/snmp/mode/components/fan.pm @@ -35,9 +35,9 @@ my $mapping = { my $oid_wlsxSysExtFanEntry = '.1.3.6.1.4.1.14823.2.2.1.2.1.17.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_wlsxSysExtFanEntry }; + push @{$self->{request}}, { oid => $oid_wlsxSysExtFanEntry }; } sub check { @@ -45,14 +45,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking fans"); $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fan')); + return if ($self->check_filter(section => 'fan')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_wlsxSysExtFanEntry}})) { next if ($oid !~ /^$mapping->{sysExtFanStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_wlsxSysExtFanEntry}, instance => $instance); - next if ($self->check_exclude(section => 'fan', instance => $instance)); + 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].", diff --git a/centreon/common/aruba/snmp/mode/components/module.pm b/centreon/common/aruba/snmp/mode/components/module.pm index eebf2fd5d..8f3174630 100644 --- a/centreon/common/aruba/snmp/mode/components/module.pm +++ b/centreon/common/aruba/snmp/mode/components/module.pm @@ -55,9 +55,9 @@ my $mapping = { my $oid_wlsxSysExtCardEntry = '.1.3.6.1.4.1.14823.2.2.1.2.1.16.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_wlsxSysExtCardEntry }; + push @{$self->{request}}, { oid => $oid_wlsxSysExtCardEntry }; } sub check { @@ -65,14 +65,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking modules"); $self->{components}->{module} = {name => 'modules', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'module')); + return if ($self->check_filter(section => 'module')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_wlsxSysExtCardEntry}})) { next if ($oid !~ /^$mapping->{sysExtCardStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_wlsxSysExtCardEntry}, instance => $instance); - next if ($self->check_exclude(section => 'module', instance => $instance)); + next if ($self->check_filter(section => 'module', instance => $instance)); $self->{components}->{module}->{total}++; $self->{output}->output_add(long_msg => sprintf("Module '%s/%s' status is %s [instance: %s].", diff --git a/centreon/common/aruba/snmp/mode/components/psu.pm b/centreon/common/aruba/snmp/mode/components/psu.pm index 754df13ed..bd031a919 100644 --- a/centreon/common/aruba/snmp/mode/components/psu.pm +++ b/centreon/common/aruba/snmp/mode/components/psu.pm @@ -35,9 +35,9 @@ my $mapping = { my $oid_wlsxSysExtPowerSupplyEntry = '.1.3.6.1.4.1.14823.2.2.1.2.1.18.1.2'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_wlsxSysExtPowerSupplyEntry }; + push @{$self->{request}}, { oid => $oid_wlsxSysExtPowerSupplyEntry }; } sub check { @@ -45,14 +45,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking power supplies"); $self->{components}->{psu} = {name => 'power supplies', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'psu')); + return if ($self->check_filter(section => 'psu')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_wlsxSysExtPowerSupplyEntry}})) { next if ($oid !~ /^$mapping->{sysExtPowerSupplyStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_wlsxSysExtPowerSupplyEntry}, instance => $instance); - next if ($self->check_exclude(section => 'psu', instance => $instance)); + 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 [instance: %s].", diff --git a/centreon/common/aruba/snmp/mode/hardware.pm b/centreon/common/aruba/snmp/mode/hardware.pm index 3dfc4cb48..2bfeff3d3 100644 --- a/centreon/common/aruba/snmp/mode/hardware.pm +++ b/centreon/common/aruba/snmp/mode/hardware.pm @@ -20,168 +20,57 @@ package centreon::common::aruba::snmp::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -my $thresholds = { - fan => [ - ['active', 'OK'], - ['inactive', 'CRITICAL'], - ], - psu => [ - ['active', 'OK'], - ['inactive', 'CRITICAL'], - ], - module => [ - ['active', 'OK'], - ['inactive', 'CRITICAL'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(fan|psu|module)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + fan => [ + ['active', 'OK'], + ['inactive', 'CRITICAL'], + ], + psu => [ + ['active', 'OK'], + ['inactive', 'CRITICAL'], + ], + module => [ + ['active', 'OK'], + ['inactive', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'centreon::common::aruba::snmp::mode::components'; + $self->{components_module} = ['fan', 'psu', 'module']; +} + +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); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_performance => 1, no_absent => 1); bless $self, $class; $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "exclude:s" => { name => 'exclude' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, + { }); - $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'; - } - } - - $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}; - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('fan', 'psu', 'module'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "centreon::common::aruba::snmp::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "centreon::common::aruba::snmp::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $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; -} - -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; -} - 1; __END__ @@ -197,10 +86,10 @@ Check hardware (modules, fans, power supplies). Which component to check (Default: '.*'). Can be: 'fan', 'psu', 'module'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=fan,module) -Can also exclude specific instance: --exclude=fan#1#2#,module#1#,psu +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=psu) +Can also exclude specific instance: --filter=fan,1 =item B<--no-component> @@ -209,7 +98,7 @@ If total (with skipped) is 0. (Default: 'critical' returns). =item B<--threshold-overload> -Set to overload default threshold values (syntax: section,status,regexp) +Set to overload default threshold values (syntax: section,[instance,]status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='fan,OK,inactive' diff --git a/centreon/common/cisco/smallbusiness/snmp/mode/components/fan.pm b/centreon/common/cisco/smallbusiness/snmp/mode/components/fan.pm index 97ab832e8..5d2166c4e 100644 --- a/centreon/common/cisco/smallbusiness/snmp/mode/components/fan.pm +++ b/centreon/common/cisco/smallbusiness/snmp/mode/components/fan.pm @@ -39,9 +39,9 @@ my $mapping = { my $oid_rlEnvMonFanStatusEntry = '.1.3.6.1.4.1.9.6.1.101.83.1.1.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_rlEnvMonFanStatusEntry }; + push @{$self->{request}}, { oid => $oid_rlEnvMonFanStatusEntry }; } sub check { @@ -49,14 +49,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking fans"); $self->{components}->{fan} = {name => 'fan', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fan')); + return if ($self->check_filter(section => 'fan')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_rlEnvMonFanStatusEntry}})) { next if ($oid !~ /^$mapping->{rlEnvMonFanState}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_rlEnvMonFanStatusEntry}, instance => $instance); - next if ($self->check_exclude(section => 'fan', instance => $instance)); + next if ($self->check_filter(section => 'fan', instance => $instance)); if ($result->{rlEnvMonFanState} =~ /notPresent/i) { $self->absent_problem(section => 'fan', instance => $instance); next; diff --git a/centreon/common/cisco/smallbusiness/snmp/mode/components/psu.pm b/centreon/common/cisco/smallbusiness/snmp/mode/components/psu.pm index 0e8a59860..e24a05483 100644 --- a/centreon/common/cisco/smallbusiness/snmp/mode/components/psu.pm +++ b/centreon/common/cisco/smallbusiness/snmp/mode/components/psu.pm @@ -39,9 +39,9 @@ my $mapping = { my $oid_rlEnvMonSupplyStatusEntry = '.1.3.6.1.4.1.9.6.1.101.83.1.2.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_rlEnvMonSupplyStatusEntry }; + push @{$self->{request}}, { oid => $oid_rlEnvMonSupplyStatusEntry }; } sub check { @@ -49,14 +49,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking power supplies"); $self->{components}->{psu} = {name => 'psu', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'psu')); + return if ($self->check_filter(section => 'psu')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_rlEnvMonSupplyStatusEntry}})) { next if ($oid !~ /^$mapping->{rlEnvMonSupplyState}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_rlEnvMonSupplyStatusEntry}, instance => $instance); - next if ($self->check_exclude(section => 'psu', instance => $instance)); + next if ($self->check_filter(section => 'psu', instance => $instance)); if ($result->{rlEnvMonSupplyState} =~ /notPresent/i) { $self->absent_problem(section => 'psu', instance => $instance); next; diff --git a/centreon/common/cisco/smallbusiness/snmp/mode/environment.pm b/centreon/common/cisco/smallbusiness/snmp/mode/environment.pm index b42b27843..e53c92eb7 100644 --- a/centreon/common/cisco/smallbusiness/snmp/mode/environment.pm +++ b/centreon/common/cisco/smallbusiness/snmp/mode/environment.pm @@ -20,189 +20,61 @@ package centreon::common::cisco::smallbusiness::snmp::mode::environment; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -my $thresholds = { - fan => [ - ['normal', 'OK'], - ['notPresent', 'OK'], - ['warning', 'WARNING'], - ['critical', 'CRITICAL'], - ['shutdown', 'CRITICAL'], - ['notFunctioning', 'CRITICAL'], - ], - psu => [ - ['normal', 'OK'], - ['notPresent', 'OK'], - ['warning', 'WARNING'], - ['critical', 'CRITICAL'], - ['shutdown', 'CRITICAL'], - ['notFunctioning', 'CRITICAL'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(fan|psu)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + fan => [ + ['normal', 'OK'], + ['notPresent', 'OK'], + ['warning', 'WARNING'], + ['critical', 'CRITICAL'], + ['shutdown', 'CRITICAL'], + ['notFunctioning', 'CRITICAL'], + ], + psu => [ + ['normal', 'OK'], + ['notPresent', 'OK'], + ['warning', 'WARNING'], + ['critical', 'CRITICAL'], + ['shutdown', 'CRITICAL'], + ['notFunctioning', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'centreon::common::cisco::smallbusiness::snmp::mode::components'; + $self->{components_module} = ['psu', 'fan']; +} + +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); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_performance => 1); bless $self, $class; $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "exclude:s" => { name => 'exclude' }, - "component:s" => { name => 'component', default => '.*' }, - "absent-problem:s" => { name => 'absent' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, + { }); - $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'; - } - } - - $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}; - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('psu', 'fan'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "centreon::common::cisco::smallbusiness::snmp::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "centreon::common::cisco::smallbusiness::snmp::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s]", - $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'); - } - - $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; -} - -sub absent_problem { - my ($self, %options) = @_; - - if (defined($self->{option_results}->{absent}) && - $self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - } - - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); - $self->{components}->{$options{section}}->{skip}++; - return 1; -} - -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; -} - 1; __END__ @@ -218,10 +90,10 @@ Check environment (Fans, Power supplies). Which component to check (Default: '.*'). Can be: 'fan', 'psu'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=psu) -Can also exclude specific instance: --exclude='psu#0#' +Exclude some parts (comma seperated list) (Example: --filter=psu) +Can also exclude specific instance: --filter=psu,0 =item B<--absent-problem> @@ -235,7 +107,7 @@ If total (with skipped) is 0. (Default: 'critical' returns). =item B<--threshold-overload> -Set to overload default threshold values (syntax: section,status,regexp) +Set to overload default threshold values (syntax: section,[instance,]status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='fan,CRITICAL,^(?!(normal)$)' diff --git a/centreon/common/cisco/standard/snmp/mode/components/module.pm b/centreon/common/cisco/standard/snmp/mode/components/module.pm index 65ab648a8..51bf40fec 100644 --- a/centreon/common/cisco/standard/snmp/mode/components/module.pm +++ b/centreon/common/cisco/standard/snmp/mode/components/module.pm @@ -53,7 +53,7 @@ my %map_module_state = ( 27 => 'fwDownloadFailure', ); -# In MIB 'CISCO-ENTITY-SENSOR-MIB' +# In MIB 'CISCO-ENTITY-FRU-CONTROL-MIB' my $mapping = { cefcModuleOperStatus => { oid => '.1.3.6.1.4.1.9.9.117.1.2.1.1.2', map => \%map_module_state }, }; diff --git a/centreon/common/cisco/standard/snmp/mode/components/sensor.pm b/centreon/common/cisco/standard/snmp/mode/components/sensor.pm new file mode 100644 index 000000000..3db0d6353 --- /dev/null +++ b/centreon/common/cisco/standard/snmp/mode/components/sensor.pm @@ -0,0 +1,234 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package centreon::common::cisco::standard::snmp::mode::components::sensor; + +use strict; +use warnings; + +my %map_sensor_status = ( + 1 => 'ok', + 2 => 'unavailable', + 3 => 'nonoperational', +); +my %map_sensor_type = ( + 1 => 'other', + 2 => 'unknown', + 3 => 'voltsAC', + 4 => 'voltsDC', + 5 => 'amperes', + 6 => 'watts', + 7 => 'hertz', + 8 => 'celsius', + 9 => 'percentRH', + 10 => 'rpm', + 11 => 'cmm', + 12 => 'truthvalue', + 13 => 'specialEnum', + 14 => 'dBm', +); +my %map_scale = ( + 1 => -24, # yocto, + 2 => -21, # zepto + 3 => -18, # atto + 4 => -15, # femto + 5 => -12, # pico + 6 => -9, # nano + 7 => -6, # micro + 8 => -3, # milli + 9 => 0, #units + 10 => 3, #kilo + 11 => 6, #mega + 12 => 9, #giga + 13 => 12, #tera + 14 => 18, #exa + 15 => 15, #peta + 16 => 21, #zetta + 17 => 24, #yotta +); +my %map_severity = ( + 1 => 'other', + 10 => 'minor', + 20 => 'major', + 30 => 'critical', +); +my %map_relation = ( + 1 => 'lessThan', + 2 => 'lessOrEqual', + 3 => 'greaterThan', + 4 => 'greaterOrEqual', + 5 => 'equalTo', + 6 => 'notEqualTo', +); +my %perfdata_unit = ( + 'other' => '', + 'unknown' => '', + 'voltsAC' => 'V', + 'voltsDC' => 'V', + 'amperes' => 'A', + 'watts' => 'W', + 'hertz' => 'Hz', + 'celsius' => 'C', + 'percentRH' => '%', + 'rpm' => 'rpm', + 'cmm' => '', + 'truthvalue' => '', + 'specialEnum' => '', + 'dBm' => 'dBm', +); + +# In MIB 'CISCO-ENTITY-SENSOR-MIB' +my $mapping = { + entSensorType => { oid => '.1.3.6.1.4.1.9.9.91.1.1.1.1.1', map => \%map_sensor_type }, + entSensorScale => { oid => '.1.3.6.1.4.1.9.9.91.1.1.1.1.2', map => \%map_scale }, + entSensorPrecision => { oid => '.1.3.6.1.4.1.9.9.91.1.1.1.1.3' }, + entSensorValue => { oid => '.1.3.6.1.4.1.9.9.91.1.1.1.1.4' }, + entSensorStatus => { oid => '.1.3.6.1.4.1.9.9.91.1.1.1.1.5', map => \%map_sensor_status }, +}; +my $mapping2 = { + entSensorThresholdSeverity => { oid => '.1.3.6.1.4.1.9.9.91.1.2.1.1.2', map => \%map_severity }, + entSensorThresholdRelation => { oid => '.1.3.6.1.4.1.9.9.91.1.2.1.1.3', map => \%map_relation }, + entSensorThresholdValue => { oid => '.1.3.6.1.4.1.9.9.91.1.2.1.1.4' }, +}; +my $oid_entSensorValueEntry = '.1.3.6.1.4.1.9.9.91.1.1.1.1'; +my $oid_entSensorThresholdEntry = '.1.3.6.1.4.1.9.9.91.1.2.1.1'; +my $oid_entPhysicalDescr = '.1.3.6.1.2.1.47.1.1.1.1.2'; + +sub load { + my (%options) = @_; + + push @{$options{request}}, { oid => $oid_entSensorValueEntry }, { oid => $oid_entSensorThresholdEntry }; +} + +sub get_default_warning_threshold { + my ($self, %options) = @_; + my ($high_th, $low_th); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_entSensorThresholdEntry}})) { + next if ($oid !~ /^$mapping2->{entSensorThresholdSeverity}->{oid}\.$options{instance}\.(.*)$/); + 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 - 0.01; + } elsif ($result->{entSensorThresholdRelation} eq 'greaterThan') { + $high_th = $value; + } elsif ($result->{entSensorThresholdRelation} eq 'lessOrEqual') { + $low_th = $value + 0.01; + } elsif ($result->{entSensorThresholdRelation} eq 'lessThan') { + $low_th = $value; + } + } + + my $th = ''; + $th = $low_th . ':' if (defined($low_th)); + $th .= $high_th if (defined($high_th)); + return $th; +} + +sub get_default_critical_threshold { + my ($self, %options) = @_; + my ($high_th, $low_th); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_entSensorThresholdEntry}})) { + next if ($oid !~ /^$mapping2->{entSensorThresholdSeverity}->{oid}\.$options{instance}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$oid_entSensorThresholdEntry}, instance => $options{instance} . '.' . $instance); + next if ($result->{entSensorThresholdSeverity} !~ /major|critical/); + + my $value = $result->{entSensorThresholdValue} * (10 ** ($options{result}->{entSensorScale}) * (10 ** -($options{result}->{entSensorPrecision}))); + if ($result->{entSensorThresholdRelation} eq 'greaterOrEqual') { + $high_th = $value - 0.01; + } elsif ($result->{entSensorThresholdRelation} eq 'greaterThan') { + $high_th = $value; + } elsif ($result->{entSensorThresholdRelation} eq 'lessOrEqual') { + $low_th = $value + 0.01; + } elsif ($result->{entSensorThresholdRelation} eq 'lessThan') { + $low_th = $value; + } + } + + my $th = ''; + $th = $low_th . ':' if (defined($low_th)); + $th .= $high_th if (defined($high_th)); + return $th; +} + +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')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_entSensorValueEntry}})) { + next if ($oid !~ /^$mapping->{entSensorStatus}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_entSensorValueEntry}, instance => $instance); + + next if (!defined($self->{results}->{$oid_entPhysicalDescr}->{$oid_entPhysicalDescr . '.' . $instance})); + my $sensor_descr = $self->{results}->{$oid_entPhysicalDescr}->{$oid_entPhysicalDescr . '.' . $instance}; + + next if ($self->check_exclude(section => 'sensor', instance => $instance)); + $self->{components}->{sensor}->{total}++; + + $result->{entSensorValue} = defined($result->{entSensorValue}) ? + $result->{entSensorValue} * (10 ** ($result->{entSensorScale}) * (10 ** -($result->{entSensorPrecision}))) : undef; + + $self->{output}->output_add(long_msg => sprintf("Sensor '%s' status is '%s' [instance: %s] [value: %s %s]", + $sensor_descr, $result->{entSensorStatus}, + $instance, + defined($result->{entSensorValue}) ? $result->{entSensorValue} : '-', + $result->{entSensorType})); + my $exit = $self->get_severity(section => $result->{entSensorType}, label => 'sensor', value => $result->{entSensorStatus}); + 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_descr, $result->{entSensorStatus})); + } + + next if (!defined($result->{entSensorValue}) || $result->{entSensorValue} !~ /[0-9]/); + + my $component = 'sensor.' . $result->{entSensorType}; + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => $component, instance => $instance, value => $result->{entSensorValue}); + if ($checked == 0) { + my $warn_th = get_default_warning_threshold($self, instance => $instance, result => $result); + my $crit_th = get_default_critical_threshold($self, instance => $instance, result => $result); + $self->{perfdata}->threshold_validate(label => 'warning-' . $component . '-instance-' . $instance, value => $warn_th); + $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' } ]); + } + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Sensor '%s' is %s %s", $sensor_descr, $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); + } +} + +1; \ No newline at end of file diff --git a/centreon/common/cisco/standard/snmp/mode/environment.pm b/centreon/common/cisco/standard/snmp/mode/environment.pm index a39f8bf3c..adb98425e 100644 --- a/centreon/common/cisco/standard/snmp/mode/environment.pm +++ b/centreon/common/cisco/standard/snmp/mode/environment.pm @@ -94,6 +94,11 @@ my $thresholds = { ['incompatible|unsupported', 'CRITICAL'], ['supported', 'OK'], ], + sensor => [ + ['ok', 'OK'], + ['unavailable', 'OK'], + ['nonoperational', 'CRITICAL'], + ], }; sub new { @@ -133,17 +138,29 @@ sub check_options { $self->{overload_th} = {}; foreach my $val (@{$self->{option_results}->{threshold_overload}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { + 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, $status, $filter) = ($1, $2, $3); + my ($section, $instance, $status, $filter); + if (scalar(@values) == 3) { + ($section, $status, $filter) = @values; + $instance = '.*'; + } else { + ($section, $instance, $status, $filter) = @values; + } + if ($section !~ /^(temperature|fan|psu)$/) { + $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}; + push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status, instance => $instance }; } $self->{numeric_threshold} = {}; @@ -154,8 +171,8 @@ sub check_options { $self->{output}->option_exit(); } my ($section, $regexp, $value) = ($1, $2, $3); - if ($section !~ /(temperature|voltage)/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "' (type must be: temperature or voltage)."); + if ($section !~ /(temperature|voltage|sensor)/i) { + $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "' (type must be: temperature, voltage or sensor)."); $self->{output}->option_exit(); } my $position = 0; @@ -181,7 +198,7 @@ sub run { my $oid_ciscoEnvMonPresent = ".1.3.6.1.4.1.9.9.13.1.1"; my $snmp_request = [ { oid => $oid_entPhysicalDescr }, { oid => $oid_ciscoEnvMonPresent } ]; - my @components = ('fan', 'psu', 'temperature', 'voltage', 'module', 'physical'); + my @components = ('fan', 'psu', 'temperature', 'voltage', 'module', 'physical', 'sensor'); foreach (@components) { if (/$self->{option_results}->{component}/) { my $mod_name = "centreon::common::cisco::standard::snmp::mode::components::$_"; @@ -278,7 +295,7 @@ sub get_severity_numeric { if (defined($self->{numeric_threshold}->{$options{section}})) { my $exits = []; foreach (@{$self->{numeric_threshold}->{$options{section}}}) { - if ($options{instance} =~ /$_->{regexp}/) { + if ($options{instance} =~ /$_->{regexp}/i) { 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; @@ -296,13 +313,15 @@ sub get_severity { if (defined($self->{overload_th}->{$options{section}})) { foreach (@{$self->{overload_th}->{$options{section}}}) { - if ($options{value} =~ /$_->{filter}/i) { + if ($options{value} =~ /$_->{filter}/i && + (!defined($options{instance}) || $options{instance} =~ /$_->{instance}/)) { $status = $_->{status}; return $status; } } } - foreach (@{$thresholds->{$options{section}}}) { + my $label = defined($options{label}) ? $options{label} : $options{section}; + foreach (@{$thresholds->{$label}}) { if ($options{value} =~ /$$_[0]/i) { $status = $$_[1]; return $status; @@ -325,7 +344,7 @@ Check environment (Power Supplies, Fans, Temperatures, Voltages, Modules, Physic =item B<--component> Which component to check (Default: '.*'). -Can be: 'fan', 'psu', 'temperature', 'voltage', 'module', 'physical'. +Can be: 'fan', 'psu', 'temperature', 'voltage', 'module', 'physical', 'sensor'. =item B<--exclude> @@ -350,12 +369,12 @@ Example: --threshold-overload='fan,CRITICAL,^(?!(up|normal)$)' =item B<--warning> -Set warning threshold for temperatures, voltages (syntax: type,regexp,treshold) +Set warning threshold for temperatures, voltages, sensors (syntax: type,regexp,treshold) Example: --warning='temperature,.*,30' =item B<--critical> -Set critical threshold for temperatures, voltages (syntax: type,regexp,treshold) +Set critical threshold for temperatures, voltages, sensors (syntax: type,regexp,treshold) Example: --critical='temperature,.*,40' =back diff --git a/centreon/common/cisco/standard/snmp/mode/ipsla.pm b/centreon/common/cisco/standard/snmp/mode/ipsla.pm index a3b98b84e..64dc72264 100644 --- a/centreon/common/cisco/standard/snmp/mode/ipsla.pm +++ b/centreon/common/cisco/standard/snmp/mode/ipsla.pm @@ -26,6 +26,7 @@ use strict; use warnings; use centreon::plugins::statefile; use centreon::plugins::values; +use Digest::MD5 qw(md5_hex); use Math::Complex; my $maps_counters = { @@ -319,7 +320,7 @@ sub get_my_delta { my $value; my ($old_time1, $old_time2) = split /_/, $options{old_datas}->{$self->{instance} . '_' . $options{name} . '_times'}; my ($new_time1, $new_time2) = split /_/, $options{new_datas}->{$self->{instance} . '_' . $options{name} . '_times'}; - if ($old_time1 == $new_time1) { + if (defined($old_time1) && defined($new_time1) && $old_time1 == $new_time1) { $value = $options{new_datas}->{$self->{instance} . '_' . $options{name} . '_1'} - $options{old_datas}->{$self->{instance} . '_' . $options{name} . '_1'} + $options{new_datas}->{$self->{instance} . '_' . $options{name} . '_2'} - $options{old_datas}->{$self->{instance} . '_' . $options{name} . '_2'}; } else { @@ -868,7 +869,8 @@ sub run { $self->manage_selection(); $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "cache_cisco_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode}); + $self->{statefile_value}->read(statefile => "cache_cisco_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_tag}) ? md5_hex($self->{option_results}->{filter_tag}) : md5_hex('all'))); $self->{new_datas}->{last_timestamp} = time(); my $multiple = 1; @@ -944,13 +946,17 @@ sub manage_selection { my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_rttMonCtrlAdminEntry}, instance => $instance); my $tag_name = $result->{rttMonCtrlAdminTag}; + if (!defined($tag_name) || $tag_name eq '') { + $self->{output}->output_add(long_msg => "skipping: please set a tag name"); + next; + } if (defined($self->{datas}->{$tag_name})) { - $self->{output}->output_add(long_msg => "Skipping '" . $tag_name . "': duplicate (please change the tag name)."); + $self->{output}->output_add(long_msg => "skipping '" . $tag_name . "': duplicate (please change the tag name)."); next; } if (defined($self->{option_results}->{filter_tag}) && $self->{option_results}->{filter_tag} ne '' && $tag_name !~ /$self->{option_results}->{filter_tag}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $tag_name . "': no matching filter."); + $self->{output}->output_add(long_msg => "skipping '" . $tag_name . "': no matching filter."); next; } $self->{datas}->{$tag_name} = { %{$result} }; @@ -966,7 +972,7 @@ sub manage_selection { my $i = 1; my $instances = []; foreach my $oid2 ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_rttMonJitterStatsEntry}})) { - next if ($oid2 !~ /^$oids_jitter_stats->{$key}\.\d+.(\d+)/); + next if ($oid2 !~ /^$oids_jitter_stats->{$key}\.$instance.(\d+)/); push @{$instances}, $1; $self->{datas}->{$tag_name}->{$key . '_' . $i} = $self->{results}->{$oid_rttMonJitterStatsEntry}->{$oid2}; $i++; diff --git a/centreon/common/force10/snmp/mode/components/fan.pm b/centreon/common/force10/snmp/mode/components/fan.pm index 0f0cc9c0f..f3717d8d1 100644 --- a/centreon/common/force10/snmp/mode/components/fan.pm +++ b/centreon/common/force10/snmp/mode/components/fan.pm @@ -42,9 +42,9 @@ my $mapping = { }; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $mapping->{sseries}->{OperStatus}->{oid} }, + push @{$self->{request}}, { oid => $mapping->{sseries}->{OperStatus}->{oid} }, { oid => $mapping->{mseries}->{OperStatus}->{oid} }, { oid => $mapping->{zseries}->{OperStatus}->{oid} }; } diff --git a/centreon/common/force10/snmp/mode/components/psu.pm b/centreon/common/force10/snmp/mode/components/psu.pm index 853f25d6f..4d754f55e 100644 --- a/centreon/common/force10/snmp/mode/components/psu.pm +++ b/centreon/common/force10/snmp/mode/components/psu.pm @@ -50,9 +50,9 @@ my $mapping = { }; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $mapping->{sseries}->{OperStatus}->{oid} }, + push @{$self->{request}}, { oid => $mapping->{sseries}->{OperStatus}->{oid} }, { oid => $mapping->{mseries}->{OperStatus}->{oid} }, { oid => $mapping->{zseries}->{OperStatus}->{oid} }; } diff --git a/centreon/common/force10/snmp/mode/components/temperature.pm b/centreon/common/force10/snmp/mode/components/temperature.pm index 7e38f45bd..9dfa727f6 100644 --- a/centreon/common/force10/snmp/mode/components/temperature.pm +++ b/centreon/common/force10/snmp/mode/components/temperature.pm @@ -34,9 +34,9 @@ my $mapping = { my $oid_deviceSensorValueEntry = '.1.3.6.1.4.1.3417.2.1.1.1.1.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $mapping->{sseries}->{Temp}->{oid} }, + push @{$self->{request}}, { oid => $mapping->{sseries}->{Temp}->{oid} }, { oid => $mapping->{mseries}->{Temp}->{oid} }; } diff --git a/centreon/common/force10/snmp/mode/hardware.pm b/centreon/common/force10/snmp/mode/hardware.pm index 65b78494c..3f93c85b0 100644 --- a/centreon/common/force10/snmp/mode/hardware.pm +++ b/centreon/common/force10/snmp/mode/hardware.pm @@ -20,31 +20,49 @@ package centreon::common::force10::snmp::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -use centreon::plugins::misc; -my $thresholds = { - fan => [ - ['up', 'OK'], - ['absent', 'OK'], - ['down', 'CRITICAL'], - ], - psu => [ - ['up', 'OK'], - ['absent', 'OK'], - ['down', 'CRITICAL'], - - ['normal', 'OK'], - ['warning', 'WARNING'], - ['critical', 'CRITICAL'], - ['shutdown', 'CRITICAL'], - ['notPresent', 'OK'], - ['notFunctioning', 'CRITICAL'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(psu|fan)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + fan => [ + ['up', 'OK'], + ['absent', 'OK'], + ['down', 'CRITICAL'], + ], + psu => [ + ['up', 'OK'], + ['absent', 'OK'], + ['down', 'CRITICAL'], + + ['normal', 'OK'], + ['warning', 'WARNING'], + ['critical', 'CRITICAL'], + ['shutdown', 'CRITICAL'], + ['notPresent', 'OK'], + ['notFunctioning', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'centreon::common::force10::snmp::mode::components'; + $self->{components_module} = ['fan', 'psu', 'temperature']; +} + +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) = @_; @@ -53,241 +71,12 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "filter:s@" => { name => 'filter' }, - "absent-problem:s@" => { name => 'absent_problem' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { }); - - $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'; - } - } - - $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->{absent_problem} = []; - foreach my $val (@{$self->{option_results}->{absent_problem}}) { - next if (!defined($val) || $val eq ''); - my @values = split (/,/, $val); - push @{$self->{absent_problem}}, { 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 !~ /^psu|fan$/) { - $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 !~ /^temperature$/) { - $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 }; - } - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('fan', 'psu', 'temperature'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "centreon::common::force10::snmp::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "centreon::common::force10::snmp::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub absent_problem { - my ($self, %options) = @_; - - foreach (@{$self->{absent_problem}}) { - if ($options{section} =~ /$_->{filter}/) { - if (!defined($_->{instance}) || $options{instance} =~ /$_->{instance}/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); - $self->{components}->{$options{section}}->{skip}++; - return 1; - } - } - } - - return 0; -} - -sub check_filter { - 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->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); - return 1; - } - } - } - - return 0; -} - -sub get_severity_numeric { - 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 - - 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; - } - } - - return $status; -} - 1; __END__ diff --git a/centreon/common/violin/snmp/mode/components/ca.pm b/centreon/common/violin/snmp/mode/components/ca.pm index 46d4533e9..cb91c747a 100644 --- a/centreon/common/violin/snmp/mode/components/ca.pm +++ b/centreon/common/violin/snmp/mode/components/ca.pm @@ -28,9 +28,9 @@ use warnings; my $oid_chassisSystemLedAlarm = '.1.3.6.1.4.1.35897.1.2.2.3.17.1.7'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_chassisSystemLedAlarm }; + push @{$self->{request}}, { oid => $oid_chassisSystemLedAlarm }; } sub check { @@ -38,7 +38,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking chassis alarm"); $self->{components}->{ca} = {name => 'chassis alarm', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'ca')); + return if ($self->check_filter(section => 'ca')); foreach my $oid (keys %{$self->{results}->{$oid_chassisSystemLedAlarm}}) { $oid =~ /^$oid_chassisSystemLedAlarm\.(.*)$/; @@ -46,7 +46,7 @@ sub check { my $instance = $array_name; my $ca_state = $self->{results}->{$oid_chassisSystemLedAlarm}->{$oid}; - next if ($self->check_exclude(section => 'ca', instance => $instance)); + next if ($self->check_filter(section => 'ca', instance => $instance)); $self->{components}->{ca}->{total}++; $self->{output}->output_add(long_msg => sprintf("Chassis alarm '%s' is %s.", diff --git a/centreon/common/violin/snmp/mode/components/fan.pm b/centreon/common/violin/snmp/mode/components/fan.pm index a6f5d40cf..e08d5c627 100644 --- a/centreon/common/violin/snmp/mode/components/fan.pm +++ b/centreon/common/violin/snmp/mode/components/fan.pm @@ -28,9 +28,9 @@ use warnings; my $oid_arrayFanEntry_speed = '.1.3.6.1.4.1.35897.1.2.2.3.18.1.3'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_arrayFanEntry_speed }; + push @{$self->{request}}, { oid => $oid_arrayFanEntry_speed }; } sub check { @@ -38,7 +38,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking fans"); $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fan')); + return if ($self->check_filter(section => 'fan')); foreach my $oid (keys %{$self->{results}->{$oid_arrayFanEntry_speed}}) { $oid =~ /^$oid_arrayFanEntry_speed\.(.*)$/; @@ -46,7 +46,7 @@ sub check { my $instance = $array_name . '-' . $fan_name; my $fan_state = $self->{results}->{$oid_arrayFanEntry_speed}->{$oid}; - next if ($self->check_exclude(section => 'fan', instance => $instance)); + next if ($self->check_filter(section => 'fan', instance => $instance)); next if ($fan_state =~ /Absent/i && $self->absent_problem(section => 'fan', instance => $instance)); diff --git a/centreon/common/violin/snmp/mode/components/gfc.pm b/centreon/common/violin/snmp/mode/components/gfc.pm index e1ee67a82..1293a7f56 100644 --- a/centreon/common/violin/snmp/mode/components/gfc.pm +++ b/centreon/common/violin/snmp/mode/components/gfc.pm @@ -31,9 +31,9 @@ my $oid_enable = '.1.3.6.1.4.1.35897.1.2.1.10.1.4'; my $oid_portState = '.1.3.6.1.4.1.35897.1.2.1.10.1.8'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_globalTargetFcEntry }; + push @{$self->{request}}, { oid => $oid_globalTargetFcEntry }; } sub check { @@ -41,7 +41,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking global fc"); $self->{components}->{gfc} = {name => 'global fc', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'gfc')); + return if ($self->check_filter(section => 'gfc')); foreach my $oid (keys %{$self->{results}->{$oid_globalTargetFcEntry}}) { next if ($oid !~ /^$oid_wwn\.(.*)$/); @@ -53,7 +53,7 @@ sub check { $self->{output}->output_add(long_msg => sprintf("Skipping instance '$wwn' (not enable)")); next; } - next if ($self->check_exclude(section => 'gfc', instance => $wwn)); + next if ($self->check_filter(section => 'gfc', instance => $wwn)); $self->{components}->{gfc}->{total}++; $self->{output}->output_add(long_msg => sprintf("Global FC '%s' is %s.", diff --git a/centreon/common/violin/snmp/mode/components/lfc.pm b/centreon/common/violin/snmp/mode/components/lfc.pm index d3c56bbb1..8bf9c5ec6 100644 --- a/centreon/common/violin/snmp/mode/components/lfc.pm +++ b/centreon/common/violin/snmp/mode/components/lfc.pm @@ -31,9 +31,9 @@ my $oid_enable = '.1.3.6.1.4.1.35897.1.2.1.6.1.3'; my $oid_portState = '.1.3.6.1.4.1.35897.1.2.1.6.1.7'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_localTargetFcEntry }; + push @{$self->{request}}, { oid => $oid_localTargetFcEntry }; } sub check { @@ -41,7 +41,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking local fc"); $self->{components}->{lfc} = {name => 'local fc', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'lfc')); + return if ($self->check_filter(section => 'lfc')); foreach my $oid (keys %{$self->{results}->{$oid_localTargetFcEntry}}) { next if ($oid !~ /^$oid_wwn\.(.*)$/); @@ -53,7 +53,7 @@ sub check { $self->{output}->output_add(long_msg => sprintf("Skipping instance '$wwn' (not enable)")); next; } - next if ($self->check_exclude(section => 'lfc', instance => $wwn)); + next if ($self->check_filter(section => 'lfc', instance => $wwn)); $self->{components}->{lfc}->{total}++; $self->{output}->output_add(long_msg => sprintf("Local FC '%s' is %s.", diff --git a/centreon/common/violin/snmp/mode/components/psu.pm b/centreon/common/violin/snmp/mode/components/psu.pm index 23dd5510e..082ad10f2 100644 --- a/centreon/common/violin/snmp/mode/components/psu.pm +++ b/centreon/common/violin/snmp/mode/components/psu.pm @@ -29,10 +29,9 @@ my $oid_chassisSystemPowerPSUA = '.1.3.6.1.4.1.35897.1.2.2.3.17.1.17'; my $oid_chassisSystemPowerPSUB = '.1.3.6.1.4.1.35897.1.2.2.3.17.1.18'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_chassisSystemPowerPSUA }; - push @{$options{request}}, { oid => $oid_chassisSystemPowerPSUB }; + push @{$self->{request}}, { oid => $oid_chassisSystemPowerPSUA }, { oid => $oid_chassisSystemPowerPSUB }; } sub psu { @@ -45,7 +44,7 @@ sub psu { my $psu_state = $options{value}; - return if ($self->check_exclude(section => 'psu', instance => $instance)); + return if ($self->check_filter(section => 'psu', instance => $instance)); return if ($psu_state =~ /Absent/i && $self->absent_problem(section => 'psu', instance => $instance)); @@ -64,7 +63,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking power supplies"); $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'psu')); + return if ($self->check_filter(section => 'psu')); foreach my $oid (keys %{$self->{results}->{$oid_chassisSystemPowerPSUA}}) { psu($self, oid => $oid, oid_short => $oid_chassisSystemPowerPSUA, value => $self->{results}->{$oid_chassisSystemPowerPSUA}->{$oid}, diff --git a/centreon/common/violin/snmp/mode/components/temperature.pm b/centreon/common/violin/snmp/mode/components/temperature.pm index c724a7251..daf330b81 100644 --- a/centreon/common/violin/snmp/mode/components/temperature.pm +++ b/centreon/common/violin/snmp/mode/components/temperature.pm @@ -30,11 +30,10 @@ my $oid_chassisSystemTempController = '.1.3.6.1.4.1.35897.1.2.2.3.17.1.21'; my $oid_arrayVimmEntry_temp = '.1.3.6.1.4.1.35897.1.2.2.3.16.1.12'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_arrayVimmEntry_temp }; - push @{$options{request}}, { oid => $oid_chassisSystemTempAmbient }; - push @{$options{request}}, { oid => $oid_chassisSystemTempController }; + push @{$self->{request}}, { oid => $oid_arrayVimmEntry_temp }, { oid => $oid_chassisSystemTempAmbient }, + { oid => $oid_chassisSystemTempController }; } sub temperature { @@ -47,7 +46,7 @@ sub temperature { my $temperature = $options{value}; - return if ($self->check_exclude(section => 'temperature', instance => $instance)); + return if ($self->check_filter(section => 'temperature', instance => $instance)); $self->{components}->{temperature}->{total}++; $self->{output}->output_add(long_msg => sprintf("Temperature '%s' is %s degree centigrade.", @@ -68,7 +67,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking temperatures"); $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'temperature')); + return if ($self->check_filter(section => 'temperature')); foreach my $oid (keys %{$self->{results}->{$oid_chassisSystemTempAmbient}}) { temperature($self, oid => $oid, oid_short => $oid_chassisSystemTempAmbient, value => $self->{results}->{$oid_chassisSystemTempAmbient}->{$oid}, diff --git a/centreon/common/violin/snmp/mode/components/vimm.pm b/centreon/common/violin/snmp/mode/components/vimm.pm index 8f0189ea9..63c36042e 100644 --- a/centreon/common/violin/snmp/mode/components/vimm.pm +++ b/centreon/common/violin/snmp/mode/components/vimm.pm @@ -39,10 +39,9 @@ my %map_vimm_present = ( ); sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_arrayVimmEntry_present }; - push @{$options{request}}, { oid => $oid_arrayVimmEntry_failed }; + push @{$self->{request}}, { oid => $oid_arrayVimmEntry_present }, { oid => $oid_arrayVimmEntry_failed }; } sub check { @@ -50,7 +49,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking vimms"); $self->{components}->{vimm} = {name => 'vimms', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'vimm')); + return if ($self->check_filter(section => 'vimm')); foreach my $oid (keys %{$self->{results}->{$oid_arrayVimmEntry_present}}) { next if ($oid !~ /^$oid_arrayVimmEntry_present\.(.*)$/); @@ -59,7 +58,7 @@ sub check { my ($dummy, $array_name, $vimm_name) = $self->convert_index(value => $1); my $instance = $array_name . '-' . $vimm_name; - next if ($self->check_exclude(section => 'vimm', instance => $instance)); + next if ($self->check_filter(section => 'vimm', instance => $instance)); next if ($map_vimm_present{$present} =~ /Absent/i && $self->absent_problem(section => 'vimm', instance => $instance)); diff --git a/centreon/common/violin/snmp/mode/hardware.pm b/centreon/common/violin/snmp/mode/hardware.pm index f264e3e5b..1200df760 100644 --- a/centreon/common/violin/snmp/mode/hardware.pm +++ b/centreon/common/violin/snmp/mode/hardware.pm @@ -20,55 +20,77 @@ package centreon::common::violin::snmp::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -use centreon::plugins::misc; my $thresholds = { - vimm => [ - ['not failed', 'OK'], - ['failed', 'CRITICAL'], - ], - ca => [ - ['ON', 'CRITICAL'], - ['OFF', 'OK'], - ], - psu => [ - ['OFF', 'CRITICAL'], - ['Absent', 'OK'], - ['ON', 'OK'], - ], - fan => [ - ['OFF', 'CRITICAL'], - ['Absent', 'OK'], - ['Low', 'OK'], - ['Medium', 'OK'], - ['High', 'WARNING'], - ], - gfc => [ - ['Online', 'OK'], - ['Unconfigured', 'OK'], - ['Unknown', 'UNKNOWN'], - ['Not\s*Supported', 'WARNING'], - ['Dead', 'CRITICAL'], - ['Lost', 'CRITICAL'], - ['Failover\s*Failed', 'CRITICAL'], - ['Failover', 'WARNING'], - ], - lfc => [ - ['Online', 'OK'], - ['Unconfigured', 'OK'], - ['Unknown', 'UNKNOWN'], - ['Not\s*Supported', 'WARNING'], - ['Dead', 'CRITICAL'], - ['Lost', 'CRITICAL'], - ['Failover\s*Failed', 'CRITICAL'], - ['Failover', 'WARNING'], - ], + }; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(vimm|ca|psu|fan|gfc|lfc)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + vimm => [ + ['not failed', 'OK'], + ['failed', 'CRITICAL'], + ], + ca => [ + ['ON', 'CRITICAL'], + ['OFF', 'OK'], + ], + psu => [ + ['OFF', 'CRITICAL'], + ['Absent', 'OK'], + ['ON', 'OK'], + ], + fan => [ + ['OFF', 'CRITICAL'], + ['Absent', 'OK'], + ['Low', 'OK'], + ['Medium', 'OK'], + ['High', 'WARNING'], + ], + gfc => [ + ['Online', 'OK'], + ['Unconfigured', 'OK'], + ['Unknown', 'UNKNOWN'], + ['Not\s*Supported', 'WARNING'], + ['Dead', 'CRITICAL'], + ['Lost', 'CRITICAL'], + ['Failover\s*Failed', 'CRITICAL'], + ['Failover', 'WARNING'], + ], + lfc => [ + ['Online', 'OK'], + ['Unconfigured', 'OK'], + ['Unknown', 'UNKNOWN'], + ['Not\s*Supported', 'WARNING'], + ['Dead', 'CRITICAL'], + ['Lost', 'CRITICAL'], + ['Failover\s*Failed', 'CRITICAL'], + ['Failover', 'WARNING'], + ], + }; + + $self->{components_path} = 'centreon::common::violin::snmp::mode::components'; + $self->{components_module} = ['ca', 'psu', 'fan', 'vimm', 'temperature', 'gfc', 'lfc']; +} + +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); @@ -76,202 +98,12 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "exclude:s" => { name => 'exclude' }, - "component:s" => { name => 'component', default => '.*' }, - "absent-problem:s" => { name => 'absent' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { }); - $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'; - } - } - - $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->{numeric_threshold} = {}; - foreach my $option (('warning', 'critical')) { - foreach my $val (@{$self->{option_results}->{$option}}) { - if ($val !~ /^(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $regexp, $value) = ('temperature', $1, $2); - 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, regexp => $regexp }; - } - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('ca', 'psu', 'fan', 'vimm', 'temperature', 'gfc', 'lfc'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "centreon::common::violin::snmp::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "centreon::common::violin::snmp::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $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; -} - -sub absent_problem { - my ($self, %options) = @_; - - if (defined($self->{option_results}->{absent}) && - $self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - } - - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); - $self->{components}->{$options{section}}->{skip}++; - return 1; -} - -sub get_severity_numeric { - my ($self, %options) = @_; - my $status = 'OK'; # default - my $thresholds = { warning => undef, critical => undef }; - - - if (defined($self->{numeric_threshold}->{$options{section}})) { - my $exits = []; - foreach (@{$self->{numeric_threshold}->{$options{section}}}) { - if ($options{instance} =~ /$_->{regexp}/) { - 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}); - - } - } - $status = $self->{output}->get_most_critical(status => $exits) if (scalar(@{$exits}) > 0); - } - - return ($status, $thresholds->{warning}, $thresholds->{critical}); -} - -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; -} - sub convert_index { my ($self, %options) = @_; @@ -306,15 +138,15 @@ Check components (Fans, Power Supplies, Temperatures, Chassis alarm, vimm, globa Which component to check (Default: '.*'). Can be: 'psu', 'fan', 'ca', 'vimm', 'lfc', 'gfc', 'temperature'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=psu) -Can also exclude specific instance: --exclude='psu#41239F00647-A#' +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=psu) +Can also exclude specific instance: --filter=fan,41239F00647-A =item B<--absent-problem> Return an error if an entity is not 'present' (default is skipping) (comma seperated list) -Can be specific or global: --absent-problem=fan#41239F00647-fan02# +Can be specific or global: --absent-problem=fan,41239F00647-fan02 =item B<--no-component> @@ -323,19 +155,19 @@ If total (with skipped) is 0. (Default: 'critical' returns). =item B<--threshold-overload> -Set to overload default threshold values (syntax: section,status,regexp) +Set to overload default threshold values (syntax: section,[instance,]status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='gfc,CRITICAL,^(?!(Online)$)' =item B<--warning> -Set warning threshold for temperatures (syntax: regexp,treshold) -Example: --warning='41239F00647-vimm46,20' --warning='41239F00647-vimm5.*,30' +Set warning threshold for temperatures (syntax: type,regexp,threshold) +Example: --warning='temperature,41239F00647-vimm46,20' --warning='temperature,41239F00647-vimm5.*,30' =item B<--critical> -Set critical threshold for temperatures (syntax: regexp,treshold) -Example: --critical='41239F00647-vimm46,25' --warning='41239F00647-vimm5.*,35' +Set critical threshold for temperatures (syntax: type,regexp,threshold) +Example: --critical='temperature,.*,25' --warning='temperature,.*,35' =back diff --git a/centreon/plugins/alternative/Getopt.pm b/centreon/plugins/alternative/Getopt.pm index 1061afbfa..62ede9f01 100644 --- a/centreon/plugins/alternative/Getopt.pm +++ b/centreon/plugins/alternative/Getopt.pm @@ -58,7 +58,7 @@ sub GetOptions { my $search_str = ',' . join(',', keys %opts) . ','; my $num_args = scalar(@ARGV); for (my $i = 0; $i < $num_args;) { - if ($ARGV[$i] =~ /^--(.*?)(?:=|$)(.*)/) { + if (defined($ARGV[$i]) && $ARGV[$i] =~ /^--(.*?)(?:=|$)(.*)/) { my ($option, $value) = ($1, $2); # find type of option @@ -89,7 +89,7 @@ sub GetOptions { splice @ARGV, $i, 1; $num_args--; } else { - warn "argument $ARGV[$i] alone" if ($warn_message == 1); + warn "argument $ARGV[$i] alone" if ($warn_message == 1 && $i != 0 && defined($ARGV[$i])); $i++; } } diff --git a/centreon/plugins/http.pm b/centreon/plugins/http.pm index db46f4555..452f765bd 100644 --- a/centreon/plugins/http.pm +++ b/centreon/plugins/http.pm @@ -43,13 +43,13 @@ sub new { warning_status => undef, critical_status => undef, }; - $self->{add_headers} = {}; + $self->{add_headers} = {}; return $self; } sub set_options { my ($self, %options) = @_; - + $self->{options} = { %{$self->{options}} }; foreach (keys %options) { $self->{options}->{$_} = $options{$_} if (defined($options{$_})); @@ -58,13 +58,13 @@ sub set_options { sub add_header { my ($self, %options) = @_; - + $self->{add_headers}->{$options{key}} = $options{value}; } sub check_options { my ($self, %options) = @_; - + 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(); @@ -81,9 +81,9 @@ sub check_options { $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}->{headers} = {}; if (defined($options{request}->{header})) { foreach (@{$options{request}->{header}}) { @@ -95,7 +95,7 @@ sub check_options { foreach (keys %{$self->{add_headers}}) { $options{request}->{headers}->{$_} = $self->{add_headers}->{$_}; } - + foreach my $method (('get', 'post')) { if (defined($options{request}->{$method . '_param'})) { $self->{$method . '_params'} = {}; @@ -115,7 +115,7 @@ sub check_options { } } } - + foreach (('unknown_status', 'warning_status', 'critical_status')) { if (defined($options{request}->{$_})) { $options{request}->{$_} =~ s/%\{http_code\}/\$response->code/g; @@ -139,7 +139,7 @@ sub get_port { sub get_port_request { my ($self, %options) = @_; - + my $port = ''; if (defined($self->{options}->{port}) && $self->{options}->{port} ne '') { $port = $self->{options}->{port}; @@ -149,13 +149,18 @@ sub get_port_request { 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; + my ($pac, $pac_uri); eval { - $pac = HTTP::ProxyPAC->new($options{request}->{proxypac}); + 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: ' . $@); @@ -163,9 +168,11 @@ sub set_proxy { } my $res = $pac->find_proxy($options{url}); if (defined($res->direct) && $res->direct != 1) { - $self->{ua}->proxy(['http', 'https'], $res->proxy); + 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}); } @@ -173,13 +180,13 @@ sub set_proxy { sub request { my ($self, %options) = @_; - + my $request_options = { %{$self->{options}} }; foreach (keys %options) { $request_options->{$_} = $options{$_} if (defined($options{$_})); } $self->check_options(request => $request_options); - + if (!defined($self->{ua})) { $self->{ua} = LWP::UserAgent->new(keep_alive => 1, protocols_allowed => ['http', 'https'], timeout => $request_options->{timeout}); if (defined($request_options->{cookies_file})) { @@ -212,7 +219,7 @@ sub request { my $content_type_forced; foreach my $key (keys %{$request_options->{headers}}) { - if ($key !~ /content-type/i) { + if ($key !~ /content-type/i) { $req->header($key => $request_options->{headers}->{$key}); } else { $content_type_forced = $request_options->{headers}->{$key}; @@ -258,7 +265,7 @@ sub request { $ssl_context->{SSL_key_file} = $request_options->{key_file} if (defined($request_options->{key_file})); $ssl_context->{SSL_ca_file} = $request_options->{cacert_file} if (defined($request_options->{cacert_file})); } - + if (defined($ssl_context)) { my $context = new IO::Socket::SSL::SSL_Context(%{$ssl_context}); IO::Socket::SSL::set_default_context($context); @@ -269,11 +276,11 @@ sub request { # 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'; @@ -289,15 +296,22 @@ sub request { $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)) { $self->{output}->output_add(severity => $status, short_msg => $response->status_line); $self->{output}->display(); $self->{output}->exit(); } - - return $response->content; + + $self->{headers} = $response->headers; + return $response->content; +} + +sub get_header { + my ($self, %options) = @_; + + return $self->{headers}; } 1; diff --git a/centreon/plugins/options.pm b/centreon/plugins/options.pm index 3a0cec151..557e2f412 100644 --- a/centreon/plugins/options.pm +++ b/centreon/plugins/options.pm @@ -32,6 +32,7 @@ sub new { my $self = {}; bless $self, $class; + $self->{sanity} = 0; $self->{options_stored} = {}; $self->{options} = {}; @{$self->{pod_package}} = (); @@ -59,10 +60,8 @@ sub set_sanity { } else { $centreon::plugins::alternative::Getopt::warn_message = 1; } - $SIG{__WARN__} = sub { - $self->{output}->add_option_msg(short_msg => $_[0]); - $self->{output}->option_exit(nolabel => 1); - }; + + $self->{sanity} = 1; } sub set_output { @@ -127,10 +126,21 @@ sub parse_options { my $self = shift; #%{$self->{options_stored}} = (); + my $save_warn_handler; + if ($self->{sanity} == 1) { + $save_warn_handler = $SIG{__WARN__}; + $SIG{__WARN__} = sub { + $self->{output}->add_option_msg(short_msg => $_[0]); + $self->{output}->option_exit(nolabel => 1); + }; + } + GetOptions( %{$self->{options}} ); %{$self->{options}} = (); + + $SIG{__WARN__} = $save_warn_handler if ($self->{sanity} == 1); } sub get_option { diff --git a/centreon/plugins/output.pm b/centreon/plugins/output.pm index d60e116a6..37964541c 100644 --- a/centreon/plugins/output.pm +++ b/centreon/plugins/output.pm @@ -40,6 +40,7 @@ sub new { "range-perfdata:s" => { name => 'range_perfdata' }, "filter-perfdata:s" => { name => 'filter_perfdata' }, "change-perfdata:s@" => { name => 'change_perfdata' }, + "filter-uom:s" => { name => 'filter_uom' }, "verbose" => { name => 'verbose' }, "debug" => { name => 'debug' }, "opt-exit:s" => { name => 'opt_exit', default => 'unknown' }, @@ -282,6 +283,8 @@ sub output_json { my %values = (); foreach my $key (keys %$perf) { + $perf->{$key} = '' if (defined($self->{option_results}->{filter_uom}) && $key eq 'unit' && + $perf->{$key} !~ /$self->{option_results}->{filter_uom}/); $values{$key} = $perf->{$key}; } @@ -372,6 +375,8 @@ sub output_xml { $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' && + $perf->{$key} !~ /$self->{option_results}->{filter_uom}/); my $child = $self->{xml_output}->createElement($key); $child->appendText($perf->{$key}); $child_perfdata->addChild($child); @@ -412,6 +417,8 @@ sub output_txt { 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}]); print " '" . $perf->{label} . "'=" . $perf->{value} . $perf->{unit} . ";" . $perf->{warning} . ";" . $perf->{critical} . ";" . $perf->{min} . ";" . $perf->{max}; } @@ -776,6 +783,10 @@ Syntax: regexp_matching,regexp_substitute Change perfdata range thresholds display: 1 = start value equals to '0' is removed, 2 = threshold range is not display. +=item B<--filter-uom> + +Filter UOM that match the regexp. + =item B<--opt-exit> Exit code for an option error, usage (default: unknown). diff --git a/centreon/plugins/script.pm b/centreon/plugins/script.pm index 8ff1070a8..bba0658ab 100644 --- a/centreon/plugins/script.pm +++ b/centreon/plugins/script.pm @@ -31,7 +31,7 @@ use Pod::Find qw(pod_where); my %handlers = (DIE => {}); -my $global_version = 20151126; +my $global_version = 20151218; sub new { my $class = shift; diff --git a/centreon/plugins/snmp.pm b/centreon/plugins/snmp.pm index b8562bbfb..4bcf9f7b1 100644 --- a/centreon/plugins/snmp.pm +++ b/centreon/plugins/snmp.pm @@ -52,6 +52,7 @@ sub new { "snmp-retries:s" => { name => 'snmp_retries', default => 5 }, "maxrepetitions:s" => { name => 'maxrepetitions', default => 50 }, "subsetleef:s" => { name => 'subsetleef', default => 50 }, + "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' }, @@ -354,7 +355,7 @@ sub get_multiple_table { my $vb = new SNMP::VarList(@bindings); - if ($self->is_snmpv1()) { + if ($self->is_snmpv1() || defined($self->{snmp_force_getnext})) { $self->{session}->getnext($vb); } else { my $current_repeat_count = floor($repeat_count / (scalar(keys %{$working_oids}))); @@ -420,6 +421,12 @@ sub get_multiple_table { $working_oids->{ $bases[$pos % $current_oids] }->{start} = $complete_oid; } + + # infinite loop. Some equipments it returns nothing!!?? + if ($pos == -1) { + $self->{output}->add_option_msg(short_msg => "SNMP Table Request: problem to get values (try --snmp-force-getnext option)"); + $self->{output}->option_exit(exit_litteral => $self->{snmp_errors_exit}); + } } my $total = 0; @@ -495,7 +502,7 @@ sub get_table { $last_oid =~ /(.*)\.(\d+)([\.\s]*)$/; my $vb = new SNMP::VarList([$1, $2]); - if ($self->is_snmpv1()) { + if ($self->is_snmpv1() || defined($self->{snmp_force_getnext})) { $self->{session}->getnext($vb); } else { $self->{session}->getbulk(0, $repeat_count, $vb); @@ -636,6 +643,7 @@ sub check_options { $self->{output}->option_exit(); } + $self->{snmp_force_getnext} = $options{option_results}->{snmp_force_getnext}; $self->{maxrepetitions} = $options{option_results}->{maxrepetitions}; $self->{subsetleef} = (defined($options{option_results}->{subsetleef}) && $options{option_results}->{subsetleef} =~ /^[0-9]+$/) ? $options{option_results}->{subsetleef} : 50; $self->{snmp_errors_exit} = $options{option_results}->{snmp_errors_exit}; @@ -842,6 +850,10 @@ Max repetitions value (default: 50) (only for SNMP v2 and v3). How many oid values per SNMP request (default: 50) (for get_leef method. Be cautious whe you set it. Prefer to let the default value). +=item B<--snmp-force-getnext> + +Use snmp getnext function (even in snmp v2c and v3). + =item B<--snmp-username> Security name (only for SNMP v3). diff --git a/centreon/plugins/templates/counter.pm b/centreon/plugins/templates/counter.pm new file mode 100644 index 000000000..a239541e8 --- /dev/null +++ b/centreon/plugins/templates/counter.pm @@ -0,0 +1,325 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package centreon::plugins::templates::counter; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::values; +use centreon::plugins::misc; + +sub set_counters { + my ($self, %options) = @_; + + if (!defined($self->{maps_counters})) { + $self->{maps_counters} = {}; + } + + $self->{maps_counters_type} = []; + + # 0 = mode total + # 1 = mode instances + #push @{$self->{maps_counters_type}}, { + # name => 'global', type => 0, message_separator => ', ', cb_prefix_output => undef, cb_init => undef, + #}; + + #$self->{maps_counters}->{global} = [ + # { label => 'client', set => { + # key_values => [ { name => 'client' } ], + # output_template => 'Current client connections : %s', + # perfdatas => [ + # { label => 'Client', value => 'client_absolute', template => '%s', + # min => 0, unit => 'con' }, + # ], + # } + # }, + #]; + + # Example for instances + #push @{$self->{maps_counters_type}}, { + # name => 'cpu', type => 1, message_separator => ', ', cb_prefix_output => undef, cb_init => undef, + # message_multiple => 'All CPU usages are ok', + #}; +} + +sub call_object_callback { + my ($self, %options) = @_; + + if (defined($options{method_name})) { + my $method = $self->can($options{method_name}); + if ($method) { + return $self->$method(%options); + } + } + + return undef; +} + +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' }, + }); + $self->{statefile_value} = undef; + if (defined($options{statefile}) && $options{statefile}) { + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'centreon::plugins::statefile', + error_msg => "Cannot load module 'centreon::plugins::statefile'."); + $self->{statefile_value} = centreon::plugins::statefile->new(%options); + } + + $self->{maps_counters} = {} if (!defined($self->{maps_counters})); + $self->set_counters(); + + foreach my $key (keys %{$self->{maps_counters}}) { + foreach (@{$self->{maps_counters}->{$key}}) { + if (!defined($_->{threshold}) || $_->{threshold} != 0) { + $options{options}->add_options(arguments => { + 'warning-' . $_->{label} . ':s' => { name => 'warning-' . $_->{label} }, + 'critical-' . $_->{label} . ':s' => { name => 'critical-' . $_->{label} }, + }); + } + $_->{obj} = centreon::plugins::values->new(statefile => $self->{statefile_value}, + output => $self->{output}, perfdata => $self->{perfdata}, + label => $_->{label}); + $_->{obj}->set(%{$_->{set}}); + } + } + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + foreach my $key (keys %{$self->{maps_counters}}) { + foreach (@{$self->{maps_counters}->{$key}}) { + $_->{obj}->init(option_results => $self->{option_results}); + } + } + + if (defined($self->{statefile_value})) { + $self->{statefile_value}->check_options(%options); + } +} + +sub run_global { + my ($self, %options) = @_; + + return undef if (defined($options{config}->{cb_init}) && $self->call_object_callback(method_name => $options{config}->{cb_init}) == 1); + + my $message_separator = defined($options{config}->{message_separator}) ? + $options{config}->{message_separator}: ', '; + 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}/); + + $obj->set(instance => $options{config}->{name}); + + my ($value_check) = $obj->execute(new_datas => $self->{new_datas}, values => $self->{$options{config}->{name}}); + + if ($value_check != 0) { + $long_msg .= $long_msg_append . $obj->output_error(); + $long_msg_append = $message_separator; + next; + } + my $exit2 = $obj->threshold_check(); + push @exits, $exit2; + + my $output = $obj->output(); + $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; + } + + $obj->perfdata(); + } + + my ($prefix_output, $suffix_output); + $prefix_output = $self->call_object_callback(method_name => $options{config}->{cb_prefix_output}) + if (defined($options{config}->{cb_prefix_output})); + $prefix_output = '' if (!defined($prefix_output)); + + $suffix_output = $self->call_object_callback(method_name => $options{config}->{cb_suffix_output}) + if (defined($options{config}->{cb_suffix_output})); + $suffix_output = '' if (!defined($suffix_output)); + + 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_output}${short_msg}${suffix_output}" + ); + } else { + $self->{output}->output_add(short_msg => "${prefix_output}${long_msg}${suffix_output}"); + } +} + +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); + + $self->{multiple} = 1; + if (scalar(keys %{$self->{$options{config}->{name}}}) == 1) { + $self->{multiple} = 0; + } + + if ($self->{multiple} == 1) { + $self->{output}->output_add(severity => 'OK', + short_msg => $options{config}->{message_multiple}); + } + + my $message_separator = defined($options{config}->{message_separator}) ? + $options{config}->{message_separator}: ', '; + foreach my $id (sort 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}/); + + $obj->set(instance => $id); + + my ($value_check) = $obj->execute(new_datas => $self->{new_datas}, + values => $self->{$options{config}->{name}}->{$id}); + + if ($value_check != 0) { + $long_msg .= $long_msg_append . $obj->output_error(); + $long_msg_append = $message_separator; + next; + } + my $exit2 = $obj->threshold_check(); + push @exits, $exit2; + + my $output = $obj->output(); + $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; + } + + $obj->perfdata(extra_instance => $self->{multiple}); + } + + my ($prefix_output, $suffix_output); + $prefix_output = $self->call_object_callback(method_name => $options{config}->{cb_prefix_output}, instance_value => $self->{$options{config}->{name}}->{$id}) + if (defined($options{config}->{cb_prefix_output})); + $prefix_output = '' if (!defined($prefix_output)); + + $suffix_output = $self->call_object_callback(method_name => $options{config}->{cb_suffix_output}) + if (defined($options{config}->{cb_suffix_output})); + $suffix_output = '' if (!defined($suffix_output)); + + $self->{output}->output_add(long_msg => "${prefix_output}${long_msg}${suffix_output}"); + 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_output}${short_msg}${suffix_output}" + ); + } + + if ($self->{multiple} == 0) { + $self->{output}->output_add(short_msg => "${prefix_output}${long_msg}${suffix_output}"); + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + + $self->{new_datas} = undef; + if (defined($self->{statefile_value})) { + $self->{new_datas} = {}; + $self->{statefile_value}->read(statefile => $self->{cache_name}) if (defined($self->{cache_name})); + $self->{new_datas}->{last_timestamp} = time(); + } + + foreach my $entry (@{$self->{maps_counters_type}}) { + if ($entry->{type} == 0) { + $self->run_global(config => $entry); + } elsif ($entry->{type} == 1) { + $self->run_instances(config => $entry); + } + } + + if (defined($self->{statefile_value})) { + $self->{statefile_value}->write(data => $self->{new_datas}); + } + $self->{output}->display(); + $self->{output}->exit(); +} + +sub manage_selection { + my ($self, %options) = @_; + + # example for snmp + #use Digest::MD5 qw(md5_hex); + #$self->{cache_name} = "choose_name_" . $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 + +Default template for counters. Should be extended. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example to check SSL connections only : --filter-counters='^xxxx|yyyy$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'xxx', 'xxx'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'xxx', 'xxx'. + +=back + +=cut \ No newline at end of file diff --git a/centreon/plugins/templates/hardware.pm b/centreon/plugins/templates/hardware.pm new file mode 100644 index 000000000..b060cc067 --- /dev/null +++ b/centreon/plugins/templates/hardware.pm @@ -0,0 +1,434 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package centreon::plugins::templates::hardware; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + # To check with a regexp + #$self->{regexp_threshold_overload_check_section_option} = ''; + #$self->{cb_threshold_overload_check_section_option} = 'callbackname'; + + #$self->{regexp_threshold_numeric_check_section_option} = ''; + #$self->{cb_threshold_numeric_check_section_option} = 'callbackname'; + + # Some callbacks + #$self->{cb_hook1} = 'callbackname'; # before the loads + #$self->{cb_hook2} = 'callbackname'; # between loads and requests + #$self->{cb_hook3} = 'callbackname'; # after requests + + # Example for threshold: + #$self->{thresholds} = { + # fan => [ + # ['bad', 'CRITICAL'], + # ['good', 'OK'], + # ['notPresent', 'OK'], + # ], + #}; + + # Unset the call to load components + #$self->{components_exec_load} = 0; + + # Set the path_info + #$self->{components_path} = 'network::xxxx::mode::components'; + + # Set the components + #$self->{components_module} = ['cpu', 'memory', ...]; +} + +sub call_object_callback { + my ($self, %options) = @_; + + if (defined($options{method_name})) { + my $method = $self->can($options{method_name}); + if ($method) { + return $self->$method(%options); + } + } + + return undef; +} + +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 => { + "component:s" => { name => 'component', default => '.*' }, + "no-component:s" => { name => 'no_component' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); + + $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' }, + }); + } + + $self->{filter_exclude} = (defined($options{no_filter_exclude}) && $options{no_filter_exclude} == 1) ? + 0 : 1; + if ($self->{filter_exclude} == 1) { + $options{options}->add_options(arguments => { + "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' }, + }); + } + + $self->{components} = {}; + $self->{no_components} = undef; + + $self->{components_module} = []; + $self->{components_exec_load} = 1; + $self->set_system(); + + $self->{request} = []; + + 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'; + } + } + + if ($self->{filter_exclude} == 1) { + $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] }; + } + } + + if ($self->{absent} == 1) { + $self->{absent_problem} = []; + foreach my $val (@{$self->{option_results}->{absent_problem}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + push @{$self->{absent_problem}}, { 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 (defined($self->{regexp_threshold_overload_check_section_option}) && + $section !~ /$self->{regexp_threshold_overload_check_section_option}/) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload section '" . $val . "'."); + $self->{output}->option_exit(); + } + $self->call_object_callback(method_name => $self->{cb_threshold_overload_check_section_option}, + section => $section, option_value => $val); + + 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 }; + } + + if ($self->{performance} == 1) { + $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 (defined($self->{regexp_threshold_numeric_check_section_option}) && + $section !~ /$self->{regexp_threshold_numeric_check_section_option}/) { + $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); + $self->{output}->option_exit(); + } + $self->call_object_callback(method_name => $self->{cb_threshold_numeric_check_section_option}, + section => $section, option_name => $option, option_value => $val); + + 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 }; + } + } + } +} + +sub load_components { + my ($self, %options) = @_; + + foreach (@{$self->{components_module}}) { + if (/$self->{option_results}->{component}/) { + my $mod_name = $self->{components_path} . "::$_"; + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, + error_msg => "Cannot load module '$mod_name'."); + $self->{loaded} = 1; + if ($self->{components_exec_load} == 1) { + my $func = $mod_name->can('load'); + $func->($self); + } + } + } +} + +sub exec_components { + my ($self, %options) = @_; + + foreach (@{$self->{components_module}}) { + if (/$self->{option_results}->{component}/) { + my $mod_name = $self->{components_path} . "::$_"; + my $func = $mod_name->can('check'); + $func->($self); + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->{loaded} = 0; + $self->call_object_callback(method_name => $self->{cb_hook1}, %options); + + $self->load_components(%options); + if ($self->{loaded} == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); + $self->{output}->option_exit(); + } + + $self->call_object_callback(method_name => $self->{cb_hook2}, %options); + $self->exec_components(%options); + $self->call_object_callback(method_name => $self->{cb_hook3}, %options); + + 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}; + my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; + $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; + $display_by_component_append = ', '; + } + + $self->{output}->output_add(severity => 'OK', + short_msg => sprintf("All %s components are ok [%s].", + $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.'); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub check_filter { + my ($self, %options) = @_; + + # Old compatibility variable. We'll be deleted + if (defined($self->{option_results}->{exclude})) { + 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.")); + 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; + } + } + + 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->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); + return 1; + } + } + } + + return 0; +} + +sub absent_problem { + my ($self, %options) = @_; + + foreach (@{$self->{absent_problem}}) { + if ($options{section} =~ /$_->{filter}/) { + if (!defined($_->{instance}) || $options{instance} =~ /$_->{instance}/) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => sprintf("Component '%s' instance '%s' is not present", + $options{section}, $options{instance})); + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); + $self->{components}->{$options{section}}->{skip}++; + return 1; + } + } + } + + return 0; +} + +sub get_severity_numeric { + 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 + + 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 (@{$self->{thresholds}->{$label}}) { + if ($options{value} =~ /$$_[0]/i) { + $status = $$_[1]; + return $status; + } + } + + return $status; +} + +1; + +__END__ + +=head1 MODE + +Default template for hardware. Should be extended. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'xxx', 'yyy'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=xxx --filter=yyyy) +Can also exclude specific instance: --filter=xxxxx,instancevalue + +=item B<--absent-problem> + +Return an error if an entity is not 'present' (default is skipping) (comma seperated list) +Can be specific or global: --absent-problem=xxxx,instancevalue + +=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='xxxxx,CRITICAL,^(?!(normal)$)' + +=item B<--warning> + +Set warning threshold for temperatures (syntax: type,instance,threshold) +Example: --warning='xxxxx,.*,30' + +=item B<--critical> + +Set critical threshold for temperatures (syntax: type,instance,threshold) +Example: --critical='xxxxx,.*,40' + +=back + +=cut \ No newline at end of file diff --git a/changelog b/changelog index 9c609d475..3c577a6f2 100644 --- a/changelog +++ b/changelog @@ -1,2 +1,27 @@ -2015-11-26 Quentin Garnier +2015-12-18 Quentin Garnier + * Plugin added: Add a plugin to check VMWare ESX with WSMAN + * Configuration: centreon-plugins don't use GetOptions anymore (custom library instead) + * Add option '--snmp-force-getnext' in core snmp library + * Mode added: [F5 BigIP] 'failover' + * Mode added: [vmware connector] for centreon-vmware 2.1.0 + * Enhancement: [extreme]{cpu} 'n/a' value managed (#223) + * Enhancement: [snmp standard]{inodes} add filter type option (#224) + * Enhancement: [netapp]{filesys} add inodes usage + * Enhancement: [snmp_standard]{ntp} change output (#232) + * Enhancement: [snmp_standard]{processcount} improve performance + * Enhancement: [cisco standard]{ipsla} manage no tag name + * Enhancement: [snmp_standard]{loadaverage} manage load with coma + * Enhancement: [oracle]{tablespaces} manage 'UNDO' tablespaces (#242) + * Enhancement: [cisco ucs]{equipment} add cpu, memory and localdisk monitoring + * Enhancement: [cisco wlc]{ap-status} can monitor the number of APs + * Enhancement: [F5 BigIP]{hardware} refactoring + * Enhancement: [cisco standard]{environment} add sensors monitoring (#160) + * Enhancement: [aws]{list} add exclude service (#248) + * Fix: [protocol x509]{validity} add default port (#240) + * Fix: [ups standard]{battery-status} hardened code (#225) + * Fix: [cisco standard]{environment} voltage threshold value issue + * Fix: [kayako api]{ticketcount} mode crash + * Fix: [elasticsearch] Crash without some values in command line (#243) + +2015-11-26 Quentin Garnier * initial release \ No newline at end of file diff --git a/cloud/aws/mode/cloudwatch.pm b/cloud/aws/mode/cloudwatch.pm index 636a09ec8..e0cd03634 100644 --- a/cloud/aws/mode/cloudwatch.pm +++ b/cloud/aws/mode/cloudwatch.pm @@ -29,12 +29,12 @@ use POSIX; use JSON; my $CloudwatchMetrics = { - cpu => "cloud::aws::mode::metrics::ec2instancecpu", - traffic => "cloud::aws::mode::metrics::ec2instancenetwork", - cpucreditusage => "cloud::aws::mode::metrics::ec2instancecpucreditusage", - cpucreditbalance => "cloud::aws::mode::metrics::ec2instancecpucreditbalance", - bucketsize => "cloud::aws::mode::metrics::s3bucketsize", - rdscpu => "cloud::aws::mode::metrics::rdsinstancecpu", + cpu => "cloud::aws::mode::metrics::ec2instancecpu", + traffic => "cloud::aws::mode::metrics::ec2instancenetwork", + cpucreditusage => "cloud::aws::mode::metrics::ec2instancecpucreditusage", + cpucreditbalance => "cloud::aws::mode::metrics::ec2instancecpucreditbalance", + bucketsize => "cloud::aws::mode::metrics::s3bucketsize", + rdscpu => "cloud::aws::mode::metrics::rdsinstancecpu", }; my $StatisticsType = "Average,Minimum,Maximum,Sum,SampleCount"; @@ -45,24 +45,25 @@ my $apiRequest = { 'subcommand' => 'get-metric-statistics', }; -sub new { - my ( $class, %options ) = @_; - my $self = $class->SUPER::new( package => __PACKAGE__, %options ); +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 => { - "metric:s" => { name => 'metric' }, - "period:s" => { name => 'period', default => 300 }, - "starttime:s" => { name => 'starttime' }, - "endtime:s" => { name => 'endtime' }, - "statistics:s" => { name => 'statistics', default => 'Average' }, - "exclude-statistics:s" => { name => 'exclude-statistics' }, - "object:s" => { name => 'object' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, + "metric:s" => {name => 'metric'}, + "period:s" => {name => 'period', default => 300}, + "starttime:s" => {name => 'starttime'}, + "endtime:s" => {name => 'endtime'}, + "statistics:s" => {name => 'statistics', default => 'Average'}, + "exclude-statistics:s" => {name => 'exclude-statistics'}, + "object:s" => {name => 'object'}, + "warning:s" => {name => 'warning'}, + "critical:s" => {name => 'critical'}, } ); $self->{result} = {}; @@ -70,30 +71,26 @@ sub new { return $self; } -sub check_options { - my ( $self, %options ) = @_; +sub check_options +{ + my ($self, %options) = @_; $self->SUPER::init(%options); $self->{option_results}->{def_endtime} = $def_endtime; - if ( ( $self->{perfdata}->threshold_validate( label => 'warning' ,value => $self->{option_results}->{warning} ) ) == 0 ) + 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}->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 ) + 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}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); $self->{output}->option_exit(); } - if ( !defined( $self->{option_results}->{metric} ) ) { + if (!defined($self->{option_results}->{metric})) + { $self->{output}->add_option_msg( severity => 'UNKNOWN', short_msg => "Please give a metric to watch (cpu, disk, ...)." @@ -101,7 +98,8 @@ sub check_options { $self->{output}->option_exit(); } - if ( !defined( $self->{option_results}->{object} ) ) { + if (!defined($self->{option_results}->{object})) + { $self->{output}->add_option_msg( severity => 'UNKNOWN', short_msg => "Please give the object to request (instanceid, ...)." @@ -109,27 +107,29 @@ sub check_options { $self->{output}->option_exit(); } - if ( !defined( $self->{option_results}->{endtime} ) ) { - $self->{option_results}->{endtime} = - strftime( "%FT%H:%M:%S.000Z", - gmtime( $self->{option_results}->{def_endtime} ) ); + if (!defined($self->{option_results}->{endtime})) + { + $self->{option_results}->{endtime} = strftime("%FT%H:%M:%S.000Z", gmtime($self->{option_results}->{def_endtime})); } - if ( !defined( $self->{option_results}->{starttime} ) ) { - $self->{option_results}->{starttime} = - strftime( "%FT%H:%M:%S.000Z", - gmtime( $self->{option_results}->{def_endtime} - 600 ) ); + if (!defined($self->{option_results}->{starttime})) + { + $self->{option_results}->{starttime} = strftime("%FT%H:%M:%S.000Z", gmtime($self->{option_results}->{def_endtime} - 600)); } # Getting some parameters # statistics - if ( $self->{option_results}->{statistics} eq 'all' ) { - @{ $self->{option_results}->{statisticstab} } = split( /,/, $StatisticsType ); + if ($self->{option_results}->{statistics} eq 'all') + { + @{$self->{option_results}->{statisticstab}} = split(/,/, $StatisticsType); } - else { - @{ $self->{option_results}->{statisticstab} } = split( /,/, $self->{option_results}->{statistics} ); - foreach my $curstate ( @{ $self->{option_results}->{statisticstab} } ) { - if ( !grep { /^$curstate$/ } split( /,/, $StatisticsType ) ) { + else + { + @{$self->{option_results}->{statisticstab}} = split(/,/, $self->{option_results}->{statistics}); + foreach my $curstate (@{$self->{option_results}->{statisticstab}}) + { + if (!grep { /^$curstate$/ } split(/,/, $StatisticsType)) + { $self->{output}->add_option_msg( severity => 'UNKNOWN', short_msg => "The statistic $curstate doesn't exist." @@ -140,37 +140,43 @@ sub check_options { } # exclusions - if (defined($self->{option_results}->{'exclude-statistics'})){ - my @excludetab = split(/,/, $self->{option_results}->{'exclude-statistics'}); - my %array1 = map { $_ => 1 } @excludetab; - @{$self->{option_results}->{statisticstab}} = grep { not $array1{$_} } @{$self->{option_results}->{statisticstab}}; + if (defined($self->{option_results}->{'exclude-statistics'})) + { + my @excludetab = split(/,/, $self->{option_results}->{'exclude-statistics'}); + my %array1 = map { $_ => 1 } @excludetab; + @{$self->{option_results}->{statisticstab}} = grep { not $array1{$_} } @{$self->{option_results}->{statisticstab}}; } - + # Force Average statistic - if ( ! grep $_ eq 'Average', @{$self->{option_results}->{statisticstab}} ) { - my $statistics = join(',',@{ $self->{option_results}->{statisticstab} }); - if ( ! $statistics eq '' ) { + if (!grep $_ eq 'Average', @{$self->{option_results}->{statisticstab}}) + { + my $statistics = join(',', @{$self->{option_results}->{statisticstab}}); + if (!$statistics eq '') + { $statistics = $statistics . ',Average'; } - else { + else + { $statistics = 'Average'; } - @{ $self->{option_results}->{statisticstab} } = split( /,/, $statistics ); + @{$self->{option_results}->{statisticstab}} = split(/,/, $statistics); } } -sub manage_selection { - my ( $self, $metric ) = @_; +sub manage_selection +{ + my ($self, $metric) = @_; my @result; my @Dimensions = ( - { - 'Value' => $self->{option_results}->{object}, - 'Name' => $metric->{ObjectName} - } - ); + { + 'Value' => $self->{option_results}->{object}, + 'Name' => $metric->{ObjectName} + } + ); - if ( defined( $metric->{ExtraDimensions} ) ) { + if (defined($metric->{ExtraDimensions})) + { push @Dimensions, $metric->{ExtraDimensions}; } @@ -186,10 +192,11 @@ sub manage_selection { }; } -sub run { - my ( $self, %options ) = @_; +sub run +{ + my ($self, %options) = @_; - my ( $msg, $exit_code, $awsapi ); + my ($msg, $exit_code, $awsapi); if ( defined( $CloudwatchMetrics->{ $self->{option_results}->{metric} } ) ) { centreon::plugins::misc::mymodule_load(output => $options{output}, module => $CloudwatchMetrics->{$self->{option_results}->{metric}}, @@ -197,52 +204,34 @@ sub run { my $func = $CloudwatchMetrics->{$self->{option_results}->{metric}}->can('cloudwatchCheck'); $func->($self); } else { - $self->{output} - ->add_option_msg( short_msg => "Wrong option. Cannot find metric '" - . $self->{option_results}->{metric} - . "'." ); + $self->{output}->add_option_msg( short_msg => "Wrong option. Cannot find metric '" . $self->{option_results}->{metric} . "'." ); $self->{output}->option_exit(); } - foreach my $metric ( @{ $self->{metric} } ) { + foreach my $metric (@{$self->{metric}}) + { $self->manage_selection($metric); $awsapi = $options{custom}; $self->{command_return} = $awsapi->execReq($apiRequest); $self->{output}->perfdata_add( - label => sprintf( - $metric->{Labels}->{PerfData}, - unit => $metric->{Labels}->{Unit} - ), - value => sprintf( - $metric->{Labels}->{Value}, - $self->{command_return}->{Datapoints}[0]->{Average} - ), - warning => $self->{perfdata}->get_perfdata_for_output( label => 'warning' ), - critical => $self->{perfdata}->get_perfdata_for_output( label => 'critical' ), + label => sprintf($metric->{Labels}->{PerfData}, unit => $metric->{Labels}->{Unit}), + value => sprintf($metric->{Labels}->{Value}, $self->{command_return}->{Datapoints}[0]->{Average}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + #min => 0, #max => 100 ); $exit_code = $self->{perfdata}->threshold_check( value => $self->{command_return}->{Datapoints}[0]->{Average}, - threshold => [ - { label => 'critical', 'exit_litteral' => 'critical' }, - { label => 'warning', exit_litteral => 'warning' } - ] + threshold => [{label => 'critical', 'exit_litteral' => 'critical'}, {label => 'warning', exit_litteral => 'warning'}] ); - $self->{output}->output_add( - long_msg => sprintf( - $metric->{Labels}->{LongOutput}, - $self->{command_return}->{Datapoints}[0]->{Average} - ) - ); + $self->{output}->output_add(long_msg => sprintf($metric->{Labels}->{LongOutput}, $self->{command_return}->{Datapoints}[0]->{Average})); $self->{output}->output_add( severity => $exit_code, - short_msg => sprintf( - $metric->{Labels}->{ShortOutput}, - $self->{command_return}->{Datapoints}[0]->{Average} - ) + short_msg => sprintf($metric->{Labels}->{ShortOutput}, $self->{command_return}->{Datapoints}[0]->{Average}) ); } diff --git a/cloud/aws/mode/list.pm b/cloud/aws/mode/list.pm index 82173e297..a732bee56 100644 --- a/cloud/aws/mode/list.pm +++ b/cloud/aws/mode/list.pm @@ -17,33 +17,31 @@ # See the License for the specific language governing permissions and # limitations under the License. # - package cloud::aws::mode::list; use base qw(centreon::plugins::mode); use strict; use warnings; use centreon::plugins::misc; -use Data::Dumper; use JSON; -my $AWSServices = 'EC2,S3,RDS'; -my @Disco_service_tab = ('EC2', 'RDS'); -my @EC2_instance_states = [ 'running', 'stopped' ]; - +my $AWSServices = 'EC2,S3,RDS'; +my @Disco_service_tab = ('EC2', 'RDS'); +my $EC2_instance_states = 'running,stopped'; my $awsapi; -sub new { - my ( $class, %options ) = @_; - my $self = $class->SUPER::new( package => __PACKAGE__, %options ); +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 => { - "service:s" => { name => 'service', default => $AWSServices }, - "exclude:s" => { name => 'exclude' }, + "service:s" => {name => 'service', default => $AWSServices}, + "exclude-service:s" => {name => 'exclude_service'}, + "ec2-state:s"=>{name=> 'ec2_state', default => $EC2_instance_states}, + "ec2-exclude-state:s" => {name => 'ec2_exclude_state'}, } ); $self->{result} = {}; @@ -59,6 +57,13 @@ sub api_request { my ($self, %options) = @_; @{$self->{option_results}->{servicetab}} = split( /,/, $self->{option_results}->{service} ); + # exclusions + if (defined($self->{option_results}->{exclude_service})) { + my @excludetab = split /,/, $self->{option_results}->{exclude_service}; + my %array1 = map { $_ => 1 } @excludetab; + @{$self->{option_results}->{servicetab}} = grep { not $array1{$_} } @{$self->{option_results}->{servicetab}}; + } + foreach my $service (@{$self->{option_results}->{servicetab}}) { $self->{result}->{count}->{$service} = 0; if ($service eq 'EC2') { @@ -74,21 +79,28 @@ sub api_request { } } -sub EC2 { - my ( $self, %options ) = @_; - +sub EC2 +{ + my ($self, %options) = @_; my $apiRequest = { 'command' => 'ec2', 'subcommand' => 'describe-instances', }; # Building JSON + my @ec2_statestab = split(/,/, $self->{option_results}->{ec2_state}); + # exclusions + if (defined($self->{option_results}->{ec2_exclude_state})) { + my @excludetab = split /,/, $self->{option_results}->{ec2_exclude_state}; + my %array1 = map { $_ => 1 } @excludetab; + @ec2_statestab = grep { not $array1{$_} } @ec2_statestab; + } $apiRequest->{json} = { 'DryRun' => JSON::false, 'Filters' => [ { 'Name' => 'instance-state-name', - 'Values' => @EC2_instance_states, + 'Values' => [@ec2_statestab], } ], }; @@ -107,17 +119,17 @@ sub EC2 { $self->{result}->{'EC2'}->{$instance->{Instances}[0]->{InstanceId}} = { State => $instance->{Instances}[0]->{State}->{Name}, - Name => $instance->{Instances}[0]->{Name} + Name => $instance->{Instances}[0]->{Name} }; $self->{result}->{count}->{'EC2'}++; } } -sub S3 { - my ( $self, %options ) = @_; - my ( @buckets, @return ) = (); - +sub S3 +{ + my ($self, %options) = @_; + my (@buckets, @return) = (); my $apiRequest = { 'command' => 's3', 'subcommand' => 'ls', @@ -137,15 +149,15 @@ sub S3 { # Compute data foreach my $bucket (@buckets) { - $self->{result}->{'S3'}->{ $bucket->{Name} } = - { 'Creation date' => $bucket->{CreationDate} }; + $self->{result}->{'S3'}->{$bucket->{Name}} = + {'Creation date' => $bucket->{CreationDate}}; $self->{result}->{count}->{'S3'}++; } } -sub RDS { - my ( $self, %options ) = @_; - +sub RDS +{ + my ($self, %options) = @_; my $apiRequest = { 'command' => 'rds', 'subcommand' => 'describe-db-instances', @@ -172,25 +184,25 @@ sub disco_format { $self->{output}->add_disco_format( elements => $names ); } -sub disco_show { - my ( $self, %options ) = @_; - +sub disco_show +{ + my ($self, %options) = @_; $self->api_request(%options); foreach my $service (@Disco_service_tab) { foreach my $device (keys %{$self->{result}->{$service}}) { $self->{output}->add_disco_entry( - name => $self->{result}->{$service}->{$device}->{Name}, - id => $device, - state => $self->{result}->{$service}->{$device}->{State}, + name => $self->{result}->{$service}->{$device}->{Name}, + id => $device, + state => $self->{result}->{$service}->{$device}->{State}, service => $service, ); } } } -sub run { - my ( $self, %options ) = @_; - +sub run +{ + my ($self, %options) = @_; $self->api_request(%options); # Send formated data to Centreon @@ -199,21 +211,14 @@ sub run { foreach my $device (keys %{$self->{result}->{$service}}) { my $output = $device . " ["; foreach my $value (sort(keys %{$self->{result}->{$service}->{$device}})) { - $output = - $output - . $value . " = " - . $self->{result}->{$service}->{$device}->{$value} . ", "; + $output = $output . $value . " = " . $self->{result}->{$service}->{$device}->{$value} . ", "; } $output =~ s/, $//; $output = $output . "]"; - $self->{output}->output_add( long_msg => $output ); + $self->{output}->output_add(long_msg => $output); } - $self->{output}->output_add( - short_msg => sprintf( "%s: %s", - $service, $self->{result}->{count}->{$service} ) - ); + $self->{output}->output_add(short_msg => sprintf("%s: %s", $service, $self->{result}->{count}->{$service})); } - $self->{output}->display( nolabel => 1, force_ignore_perfdata => 1, @@ -221,9 +226,7 @@ sub run { ); $self->{output}->exit(); } - 1; - __END__ =head1 MODE @@ -236,10 +239,18 @@ List your EC2, RDS instance and S3 buckets (optional) List one particular service. -=item B<--exclude> +=item B<--exclude-service> (optional) Service to exclude from the scan. +=item B<--ec2-state> + +(optional) State to request (default: 'running','stopped') + +=item B<--ec2-exclude-state> + +(optional) State to exclude from the scan. + =back =cut diff --git a/database/oracle/mode/tablespaceusage.pm b/database/oracle/mode/tablespaceusage.pm index 98a47f5b4..e0df54b48 100644 --- a/database/oracle/mode/tablespaceusage.pm +++ b/database/oracle/mode/tablespaceusage.pm @@ -113,6 +113,9 @@ sub run { a.tablespace_name = c.tablespace_name (+) AND a.tablespace_name = b.tablespace_name AND a.tablespace_name = d.tablespace_name (+) + AND (b.contents = 'PERMANENT' + OR (b.contents <> 'PERMANENT' + AND a.tablespace_name=(select value from v$parameter where name='undo_tablespace'))) UNION ALL SELECT d.tablespace_name "Tablespace", @@ -180,6 +183,9 @@ sub run { WHERE a.tablespace_name = c.tablespace_name (+) AND a.tablespace_name = b.tablespace_name + AND (b.contents = 'PERMANENT' + OR (b.contents <> 'PERMANENT' + AND a.tablespace_name=(select value from v$parameter where name='undo_tablespace'))) UNION ALL SELECT a.tablespace_name "Tablespace", diff --git a/docs/en/index.rst b/docs/en/index.rst index fe30100a1..e0906521e 100644 --- a/docs/en/index.rst +++ b/docs/en/index.rst @@ -2,8 +2,8 @@ Welcome to Centreon Plugins documentation! ========================================== Centreon Plugins is a common monitoring library and plugins written in -Perl. It is licensed under the terms of the `GNU General Public -License Version 2 `_ as +Perl. It is licensed under the terms of the `Apache License Version 2 +`_ as published by the Free Software Foundation. Contents: diff --git a/docs/en/user/guide.rst b/docs/en/user/guide.rst index 60ff97ab4..edbcdadf1 100644 --- a/docs/en/user/guide.rst +++ b/docs/en/user/guide.rst @@ -614,7 +614,7 @@ Warning if space used > 80% and critical if space used > 90%: Warning if space free < 5G and critical if space free < 2G: :: - $ perl centreon_plugins.pl --plugin=os::windows::snmp::plugin --mode=storage --hostname=xxx.xxx.xxx.xxx --snmp-version=2c --snmp-public=community --verbose --storage='.*' --name --regexp --display-transform-src='(..).*' --display-transform-dst='$1' --warning=5497558138880 --critical=2199023255552 --units='B' --free + $ perl centreon_plugins.pl --plugin=os::windows::snmp::plugin --mode=storage --hostname=xxx.xxx.xxx.xxx --snmp-version=2c --snmp-public=community --verbose --storage='.*' --name --regexp --display-transform-src='(..).*' --display-transform-dst='$1' --warning=5497558138880: --critical=2199023255552: --units='B' --free OK: All storages are ok. | 'free_C:'=97372344320B;0:5497558138880;0:2199023255552;0;135996108800 'free_D:'=97372344320B;0:5497558138880;0:2199023255552;0;135996108800 Storage 'C:' Total: 126.66 GB Used: 35.97 GB (28.40%) Free: 90.69 GB (71.60%) Storage 'D:' Total: 126.66 GB Used: 35.97 GB (28.40%) Free: 90.69 GB (71.60%) diff --git a/docs/fr/index.rst b/docs/fr/index.rst index 252067534..c8b9c4c74 100644 --- a/docs/fr/index.rst +++ b/docs/fr/index.rst @@ -2,8 +2,7 @@ Bienvenue dans la documentation Centreon Plugins! ================================================= Centreon Plugins est un ensemble de bibliothèques et plugins de supervision -écrits en Perl. Cet ensemble est licencié sous les termes de `GNU General Public -License Version 2 ` tel que +écrits en Perl. Cet ensemble est licencié sous les termes de `Apache License Version 2 ` tel que publié par la "Free Software Fondation". Sommaire : diff --git a/docs/fr/user/guide.rst b/docs/fr/user/guide.rst index df9d7da3b..826096647 100644 --- a/docs/fr/user/guide.rst +++ b/docs/fr/user/guide.rst @@ -616,7 +616,7 @@ Dégradé si l'espace utilisé > 80% et critique sur l'espace utilisé > 90% : Dégradé si l'espace disponible < 5G et critique si l'espace disponible < 2G : :: - $ perl centreon_plugins.pl --plugin=os::windows::snmp::plugin --mode=storage --hostname=xxx.xxx.xxx.xxx --snmp-version=2c --snmp-public=community --verbose --storage='.*' --name --regexp --display-transform-src='(..).*' --display-transform-dst='$1' --warning=5497558138880 --critical=2199023255552 --units='B' --free + $ perl centreon_plugins.pl --plugin=os::windows::snmp::plugin --mode=storage --hostname=xxx.xxx.xxx.xxx --snmp-version=2c --snmp-public=community --verbose --storage='.*' --name --regexp --display-transform-src='(..).*' --display-transform-dst='$1' --warning=5497558138880: --critical=2199023255552: --units='B' --free OK: All storages are ok. | 'free_C:'=97372344320B;0:5497558138880;0:2199023255552;0;135996108800 'free_D:'=97372344320B;0:5497558138880;0:2199023255552;0;135996108800 Storage 'C:' Total: 126.66 GB Used: 35.97 GB (28.40%) Free: 90.69 GB (71.60%) Storage 'D:' Total: 126.66 GB Used: 35.97 GB (28.40%) Free: 90.69 GB (71.60%) diff --git a/hardware/pdu/raritan/snmp/mode/components/sensor.pm b/hardware/pdu/raritan/snmp/mode/components/sensor.pm index 8b5a1d7de..b9032d28e 100644 --- a/hardware/pdu/raritan/snmp/mode/components/sensor.pm +++ b/hardware/pdu/raritan/snmp/mode/components/sensor.pm @@ -25,9 +25,9 @@ use warnings; use hardware::pdu::raritan::snmp::mode::components::resources qw($mapping %raritan_type %map_type); sub load { - my (%options) = @_; + my ($self, %options) = @_; - push @{$options{request}}, { oid => $mapping->{$options{type} . '_label'}->{Label}->{oid} }, + push @{$self->{request}}, { oid => $mapping->{$options{type} . '_label'}->{Label}->{oid} }, { oid => $mapping->{$options{type}}->{Unit}->{oid} }, { oid => $mapping->{$options{type}}->{Decimal}->{oid} }, { oid => $mapping->{$options{type}}->{EnabledThresholds}->{oid} }, diff --git a/hardware/pdu/raritan/snmp/mode/inletsensors.pm b/hardware/pdu/raritan/snmp/mode/inletsensors.pm index 7faf3a50b..5c057f615 100644 --- a/hardware/pdu/raritan/snmp/mode/inletsensors.pm +++ b/hardware/pdu/raritan/snmp/mode/inletsensors.pm @@ -20,210 +20,73 @@ package hardware::pdu::raritan::snmp::mode::inletsensors; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; use hardware::pdu::raritan::snmp::mode::components::resources qw($thresholds %raritan_type); +sub set_system { + my ($self, %options) = @_; + + $self->{cb_threshold_numeric_check_section_option} = 'check_numeric_section_option'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = $thresholds; + + $self->{components_path} = 'hardware::pdu::raritan::snmp::mode::components'; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}, return_type => 1); +} + +sub check_numeric_section_option { + my ($self, %options) = @_; + + if (!defined($raritan_type{$options{section}})) { + $self->{output}->add_option_msg(short_msg => "Wrong $options{option_name} option '" . $options{option_value} . "'."); + $self->{output}->option_exit(); + } +} + +sub load_components { + my ($self, %options) = @_; + + my $mod_name = $self->{components_path} . "::sensor"; + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, + error_msg => "Cannot load module '$mod_name'."); + my $func = $mod_name->can('load'); + $func->($self, type => 'inlet'); + + $self->{loaded} = 1; +} + +sub exec_components { + my ($self, %options) = @_; + + my $mod_name = $self->{components_path} . "::sensor"; + my $func = $mod_name->can('check'); + $func->($self, component => $self->{option_results}->{component}, type => 'inlet'); +} + 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 => - { - "filter:s@" => { name => 'filter' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { }); - - $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'; - } - } - - $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 ($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 (!defined($raritan_type{$section})) { - $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 }; - } - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - - my $mod_name = "hardware::pdu::raritan::snmp::mode::components::sensor"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(type => 'inlet', request => $snmp_request); - - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request, return_type => 1); - - $func = $mod_name->can('check'); - $func->($self, component => $self->{option_results}->{component}, type => 'inlet'); - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s sensors are ok [%s].", - $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 sensors are checked.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub check_filter { - 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->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); - return 1; - } - } - } - - return 0; -} - -sub get_severity_numeric { - 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 - - 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; - } - } - - return $status; -} - 1; __END__ diff --git a/hardware/pdu/raritan/snmp/mode/ocprotsensors.pm b/hardware/pdu/raritan/snmp/mode/ocprotsensors.pm index 666aeb569..8bfdf2949 100644 --- a/hardware/pdu/raritan/snmp/mode/ocprotsensors.pm +++ b/hardware/pdu/raritan/snmp/mode/ocprotsensors.pm @@ -20,210 +20,73 @@ package hardware::pdu::raritan::snmp::mode::ocprotsensors; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; use hardware::pdu::raritan::snmp::mode::components::resources qw($thresholds %raritan_type); +sub set_system { + my ($self, %options) = @_; + + $self->{cb_threshold_numeric_check_section_option} = 'check_numeric_section_option'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = $thresholds; + + $self->{components_path} = 'hardware::pdu::raritan::snmp::mode::components'; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}, return_type => 1); +} + +sub check_numeric_section_option { + my ($self, %options) = @_; + + if (!defined($raritan_type{$options{section}})) { + $self->{output}->add_option_msg(short_msg => "Wrong $options{option_name} option '" . $options{option_value} . "'."); + $self->{output}->option_exit(); + } +} + +sub load_components { + my ($self, %options) = @_; + + my $mod_name = $self->{components_path} . "::sensor"; + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, + error_msg => "Cannot load module '$mod_name'."); + my $func = $mod_name->can('load'); + $func->($self, type => 'ocprot'); + + $self->{loaded} = 1; +} + +sub exec_components { + my ($self, %options) = @_; + + my $mod_name = $self->{components_path} . "::sensor"; + my $func = $mod_name->can('check'); + $func->($self, component => $self->{option_results}->{component}, type => 'ocprot'); +} + 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 => - { - "filter:s@" => { name => 'filter' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { }); - - $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'; - } - } - - $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 ($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 (!defined($raritan_type{$section})) { - $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 }; - } - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - - my $mod_name = "hardware::pdu::raritan::snmp::mode::components::sensor"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(type => 'ocprot', request => $snmp_request); - - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request, return_type => 1); - - $func = $mod_name->can('check'); - $func->($self, component => $self->{option_results}->{component}, type => 'ocprot'); - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s sensors are ok [%s].", - $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 sensors are checked.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub check_filter { - 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->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); - return 1; - } - } - } - - return 0; -} - -sub get_severity_numeric { - 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 - - 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; - } - } - - return $status; -} - 1; __END__ diff --git a/hardware/pdu/raritan/snmp/mode/outletsensors.pm b/hardware/pdu/raritan/snmp/mode/outletsensors.pm index b6586f5a6..56b380224 100644 --- a/hardware/pdu/raritan/snmp/mode/outletsensors.pm +++ b/hardware/pdu/raritan/snmp/mode/outletsensors.pm @@ -20,12 +20,60 @@ package hardware::pdu::raritan::snmp::mode::outletsensors; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; use hardware::pdu::raritan::snmp::mode::components::resources qw($thresholds %raritan_type); +sub set_system { + my ($self, %options) = @_; + + $self->{cb_threshold_numeric_check_section_option} = 'check_numeric_section_option'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = $thresholds; + + $self->{components_path} = 'hardware::pdu::raritan::snmp::mode::components'; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}, return_type => 1); +} + +sub check_numeric_section_option { + my ($self, %options) = @_; + + if (!defined($raritan_type{$options{section}})) { + $self->{output}->add_option_msg(short_msg => "Wrong $options{option_name} option '" . $options{option_value} . "'."); + $self->{output}->option_exit(); + } +} + +sub load_components { + my ($self, %options) = @_; + + my $mod_name = $self->{components_path} . "::sensor"; + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, + error_msg => "Cannot load module '$mod_name'."); + my $func = $mod_name->can('load'); + $func->($self, type => 'outlet'); + + $self->{loaded} = 1; +} + +sub exec_components { + my ($self, %options) = @_; + + my $mod_name = $self->{components_path} . "::sensor"; + my $func = $mod_name->can('check'); + $func->($self, component => $self->{option_results}->{component}, type => 'outlet'); +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -33,197 +81,12 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "filter:s@" => { name => 'filter' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { }); - - $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'; - } - } - - $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 ($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 (!defined($raritan_type{$section})) { - $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 }; - } - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - - my $mod_name = "hardware::pdu::raritan::snmp::mode::components::sensor"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(type => 'outlet', request => $snmp_request); - - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request, return_type => 1); - - $func = $mod_name->can('check'); - $func->($self, component => $self->{option_results}->{component}, type => 'outlet'); - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s sensors are ok [%s].", - $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 sensors are checked.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub check_filter { - 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->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); - return 1; - } - } - } - - return 0; -} - -sub get_severity_numeric { - 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 - - 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; - } - } - - return $status; -} - 1; __END__ diff --git a/hardware/pdu/raritan/snmp/plugin.pm b/hardware/pdu/raritan/snmp/plugin.pm index cf9db830a..cef7dfaf8 100644 --- a/hardware/pdu/raritan/snmp/plugin.pm +++ b/hardware/pdu/raritan/snmp/plugin.pm @@ -46,6 +46,6 @@ __END__ =head1 PLUGIN DESCRIPTION -Check Rarian PDU in SNMP. +Check Raritan PDU in SNMP. =cut diff --git a/hardware/server/cisco/ucs/mode/components/blade.pm b/hardware/server/cisco/ucs/mode/components/blade.pm index cb3d3173f..e928ddf72 100644 --- a/hardware/server/cisco/ucs/mode/components/blade.pm +++ b/hardware/server/cisco/ucs/mode/components/blade.pm @@ -22,59 +22,62 @@ package hardware::server::cisco::ucs::mode::components::blade; use strict; use warnings; -use hardware::server::cisco::ucs::mode::components::resources qw($thresholds); +use hardware::server::cisco::ucs::mode::components::resources qw(%mapping_presence %mapping_overall_status); + +# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB' +my $mapping1 = { + cucsComputeBladePresence => { oid => '.1.3.6.1.4.1.9.9.719.1.9.2.1.45', map => \%mapping_presence }, +}; +my $mapping2 = { + cucsComputeBladeOperState => { oid => '.1.3.6.1.4.1.9.9.719.1.9.2.1.42', map => \%mapping_overall_status }, +}; +my $oid_cucsComputeBladeDn = '.1.3.6.1.4.1.9.9.719.1.9.2.1.2'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping1->{cucsComputeBladePresence}->{oid} }, + { oid => $mapping2->{cucsComputeBladeOperState}->{oid} }, { oid => $oid_cucsComputeBladeDn }; +} sub check { my ($self) = @_; - # In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB' $self->{output}->output_add(long_msg => "Checking blades"); $self->{components}->{blade} = {name => 'blades', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'blade')); - - my $oid_cucsComputeBladePresence = '.1.3.6.1.4.1.9.9.719.1.9.2.1.45'; - my $oid_cucsComputeBladeOperState = '.1.3.6.1.4.1.9.9.719.1.9.2.1.42'; - my $oid_cucsComputeBladeDn = '.1.3.6.1.4.1.9.9.719.1.9.2.1.2'; + return if ($self->check_filter(section => 'blade')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cucsComputeBladeDn}})) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + my $blade_dn = $self->{results}->{$oid_cucsComputeBladeDn}->{$oid}; + my $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$mapping1->{cucsComputeBladePresence}->{oid}}, instance => $instance); + my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{cucsComputeBladeOperState}->{oid}}, instance => $instance); - my $result = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_cucsComputeBladePresence }, - { oid => $oid_cucsComputeBladeOperState }, - { oid => $oid_cucsComputeBladeDn }, - ] - ); - foreach my $key ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_cucsComputeBladePresence}})) { - # index - $key =~ /\.(\d+)$/; - my $blade_index = $1; - my $blade_dn = $result->{$oid_cucsComputeBladeDn}->{$oid_cucsComputeBladeDn . '.' . $blade_index}; - my $blade_operstate = defined($result->{$oid_cucsComputeBladeOperState}->{$oid_cucsComputeBladeOperState . '.' . $blade_index}) ? - $result->{$oid_cucsComputeBladeOperState}->{$oid_cucsComputeBladeOperState . '.' . $blade_index} : 0; # unknown - my $blade_presence = defined($result->{$oid_cucsComputeBladePresence}->{$oid_cucsComputeBladePresence . '.' . $blade_index}) ? - $result->{$oid_cucsComputeBladePresence}->{$oid_cucsComputeBladePresence . '.' . $blade_index} : 0; - next if ($self->absent_problem(section => 'blade', instance => $blade_dn)); - next if ($self->check_exclude(section => 'blade', instance => $blade_dn)); + next if ($self->check_filter(section => 'blade', instance => $blade_dn)); - my $exit = $self->get_severity(section => 'blade', threshold => 'presence', value => $blade_presence); + $self->{output}->output_add(long_msg => sprintf("blade '%s' state is '%s' [presence: %s].", + $blade_dn, $result2->{cucsComputeBladeOperState}, + $result->{cucsComputeBladePresence}) + ); + + my $exit = $self->get_severity(section => 'blade.presence', label => 'default.presence', value => $result->{cucsComputeBladePresence}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("blade '%s' presence is: '%s'", - $blade_dn, ${$thresholds->{presence}{$blade_presence}}[0]) + $blade_dn, $result->{cucsComputeBladePresence}) ); next; } $self->{components}->{blade}->{total}++; - - $self->{output}->output_add(long_msg => sprintf("blade '%s' state is '%s' [presence: %s].", - $blade_dn, ${$thresholds->{overall_status}->{$blade_operstate}}[0], - ${$thresholds->{presence}->{$blade_presence}}[0] - )); - $exit = $self->get_severity(section => 'blade', threshold => 'overall_status', value => $blade_operstate); + + $exit = $self->get_severity(section => 'blade.overall_status', label => 'default.overall_status', value => $result2->{cucsComputeBladeOperState}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, - short_msg => sprintf("blade '%s' state is '%s'.", - $blade_dn, ${$thresholds->{overall_status}->{$blade_operstate}}[0] + short_msg => sprintf("blade '%s' state is '%s'", + $blade_dn, $result2->{cucsComputeBladeOperState} ) ); } diff --git a/hardware/server/cisco/ucs/mode/components/chassis.pm b/hardware/server/cisco/ucs/mode/components/chassis.pm index 9fe8cb9c3..b1413df31 100644 --- a/hardware/server/cisco/ucs/mode/components/chassis.pm +++ b/hardware/server/cisco/ucs/mode/components/chassis.pm @@ -22,46 +22,48 @@ package hardware::server::cisco::ucs::mode::components::chassis; use strict; use warnings; -use hardware::server::cisco::ucs::mode::components::resources qw($thresholds); +use hardware::server::cisco::ucs::mode::components::resources qw(%mapping_operability); + +# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB' +# Don't do the 'presence'. Is 'unknown' ??!!! +my $mapping1 = { + cucsEquipmentChassisOperState => { oid => '.1.3.6.1.4.1.9.9.719.1.15.7.1.27', map => \%mapping_operability }, +}; +my $oid_cucsEquipmentChassisDn = '.1.3.6.1.4.1.9.9.719.1.15.7.1.2'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping1->{cucsEquipmentChassisOperState}->{oid} }, + { oid => $oid_cucsEquipmentChassisDn }; +} sub check { my ($self) = @_; - # In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB' $self->{output}->output_add(long_msg => "Checking chassis"); $self->{components}->{chassis} = {name => 'chassis', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'chassis')); - - # Don't do the 'presence'. Is 'unknown' ??!!! - my $oid_cucsEquipmentChassisOperState = '.1.3.6.1.4.1.9.9.719.1.15.7.1.27'; - my $oid_cucsEquipmentChassisDn = '.1.3.6.1.4.1.9.9.719.1.15.7.1.2'; + return if ($self->check_filter(section => 'chassis')); - my $result = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_cucsEquipmentChassisOperState }, - { oid => $oid_cucsEquipmentChassisDn }, - ] - ); - foreach my $key ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_cucsEquipmentChassisOperState}})) { - # index - $key =~ /\.(\d+)$/; - my $chassis_index = $1; - my $chassis_dn = $result->{$oid_cucsEquipmentChassisDn}->{$oid_cucsEquipmentChassisDn . '.' . $chassis_index}; - my $chassis_operstate = defined($result->{$oid_cucsEquipmentChassisOperState}->{$oid_cucsEquipmentChassisOperState . '.' . $chassis_index}) ? - $result->{$oid_cucsEquipmentChassisOperState}->{$oid_cucsEquipmentChassisOperState . '.' . $chassis_index} : 0; # unknown + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cucsEquipmentChassisDn}})) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + my $chassis_dn = $self->{results}->{$oid_cucsEquipmentChassisDn}->{$oid}; + my $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$mapping1->{cucsEquipmentChassisOperState}->{oid}}, instance => $instance); next if ($self->absent_problem(section => 'chassis', instance => $chassis_dn)); - next if ($self->check_exclude(section => 'chassis', instance => $chassis_dn)); + next if ($self->check_filter(section => 'chassis', instance => $chassis_dn)); $self->{components}->{chassis}->{total}++; $self->{output}->output_add(long_msg => sprintf("chassis '%s' state is '%s'.", - $chassis_dn, ${$thresholds->{operability}->{$chassis_operstate}}[0] - )); - my $exit = $self->get_severity(section => 'chassis', threshold => 'operability', value => $chassis_operstate); + $chassis_dn, $result->{cucsEquipmentChassisOperState}) + ); + my $exit = $self->get_severity(section => 'chassis.operability', label => 'default.operability', value => $result->{cucsEquipmentChassisOperState}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, - short_msg => sprintf("chassis '%s' state is '%s'.", - $chassis_dn, ${$thresholds->{operability}->{$chassis_operstate}}[0] + short_msg => sprintf("chassis '%s' state is '%s'", + $chassis_dn, $result->{cucsEquipmentChassisOperState} ) ); } diff --git a/hardware/server/cisco/ucs/mode/components/cpu.pm b/hardware/server/cisco/ucs/mode/components/cpu.pm new file mode 100644 index 000000000..c49b1c074 --- /dev/null +++ b/hardware/server/cisco/ucs/mode/components/cpu.pm @@ -0,0 +1,87 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::server::cisco::ucs::mode::components::cpu; + +use strict; +use warnings; +use hardware::server::cisco::ucs::mode::components::resources qw(%mapping_presence %mapping_operability); + +# In MIB 'CISCO-UNIFIED-COMPUTING-PROCESSOR-MIB' +my $mapping1 = { + cucsProcessorUnitPresence => { oid => '.1.3.6.1.4.1.9.9.719.1.41.9.1.13', map => \%mapping_presence }, +}; +my $mapping2 = { + cucsProcessorUnitOperState => { oid => '.1.3.6.1.4.1.9.9.719.1.41.9.1.9', map => \%mapping_operability }, +}; +my $oid_cucsProcessorUnitDn = '.1.3.6.1.4.1.9.9.719.1.41.9.1.2'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping1->{cucsProcessorUnitPresence}->{oid} }, + { oid => $mapping2->{cucsProcessorUnitOperState}->{oid} }, { oid => $oid_cucsProcessorUnitDn }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking cpus"); + $self->{components}->{cpu} = {name => 'cpus', total => 0, skip => 0}; + return if ($self->check_filter(section => 'cpu')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cucsProcessorUnitDn}})) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + my $cpu_dn = $self->{results}->{$oid_cucsProcessorUnitDn}->{$oid}; + my $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$mapping1->{cucsProcessorUnitPresence}->{oid}}, instance => $instance); + my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{cucsProcessorUnitOperState}->{oid}}, instance => $instance); + + next if ($self->absent_problem(section => 'cpu', instance => $cpu_dn)); + next if ($self->check_filter(section => 'cpu', instance => $cpu_dn)); + + $self->{output}->output_add(long_msg => sprintf("cpu '%s' state is '%s' [presence: %s].", + $cpu_dn, $result2->{cucsProcessorUnitOperState}, + $result->{cucsProcessorUnitPresence}) + ); + + my $exit = $self->get_severity(section => 'cpu.presence', label => 'default.presence', value => $result->{cucsProcessorUnitPresence}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("cpu '%s' presence is: '%s'", + $cpu_dn, $result->{cucsProcessorUnitPresence}) + ); + next; + } + + $self->{components}->{cpu}->{total}++; + + $exit = $self->get_severity(section => 'cpu.operability', label => 'default.operability', value => $result2->{cucsProcessorUnitOperState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("cpu '%s' state is '%s'", + $cpu_dn, $result2->{cucsProcessorUnitOperState} + ) + ); + } + } +} + +1; \ No newline at end of file diff --git a/hardware/server/cisco/ucs/mode/components/fan.pm b/hardware/server/cisco/ucs/mode/components/fan.pm index 9c7ddd465..169341beb 100644 --- a/hardware/server/cisco/ucs/mode/components/fan.pm +++ b/hardware/server/cisco/ucs/mode/components/fan.pm @@ -22,58 +22,62 @@ package hardware::server::cisco::ucs::mode::components::fan; use strict; use warnings; -use hardware::server::cisco::ucs::mode::components::resources qw($thresholds); +use hardware::server::cisco::ucs::mode::components::resources qw(%mapping_presence %mapping_operability); + +# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB' +my $mapping1 = { + cucsEquipmentFanPresence => { oid => '.1.3.6.1.4.1.9.9.719.1.15.12.1.13', map => \%mapping_presence }, +}; +my $mapping2 = { + cucsEquipmentFanOperState => { oid => '.1.3.6.1.4.1.9.9.719.1.15.12.1.9', map => \%mapping_operability }, +}; +my $oid_cucsEquipmentFanDn = '.1.3.6.1.4.1.9.9.719.1.15.12.1.2'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping1->{cucsEquipmentFanPresence}->{oid} }, + { oid => $mapping2->{cucsEquipmentFanOperState}->{oid} }, { oid => $oid_cucsEquipmentFanDn }; +} sub check { my ($self) = @_; - # In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB' $self->{output}->output_add(long_msg => "Checking fans"); $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fan')); - - my $oid_cucsEquipmentFanPresence = '.1.3.6.1.4.1.9.9.719.1.15.12.1.13'; - my $oid_cucsEquipmentFanOperState = '.1.3.6.1.4.1.9.9.719.1.15.12.1.9'; - my $oid_cucsEquipmentFanDn = '.1.3.6.1.4.1.9.9.719.1.15.12.1.2'; + return if ($self->check_filter(section => 'fan')); - my $result = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_cucsEquipmentFanPresence }, - { oid => $oid_cucsEquipmentFanOperState }, - { oid => $oid_cucsEquipmentFanDn }, - ] - ); - foreach my $key ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_cucsEquipmentFanPresence}})) { - # index - $key =~ /\.(\d+)$/; - my $fan_index = $1; - my $fan_dn = $result->{$oid_cucsEquipmentFanDn}->{$oid_cucsEquipmentFanDn . '.' . $fan_index}; - my $fan_operstate = defined($result->{$oid_cucsEquipmentFanOperState}->{$oid_cucsEquipmentFanOperState . '.' . $fan_index}) ? - $result->{$oid_cucsEquipmentFanOperState}->{$oid_cucsEquipmentFanOperState . '.' . $fan_index} : 0; # unknown - my $fan_presence = defined($result->{$oid_cucsEquipmentFanPresence}->{$oid_cucsEquipmentFanPresence . '.' . $fan_index}) ? - $result->{$oid_cucsEquipmentFanPresence}->{$oid_cucsEquipmentFanPresence . '.' . $fan_index} : 0; + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cucsEquipmentFanDn}})) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + my $fan_dn = $self->{results}->{$oid_cucsEquipmentFanDn}->{$oid}; + my $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$mapping1->{cucsEquipmentFanPresence}->{oid}}, instance => $instance); + my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{cucsEquipmentFanOperState}->{oid}}, instance => $instance); next if ($self->absent_problem(section => 'fan', instance => $fan_dn)); - next if ($self->check_exclude(section => 'fan', instance => $fan_dn)); + next if ($self->check_filter(section => 'fan', instance => $fan_dn)); - my $exit = $self->get_severity(section => 'fan', threshold => 'presence', value => $fan_presence); + $self->{output}->output_add(long_msg => sprintf("fan '%s' state is '%s' [presence: %s].", + $fan_dn, $result2->{cucsEquipmentFanOperState}, + $result->{cucsEquipmentFanPresence}) + ); + + my $exit = $self->get_severity(section => 'fan.presence', label => 'default.presence', value => $result->{cucsEquipmentFanPresence}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("fan '%s' presence is: '%s'", - $fan_dn, ${$thresholds->{presence}->{$fan_presence}}[0]) + $fan_dn, $result->{cucsEquipmentFanPresence}) ); next; } - $self->{components}->{fan}->{total}++; - $self->{output}->output_add(long_msg => sprintf("fan '%s' state is '%s' [presence: %s].", - $fan_dn, ${$thresholds->{operability}->{$fan_operstate}}[0], - ${$thresholds->{presence}->{$fan_presence}}[0] - )); - $exit = $self->get_severity(section => 'fan', threshold => 'operability', value => $fan_operstate); + $self->{components}->{fan}->{total}++; + + $exit = $self->get_severity(section => 'fan.operability', label => 'default.operability', value => $result2->{cucsEquipmentFanOperState}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, - short_msg => sprintf("fan '%s' state is '%s'.", - $fan_dn, ${$thresholds->{operability}->{$fan_operstate}}[0] + short_msg => sprintf("fan '%s' state is '%s'", + $fan_dn, $result2->{cucsEquipmentFanOperState} ) ); } diff --git a/hardware/server/cisco/ucs/mode/components/fex.pm b/hardware/server/cisco/ucs/mode/components/fex.pm index 3bc0fb6b5..a6845cc79 100644 --- a/hardware/server/cisco/ucs/mode/components/fex.pm +++ b/hardware/server/cisco/ucs/mode/components/fex.pm @@ -22,59 +22,62 @@ package hardware::server::cisco::ucs::mode::components::fex; use strict; use warnings; -use hardware::server::cisco::ucs::mode::components::resources qw($thresholds); +use hardware::server::cisco::ucs::mode::components::resources qw(%mapping_presence %mapping_operability); + +# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB' +my $mapping1 = { + cucsEquipmentFexPresence => { oid => '.1.3.6.1.4.1.9.9.719.1.15.19.1.24', map => \%mapping_presence }, +}; +my $mapping2 = { + cucsEquipmentFexOperState => { oid => '.1.3.6.1.4.1.9.9.719.1.15.19.1.21', map => \%mapping_operability }, +}; +my $oid_cucsEquipmentFexDn = '.1.3.6.1.4.1.9.9.719.1.15.19.1.2'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping1->{cucsEquipmentFexPresence}->{oid} }, + { oid => $mapping2->{cucsEquipmentFexOperState}->{oid} }, { oid => $oid_cucsEquipmentFexDn }; +} sub check { my ($self) = @_; - # In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB' $self->{output}->output_add(long_msg => "Checking fabric extenders"); $self->{components}->{fex} = {name => 'fabric extenders', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fex')); - - my $oid_cucsEquipmentFexDn = '.1.3.6.1.4.1.9.9.719.1.15.19.1.2'; - my $oid_cucsEquipmentFexOperState = '.1.3.6.1.4.1.9.9.719.1.15.19.1.21'; - my $oid_cucsEquipmentFexPresence = '.1.3.6.1.4.1.9.9.719.1.15.19.1.24'; + return if ($self->check_filter(section => 'fex')); - my $result = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_cucsEquipmentFexDn }, - { oid => $oid_cucsEquipmentFexOperState }, - { oid => $oid_cucsEquipmentFexPresence }, - ] - ); - foreach my $key ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_cucsEquipmentFexDn}})) { - # index - $key =~ /\.(\d+)$/; - my $fex_index = $1; - my $fex_dn = $result->{$oid_cucsEquipmentFexDn}->{$oid_cucsEquipmentFexDn . '.' . $fex_index}; - my $fex_operstate = defined($result->{$oid_cucsEquipmentFexOperState}->{$oid_cucsEquipmentFexOperState . '.' . $fex_index}) ? - $result->{$oid_cucsEquipmentFexOperState}->{$oid_cucsEquipmentFexOperState . '.' . $fex_index} : 0; # unknown - my $fex_presence = defined($result->{$oid_cucsEquipmentFexPresence}->{$oid_cucsEquipmentFexPresence . '.' . $fex_index}) ? - $result->{$oid_cucsEquipmentFexPresence}->{$oid_cucsEquipmentFexPresence . '.' . $fex_index} : 0; + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cucsEquipmentFexDn}})) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + my $fex_dn = $self->{results}->{$oid_cucsEquipmentFexDn}->{$oid}; + my $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$mapping1->{cucsEquipmentFexPresence}->{oid}}, instance => $instance); + my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{cucsEquipmentFexOperState}->{oid}}, instance => $instance); next if ($self->absent_problem(section => 'fex', instance => $fex_dn)); - next if ($self->check_exclude(section => 'fex', instance => $fex_dn)); + next if ($self->check_filter(section => 'fex', instance => $fex_dn)); - my $exit = $self->get_severity(section => 'fex', threshold => 'presence', value => $fex_presence); + $self->{output}->output_add(long_msg => sprintf("Fabric extender '%s' state is '%s' [presence: %s].", + $fex_dn, $result2->{cucsEquipmentFexOperState}, + $result->{cucsEquipmentFexPresence}) + ); + + my $exit = $self->get_severity(section => 'fex.presence', label => 'default.presence', value => $result->{cucsEquipmentFexPresence}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fabric extender '%s' presence is: '%s'", - $fex_dn, ${$thresholds->{presence}->{$fex_presence}}[0]) + $fex_dn, $result->{cucsEquipmentFexPresence}) ); next; } $self->{components}->{fex}->{total}++; - - $self->{output}->output_add(long_msg => sprintf("Fabric extender '%s' state is '%s' [presence: %s].", - $fex_dn, ${$thresholds->{operability}->{$fex_operstate}}[0], - ${$thresholds->{presence}->{$fex_presence}}[0] - )); - $exit = $self->get_severity(section => 'fex', threshold => 'operability', value => $fex_operstate); + + $exit = $self->get_severity(section => 'fex.presence', label => 'default.operability', value => $result2->{cucsEquipmentFexOperState}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Fabric extender '%s' state is '%s'.", - $fex_dn, ${$thresholds->{operability}->{$fex_operstate}}[0] + $fex_dn, $result2->{cucsEquipmentFexOperState} ) ); } diff --git a/hardware/server/cisco/ucs/mode/components/iocard.pm b/hardware/server/cisco/ucs/mode/components/iocard.pm index 9b6bb7145..b3808608f 100644 --- a/hardware/server/cisco/ucs/mode/components/iocard.pm +++ b/hardware/server/cisco/ucs/mode/components/iocard.pm @@ -22,7 +22,23 @@ package hardware::server::cisco::ucs::mode::components::iocard; use strict; use warnings; -use hardware::server::cisco::ucs::mode::components::resources qw($thresholds); +use hardware::server::cisco::ucs::mode::components::resources qw(%mapping_presence %mapping_operability); + +# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB' +my $mapping1 = { + cucsEquipmentIOCardPresence => { oid => '.1.3.6.1.4.1.9.9.719.1.15.30.1.31', map => \%mapping_presence }, +}; +my $mapping2 = { + cucsEquipmentIOCardOperState => { oid => '.1.3.6.1.4.1.9.9.719.1.15.30.1.25', map => \%mapping_operability }, +}; +my $oid_cucsEquipmentIOCardDn = '.1.3.6.1.4.1.9.9.719.1.15.30.1.2'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping1->{cucsEquipmentIOCardPresence}->{oid} }, + { oid => $mapping2->{cucsEquipmentIOCardOperState}->{oid} }, { oid => $oid_cucsEquipmentIOCardDn }; +} sub check { my ($self) = @_; @@ -30,51 +46,39 @@ sub check { # In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB' $self->{output}->output_add(long_msg => "Checking io cards"); $self->{components}->{iocard} = {name => 'io cards', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'iocard')); - - my $oid_cucsEquipmentIOCardPresence = '.1.3.6.1.4.1.9.9.719.1.15.30.1.31'; - my $oid_cucsEquipmentIOCardOperState = '.1.3.6.1.4.1.9.9.719.1.15.30.1.25'; - my $oid_cucsEquipmentIOCardDn = '.1.3.6.1.4.1.9.9.719.1.15.30.1.2'; + return if ($self->check_filter(section => 'iocard')); - my $result = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_cucsEquipmentIOCardPresence }, - { oid => $oid_cucsEquipmentIOCardOperState }, - { oid => $oid_cucsEquipmentIOCardDn }, - ] - ); - foreach my $key ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_cucsEquipmentIOCardPresence}})) { - # index - $key =~ /\.(\d+)$/; - my $iocard_index = $1; - my $iocard_dn = $result->{$oid_cucsEquipmentIOCardDn}->{$oid_cucsEquipmentIOCardDn . '.' . $iocard_index}; - my $iocard_operstate = defined($result->{$oid_cucsEquipmentIOCardOperState}->{$oid_cucsEquipmentIOCardOperState . '.' . $iocard_index}) ? - $result->{$oid_cucsEquipmentIOCardOperState}->{$oid_cucsEquipmentIOCardOperState . '.' . $iocard_index} : 0; # unknown - my $iocard_presence = defined($result->{$oid_cucsEquipmentIOCardPresence}->{$oid_cucsEquipmentIOCardPresence . '.' . $iocard_index}) ? - $result->{$oid_cucsEquipmentIOCardPresence}->{$oid_cucsEquipmentIOCardPresence . '.' . $iocard_index} : 0; + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cucsEquipmentIOCardDn}})) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + my $iocard_dn = $self->{results}->{$oid_cucsEquipmentIOCardDn}->{$oid}; + my $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$mapping1->{cucsEquipmentIOCardPresence}->{oid}}, instance => $instance); + my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{cucsEquipmentIOCardOperState}->{oid}}, instance => $instance); next if ($self->absent_problem(section => 'iocard', instance => $iocard_dn)); - next if ($self->check_exclude(section => 'iocard', instance => $iocard_dn)); + next if ($self->check_filter(section => 'iocard', instance => $iocard_dn)); - my $exit = $self->get_severity(section => 'iocard', threshold => 'presence', value => $iocard_presence); + $self->{output}->output_add(long_msg => sprintf("IO cards '%s' state is '%s' [presence: %s].", + $iocard_dn, $result2->{cucsEquipmentIOCardOperState}, + $result->{cucsEquipmentIOCardPresence}) + ); + + my $exit = $self->get_severity(section => 'iocard.presence', label => 'default.presence', value => $result->{cucsEquipmentIOCardPresence}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("IO cards '%s' presence is: '%s'", - $iocard_dn, ${$thresholds->{presence}->{$iocard_presence}}[0]) + $iocard_dn, $result->{cucsEquipmentIOCardPresence}) ); next; } $self->{components}->{iocard}->{total}++; - $self->{output}->output_add(long_msg => sprintf("IO cards '%s' state is '%s' [presence: %s].", - $iocard_dn, ${$thresholds->{operability}->{$iocard_operstate}}[0], - ${$thresholds->{presence}->{$iocard_presence}}[0] - )); - $exit = $self->get_severity(section => 'iocard', threshold => 'operability', value => $iocard_operstate); + $exit = $self->get_severity(section => 'default.operability', label => 'iocard.operability', value => $result2->{cucsEquipmentIOCardOperState}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("IO cards '%s' state is '%s'.", - $iocard_dn, ${$thresholds->{operability}->{$iocard_operstate}}[0] + $iocard_dn, $result2->{cucsEquipmentIOCardOperState} ) ); } diff --git a/hardware/server/cisco/ucs/mode/components/localdisk.pm b/hardware/server/cisco/ucs/mode/components/localdisk.pm new file mode 100644 index 000000000..35f7c8306 --- /dev/null +++ b/hardware/server/cisco/ucs/mode/components/localdisk.pm @@ -0,0 +1,87 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::server::cisco::ucs::mode::components::localdisk; + +use strict; +use warnings; +use hardware::server::cisco::ucs::mode::components::resources qw(%mapping_presence %mapping_operability); + +# In MIB 'CISCO-UNIFIED-COMPUTING-STORAGE-MIB' +my $mapping1 = { + cucsStorageLocalDiskPresence => { oid => '.1.3.6.1.4.1.9.9.719.1.45.4.1.10', map => \%mapping_presence }, +}; +my $mapping2 = { + cucsStorageLocalDiskOperability => { oid => '.1.3.6.1.4.1.9.9.719.1.45.4.1.9', map => \%mapping_operability }, +}; +my $oid_cucsStorageLocalDiskDn = '.1.3.6.1.4.1.9.9.719.1.45.4.1.2'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping1->{cucsStorageLocalDiskPresence}->{oid} }, + { oid => $mapping2->{cucsStorageLocalDiskOperability}->{oid} }, { oid => $oid_cucsStorageLocalDiskDn }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking local disks"); + $self->{components}->{localdisk} = {name => 'local disks', total => 0, skip => 0}; + return if ($self->check_filter(section => 'localdisk')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cucsStorageLocalDiskDn}})) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + my $localdisk_dn = $self->{results}->{$oid_cucsStorageLocalDiskDn}->{$oid}; + my $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$mapping1->{cucsStorageLocalDiskPresence}->{oid}}, instance => $instance); + my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{cucsStorageLocalDiskOperability}->{oid}}, instance => $instance); + + next if ($self->absent_problem(section => 'localdisk', instance => $localdisk_dn)); + next if ($self->check_filter(section => 'localdisk', instance => $localdisk_dn)); + + $self->{output}->output_add(long_msg => sprintf("local disk '%s' state is '%s' [presence: %s].", + $localdisk_dn, $result2->{cucsStorageLocalDiskOperability}, + $result->{cucsStorageLocalDiskPresence}) + ); + + my $exit = $self->get_severity(section => 'localdisk.presence', label => 'default.presence', value => $result->{cucsStorageLocalDiskPresence}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("local disk '%s' presence is: '%s'", + $localdisk_dn, $result->{cucsStorageLocalDiskPresence}) + ); + next; + } + + $self->{components}->{localdisk}->{total}++; + + $exit = $self->get_severity(section => 'localdisk.operability', label => 'default.operability', value => $result2->{cucsStorageLocalDiskOperability}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("local disk '%s' state is '%s'", + $localdisk_dn, $result2->{cucsStorageLocalDiskOperability} + ) + ); + } + } +} + +1; \ No newline at end of file diff --git a/hardware/server/cisco/ucs/mode/components/memory.pm b/hardware/server/cisco/ucs/mode/components/memory.pm new file mode 100644 index 000000000..d79451b60 --- /dev/null +++ b/hardware/server/cisco/ucs/mode/components/memory.pm @@ -0,0 +1,88 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::server::cisco::ucs::mode::components::memory; + +use strict; +use warnings; +use hardware::server::cisco::ucs::mode::components::resources qw(%mapping_presence %mapping_operability); + +# In MIB 'CISCO-UNIFIED-COMPUTING-MEMORY-MIB' +my $mapping1 = { + cucsMemoryUnitPresence => { oid => '.1.3.6.1.4.1.9.9.719.1.30.11.1.17', map => \%mapping_presence }, +}; +my $mapping2 = { + cucsMemoryUnitOperState => { oid => '.1.3.6.1.4.1.9.9.719.1.30.11.1.13', map => \%mapping_operability }, +}; +my $oid_cucsMemoryUnitDn = '.1.3.6.1.4.1.9.9.719.1.30.11.1.2'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping1->{cucsMemoryUnitPresence}->{oid} }, + { oid => $mapping2->{cucsMemoryUnitOperState}->{oid} }, { oid => $oid_cucsMemoryUnitDn }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking memories"); + $self->{components}->{memory} = {name => 'memories', total => 0, skip => 0}; + return if ($self->check_filter(section => 'memory')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cucsMemoryUnitDn}})) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + my $memory_dn = $self->{results}->{$oid_cucsMemoryUnitDn}->{$oid}; + $memory_dn =~ s/\n$//ms; + my $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$mapping1->{cucsMemoryUnitPresence}->{oid}}, instance => $instance); + my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{cucsMemoryUnitOperState}->{oid}}, instance => $instance); + + next if ($self->absent_problem(section => 'memory', instance => $memory_dn)); + next if ($self->check_filter(section => 'memory', instance => $memory_dn)); + + $self->{output}->output_add(long_msg => sprintf("memory '%s' state is '%s' [presence: %s].", + $memory_dn, $result2->{cucsMemoryUnitOperState}, + $result->{cucsMemoryUnitPresence}) + ); + + my $exit = $self->get_severity(section => 'memory.presence', label => 'default.presence', value => $result->{cucsMemoryUnitPresence}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("memory '%s' presence is: '%s'", + $memory_dn, $result->{cucsMemoryUnitPresence}) + ); + next; + } + + $self->{components}->{memory}->{total}++; + + $exit = $self->get_severity(section => 'memory.operability', label => 'default.operability', value => $result2->{cucsMemoryUnitOperState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("memory '%s' state is '%s'", + $memory_dn, $result2->{cucsMemoryUnitOperState} + ) + ); + } + } +} + +1; \ No newline at end of file diff --git a/hardware/server/cisco/ucs/mode/components/psu.pm b/hardware/server/cisco/ucs/mode/components/psu.pm index b155968f5..5180e6ae7 100644 --- a/hardware/server/cisco/ucs/mode/components/psu.pm +++ b/hardware/server/cisco/ucs/mode/components/psu.pm @@ -22,7 +22,23 @@ package hardware::server::cisco::ucs::mode::components::psu; use strict; use warnings; -use hardware::server::cisco::ucs::mode::components::resources qw($thresholds); +use hardware::server::cisco::ucs::mode::components::resources qw(%mapping_presence %mapping_operability); + +# In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB' +my $mapping1 = { + cucsEquipmentPsuPresence => { oid => '.1.3.6.1.4.1.9.9.719.1.15.56.1.11', map => \%mapping_presence }, +}; +my $mapping2 = { + cucsEquipmentPsuOperState => { oid => '.1.3.6.1.4.1.9.9.719.1.15.56.1.7', map => \%mapping_operability }, +}; +my $oid_cucsEquipmentPsuDn = '.1.3.6.1.4.1.9.9.719.1.15.56.1.2'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping1->{cucsEquipmentPsuPresence}->{oid} }, + { oid => $mapping2->{cucsEquipmentPsuOperState}->{oid} }, { oid => $oid_cucsEquipmentPsuDn }; +} sub check { my ($self) = @_; @@ -30,51 +46,39 @@ sub check { # In MIB 'CISCO-UNIFIED-COMPUTING-EQUIPMENT-MIB' $self->{output}->output_add(long_msg => "Checking power supplies"); $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'psu')); + return if ($self->check_filter(section => 'psu')); - my $oid_cucsEquipmentPsuPresence = '.1.3.6.1.4.1.9.9.719.1.15.56.1.11'; - my $oid_cucsEquipmentPsuOperState = '.1.3.6.1.4.1.9.9.719.1.15.56.1.7'; - my $oid_cucsEquipmentPsuDn = '.1.3.6.1.4.1.9.9.719.1.15.56.1.2'; - - my $result = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_cucsEquipmentPsuPresence }, - { oid => $oid_cucsEquipmentPsuOperState }, - { oid => $oid_cucsEquipmentPsuDn }, - ] - ); - foreach my $key ($self->{snmp}->oid_lex_sort(keys %{$result->{$oid_cucsEquipmentPsuPresence}})) { - # index - $key =~ /\.(\d+)$/; - my $psu_index = $1; - my $psu_dn = $result->{$oid_cucsEquipmentPsuDn}->{$oid_cucsEquipmentPsuDn . '.' . $psu_index}; - my $psu_operstate = defined($result->{$oid_cucsEquipmentPsuOperState}->{$oid_cucsEquipmentPsuOperState . '.' . $psu_index}) ? - $result->{$oid_cucsEquipmentPsuOperState}->{$oid_cucsEquipmentPsuOperState . '.' . $psu_index} : 0; # unknown - my $psu_presence = defined($result->{$oid_cucsEquipmentPsuPresence}->{$oid_cucsEquipmentPsuPresence . '.' . $psu_index}) ? - $result->{$oid_cucsEquipmentPsuPresence}->{$oid_cucsEquipmentPsuPresence . '.' . $psu_index} : 0; + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_cucsEquipmentPsuDn}})) { + $oid =~ /\.(\d+)$/; + my $instance = $1; + my $psu_dn = $self->{results}->{$oid_cucsEquipmentPsuDn}->{$oid}; + my $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$mapping1->{cucsEquipmentPsuPresence}->{oid}}, instance => $instance); + my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{cucsEquipmentPsuOperState}->{oid}}, instance => $instance); next if ($self->absent_problem(section => 'psu', instance => $psu_dn)); - next if ($self->check_exclude(section => 'psu', instance => $psu_dn)); + next if ($self->check_filter(section => 'psu', instance => $psu_dn)); - my $exit = $self->get_severity(section => 'psu', threshold => 'presence', value => $psu_presence); + $self->{output}->output_add(long_msg => sprintf("power supply '%s' state is '%s' [presence: %s].", + $psu_dn, $result2->{cucsEquipmentPsuOperState}, + $result->{cucsEquipmentPsuPresence}) + ); + + my $exit = $self->get_severity(section => 'psu.presence', label => 'default.presence', value => $result->{cucsEquipmentPsuPresence}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("power supply '%s' presence is: '%s'", - $psu_dn, ${$thresholds->{presence}->{$psu_presence}}[0]) + $psu_dn, $result->{cucsEquipmentPsuPresence}) ); next; } $self->{components}->{psu}->{total}++; - $self->{output}->output_add(long_msg => sprintf("power supply '%s' state is '%s' [presence: %s].", - $psu_dn, ${$thresholds->{operability}->{$psu_operstate}}[0], - ${$thresholds->{presence}->{$psu_presence}}[0] - )); - $exit = $self->get_severity(section => 'psu', threshold => 'operability', value => $psu_operstate); + $exit = $self->get_severity(section => 'psu.operability', label => 'default.operability', value => $result2->{cucsEquipmentPsuOperState}); 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'.", - $psu_dn, ${$thresholds->{operability}->{$psu_operstate}}[0] + $psu_dn, $result2->{cucsEquipmentPsuOperState} ) ); } diff --git a/hardware/server/cisco/ucs/mode/components/resources.pm b/hardware/server/cisco/ucs/mode/components/resources.pm index f9987cdc6..d8beeb34a 100644 --- a/hardware/server/cisco/ucs/mode/components/resources.pm +++ b/hardware/server/cisco/ucs/mode/components/resources.pm @@ -25,85 +25,197 @@ use warnings; use Exporter; our $thresholds; +our %mapping_presence; +our %mapping_operability; +our %mapping_overall_status; +our %mapping_drive_status; our @ISA = qw(Exporter); -our @EXPORT_OK = qw($thresholds); +our @EXPORT_OK = qw($thresholds %mapping_presence %mapping_operability %mapping_overall_status %mapping_drive_status); + +%mapping_drive_status = ( + 0 => 'unknown', + 1 => 'online', + 2 => 'unconfiguredGood', + 3 => 'globalHotSpare', + 4 => 'dedicatedHotSpare', + 5 => 'jbod', + 6 => 'offline', + 7 => 'rebuilding', + 8 => 'copyback', + 9 => 'failed', + 10 => 'unconfiguredBad', + 11 => 'predictiveFailure', + 12 => 'disabledForRemoval', + 13 => 'foreignConfiguration', +); +%mapping_presence = ( + 0 => 'unknown', + 1 => 'empty', + 10 => 'equipped', + 11 => 'missing', + 12 => 'mismatch', + 13 => 'equippedNotPrimary', + 20 => 'equippedIdentityUnestablishable', + 21 => 'mismatchIdentityUnestablishable', + 30 => 'inaccessible', + 40 => 'unauthorized', + 100 => 'notSupported', +); +%mapping_operability = ( + 0 => 'unknown', + 1 => 'operable', + 2 => 'inoperable', + 3 => 'degraded', + 4 => 'poweredOff', + 5 => 'powerProblem', + 6 => 'removed', + 7 => 'voltageProblem', + 8 => 'thermalProblem', + 9 => 'performanceProblem', + 10 => 'accessibilityProblem', + 11 => 'identityUnestablishable', + 12 => 'biosPostTimeout', + 13 => 'disabled', + 51 => 'fabricConnProblem', + 52 => 'fabricUnsupportedConn', + 81 => 'config', + 82 => 'equipmentProblem', + 83 => 'decomissioning', + 84 => 'chassisLimitExceeded', + 100 => 'notSupported', + 101 => 'discovery', + 102 => 'discoveryFailed', + 104 => 'postFailure', + 105 => 'upgradeProblem', + 106 => 'peerCommProblem', + 107 => 'autoUpgrade', + 108 => 'linkActivateBlocked', +); +%mapping_overall_status = ( + 0 => 'indeterminate', + 1 => 'unassociated', + 10 => 'ok', + 11 => 'discovery', + 12 => 'config', + 13 => 'unconfig', + 14 => 'power-off', + 15 => 'restart', + 20 => 'maintenance', + 21 => 'test', + 29 => 'compute-mismatch', + 30 => 'compute-failed', + 31 => 'degraded', + 32 => 'discovery-failed', + 33 => 'config-failure', + 34 => 'unconfig-failed', + 35 => 'test-failed', + 36 => 'maintenance-failed', + 40 => 'removed', + 41 => 'disabled', + 50 => 'inaccessible', + 60 => 'thermal-problem', + 61 => 'power-problem', + 62 => 'voltage-problem', + 63 => 'inoperable', + 101 => 'decommissioning', + 201 => 'bios-restore', + 202 => 'cmos-reset', + 203 => 'diagnostics', + 204 => 'diagnostic-failed', +); $thresholds = { - presence => { - 0 => ['unknown', 'UNKNOWN'], - 1 => ['empty', 'OK'], - 10 => ['equipped', 'OK'], - 11 => ['missing', 'WARNING'], - 12 => ['mismatch', 'WARNING'], - 13 => ['equippedNotPrimary', 'OK'], - 20 => ['equippedIdentityUnestablishable', 'WARNING'], - 21 => ['mismatchIdentityUnestablishable', 'WARNING'], - 30 => ['inaccessible', 'UNKNOWN'], - 40 => ['unauthorized', 'UNKNOWN'], - 100 => ['notSupported', 'WARNING'], - }, - operability => { - 0 => ['unknown', 'UNKNOWN'], - 1 => ['operable', 'OK'], - 2 => ['inoperable', 'CRITICAL'], - 3 => ['degraded', 'WARNING'], - 4 => ['poweredOff', 'WARNING'], - 5 => ['powerProblem', 'CRITICAL'], - 6 => ['removed', 'WARNING'], - 7 => ['voltageProblem', 'CRITICAL'], - 8 => ['thermalProblem', 'CRITICAL'], - 9 => ['performanceProblem', 'CRITICAL'], - 10 => ['accessibilityProblem', 'WARNING'], - 11 => ['identityUnestablishable', 'WARNING'], - 12 => ['biosPostTimeout', 'WARNING'], - 13 => ['disabled', 'OK'], - 51 => ['fabricConnProblem', 'WARNING'], - 52 => ['fabricUnsupportedConn', 'WARNING'], - 81 => ['config', 'OK'], - 82 => ['equipmentProblem', 'CRITICAL'], - 83 => ['decomissioning', 'WARNING'], - 84 => ['chassisLimitExceeded', 'WARNING'], - 100 => ['notSupported', 'WARNING'], - 101 => ['discovery', 'OK'], - 102 => ['discoveryFailed', 'WARNING'], - 104 => ['postFailure', 'WARNING'], - 105 => ['upgradeProblem', 'WARNING'], - 106 => ['peerCommProblem', 'WARNING'], - 107 => ['autoUpgrade', 'OK'], - }, - overall_status => { - 0 => ['indeterminate', 'UNKNOWN'], - 1 => ['unassociated', 'OK'], - 10 => ['ok', 'OK'], - 11 => ['discovery', 'OK'], - 12 => ['config', 'OK'], - 13 => ['unconfig', 'OK'], - 14 => ['power-off', 'WARNING'], - 15 => ['restart', 'WARNING'], - 20 => ['maintenance', 'OK'], - 21 => ['test', 'OK'], - 29 => ['compute-mismatch', 'WARNING'], - 30 => ['compute-failed', 'WARNING'], - 31 => ['degraded', 'WARNING'], - 32 => ['discovery-failed', 'WARNING'], - 33 => ['config-failure', 'WARNING'], - 34 => ['unconfig-failed', 'WARNING'], - 35 => ['test-failed', 'WARNING'], - 36 => ['maintenance-failed', 'WARNING'], - 40 => ['removed', 'WARNING'], - 41 => ['disabled', 'OK'], - 50 => ['inaccessible', 'WARNING'], - 60 => ['thermal-problem', 'CRITICAL'], - 61 => ['power-problem', 'CRITICAL'], - 62 => ['voltage-problem', 'CRITICAL'], - 63 => ['inoperable', 'CRITICAL'], - 101 => ['decommissioning', 'WARNING'], - 201 => ['bios-restore', 'WARNING'], - 202 => ['cmos-reset', 'WARNING'], - 203 => ['diagnostics', 'OK'], - 204 => ['diagnostic-failed', 'WARNING'], - }, + 'default.drivestatus' => [ + ['unknown', 'UNKNOWN'], + ['online', 'OK'], + ['unconfiguredGood', 'OK'], + ['globalHotSpare', 'OK'], + ['dedicatedHotSpare', 'OK'], + ['jbod', 'OK'], + ['offline', 'OK'], + ['rebuilding', 'WARNING'], + ['copyback', 'OK'], + ['failed', 'CRITICAL'], + ['unconfiguredBad', 'CRITICAL'], + ['predictiveFailure', 'WARNING'], + ['disabledForRemoval', 'OK'], + ['foreignConfiguration', 'OK'], + ], + 'default.presence' => [ + ['unknown', 'UNKNOWN'], + ['empty', 'OK'], + ['equipped', 'OK'], + ['missing', 'WARNING'], + ['mismatch', 'WARNING'], + ['equippedNotPrimary', 'OK'], + ['equippedIdentityUnestablishable', 'WARNING'], + ['mismatchIdentityUnestablishable', 'WARNING'], + ['inaccessible', 'UNKNOWN'], + ['unauthorized', 'UNKNOWN'], + ['notSupported', 'WARNING'], + ], + 'default.operability' => [ + ['unknown', 'UNKNOWN'], + ['operable', 'OK'], + ['inoperable', 'CRITICAL'], + ['degraded', 'WARNING'], + ['poweredOff', 'WARNING'], + ['powerProblem', 'CRITICAL'], + ['removed', 'WARNING'], + ['voltageProblem', 'CRITICAL'], + ['thermalProblem', 'CRITICAL'], + ['performanceProblem', 'CRITICAL'], + ['accessibilityProblem', 'WARNING'], + ['identityUnestablishable', 'WARNING'], + ['biosPostTimeout', 'WARNING'], + ['disabled', 'OK'], + ['fabricConnProblem', 'WARNING'], + ['fabricUnsupportedConn', 'WARNING'], + ['config', 'OK'], + ['equipmentProblem', 'CRITICAL'], + ['decomissioning', 'WARNING'], + ['chassisLimitExceeded', 'WARNING'], + ['notSupported', 'WARNING'], + ['discovery', 'OK'], + ['discoveryFailed', 'WARNING'], + ['postFailure', 'WARNING'], + ['upgradeProblem', 'WARNING'], + ['peerCommProblem', 'WARNING'], + ['autoUpgrade', 'OK'], + ], + 'default.overall_status' => [ + ['indeterminate', 'UNKNOWN'], + ['unassociated', 'OK'], + ['ok', 'OK'], + ['discovery', 'OK'], + ['config', 'OK'], + ['unconfig', 'OK'], + ['power-off', 'WARNING'], + ['restart', 'WARNING'], + ['maintenance', 'OK'], + ['test', 'OK'], + ['compute-mismatch', 'WARNING'], + ['compute-failed', 'WARNING'], + ['degraded', 'WARNING'], + ['discovery-failed', 'WARNING'], + ['config-failure', 'WARNING'], + ['unconfig-failed', 'WARNING'], + ['test-failed', 'WARNING'], + ['maintenance-failed', 'WARNING'], + ['removed', 'WARNING'], + ['disabled', 'OK'], + ['inaccessible', 'WARNING'], + ['thermal-problem', 'CRITICAL'], + ['power-problem', 'CRITICAL'], + ['voltage-problem', 'CRITICAL'], + ['inoperable', 'CRITICAL'], + ['decommissioning', 'WARNING'], + ['bios-restore', 'WARNING'], + ['cmos-reset', 'WARNING'], + ['diagnostics', 'OK'], + ['diagnostic-failed', 'WARNING'], + ], }; 1; diff --git a/hardware/server/cisco/ucs/mode/equipment.pm b/hardware/server/cisco/ucs/mode/equipment.pm index 34cc9894e..fbd837d37 100644 --- a/hardware/server/cisco/ucs/mode/equipment.pm +++ b/hardware/server/cisco/ucs/mode/equipment.pm @@ -20,180 +20,45 @@ package hardware::server::cisco::ucs::mode::equipment; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; use hardware::server::cisco::ucs::mode::components::resources qw($thresholds); -use hardware::server::cisco::ucs::mode::components::fan; -use hardware::server::cisco::ucs::mode::components::psu; -use hardware::server::cisco::ucs::mode::components::iocard; -use hardware::server::cisco::ucs::mode::components::chassis; -use hardware::server::cisco::ucs::mode::components::blade; -use hardware::server::cisco::ucs::mode::components::fex; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(fan|psu|chassis|iocard|blade|fex|cpu|memory|localdisk)\.(presence|operability|overall_status)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = $thresholds; + + $self->{components_path} = 'hardware::server::cisco::ucs::mode::components'; + $self->{components_module} = ['fan', 'psu', 'chassis', 'iocard', 'blade', 'fex', 'cpu', 'memory', 'localdisk']; +} + +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); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_performance => 1); bless $self, $class; $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "exclude:s" => { name => 'exclude' }, - "absent-problem:s" => { name => 'absent' }, - "component:s" => { name => 'component', default => 'all' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, + { }); - $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'; - } - } - - $self->{overload_th} = {}; - foreach my $val (@{$self->{option_results}->{threshold_overload}}) { - if ($val !~ /^(.*?),(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong treshold-overload option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $type, $status, $filter) = ($1, $2, $3, $4); - if ($self->{output}->is_litteral_status(status => $status) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong treshold-overload status '" . $val . "'."); - $self->{output}->option_exit(); - } - $self->{overload_th}->{$section} = { } if (!defined($self->{overload_th}->{$section})); - $self->{overload_th}->{$section}->{$type} = { } if (!defined($self->{overload_th}->{$section}->{$type})); - $self->{overload_th}->{$section}->{$type}->{$filter} = $status; - } -} - -sub global { - my ($self, %options) = @_; - - hardware::server::cisco::ucs::mode::components::fan::check($self); - hardware::server::cisco::ucs::mode::components::psu::check($self); - hardware::server::cisco::ucs::mode::components::iocard::check($self); - hardware::server::cisco::ucs::mode::components::chassis::check($self); - hardware::server::cisco::ucs::mode::components::blade::check($self); - hardware::server::cisco::ucs::mode::components::fex::check($self); -} - -sub component { - my ($self, %options) = @_; - - if ($self->{option_results}->{component} eq 'fan') { - hardware::server::cisco::ucs::mode::components::fan::check($self); - } elsif ($self->{option_results}->{component} eq 'psu') { - hardware::server::cisco::ucs::mode::components::psu::check($self); - } elsif ($self->{option_results}->{component} eq 'iocard') { - hardware::server::cisco::ucs::mode::components::iocard::check($self); - } elsif ($self->{option_results}->{component} eq 'chassis') { - hardware::server::cisco::ucs::mode::components::chassis::check($self); - } elsif ($self->{option_results}->{component} eq 'blade') { - hardware::server::cisco::ucs::mode::components::blade::check($self); - } elsif ($self->{option_results}->{component} eq 'fex') { - hardware::server::cisco::ucs::mode::components::fex::check($self); - } else { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - if ($self->{option_results}->{component} eq 'all') { - $self->global(); - } else { - $self->component(); - } - - 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.'); - } - - $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; -} - -sub get_severity { - my ($self, %options) = @_; - - my $status = ${$thresholds->{$options{threshold}}->{$options{value}}}[1]; - if (defined($self->{overload_th}->{$options{section}}->{$options{threshold}})) { - foreach (keys %{$self->{overload_th}->{$options{section}}->{$options{threshold}}}) { - if (${$thresholds->{$options{threshold}}->{$options{value}}}[0] =~ /$_/i) { - $status = $self->{overload_th}->{$options{section}}->{$options{threshold}}->{$_}; - last; - } - } - } - return $status; -} - -sub absent_problem { - my ($self, %options) = @_; - - if (defined($self->{option_results}->{absent}) && - $self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - return 1; - } - - return 0; -} - 1; __END__ @@ -206,18 +71,18 @@ Check Hardware (Fans, Power supplies, chassis, io cards, blades, fabric extender =item B<--component> -Which component to check (Default: 'all'). -Can be: 'fan', 'psu', 'chassis', 'iocard', 'blade', 'fex' +Which component to check (Default: '.*'). +Can be: 'fan', 'psu', 'chassis', 'iocard', 'blade', 'fex', 'cpu', 'memory', 'localdisk'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=fan) -Can also exclude specific instance: --exclude=fan#/sys/chassis-7/fan-module-1-7/fan-1# +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=psu) +Can also exclude specific instance: --filter=fan,/sys/chassis-7/fan-module-1-7/fan-1 =item B<--absent-problem> Return an error if an entity is not 'present' (default is skipping) (comma seperated list) -Can be specific or global: --exclude=fan#/sys/chassis-7/fan-module-1-7/fan-1# +Can be specific or global: --absent-problem=fan,/sys/chassis-7/fan-module-1-7/fan-1 =item B<--no-component> @@ -226,8 +91,9 @@ If total (with skipped) is 0. (Default: 'critical' returns). =item B<--threshold-overload> -Set to overload default threshold values (syntax: section,threshold,status,regexp) -Example: --threshold-overload='fan,operability,OK,poweredOff|removed' +Set to overload default threshold values (syntax: section,[instance,]status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='fan.operability,OK,poweredOff|removed' =back diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/ambient.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/ambient.pm index eabf896d3..88361c9ff 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/ambient.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/ambient.pm @@ -40,9 +40,9 @@ my $oids = { }; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_temperature, end => $oid_end }; + push @{$self->{request}}, { oid => $oid_temperature, end => $oid_end }; } sub check { @@ -50,7 +50,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking ambient"); $self->{components}->{ambient} = {name => 'ambient', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'ambient')); + return if ($self->check_filter(section => 'ambient')); my @sensors = ('mm', 'frontpanel', 'frontpanel2'); my $label = 'bladecenter'; @@ -68,7 +68,7 @@ sub check { } my $value = $1; - next if ($self->check_exclude(section => 'ambient', instance => $temp)); + next if ($self->check_filter(section => 'ambient', instance => $temp)); $self->{components}->{ambient}->{total}++; $self->{output}->output_add(long_msg => sprintf("ambient '%s' is %s degree centigrade.", diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/blade.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/blade.pm index 2f020405a..dd9918b7d 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/blade.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/blade.pm @@ -59,9 +59,9 @@ my $mapping = { my $oid_bladeSystemStatusEntry = '.1.3.6.1.4.1.2.3.51.2.22.1.5.1.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_bladeSystemStatusEntry, start => $mapping->{bladeId}->{oid}, end => $mapping->{bladeName}->{oid} }; + push @{$self->{request}}, { oid => $oid_bladeSystemStatusEntry, start => $mapping->{bladeId}->{oid}, end => $mapping->{bladeName}->{oid} }; } sub check { @@ -69,14 +69,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking blades"); $self->{components}->{blade} = {name => 'blades', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'blade')); + return if ($self->check_filter(section => 'blade')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_bladeSystemStatusEntry}})) { next if ($oid !~ /^$mapping->{bladeExists}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_bladeSystemStatusEntry}, instance => $instance); - next if ($self->check_exclude(section => 'blade', instance => $result->{bladeId})); + next if ($self->check_filter(section => 'blade', instance => $result->{bladeId})); if ($result->{bladeExists} =~ /false/i) { $self->{output}->output_add(long_msg => "skipping blade '" . $instance . "' : not exits"); next; diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/blower.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/blower.pm index b03b7c565..022cb698b 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/blower.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/blower.pm @@ -45,9 +45,9 @@ my $entry_controller_state = '30'; my $count = 4; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_blowers }; + push @{$self->{request}}, { oid => $oid_blowers }; } sub check { @@ -55,7 +55,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking blowers"); $self->{components}->{blower} = {name => 'blowers', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'blower')); + return if ($self->check_filter(section => 'blower')); for (my $i = 0; $i < $count; $i++) { my $instance = $i + 1; @@ -64,7 +64,7 @@ sub check { my $blower_speed = defined($self->{results}->{$oid_blowers}->{$oid_blowers . '.' . ($entry_blower_speed + $i) . '.0'}) ? $self->{results}->{$oid_blowers}->{$oid_blowers . '.' . ($entry_blower_speed + $i) . '.0'} : 'unknown'; my $ctrl_state = defined($self->{results}->{$oid_blowers}->{$oid_blowers . '.' . ($entry_controller_state + $i) . '.0'}) ? $map_controller_state{$self->{results}->{$oid_blowers}->{$oid_blowers . '.' . ($entry_controller_state + $i) . '.0'}} : undef; - next if ($self->check_exclude(section => 'blower', instance => $instance)); + next if ($self->check_filter(section => 'blower', instance => $instance)); next if ($blower_speed =~ /No Blower/i && $self->absent_problem(section => 'blower', instance => $instance)); $self->{components}->{blower}->{total}++; @@ -94,7 +94,7 @@ sub check { next if (!defined($ctrl_state)); - next if ($self->check_exclude(section => 'blowerctrl', instance => $instance)); + next if ($self->check_filter(section => 'blowerctrl', instance => $instance)); next if ($ctrl_state =~ /notPresent/i && $self->absent_problem(section => 'blowerctrl', instance => $instance)); $self->{output}->output_add(long_msg => sprintf("Blower controller '%s' state is %s.", diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/chassisfan.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/chassisfan.pm index a3c90d7a2..f3648f55c 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/chassisfan.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/chassisfan.pm @@ -38,9 +38,9 @@ my $mapping = { my $oid_chassisFansEntry = '.1.3.6.1.4.1.2.3.51.2.2.3.50.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_chassisFansEntry }; + push @{$self->{request}}, { oid => $oid_chassisFansEntry }; } sub check { @@ -48,14 +48,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking chassis fan"); $self->{components}->{chassisfan} = {name => 'chassis fan', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'chassisfan')); + return if ($self->check_filter(section => 'chassisfan')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_chassisFansEntry}})) { next if ($oid !~ /^$mapping->{chassisFanState}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_chassisFansEntry}, instance => $instance); - next if ($self->check_exclude(section => 'chassisfan', instance => $instance)); + next if ($self->check_filter(section => 'chassisfan', instance => $instance)); $self->{components}->{chassisfan}->{total}++; $self->{output}->output_add(long_msg => sprintf("Chassis fan '%s' is %s rpm [status: %s, instance: %s]", diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/chassisstatus.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/chassisstatus.pm index db8b4a56a..f4a315fdb 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/chassisstatus.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/chassisstatus.pm @@ -64,9 +64,9 @@ my %map_test_state = ( ); sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_mmBistAndChassisStatus, end => $oid_bistLogicalNetworkLink }; + push @{$self->{request}}, { oid => $oid_mmBistAndChassisStatus, end => $oid_bistLogicalNetworkLink }; } sub check { @@ -74,7 +74,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking chassis status"); $self->{components}->{chassisstatus} = {name => 'chassis-status', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'chassisstatus')); + return if ($self->check_filter(section => 'chassisstatus')); foreach my $name (sort keys %{$oids}) { if (!defined($self->{results}->{$oid_mmBistAndChassisStatus}->{$oids->{$name}})) { @@ -84,7 +84,7 @@ sub check { } my $value = $map_test_state{$self->{results}->{$oid_mmBistAndChassisStatus}->{$oids->{$name}}}; - next if ($self->check_exclude(section => 'chassisstatus', instance => $name)); + next if ($self->check_filter(section => 'chassisstatus', instance => $name)); $self->{components}->{chassisstatus}->{total}++; $self->{output}->output_add(long_msg => sprintf("Chassis status '%s' state is %s", diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/fanpack.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/fanpack.pm index 918cd655a..7f9a067f2 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/fanpack.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/fanpack.pm @@ -43,9 +43,9 @@ my $mapping = { my $oid_fanPackEntry = '.1.3.6.1.4.1.2.3.51.2.2.6.1.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_fanPackEntry }; + push @{$self->{request}}, { oid => $oid_fanPackEntry }; } sub check { @@ -53,7 +53,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking fanpack"); $self->{components}->{fanpack} = {name => 'fanpacks', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fanpack')); + return if ($self->check_filter(section => 'fanpack')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_fanPackEntry}})) { next if ($oid !~ /^$mapping->{fanPackState}->{oid}\.(.*)$/); @@ -64,7 +64,7 @@ sub check { $self->{output}->output_add(long_msg => "skipping fanpack '" . $instance . "' : not exits"); next; } - next if ($self->check_exclude(section => 'fanpack', instance => $instance)); + next if ($self->check_filter(section => 'fanpack', instance => $instance)); $self->{components}->{fanpack}->{total}++; $self->{output}->output_add(long_msg => sprintf("Fanpack '%s' is %s rpm [status: %s, instance: %s]", diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/powermodule.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/powermodule.pm index dd4fd6135..27e6d8a5d 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/powermodule.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/powermodule.pm @@ -44,9 +44,9 @@ my $mapping = { my $oid_powerModuleHealthEntry = '.1.3.6.1.4.1.2.3.51.2.2.4.1.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_powerModuleHealthEntry, start => $mapping->{powerModuleExists}->{oid} }; + push @{$self->{request}}, { oid => $oid_powerModuleHealthEntry, start => $mapping->{powerModuleExists}->{oid} }; } sub check { @@ -54,14 +54,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking power modules"); $self->{components}->{powermodule} = {name => 'power modules', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'powermodule')); + return if ($self->check_filter(section => 'powermodule')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_powerModuleHealthEntry}})) { next if ($oid !~ /^$mapping->{powerModuleState}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_powerModuleHealthEntry}, instance => $instance); - next if ($self->check_exclude(section => 'powermodule', instance => $instance)); + next if ($self->check_filter(section => 'powermodule', instance => $instance)); next if ($result->{powerModuleExists} =~ /No/i && $self->absent_problem(section => 'powermodule', instance => $instance)); $self->{components}->{powermodule}->{total}++; diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/switchmodule.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/switchmodule.pm index 3d6c6b3f2..95e2517d2 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/switchmodule.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/switchmodule.pm @@ -36,9 +36,9 @@ my $mapping = { }; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $mapping->{smHealthState}->{oid} }; + push @{$self->{request}}, { oid => $mapping->{smHealthState}->{oid} }; } sub check { @@ -46,14 +46,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking switch module"); $self->{components}->{switchmodule} = {name => 'switch modules', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'switchmodule')); + return if ($self->check_filter(section => 'switchmodule')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$mapping->{smHealthState}->{oid}}})) { $oid =~ /^$mapping->{smHealthState}->{oid}\.(.*)/; my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{smHealthState}->{oid}}, instance => $instance); - next if ($self->check_exclude(section => 'switchmodule', instance => $instance)); + next if ($self->check_filter(section => 'switchmodule', instance => $instance)); $self->{components}->{switchmodule}->{total}++; $self->{output}->output_add(long_msg => sprintf("Switch module '%s' status is %s [instance: %s]", diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/systemhealth.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/systemhealth.pm index 4f4958292..18c5e49b0 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/systemhealth.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/systemhealth.pm @@ -34,9 +34,9 @@ my %map_systemhealth_state = ( ); sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_systemHealthStat }; + push @{$self->{request}}, { oid => $oid_systemHealthStat }; } sub check { @@ -44,8 +44,11 @@ sub check { $self->{output}->output_add(long_msg => "Checking system health"); $self->{components}->{systemhealth} = {name => 'system-health', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'systemhealth')); + return if ($self->check_filter(section => 'systemhealth')); + return if (!defined($self->{results}->{$oid_systemHealthStat}->{$oid_systemHealthStat . '.0'}) || + !defined($map_systemhealth_state{$self->{results}->{$oid_systemHealthStat}->{$oid_systemHealthStat . '.0'}})); + my $value = $map_systemhealth_state{$self->{results}->{$oid_systemHealthStat}->{$oid_systemHealthStat . '.0'}}; $self->{components}->{systemhealth}->{total}++; diff --git a/hardware/server/ibm/bladecenter/snmp/mode/hardware.pm b/hardware/server/ibm/bladecenter/snmp/mode/hardware.pm index 1d939c6e7..7be62e343 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/hardware.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/hardware.pm @@ -20,74 +20,92 @@ package hardware::server::ibm::bladecenter::snmp::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -my $thresholds = { - chassisstatus => [ - ['testSucceeded', 'OK'], - ['testFailed', 'CRITICAL'], - ], - systemhealth => [ - ['normal', 'OK'], - ['systemLevel', 'WARNING'], - ['nonCritical', 'WARNING'], - ['critical', 'CRITICAL'], - ], - powermodule => [ - ['unknown', 'UNKNOWN'], - ['good', 'OK'], - ['warning', 'WARNING'], - ['notAvailable', 'UNKNOWN'], - ], - fanpack => [ - ['unknown', 'UNKNOWN'], - ['good', 'OK'], - ['warning', 'WARNING'], - ['bad', 'CRITICAL'], - ], - chassisfan => [ - ['unknown', 'UNKNOWN'], - ['good', 'OK'], - ['warning', 'WARNING'], - ['bad', 'CRITICAL'], - ], - blower => [ - ['unknown', 'UNKNOWN'], - ['good', 'OK'], - ['warning', 'WARNING'], - ['bad', 'CRITICAL'], - ], - switchmodule => [ - ['unknown', 'UNKNOWN'], - ['good', 'OK'], - ['warning', 'WARNING'], - ['bad', 'CRITICAL'], - ], - blowerctrl => [ - ['unknown', 'UNKNOWN'], - ['operational', 'OK'], - ['flashing', 'WARNING'], - ['communicationError', 'CRITICAL'], - ['notPresent', 'UNKNOWN'], - ], - blade => [ - ['unknown', 'UNKNOWN'], - ['good', 'OK'], - ['warning', 'WARNING'], - ['critical', 'CRITICAL'], - ['kernelMode', 'WARNING'], - ['discovering', 'WARNING'], - ['commError', 'CRITICAL'], - ['noPower', 'WARNING'], - ['flashing', 'WARNING'], - ['initFailure', 'CRITICAL'], - ['insufficientPower', 'CRITICAL'], - ['powerDenied', 'CRITICAL'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_numeric_check_section_option} = '^(blower|ambient|fanpack|chassisfan)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + chassisstatus => [ + ['testSucceeded', 'OK'], + ['testFailed', 'CRITICAL'], + ], + systemhealth => [ + ['normal', 'OK'], + ['systemLevel', 'WARNING'], + ['nonCritical', 'WARNING'], + ['critical', 'CRITICAL'], + ], + powermodule => [ + ['unknown', 'UNKNOWN'], + ['good', 'OK'], + ['warning', 'WARNING'], + ['notAvailable', 'UNKNOWN'], + ], + fanpack => [ + ['unknown', 'UNKNOWN'], + ['good', 'OK'], + ['warning', 'WARNING'], + ['bad', 'CRITICAL'], + ], + chassisfan => [ + ['unknown', 'UNKNOWN'], + ['good', 'OK'], + ['warning', 'WARNING'], + ['bad', 'CRITICAL'], + ], + blower => [ + ['unknown', 'UNKNOWN'], + ['good', 'OK'], + ['warning', 'WARNING'], + ['bad', 'CRITICAL'], + ], + switchmodule => [ + ['unknown', 'UNKNOWN'], + ['good', 'OK'], + ['warning', 'WARNING'], + ['bad', 'CRITICAL'], + ], + blowerctrl => [ + ['unknown', 'UNKNOWN'], + ['operational', 'OK'], + ['flashing', 'WARNING'], + ['communicationError', 'CRITICAL'], + ['notPresent', 'UNKNOWN'], + ], + blade => [ + ['unknown', 'UNKNOWN'], + ['good', 'OK'], + ['warning', 'WARNING'], + ['critical', 'CRITICAL'], + ['kernelMode', 'WARNING'], + ['discovering', 'WARNING'], + ['commError', 'CRITICAL'], + ['noPower', 'WARNING'], + ['flashing', 'WARNING'], + ['initFailure', 'CRITICAL'], + ['insufficientPower', 'CRITICAL'], + ['powerDenied', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'hardware::server::ibm::bladecenter::snmp::mode::components'; + $self->{components_module} = ['ambient', 'powermodule', 'blade', 'blower', 'fanpack', 'chassisfan', 'systemhealth', 'chassisstatus', 'switchmodule']; +} + +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) = @_; @@ -96,211 +114,12 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "exclude:s" => { name => 'exclude' }, - "absent-problem:s" => { name => 'absent' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { }); - $self->{product_name} = undef; - $self->{serial} = undef; - $self->{romversion} = undef; - $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'; - } - } - - $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->{numeric_threshold} = {}; - foreach my $option (('warning', 'critical')) { - foreach my $val (@{$self->{option_results}->{$option}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $regexp, $value) = ($1, $2, $3); - if ($section !~ /(blower|ambient|fanpack|chassisfan)/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "' (type must be: blower, fanpack, chassisfan or ambient)."); - $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, regexp => $regexp }; - } - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('ambient', 'powermodule', 'blade', 'blower', 'fanpack', 'chassisfan', 'systemhealth', 'chassisstatus', 'switchmodule'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "hardware::server::ibm::bladecenter::snmp::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "hardware::server::ibm::bladecenter::snmp::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $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; -} - -sub absent_problem { - my ($self, %options) = @_; - - if (defined($self->{option_results}->{absent}) && - $self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - } - - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); - $self->{components}->{$options{section}}->{skip}++; - return 1; -} - - -sub get_severity_numeric { - 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} =~ /$_->{regexp}/) { - 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 - - 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; -} - 1; __END__ @@ -317,15 +136,15 @@ Which component to check (Default: 'all'). Can be: 'ambient', 'powermodule', 'fanpack', 'chassisfan', 'blower', 'blade', 'systemhealth', 'chassisstatus', 'switchmodule'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=blower,powermodule) -Can also exclude specific instance: --exclude=blower#1#,powermodule#2# +Exclude some parts (comma seperated list) (Example: --filter=blower --filter=powermodule) +Can also exclude specific instance: --filter=blower,1 =item B<--absent-problem> Return an error if an entity is not 'notAvailable' (default is skipping) (comma seperated list) -Can be specific or global: --absent-problem=powermodule#2# +Can be specific or global: --absent-problem=powermodule,2 =item B<--no-component> @@ -334,18 +153,18 @@ If total (with skipped) is 0. (Default: 'critical' returns). =item B<--threshold-overload> -Set to overload default threshold values (syntax: section,status,regexp) +Set to overload default threshold values (syntax: section,[instance,]status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='blade,OK,unknown' =item B<--warning> -Set warning threshold for temperatures (syntax: type,regexp,treshold) +Set warning threshold (syntax: type,regexp,threshold) Example: --warning='ambient,mm,30' --warning='ambient,frontpanel,35' =item B<--critical> -Set critical threshold for temperatures (syntax: type,regexp,treshold) +Set critical threshold (syntax: type,regexp,threshold) Example: --critical='blower,1,50' =back diff --git a/network/3com/snmp/mode/cpu.pm b/network/3com/snmp/mode/cpu.pm index 71e7df6fe..af8b72602 100644 --- a/network/3com/snmp/mode/cpu.pm +++ b/network/3com/snmp/mode/cpu.pm @@ -20,48 +20,56 @@ package network::3com::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', 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 }, + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '001_1m' => { - set => { + { label => '1m', 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 }, + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, - '002_5m' => { - set => { + { label => '5m', 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 }, + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, ], - }, + } }, + ]; +} + +sub prefix_cpu_output { + my ($self, %options) = @_; + + if ($self->{multiple} == 1) { + return "CPU '" . $options{instance_value}->{display} . "' Usage "; } -}; + return "CPU Usage "; +} sub new { my ($class, %options) = @_; @@ -72,107 +80,10 @@ sub new { $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}}); - } - } 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 { - 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(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(); -} - my $mapping = { hwCpuCostRate => { oid => '.1.3.6.1.4.1.43.45.1.6.1.1.1.2' }, hwCpuCostRatePer1Min => { oid => '.1.3.6.1.4.1.43.45.1.6.1.1.1.3' }, @@ -214,6 +125,11 @@ Check cpu usages. =over 8 +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='5m' + =item B<--warning-*> Threshold warning. diff --git a/network/3com/snmp/mode/memory.pm b/network/3com/snmp/mode/memory.pm index d0e92264b..c54fdd0d5 100644 --- a/network/3com/snmp/mode/memory.pm +++ b/network/3com/snmp/mode/memory.pm @@ -20,27 +20,10 @@ package network::3com::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 => { - 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) = @_; @@ -89,6 +72,34 @@ 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', 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); @@ -98,107 +109,10 @@ sub new { $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}}); - } - } 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(extra_instance => $multiple); - } - - my $prefix = ''; - if ($multiple == 1) { - $prefix = sprintf("Memory '%s' ", $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 = { hwMemSize => { oid => '.1.3.6.1.4.1.43.45.1.6.1.2.1.1.2' }, hwMemFree => { oid => '.1.3.6.1.4.1.43.45.1.6.1.2.1.1.3' }, @@ -210,7 +124,7 @@ sub manage_selection { # a3com-huawei-splat-devm.mib my $oid_hwMemEntry = '.1.3.6.1.4.1.43.45.1.6.1.2.1.1'; my $results = $options{snmp}->get_table(oid => $oid_hwMemEntry, nothing_quit => 1); - $self->{mem} = {}; + $self->{memory} = {}; foreach my $oid (keys %{$results}) { next if ($oid !~ /^$mapping->{hwMemSize}->{oid}\.(.*)/); my $instance = $1; @@ -218,10 +132,10 @@ sub manage_selection { my $total = $result->{hwMemSize}; my $used = $result->{hwMemSize} - $result->{hwMemFree}; - $self->{mem}->{$instance} = { display => $instance, used => $used, total => $total }; + $self->{memory}->{$instance} = { display => $instance, used => $used, total => $total }; } - 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/network/bluecoat/snmp/mode/components/disk.pm b/network/bluecoat/snmp/mode/components/disk.pm index bf0127b44..cb078d198 100644 --- a/network/bluecoat/snmp/mode/components/disk.pm +++ b/network/bluecoat/snmp/mode/components/disk.pm @@ -44,9 +44,9 @@ my $mapping = { my $oid_deviceDiskValueEntry = '.1.3.6.1.4.1.3417.2.2.1.1.1.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_deviceDiskValueEntry }; + push @{$self->{request}}, { oid => $oid_deviceDiskValueEntry }; } sub check { @@ -57,7 +57,7 @@ sub check { return if ($self->check_filter(section => 'disk')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_deviceDiskValueEntry}})) { - next if ($oid !~ /^$mapping->{deviceSensorStatus}->{oid}\.(.*)$/); + next if ($oid !~ /^$mapping->{deviceDiskStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_deviceDiskValueEntry}, instance => $instance); diff --git a/network/bluecoat/snmp/mode/components/sensor.pm b/network/bluecoat/snmp/mode/components/sensor.pm index 73caaff1a..940ab82e6 100644 --- a/network/bluecoat/snmp/mode/components/sensor.pm +++ b/network/bluecoat/snmp/mode/components/sensor.pm @@ -66,9 +66,9 @@ my $mapping = { my $oid_deviceSensorValueEntry = '.1.3.6.1.4.1.3417.2.1.1.1.1.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_deviceSensorValueEntry }; + push @{$self->{request}}, { oid => $oid_deviceSensorValueEntry }; } sub check { diff --git a/network/bluecoat/snmp/mode/hardware.pm b/network/bluecoat/snmp/mode/hardware.pm index af39b7603..9f9123069 100644 --- a/network/bluecoat/snmp/mode/hardware.pm +++ b/network/bluecoat/snmp/mode/hardware.pm @@ -20,49 +20,71 @@ package network::bluecoat::snmp::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -use centreon::plugins::misc; my $thresholds = { - sensor_opstatus => [ - ['ok', 'OK'], - ['unavailable', 'UNKNOWN'], - ['nonoperational', 'UNKNOWN'], - ], - sensor => [ - ['ok', 'OK'], - ['unknown', 'UNKNOWN'], - ['nonInstalled', 'OK'], - ['voltageLowWarning', 'WARNING'], - ['voltageLowCritical', 'CRITICAL'], - ['noPower', 'CRITICAL'], - ['voltageHighWarning', 'WARNING'], - ['voltageHighCritical', 'CRITICAL'], - ['voltageHighSevere', 'CRITICAL'], - ['temperatureHighWarning', 'WARNING'], - ['temperatureHighCritical', 'CRITICAL'], - ['temperatureHighSevere', 'CRITICAL'], - ['fanSlowWarning', 'WARNING'], - ['fanSlowCritical', 'CRITICAL'], - ['fanStopped', 'CRITICAL'], - ], - disk => [ - ['present', 'OK'], - ['initializing', 'OK'], - ['inserted', 'OK'], - ['offline', 'WARNING'], - ['removed', 'WARNING'], - ['notpresent', 'OK'], - ['empty', 'WARNING'], - ['ioerror', 'CRITICAL'], - ['unusable', 'CRITICAL'], - ['unknown', 'UNKNOWN'], - ], + }; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(sensor|disk|sensor_opstatus)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^sensor$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + sensor_opstatus => [ + ['ok', 'OK'], + ['unavailable', 'UNKNOWN'], + ['nonoperational', 'UNKNOWN'], + ], + sensor => [ + ['ok', 'OK'], + ['unknown', 'UNKNOWN'], + ['nonInstalled', 'OK'], + ['voltageLowWarning', 'WARNING'], + ['voltageLowCritical', 'CRITICAL'], + ['noPower', 'CRITICAL'], + ['voltageHighWarning', 'WARNING'], + ['voltageHighCritical', 'CRITICAL'], + ['voltageHighSevere', 'CRITICAL'], + ['temperatureHighWarning', 'WARNING'], + ['temperatureHighCritical', 'CRITICAL'], + ['temperatureHighSevere', 'CRITICAL'], + ['fanSlowWarning', 'WARNING'], + ['fanSlowCritical', 'CRITICAL'], + ['fanStopped', 'CRITICAL'], + ], + disk => [ + ['present', 'OK'], + ['initializing', 'OK'], + ['inserted', 'OK'], + ['offline', 'WARNING'], + ['removed', 'WARNING'], + ['notpresent', 'OK'], + ['empty', 'WARNING'], + ['ioerror', 'CRITICAL'], + ['unusable', 'CRITICAL'], + ['unknown', 'UNKNOWN'], + ], + }; + + $self->{components_path} = 'network::bluecoat::snmp::mode::components'; + $self->{components_module} = ['sensor', 'disk']; +} + +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); @@ -70,241 +92,12 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "filter:s@" => { name => 'filter' }, - "absent-problem:s@" => { name => 'absent_problem' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { }); - - $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'; - } - } - - $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->{absent_problem} = []; - foreach my $val (@{$self->{option_results}->{absent_problem}}) { - next if (!defined($val) || $val eq ''); - my @values = split (/,/, $val); - push @{$self->{absent_problem}}, { 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 !~ /^sensor|disk|sensor_opstatus$/) { - $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 !~ /^sensor$/) { - $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 }; - } - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('sensor', 'disk'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::bluecoat::snmp::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::bluecoat::snmp::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub absent_problem { - my ($self, %options) = @_; - - foreach (@{$self->{absent_problem}}) { - if ($options{section} =~ /$_->{filter}/) { - if (!defined($_->{instance}) || $options{instance} =~ /$_->{instance}/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); - $self->{components}->{$options{section}}->{skip}++; - return 1; - } - } - } - - return 0; -} - -sub check_filter { - 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->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); - return 1; - } - } - } - - return 0; -} - -sub get_severity_numeric { - 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 - - 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; - } - } - - return $status; -} - 1; __END__ diff --git a/network/checkpoint/mode/components/fan.pm b/network/checkpoint/mode/components/fan.pm index 3bee03320..97d3400f0 100644 --- a/network/checkpoint/mode/components/fan.pm +++ b/network/checkpoint/mode/components/fan.pm @@ -37,9 +37,9 @@ my $mapping = { my $oid_fanSpeedSensorEntry = '.1.3.6.1.4.1.2620.1.6.7.8.2.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_fanSpeedSensorEntry, start => $mapping->{fanSpeedSensorName}->{oid}, end => $mapping->{fanSpeedSensorStatus}->{oid} }; + push @{$self->{request}}, { oid => $oid_fanSpeedSensorEntry, start => $mapping->{fanSpeedSensorName}->{oid}, end => $mapping->{fanSpeedSensorStatus}->{oid} }; } sub check { @@ -47,14 +47,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking fans"); $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fan')); + return if ($self->check_filter(section => 'fan')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_fanSpeedSensorEntry}})) { next if ($oid !~ /^$mapping->{fanSpeedSensorStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_fanSpeedSensorEntry}, instance => $instance); - next if ($self->check_exclude(section => 'fan', instance => $instance)); + next if ($self->check_filter(section => 'fan', instance => $instance)); next if ($result->{fanSpeedSensorName} !~ /^[0-9a-zA-Z ]+$/); # sometimes there is some wrong values in hex $self->{components}->{fan}->{total}++; diff --git a/network/checkpoint/mode/components/psu.pm b/network/checkpoint/mode/components/psu.pm index f3801f1b0..e987a2623 100644 --- a/network/checkpoint/mode/components/psu.pm +++ b/network/checkpoint/mode/components/psu.pm @@ -29,9 +29,9 @@ my $mapping = { my $oid_powerSupplyStatus = '.1.3.6.1.4.1.2620.1.6.7.9.1.1.2'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_powerSupplyStatus }; + push @{$self->{request}}, { oid => $oid_powerSupplyStatus }; } sub check { @@ -39,14 +39,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking power supplies"); $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'psu')); + return if ($self->check_filter(section => 'psu')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_powerSupplyStatus}})) { next if ($oid !~ /^$mapping->{powerSupplyStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_powerSupplyStatus}, instance => $instance); - next if ($self->check_exclude(section => 'psu', instance => $instance)); + 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'", diff --git a/network/checkpoint/mode/components/temperature.pm b/network/checkpoint/mode/components/temperature.pm index 60d24298b..9dac9032a 100644 --- a/network/checkpoint/mode/components/temperature.pm +++ b/network/checkpoint/mode/components/temperature.pm @@ -37,9 +37,9 @@ my $mapping = { my $oid_tempertureSensorEntry = '.1.3.6.1.4.1.2620.1.6.7.8.1.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_tempertureSensorEntry, start => $mapping->{tempertureSensorName}->{oid}, end => $mapping->{tempertureSensorStatus}->{oid} }; + push @{$self->{request}}, { oid => $oid_tempertureSensorEntry, start => $mapping->{tempertureSensorName}->{oid}, end => $mapping->{tempertureSensorStatus}->{oid} }; } sub check { @@ -47,14 +47,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking temperatures"); $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'temperature')); + return if ($self->check_filter(section => 'temperature')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_tempertureSensorEntry}})) { next if ($oid !~ /^$mapping->{tempertureSensorStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_tempertureSensorEntry}, instance => $instance); - next if ($self->check_exclude(section => 'temperature', instance => $instance)); + next if ($self->check_filter(section => 'temperature', instance => $instance)); next if ($result->{tempertureSensorName} !~ /^[0-9a-zA-Z ]+$/); # sometimes there is some wrong values in hex $self->{components}->{temperature}->{total}++; diff --git a/network/checkpoint/mode/components/voltage.pm b/network/checkpoint/mode/components/voltage.pm index edc9aeb8b..b4d49bd5a 100644 --- a/network/checkpoint/mode/components/voltage.pm +++ b/network/checkpoint/mode/components/voltage.pm @@ -37,9 +37,9 @@ my $mapping = { my $oid_voltageSensorEntry = '.1.3.6.1.4.1.2620.1.6.7.8.3.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_voltageSensorEntry, start => $mapping->{voltageSensorName}->{oid}, end => $mapping->{voltageSensorStatus}->{oid} }; + push @{$self->{request}}, { oid => $oid_voltageSensorEntry, start => $mapping->{voltageSensorName}->{oid}, end => $mapping->{voltageSensorStatus}->{oid} }; } sub check { @@ -47,14 +47,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking voltages"); $self->{components}->{voltage} = {name => 'voltages', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'voltage')); + return if ($self->check_filter(section => 'voltage')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_voltageSensorEntry}})) { next if ($oid !~ /^$mapping->{voltageSensorStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_voltageSensorEntry}, instance => $instance); - next if ($self->check_exclude(section => 'voltage', instance => $instance)); + next if ($self->check_filter(section => 'voltage', instance => $instance)); next if ($result->{voltageSensorName} !~ /^[0-9a-zA-Z ]+$/); # sometimes there is some wrong values in hex $self->{components}->{voltage}->{total}++; diff --git a/network/checkpoint/mode/hardware.pm b/network/checkpoint/mode/hardware.pm index 95a058b2e..4225386b6 100644 --- a/network/checkpoint/mode/hardware.pm +++ b/network/checkpoint/mode/hardware.pm @@ -20,176 +20,65 @@ package network::checkpoint::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -my $thresholds = { - temperature => [ - ['true', 'CRITICAL'], - ['reading error', 'CRITICAL'], - ['false', 'OK'], - ], - voltage => [ - ['true', 'CRITICAL'], - ['reading error', 'CRITICAL'], - ['false', 'OK'], - ], - fan => [ - ['true', 'CRITICAL'], - ['reading error', 'CRITICAL'], - ['false', 'OK'], - ], - psu => [ - ['up', 'OK'], - ['down', 'CRITICAL'], - ['.*', 'UNKNOWN'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(temperature|voltage|fan|psu)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + temperature => [ + ['true', 'CRITICAL'], + ['reading error', 'CRITICAL'], + ['false', 'OK'], + ], + voltage => [ + ['true', 'CRITICAL'], + ['reading error', 'CRITICAL'], + ['false', 'OK'], + ], + fan => [ + ['true', 'CRITICAL'], + ['reading error', 'CRITICAL'], + ['false', 'OK'], + ], + psu => [ + ['up', 'OK'], + ['down', 'CRITICAL'], + ['.*', 'UNKNOWN'], + ], + }; + + $self->{components_path} = 'network::checkpoint::mode::components'; + $self->{components_module} = ['voltage', 'fan', 'temperature', 'psu']; +} + +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); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_performance => 1, no_absent => 1); bless $self, $class; $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "exclude:s" => { name => 'exclude' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, + { }); - $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'; - } - } - - $self->{overload_th} = {}; - foreach my $val (@{$self->{option_results}->{threshold_overload}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong treshold-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 treshold-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}; - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('voltage', 'fan', 'temperature', 'psu'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::checkpoint::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::checkpoint::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $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; -} - -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; -} - 1; __END__ @@ -205,15 +94,10 @@ Check hardware (fans, power supplies, temperatures, voltages). Which component to check (Default: '.*'). Can be: 'psu', 'fan', 'temperature', 'voltage'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=psu) -Can also exclude specific instance: --exclude='psu#1#' - -=item B<--absent-problem> - -Return an error if an entity is not 'present' (default is skipping) (comma seperated list) -Can be specific or global: --absent-problem=fan#1# +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=psu) +Can also exclude specific instance: --filter=psu,1 =item B<--no-component> @@ -222,7 +106,7 @@ If total (with skipped) is 0. (Default: 'critical' returns). =item B<--threshold-overload> -Set to overload default threshold values (syntax: section,status,regexp) +Set to overload default threshold values (syntax: section,[instance,]status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='fan,CRITICAL,^(?!(false)$)' diff --git a/network/cisco/ironport/snmp/mode/components/fan.pm b/network/cisco/ironport/snmp/mode/components/fan.pm index 6e91a53f8..708b6e310 100644 --- a/network/cisco/ironport/snmp/mode/components/fan.pm +++ b/network/cisco/ironport/snmp/mode/components/fan.pm @@ -30,9 +30,9 @@ my $mapping = { my $oid_fanEntry = '.1.3.6.1.4.1.15497.1.1.1.10.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_fanEntry, start => $mapping->{fanRPMs}->{oid} }; + push @{$self->{request}}, { oid => $oid_fanEntry, start => $mapping->{fanRPMs}->{oid} }; } sub check { @@ -40,14 +40,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking fans"); $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fan')); + return if ($self->check_filter(section => 'fan')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_fanEntry}})) { next if ($oid !~ /^$mapping->{fanRPMs}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_fanEntry}, instance => $instance); - next if ($self->check_exclude(section => 'fan', instance => $instance)); + next if ($self->check_filter(section => 'fan', instance => $instance)); $self->{components}->{fan}->{total}++; $self->{output}->output_add(long_msg => sprintf("Fan '%s' is '%s' rpm [instance = %s]", diff --git a/network/cisco/ironport/snmp/mode/components/psu.pm b/network/cisco/ironport/snmp/mode/components/psu.pm index 782c11de5..7e4343418 100644 --- a/network/cisco/ironport/snmp/mode/components/psu.pm +++ b/network/cisco/ironport/snmp/mode/components/psu.pm @@ -37,9 +37,9 @@ my $mapping = { my $oid_powerSupplyEntry = '.1.3.6.1.4.1.15497.1.1.1.8.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_powerSupplyEntry, start => $mapping->{powerSupplyStatus}->{oid} }; + push @{$self->{request}}, { oid => $oid_powerSupplyEntry, start => $mapping->{powerSupplyStatus}->{oid} }; } sub check { @@ -47,14 +47,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking power supplies"); $self->{components}->{psu} = {name => 'power supplies', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'psu')); + return if ($self->check_filter(section => 'psu')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_powerSupplyEntry}})) { next if ($oid !~ /^$mapping->{powerSupplyStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_powerSupplyEntry}, instance => $instance); - next if ($self->check_exclude(section => 'psu', instance => $instance)); + next if ($self->check_filter(section => 'psu', instance => $instance)); if ($result->{powerSupplyStatus} =~ /powerSupplyNotInstalled/i) { $self->absent_problem(section => 'psu', instance => $instance); next; diff --git a/network/cisco/ironport/snmp/mode/components/raid.pm b/network/cisco/ironport/snmp/mode/components/raid.pm index 9b6a80b85..d57bb01e6 100644 --- a/network/cisco/ironport/snmp/mode/components/raid.pm +++ b/network/cisco/ironport/snmp/mode/components/raid.pm @@ -36,9 +36,9 @@ my $mapping = { my $oid_raidEntry = '.1.3.6.1.4.1.15497.1.1.1.18.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_raidEntry, start => $mapping->{raidStatus}->{oid} }; + push @{$self->{request}}, { oid => $oid_raidEntry, start => $mapping->{raidStatus}->{oid} }; } sub check { @@ -46,14 +46,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking raids"); $self->{components}->{raid} = {name => 'raids', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'raid')); + return if ($self->check_filter(section => 'raid')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_raidEntry}})) { next if ($oid !~ /^$mapping->{raidStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_raidEntry}, instance => $instance); - next if ($self->check_exclude(section => 'raid', instance => $instance)); + next if ($self->check_filter(section => 'raid', instance => $instance)); $self->{components}->{raid}->{total}++; $self->{output}->output_add(long_msg => sprintf("Raid '%s' status is '%s' [instance = %s]", diff --git a/network/cisco/ironport/snmp/mode/components/temperature.pm b/network/cisco/ironport/snmp/mode/components/temperature.pm index 8140b4c58..f58ccc5ad 100644 --- a/network/cisco/ironport/snmp/mode/components/temperature.pm +++ b/network/cisco/ironport/snmp/mode/components/temperature.pm @@ -44,9 +44,9 @@ my $mapping = { my $oid_temperatureEntry = '.1.3.6.1.4.1.15497.1.1.1.9.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_temperatureEntry, start => $mapping->{degreesCelsius}->{oid} }; + push @{$self->{request}}, { oid => $oid_temperatureEntry, start => $mapping->{degreesCelsius}->{oid} }; } sub check { @@ -54,14 +54,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking temperatures"); $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'temperature')); + return if ($self->check_filter(section => 'temperature')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_temperatureEntry}})) { next if ($oid !~ /^$mapping->{degreesCelsius}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_temperatureEntry}, instance => $instance); - next if ($self->check_exclude(section => 'temperature', instance => $instance)); + next if ($self->check_filter(section => 'temperature', instance => $instance)); $self->{components}->{temperature}->{total}++; $self->{output}->output_add(long_msg => sprintf("Temperature '%s' is '%s' degree centigrade [instance = %s]", diff --git a/network/cisco/ironport/snmp/mode/hardware.pm b/network/cisco/ironport/snmp/mode/hardware.pm index c7705df11..d1f10ff00 100644 --- a/network/cisco/ironport/snmp/mode/hardware.pm +++ b/network/cisco/ironport/snmp/mode/hardware.pm @@ -20,24 +20,43 @@ package network::cisco::ironport::snmp::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -my $thresholds = { - psu => [ - ['powerSupplyNotInstalled', 'OK'], - ['powerSupplyHealthy', 'OK'], - ['powerSupplyNoAC', 'WARNING'], - ['powerSupplyFaulty', 'CRITICAL'], - ], - raid => [ - ['driveHealthy', 'OK'], - ['driveFailure', 'CRITICAL'], - ['driveRebuild', 'WARNING'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(raid|psu)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|fan)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + psu => [ + ['powerSupplyNotInstalled', 'OK'], + ['powerSupplyHealthy', 'OK'], + ['powerSupplyNoAC', 'WARNING'], + ['powerSupplyFaulty', 'CRITICAL'], + ], + raid => [ + ['driveHealthy', 'OK'], + ['driveFailure', 'CRITICAL'], + ['driveRebuild', 'WARNING'], + ], + }; + + $self->{components_path} = 'network::cisco::ironport::snmp::mode::components'; + $self->{components_module} = ['fan', 'temperature', 'psu', 'raid']; +} + +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) = @_; @@ -46,207 +65,12 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "exclude:s" => { name => 'exclude' }, - "absent-problem:s" => { name => 'absent' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { }); - - $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'; - } - } - - $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->{numeric_threshold} = {}; - foreach my $option (('warning', 'critical')) { - foreach my $val (@{$self->{option_results}->{$option}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $regexp, $value) = ($1, $2, $3); - if ($section !~ /(temperature|fan)/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "' (type must be: temperature or fan)."); - $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, regexp => $regexp }; - } - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('fan', 'temperature', 'psu', 'raid'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::cisco::ironport::snmp::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::cisco::ironport::snmp::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $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; -} - -sub absent_problem { - my ($self, %options) = @_; - - if (defined($self->{option_results}->{absent}) && - $self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - } - - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); - $self->{components}->{$options{section}}->{skip}++; - return 1; -} - -sub get_severity_numeric { - 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} =~ /$_->{regexp}/) { - 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 - - 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; -} - 1; __END__ @@ -262,10 +86,10 @@ Check Hardware (Fans, Power Supplies, Temperatures, Raids). Which component to check (Default: '.*'). Can be: 'fan', 'temperature', 'psu', 'raid'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=fan,temperature) -Can also exclude specific instance: --exclude=fan#1#,temperature#2# +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=temperature) +Can also exclude specific instance: --filter=fan,1 =item B<--absent-problem> @@ -279,7 +103,7 @@ If total (with skipped) is 0. (Default: 'critical' returns). =item B<--threshold-overload> -Set to overload default threshold values (syntax: section,status,regexp) +Set to overload default threshold values (syntax: section,[instance,]status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='psu,CRITICAL,^(?!(powerSupplyHealthy)$)' diff --git a/network/digi/portserverts/snmp/mode/memory.pm b/network/digi/portserverts/snmp/mode/memory.pm index b04a2172c..d5933ff4a 100644 --- a/network/digi/portserverts/snmp/mode/memory.pm +++ b/network/digi/portserverts/snmp/mode/memory.pm @@ -20,24 +20,10 @@ package network::digi::portserverts::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 $maps_counters = { - global => { - '000_usage' => { set => { - key_values => [ { 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) = @_; @@ -81,6 +67,25 @@ sub custom_usage_calc { 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 => '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); @@ -90,95 +95,18 @@ sub new { $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(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}); - } - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $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}; - - use Data::Dumper; - Data::Dumper::Dumper($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"); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; my $oid_memoryTotalMemory = '.1.3.6.1.4.1.332.11.5.3.3.22.11.0'; my $oid_memoryAvailable = '.1.3.6.1.4.1.332.11.5.3.3.22.12.0'; - my $result = $self->{snmp}->get_leef(oids => [$oid_memoryTotalMemory, $oid_memoryAvailable], - nothing_quit => 1); - $self->{global} = { free => $result->{$oid_memoryAvailable}, total => $result->{$oid_memoryTotalMemory} }; + my $result = $options{snmp}->get_leef(oids => [$oid_memoryTotalMemory, $oid_memoryAvailable], + nothing_quit => 1); + $self->{memory} = { free => $result->{$oid_memoryAvailable}, total => $result->{$oid_memoryTotalMemory} }; } 1; diff --git a/network/dlink/dgs3100/snmp/mode/components/fan.pm b/network/dlink/dgs3100/snmp/mode/components/fan.pm index 915d4087a..6b056206c 100644 --- a/network/dlink/dgs3100/snmp/mode/components/fan.pm +++ b/network/dlink/dgs3100/snmp/mode/components/fan.pm @@ -40,9 +40,9 @@ my $mapping = { my $oid_rlEnvMonFanStatusEntry = '.1.3.6.1.4.1.171.10.94.89.89.83.1.1.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_rlEnvMonFanStatusEntry }; + push @{$self->{request}}, { oid => $oid_rlEnvMonFanStatusEntry }; } sub check { @@ -50,14 +50,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking fans"); $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fan')); + return if ($self->check_filter(section => 'fan')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_rlEnvMonFanStatusEntry}})) { next if ($oid !~ /^$mapping->{rlEnvMonFanStatusDescr}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_rlEnvMonFanStatusEntry}, instance => $instance); - next if ($self->check_exclude(section => 'fan', instance => $result->{rlEnvMonFanStatusDescr})); + next if ($self->check_filter(section => 'fan', instance => $result->{rlEnvMonFanStatusDescr})); next if ($result->{rlEnvMonFanState} eq 'notPresent' && $self->absent_problem(section => 'fan', instance => $result->{rlEnvMonFanStatusDescr})); $self->{components}->{fan}->{total}++; diff --git a/network/dlink/dgs3100/snmp/mode/components/psu.pm b/network/dlink/dgs3100/snmp/mode/components/psu.pm index e80dd4436..642cfb0bb 100644 --- a/network/dlink/dgs3100/snmp/mode/components/psu.pm +++ b/network/dlink/dgs3100/snmp/mode/components/psu.pm @@ -40,9 +40,9 @@ my $mapping = { my $oid_rlEnvMonSupplyStatusEntry = '.1.3.6.1.4.1.171.10.94.89.89.83.1.2.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_rlEnvMonSupplyStatusEntry }; + push @{$self->{request}}, { oid => $oid_rlEnvMonSupplyStatusEntry }; } sub check { @@ -50,14 +50,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking power supplies"); $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'psu')); + return if ($self->check_filter(section => 'psu')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_rlEnvMonSupplyStatusEntry}})) { next if ($oid !~ /^$mapping->{rlEnvMonSupplyStatusDescr}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_rlEnvMonSupplyStatusEntry}, instance => $instance); - next if ($self->check_exclude(section => 'psu', instance => $result->{rlEnvMonSupplyStatusDescr})); + next if ($self->check_filter(section => 'psu', instance => $result->{rlEnvMonSupplyStatusDescr})); next if ($result->{rlEnvMonSupplyState} eq 'notPresent' && $self->absent_problem(section => 'psu', instance => $result->{rlEnvMonSupplyStatusDescr})); $self->{components}->{psu}->{total}++; diff --git a/network/dlink/dgs3100/snmp/mode/hardware.pm b/network/dlink/dgs3100/snmp/mode/hardware.pm index d56eb2ecc..ff20f4981 100644 --- a/network/dlink/dgs3100/snmp/mode/hardware.pm +++ b/network/dlink/dgs3100/snmp/mode/hardware.pm @@ -20,189 +20,61 @@ package network::dlink::dgs3100::snmp::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -my $thresholds = { - psu => [ - ['shutdown', 'WARNING'], - ['warning', 'WARNING'], - ['critical', 'CRITICAL'], - ['notFunctioning', 'CRITICAL'], - ['notPresent', 'OK'], - ['normal', 'OK'], - ], - fan => [ - ['shutdown', 'WARNING'], - ['warning', 'WARNING'], - ['critical', 'CRITICAL'], - ['notFunctioning', 'CRITICAL'], - ['notPresent', 'OK'], - ['normal', 'OK'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(fan|psu)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + psu => [ + ['shutdown', 'WARNING'], + ['warning', 'WARNING'], + ['critical', 'CRITICAL'], + ['notFunctioning', 'CRITICAL'], + ['notPresent', 'OK'], + ['normal', 'OK'], + ], + fan => [ + ['shutdown', 'WARNING'], + ['warning', 'WARNING'], + ['critical', 'CRITICAL'], + ['notFunctioning', 'CRITICAL'], + ['notPresent', 'OK'], + ['normal', 'OK'], + ], + }; + + $self->{components_path} = 'network::dlink::dgs3100::snmp::mode::components'; + $self->{components_module} = ['fan', 'psu']; +} + +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); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_performance => 1); bless $self, $class; $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "exclude:s" => { name => 'exclude' }, - "component:s" => { name => 'component', default => '.*' }, - "absent-problem:s" => { name => 'absent' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, + { }); - $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'; - } - } - - $self->{overload_th} = {}; - foreach my $val (@{$self->{option_results}->{threshold_overload}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong treshold-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 treshold-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}; - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('fan', 'psu'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::dlink::dgs3100::snmp::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::dlink::dgs3100::snmp::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $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; -} - -sub absent_problem { - my ($self, %options) = @_; - - if (defined($self->{option_results}->{absent}) && - $self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - } - - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); - $self->{components}->{$options{section}}->{skip}++; - return 1; -} - -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; -} - 1; __END__ @@ -218,10 +90,10 @@ Check hardware (Fans, Power Supplies). Which component to check (Default: '.*'). Can be: 'psu', 'fan'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=psu) -Can also exclude specific instance: --exclude='fan#fan1_unit2#' +Exclude some parts (comma seperated list) (Example: --filter=psu) +Can also exclude specific instance: --filter=fan,fan1_unit2 =item B<--absent-problem> @@ -235,7 +107,7 @@ If total (with skipped) is 0. (Default: 'critical' returns). =item B<--threshold-overload> -Set to overload default threshold values (syntax: section,status,regexp) +Set to overload default threshold values (syntax: section,[instance,]status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='psu,CRITICAL,^(?!(normal)$)' diff --git a/network/dlink/standard/snmp/mode/components/fan.pm b/network/dlink/standard/snmp/mode/components/fan.pm index 4d0d9e5c2..deb12ab4d 100644 --- a/network/dlink/standard/snmp/mode/components/fan.pm +++ b/network/dlink/standard/snmp/mode/components/fan.pm @@ -41,9 +41,9 @@ my $mapping = { my $oid_swFanEntry = '.1.3.6.1.4.1.171.12.11.1.7.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_swFanEntry }; + push @{$self->{request}}, { oid => $oid_swFanEntry }; } sub check { @@ -51,14 +51,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking fans"); $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fan')); + return if ($self->check_filter(section => 'fan')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_swFanEntry}})) { next if ($oid !~ /^$mapping->{swFanStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_swFanEntry}, instance => $instance); - next if ($self->check_exclude(section => 'fan', instance => $instance)); + 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 [speed = %s].", diff --git a/network/dlink/standard/snmp/mode/components/psu.pm b/network/dlink/standard/snmp/mode/components/psu.pm index 3f82dd5ba..fba713ac0 100644 --- a/network/dlink/standard/snmp/mode/components/psu.pm +++ b/network/dlink/standard/snmp/mode/components/psu.pm @@ -40,9 +40,9 @@ my $mapping = { my $oid_swPowerEntry = '.1.3.6.1.4.1.171.12.11.1.6.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_swPowerEntry }; + push @{$self->{request}}, { oid => $oid_swPowerEntry }; } sub check { @@ -50,14 +50,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking power supplies"); $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'psu')); + return if ($self->check_filter(section => 'psu')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_swPowerEntry}})) { next if ($oid !~ /^$mapping->{swPowerStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_swPowerEntry}, instance => $instance); - next if ($self->check_exclude(section => 'psu', instance => $instance)); + 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.", diff --git a/network/dlink/standard/snmp/mode/components/temperature.pm b/network/dlink/standard/snmp/mode/components/temperature.pm index 0fc334b51..463c51b49 100644 --- a/network/dlink/standard/snmp/mode/components/temperature.pm +++ b/network/dlink/standard/snmp/mode/components/temperature.pm @@ -30,9 +30,9 @@ my $mapping = { my $oid_swTemperatureEntry = '.1.3.6.1.4.1.171.12.11.1.8.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_swTemperatureEntry }; + push @{$self->{request}}, { oid => $oid_swTemperatureEntry }; } sub check { @@ -40,14 +40,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking temperatures"); $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'temperature')); + return if ($self->check_filter(section => 'temperature')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_swTemperatureEntry}})) { next if ($oid !~ /^$mapping->{swTemperatureCurrent}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_swTemperatureEntry}, instance => $instance); - next if ($self->check_exclude(section => 'temperature', instance => $instance)); + next if ($self->check_filter(section => 'temperature', instance => $instance)); $self->{components}->{temperature}->{total}++; $self->{output}->output_add(long_msg => sprintf("Temperature '%s' is %dC.", diff --git a/network/dlink/standard/snmp/mode/hardware.pm b/network/dlink/standard/snmp/mode/hardware.pm index 4e982c94d..dad5c3d63 100644 --- a/network/dlink/standard/snmp/mode/hardware.pm +++ b/network/dlink/standard/snmp/mode/hardware.pm @@ -20,222 +20,64 @@ package network::dlink::standard::snmp::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -my $thresholds = { - psu => [ - ['connect', 'OK'], - ['working', 'OK'], - ['other', 'UNKNOWN'], - ['lowVoltage', 'WARNING'], - ['overCurrent', 'CRITICAL'], - ['fail', 'CRITICAL'], - ['disconnect', 'WARNING'], - ], - fan => [ - ['working', 'OK'], - ['fail', 'CRITICAL'], - ['other', 'UNKNOWN'], - ['speed-0', 'WARNING'], - ['speed-low', 'WARNING'], - ['speed-middle', 'OK'], - ['speed-high', 'WARNING'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(fan|psu)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(fan|temperature)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + psu => [ + ['connect', 'OK'], + ['working', 'OK'], + ['other', 'UNKNOWN'], + ['lowVoltage', 'WARNING'], + ['overCurrent', 'CRITICAL'], + ['fail', 'CRITICAL'], + ['disconnect', 'WARNING'], + ], + fan => [ + ['working', 'OK'], + ['fail', 'CRITICAL'], + ['other', 'UNKNOWN'], + ['speed-0', 'WARNING'], + ['speed-low', 'WARNING'], + ['speed-middle', 'OK'], + ['speed-high', 'WARNING'], + ], + }; + + $self->{components_path} = 'network::dlink::standard::snmp::mode::components'; + $self->{components_module} = ['fan', 'psu', 'temperature']; +} + +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); + 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 => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { }); - $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'; - } - } - - $self->{overload_th} = {}; - foreach my $val (@{$self->{option_results}->{threshold_overload}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong treshold-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 treshold-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->{numeric_threshold} = {}; - foreach my $option (('warning', 'critical')) { - foreach my $val (@{$self->{option_results}->{$option}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $regexp, $value) = ($1, $2, $3); - if ($section !~ /(fan|temperature)/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "' (type must be: temperature or fan)."); - $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, regexp => $regexp }; - } - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('fan', 'psu', 'temperature'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::dlink::standard::snmp::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::dlink::standard::snmp::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $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; -} - -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; -} - -sub get_severity_numeric { - 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} =~ /$_->{regexp}/) { - 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); -} - 1; __END__ @@ -251,10 +93,10 @@ Check hardware (Fans, Power Supplies, Temperatures). Which component to check (Default: '.*'). Can be: 'psu', 'fan', 'temperature'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=psu) -Can also exclude specific instance: --exclude='fan#1.1#' +Exclude some parts (comma seperated list) (Example: --filter=psu) +Can also exclude specific instance: --filter=fan,1.1 =item B<--no-component> @@ -269,12 +111,12 @@ Example: --threshold-overload='fan,CRITICAL,^(?!(working)$)' =item B<--warning> -Set warning threshold for temperatures (syntax: type,regexp,threshold) +Set warning threshold for temperatures (syntax: section,[instance,]status,regexp) Example: --warning='temperature,.*,30' --warning='fan,.*,1000' =item B<--critical> -Set critical threshold for temperatures (syntax: type,regexp,threshold) +Set critical threshold for temperatures (syntax: section,[instance,]status,regexp) Example: --critical='temperature,.*,40' =back diff --git a/network/extreme/snmp/mode/components/fan.pm b/network/extreme/snmp/mode/components/fan.pm index d84a83995..ba18742a3 100644 --- a/network/extreme/snmp/mode/components/fan.pm +++ b/network/extreme/snmp/mode/components/fan.pm @@ -35,9 +35,9 @@ my $mapping = { my $oid_extremeFanStatusEntry = '.1.3.6.1.4.1.1916.1.1.1.9.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_extremeFanStatusEntry, end => $mapping->{extremeFanOperational}->{oid} }; + push @{$self->{request}}, { oid => $oid_extremeFanStatusEntry, end => $mapping->{extremeFanOperational}->{oid} }; } sub check { @@ -45,7 +45,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking fans"); $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fan')); + return if ($self->check_filter(section => 'fan')); my ($exit, $warn, $crit, $checked); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_extremeFanStatusEntry}})) { @@ -53,7 +53,7 @@ sub check { my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_extremeFanStatusEntry}, instance => $instance); - next if ($self->check_exclude(section => 'fan', instance => $instance)); + 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, speed = %s]", diff --git a/network/extreme/snmp/mode/components/psu.pm b/network/extreme/snmp/mode/components/psu.pm index f79422f79..6ec457893 100644 --- a/network/extreme/snmp/mode/components/psu.pm +++ b/network/extreme/snmp/mode/components/psu.pm @@ -40,9 +40,9 @@ my $mapping = { my $oid_extremePowerSupplyEntry = '.1.3.6.1.4.1.1916.1.1.1.27.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_extremePowerSupplyEntry, start => $mapping->{extremePowerSupplyStatus}->{oid} }; + push @{$self->{request}}, { oid => $oid_extremePowerSupplyEntry, start => $mapping->{extremePowerSupplyStatus}->{oid} }; } sub check_fan_speed { @@ -69,14 +69,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking power supplies"); $self->{components}->{psu} = {name => 'power supplies', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'psu')); + return if ($self->check_filter(section => 'psu')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_extremePowerSupplyEntry}})) { next if ($oid !~ /^$mapping->{extremePowerSupplyStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_extremePowerSupplyEntry}, instance => $instance); - next if ($self->check_exclude(section => 'psu', instance => $instance)); + next if ($self->check_filter(section => 'psu', instance => $instance)); if ($result->{extremePowerSupplyStatus} =~ /notPresent/i) { $self->absent_problem(section => 'psu', instance => $instance); next; diff --git a/network/extreme/snmp/mode/components/slot.pm b/network/extreme/snmp/mode/components/slot.pm index 90bf3d4c1..138d7a879 100644 --- a/network/extreme/snmp/mode/components/slot.pm +++ b/network/extreme/snmp/mode/components/slot.pm @@ -48,9 +48,9 @@ my $mapping = { my $oid_extremeSlotEntry = '.1.3.6.1.4.1.1916.1.1.2.2.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_extremeSlotEntry, start => $mapping->{extremeSlotName}->{oid}, end => $mapping->{extremeSlotModuleState}->{oid} }; + push @{$self->{request}}, { oid => $oid_extremeSlotEntry, start => $mapping->{extremeSlotName}->{oid}, end => $mapping->{extremeSlotModuleState}->{oid} }; } sub check { @@ -58,14 +58,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking slots"); $self->{components}->{slot} = {name => 'slots', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'slot')); + return if ($self->check_filter(section => 'slot')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_extremeSlotEntry}})) { next if ($oid !~ /^$mapping->{extremeSlotModuleState}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_extremeSlotEntry}, instance => $instance); - next if ($self->check_exclude(section => 'slot', instance => $instance)); + next if ($self->check_filter(section => 'slot', instance => $instance)); if ($result->{extremeSlotModuleState} =~ /notPresent/i) { $self->absent_problem(section => 'slot', instance => $instance); next; diff --git a/network/extreme/snmp/mode/components/temperature.pm b/network/extreme/snmp/mode/components/temperature.pm index 995af0721..4afff714a 100644 --- a/network/extreme/snmp/mode/components/temperature.pm +++ b/network/extreme/snmp/mode/components/temperature.pm @@ -28,9 +28,9 @@ my $mapping = { }; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $mapping->{extremeCurrentTemperature}->{oid} }; + push @{$self->{request}}, { oid => $mapping->{extremeCurrentTemperature}->{oid} }; } sub check { @@ -38,13 +38,13 @@ sub check { $self->{output}->output_add(long_msg => "Checking temperatures"); $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'temperature')); + return if ($self->check_filter(section => 'temperature')); return if (!defined($self->{results}->{$mapping->{extremeCurrentTemperature}->{oid}}->{$mapping->{extremeCurrentTemperature}->{oid} . '.0'})); my $instance = 0; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{extremeCurrentTemperature}->{oid}}, instance => $instance); - next if ($self->check_exclude(section => 'temperature', instance => $instance)); + next if ($self->check_filter(section => 'temperature', instance => $instance)); $self->{components}->{temperature}->{total}++; $self->{output}->output_add(long_msg => sprintf("temperature is %dC [instance: %s].", diff --git a/network/extreme/snmp/mode/cpu.pm b/network/extreme/snmp/mode/cpu.pm index 1ead97521..cd045a7c3 100644 --- a/network/extreme/snmp/mode/cpu.pm +++ b/network/extreme/snmp/mode/cpu.pm @@ -20,71 +20,89 @@ package network::extreme::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 $maps_counters = { - cpu => { - '000_5secs' => { set => { - key_values => [ { name => 'extremeCpuMonitorSystemUtilization5secs' }, { name => 'num' }, ], - output_template => '5 seconds : %.2f %%', - perfdatas => [ - { label => 'cpu_5secs', value => 'extremeCpuMonitorSystemUtilization5secs_absolute', template => '%.2f', - min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'num_absolute' }, - ], - } - }, - '001_10secs' => { set => { - key_values => [ { name => 'extremeCpuMonitorSystemUtilization10secs' }, { name => 'num' }, ], - output_template => '10 seconds : %.2f %%', - perfdatas => [ - { label => 'cpu_10secs', value => 'extremeCpuMonitorSystemUtilization10secs_absolute', template => '%.2f', - min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'num_absolute' }, - ], - } - }, - '002_30secs' => { set => { - key_values => [ { name => 'extremeCpuMonitorSystemUtilization30secs' }, { name => 'num' }, ], - output_template => '30 seconds : %.2f %%', - perfdatas => [ - { label => 'cpu_30secs', value => 'extremeCpuMonitorSystemUtilization30secs_absolute', template => '%.2f', - min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'num_absolute' }, - ], - } - }, - '003_1min' => { set => { - key_values => [ { name => 'extremeCpuMonitorSystemUtilization1min' }, { name => 'num' }, ], - output_template => '1 minute : %.2f %%', - perfdatas => [ - { label => 'cpu_1min', value => 'extremeCpuMonitorSystemUtilization1min_absolute', template => '%.2f', - min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'num_absolute' }, - ], - } - }, - '004_5min' => { set => { - key_values => [ { name => 'extremeCpuMonitorSystemUtilization5mins' }, { name => 'num' }, ], - output_template => '5 minutes : %.2f %%', - perfdatas => [ - { label => 'cpu_5min', value => 'extremeCpuMonitorSystemUtilization5mins_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 => 'global', type => 0, cb_init => 'skip_global', }, + { name => 'cpu', type => 1, cb_prefix_output => 'prefix_cpu_output', message_multiple => 'All CPU usages are ok' } + ]; + $self->{maps_counters}->{global} = [ + { label => 'total', set => { + key_values => [ { name => 'total' } ], + output_template => 'Total CPU Usage : %.2f %%', + perfdatas => [ + { label => 'cpu_total', value => 'total_absolute', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } }, - total => { - '000_total' => { set => { - key_values => [ { name => 'total' } ], - output_template => 'CPU Usage : %.2f %%', - perfdatas => [ - { label => 'cpu_total', value => 'total_absolute', template => '%.2f', min => 0, max => 100, unit => '%' }, - ], - } - }, - } -}; + ]; + + $self->{maps_counters}->{cpu} = [ + { label => '5secs', set => { + key_values => [ { name => 'extremeCpuMonitorSystemUtilization5secs' }, { name => 'num' }, ], + output_template => '5 seconds : %.2f %%', + perfdatas => [ + { label => 'cpu_5secs', value => 'extremeCpuMonitorSystemUtilization5secs_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'num_absolute' }, + ], + } + }, + { label => '10secs', set => { + key_values => [ { name => 'extremeCpuMonitorSystemUtilization10secs' }, { name => 'num' }, ], + output_template => '10 seconds : %.2f %%', + perfdatas => [ + { label => 'cpu_10secs', value => 'extremeCpuMonitorSystemUtilization10secs_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'num_absolute' }, + ], + } + }, + { label => '30secs', set => { + key_values => [ { name => 'extremeCpuMonitorSystemUtilization30secs' }, { name => 'num' }, ], + output_template => '30 seconds : %.2f %%', + perfdatas => [ + { label => 'cpu_30secs', value => 'extremeCpuMonitorSystemUtilization30secs_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'num_absolute' }, + ], + } + }, + { label => '1min', set => { + key_values => [ { name => 'extremeCpuMonitorSystemUtilization1min' }, { name => 'num' }, ], + output_template => '1 minute : %.2f %%', + perfdatas => [ + { label => 'cpu_1min', value => 'extremeCpuMonitorSystemUtilization1min_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'num_absolute' }, + ], + } + }, + { label => '5min', set => { + key_values => [ { name => 'extremeCpuMonitorSystemUtilization5mins' }, { name => 'num' }, ], + output_template => '5 minutes : %.2f %%', + perfdatas => [ + { label => 'cpu_5min', value => 'extremeCpuMonitorSystemUtilization5mins_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'num_absolute' }, + ], + } + }, + ]; +} + +sub skip_global { + my ($self, %options) = @_; + + scalar(keys %{$self->{cpu}}) > 1 ? return(0) : return(1); +} + +sub prefix_cpu_output { + my ($self, %options) = @_; + + return "CPU '" . $options{instance_value}->{num} . "' "; +} sub new { my ($class, %options) = @_; @@ -94,147 +112,11 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { - }); - - foreach my $key (('cpu', '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 { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('cpu', '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) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{cpu}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->check_total(); - } - - #### - # By CPU - 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(extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "CPU '" . $self->{cpu}->{$id}->{num} . "' 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 => "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 $mapping = { extremeCpuMonitorSystemUtilization5secs => { oid => '.1.3.6.1.4.1.1916.1.32.1.4.1.5' }, extremeCpuMonitorSystemUtilization10secs => { oid => '.1.3.6.1.4.1.1916.1.32.1.4.1.6' }, @@ -248,23 +130,22 @@ sub manage_selection { my $oid_extremeCpuMonitorSystemEntry = '.1.3.6.1.4.1.1916.1.32.1.4.1'; my $oid_extremeCpuMonitorTotalUtilization = '.1.3.6.1.4.1.1916.1.32.1.2'; # without .0 - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ + $self->{results} = $options{snmp}->get_multiple_table(oids => [ { oid => $oid_extremeCpuMonitorTotalUtilization }, { oid => $oid_extremeCpuMonitorSystemEntry }, - ], - , nothing_quit => 1); + ], nothing_quit => 1); $self->{cpu} = {}; foreach my $oid (keys %{$self->{results}->{$oid_extremeCpuMonitorSystemEntry}}) { next if ($oid !~ /^$mapping->{extremeCpuMonitorSystemUtilization1min}->{oid}\.(.*)$/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_extremeCpuMonitorSystemEntry}, instance => $instance); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_extremeCpuMonitorSystemEntry}, instance => $instance); foreach (keys %{$mapping}) { $result->{$_} = undef if (defined($result->{$_}) && $result->{$_} =~ /n\/a/i); } - $self->{cpu}->{$instance} = {num => $instance, %$result}; + $self->{cpu}->{$instance} = { num => $instance, %$result }; } $self->{global} = { total => $self->{results}->{$oid_extremeCpuMonitorTotalUtilization}->{$oid_extremeCpuMonitorTotalUtilization . '.0'} }; @@ -280,6 +161,11 @@ Check CPU usages. =over 8 +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^(1min|5min)$' + =item B<--warning-*> Threshold warning. diff --git a/network/extreme/snmp/mode/hardware.pm b/network/extreme/snmp/mode/hardware.pm index befb4e05c..b7a908093 100644 --- a/network/extreme/snmp/mode/hardware.pm +++ b/network/extreme/snmp/mode/hardware.pm @@ -20,40 +20,59 @@ package network::extreme::snmp::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -my $thresholds = { - psu => [ - ['notPresent', 'OK'], - ['presentOK', 'OK'], - ['presentPowerOff', 'WARNING'], - ['presentNotOK', 'CRITICAL'], - ], - fan => [ - ['not operational', 'CRITICAL'], - ['operational', 'OK'], - ], - slot => [ - ['notPresent', 'OK'], - ['testing', 'OK'], - ['mismatch', 'WARNING'], - ['failed', 'CRITICAL'], - ['operational', 'OK'], - ['powerdown', 'WARNING'], - ['unknown', 'UNKNOWN'], - ['present', 'OK'], - ['poweron', 'OK'], - ['post', 'UNKNOWN'], - ['downloading', 'WARNING'], - ['booting', 'WARNING'], - ['offline', 'WARNING'], - ['initializing', 'OK'], - ['invalid', 'CRITICAL'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(fan|psu|slot)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|fan|psu\.power|psu\.fan)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + psu => [ + ['notPresent', 'OK'], + ['presentOK', 'OK'], + ['presentPowerOff', 'WARNING'], + ['presentNotOK', 'CRITICAL'], + ], + fan => [ + ['not operational', 'CRITICAL'], + ['operational', 'OK'], + ], + slot => [ + ['notPresent', 'OK'], + ['testing', 'OK'], + ['mismatch', 'WARNING'], + ['failed', 'CRITICAL'], + ['operational', 'OK'], + ['powerdown', 'WARNING'], + ['unknown', 'UNKNOWN'], + ['present', 'OK'], + ['poweron', 'OK'], + ['post', 'UNKNOWN'], + ['downloading', 'WARNING'], + ['booting', 'WARNING'], + ['offline', 'WARNING'], + ['initializing', 'OK'], + ['invalid', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'network::extreme::snmp::mode::components'; + $self->{components_module} = ['fan', 'psu', 'slot', 'temperature']; +} + +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) = @_; @@ -63,206 +82,11 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "exclude:s" => { name => 'exclude' }, - "absent-problem:s" => { name => 'absent' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, }); - - $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'; - } - } - - $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->{numeric_threshold} = {}; - foreach my $option (('warning', 'critical')) { - foreach my $val (@{$self->{option_results}->{$option}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $regexp, $value) = ($1, $2, $3); - if ($section !~ /^(temperature|fan|psu\.power|psu\.fan)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "' (type must be: temperature, fan, psu.power, psu.fan)."); - $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, regexp => $regexp }; - } - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('fan', 'psu', 'slot', 'temperature'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::extreme::snmp::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::extreme::snmp::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $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; -} - -sub absent_problem { - my ($self, %options) = @_; - - if (defined($self->{option_results}->{absent}) && - $self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - } - - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); - $self->{components}->{$options{section}}->{skip}++; - return 1; -} - -sub get_severity_numeric { - 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} =~ /$_->{regexp}/) { - 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 - - 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; -} - 1; __END__ @@ -278,15 +102,15 @@ Check Hardware (Fans, Power Supplies, Slot, Temperature). Which component to check (Default: '.*'). Can be: 'fan', 'psu', 'slot', 'temperature'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=fan) -Can also exclude specific instance: --exclude=fan#101# +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=psu) +Can also exclude specific instance: --filter=fan,101 =item B<--absent-problem> Return an error if an entity is not 'present' (default is skipping) (comma seperated list) -Can be specific or global: --absent-problem=psu#1# +Can be specific or global: --absent-problem=psu,1 =item B<--no-component> @@ -295,7 +119,7 @@ If total (with skipped) is 0. (Default: 'critical' returns). =item B<--threshold-overload> -Set to overload default threshold values (syntax: section,status,regexp) +Set to overload default threshold values (syntax: section,[instance,]status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='psu,CRITICAL,^(?!(presentOK)$)' diff --git a/network/extreme/snmp/mode/memory.pm b/network/extreme/snmp/mode/memory.pm index 2d7b224f6..5444bb1ef 100644 --- a/network/extreme/snmp/mode/memory.pm +++ b/network/extreme/snmp/mode/memory.pm @@ -20,24 +20,10 @@ package network::extreme::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 $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) = @_; @@ -86,6 +72,31 @@ 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', 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 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); @@ -94,95 +105,11 @@ sub new { $self->{version} = '1.0'; $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 }, - }); - } - $maps_counters->{$_}->{obj} = centreon::plugins::values->new(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}); - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $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(extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Memory '" . $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 => "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 $mapping = { extremeMemoryMonitorSystemFree => { oid => '.1.3.6.1.4.1.1916.1.32.2.2.1.3' }, extremeMemoryMonitorSystemTotal => { oid => '.1.3.6.1.4.1.1916.1.32.2.2.1.2' }, @@ -191,17 +118,17 @@ my $mapping = { sub manage_selection { my ($self, %options) = @_; - $self->{memory_selected} = {}; + $self->{memory} = {}; my $oid_extremeMemoryMonitorSystemEntry = '.1.3.6.1.4.1.1916.1.32.2.2.1'; - $self->{results} = $self->{snmp}->get_table(oid => $oid_extremeMemoryMonitorSystemEntry, - nothing_quit => 1); + $self->{results} = $options{snmp}->get_table(oid => $oid_extremeMemoryMonitorSystemEntry, + nothing_quit => 1); foreach my $oid (keys %{$self->{results}}) { next if ($oid !~ /^$mapping->{extremeMemoryMonitorSystemFree}->{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 => $self->{results}, instance => $instance); - $self->{memory_selected}->{$instance} = { display => $instance, - free => $result->{extremeMemoryMonitorSystemFree} * 1024, total => $result->{extremeMemoryMonitorSystemTotal} * 1024}; + $self->{memory}->{$instance} = { display => $instance, + free => $result->{extremeMemoryMonitorSystemFree} * 1024, total => $result->{extremeMemoryMonitorSystemTotal} * 1024}; } } diff --git a/network/f5/bigip/mode/components/fan.pm b/network/f5/bigip/mode/components/fan.pm index 3218c2697..912d701e8 100644 --- a/network/f5/bigip/mode/components/fan.pm +++ b/network/f5/bigip/mode/components/fan.pm @@ -29,43 +29,59 @@ my %map_status = ( 2 => 'notPresent', ); +my $mapping = { + sysChassisFanStatus => { oid => '.1.3.6.1.4.1.3375.2.1.3.2.1.2.1.2', map => \%map_status }, + sysChassisFanSpeed => { oid => '.1.3.6.1.4.1.3375.2.1.3.2.1.2.1.3' }, +}; +my $oid_sysChassisFanEntry = '.1.3.6.1.4.1.3375.2.1.3.2.1.2.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_sysChassisFanEntry }; +} + sub check { my ($self) = @_; - $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; $self->{output}->output_add(long_msg => "Checking fans"); - return if ($self->check_exclude(section => 'fan')); - - my $oid_sysChassisFanEntry = '.1.3.6.1.4.1.3375.2.1.3.2.1.2.1'; - my $oid_sysChassisFanStatus = '.1.3.6.1.4.1.3375.2.1.3.2.1.2.1.2'; - my $oid_sysChassisFanSpeed = '.1.3.6.1.4.1.3375.2.1.3.2.1.2.1.3'; - - my $result = $self->{snmp}->get_table(oid => $oid_sysChassisFanEntry); - return if (scalar(keys %$result) <= 0); + $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; + return if ($self->check_filter(section => 'fan')); - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - next if ($key !~ /^$oid_sysChassisFanStatus\.(\d+)$/); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_sysChassisFanEntry}})) { + next if ($oid !~ /^$mapping->{sysChassisFanStatus}->{oid}\.(.*)$/); my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_sysChassisFanEntry}, instance => $instance); - next if ($self->check_exclude(section => 'fan', instance => $instance)); - - my $status = $result->{$oid_sysChassisFanStatus . '.' . $instance}; - my $speed = $result->{$oid_sysChassisFanSpeed . '.' . $instance}; - + next if ($result->{sysChassisFanStatus} =~ /notPresent/i && + $self->absent_problem(section => 'fan', instance => $instance)); + 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, $map_status{$status})); - if ($status < 1) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Fan '%s' status is %s", - $instance, $map_status{$status})); + + $self->{output}->output_add(long_msg => sprintf("fan '%s' status is '%s' [instance: %s, speed: %s].", + $instance, $result->{sysChassisFanStatus}, $instance, + defined($result->{sysChassisFanSpeed}) ? $result->{sysChassisFanSpeed} : '-')); + my $exit = $self->get_severity(section => 'fan', value => $result->{sysChassisFanStatus}); + 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'", + $instance, $result->{sysChassisFanStatus})); } - - $self->{output}->perfdata_add(label => "fan_" . $instance, - value => $speed, - ); - } - + + if (defined($result->{sysChassisFanSpeed}) && $result->{sysChassisFanSpeed} =~ /[0-9]/) { + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $result->{sysChassisFanSpeed}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $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); + } + } } 1; diff --git a/network/f5/bigip/mode/components/psu.pm b/network/f5/bigip/mode/components/psu.pm index e43902701..705fa73bf 100644 --- a/network/f5/bigip/mode/components/psu.pm +++ b/network/f5/bigip/mode/components/psu.pm @@ -29,33 +29,42 @@ my %map_status = ( 2 => 'notPresent', ); +my $mapping = { + sysChassisPowerSupplyStatus => { oid => '.1.3.6.1.4.1.3375.2.1.3.2.2.2.1.2', map => \%map_status }, +}; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping->{sysChassisPowerSupplyStatus}->{oid} }; +} + sub check { my ($self) = @_; - $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; $self->{output}->output_add(long_msg => "Checking power supplies"); - return if ($self->check_exclude(section => 'psu')); - - my $oid_sysChassisPowerSupplyEntry = '.1.3.6.1.4.1.3375.2.1.3.2.2.2.1'; - my $oid_sysChassisPowerSupplyStatus = '.1.3.6.1.4.1.3375.2.1.3.2.2.2.1.2'; - - my $result = $self->{snmp}->get_table(oid => $oid_sysChassisPowerSupplyEntry); - return if (scalar(keys %$result) <= 0); + $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; + return if ($self->check_filter(section => 'psu')); - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - next if ($key !~ /^$oid_sysChassisPowerSupplyStatus\.(\d+)$/); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$mapping->{sysChassisPowerSupplyStatus}->{oid}}})) { + $oid =~ /^$mapping->{sysChassisPowerSupplyStatus}->{oid}\.(.*)$/; my $instance = $1; - next if ($self->check_exclude(section => 'psu', instance => $instance)); + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{sysChassisPowerSupplyStatus}->{oid}}, instance => $instance); - my $status = $result->{$oid_sysChassisPowerSupplyStatus . '.' . $instance}; - + next if ($result->{sysChassisPowerSupplyStatus} =~ /notPresent/i && + $self->absent_problem(section => 'psu', instance => $instance)); + 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.", - $instance, $map_status{$status})); - if ($status < 1) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Power Supply '%s' status is %s", - $instance, $map_status{$status})); + + $self->{output}->output_add(long_msg => sprintf("power supply '%s' status is '%s' [instance: %s].", + $instance, $result->{sysChassisPowerSupplyStatus}, $instance + )); + my $exit = $self->get_severity(section => 'psu', value => $result->{sysChassisPowerSupplyStatus}); + 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'", + $instance, $result->{sysChassisPowerSupplyStatus})); } } } diff --git a/network/f5/bigip/mode/components/temperature.pm b/network/f5/bigip/mode/components/temperature.pm index db2840ee9..c2b5fe378 100644 --- a/network/f5/bigip/mode/components/temperature.pm +++ b/network/f5/bigip/mode/components/temperature.pm @@ -23,37 +23,46 @@ package network::f5::bigip::mode::components::temperature; use strict; use warnings; -sub check { +my $mapping = { + sysChassisTempTemperature => { oid => '.1.3.6.1.4.1.3375.2.1.3.2.3.2.1.2' }, +}; + +sub load { my ($self) = @_; + push @{$self->{request}}, { oid => $mapping->{sysChassisTempTemperature}->{oid} }; +} + +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_exclude(section => 'temperature')); + return if ($self->check_filter(section => 'temperature')); - my $oid_sysChassisTempEntry = '.1.3.6.1.4.1.3375.2.1.3.2.3.2.1'; - my $oid_sysChassisTempTemperature = '.1.3.6.1.4.1.3375.2.1.3.2.3.2.1.2'; - - my $result = $self->{snmp}->get_table(oid => $oid_sysChassisTempEntry); - return if (scalar(keys %$result) <= 0); - - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - next if ($key !~ /^$oid_sysChassisTempTemperature\.(\d+)$/); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$mapping->{sysChassisTempTemperature}->{oid}}})) { + $oid =~ /^$mapping->{sysChassisTempTemperature}->{oid}\.(.*)$/; my $instance = $1; - next if ($self->check_exclude(section => 'temperature', instance => $instance)); + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{sysChassisTempTemperature}->{oid}}, instance => $instance); + + next if ($self->check_filter(section => 'temperature', instance => $instance)); - my $exit_code = $self->{perfdata}->threshold_check(value => $result->{$oid_sysChassisTempTemperature . '.' . $instance}, - threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - - $self->{components}->{temperature}->{total}++; - $self->{output}->output_add(severity => $exit_code,long_msg => sprintf("temp_" . $instance . " is %.2f C", $result->{$oid_sysChassisTempTemperature . '.' . $instance})); - if (!$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit_code,short_msg => sprintf("temp_" . $instance . " is %.2f C", $result->{$oid_sysChassisTempTemperature . '.' . $instance})); + $self->{components}->{temperature}->{total}++; + $self->{output}->output_add(long_msg => sprintf("temperature '%s' is %.2f C [instance: %s].", + $instance, $result->{sysChassisTempTemperature}, $instance + )); + + if (defined($result->{sysChassisTempTemperature}) && $result->{sysChassisTempTemperature} =~ /[0-9]/) { + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{sysChassisTempTemperature}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $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_" . $instance , unit => 'C', - value => sprintf("%.2f", $result->{$oid_sysChassisTempTemperature . '.' . $instance}), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical')); } } diff --git a/network/f5/bigip/mode/connections.pm b/network/f5/bigip/mode/connections.pm index fd4a55d81..863e30138 100644 --- a/network/f5/bigip/mode/connections.pm +++ b/network/f5/bigip/mode/connections.pm @@ -20,97 +20,123 @@ package network::f5::bigip::mode::connections; -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_client_tps_calc { + my ($self, %options) = @_; + + my $diff_native = $options{new_datas}->{$self->{instance} . '_client_ssl_tot_native'} - $options{old_datas}->{$self->{instance} . '_client_ssl_tot_native'}; + my $diff_compat = $options{new_datas}->{$self->{instance} . '_client_ssl_tot_compat'} - $options{old_datas}->{$self->{instance} . '_client_ssl_tot_compat'}; + $self->{result_values}->{client_ssl_tps} = ($diff_native + $diff_compat) / $options{delta_time}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + $self->{maps_counters}->{global} = [ + { label => 'client', set => { + key_values => [ { name => 'client' } ], + output_template => 'Current client connections : %s', + perfdatas => [ + { label => 'Client', value => 'client_absolute', template => '%s', + min => 0, unit => 'con' }, + ], + } + }, + { label => 'client-ssl', set => { + key_values => [ { name => 'client_ssl' } ], + output_template => 'Current client SSL connections : %s', + perfdatas => [ + { label => 'ClientSSL', value => 'client_ssl_absolute', template => '%s', + min => 0, unit => 'con' }, + ], + } + }, + { label => 'client-ssl-tps', set => { + key_values => [ { name => 'client_ssl_tot_native', diff => 1 }, { name => 'client_ssl_tot_compat', diff => 1 } ], + output_template => 'TPS client SSL connections : %.2f', threshold_use => 'client_ssl_tps', output_use => 'client_ssl_tps', + closure_custom_calc => $self->can('custom_client_tps_calc'), + per_second => 1, + perfdatas => [ + { label => 'ClientSSL_Tps', value => 'client_ssl_tps', template => '%.2f', + unit => 'tps', min => 0 }, + ], + } + }, + { label => 'server', set => { + key_values => [ { name => 'server' } ], + output_template => 'Current server connections: %s', + perfdatas => [ + { label => 'Server', value => 'server_absolute', template => '%s', + min => 0, unit => 'con' }, + ], + } + }, + { label => 'server-ssl', set => { + key_values => [ { name => 'server_ssl' } ], + output_template => 'Current server SSL connections : %s', + perfdatas => [ + { label => 'ServerSSL', value => 'server_ssl_absolute', template => '%s', + min => 0, unit => 'con' }, + ], + } + }, + ]; +} 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-client:s" => { name => 'warning_client' }, - "critical-client:s" => { name => 'critical_client' }, - "warning-server:s" => { name => 'warning_server' }, - "critical-server:s" => { name => 'critical_server' }, + "filter-counters:s" => { name => 'filter_counters' }, }); - + return $self; } -sub check_options { +sub manage_selection { my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning-client', value => $self->{option_results}->{warning_client})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning-client threshold '" . $self->{option_results}->{option_results}->{warning_client} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical-client', value => $self->{option_results}->{critical_client})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical-client threshold '" . $self->{option_results}->{critical_client} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'warning-server', value => $self->{option_results}->{warning_server})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning-server threshold '" . $self->{option_results}->{warning_client} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical-server', value => $self->{option_results}->{critical_server})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical-server threshold '" . $self->{option_results}->{critical_client} . "'."); - $self->{output}->option_exit(); - } -} -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; + $self->{cache_name} = "f5_bipgip_" . $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')); - if ($self->{snmp}->is_snmpv1()) { - $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); - $self->{output}->option_exit(); - } - my $oid_sysStatClientCurConns = '.1.3.6.1.4.1.3375.2.1.1.2.1.8.0'; my $oid_sysStatServerCurConns = '.1.3.6.1.4.1.3375.2.1.1.2.1.15.0'; my $oid_sysClientsslStatCurConns = '.1.3.6.1.4.1.3375.2.1.1.2.9.2.0'; my $oid_sysServersslStatCurConns = '.1.3.6.1.4.1.3375.2.1.1.2.10.2.0'; - - my $result = $self->{snmp}->get_leef(oids => [$oid_sysStatClientCurConns, $oid_sysStatServerCurConns, $oid_sysClientsslStatCurConns, $oid_sysServersslStatCurConns], nothing_quit => 1); + my $oid_sysClientsslStatTotNativeConns = '.1.3.6.1.4.1.3375.2.1.1.2.9.6.0'; + my $oid_sysClientsslStatTotCompatConns = '.1.3.6.1.4.1.3375.2.1.1.2.9.9.0'; - my $sysStatClientCurConns = $result->{$oid_sysStatClientCurConns}; - my $sysStatServerCurConns = $result->{$oid_sysStatServerCurConns}; - my $sysClientsslStatCurConns = $result->{$oid_sysClientsslStatCurConns}; - my $sysServersslStatCurConns = $result->{$oid_sysServersslStatCurConns}; + if ($options{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); + $self->{output}->option_exit(); + } - my $exit1 = $self->{perfdata}->threshold_check(value => $sysStatClientCurConns, threshold => [ { label => 'critical-client', 'exit_litteral' => 'critical' }, { label => 'warning-client', exit_litteral => 'warning' } ]); - my $exit2 = $self->{perfdata}->threshold_check(value => $sysStatServerCurConns, threshold => [ { label => 'critical-server', 'exit_litteral' => 'critical' }, { label => 'warning-server', exit_litteral => 'warning' } ]); - my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2 ]); - - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Current connections : Client = %d (SSL: %d) , Server = %d (SSL: %d)", - $sysStatClientCurConns, $sysClientsslStatCurConns, - $sysStatServerCurConns, $sysServersslStatCurConns)); - $self->{output}->perfdata_add(label => "Client", unit => 'con', - value => $sysStatClientCurConns, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-client'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-client'), - ); - $self->{output}->perfdata_add(label => "Server", unit => 'con', - value => $sysStatServerCurConns, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-server'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-server'), - ); - $self->{output}->perfdata_add(label => "ClientSSL", unit => 'con', - value => $sysClientsslStatCurConns); - $self->{output}->perfdata_add(label => "ServerSSL", unit => 'con', - value => $sysServersslStatCurConns); - - $self->{output}->display(); - $self->{output}->exit(); + my $result = $options{snmp}->get_leef(oids => [$oid_sysStatClientCurConns, $oid_sysStatServerCurConns, + $oid_sysClientsslStatCurConns, $oid_sysServersslStatCurConns, + $oid_sysClientsslStatTotNativeConns, $oid_sysClientsslStatTotCompatConns], + nothing_quit => 1); + $self->{global} = { + client => $result->{$oid_sysStatClientCurConns}, + client_ssl => $result->{$oid_sysClientsslStatCurConns}, + client_ssl_tot_native => $result->{$oid_sysClientsslStatTotNativeConns}, + client_ssl_tot_compat => $result->{$oid_sysClientsslStatTotCompatConns}, + server => $result->{$oid_sysStatServerCurConns}, + server_ssl => $result->{$oid_sysServersslStatCurConns}, + }; } 1; @@ -123,23 +149,21 @@ Check current connections on F5 BIG IP device. =over 8 -=item B<--warning-client> +=item B<--filter-counters> -Threshold warning (current client connection number) +Only display some counters (regexp can be used). +Example to check SSL connections only : --filter-counters='^client-ssl|server-ssl$' -=item B<--critical-client> +=item B<--warning-*> -Threshold critical (current client connection number) +Threshold warning. +Can be: 'client', 'server', 'client-ssl', 'server-ssl', 'client-ssl-tps'. -=item B<--warning-server> +=item B<--critical-*> -Threshold warning (current server connection number) - -=item B<--critical-server> - -Threshold critical (current server connection number) +Threshold critical. +Can be: 'client', 'server', 'client-ssl', 'server-ssl', 'client-ssl-tps'. =back -=cut - +=cut \ No newline at end of file diff --git a/network/f5/bigip/mode/failover.pm b/network/f5/bigip/mode/failover.pm new file mode 100644 index 000000000..355407b7e --- /dev/null +++ b/network/f5/bigip/mode/failover.pm @@ -0,0 +1,337 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::f5::bigip::mode::failover; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::values; + +my $instance_mode; + +my $maps_counters = { + global => [ + { label => 'sync-status', threshold => 0, set => { + key_values => [ { name => 'syncstatus' } ], + closure_custom_calc => \&custom_syncstatus_calc, + closure_custom_output => \&custom_syncstatus_output, + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&custom_syncstatus_threshold, + } + }, + { label => 'failover-status', threshold => 0, set => { + key_values => [ { name => 'failoverstatus' } ], + closure_custom_calc => \&custom_failoverstatus_calc, + closure_custom_output => \&custom_failoverstatus_output, + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&custom_failoverstatus_threshold, + } + }, + ] +}; + +sub custom_syncstatus_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_sync_status}) && $instance_mode->{option_results}->{critical_sync_status} ne '' && + eval "$instance_mode->{option_results}->{critical_sync_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{critical_sync_status}) && $instance_mode->{option_results}->{critical_sync_status} ne '' && + eval "$instance_mode->{option_results}->{critical_sync_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_syncstatus_output { + my ($self, %options) = @_; + my $msg = "Sync status is '" . $self->{result_values}->{syncstatus} . "'"; + + return $msg; +} + +sub custom_syncstatus_calc { + my ($self, %options) = @_; + + $self->{result_values}->{syncstatus} = $options{new_datas}->{$self->{instance} . '_syncstatus'}; + return 0; +} + +sub custom_failoverstatus_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_failover_status}) && $instance_mode->{option_results}->{critical_failover_status} ne '' && + eval "$instance_mode->{option_results}->{critical_failover_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{critical_failover_status}) && $instance_mode->{option_results}->{critical_failover_status} ne '' && + eval "$instance_mode->{option_results}->{critical_failover_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_failoverstatus_output { + my ($self, %options) = @_; + my $msg = "Failover status is '" . $self->{result_values}->{failoverstatus} . "'"; + + return $msg; +} + +sub custom_failoverstatus_calc { + my ($self, %options) = @_; + + $self->{result_values}->{failoverstatus} = $options{new_datas}->{$self->{instance} . '_failoverstatus'}; + 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-counters:s" => { name => 'filter_counters' }, + "warning-sync-status:s" => { name => 'warning_sync_status', default => '' }, + "critical-sync-status:s" => { name => 'critical_sync_status', default => '%{syncstatus} =~ /unknown|syncFailed|syncDisconnected|incompatibleVersion/' }, + "warning-failover-status:s" => { name => 'warning_failover_status', default => '' }, + "critical-failover-status:s" => { name => 'critical_failover_status', default => '%{failoverstatus} =~ /unknown/' }, + }); + + foreach my $key (('global')) { + foreach (@{$maps_counters->{$key}}) { + if (!defined($_->{threshold}) || $_->{threshold} != 0) { + $options{options}->add_options(arguments => { + 'warning-' . $_->{label} . ':s' => { name => 'warning-' . $_->{label} }, + 'critical-' . $_->{label} . ':s' => { name => 'critical-' . $_->{label} }, + }); + } + $_->{obj} = centreon::plugins::values->new(statefile => $self->{statefile_value}, + output => $self->{output}, perfdata => $self->{perfdata}, + label => $_->{label}); + $_->{obj}->set(%{$_->{set}}); + } + } + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + foreach my $key (('global')) { + foreach (@{$maps_counters->{$key}}) { + $_->{obj}->init(option_results => $self->{option_results}); + } + } + + $instance_mode = $self; + $self->change_macros(); +} + +sub run_global { + my ($self, %options) = @_; + + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits; + foreach (@{$maps_counters->{global}}) { + my $obj = $_->{obj}; + + next if (defined($self->{option_results}->{filter_counters}) && $self->{option_results}->{filter_counters} ne '' && + $_->{name} !~ /$self->{option_results}->{filter_counters}/); + + $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->manage_selection(%options); + + $self->run_global(); + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_sync_status', 'critical_sync_status', 'warning_failover_status', 'critical_failover_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +my %map_boolean = ( + 0 => 'false', + 1 => 'true', +); +my %map_sync_status = ( + 0 => 'unknown', + 1 => 'syncing', + 2 => 'needManualSync', + 3 => 'inSync', + 4 => 'syncFailed', + 5 => 'syncDisconnected', + 6 => 'standalone', + 7 => 'awaitingInitialSync', + 8 => 'incompatibleVersion', + 9 => 'partialSync', +); +my %map_failover_status = ( + 0 => 'unknown', + 1 => 'offline', + 2 => 'forcedOffline', + 3 => 'standby', + 4 => 'active', +); + +my $mapping = { + sysAttrFailoverIsRedundant => { oid => '.1.3.6.1.4.1.3375.2.1.1.1.1.13', map => \%map_boolean }, + sysAttrModeMaint => { oid => '.1.3.6.1.4.1.3375.2.1.1.1.1.21', map => \%map_boolean }, + sysCmSyncStatusId => { oid => '.1.3.6.1.4.1.3375.2.1.14.1.1', map => \%map_sync_status }, + sysCmFailoverStatusId => { oid => '.1.3.6.1.4.1.3375.2.1.14.3.1', map => \%map_failover_status }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{snmp}->get_leef(oids => [$mapping->{sysAttrFailoverIsRedundant}->{oid} . '.0', + $mapping->{sysAttrModeMaint}->{oid} . '.0', + $mapping->{sysCmSyncStatusId}->{oid} . '.0', + $mapping->{sysCmFailoverStatusId}->{oid} . '.0'], + nothing_quit => 1); + my $result2 = $options{snmp}->map_instance(mapping => $mapping, results => $result, instance => '0'); + + if ($result2->{sysAttrModeMaint} eq 'true') { + $self->{output}->output_add(severity => 'OK', + short_msg => 'maintenance mode is active'); + $self->{output}->display(); + $self->{output}->exit(); + } + if ($result2->{sysAttrFailoverIsRedundant} eq 'false') { + $self->{output}->output_add(severity => 'OK', + short_msg => 'failover mode is disable'); + $self->{output}->display(); + $self->{output}->exit(); + } + + $self->{global} = { + syncstatus => $result2->{sysCmSyncStatusId}, + failoverstatus => $result2->{sysCmFailoverStatusId}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check failover status. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). + +=item B<--warning-sync-status> + +Set warning threshold for sync status +Can used special variables like: %{syncstatus} + +=item B<--critical-sync-status> + +Set critical threshold for sync status (Default: '%{syncstatus} =~ /unknown|syncFailed|syncDisconnected|incompatibleVersion/'). +Can used special variables like: %{syncstatus} + +=item B<--warning-failover-status> + +Set warning threshold for failover status +Can used special variables like: %{failoverstatus} + +=item B<--critical-failover-status> + +Set critical threshold for failover status (Default: '%{failoverstatus} =~ /unknown/'). +Can used special variables like: %{failoverstatus} + +=back + +=cut \ No newline at end of file diff --git a/network/f5/bigip/mode/hardware.pm b/network/f5/bigip/mode/hardware.pm index 09b0ce08a..624e1c469 100644 --- a/network/f5/bigip/mode/hardware.pm +++ b/network/f5/bigip/mode/hardware.pm @@ -20,14 +20,42 @@ package network::f5::bigip::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -use network::f5::bigip::mode::components::fan; -use network::f5::bigip::mode::components::psu; -use network::f5::bigip::mode::components::temperature; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(temperature|fan|psu)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|fan)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + fan => [ + ['bad', 'CRITICAL'], + ['good', 'OK'], + ['notPresent', 'OK'], + ], + psu => [ + ['bad', 'CRITICAL'], + ['good', 'OK'], + ['notPresent', 'OK'], + ], + }; + + $self->{components_path} = 'network::f5::bigip::mode::components'; + $self->{components_module} = ['fan', 'psu', 'temperature']; +} + +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) = @_; @@ -36,95 +64,12 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "exclude:s" => { name => 'exclude' }, - "component:s" => { name => 'component', default => 'all' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, + { }); - $self->{components} = {}; + 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 global { - my ($self, %options) = @_; - - network::f5::bigip::mode::components::temperature::check($self); - network::f5::bigip::mode::components::fan::check($self); - network::f5::bigip::mode::components::psu::check($self); -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - if ($self->{option_results}->{component} eq 'all') { - $self->global(); - } elsif ($self->{option_results}->{component} eq 'fan') { - network::f5::bigip::mode::components::fan::check($self); - } elsif ($self->{option_results}->{component} eq 'psu') { - network::f5::bigip::mode::components::psu::check($self); - } elsif ($self->{option_results}->{component} eq 'temperature') { - network::f5::bigip::mode::components::temperature::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 - ) - ); - - $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__ @@ -137,21 +82,34 @@ Check hardware (fans, temperatures, power supplies). =item B<--component> -Which component to check (Default: 'all'). +Which component to check (Default: '.*'). Can be: 'fan', 'psu', 'temperature'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=fan,psu) -Can also exclude specific instance: --exclude=fan#1#2#,psu +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=psu) +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,CRITICAL,^(?!(good)$)' =item B<--warning> -Threshold warning in degree celsius. +Set warning threshold for temperatures, fan speed (syntax: type,instance,threshold) +Example: --warning='temperature,.*,30' =item B<--critical> -Threshold critical in degree celsius. +Set critical threshold for temperatures, fan speed (syntax: type,instance,threshold) +Example: --critical='temperature,.*,40' =back diff --git a/network/f5/bigip/mode/nodestatus.pm b/network/f5/bigip/mode/nodestatus.pm index f0ede22fe..05cd16fb9 100644 --- a/network/f5/bigip/mode/nodestatus.pm +++ b/network/f5/bigip/mode/nodestatus.pm @@ -20,11 +20,10 @@ package network::f5::bigip::mode::nodestatus; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; my $thresholds = { node => [ @@ -38,21 +37,6 @@ my $thresholds = { }; my $instance_mode; -my $maps_counters = { - node => { - '000_status' => { set => { - key_values => [ { name => 'AvailState' } ], - closure_custom_calc => \&custom_status_calc, - output_template => 'Status : %s', output_error_template => 'Status : %s', - output_use => 'AvailState', - closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&custom_threshold_output, - } - }, - }, -}; - - sub custom_threshold_output { my ($self, %options) = @_; @@ -66,6 +50,31 @@ sub custom_status_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'node', type => 1, cb_prefix_output => 'prefix_node_output', message_multiple => 'All Nodes are ok' }, + ]; + $self->{maps_counters}->{node} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'AvailState' } ], + closure_custom_calc => $self->can('custom_status_calc'), + output_template => 'Status : %s', output_error_template => 'Status : %s', + output_use => 'AvailState', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_threshold_output'), + } + }, + ]; +} + +sub prefix_node_output { + my ($self, %options) = @_; + + return "Node '" . $options{instance_value}->{Name} . "' "; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -77,21 +86,6 @@ sub new { "filter-name:s" => { name => 'filter_name' }, "threshold-overload:s@" => { name => 'threshold_overload' }, }); - - foreach my $key (('node')) { - 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; } @@ -100,12 +94,6 @@ sub check_options { my ($self, %options) = @_; $self->SUPER::init(%options); - foreach my $key (('node')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - $instance_mode = $self; $self->{overload_th} = {}; @@ -124,69 +112,6 @@ sub check_options { } } -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{node}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All Nodes are ok'); - } - - foreach my $id (sort keys %{$self->{node}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{node}}) { - my $obj = $maps_counters->{node}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{node}->{$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->{node}->{$_}->{obj}->perfdata(extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Node '$self->{node}->{$id}->{Name}' $long_msg [Status Reason: $self->{node}->{$id}->{StatusReason}]"); - 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 => "Node '$self->{node}->{$id}->{Name}' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Node '$self->{node}->{$id}->{Name}' $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} - sub get_severity { my ($self, %options) = @_; my $status = 'UNKNOWN'; # default @@ -243,7 +168,7 @@ my $oid_ltmNodeAddrEntry = '.1.3.6.1.4.1.3375.2.2.4.1.2.1'; # old sub manage_selection { my ($self, %options) = @_; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ + $self->{results} = $options{snmp}->get_multiple_table(oids => [ { oid => $oid_ltmNodeAddrEntry, start => $mapping->{old}->{AvailState}->{oid} }, { oid => $oid_ltmNodeAddrStatusEntry, start => $mapping->{new}->{AvailState}->{oid} }, ], @@ -258,7 +183,7 @@ sub manage_selection { foreach my $oid (keys %{$self->{results}->{$branch}}) { next if ($oid !~ /^$mapping->{$map}->{AvailState}->{oid}\.(.*)$/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping->{$map}, results => $self->{results}->{$branch}, instance => $instance); + my $result = $options{snmp}->map_instance(mapping => $mapping->{$map}, results => $self->{results}->{$branch}, instance => $instance); $result->{Name} = $instance; # prefix by '1.4' diff --git a/network/f5/bigip/mode/poolstatus.pm b/network/f5/bigip/mode/poolstatus.pm index 4c0787f54..f184244d2 100644 --- a/network/f5/bigip/mode/poolstatus.pm +++ b/network/f5/bigip/mode/poolstatus.pm @@ -20,11 +20,10 @@ package network::f5::bigip::mode::poolstatus; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; my $thresholds = { pool => [ @@ -38,21 +37,6 @@ my $thresholds = { }; my $instance_mode; -my $maps_counters = { - pool => { - '000_status' => { set => { - key_values => [ { name => 'AvailState' } ], - closure_custom_calc => \&custom_status_calc, - output_template => 'Status : %s', output_error_template => 'Status : %s', - output_use => 'AvailState', - closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&custom_threshold_output, - } - }, - }, -}; - - sub custom_threshold_output { my ($self, %options) = @_; @@ -66,6 +50,31 @@ sub custom_status_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 Pools are ok' }, + ]; + $self->{maps_counters}->{pool} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'AvailState' } ], + closure_custom_calc => $self->can('custom_status_calc'), + output_template => 'Status : %s', output_error_template => 'Status : %s', + output_use => 'AvailState', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_threshold_output'), + } + }, + ]; +} + +sub prefix_pool_output { + my ($self, %options) = @_; + + return "Pool '" . $options{instance_value}->{Name} . "' "; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -77,21 +86,6 @@ sub new { "filter-name:s" => { name => 'filter_name' }, "threshold-overload:s@" => { name => 'threshold_overload' }, }); - - foreach my $key (('pool')) { - 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; } @@ -100,12 +94,6 @@ sub check_options { my ($self, %options) = @_; $self->SUPER::init(%options); - foreach my $key (('pool')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - $instance_mode = $self; $self->{overload_th} = {}; @@ -124,69 +112,6 @@ sub check_options { } } -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{pool}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All Pools are ok'); - } - - foreach my $id (sort keys %{$self->{pool}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{pool}}) { - my $obj = $maps_counters->{pool}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{pool}->{$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->{pool}->{$_}->{obj}->perfdata(extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Pool '$self->{pool}->{$id}->{Name}' $long_msg [Status Reason: $self->{pool}->{$id}->{StatusReason}]"); - 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}->{$id}->{Name}' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Pool '$self->{pool}->{$id}->{Name}' $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} - sub get_severity { my ($self, %options) = @_; my $status = 'UNKNOWN'; # default @@ -243,7 +168,7 @@ my $oid_ltmPoolEntry = '.1.3.6.1.4.1.3375.2.2.5.1.2.1'; # old sub manage_selection { my ($self, %options) = @_; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ + $self->{results} = $options{snmp}->get_multiple_table(oids => [ { oid => $oid_ltmPoolEntry, start => $mapping->{old}->{AvailState}->{oid} }, { oid => $oid_ltmPoolStatusEntry, start => $mapping->{new}->{AvailState}->{oid} }, ], @@ -258,7 +183,7 @@ sub manage_selection { foreach my $oid (keys %{$self->{results}->{$branch}}) { next if ($oid !~ /^$mapping->{$map}->{AvailState}->{oid}\.(.*)$/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping->{$map}, results => $self->{results}->{$branch}, instance => $instance); + my $result = $options{snmp}->map_instance(mapping => $mapping->{$map}, results => $self->{results}->{$branch}, instance => $instance); $result->{Name} = ''; foreach (split /\./, $instance) { diff --git a/network/f5/bigip/mode/virtualserverstatus.pm b/network/f5/bigip/mode/virtualserverstatus.pm index 390af87c1..3075a70bc 100644 --- a/network/f5/bigip/mode/virtualserverstatus.pm +++ b/network/f5/bigip/mode/virtualserverstatus.pm @@ -20,11 +20,10 @@ package network::f5::bigip::mode::virtualserverstatus; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; my $thresholds = { vs => [ @@ -38,20 +37,6 @@ my $thresholds = { }; my $instance_mode; -my $maps_counters = { - vs => { - '000_status' => { set => { - key_values => [ { name => 'AvailState' } ], - closure_custom_calc => \&custom_status_calc, - output_template => 'Status : %s', output_error_template => 'Status : %s', - output_use => 'AvailState', - closure_custom_perfdata => sub { return 0; }, - closure_custom_threshold_check => \&custom_threshold_output, - } - }, - }, -}; - sub custom_threshold_output { my ($self, %options) = @_; @@ -65,6 +50,31 @@ sub custom_status_calc { return 0; } +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'vs', type => 1, cb_prefix_output => 'prefix_vs_output', message_multiple => 'All Virtual Servers are ok' }, + ]; + $self->{maps_counters}->{vs} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'AvailState' } ], + closure_custom_calc => $self->can('custom_status_calc'), + output_template => 'Status : %s', output_error_template => 'Status : %s', + output_use => 'AvailState', + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_threshold_output'), + } + }, + ]; +} + +sub prefix_vs_output { + my ($self, %options) = @_; + + return "Virtual Server '" . $options{instance_value}->{Name} . "' "; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -76,21 +86,6 @@ sub new { "filter-name:s" => { name => 'filter_name' }, "threshold-overload:s@" => { name => 'threshold_overload' }, }); - - foreach my $key (('vs')) { - 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; } @@ -99,12 +94,6 @@ sub check_options { my ($self, %options) = @_; $self->SUPER::init(%options); - foreach my $key (('vs')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - $instance_mode = $self; $self->{overload_th} = {}; @@ -123,69 +112,6 @@ sub check_options { } } -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{vs}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All Virtual Servers are ok'); - } - - foreach my $id (sort keys %{$self->{vs}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{vs}}) { - my $obj = $maps_counters->{vs}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{vs}->{$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->{vs}->{$_}->{obj}->perfdata(extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Virtual Server '$self->{vs}->{$id}->{Name}' $long_msg [Status Reason: $self->{vs}->{$id}->{StatusReason}]"); - 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 => "Virtual Server '$self->{vs}->{$id}->{Name}' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Virtual Server '$self->{vs}->{$id}->{Name}' $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} - sub get_severity { my ($self, %options) = @_; my $status = 'UNKNOWN'; # default @@ -242,7 +168,7 @@ my $oid_ltmVirtualServEntry = '.1.3.6.1.4.1.3375.2.2.10.1.2.1'; # old sub manage_selection { my ($self, %options) = @_; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ + $self->{results} = $options{snmp}->get_multiple_table(oids => [ { oid => $oid_ltmVirtualServEntry, start => $mapping->{old}->{AvailState}->{oid} }, { oid => $oid_ltmVsStatusEntry, start => $mapping->{new}->{AvailState}->{oid} }, ], @@ -257,7 +183,7 @@ sub manage_selection { foreach my $oid (keys %{$self->{results}->{$branch}}) { next if ($oid !~ /^$mapping->{$map}->{AvailState}->{oid}\.(.*)$/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping->{$map}, results => $self->{results}->{$branch}, instance => $instance); + my $result = $options{snmp}->map_instance(mapping => $mapping->{$map}, results => $self->{results}->{$branch}, instance => $instance); $result->{Name} = ''; foreach (split /\./, $instance) { diff --git a/network/f5/bigip/plugin.pm b/network/f5/bigip/plugin.pm index 5657b0128..05d5e0437 100644 --- a/network/f5/bigip/plugin.pm +++ b/network/f5/bigip/plugin.pm @@ -32,14 +32,15 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'node-status' => 'network::f5::bigip::mode::nodestatus', - 'pool-status' => 'network::f5::bigip::mode::poolstatus', - 'virtualserver-status' => 'network::f5::bigip::mode::virtualserverstatus', + 'connections' => 'network::f5::bigip::mode::connections', + 'failover' => 'network::f5::bigip::mode::failover', + 'hardware' => 'network::f5::bigip::mode::hardware', 'list-nodes' => 'network::f5::bigip::mode::listnodes', 'list-pools' => 'network::f5::bigip::mode::listpools', 'list-virtualservers' => 'network::f5::bigip::mode::listvirtualservers', - 'hardware' => 'network::f5::bigip::mode::hardware', - 'connections' => 'network::f5::bigip::mode::connections', + 'node-status' => 'network::f5::bigip::mode::nodestatus', + 'pool-status' => 'network::f5::bigip::mode::poolstatus', + 'virtualserver-status' => 'network::f5::bigip::mode::virtualserverstatus', ); return $self; diff --git a/network/h3c/snmp/mode/components/default.pm b/network/h3c/snmp/mode/components/default.pm index 6be93e67d..712f28b5f 100644 --- a/network/h3c/snmp/mode/components/default.pm +++ b/network/h3c/snmp/mode/components/default.pm @@ -48,7 +48,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking " . $options{component}); $self->{components}->{$options{component}} = {name => $options{component}, total => 0, skip => 0}; - return if ($self->check_exclude(section => $options{component})); + return if ($self->check_filter(section => $options{component})); my $mapping = { EntityExtErrorStatus => { oid => $self->{branch} . '.19', map => \%map_default_status }, @@ -58,7 +58,7 @@ sub check { my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$self->{branch} . '.19'}, instance => $instance); next if (!defined($result->{EntityExtErrorStatus})); - next if ($self->check_exclude(section => $options{component}, instance => $instance)); + next if ($self->check_filter(section => $options{component}, instance => $instance)); if ($result->{EntityExtErrorStatus} =~ /entityAbsent/i) { $self->absent_problem(section => $options{component}, instance => $instance); next; diff --git a/network/h3c/snmp/mode/components/fan.pm b/network/h3c/snmp/mode/components/fan.pm index a4e2b1cfb..1d6d79511 100644 --- a/network/h3c/snmp/mode/components/fan.pm +++ b/network/h3c/snmp/mode/components/fan.pm @@ -36,7 +36,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking fans"); $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fan')); + return if ($self->check_filter(section => 'fan')); my $mapping = { EntityExtErrorStatus => { oid => $self->{branch} . '.19', map => \%map_fan_status }, @@ -46,7 +46,7 @@ sub check { my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$self->{branch} . '.19'}, instance => $instance); next if (!defined($result->{EntityExtErrorStatus})); - next if ($self->check_exclude(section => 'fan', instance => $instance)); + next if ($self->check_filter(section => 'fan', instance => $instance)); if ($result->{EntityExtErrorStatus} =~ /entityAbsent/i) { $self->absent_problem(section => 'fan', instance => $instance); next; diff --git a/network/h3c/snmp/mode/components/psu.pm b/network/h3c/snmp/mode/components/psu.pm index aa963bf58..39c553251 100644 --- a/network/h3c/snmp/mode/components/psu.pm +++ b/network/h3c/snmp/mode/components/psu.pm @@ -36,7 +36,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking power supplies"); $self->{components}->{psu} = {name => 'power supplies', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'psu')); + return if ($self->check_filter(section => 'psu')); my $mapping = { EntityExtErrorStatus => { oid => $self->{branch} . '.19', map => \%map_psu_status }, @@ -46,7 +46,7 @@ sub check { my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$self->{branch} . '.19'}, instance => $instance); next if (!defined($result->{EntityExtErrorStatus})); - next if ($self->check_exclude(section => 'psu', instance => $instance)); + next if ($self->check_filter(section => 'psu', instance => $instance)); if ($result->{EntityExtErrorStatus} =~ /entityAbsent/i) { $self->absent_problem(section => 'psu', instance => $instance); next; diff --git a/network/h3c/snmp/mode/components/sensor.pm b/network/h3c/snmp/mode/components/sensor.pm index f6f5735c5..b8953d033 100644 --- a/network/h3c/snmp/mode/components/sensor.pm +++ b/network/h3c/snmp/mode/components/sensor.pm @@ -36,7 +36,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking sensors"); $self->{components}->{sensor} = {name => 'sensors', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'sensor')); + return if ($self->check_filter(section => 'sensor')); my $mapping = { EntityExtErrorStatus => { oid => $self->{branch} . '.19', map => \%map_sensor_status }, @@ -59,7 +59,7 @@ sub check { my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $results, instance => $instance); next if (!defined($result->{EntityExtErrorStatus})); - next if ($self->check_exclude(section => 'sensor', instance => $instance)); + next if ($self->check_filter(section => 'sensor', instance => $instance)); if ($result->{EntityExtErrorStatus} =~ /entityAbsent/i) { $self->absent_problem(section => 'sensor', instance => $instance); next; diff --git a/network/h3c/snmp/mode/hardware.pm b/network/h3c/snmp/mode/hardware.pm index ac5b9217a..8bcf36691 100644 --- a/network/h3c/snmp/mode/hardware.pm +++ b/network/h3c/snmp/mode/hardware.pm @@ -20,89 +20,138 @@ package network::h3c::snmp::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; use centreon::plugins::statefile; -my $thresholds = { - psu => [ - ['notSupported', 'WARNING'], - ['normal', 'OK'], - ['entityAbsent', 'OK'], - ['psuError', 'CRITICAL'], - ['hardwareFaulty', 'CRITICAL'], - ], - fan => [ - ['notSupported', 'WARNING'], - ['normal', 'OK'], - ['entityAbsent', 'OK'], - ['fanError', 'CRITICAL'], - ['hardwareFaulty', 'CRITICAL'], - ], - sensor => [ - ['notSupported', 'WARNING'], - ['normal', 'OK'], - ['entityAbsent', 'OK'], - ['sensorError', 'CRITICAL'], - ['hardwareFaulty', 'CRITICAL'], - ], - other => [ - ['notSupported', 'WARNING'], - ['normal', 'OK'], - ['entityAbsent', 'OK'], - ['hardwareFaulty', 'CRITICAL'], - ], - unknown => [ - ['notSupported', 'WARNING'], - ['normal', 'OK'], - ['entityAbsent', 'OK'], - ['hardwareFaulty', 'CRITICAL'], - ], - chassis => [ - ['notSupported', 'WARNING'], - ['normal', 'OK'], - ['entityAbsent', 'OK'], - ['hardwareFaulty', 'CRITICAL'], - ], - backplane => [ - ['notSupported', 'WARNING'], - ['normal', 'OK'], - ['entityAbsent', 'OK'], - ['hardwareFaulty', 'CRITICAL'], - ], - container => [ - ['notSupported', 'WARNING'], - ['normal', 'OK'], - ['entityAbsent', 'OK'], - ['hardwareFaulty', 'CRITICAL'], - ], - module => [ - ['notSupported', 'WARNING'], - ['normal', 'OK'], - ['entityAbsent', 'OK'], - ['hardwareFaulty', 'CRITICAL'], - ], - port => [ - ['notSupported', 'WARNING'], - ['normal', 'OK'], - ['entityAbsent', 'OK'], - ['hardwareFaulty', 'CRITICAL'], - ], - stack => [ - ['notSupported', 'WARNING'], - ['normal', 'OK'], - ['entityAbsent', 'OK'], - ['hardwareFaulty', 'CRITICAL'], - ], - cpu => [ - ['notSupported', 'WARNING'], - ['normal', 'OK'], - ['entityAbsent', 'OK'], - ['hardwareFaulty', 'CRITICAL'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature)$'; + + $self->{cb_hook1} = 'init_cache'; + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + psu => [ + ['notSupported', 'WARNING'], + ['normal', 'OK'], + ['entityAbsent', 'OK'], + ['psuError', 'CRITICAL'], + ['hardwareFaulty', 'CRITICAL'], + ], + fan => [ + ['notSupported', 'WARNING'], + ['normal', 'OK'], + ['entityAbsent', 'OK'], + ['fanError', 'CRITICAL'], + ['hardwareFaulty', 'CRITICAL'], + ], + sensor => [ + ['notSupported', 'WARNING'], + ['normal', 'OK'], + ['entityAbsent', 'OK'], + ['sensorError', 'CRITICAL'], + ['hardwareFaulty', 'CRITICAL'], + ], + other => [ + ['notSupported', 'WARNING'], + ['normal', 'OK'], + ['entityAbsent', 'OK'], + ['hardwareFaulty', 'CRITICAL'], + ], + unknown => [ + ['notSupported', 'WARNING'], + ['normal', 'OK'], + ['entityAbsent', 'OK'], + ['hardwareFaulty', 'CRITICAL'], + ], + chassis => [ + ['notSupported', 'WARNING'], + ['normal', 'OK'], + ['entityAbsent', 'OK'], + ['hardwareFaulty', 'CRITICAL'], + ], + backplane => [ + ['notSupported', 'WARNING'], + ['normal', 'OK'], + ['entityAbsent', 'OK'], + ['hardwareFaulty', 'CRITICAL'], + ], + container => [ + ['notSupported', 'WARNING'], + ['normal', 'OK'], + ['entityAbsent', 'OK'], + ['hardwareFaulty', 'CRITICAL'], + ], + module => [ + ['notSupported', 'WARNING'], + ['normal', 'OK'], + ['entityAbsent', 'OK'], + ['hardwareFaulty', 'CRITICAL'], + ], + port => [ + ['notSupported', 'WARNING'], + ['normal', 'OK'], + ['entityAbsent', 'OK'], + ['hardwareFaulty', 'CRITICAL'], + ], + stack => [ + ['notSupported', 'WARNING'], + ['normal', 'OK'], + ['entityAbsent', 'OK'], + ['hardwareFaulty', 'CRITICAL'], + ], + cpu => [ + ['notSupported', 'WARNING'], + ['normal', 'OK'], + ['entityAbsent', 'OK'], + ['hardwareFaulty', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'network::h3c::snmp::mode::components'; + $self->{components_module} = ['fan', 'psu', 'slot', 'temperature']; + + $self->{mapping_name} = { + 1 => 'other', 2 => 'unknown', 3 => 'chassis', 4 => 'backplane', 5 => 'container', 6 => 'psu', + 7 => 'fan', 8 => 'sensor', 9 => 'module', 10 => 'port', 11 => 'stack', 12 => 'cpu' + }; + $self->{mapping_component} = { + 1 => 'default', 2 => 'default', 3 => 'default', 4 => 'default', 5 => 'default', 6 => 'psu', + 7 => 'fan', 8 => 'sensor', 9 => 'default', 10 => 'default', 11 => 'default', 12 => 'default' + }; +} + +my $oid_hh3cEntityExtStateEntry = '.1.3.6.1.4.1.25506.2.6.1.1.1.1'; +my $oid_h3cEntityExtStateEntry = '.1.3.6.1.4.1.2011.10.2.6.1.1.1.1'; +my $oid_h3cEntityExtErrorStatus = '.1.3.6.1.4.1.2011.10.2.6.1.1.1.1.19'; +my $oid_hh3cEntityExtErrorStatus = '.1.3.6.1.4.1.25506.2.6.1.1.1.1.19'; + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); + $self->write_cache(); + + $self->{branch} = $oid_hh3cEntityExtStateEntry; + if (defined($self->{results}->{$oid_h3cEntityExtErrorStatus}) && scalar(keys %{$self->{results}->{$oid_h3cEntityExtErrorStatus}}) > 0) { + $self->{branch} = $oid_h3cEntityExtStateEntry; + } +} + +sub init_cache { + my ($self, %options) = @_; + + $self->{request} = [ + { oid => $oid_h3cEntityExtErrorStatus }, + { oid => $oid_hh3cEntityExtErrorStatus }, + ]; + $self->check_cache(%options); +} sub new { my ($class, %options) = @_; @@ -111,21 +160,11 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "exclude:s" => { name => 'exclude' }, - "absent-problem:s" => { name => 'absent' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { "reload-cache-time:s" => { name => 'reload_cache_time', default => 180 }, }); - $self->{components} = {}; - $self->{no_components} = undef; - $self->{statefile_cache} = centreon::plugins::statefile->new(%options); - + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); return $self; } @@ -133,54 +172,6 @@ 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'; - } - } - - $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->{numeric_threshold} = {}; - foreach my $option (('warning', 'critical')) { - foreach my $val (@{$self->{option_results}->{$option}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $regexp, $value) = ($1, $2, $3); - if ($section !~ /^(temperature)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "' (type must be: temperature)."); - $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, regexp => $regexp }; - } - } - $self->{statefile_cache}->check_options(%options); } @@ -193,8 +184,8 @@ my $oid_entPhysicalName = '.1.3.6.1.2.1.47.1.1.1.1.7'; sub check_cache { my ($self, %options) = @_; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); + $self->{hostname} = $options{snmp}->get_hostname(); + $self->{snmp_port} = $options{snmp}->get_port(); # init cache file $self->{write_cache} = 0; @@ -202,7 +193,7 @@ sub check_cache { my $timestamp_cache = $self->{statefile_cache}->get(name => 'last_timestamp'); if ($has_cache_file == 0 || !defined($timestamp_cache) || ((time() - $timestamp_cache) > (($self->{option_results}->{reload_cache_time}) * 60))) { - push @{$self->{snmp_request}}, { oid => $oid_entPhysicalEntry, start => $oid_entPhysicalDescr, end => $oid_entPhysicalName }; + push @{$self->{request}}, { oid => $oid_entPhysicalEntry, start => $oid_entPhysicalDescr, end => $oid_entPhysicalName }; $self->{write_cache} = 1; } } @@ -250,159 +241,29 @@ sub get_instance_class { return @instances; } -sub run { +sub load_components { my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $oid_hh3cEntityExtStateEntry = '.1.3.6.1.4.1.25506.2.6.1.1.1.1'; - my $oid_h3cEntityExtStateEntry = '.1.3.6.1.4.1.2011.10.2.6.1.1.1.1'; - my $oid_h3cEntityExtErrorStatus = '.1.3.6.1.4.1.2011.10.2.6.1.1.1.1.19'; - my $oid_hh3cEntityExtErrorStatus = '.1.3.6.1.4.1.25506.2.6.1.1.1.1.19'; - $self->{snmp_request} = [ - { oid => $oid_h3cEntityExtErrorStatus }, - { oid => $oid_hh3cEntityExtErrorStatus }, - ]; - $self->check_cache(); - - my %mapping_name = ( - 1 => 'other', 2 => 'unknown', 3 => 'chassis', 4 => 'backplane', 5 => 'container', 6 => 'psu', - 7 => 'fan', 8 => 'sensor', 9 => 'module', 10 => 'port', 11 => 'stack', 12 => 'cpu' - ); - my %mapping_component = ( - 1 => 'default', 2 => 'default', 3 => 'default', 4 => 'default', 5 => 'default', 6 => 'psu', - 7 => 'fan', 8 => 'sensor', 9 => 'default', 10 => 'default', 11 => 'default', 12 => 'default' - ); - my $component = 0; - foreach (keys %mapping_name) { - if ($mapping_name{$_} =~ /$self->{option_results}->{component}/) { - my $mod_name = "network::h3c::snmp::mode::components::" . $mapping_component{$_}; + foreach (keys %{$self->{mapping_name}}) { + if ($self->{mapping_name}->{$_} =~ /$self->{option_results}->{component}/) { + my $mod_name = $self->{components_path} . "::" . $self->{mapping_component}->{$_}; centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, error_msg => "Cannot load module '$mod_name'."); - $component = 1; + $self->{loaded} = 1; } } - if ($component == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } +} + +sub exec_components { + my ($self, %options) = @_; - $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{snmp_request}); - $self->write_cache(); - - $self->{branch} = $oid_hh3cEntityExtStateEntry; - if (defined($self->{results}->{$oid_h3cEntityExtErrorStatus}) && scalar(keys %{$self->{results}->{$oid_h3cEntityExtErrorStatus}}) > 0) { - $self->{branch} = $oid_h3cEntityExtStateEntry; - } - - foreach (keys %mapping_name) { - if ($mapping_name{$_} =~ /$self->{option_results}->{component}/) { - my $mod_name = "network::h3c::snmp::mode::components::" . $mapping_component{$_}; + foreach (keys %{$self->{mapping_name}}) { + if ($self->{mapping_name}->{$_} =~ /$self->{option_results}->{component}/) { + my $mod_name = $self->{components_path} . "::" . $self->{mapping_component}->{$_}; my $func = $mod_name->can('check'); - $func->($self, component => $mapping_name{$_}, component_class => $_); + $func->($self, component => $self->{mapping_name}->{$_}, component_class => $_); } } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $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; -} - -sub absent_problem { - my ($self, %options) = @_; - - if (defined($self->{option_results}->{absent}) && - $self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - } - - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); - $self->{components}->{$options{section}}->{skip}++; - return 1; -} - -sub get_severity_numeric { - 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} =~ /$_->{regexp}/) { - 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 - - 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; } 1; @@ -421,10 +282,10 @@ Which component to check (Default: '.*'). Can be: 'fan', 'psu', 'other', 'unknown', 'sensor', 'chassis', 'backplane', 'container', 'module', 'port', 'stack', 'cpu'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=fan) -Can also exclude specific instance: --exclude=fan#101# +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=psu) +Can also exclude specific instance: --filter=fan,101 =item B<--absent-problem> @@ -438,7 +299,7 @@ If total (with skipped) is 0. (Default: 'critical' returns). =item B<--threshold-overload> -Set to overload default threshold values (syntax: section,status,regexp) +Set to overload default threshold values (syntax: section,[instance,]status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='psu,CRITICAL,^(?!(normal)$)' diff --git a/network/hirschmann/standard/snmp/mode/components/fan.pm b/network/hirschmann/standard/snmp/mode/components/fan.pm index d4695f9da..be913512e 100644 --- a/network/hirschmann/standard/snmp/mode/components/fan.pm +++ b/network/hirschmann/standard/snmp/mode/components/fan.pm @@ -34,9 +34,9 @@ my $mapping = { }; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $mapping->{hmFanState}->{oid} }; + push @{$self->{request}}, { oid => $mapping->{hmFanState}->{oid} }; } sub check { @@ -44,14 +44,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking fans"); $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fan')); + return if ($self->check_filter(section => 'fan')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$mapping->{hmFanState}->{oid}}})) { next if ($oid !~ /^$mapping->{hmFanState}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{hmFanState}->{oid}}, instance => $instance); - next if ($self->check_exclude(section => 'fan', instance => $instance)); + 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].", diff --git a/network/hirschmann/standard/snmp/mode/components/led.pm b/network/hirschmann/standard/snmp/mode/components/led.pm index cce547c46..92ea47020 100644 --- a/network/hirschmann/standard/snmp/mode/components/led.pm +++ b/network/hirschmann/standard/snmp/mode/components/led.pm @@ -34,9 +34,9 @@ my %map_led_status = ( my $oid_hmLEDGroup = '.1.3.6.1.4.1.248.14.1.1.35'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_hmLEDGroup }; + push @{$self->{request}}, { oid => $oid_hmLEDGroup }; } sub check_led { @@ -49,7 +49,7 @@ sub check_led { $options{mapping}->{$name}->{oid} =~ /\.(\d+)$/; my $instance = $1; - next if ($self->check_exclude(section => 'led', instance => $instance)); + next if ($self->check_filter(section => 'led', instance => $instance)); $self->{components}->{led}->{total}++; $self->{output}->output_add(long_msg => sprintf("Led '%s' status is %s [instance: %s].", @@ -70,7 +70,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking leds"); $self->{components}->{led} = {name => 'leds', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'led')); + return if ($self->check_filter(section => 'led')); my $mapping; if (defined($self->{results}->{$oid_hmLEDGroup}->{$oid_hmLEDGroup . '.1.1.0'})) { diff --git a/network/hirschmann/standard/snmp/mode/components/psu.pm b/network/hirschmann/standard/snmp/mode/components/psu.pm index 9af81b65a..66abdf17f 100644 --- a/network/hirschmann/standard/snmp/mode/components/psu.pm +++ b/network/hirschmann/standard/snmp/mode/components/psu.pm @@ -36,9 +36,9 @@ my $mapping = { }; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $mapping->{hmPSState}->{oid} }; + push @{$self->{request}}, { oid => $mapping->{hmPSState}->{oid} }; } sub check { @@ -46,14 +46,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking power supplies"); $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'psu')); + 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; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{hmPSState}->{oid}}, instance => $instance); - next if ($self->check_exclude(section => 'psu', instance => $instance)); + next if ($self->check_filter(section => 'psu', instance => $instance)); next if ($result->{hmPSState} =~ /notInstalled/i && $self->absent_problem(section => 'psu', instance => $instance)); $self->{components}->{psu}->{total}++; diff --git a/network/hirschmann/standard/snmp/mode/components/temperature.pm b/network/hirschmann/standard/snmp/mode/components/temperature.pm index 3f571bfb2..158bbe7ad 100644 --- a/network/hirschmann/standard/snmp/mode/components/temperature.pm +++ b/network/hirschmann/standard/snmp/mode/components/temperature.pm @@ -32,9 +32,9 @@ my $mapping = { my $oid_hmTempTable = '.1.3.6.1.4.1.248.14.2.5'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_hmTempTable }; + push @{$self->{request}}, { oid => $oid_hmTempTable }; } sub check { @@ -42,13 +42,13 @@ sub check { $self->{output}->output_add(long_msg => "Checking temperatures"); $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'temperature')); + return if ($self->check_filter(section => 'temperature')); return if (!defined($self->{results}->{$oid_hmTempTable}->{$mapping->{hmTemperature}->{oid} . '.0'})); my $instance = 0; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_hmTempTable}, instance => $instance); - next if ($self->check_exclude(section => 'temperature', instance => $instance)); + next if ($self->check_filter(section => 'temperature', instance => $instance)); $self->{components}->{temperature}->{total}++; $self->{output}->output_add(long_msg => sprintf("temperature is %dC [instance: %s].", diff --git a/network/hirschmann/standard/snmp/mode/hardware.pm b/network/hirschmann/standard/snmp/mode/hardware.pm index 5371baf6c..f3310e394 100644 --- a/network/hirschmann/standard/snmp/mode/hardware.pm +++ b/network/hirschmann/standard/snmp/mode/hardware.pm @@ -20,29 +20,48 @@ package network::hirschmann::standard::snmp::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -my $thresholds = { - fan => [ - ['ok', 'OK'], - ['failed', 'CRITICAL'], - ], - psu => [ - ['ok', 'OK'], - ['failed', 'CRITICAL'], - ['notInstalled', 'OK'], - ['unknown', 'UNKNOWN'], - ], - led => [ - ['off', 'UNKNOWN'], - ['green', 'OK'], - ['yellow', 'WARNING'], - ['red', 'CRITICAL'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(fan|psu|led)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + fan => [ + ['ok', 'OK'], + ['failed', 'CRITICAL'], + ], + psu => [ + ['ok', 'OK'], + ['failed', 'CRITICAL'], + ['notInstalled', 'OK'], + ['unknown', 'UNKNOWN'], + ], + led => [ + ['off', 'UNKNOWN'], + ['green', 'OK'], + ['yellow', 'WARNING'], + ['red', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'network::hirschmann::standard::snmp::mode::components'; + $self->{components_module} = ['fan', 'psu', 'temperature', 'led']; +} + +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) = @_; @@ -51,208 +70,12 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "exclude:s" => { name => 'exclude' }, - "absent-problem:s" => { name => 'absent' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { }); - $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'; - } - } - - $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->{numeric_threshold} = {}; - foreach my $option (('warning', 'critical')) { - foreach my $val (@{$self->{option_results}->{$option}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $regexp, $value) = ($1, $2, $3); - if ($section !~ /(temperature)/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "' (type must be: temperature)."); - $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, regexp => $regexp }; - } - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('fan', 'psu', 'temperature', 'led'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::hirschmann::standard::snmp::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::hirschmann::standard::snmp::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $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; -} - -sub absent_problem { - my ($self, %options) = @_; - - if (defined($self->{option_results}->{absent}) && - $self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - } - - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); - $self->{components}->{$options{section}}->{skip}++; - return 1; -} - - -sub get_severity_numeric { - 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} =~ /$_->{regexp}/) { - 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 - - 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; -} - 1; __END__ @@ -268,15 +91,15 @@ Check Hardware (Power Supplies, Fans, Temperatures, LEDs). Which component to check (Default: '.*'). Can be: 'fan', 'psu', 'temperature', 'led'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=fan) -Can also exclude specific instance: --exclude=fan#1.1#,psu#3.2# +Exclude some parts (comma seperated list) (Example: --filter=fan) +Can also exclude specific instance: --filter=fan,1.1 =item B<--absent-problem> Return an error if an entity is not 'present' (default is skipping) (comma seperated list) -Can be specific or global: --absent-problem=psu#1.1# +Can be specific or global: --absent-problem=psu,1.1 =item B<--no-component> @@ -285,7 +108,7 @@ If total (with skipped) is 0. (Default: 'critical' returns). =item B<--threshold-overload> -Set to overload default threshold values (syntax: section,status,regexp) +Set to overload default threshold values (syntax: section,[instance,]status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='psu,CRITICAL,^(?!(ok)$)' diff --git a/network/hp/procurve/mode/components/sensor.pm b/network/hp/procurve/mode/components/sensor.pm index de152d1a0..8d4ba0fe1 100644 --- a/network/hp/procurve/mode/components/sensor.pm +++ b/network/hp/procurve/mode/components/sensor.pm @@ -45,9 +45,9 @@ my $mapping = { my $oid_hpicfSensorEntry = '.1.3.6.1.4.1.11.2.14.11.1.2.6.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_hpicfSensorEntry }; + push @{$self->{request}}, { oid => $oid_hpicfSensorEntry }; } sub check { @@ -56,7 +56,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking sensors"); $self->{components}->{sensor} = {name => 'sensors', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'sensor')); + return if ($self->check_filter(section => 'sensor')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_hpicfSensorEntry}})) { next if ($oid !~ /^$mapping->{hpicfSensorStatus}->{oid}\.(.*)$/); @@ -64,7 +64,7 @@ sub check { my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_hpicfSensorEntry}, instance => $instance_mapping); my $instance = $result->{hpicfSensorObjectId} . '.' . $instance_mapping; - next if ($self->check_exclude(section => 'sensor', instance => $instance)); + next if ($self->check_filter(section => 'sensor', instance => $instance)); next if ($result->{hpicfSensorStatus} =~ /not present/i && $self->absent_problem(section => 'sensor', instance => $instance)); $self->{components}->{sensor}->{total}++; diff --git a/network/hp/procurve/mode/environment.pm b/network/hp/procurve/mode/environment.pm index 64d39f504..807578994 100644 --- a/network/hp/procurve/mode/environment.pm +++ b/network/hp/procurve/mode/environment.pm @@ -20,179 +20,52 @@ package network::hp::procurve::mode::environment; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -use centreon::plugins::misc; -my $thresholds = { - sensor => [ - ['unknown', 'UNKNOWN'], - ['bad', 'CRITICAL'], - ['warning', 'WARNING'], - ['good', 'OK'], - ['not present', 'WARNING'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(sensor)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + sensor => [ + ['unknown', 'UNKNOWN'], + ['bad', 'CRITICAL'], + ['warning', 'WARNING'], + ['good', 'OK'], + ['not present', 'WARNING'], + ], + }; + + $self->{components_path} = 'network::hp::procurve::mode::components'; + $self->{components_module} = ['sensor']; +} + +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); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_performance => 1); bless $self, $class; $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "exclude:s" => { name => 'exclude' }, - "absent-problem:s" => { name => 'absent' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, }); 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'; - } - } - - $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) = ('sensor', $1, $2); - 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}; - } -} - -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; -} - -sub absent_problem { - my ($self, %options) = @_; - - if (defined($self->{option_results}->{absent}) && - $self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - } - - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); - $self->{components}->{$options{section}}->{skip}++; - return 1; -} - -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; -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('sensor'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::hp::procurve::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::hp::procurve::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - 1; __END__ @@ -208,15 +81,15 @@ Check sensors (hpicfChassis.mib). Which component to check (Default: '.*'). Can be: 'sensor'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) -Can also exclude specific instance: --exclude=sensor#fan.1# +Exclude some parts (comma seperated list) (Example: --filter=sensor) +Can also exclude specific instance: --filter=sensor,fan.1 =item B<--absent-problem> Return an error if an entity is not 'present' (default is skipping) (comma seperated list) -Can be specific or global: --absent-problem=sensor#temperature.2# +Can be specific or global: --absent-problem=sensor,temperature.2 =item B<--no-component> @@ -225,9 +98,9 @@ If total (with skipped) is 0. (Default: 'critical' returns). =item B<--threshold-overload> -Set to overload default threshold values (syntax: section,status,regexp) +Set to overload default threshold values (syntax: section,[instance,]status,regexp) It used before default thresholds (order stays). -Example: --threshold-overload='CRITICAL,^(?!(good)$)' +Example: --threshold-overload='sensor,CRITICAL,^(?!(good)$)' =back diff --git a/network/juniper/common/ive/mode/users.pm b/network/juniper/common/ive/mode/users.pm index 04619612e..22c066f5a 100644 --- a/network/juniper/common/ive/mode/users.pm +++ b/network/juniper/common/ive/mode/users.pm @@ -20,11 +20,53 @@ package network::juniper::common::ive::mode::users; -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 => 'global', type => 0, message_separator => ' - ' }, + ]; + $self->{maps_counters}->{global} = [ + { label => 'web', set => { + key_values => [ { name => 'web' } ], + output_template => 'Current concurrent signed-in web users connections: %s', output_error_template => 'Current concurrent signed-in web users connections: %s', + perfdatas => [ + { label => 'web', value => 'web_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'meeting', set => { + key_values => [ { name => 'meeting' } ], + output_template => 'Current concurrent meeting users connections: %s', output_error_template => 'Current concurrent meeting users connections: %s', + perfdatas => [ + { label => 'meeting', value => 'meeting_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'node', set => { + key_values => [ { name => 'node' } ], + output_template => 'Current concurrent node logged users connections: %s', output_error_template => 'Current concurrent node logged users connections: %s', + perfdatas => [ + { label => 'node', value => 'node_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'cluster', set => { + key_values => [ { name => 'cluster' } ], + output_template => 'Current concurrent cluster logged users connections: %s', output_error_template => 'Current concurrent cluster logged users connections: %s', + perfdatas => [ + { label => 'cluster', value => 'cluster_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -33,114 +75,24 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "warning-web:s" => { name => 'warning_web' }, - "critical-web:s" => { name => 'critical_web' }, - "warning-meeting:s" => { name => 'warning_meeting' }, - "critical-meeting:s" => { name => 'critical_meeting' }, - "warning-node:s" => { name => 'warning_node' }, - "critical-node:s" => { name => 'critical_node' }, - "warning-cluster:s" => { name => 'warning_cluster' }, - "critical-cluster:s" => { name => 'critical_cluster' }, }); return $self; } -sub check_options { +sub manage_selection { my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning_web', value => $self->{option_results}->{warning_web})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning web threshold '" . $self->{option_results}->{warning_web} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical_web', value => $self->{option_results}->{critical_web})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical web threshold '" . $self->{option_results}->{critical_web} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'warning_meeting', value => $self->{option_results}->{warning_meeting})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning meeting threshold '" . $self->{option_results}->{warning_meeting} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical_meeting', value => $self->{option_results}->{critical_meeting})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical meeting threshold '" . $self->{option_results}->{critical_meeting} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'warning_node', value => $self->{option_results}->{warning_node})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning node threshold '" . $self->{option_results}->{warning_node} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical_node', value => $self->{option_results}->{critical_node})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical node threshold '" . $self->{option_results}->{critical_node} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'warning_cluster', value => $self->{option_results}->{warning_cluster})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning cluster threshold '" . $self->{option_results}->{warning_cluster} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical_cluster', value => $self->{option_results}->{critical_cluster})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical cluster threshold '" . $self->{option_results}->{critical_cluster} . "'."); - $self->{output}->option_exit(); - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; my $oid_signedInWebUsers = '.1.3.6.1.4.1.12532.2.0'; my $oid_meetingUserCount = '.1.3.6.1.4.1.12532.9.0'; my $oid_iveConcurrentUsers = '.1.3.6.1.4.1.12532.12.0'; my $oid_clusterConcurrentUsers = '.1.3.6.1.4.1.12532.13.0'; - my $result = $self->{snmp}->get_leef(oids => [$oid_signedInWebUsers, $oid_meetingUserCount, - $oid_iveConcurrentUsers, $oid_clusterConcurrentUsers], nothing_quit => 1); - - my $exit1 = $self->{perfdata}->threshold_check(value => $result->{$oid_signedInWebUsers}, - threshold => [ { label => 'critical_web', 'exit_litteral' => 'critical' }, { label => 'warning_web', exit_litteral => 'warning' } ]); - my $exit2 = $self->{perfdata}->threshold_check(value => $result->{$oid_meetingUserCount}, - threshold => [ { label => 'critical_meeting', 'exit_litteral' => 'critical' }, { label => 'warning_meeting', exit_litteral => 'warning' } ]); - my $exit3 = $self->{perfdata}->threshold_check(value => $result->{$oid_iveConcurrentUsers}, - threshold => [ { label => 'critical_node', 'exit_litteral' => 'critical' }, { label => 'warning_node', exit_litteral => 'warning' } ]); - my $exit4 = $self->{perfdata}->threshold_check(value => $result->{$oid_clusterConcurrentUsers}, - threshold => [ { label => 'critical_cluster', 'exit_litteral' => 'critical' }, { label => 'warning_cluster', exit_litteral => 'warning' } ]); - - $self->{output}->output_add(severity => $exit1, - short_msg => sprintf("Current concurrent signed-in web users connections: %d", - $result->{$oid_signedInWebUsers})); - $self->{output}->output_add(severity => $exit2, - short_msg => sprintf("Current concurrent meeting users connections: %s", - defined($result->{$oid_meetingUserCount}) ? $result->{$oid_meetingUserCount} : 'unknown')); - $self->{output}->output_add(severity => $exit3, - short_msg => sprintf("Current concurrent node logged users connections: %d", - $result->{$oid_iveConcurrentUsers})); - $self->{output}->output_add(severity => $exit4, - short_msg => sprintf("Current concurrent cluster logged users connections: %d", - $result->{$oid_clusterConcurrentUsers})); - - $self->{output}->perfdata_add(label => "web", - value => $result->{$oid_signedInWebUsers}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_web'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_web'), - min => 0); - $self->{output}->perfdata_add(label => "meeting", - value => $result->{$oid_meetingUserCount}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_meeting'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_meeting'), - min => 0); - $self->{output}->perfdata_add(label => "node", - value => $result->{$oid_iveConcurrentUsers}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_node'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_node'), - min => 0); - $self->{output}->perfdata_add(label => "cluster", - value => $result->{$oid_clusterConcurrentUsers}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_cluster'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_cluster'), - min => 0); - - $self->{output}->display(); - $self->{output}->exit(); + my $result = $options{snmp}->get_leef(oids => [$oid_signedInWebUsers, $oid_meetingUserCount, + $oid_iveConcurrentUsers, $oid_clusterConcurrentUsers], nothing_quit => 1); + $self->{global} = { web => $result->{$oid_signedInWebUsers}, + meeting => $result->{$oid_meetingUserCount}, + node => $result->{$oid_iveConcurrentUsers}, + cluster => $result->{$oid_clusterConcurrentUsers} }; } 1; @@ -153,37 +105,20 @@ Check users connections (web users, cluster users, node users, meeting users) (J =over 8 -=item B<--warning-web> +=item B<--filter-counters> -Threshold warning for users connected and uses the web feature. +Only display some counters (regexp can be used). +Example: --filter-counters='^web|meeting$' -=item B<--critical-web> +=item B<--warning-*> -Threshold critical for users connected and uses the web feature. +Threshold warning. +Can be: 'web', 'meeting', 'node', 'cluster'. -=item B<--warning-meeting> +=item B<--critical-*> -Threshold warning for secure meeting users connected. - -=item B<--critical-meeting> - -Threshold critical for secure meeting users connected. - -=item B<--warning-node> - -Threshold warning for users in this node that are logged in. - -=item B<--critical-node> - -Threshold critical for users in this node that are logged in. - -=item B<--warning-cluster> - -Threshold warning for users in this cluster that are logged in. - -=item B<--critical-cluster> - -Threshold critical for users in this cluster that are logged in. +Threshold critical. +Can be: 'web', 'meeting', 'node', 'cluster'. =back diff --git a/network/juniper/common/junos/mode/components/fru.pm b/network/juniper/common/junos/mode/components/fru.pm index b9458b2e9..c45c8f059 100644 --- a/network/juniper/common/junos/mode/components/fru.pm +++ b/network/juniper/common/junos/mode/components/fru.pm @@ -76,9 +76,9 @@ my $mapping = { my $oid_jnxFruEntry = '.1.3.6.1.4.1.2636.3.1.15.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_jnxFruEntry, start => $mapping->{jnxFruName}->{oid}, end => $mapping->{jnxFruOfflineReason}->{oid} }; + push @{$self->{request}}, { oid => $oid_jnxFruEntry, start => $mapping->{jnxFruName}->{oid}, end => $mapping->{jnxFruOfflineReason}->{oid} }; } sub check { @@ -86,14 +86,14 @@ sub check { $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')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_jnxFruEntry}})) { next if ($oid !~ /^$mapping->{jnxFruName}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_jnxFruEntry}, instance => $instance); - next if ($self->check_exclude(section => 'fru', instance => $instance)); + next if ($self->check_filter(section => 'fru', instance => $instance)); next if ($result->{jnxFruState} =~ /empty/i && $self->absent_problem(section => 'fru', instance => $instance)); $self->{components}->{fru}->{total}++; diff --git a/network/juniper/common/junos/mode/components/operating.pm b/network/juniper/common/junos/mode/components/operating.pm index 3b3ad5bea..f6be53c42 100644 --- a/network/juniper/common/junos/mode/components/operating.pm +++ b/network/juniper/common/junos/mode/components/operating.pm @@ -41,9 +41,9 @@ my $mapping = { my $oid_jnxOperatingEntry = '.1.3.6.1.4.1.2636.3.1.13.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_jnxOperatingEntry, start => $mapping->{jnxOperatingDescr}->{oid}, end => $mapping->{jnxOperatingState}->{oid} }; + push @{$self->{request}}, { oid => $oid_jnxOperatingEntry, start => $mapping->{jnxOperatingDescr}->{oid}, end => $mapping->{jnxOperatingState}->{oid} }; } sub check { @@ -51,14 +51,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking operatings"); $self->{components}->{operating} = {name => 'operatings', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'operating')); + return if ($self->check_filter(section => 'operating')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_jnxOperatingEntry}})) { next if ($oid !~ /^$mapping->{jnxOperatingDescr}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_jnxOperatingEntry}, instance => $instance); - next if ($self->check_exclude(section => 'operating', instance => $instance)); + next if ($self->check_filter(section => 'operating', instance => $instance)); $self->{components}->{operating}->{total}++; $self->{output}->output_add(long_msg => sprintf("Operating '%s' state is %s [instance: %s]", diff --git a/network/juniper/common/junos/mode/hardware.pm b/network/juniper/common/junos/mode/hardware.pm index 8f31b2469..3c3eadde5 100644 --- a/network/juniper/common/junos/mode/hardware.pm +++ b/network/juniper/common/junos/mode/hardware.pm @@ -20,34 +20,54 @@ package network::juniper::common::junos::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -my $thresholds = { - fru => [ - ['unknown', 'UNKNOWN'], - ['present', 'OK'], - ['ready', 'OK'], - ['announce online', 'OK'], - ['online', 'OK'], - ['announce offline', 'WARNING'], - ['offline', 'CRITICAL'], - ['diagnostic', 'WARNING'], - ['standby', 'WARNING'], - ['empty', 'OK'], - ], - operating => [ - ['unknown', 'UNKNOWN'], - ['running', 'OK'], - ['ready', 'OK'], - ['reset', 'WARNING'], - ['runningAtFullSpeed', 'WARNING'], - ['down', 'CRITICAL'], - ['standby', 'OK'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(fru|operating)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(fru-temperature)$'; + + $self->{cb_hook1} = 'get_type'; + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + fru => [ + ['unknown', 'UNKNOWN'], + ['present', 'OK'], + ['ready', 'OK'], + ['announce online', 'OK'], + ['online', 'OK'], + ['announce offline', 'WARNING'], + ['offline', 'CRITICAL'], + ['diagnostic', 'WARNING'], + ['standby', 'WARNING'], + ['empty', 'OK'], + ], + operating => [ + ['unknown', 'UNKNOWN'], + ['running', 'OK'], + ['ready', 'OK'], + ['reset', 'WARNING'], + ['runningAtFullSpeed', 'WARNING'], + ['down', 'CRITICAL'], + ['standby', 'OK'], + ], + }; + + $self->{components_path} = 'network::juniper::common::junos::mode::components'; + $self->{components_module} = ['fru', 'operating']; +} + +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) = @_; @@ -56,220 +76,23 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "exclude:s" => { name => 'exclude' }, - "absent-problem:s" => { name => 'absent' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { }); - $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'; - } - } - - $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->{numeric_threshold} = {}; - foreach my $option (('warning', 'critical')) { - foreach my $val (@{$self->{option_results}->{$option}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $regexp, $value) = ($1, $2, $3); - if ($section !~ /(fru-temperature)/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "' (type must be: fru-temperature)."); - $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, regexp => $regexp }; - } - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - $self->get_type(); - - my $snmp_request = []; - my @components = ('fru', 'operating'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::juniper::common::junos::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::juniper::common::junos::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - sub get_type { - my ($self) = @_; + my ($self, %options) = @_; my $oid_jnxBoxDescr = ".1.3.6.1.4.1.2636.3.1.2.0"; - my $result = $self->{snmp}->get_leef(oids => [$oid_jnxBoxDescr]); + 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})); } - -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; -} - -sub absent_problem { - my ($self, %options) = @_; - - if (defined($self->{option_results}->{absent}) && - $self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - } - - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); - $self->{components}->{$options{section}}->{skip}++; - return 1; -} - -sub get_severity_numeric { - 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} =~ /$_->{regexp}/) { - 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 - - 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; -} - 1; __END__ @@ -285,15 +108,15 @@ Check Hardware (mib-jnx-chassis) (frus, operating). Which component to check (Default: '.*'). Can be: 'fru', 'operating'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=fru) -Can also exclude specific instance: --exclude=fru#7.3.0.0# +Exclude some parts (comma seperated list) (Example: --filter=fru) +Can also exclude specific instance: --filter=fru,7.3.0.0 =item B<--absent-problem> Return an error if an entity is not 'present' (default is skipping) (comma seperated list) -Can be specific or global: --absent-problem=fru#7.1.0.0# +Can be specific or global: --absent-problem=fru,7.1.0.0 =item B<--no-component> @@ -302,18 +125,18 @@ If total (with skipped) is 0. (Default: 'critical' returns). =item B<--threshold-overload> -Set to overload default threshold values (syntax: section,status,regexp) +Set to overload default threshold values (syntax: section,[instance,]status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='operating,CRITICAL,^(?!(running)$)' =item B<--warning> -Set warning threshold for fru temperatures (syntax: type,regexp,treshold) +Set warning threshold for fru temperatures (syntax: type,regexp,threshold) Example: --warning='fru-temperature,.*,30' =item B<--critical> -Set critical threshold for fru temperatures (syntax: type,regexp,treshold) +Set critical threshold for fru temperatures (syntax: type,regexp,threshold) Example: --critical='fru-temperature,.*,40' =back diff --git a/network/juniper/common/screenos/mode/components/fan.pm b/network/juniper/common/screenos/mode/components/fan.pm index 0007759ec..7da0b128f 100644 --- a/network/juniper/common/screenos/mode/components/fan.pm +++ b/network/juniper/common/screenos/mode/components/fan.pm @@ -34,9 +34,9 @@ my $mapping = { my $oid_nsFanEntry = '.1.3.6.1.4.1.3224.21.2.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_nsFanEntry }; + push @{$self->{request}}, { oid => $oid_nsFanEntry }; } sub check { diff --git a/network/juniper/common/screenos/mode/components/module.pm b/network/juniper/common/screenos/mode/components/module.pm index 568bc5011..a589fab14 100644 --- a/network/juniper/common/screenos/mode/components/module.pm +++ b/network/juniper/common/screenos/mode/components/module.pm @@ -35,9 +35,9 @@ my $mapping = { my $oid_nsSlotEntry = '.1.3.6.1.4.1.3224.21.5.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_nsSlotEntry }; + push @{$self->{request}}, { oid => $oid_nsSlotEntry }; } sub check { diff --git a/network/juniper/common/screenos/mode/components/psu.pm b/network/juniper/common/screenos/mode/components/psu.pm index be8f99471..4b88ae158 100644 --- a/network/juniper/common/screenos/mode/components/psu.pm +++ b/network/juniper/common/screenos/mode/components/psu.pm @@ -34,9 +34,9 @@ my $mapping = { my $oid_nsPowerEntry = '.1.3.6.1.4.1.3224.21.1.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_nsPowerEntry }; + push @{$self->{request}}, { oid => $oid_nsPowerEntry }; } sub check { diff --git a/network/juniper/common/screenos/mode/components/temperature.pm b/network/juniper/common/screenos/mode/components/temperature.pm index 05ec02119..047667e4f 100644 --- a/network/juniper/common/screenos/mode/components/temperature.pm +++ b/network/juniper/common/screenos/mode/components/temperature.pm @@ -30,9 +30,9 @@ my $mapping = { my $oid_nsTemperatureEntry = '.1.3.6.1.4.1.3224.21.4.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_nsTemperatureEntry }; + push @{$self->{request}}, { oid => $oid_nsTemperatureEntry }; } sub check { diff --git a/network/juniper/common/screenos/mode/hardware.pm b/network/juniper/common/screenos/mode/hardware.pm index 705f2c3b2..c4a808cb7 100644 --- a/network/juniper/common/screenos/mode/hardware.pm +++ b/network/juniper/common/screenos/mode/hardware.pm @@ -20,240 +20,58 @@ package network::juniper::common::screenos::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -my $thresholds = { - fan => [ - ['active', 'OK'], - ['.*', 'CRITICAL'], - ], - module => [ - ['active', 'OK'], - ['.*', 'CRITICAL'], - ], - psu => [ - ['active', 'OK'], - ['.*', 'CRITICAL'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(psu|module|fan)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + fan => [ + ['active', 'OK'], + ['.*', 'CRITICAL'], + ], + module => [ + ['active', 'OK'], + ['.*', 'CRITICAL'], + ], + psu => [ + ['active', 'OK'], + ['.*', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'network::juniper::common::screenos::mode::components'; + $self->{components_module} = ['psu', 'fan', 'temperature', 'module']; +} + +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); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1); bless $self, $class; $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "filter:s@" => { name => 'filter' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { }); - $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'; - } - } - - $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 !~ /^temperature|psu|module|fan$/) { - $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 !~ /^sensor$/) { - $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 }; - } - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('psu', 'fan', 'temperature', 'module'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::juniper::common::screenos::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::juniper::common::screenos::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - - -sub check_filter { - 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->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); - return 1; - } - } - } - - return 0; -} - -sub get_severity_numeric { - 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 - - 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; - } - } - - return $status; -} - 1; __END__ diff --git a/network/juniper/common/screenos/mode/sessions.pm b/network/juniper/common/screenos/mode/sessions.pm index b529e1922..05531164e 100644 --- a/network/juniper/common/screenos/mode/sessions.pm +++ b/network/juniper/common/screenos/mode/sessions.pm @@ -20,99 +20,80 @@ package network::juniper::common::screenos::mode::sessions; -use base qw(centreon::plugins::mode); +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, message_separator => ' - ' }, + ]; + $self->{maps_counters}->{global} = [ + { label => 'usage', set => { + key_values => [ { name => 'prct_used' }, { name => 'total' }, { name => 'used' } ], + closure_custom_output => $self->can('custom_usage_output'), + perfdatas => [ + { label => 'sessions', value => 'used_absolute', template => '%s', + min => 0, max => 'total_absolute', threshold_total => 'total_absolute', cast_int => 1 }, + ], + } + }, + { label => 'failed', set => { + key_values => [ { name => 'failed', diff => 1 } ], + per_second => 1, + output_template => 'Failed sessions : %.2f/s', output_error_template => "Failed sessions : %s", + perfdatas => [ + { label => 'sessions_failed', value => 'failed_per_second', template => '%.2f', unit => '/s', + min => 0 }, + ], + } + }, + ]; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my $msg = sprintf("%.2f%% of the sessions limit reached (%d of max. %d)", + $self->{result_values}->{prct_used_absolute}, + $self->{result_values}->{used_absolute}, + $self->{result_values}->{total_absolute}); + return $msg; +} 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', }, - "warning-failed:s" => { name => 'warning_failed', }, - "critical:s" => { name => 'critical', }, - "critical-failed:s" => { name => 'critical_failed', }, + { }); 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(); - } - if (($self->{perfdata}->threshold_validate(label => 'warning-failed', value => $self->{option_results}->{warning_failed})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning-failed threshold '" . $self->{option_results}->{warning_failed} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical-failed', value => $self->{option_results}->{critical_failed})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical-failed threshold '" . $self->{option_results}->{critical_failed} . "'."); - $self->{output}->option_exit(); - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - my $oid_nsResSessAllocate = '.1.3.6.1.4.1.3224.16.3.2.0'; my $oid_nsResSessMaxium = '.1.3.6.1.4.1.3224.16.3.3.0'; my $oid_nsResSessFailed = '.1.3.6.1.4.1.3224.16.3.4.0'; - my $result = $self->{snmp}->get_leef(oids => [$oid_nsResSessAllocate, $oid_nsResSessMaxium, $oid_nsResSessFailed], nothing_quit => 1); - - my $spu_done = 0; - my $cp_total = $result->{$oid_nsResSessMaxium}; - my $cp_used = $result->{$oid_nsResSessAllocate}; - my $cp_failed = $result->{$oid_nsResSessFailed}; - my $prct_used = $cp_used * 100 / $cp_total; - my $prct_failed = $cp_failed * 100 / $cp_total; - $spu_done = 1; - - my $exit_used = $self->{perfdata}->threshold_check(value => $prct_used, - threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my $exit_failed = $self->{perfdata}->threshold_check(value => $prct_failed, - threshold => [ { label => 'critical-failed', 'exit_litteral' => 'critical' }, { label => 'warning-failed', exit_litteral => 'warning' } ]); - - $self->{output}->output_add(severity => $exit_used, - short_msg => sprintf("%.2f%% of the sessions limit reached (%d of max. %d)", - $prct_used, $cp_used, $cp_total)); - $self->{output}->output_add(severity => $exit_failed, - short_msg => sprintf("%.2f%% of failed sessions (%d of max. %d)", - $prct_failed, $cp_failed, $cp_total)); - - $self->{output}->perfdata_add(label => 'sessions', - value => $cp_used, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $cp_total, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $cp_total, cast_int => 1), - min => 0, max => $cp_total); - $self->{output}->perfdata_add(label => 'sessions_failed', - value => $cp_failed, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-failed', total => $cp_total, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-failed', total => $cp_total, cast_int => 1), - min => 0, max => $cp_total); - - if ($spu_done == 0) { - $self->{output}->add_option_msg(short_msg => "Cannot check sessions usage (no total values)."); - $self->{output}->option_exit(); - } - - $self->{output}->display(); - $self->{output}->exit(); + my $result = $options{snmp}->get_leef(oids => [$oid_nsResSessAllocate, $oid_nsResSessMaxium, $oid_nsResSessFailed], nothing_quit => 1); + $self->{global} = { total => $result->{$oid_nsResSessMaxium}, + used => $result->{$oid_nsResSessAllocate}, + failed => $result->{$oid_nsResSessFailed}, + prct_used => $result->{$oid_nsResSessAllocate} * 100 / $result->{$oid_nsResSessMaxium}, + }; + + $self->{cache_name} = "juniper_" . $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; @@ -123,21 +104,20 @@ Check Juniper sessions usage and failed sessions (NETSCREEN-RESOURCE-MIB). =over 8 -=item B<--warning> +=item B<--filter-counters> -Threshold warning (percentage). +Only display some counters (regexp can be used). +Example: --filter-counters='^usage$' -=item B<--critical> +=item B<--warning-*> -Threshold critical (percentage). +Threshold warning. +Can be: 'usage' (%), 'failed'. -=item B<--warning-failed> +=item B<--critical-*> -Threshold warning on failed sessions (percentage). - -=item B<--critical-failed> - -Threshold critical in failed sessions (percentage). +Threshold critical. +Can be: 'usage' (%), 'failed'. =back diff --git a/network/redback/snmp/mode/components/disk.pm b/network/redback/snmp/mode/components/disk.pm index afee478a8..209063263 100644 --- a/network/redback/snmp/mode/components/disk.pm +++ b/network/redback/snmp/mode/components/disk.pm @@ -37,9 +37,9 @@ my $mapping = { my $oid_rbnSRStorageEntry = '.1.3.6.1.4.1.2352.2.24.1.2.1.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_rbnSRStorageEntry }; + push @{$self->{request}}, { oid => $oid_rbnSRStorageEntry }; } sub check { @@ -47,14 +47,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking disks"); $self->{components}->{disk} = {name => 'disks', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'disk')); + return if ($self->check_filter(section => 'disk')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_rbnSRStorageEntry}})) { next if ($oid !~ /^$mapping->{rbnSRStorageStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_rbnSRStorageEntry}, instance => $instance); - next if ($self->check_exclude(section => 'disk', 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].", diff --git a/network/redback/snmp/mode/components/fan.pm b/network/redback/snmp/mode/components/fan.pm index de66c2a0b..dcfedab8c 100644 --- a/network/redback/snmp/mode/components/fan.pm +++ b/network/redback/snmp/mode/components/fan.pm @@ -38,9 +38,9 @@ my $mapping = { my $oid_rbnFanStatusEntry = '.1.3.6.1.4.1.2352.2.4.1.1.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_rbnFanStatusEntry }; + push @{$self->{request}}, { oid => $oid_rbnFanStatusEntry }; } sub check { @@ -48,14 +48,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking fans"); $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fan')); + return if ($self->check_filter(section => 'fan')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_rbnFanStatusEntry}})) { next if ($oid !~ /^$mapping->{rbnFanStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_rbnFanStatusEntry}, instance => $instance); - next if ($self->check_exclude(section => 'fan', instance => $instance)); + next if ($self->check_filter(section => 'fan', instance => $instance)); next if ($result->{rbnFanStatus} =~ /absent/i && $self->absent_problem(section => 'fan', instance => $instance)); $self->{components}->{fan}->{total}++; diff --git a/network/redback/snmp/mode/components/psu.pm b/network/redback/snmp/mode/components/psu.pm index 0fcb8395d..6bea8f2d6 100644 --- a/network/redback/snmp/mode/components/psu.pm +++ b/network/redback/snmp/mode/components/psu.pm @@ -38,9 +38,9 @@ my $mapping = { my $oid_rbnPowerStatusEntry = '.1.3.6.1.4.1.2352.2.4.1.2.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_rbnPowerStatusEntry }; + push @{$self->{request}}, { oid => $oid_rbnPowerStatusEntry }; } sub check { @@ -48,14 +48,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking power supplies"); $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'psu')); + return if ($self->check_filter(section => 'psu')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_rbnPowerStatusEntry}})) { next if ($oid !~ /^$mapping->{rbnPowerStatus}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_rbnPowerStatusEntry}, instance => $instance); - next if ($self->check_exclude(section => 'psu', instance => $instance)); + next if ($self->check_filter(section => 'psu', instance => $instance)); next if ($result->{rbnPowerStatus} =~ /absent/i && $self->absent_problem(section => 'psu', instance => $instance)); $self->{components}->{psu}->{total}++; diff --git a/network/redback/snmp/mode/components/temperature.pm b/network/redback/snmp/mode/components/temperature.pm index 8aa26b996..4d712a1b7 100644 --- a/network/redback/snmp/mode/components/temperature.pm +++ b/network/redback/snmp/mode/components/temperature.pm @@ -31,9 +31,9 @@ my $mapping = { my $oid_rbnEntityTempSensorEntry = '.1.3.6.1.4.1.2352.2.4.1.6.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_rbnEntityTempSensorEntry }; + push @{$self->{request}}, { oid => $oid_rbnEntityTempSensorEntry }; } sub check { @@ -41,14 +41,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking temperatures"); $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'temperature')); + return if ($self->check_filter(section => 'temperature')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_rbnEntityTempSensorEntry}})) { next if ($oid !~ /^$mapping->{rbnEntityTempCurrent}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_rbnEntityTempSensorEntry}, instance => $instance); - next if ($self->check_exclude(section => 'temperature', instance => $instance)); + next if ($self->check_filter(section => 'temperature', instance => $instance)); $self->{components}->{temperature}->{total}++; $self->{output}->output_add(long_msg => sprintf("'%s' temperature is %dC [instance: %s].", diff --git a/network/redback/snmp/mode/components/voltage.pm b/network/redback/snmp/mode/components/voltage.pm index afdf75800..6ae69e7de 100644 --- a/network/redback/snmp/mode/components/voltage.pm +++ b/network/redback/snmp/mode/components/voltage.pm @@ -31,9 +31,9 @@ my $mapping = { my $oid_rbnVoltageSensorEntry = '.1.3.6.1.4.1.2352.2.4.1.3.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_rbnVoltageSensorEntry }; + push @{$self->{request}}, { oid => $oid_rbnVoltageSensorEntry }; } sub check { @@ -41,14 +41,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking voltages"); $self->{components}->{voltage} = {name => 'voltages', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'voltage')); + return if ($self->check_filter(section => 'voltage')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_rbnVoltageSensorEntry}})) { next if ($oid !~ /^$mapping->{rbnVoltageCurrent}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_rbnVoltageSensorEntry}, instance => $instance); - next if ($self->check_exclude(section => 'voltage', instance => $instance)); + next if ($self->check_filter(section => 'voltage', instance => $instance)); $self->{components}->{voltage}->{total}++; $self->{output}->output_add(long_msg => sprintf("'%s' voltage is %d mV [instance: %s].", diff --git a/network/redback/snmp/mode/disk.pm b/network/redback/snmp/mode/disk.pm index 0b5ac4982..f1432ad4e 100644 --- a/network/redback/snmp/mode/disk.pm +++ b/network/redback/snmp/mode/disk.pm @@ -20,25 +20,10 @@ package network::redback::snmp::mode::disk; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; - -my $maps_counters = { - '0_usage' => { class => 'centreon::plugins::values', obj => undef, - 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) = @_; @@ -87,6 +72,31 @@ sub custom_usage_calc { 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' } + ]; + + $self->{maps_counters}->{disk} = [ + { label => 'usage', 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_disk_output { + my ($self, %options) = @_; + + return "Disk '" . $options{instance_value}->{display} . "' "; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -97,95 +107,10 @@ sub new { { "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(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}); - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{disk_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->{disk_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->{disk_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(extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Disk '" . $self->{disk_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->{disk_selected}->{$id}->{display} . "' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Disk '" . $self->{disk_selected}->{$id}->{display} . "' $long_msg"); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} - my $mapping = { rbnSRStorageDescr => { oid => '.1.3.6.1.4.1.2352.2.24.1.2.1.1.2' }, rbnSRStorageSize => { oid => '.1.3.6.1.4.1.2352.2.24.1.2.1.1.5' }, # KB @@ -195,14 +120,14 @@ my $mapping = { sub manage_selection { my ($self, %options) = @_; - $self->{disk_selected} = {}; + $self->{disk} = {}; my $oid_rbnSRStorageEntry = '.1.3.6.1.4.1.2352.2.24.1.2.1.1'; - $self->{results} = $self->{snmp}->get_table(oid => $oid_rbnSRStorageEntry, + $self->{results} = $options{snmp}->get_table(oid => $oid_rbnSRStorageEntry, nothing_quit => 1); foreach my $oid (keys %{$self->{results}}) { next if ($oid !~ /^$mapping->{rbnSRStorageSize}->{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 => $self->{results}, instance => $instance); if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $result->{rbnSRStorageDescr} !~ /$self->{option_results}->{filter_name}/) { $self->{output}->output_add(long_msg => "Skipping '" . $result->{rbnSRStorageDescr} . "': no matching filter."); @@ -213,11 +138,11 @@ sub manage_selection { next; } - $self->{disk_selected}->{$instance} = { display => $result->{rbnSRStorageDescr}, - used => $result->{rbnSRStorageUtilization}, total => $result->{rbnSRStorageSize} * 1024}; + $self->{disk}->{$instance} = { display => $result->{rbnSRStorageDescr}, + used => $result->{rbnSRStorageUtilization}, total => $result->{rbnSRStorageSize} * 1024}; } - if (scalar(keys %{$self->{disk_selected}}) <= 0) { + if (scalar(keys %{$self->{disk}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No entry found."); $self->{output}->option_exit(); } diff --git a/network/redback/snmp/mode/hardware.pm b/network/redback/snmp/mode/hardware.pm index 0d0c8044c..586330438 100644 --- a/network/redback/snmp/mode/hardware.pm +++ b/network/redback/snmp/mode/hardware.pm @@ -20,30 +20,49 @@ package network::redback::snmp::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -my $thresholds = { - fan => [ - ['unknown', 'UNKNOWN'], - ['normal', 'OK'], - ['failed', 'CRITICAL'], - ['absent', 'OK'], - ], - psu => [ - ['unknown', 'UNKNOWN'], - ['normal', 'OK'], - ['failed', 'CRITICAL'], - ['absent', 'OK'], - ], - disk => [ - ['operational', 'OK'], - ['failed', 'CRITICAL'], - ['degrading', 'WARNING'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(fan|psu|disk)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|voltage)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + fan => [ + ['unknown', 'UNKNOWN'], + ['normal', 'OK'], + ['failed', 'CRITICAL'], + ['absent', 'OK'], + ], + psu => [ + ['unknown', 'UNKNOWN'], + ['normal', 'OK'], + ['failed', 'CRITICAL'], + ['absent', 'OK'], + ], + disk => [ + ['operational', 'OK'], + ['failed', 'CRITICAL'], + ['degrading', 'WARNING'], + ], + }; + + $self->{components_path} = 'network::redback::snmp::mode::components'; + $self->{components_module} = ['fan', 'psu', 'temperature', 'voltage', 'disk']; +} + +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) = @_; @@ -52,208 +71,12 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "exclude:s" => { name => 'exclude' }, - "absent-problem:s" => { name => 'absent' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { }); - $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'; - } - } - - $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->{numeric_threshold} = {}; - foreach my $option (('warning', 'critical')) { - foreach my $val (@{$self->{option_results}->{$option}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $regexp, $value) = ($1, $2, $3); - if ($section !~ /(temperature|voltage)/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "' (type must be: temperature or voltage)."); - $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, regexp => $regexp }; - } - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('fan', 'psu', 'temperature', 'voltage', 'disk'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::redback::snmp::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "network::redback::snmp::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $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; -} - -sub absent_problem { - my ($self, %options) = @_; - - if (defined($self->{option_results}->{absent}) && - $self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - } - - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); - $self->{components}->{$options{section}}->{skip}++; - return 1; -} - - -sub get_severity_numeric { - 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} =~ /$_->{regexp}/) { - 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 - - 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; -} - 1; __END__ @@ -269,15 +92,15 @@ Check Hardware (Power Supplies, Fans, Temperatures, Voltages, Disks). Which component to check (Default: '.*'). Can be: 'fan', 'psu', 'temperature', 'voltage', 'disk'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=fan) -Can also exclude specific instance: --exclude=fan#1#,psu#3# +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=psu) +Can also exclude specific instance: --filter=fan,1 =item B<--absent-problem> Return an error if an entity is not 'present' (default is skipping) (comma seperated list) -Can be specific or global: --absent-problem=fan#1# +Can be specific or global: --absent-problem=fan,1 =item B<--no-component> @@ -286,7 +109,7 @@ If total (with skipped) is 0. (Default: 'critical' returns). =item B<--threshold-overload> -Set to overload default threshold values (syntax: section,status,regexp) +Set to overload default threshold values (syntax: section,[instance,]status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='fan,CRITICAL,^(?!(normal)$)' diff --git a/network/redback/snmp/mode/memory.pm b/network/redback/snmp/mode/memory.pm index 700145de6..ed9dd24b3 100644 --- a/network/redback/snmp/mode/memory.pm +++ b/network/redback/snmp/mode/memory.pm @@ -20,25 +20,10 @@ package network::redback::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 $maps_counters = { - '0_usage' => { class => 'centreon::plugins::values', obj => undef, - 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) = @_; @@ -87,6 +72,31 @@ 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', set => { + key_values => [ { name => 'display' }, { name => 'free' }, { 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) = @_; + + return "Memory '" . $options{instance_value}->{display} . "' "; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -96,96 +106,11 @@ sub new { $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(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}); - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $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(extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Memory '" . $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 => "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 $mapping = { rbnMemoryModule => { oid => '.1.3.6.1.4.1.2352.2.16.1.2.1.2' }, rbnMemoryFreeKBytes => { oid => '.1.3.6.1.4.1.2352.2.16.1.2.1.3' }, @@ -195,25 +120,25 @@ my $mapping = { sub manage_selection { my ($self, %options) = @_; - $self->{memory_selected} = {}; + $self->{memory} = {}; my $oid_rbnMemoryEntry = '.1.3.6.1.4.1.2352.2.16.1.2.1'; - $self->{results} = $self->{snmp}->get_table(oid => $oid_rbnMemoryEntry, - nothing_quit => 1); + $self->{results} = $options{snmp}->get_table(oid => $oid_rbnMemoryEntry, + nothing_quit => 1); foreach my $oid (keys %{$self->{results}}) { next if ($oid !~ /^$mapping->{rbnMemoryModule}->{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 => $self->{results}, instance => $instance); if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $result->{rbnMemoryModule} !~ /$self->{option_results}->{filter_name}/) { $self->{output}->output_add(long_msg => "Skipping '" . $result->{rbnMemoryModule} . "': no matching filter."); next; } - $self->{memory_selected}->{$instance} = { display => $result->{rbnMemoryModule}, - free => $result->{rbnMemoryFreeKBytes} * 1024, used => $result->{rbnMemoryKBytesInUse} * 1024}; + $self->{memory}->{$instance} = { display => $result->{rbnMemoryModule}, + free => $result->{rbnMemoryFreeKBytes} * 1024, used => $result->{rbnMemoryKBytesInUse} * 1024}; } - 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/snmp_standard/mode/diskio.pm b/snmp_standard/mode/diskio.pm index ad93f7ea9..ed26dea82 100644 --- a/snmp_standard/mode/diskio.pm +++ b/snmp_standard/mode/diskio.pm @@ -20,83 +20,42 @@ package snmp_standard::mode::diskio; -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 = { - disk => { - '000_read' => { set => { - key_values => [ { name => 'read', diff => 1 }, { name => 'display' } ], - per_second => 1, - output_template => 'Read I/O : %s %s/s', output_error_template => "Read I/O : %s", - output_change_bytes => 1, - perfdatas => [ - { label => 'read', value => 'read_per_second', template => '%d', - unit => 'B/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '001_write' => { set => { - key_values => [ { name => 'write', diff => 1 }, { name => 'display' } ], - per_second => 1, - output_template => 'Write I/O : %s %s/s', output_error_template => "Write I/O : %s", - output_change_bytes => 1, - perfdatas => [ - { label => 'write', value => 'write_per_second', template => '%d', - unit => 'B/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '002_read-iops' => { set => { - key_values => [ { name => 'read_iops', diff => 1 }, { name => 'display' } ], - per_second => 1, - output_template => 'Read IOPs : %.2f', output_error_template => "Read IOPs : %s", - perfdatas => [ - { label => 'read_iops', value => 'read_iops_per_second', template => '%.2f', - unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - '003_write-iops' => { set => { - key_values => [ { name => 'write_iops', diff => 1 }, { name => 'display' } ], - per_second => 1, - output_template => 'Write IOPs : %.2f', output_error_template => "Write IOPs : %s", - perfdatas => [ - { label => 'write_iops', value => 'write_iops_per_second', template => '%.2f', - unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - } - }, - }, - total => { - '000_total-read' => { set => { +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_init => 'skip_global', cb_prefix_output => 'prefix_global_output', cb_suffix_output => 'suffix_output' }, + { name => 'sum', type => 0, cb_init => 'skip_global', cb_prefix_output => 'prefix_sum_output', cb_suffix_output => 'suffix_output' }, + { name => 'disk', type => 1, cb_prefix_output => 'prefix_disk_output', message_multiple => 'All devices are ok' } + ]; + $self->{maps_counters}->{global} = [ + { label => 'total-read', set => { key_values => [ { name => 'total_read', diff => 1 } ], - per_second => 1, output_template => 'Read I/O : %s %s/s', output_error_template => "Read I/O : %s", - output_change_bytes => 1, + output_change_bytes => 1, per_second => 1, perfdatas => [ { label => 'total_read', value => 'total_read_per_second', template => '%d', unit => 'B/s', min => 0 }, ], } }, - '001_total-write' => { set => { + { label => 'total-write', set => { key_values => [ { name => 'total_write', diff => 1 } ], - per_second => 1, output_template => 'Write I/O : %s %s/s', output_error_template => "Write I/O : %s", - output_change_bytes => 1, + output_change_bytes => 1, per_second => 1, perfdatas => [ { label => 'total_write', value => 'total_write_per_second', template => '%d', unit => 'B/s', min => 0 }, ], } }, - '002_total-read-iops' => { set => { + { label => 'total-read-iops', set => { key_values => [ { name => 'total_read_iops', diff => 1 } ], per_second => 1, output_template => 'Read IOPs : %.2f', output_error_template => "Read IOPs : %s", @@ -106,7 +65,7 @@ my $maps_counters = { ], } }, - '003_total-write-iops' => { set => { + { label => 'total-write-iops', set => { key_values => [ { name => 'total_write_iops', diff => 1 } ], per_second => 1, output_template => 'Write IOPs : %.2f', output_error_template => "Write IOPs : %s", @@ -115,10 +74,11 @@ my $maps_counters = { unit => 'iops', min => 0 }, ], } - }, - }, - sum => { - '000_sum-read-write' => { set => { + }, + ]; + + $self->{maps_counters}->{sum} = [ + { label => 'sum-read-write', set => { key_values => [ { name => 'sum_read_write', diff => 1 } ], per_second => 1, output_template => 'R+W I/O : %s %s/s', output_error_template => "R+W I/O : %s", @@ -128,8 +88,8 @@ my $maps_counters = { unit => 'B/s', min => 0 }, ], } - }, - '001_sum-read-write-iops' => { set => { + }, + { label => 'sum-read-write-iops', set => { key_values => [ { name => 'sum_read_write_iops', diff => 1 } ], per_second => 1, output_template => 'R+W IOPs : %.2f', output_error_template => "R+W IOPs : %s", @@ -139,18 +99,55 @@ my $maps_counters = { ], } }, - }, -}; - -my $oid_diskIODevice = '.1.3.6.1.4.1.2021.13.15.1.1.2'; -my $oid_diskIOReads = '.1.3.6.1.4.1.2021.13.15.1.1.5'; -my $oid_diskIOWrites = '.1.3.6.1.4.1.2021.13.15.1.1.6'; -my $oid_diskIONReadX = '.1.3.6.1.4.1.2021.13.15.1.1.12'; # in B -my $oid_diskIONWrittenX = '.1.3.6.1.4.1.2021.13.15.1.1.13'; # in B + ]; + + $self->{maps_counters}->{disk} = [ + { label => 'read', set => { + key_values => [ { name => 'read', diff => 1 }, { name => 'display' } ], + output_template => 'Read I/O : %s %s/s', output_error_template => "Read I/O : %s", + output_change_bytes => 1, per_second => 1, + perfdatas => [ + { label => 'read', value => 'read_per_second', template => '%d', + unit => 'B/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write', set => { + key_values => [ { name => 'write', diff => 1 }, { name => 'display' } ], + output_template => 'Write I/O : %s %s/s', output_error_template => "Write I/O : %s", + output_change_bytes => 1, per_second => 1, + perfdatas => [ + { label => 'write', value => 'write_per_second', template => '%d', + unit => 'B/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'read-iops', set => { + key_values => [ { name => 'read_iops', diff => 1 }, { name => 'display' } ], + per_second => 1, + output_template => 'Read IOPs : %.2f', output_error_template => "Read IOPs : %s", + perfdatas => [ + { label => 'read_iops', value => 'read_iops_per_second', template => '%.2f', + unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-iops', set => { + key_values => [ { name => 'write_iops', diff => 1 }, { name => 'display' } ], + per_second => 1, + output_template => 'Write IOPs : %.2f', output_error_template => "Write IOPs : %s", + perfdatas => [ + { label => 'write_iops', value => 'write_iops_per_second', template => '%.2f', + unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_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'; @@ -161,240 +158,91 @@ sub new { "regexp" => { name => 'use_regexp' }, "regexp-isensitive" => { name => 'use_regexpi' }, }); - - $self->{device_id_selected} = {}; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - - foreach my $key (('total', 'disk', 'sum')) { - 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 (('total', 'disk', 'sum')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - $self->{statefile_value}->check_options(%options); -} - -sub check_total { +sub skip_global { 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 => "All devices [$short_msg]" - ); - } else { - $self->{output}->output_add(short_msg => "All devices [$long_msg]"); - } + scalar(keys %{$self->{disk}}) > 1 ? return(0) : return(1); } -sub check_sum { +sub prefix_global_output { my ($self, %options) = @_; - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{sum}}) { - my $obj = $maps_counters->{sum}->{$_}->{obj}; - $obj->set(instance => 'sum'); - - my ($value_check) = $obj->execute(values => $self->{sum_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 => "Server overall [$short_msg]" - ); - } else { - $self->{output}->output_add(short_msg => "Server overall [$long_msg]"); - } + + return "All devices ["; } -sub run { +sub prefix_sum_output { 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 => "snmpstandard_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{device}) ? md5_hex($self->{option_results}->{device}) : md5_hex('all'))); - $self->{new_datas}->{last_timestamp} = time(); - - my $multiple = 1; - if (scalar(keys %{$self->{device_id_selected}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->check_total(); - $self->check_sum(); - $self->{output}->output_add(severity => 'OK', - short_msg => 'All devices are ok.'); - } - - foreach my $id (sort keys %{$self->{device_id_selected}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters->{disk}}) { - my $obj = $maps_counters->{disk}->{$_}->{obj}; - - $obj->set(instance => $id); - my ($value_check) = $obj->execute(values => $self->{device_id_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 = ', '; - } - - $obj->perfdata(extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "Device '" . $self->{device_id_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 => "Device '" . $self->{device_id_selected}->{$id}->{display} . "' $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "Device '" . $self->{device_id_selected}->{$id}->{display} . "' $long_msg"); - } - } - - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); + return "Server overall ["; } +sub prefix_disk_output { + my ($self, %options) = @_; + + return "Device '" . $options{instance_value}->{display} . "' "; +} + +sub suffix_output { + my ($self, %options) = @_; + + return "]"; +} + +my $oid_diskIODevice = '.1.3.6.1.4.1.2021.13.15.1.1.2'; +my $oid_diskIOReads = '.1.3.6.1.4.1.2021.13.15.1.1.5'; +my $oid_diskIOWrites = '.1.3.6.1.4.1.2021.13.15.1.1.6'; +my $oid_diskIONReadX = '.1.3.6.1.4.1.2021.13.15.1.1.12'; # in B +my $oid_diskIONWrittenX = '.1.3.6.1.4.1.2021.13.15.1.1.13'; # in B + sub add_result { my ($self, %options) = @_; - $self->{device_id_selected}->{$options{instance}} = { read => undef, write => undef, read_iops => undef, write_iops => undef }; - $self->{device_id_selected}->{$options{instance}}->{display} = $self->{results}->{$oid_diskIODevice}->{$oid_diskIODevice . '.' . $options{instance}}; + $self->{disk}->{$options{instance}} = { read => undef, write => undef, read_iops => undef, write_iops => undef }; + $self->{disk}->{$options{instance}}->{display} = $self->{results}->{$oid_diskIODevice}->{$oid_diskIODevice . '.' . $options{instance}}; if (defined($self->{results}->{$oid_diskIONReadX}->{$oid_diskIONReadX . '.' . $options{instance}}) && $self->{results}->{$oid_diskIONReadX}->{$oid_diskIONReadX . '.' . $options{instance}} != 0) { - $self->{device_id_selected}->{$options{instance}}->{read} = $self->{results}->{$oid_diskIONReadX}->{$oid_diskIONReadX . '.' . $options{instance}}; - $self->{global}->{total_read} += $self->{device_id_selected}->{$options{instance}}->{read}; + $self->{disk}->{$options{instance}}->{read} = $self->{results}->{$oid_diskIONReadX}->{$oid_diskIONReadX . '.' . $options{instance}}; + $self->{global}->{total_read} += $self->{disk}->{$options{instance}}->{read}; } if (defined($self->{results}->{$oid_diskIONWrittenX}->{$oid_diskIONWrittenX . '.' . $options{instance}}) && $self->{results}->{$oid_diskIONWrittenX}->{$oid_diskIONWrittenX . '.' . $options{instance}} != 0) { - $self->{device_id_selected}->{$options{instance}}->{write} = $self->{results}->{$oid_diskIONWrittenX}->{$oid_diskIONWrittenX . '.' . $options{instance}}; - $self->{global}->{total_write} += $self->{device_id_selected}->{$options{instance}}->{write}; + $self->{disk}->{$options{instance}}->{write} = $self->{results}->{$oid_diskIONWrittenX}->{$oid_diskIONWrittenX . '.' . $options{instance}}; + $self->{global}->{total_write} += $self->{disk}->{$options{instance}}->{write}; } if (defined($self->{results}->{$oid_diskIOReads}->{$oid_diskIOReads . '.' . $options{instance}}) && $self->{results}->{$oid_diskIOReads}->{$oid_diskIOReads . '.' . $options{instance}} != 0) { - $self->{device_id_selected}->{$options{instance}}->{read_iops} = $self->{results}->{$oid_diskIOReads}->{$oid_diskIOReads . '.' . $options{instance}}; - $self->{global}->{total_read_iops} += $self->{device_id_selected}->{$options{instance}}->{read_iops}; + $self->{disk}->{$options{instance}}->{read_iops} = $self->{results}->{$oid_diskIOReads}->{$oid_diskIOReads . '.' . $options{instance}}; + $self->{global}->{total_read_iops} += $self->{disk}->{$options{instance}}->{read_iops}; } if (defined($self->{results}->{$oid_diskIOWrites}->{$oid_diskIOWrites . '.' . $options{instance}}) && $self->{results}->{$oid_diskIOWrites}->{$oid_diskIOWrites . '.' . $options{instance}} != 0) { - $self->{device_id_selected}->{$options{instance}}->{write_iops} = $self->{results}->{$oid_diskIOWrites}->{$oid_diskIOWrites . '.' . $options{instance}}; - $self->{global}->{total_write_iops} += $self->{device_id_selected}->{$options{instance}}->{write_iops}; + $self->{disk}->{$options{instance}}->{write_iops} = $self->{results}->{$oid_diskIOWrites}->{$oid_diskIOWrites . '.' . $options{instance}}; + $self->{global}->{total_write_iops} += $self->{disk}->{$options{instance}}->{write_iops}; } if ($self->{global}->{total_read} && $self->{global}->{total_write}) { - $self->{sum_global}->{sum_read_write} = $self->{global}->{total_read} + $self->{global}->{total_write}; + $self->{sum}->{sum_read_write} = $self->{global}->{total_read} + $self->{global}->{total_write}; } if ($self->{global}->{total_read_iops} && $self->{global}->{total_write_iops}) { - $self->{sum_global}->{sum_read_write_iops} = $self->{global}->{total_read_iops} + $self->{global}->{total_write_iops}; + $self->{sum}->{sum_read_write_iops} = $self->{global}->{total_read_iops} + $self->{global}->{total_write_iops}; } } 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->{cache_name} = "snmpstandard_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{device}) ? md5_hex($self->{option_results}->{device}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + $self->{global} = { total_read => 0, total_write => 0, total_read_iops => 0, total_write_iops => 0 }; - $self->{sum_global} = { sum_read_write => 0, sum_read_write_iops => 0 }; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ + $self->{sum} = { sum_read_write => 0, sum_read_write_iops => 0 }; + $self->{results} = $options{snmp}->get_multiple_table(oids => [ { oid => $oid_diskIODevice }, { oid => $oid_diskIOReads }, { oid => $oid_diskIOWrites }, @@ -430,7 +278,7 @@ sub manage_selection { } } - if (scalar(keys %{$self->{device_id_selected}}) <= 0 && !defined($options{disco})) { + if (scalar(keys %{$self->{disk}}) <= 0 && !defined($options{disco})) { if (defined($self->{option_results}->{device})) { $self->{output}->add_option_msg(short_msg => "No device found '" . $self->{option_results}->{device} . "' (or counter values are 0)."); } else { @@ -449,11 +297,8 @@ sub disco_format { sub disco_show { my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->manage_selection(disco => 1); - foreach (sort keys %{$self->{device_id_selected}}) { + $self->manage_selection(disco => 1, %options); + foreach (sort keys %{$self->{disk}}) { $self->{output}->add_disco_entry(name => $self->{results}->{$oid_diskIODevice}->{$oid_diskIODevice . '.' . $_}, deviceid => $_); } diff --git a/snmp_standard/mode/interfaces.pm b/snmp_standard/mode/interfaces.pm index fd06e2512..e681dd0e5 100644 --- a/snmp_standard/mode/interfaces.pm +++ b/snmp_standard/mode/interfaces.pm @@ -668,6 +668,7 @@ sub new { "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' } }); @@ -1053,7 +1054,7 @@ sub load_traffic { if ($self->{get_speed} == 1) { $self->{snmp}->load(oids => [$self->{oid_speed32}], instances => $self->{array_interface_selected}); } - if (!$self->{snmp}->is_snmpv1()) { + if (!$self->{snmp}->is_snmpv1() && !defined($self->{option_results}->{force_counters32})) { $self->{snmp}->load(oids => [$self->{oid_in64}, $self->{oid_out64}], instances => $self->{array_interface_selected}); if ($self->{get_speed} == 1) { $self->{snmp}->load(oids => [$self->{oid_speed64}], instances => $self->{array_interface_selected}); @@ -1076,7 +1077,7 @@ sub load_cast { $self->{snmp}->load(oids => [$self->{oid_ifInUcastPkts}, $self->{oid_ifInBroadcastPkts}, $self->{oid_ifInMulticastPkts}, $self->{oid_ifOutUcastPkts}, $self->{oid_ifOutMulticastPkts}, $self->{oid_ifOutBroadcastPkts}], instances => $self->{array_interface_selected}); - if (!$self->{snmp}->is_snmpv1()) { + if (!$self->{snmp}->is_snmpv1() && !defined($self->{option_results}->{force_counters32})) { $self->{snmp}->load(oids => [$self->{oid_ifHCInUcastPkts}, $self->{oid_ifHCInMulticastPkts}, $self->{oid_ifHCInBroadcastPkts}, $self->{oid_ifHCOutUcastPkts}, $self->{oid_ifHCOutMulticastPkts}, $self->{oid_ifHCOutBroadcastPkts}], instances => $self->{array_interface_selected}); @@ -1155,7 +1156,7 @@ sub add_result_traffic { $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}}; - if (!$self->{snmp}->is_snmpv1()) { + 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; @@ -1204,7 +1205,7 @@ sub add_result_cast { $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; - if (!$self->{snmp}->is_snmpv1()) { + 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; @@ -1315,6 +1316,10 @@ Set interface speed for outgoing traffic (in Mb). 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). diff --git a/snmp_standard/mode/loadaverage.pm b/snmp_standard/mode/loadaverage.pm index bc38684f7..dc26c4bcc 100644 --- a/snmp_standard/mode/loadaverage.pm +++ b/snmp_standard/mode/loadaverage.pm @@ -87,6 +87,9 @@ sub run { my $result = $self->{snmp}->get_leef(oids => [$oid_CpuLoad1m, $oid_CpuLoad5m, $oid_CpuLoad15m], nothing_quit => 1); my ($msg, $cpu_load1, $cpu_load5, $cpu_load15); + $result->{$oid_CpuLoad1m} =~ s/,/\./g; + $result->{$oid_CpuLoad5m} =~ s/,/\./g; + $result->{$oid_CpuLoad15m} =~ s/,/\./g; if (defined($self->{option_results}->{average})) { my $result2 = $self->{snmp}->get_table(oid => $oid_CountCpu); diff --git a/snmp_standard/mode/ntp.pm b/snmp_standard/mode/ntp.pm index 3380ce232..d7708a54c 100644 --- a/snmp_standard/mode/ntp.pm +++ b/snmp_standard/mode/ntp.pm @@ -114,11 +114,13 @@ sub run { $distant_time = $dt->epoch; my $diff = $distant_time - $ref_time; + my $remote_date_formated = sprintf("%02d-%02d-%02dT%02d:%02d:%02d (%s)", $remote_date[0], $remote_date[1], $remote_date[2], + $remote_date[3], $remote_date[4], $remote_date[5], $timezone); my $exit = $self->{perfdata}->threshold_check(value => $diff, - threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Time offset %d second(s)", $diff)); + short_msg => sprintf("Time offset %d second(s) : %s", $diff, $remote_date_formated)); $self->{output}->perfdata_add(label => 'offset', unit => 's', value => sprintf("%d", $diff), diff --git a/snmp_standard/mode/processcount.pm b/snmp_standard/mode/processcount.pm index dd8fc1cb3..e4c8c7d42 100644 --- a/snmp_standard/mode/processcount.pm +++ b/snmp_standard/mode/processcount.pm @@ -157,10 +157,10 @@ sub run { # $options{snmp} = snmp object $self->{snmp} = $options{snmp}; - my $oid2check_filter; + my $oid2check_filter = 'status'; # To have a better order foreach (('name', 'path', 'args', 'status')) { - if (defined($self->{option_results}->{'process_' . $_})) { + if (defined($self->{option_results}->{'process_' . $_}) && $self->{option_results}->{'process_' . $_} ne '') { $oid2check_filter = $_; last; } @@ -175,7 +175,7 @@ sub run { push @{$more_oids}, $oid_hrSWRunPerfCPU; } foreach (keys %$oids) { - if ($_ ne $oid2check_filter && defined($self->{option_results}->{'process_' . $_})) { + if ($_ ne $oid2check_filter && defined($self->{option_results}->{'process_' . $_}) && $self->{option_results}->{'process_' . $_} ne '') { push @{$more_oids}, $oids->{$_}; $mores_filters->{$_} = 1; } diff --git a/storage/netapp/snmp/mode/components/communication.pm b/storage/netapp/snmp/mode/components/communication.pm index c8a9b297b..76d259daa 100644 --- a/storage/netapp/snmp/mode/components/communication.pm +++ b/storage/netapp/snmp/mode/components/communication.pm @@ -37,9 +37,9 @@ my $oid_enclChannelShelfAddr = '.1.3.6.1.4.1.789.1.21.1.2.1.3'; my $oid_enclContactState = '.1.3.6.1.4.1.789.1.21.1.2.1.2'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_enclContactState }; + push @{$self->{request}}, { oid => $oid_enclContactState }; } sub check { @@ -47,13 +47,13 @@ sub check { $self->{output}->output_add(long_msg => "Checking communications"); $self->{components}->{communication} = {name => 'communications', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'communication')); + return if ($self->check_filter(section => 'communication')); for (my $i = 1; $i <= $self->{number_shelf}; $i++) { my $shelf_addr = $self->{shelf_addr}->{$oid_enclChannelShelfAddr . '.' . $i}; my $com_state = $map_com_states{$self->{results}->{$oid_enclContactState}->{$oid_enclContactState . '.' . $i}}; - next if ($self->check_exclude(section => 'communication', instance => $shelf_addr)); + next if ($self->check_filter(section => 'communication', instance => $shelf_addr)); $self->{components}->{communication}->{total}++; $self->{output}->output_add(long_msg => sprintf("Shelve '%s' communication state is '%s'", diff --git a/storage/netapp/snmp/mode/components/electronics.pm b/storage/netapp/snmp/mode/components/electronics.pm index f1e25de26..d34b5046d 100644 --- a/storage/netapp/snmp/mode/components/electronics.pm +++ b/storage/netapp/snmp/mode/components/electronics.pm @@ -30,10 +30,9 @@ my $oid_enclElectronicsPresent = '.1.3.6.1.4.1.789.1.21.1.2.1.31'; my $oid_enclElectronicsFailed = '.1.3.6.1.4.1.789.1.21.1.2.1.33'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_enclElectronicsPresent }; - push @{$options{request}}, { oid => $oid_enclElectronicsFailed }; + push @{$self->{request}}, { oid => $oid_enclElectronicsPresent }, { oid => $oid_enclElectronicsFailed }; } sub check { @@ -41,7 +40,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking electronics"); $self->{components}->{electronics} = {name => 'electronics', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'electronics')); + return if ($self->check_filter(section => 'electronics')); for (my $i = 1; $i <= $self->{number_shelf}; $i++) { my $shelf_addr = $self->{shelf_addr}->{$oid_enclChannelShelfAddr . '.' . $i}; @@ -52,7 +51,7 @@ sub check { $num = centreon::plugins::misc::trim($num); next if ($num !~ /[0-9]/); - next if ($self->check_exclude(section => 'electronics', instance => $shelf_addr . '.' . $num)); + next if ($self->check_filter(section => 'electronics', instance => $shelf_addr . '.' . $num)); $self->{components}->{electronics}->{total}++; my $status = 'ok'; diff --git a/storage/netapp/snmp/mode/components/fan.pm b/storage/netapp/snmp/mode/components/fan.pm index 2f8b5ba9b..3f2e6d3d6 100644 --- a/storage/netapp/snmp/mode/components/fan.pm +++ b/storage/netapp/snmp/mode/components/fan.pm @@ -31,11 +31,10 @@ my $oid_enclFansFailed = '.1.3.6.1.4.1.789.1.21.1.2.1.18'; my $oid_enclFansSpeed = '.1.3.6.1.4.1.789.1.21.1.2.1.62'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_enclFansPresent }; - push @{$options{request}}, { oid => $oid_enclFansFailed }; - push @{$options{request}}, { oid => $oid_enclFansSpeed }; + push @{$self->{request}}, { oid => $oid_enclFansPresent }, { oid => $oid_enclFansFailed }, + { oid => $oid_enclFansSpeed }; } sub check { @@ -43,7 +42,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking fans"); $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fan')); + return if ($self->check_filter(section => 'fan')); for (my $i = 1; $i <= $self->{number_shelf}; $i++) { my $shelf_addr = $self->{shelf_addr}->{$oid_enclChannelShelfAddr . '.' . $i}; @@ -56,7 +55,7 @@ sub check { next if ($num !~ /[0-9]/); my $current_value = (defined($current_speed[$num - 1]) && $current_speed[$num - 1] =~ /(^|\s)([0-9]+)/) ? $2 : ''; - next if ($self->check_exclude(section => 'fan', instance => $shelf_addr . '.' . $num)); + next if ($self->check_filter(section => 'fan', instance => $shelf_addr . '.' . $num)); $self->{components}->{fan}->{total}++; my $status = 'ok'; diff --git a/storage/netapp/snmp/mode/components/psu.pm b/storage/netapp/snmp/mode/components/psu.pm index 5f54b8fe8..6905fbc20 100644 --- a/storage/netapp/snmp/mode/components/psu.pm +++ b/storage/netapp/snmp/mode/components/psu.pm @@ -30,10 +30,9 @@ my $oid_enclPowerSuppliesPresent = '.1.3.6.1.4.1.789.1.21.1.2.1.13'; my $oid_enclPowerSuppliesFailed = '.1.3.6.1.4.1.789.1.21.1.2.1.15'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_enclPowerSuppliesPresent }; - push @{$options{request}}, { oid => $oid_enclPowerSuppliesFailed }; + push @{$self->{request}}, { oid => $oid_enclPowerSuppliesPresent }, { oid => $oid_enclPowerSuppliesFailed }; } sub check { @@ -41,7 +40,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking power supplies"); $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'psu')); + return if ($self->check_filter(section => 'psu')); for (my $i = 1; $i <= $self->{number_shelf}; $i++) { my $shelf_addr = $self->{shelf_addr}->{$oid_enclChannelShelfAddr . '.' . $i}; @@ -52,7 +51,7 @@ sub check { $num = centreon::plugins::misc::trim($num); next if ($num !~ /[0-9]/); - next if ($self->check_exclude(section => 'psu', instance => $shelf_addr . '.' . $num)); + next if ($self->check_filter(section => 'psu', instance => $shelf_addr . '.' . $num)); $self->{components}->{psu}->{total}++; my $status = 'ok'; diff --git a/storage/netapp/snmp/mode/components/raid.pm b/storage/netapp/snmp/mode/components/raid.pm index 74bc1a659..adb9c9530 100644 --- a/storage/netapp/snmp/mode/components/raid.pm +++ b/storage/netapp/snmp/mode/components/raid.pm @@ -38,9 +38,9 @@ my %map_raid_states = ( my $oid_raidPStatus = '.1.3.6.1.4.1.789.1.6.10.1.2'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_raidPStatus }; + push @{$self->{request}}, { oid => $oid_raidPStatus }; } sub check { @@ -48,14 +48,14 @@ sub check { $self->{output}->output_add(long_msg => "Checking raids"); $self->{components}->{raid} = {name => 'raids', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'raid')); + return if ($self->check_filter(section => 'raid')); foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_raidPStatus}})) { $oid =~ /^$oid_raidPStatus\.(.*)$/; my $instance = $1; my $raid_state = $map_raid_states{$self->{results}->{$oid_raidPStatus}->{$oid}}; - next if ($self->check_exclude(section => 'raid', instance => $instance)); + next if ($self->check_filter(section => 'raid', instance => $instance)); $self->{components}->{raid}->{total}++; $self->{output}->output_add(long_msg => sprintf("Raid '%s' state is '%s'", diff --git a/storage/netapp/snmp/mode/components/temperature.pm b/storage/netapp/snmp/mode/components/temperature.pm index ebb6c82f9..48d131bb6 100644 --- a/storage/netapp/snmp/mode/components/temperature.pm +++ b/storage/netapp/snmp/mode/components/temperature.pm @@ -53,9 +53,9 @@ my $oid_enclChannelShelfAddr = '.1.3.6.1.4.1.789.1.21.1.2.1.3'; my $oid_enclEntry = '.1.3.6.1.4.1.789.1.21.1.2.1'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_enclEntry, begin => $mapping->{enclTempSensorsPresent}->{oid}, end => $mapping->{enclTempSensorsUnderTempWarnThr}->{oid} }; + push @{$self->{request}}, { oid => $oid_enclEntry, begin => $mapping->{enclTempSensorsPresent}->{oid}, end => $mapping->{enclTempSensorsUnderTempWarnThr}->{oid} }; } sub check { @@ -63,7 +63,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking temperatures"); $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'temperature')); + return if ($self->check_filter(section => 'temperature')); for (my $i = 1; $i <= $self->{number_shelf}; $i++) { my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_enclEntry}, instance => $i); @@ -77,7 +77,7 @@ sub check { foreach my $num (split /,/, $result->{enclTempSensorsPresent}) { $num = centreon::plugins::misc::trim($num); - next if ($num !~ /[0-9]/); + next if ($num !~ /[0-9]/ || !defined($current_temp[$num - 1])); $warn_under_thr[$num - 1] =~ /(-*[0-9]+)C/; my $wu_thr = $1; @@ -90,7 +90,7 @@ sub check { $current_temp[$num - 1] =~ /(-*[0-9]+)C/; my $current_value = $1; - next if ($self->check_exclude(section => 'temperature', instance => $shelf_addr . '.' . $num)); + next if ($self->check_filter(section => 'temperature', instance => $shelf_addr . '.' . $num)); $self->{components}->{temperature}->{total}++; my $status = 'ok'; diff --git a/storage/netapp/snmp/mode/components/voltage.pm b/storage/netapp/snmp/mode/components/voltage.pm index e5892e6d4..fa6f6cb39 100644 --- a/storage/netapp/snmp/mode/components/voltage.pm +++ b/storage/netapp/snmp/mode/components/voltage.pm @@ -53,9 +53,9 @@ my $oid_enclChannelShelfAddr = '.1.3.6.1.4.1.789.1.21.1.2.1.3'; my $oid_enclTable = '.1.3.6.1.4.1.789.1.21.1.2'; sub load { - my (%options) = @_; + my ($self) = @_; - push @{$options{request}}, { oid => $oid_enclTable, begin => $mapping->{enclVoltSensorsPresent}->{oid}, end => $mapping->{enclVoltSensorsUnderVoltWarnThr}->{oid} }; + push @{$self->{request}}, { oid => $oid_enclTable, begin => $mapping->{enclVoltSensorsPresent}->{oid}, end => $mapping->{enclVoltSensorsUnderVoltWarnThr}->{oid} }; } sub check { @@ -63,7 +63,7 @@ sub check { $self->{output}->output_add(long_msg => "Checking voltages"); $self->{components}->{voltage} = {name => 'voltages', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'voltage')); + return if ($self->check_filter(section => 'voltage')); for (my $i = 1; $i <= $self->{number_shelf}; $i++) { my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_enclTable}, instance => $i); @@ -78,7 +78,7 @@ sub check { my @values = defined($result->{enclVoltSensorsPresent}) ? split /,/, $result->{enclVoltSensorsPresent} : (); foreach my $num (@values) { $num = centreon::plugins::misc::trim($num); - next if ($num !~ /[0-9]/); + next if ($num !~ /[0-9]/ || !defined($current_volt[$num - 1])); my $wu_thr = (defined($warn_under_thr[$num - 1]) && $warn_under_thr[$num - 1] =~ /(^|\s)(-*[0-9]+)/) ? $2 : ''; my $cu_thr = (defined($crit_under_thr[$num - 1]) && $crit_under_thr[$num - 1] =~ /(^|\s)(-*[0-9]+)/) ? $2 : ''; @@ -86,7 +86,7 @@ sub check { my $co_thr = (defined($crit_over_thr[$num - 1]) && $crit_over_thr[$num - 1] =~ /(^|\s)(-*[0-9]+)/) ? $2 : ''; my $current_value = ($current_volt[$num - 1] =~ /(^|\s)(-*[0-9]+)/) ? $2 : ''; - next if ($self->check_exclude(section => 'voltage', instance => $shelf_addr . '.' . $num)); + next if ($self->check_filter(section => 'voltage', instance => $shelf_addr . '.' . $num)); $self->{components}->{voltage}->{total}++; my $status = 'ok'; diff --git a/storage/netapp/snmp/mode/shelf.pm b/storage/netapp/snmp/mode/shelf.pm index 16ea5dee0..e08b0df2b 100644 --- a/storage/netapp/snmp/mode/shelf.pm +++ b/storage/netapp/snmp/mode/shelf.pm @@ -20,61 +20,81 @@ package storage::netapp::snmp::mode::shelf; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -use centreon::plugins::misc; -my $thresholds = { - communication => [ - ['initializing', 'WARNING'], - ['transitioning', 'WARNING'], - ['inactive', 'CRITICAL'], - ['reconfiguring', 'WARNING'], - ['nonexistent', 'CRITICAL'], - ['active', 'OK'], - ], - raid => [ - ['initializing', 'WARNING'], - ['reconstructionInProgress', 'WARNING'], - ['parityVerificationInProgress', 'OK'], - ['scrubbingInProgress', 'OK'], - ['prefailed', 'CRITICAL'], - ['failed', 'CRITICAL'], - ['active', 'OK'], - ], - fan => [ - ['failed', 'CRITICAL'], - ['ok', 'OK'], - ], - psu => [ - ['failed', 'CRITICAL'], - ['ok', 'OK'], - ], - electronics => [ - ['failed', 'CRITICAL'], - ['ok', 'OK'], - ], - voltage => [ - ['under critical threshold', 'CRITICAL'], - ['under warning threshold', 'WARNING'], - ['over critical threshold', 'CRITICAL'], - ['over warning threshold', 'WARNING'], - ['ok', 'OK'], - ], - temperature => [ - ['under critical threshold', 'CRITICAL'], - ['under warning threshold', 'WARNING'], - ['over critical threshold', 'CRITICAL'], - ['over warning threshold', 'WARNING'], - ['ok', 'OK'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_numeric_check_section_option} = '^(voltage|temperature|fan)$'; + + $self->{cb_hook1} = 'init_shelf'; + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + communication => [ + ['initializing', 'WARNING'], + ['transitioning', 'WARNING'], + ['inactive', 'CRITICAL'], + ['reconfiguring', 'WARNING'], + ['nonexistent', 'CRITICAL'], + ['active', 'OK'], + ], + raid => [ + ['initializing', 'WARNING'], + ['reconstructionInProgress', 'WARNING'], + ['parityVerificationInProgress', 'OK'], + ['scrubbingInProgress', 'OK'], + ['prefailed', 'CRITICAL'], + ['failed', 'CRITICAL'], + ['active', 'OK'], + ], + fan => [ + ['failed', 'CRITICAL'], + ['ok', 'OK'], + ], + psu => [ + ['failed', 'CRITICAL'], + ['ok', 'OK'], + ], + electronics => [ + ['failed', 'CRITICAL'], + ['ok', 'OK'], + ], + voltage => [ + ['under critical threshold', 'CRITICAL'], + ['under warning threshold', 'WARNING'], + ['over critical threshold', 'CRITICAL'], + ['over warning threshold', 'WARNING'], + ['ok', 'OK'], + ], + temperature => [ + ['under critical threshold', 'CRITICAL'], + ['under warning threshold', 'WARNING'], + ['over critical threshold', 'CRITICAL'], + ['over warning threshold', 'WARNING'], + ['ok', 'OK'], + ], + }; + + $self->{components_path} = 'storage::netapp::snmp::mode::components'; + $self->{components_module} = ['communication', 'psu', 'fan', 'temperature', 'voltage', 'electronics', 'raid']; +} my $oid_enclNumber = '.1.3.6.1.4.1.789.1.21.1.1'; my $oid_enclChannelShelfAddr = '.1.3.6.1.4.1.789.1.21.1.2.1.3'; +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); + $self->{number_shelf} = defined($self->{results}->{$oid_enclNumber}->{$oid_enclNumber . '.0'}) ? $self->{results}->{$oid_enclNumber}->{$oid_enclNumber . '.0'} : -1; + $self->{shelf_addr} = $self->{results}->{$oid_enclChannelShelfAddr}; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -83,207 +103,15 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "exclude:s" => { name => 'exclude' }, - "component:s" => { name => 'component', default => '.*' }, - "absent-problem:s" => { name => 'absent' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, }); - - $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'; - } - } - - $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->{numeric_threshold} = {}; - foreach my $option (('warning', 'critical')) { - foreach my $val (@{$self->{option_results}->{$option}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $regexp, $value) = ($1, $2, $3); - if ($section !~ /(voltage|temperature|fan)/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "' (type must be: fan, voltage or temperature)."); - $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, regexp => $regexp }; - } - } -} - -sub run { - my ($self, %options) = @_; - # $options{snmp} = snmp object - $self->{snmp} = $options{snmp}; - - my $snmp_request = []; - my @components = ('communication', 'psu', 'fan', 'temperature', 'voltage', 'electronics', 'raid'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "storage::netapp::snmp::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('load'); - $func->(request => $snmp_request); - } - } - - if (scalar(@{$snmp_request}) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - - push @{$snmp_request}, ({ oid => $oid_enclNumber }, { oid => $oid_enclChannelShelfAddr }); - $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); - $self->{number_shelf} = defined($self->{results}->{$oid_enclNumber}->{$oid_enclNumber . '.0'}) ? $self->{results}->{$oid_enclNumber}->{$oid_enclNumber . '.0'} : -1; - $self->{shelf_addr} = $self->{results}->{$oid_enclChannelShelfAddr}; - - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "storage::netapp::snmp::mode::components::$_"; - my $func = $mod_name->can('check'); - $func->($self); - } - } - - 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}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components are ok [%s].", - $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.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub check_exclude { +sub init_shelf { 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; -} - -sub absent_problem { - my ($self, %options) = @_; - - if (defined($self->{option_results}->{absent}) && - $self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Component '%s' instance '%s' is not present", - $options{section}, $options{instance})); - } - - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); - $self->{components}->{$options{section}}->{skip}++; - return 1; -} - -sub get_severity_numeric { - 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} =~ /$_->{regexp}/) { - 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 - - 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; + push @{$self->{request}}, ({ oid => $oid_enclNumber }, { oid => $oid_enclChannelShelfAddr }); } 1; @@ -301,15 +129,15 @@ Check Shelves hardware (temperatures, voltages, electronics, fan, power supplies Which component to check (Default: '.*'). Can be: 'psu', 'fan', 'communication', 'voltage', 'temperature', 'electronics', 'raid'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=psu) -Can also exclude specific instance: --exclude='psu#41239F00647-A#' +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=psu) +Can also exclude specific instance: --filter=psu,41239F00647-A =item B<--absent-problem> Return an error if an entity is not 'present' (default is skipping) (comma seperated list) -Can be specific or global: --absent-problem=fan#41239F00647-fan02# +Can be specific or global: --absent-problem=fan,41239F00647-fan02 =item B<--no-component> @@ -318,19 +146,19 @@ If total (with skipped) is 0. (Default: 'critical' returns). =item B<--threshold-overload> -Set to overload default threshold values (syntax: section,status,regexp) +Set to overload default threshold values (syntax: section,[instance,]status,regexp) It used before default thresholds (order stays). Example: --threshold-overload='gfc,CRITICAL,^(?!(Online)$)' =item B<--warning> -Set warning threshold for temperatures (syntax: regexp,treshold) +Set warning threshold for temperature, fan, voltage (syntax: type,regexp,threshold) Example: --warning='41239F00647-vimm46,20' --warning='41239F00647-vimm5.*,30' =item B<--critical> -Set critical threshold for temperatures (syntax: regexp,treshold) -Example: --critical='41239F00647-vimm46,25' --warning='41239F00647-vimm5.*,35' +Set critical threshold for temperature, fan, voltage (syntax: type,regexp,threshold) +Example: --critical='temperature,.*,25' --warning='temperature,.*,35' =back