diff --git a/apps/centreon/local/mode/metaservice.pm b/apps/centreon/local/mode/metaservice.pm index d67614351..e44290f8a 100644 --- a/apps/centreon/local/mode/metaservice.pm +++ b/apps/centreon/local/mode/metaservice.pm @@ -75,7 +75,7 @@ sub select_by_regexp { my $count = 0; my $stmt = $self->execute_query($self->{centreon_db_centstorage}, - "SELECT metrics.metric_id, metrics.metric_name, metrics.current_value FROM index_data, metrics WHERE index_data.service_description LIKE " . $self->{centreon_db_centstorage}->quote($options{regexp_str}) . " AND index.id = metrics.index_id"); + "SELECT metrics.metric_id, metrics.metric_name, metrics.current_value FROM index_data, metrics WHERE index_data.service_description LIKE " . $self->{centreon_db_centstorage}->quote($options{regexp_str}) . " AND index_data.id = metrics.index_id"); while ((my $row = $stmt->fetchrow_hashref())) { if ($options{metric_select} eq $row->{metric_name}) { $self->{metric_selected}->{$row->{metric_id}} = $row->{current_value}; diff --git a/apps/protocols/bgp/4/mode/bgppeerstate.pm b/apps/protocols/bgp/4/mode/bgppeerstate.pm index 0d10eab70..f38394cca 100644 --- a/apps/protocols/bgp/4/mode/bgppeerstate.pm +++ b/apps/protocols/bgp/4/mode/bgppeerstate.pm @@ -20,11 +20,128 @@ package apps::protocols::bgp::4::mode::bgppeerstate; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + my $msg = "AS:'" . $self->{result_values}->{as} . "' "; + $msg .= " Local: '" . $self->{result_values}->{local} . "'"; + $msg .= " Remote: '" . $self->{result_values}->{remote} . "'"; + $msg .= " Peer State: '" . $self->{result_values}->{peerstate} . "'"; + $msg .= " Admin State : '" . $self->{result_values}->{adminstate} . "'"; + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{adminstate} = $options{new_datas}->{$self->{instance} . '_adminstate'}; + $self->{result_values}->{peerstate} = $options{new_datas}->{$self->{instance} . '_peerstate'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{local} = $options{new_datas}->{$self->{instance} . '_local'}; + $self->{result_values}->{remote} = $options{new_datas}->{$self->{instance} . '_remote'}; + $self->{result_values}->{as} = $options{new_datas}->{$self->{instance} . '_as'}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'peers', type => 1, cb_prefix_output => 'prefix_peers_output', message_multiple => 'All BGP peers are ok' }, + ]; + $self->{maps_counters}->{peers} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'adminstate' }, { name => 'peerstate' }, { name => 'display' }, + { name => 'local' }, { name => 'remote' }, { name => 'as' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'updates', set => { + key_values => [ { name => 'seconds' }, { name => 'display' } ], + output_template => 'Last update : %ss', + perfdatas => [ + { label => 'seconds', value => 'seconds_absolute', template => '%s', + unit => 's', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_peers_output { + my ($self, %options) = @_; + + return "Peer: '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-peer:s" => { name => 'filter_peer' }, + "filter-as:s" => { name => 'filter_as' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + }); + + return $self; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + my %map_peer_state = ( 1 => 'idle', 2 => 'connect', @@ -39,157 +156,52 @@ my %map_admin_state = ( 2 => 'start', ); -my $thresholds = { - peers => [ - ['idle', 'CRITICAL'], - ['active', 'CRITICAL'], - ['connect', 'CRITICAL'], - ['opensent', 'WARNING'], - ['openconfirm', 'WARNING'], - ['established', 'OK'], - ], +my $oid_bgpPeerTable = '.1.3.6.1.2.1.15.3'; + +my $mapping = { + bgpPeerState => { oid => '.1.3.6.1.2.1.15.3.1.2', map => \%map_peer_state }, + bgpPeerAdminStatus => { oid => '.1.3.6.1.2.1.15.3.1.3', map => \%map_admin_state }, + bgpPeerRemoteAs => { oid => '.1.3.6.1.2.1.15.3.1.9' }, + bgpPeerLocalAddr => { oid => '.1.3.6.1.2.1.15.3.1.5' }, + bgpPeerLocalPort => { oid => '.1.3.6.1.2.1.15.3.1.6' }, + bgpPeerRemoteAddr => { oid => '.1.3.6.1.2.1.15.3.1.7' }, + bgpPeerRemotePort => { oid => '.1.3.6.1.2.1.15.3.1.8' }, + bgpPeerInUpdateElpasedTime => { oid => '.1.3.6.1.2.1.15.3.1.24' }, }; -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 => - { - "peer:s" => { name => 'peer', }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - }); - - return $self; -} - -sub check_options { +sub manage_selection { my ($self, %options) = @_; - $self->SUPER::init(%options); - - $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->{peers} = {}; + + my $result = $options{snmp}->get_table(oid => $oid_bgpPeerTable, nothing_quit => 1); + foreach my $oid (keys %{$result}) { + next if ($oid !~ /^$mapping->{bgpPeerState}->{oid}\.(.*)$/); + my $instance = $1; + my $mapped_value = $options{snmp}->map_instance(mapping => $mapping, results => $result, instance => $instance); + + my $local_addr = $mapped_value->{bgpPeerLocalAddr} . ':' . $mapped_value->{bgpPeerLocalPort}; + my $remote_addr = $mapped_value->{bgpPeerRemoteAddr} . ':' . $mapped_value->{bgpPeerRemotePort}; + + if (defined($self->{option_results}->{filter_peer}) && $self->{option_results}->{filter_peer} ne '' && + $instance !~ /$self->{option_results}->{filter_peer}/) { + $self->{output}->output_add(long_msg => "skipping peer '" . $instance . "': no matching filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_as}) && $self->{option_results}->{filter_as} ne '' && + $instance !~ /$self->{option_results}->{filter_as}/) { + $self->{output}->output_add(long_msg => "skipping AS '" . $mapped_value->{bgpPeerRemoteAs} . "': no matching filter.", debug => 1); + next; + } + + $self->{peers}->{$instance} = { adminstate => $mapped_value->{bgpPeerAdminStatus}, local => $local_addr, + peerstate => $mapped_value->{bgpPeerState}, remote => $remote_addr, + seconds => $mapped_value->{bgpPeerInUpdateElpasedTime}, as => $mapped_value->{bgpPeerRemoteAs}, + display => $instance }; + } } -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - my $oid_bgpPeerTable = '.1.3.6.1.2.1.15.3'; - my $oid_bgpPeerState = '.1.3.6.1.2.1.15.3.1.2'; - my $oid_bgpPeerAdminStatus = '.1.3.6.1.2.1.15.3.1.3'; - my $oid_bgpPeerRemoteAs = '.1.3.6.1.2.1.15.3.1.9'; - my $oid_bgpPeerLocalAddr = '.1.3.6.1.2.1.15.3.1.5'; - my $oid_bgpPeerLocalPort = '.1.3.6.1.2.1.15.3.1.6'; - my $oid_bgpPeerRemoteAddr = '.1.3.6.1.2.1.15.3.1.7'; - my $oid_bgpPeerRemotePort = '.1.3.6.1.2.1.15.3.1.8'; - my $oid_bgpPeerInUpdateElpasedTime = '.1.3.6.1.2.1.15.3.1.24'; - - my $result = $self->{snmp}->get_table(oid => $oid_bgpPeerTable, nothing_quit => 1); - - if (defined($self->{option_results}->{peer})) { - my $bgpPeerState = $result->{$oid_bgpPeerState . '.' . $self->{option_results}->{peer}}; - my $bgpPeerAdminStatus = $result->{$oid_bgpPeerAdminStatus . '.' . $self->{option_results}->{peer}}; - my $bgpPeerRemoteAs = $result->{$oid_bgpPeerRemoteAs . '.' . $self->{option_results}->{peer}}; - my $bgpPeerInUpdateElpasedTime = $result->{$oid_bgpPeerInUpdateElpasedTime . '.' . $self->{option_results}->{peer}}; - my $bgpLocalInfos = $result->{$oid_bgpPeerLocalAddr . '.' . $self->{option_results}->{peer}} . ':' . $result->{$oid_bgpPeerLocalPort . '.' . $self->{option_results}->{peer}}; - my $bgpRemoteInfos = $result->{$oid_bgpPeerRemoteAddr. '.' . $self->{option_results}->{peer}} . ':' . $result->{$oid_bgpPeerRemotePort . '.' . $self->{option_results}->{peer}}; - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("Peer %s AdminState=%s Connection=%s [Remote Addr:%s AS:%d] [Last Update %d s]", - $self->{option_results}->{peer}, $map_admin_state{$bgpPeerAdminStatus}, $map_peer_state{$bgpPeerState}, - $bgpRemoteInfos, $bgpPeerRemoteAs, $bgpPeerInUpdateElpasedTime)); - if ($bgpPeerAdminStatus < 2) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Peer '%s' AdminState is '%s' Remote AS: %s Remote Addr: %s", - $self->{option_results}->{peer}, $map_admin_state{$bgpPeerAdminStatus}, $bgpPeerRemoteAs, $bgpRemoteInfos) - ); - } else { - my $exit = $self->get_severity(section => 'peers', value => $map_peer_state{$bgpPeerState}); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Peer %s AdminState=%s Connection=%s [Remote Addr:%s AS:%d] [Last Update %d s]", - $self->{option_results}->{peer}, $map_admin_state{$bgpPeerAdminStatus}, $map_peer_state{$bgpPeerState}, $bgpRemoteInfos, $bgpPeerRemoteAs, $bgpPeerInUpdateElpasedTime)); - } - } - } else { - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All BGP peers are in an OK state")); - - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - next if ($key !~ /^$oid_bgpPeerState\.(.*)$/); - my $instance = $1; - next if ($instance eq '0.0.0.0'); - - my $bgpPeerState = $result->{$oid_bgpPeerState . '.' . $instance}; - my $bgpPeerAdminStatus = $result->{$oid_bgpPeerAdminStatus . '.' . $instance}; - my $bgpPeerRemoteAs = $result->{$oid_bgpPeerRemoteAs . '.' . $instance}; - my $bgpPeerInUpdateElpasedTime = $result->{$oid_bgpPeerInUpdateElpasedTime . '.' . $instance}; - my $bgpLocalInfos = $result->{$oid_bgpPeerLocalAddr . '.' . $instance} . ':' . $result->{$oid_bgpPeerLocalPort . '.' . $instance}; - my $bgpRemoteInfos = $result->{$oid_bgpPeerRemoteAddr. '.' . $instance} . ':' . $result->{$oid_bgpPeerRemotePort . '.' . $instance}; - - if ($bgpPeerAdminStatus < 2) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Peer '%s' AdminState is '%s' Remote AS: %s Remote Addr: %s", - $instance, $map_admin_state{$bgpPeerAdminStatus}, $bgpPeerRemoteAs, - $bgpRemoteInfos)); - } else { - my $exit = $self->get_severity(section => 'peers', value => $map_peer_state{$bgpPeerState}); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Peer %s AdminState=%s Connection=%s [Remote Addr:%s AS:%d] [Last Update %d s]", - $instance, $map_admin_state{$bgpPeerAdminStatus}, $map_peer_state{$bgpPeerState}, $bgpRemoteInfos, $bgpPeerRemoteAs, $bgpPeerInUpdateElpasedTime)); - } - } - - $self->{output}->output_add(long_msg => sprintf("Peer:%s Local:%s Remote:%s AS:%d AdminState:'%s' Connection:'%s' Last Update:%d sec", - $instance, $bgpLocalInfos, $bgpRemoteInfos, $bgpPeerRemoteAs, $map_admin_state{$bgpPeerAdminStatus}, $map_peer_state{$bgpPeerState}, $bgpPeerInUpdateElpasedTime)); - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub get_severity { - my ($self, %options) = @_; - my $status = 'UNKNOWN'; # default - - if (defined($self->{overload_th}->{$options{section}})) { - foreach (@{$self->{overload_th}->{$options{section}}}) { - if ($options{value} =~ /$_->{filter}/i) { - $status = $_->{status}; - return $status; - } - } - } - foreach (@{$thresholds->{$options{section}}}) { - if ($options{value} =~ /$$_[0]/i) { - $status = $$_[1]; - return $status; - } - } - - return $status; -} - -1; +1; __END__ @@ -197,23 +209,33 @@ __END__ Check BGP basic infos (BGP4-MIB.mib and rfc4273) -Default is Active,Connect,Idle=CRITICAL // Opensent,Openconfirm=WARNING // Established=OK - =over 8 -=item B<--peer> +=item B<--filter-as> -Specify IP of a specific peer (otherwise all peer are checked +Filter based on AS number (regexp allowed) -=item B<--threshold-overload> +=item B<--filter-peer> -Set to overload default threshold values (syntax: section,status,regexp) -It used before default thresholds (order stays). -Example: --threshold-overload='peers,CRITICAL,^(?!(ok)$)' +Filter based on IP of peers (regexp allowed) +=item B<--warning-updates> + +Warning threshold on last update (seconds) + +=item B<--critical-updates> + +Critical threshold on last update (seconds) + +=item B<--warning-status> + +Specify admin and peer state that trigger a warning. Can use %{adminstate} and %{peerstate} +e.g --warning-status "%{adminstate} =~ /stop" + +=item B<--critical-status> + +Specify admin and peer state that trigger a critical. Can use %{adminstate} and %{peerstate} =back =cut - - diff --git a/centreon/common/cisco/standard/snmp/mode/qosusage.pm b/centreon/common/cisco/standard/snmp/mode/qosusage.pm new file mode 100644 index 000000000..92e8be43d --- /dev/null +++ b/centreon/common/cisco/standard/snmp/mode/qosusage.pm @@ -0,0 +1,436 @@ +# +# Copyright 2016 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES 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::qosusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'total', type => 0 }, + { name => 'interface_classmap', type => 1, cb_prefix_output => 'prefix_intcmap_output', message_multiple => 'All interface classmaps are ok' }, + { name => 'classmap', type => 1, cb_prefix_output => 'prefix_cmap_output', message_multiple => 'All classmaps are ok' }, + ]; + + $self->{maps_counters}->{interface_classmap} = [ + { label => 'int-cmap-traffic', set => { + key_values => [ { name => 'display' }, { name => 'traffic_usage', diff => 1 }, { name => 'total' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_traffic_calc'), + closure_custom_output => $self->can('custom_traffic_output'), + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }, + { label => 'int-cmap-drop', set => { + key_values => [ { name => 'drop_usage', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Drop : %s %s/s', + perfdatas => [ + { label => 'icmap_drop', value => 'drop_usage_per_second', template => '%d', + unit => 'b/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; + $self->{maps_counters}->{classmap} = [ + { label => 'cmap-traffic', set => { + key_values => [ { name => 'traffic_usage', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic : %s %s/s', + perfdatas => [ + { label => 'cmap_traffic', value => 'traffic_usage_per_second', template => '%d', + unit => 'b/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'cmap-drop', set => { + key_values => [ { name => 'drop_usage', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Drop : %s %s/s', + perfdatas => [ + { label => 'cmap_drop', value => 'drop_usage_per_second', template => '%d', + unit => 'b/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; + $self->{maps_counters}->{total} = [ + { label => 'total-traffic', set => { + key_values => [ { name => 'traffic_usage', diff => 1 } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Total Traffic : %s %s/s', + perfdatas => [ + { label => 'total_traffic', value => 'traffic_usage_per_second', template => '%d', + unit => 'b/s', min => 0 }, + ], + } + }, + { label => 'total-drop', set => { + key_values => [ { name => 'drop_usage', diff => 1 } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Total Drop : %s %s/s', + perfdatas => [ + { label => 'total_drop', value => 'drop_usage_per_second', template => '%d', + unit => 'b/s', min => 0 }, + ], + } + }, + ]; +} + +sub custom_traffic_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { + $extra_label .= '_' . $self->{result_values}->{display}; + } + + my ($warning, $critical); + if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{total})) { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1); + } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}); + } + + $self->{output}->perfdata_add(label => 'icmap_traffic' . $extra_label, unit => 'b/s', + value => sprintf("%.2f", $self->{result_values}->{traffic_per_seconds}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_traffic_threshold { + my ($self, %options) = @_; + + my $exit = 'ok'; + if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{total})) { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_per_seconds}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + } + return $exit; +} + +sub custom_traffic_output { + my ($self, %options) = @_; + + my ($traffic_value, $traffic_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{traffic_per_seconds}, network => 1); + my $msg = sprintf("Traffic : %s/s (%s)", + $traffic_value . $traffic_unit, + defined($self->{result_values}->{traffic_prct}) ? sprintf("%.2f%%", $self->{result_values}->{traffic_prct}) : '-'); + return $msg; +} + +sub custom_traffic_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{traffic_usage} = $options{new_datas}->{$self->{instance} . '_traffic_usage'}; + + my $diff_traffic = ($options{new_datas}->{$self->{instance} . '_traffic_usage'} - $options{old_datas}->{$self->{instance} . '_traffic_usage'}); + $self->{result_values}->{traffic_per_seconds} = $diff_traffic / $options{delta_time}; + if ($options{new_datas}->{$self->{instance} . '_total'} =~ /[1-9]/) { + $self->{result_values}->{traffic_prct} = $self->{result_values}->{traffic_per_seconds} * 100 / $options{new_datas}->{$self->{instance} . '_total'}; + } + + return 0; +} + +sub prefix_intcmap_output { + my ($self, %options) = @_; + + return "Interface classmap '" . $options{instance_value}->{display} . "' "; +} + +sub prefix_cmap_output { + my ($self, %options) = @_; + + return "Classmap '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-source:s" => { name => 'filter_source' }, + "oid-filter:s" => { name => 'oid_filter', default => 'ifname' }, + "oid-display:s" => { name => 'oid_display', default => 'ifname' }, + "units-traffic:s" => { name => 'units_traffic', default => '%' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->{oids_label} = { + 'ifdesc' => '.1.3.6.1.2.1.2.2.1.2', + 'ifalias' => '.1.3.6.1.2.1.31.1.1.1.18', + 'ifname' => '.1.3.6.1.2.1.31.1.1.1.1', + }; + $self->check_oids_label(); + $instance_mode = $self; +} + +sub check_oids_label { + my ($self, %options) = @_; + + foreach (('oid_filter', 'oid_display')) { + $self->{option_results}->{$_} = lc($self->{option_results}->{$_}) if (defined($self->{option_results}->{$_})); + if (!defined($self->{oids_label}->{$self->{option_results}->{$_}})) { + my $label = $_; + $label =~ s/_/-/g; + $self->{output}->add_option_msg(short_msg => "Unsupported oid in --" . $label . " option."); + $self->{output}->option_exit(); + } + } +} + +my $mapping = { + cbQosCMPrePolicyByteOverflow => { oid => '.1.3.6.1.4.1.9.9.166.1.15.1.1.4' }, + cbQosCMPrePolicyByte => { oid => '.1.3.6.1.4.1.9.9.166.1.15.1.1.5' }, + cbQosCMPrePolicyByte64 => { oid => '.1.3.6.1.4.1.9.9.166.1.15.1.1.6' }, + cbQosCMPostPolicyByteOverflow => { oid => '.1.3.6.1.4.1.9.9.166.1.15.1.1.8' }, + cbQosCMPostPolicyByte => { oid => '.1.3.6.1.4.1.9.9.166.1.15.1.1.9' }, + cbQosCMPostPolicyByte64 => { oid => '.1.3.6.1.4.1.9.9.166.1.15.1.1.10' }, + cbQosCMDropByteOverflow => { oid => '.1.3.6.1.4.1.9.9.166.1.15.1.1.15' }, + cbQosCMDropByte => { oid => '.1.3.6.1.4.1.9.9.166.1.15.1.1.16' }, + cbQosCMDropByte64 => { oid => '.1.3.6.1.4.1.9.9.166.1.15.1.1.17' }, +}; +my $mapping2 = { + cbQosTSCfgRate => { oid => '.1.3.6.1.4.1.9.9.166.1.13.1.1.1' }, # bps + cbQosTSCfgRate64 => { oid => '.1.3.6.1.4.1.9.9.166.1.13.1.1.11' }, # bps +}; + +my $oid_cbQosIfIndex = '.1.3.6.1.4.1.9.9.166.1.1.1.1.4'; +my $oid_cbQosConfigIndex = '.1.3.6.1.4.1.9.9.166.1.5.1.1.2'; +my $oid_cbQosParentObjectsIndex = '.1.3.6.1.4.1.9.9.166.1.5.1.1.4'; +# Classmap information +my $oid_cbQosCMName = '.1.3.6.1.4.1.9.9.166.1.7.1.1.1'; +my $oid_cbQosCMStatsEntry = '.1.3.6.1.4.1.9.9.166.1.15.1.1'; +# Can be linked to a classmap also +my $oid_cbQosPolicyMapName = '.1.3.6.1.4.1.9.9.166.1.6.1.1.1'; +# Shaping : Linked to a classmap +my $oid_cbQosTSCfgEntry = '.1.3.6.1.4.1.9.9.166.1.13.1.1'; +# Linked to a classmap +my $oid_cbQosQueueingCfgBandwidth = '.1.3.6.1.4.1.9.9.166.1.9.1.1.1'; +my $oid_cbQosQueueingCfgBandwidthUnits = '.1.3.6.1.4.1.9.9.166.1.9.1.1.2'; + +sub build_qos_information { + my ($self, %options) = @_; + + my $qos_data = { complete_name => $options{class_name} }; + # Need to try and find the queueing (it's a child) + $qos_data->{queueing} = $options{link_queueing}->{$options{policy_index} . '.' . $options{object_index}} + if (defined($options{link_queueing}->{$options{policy_index} . '.' . $options{object_index}})); + $qos_data->{shaping} = $options{link_shaping}->{$options{policy_index} . '.' . $options{object_index}} + if (!defined($qos_data->{shaping}) && defined($options{link_shaping}->{$options{policy_index} . '.' . $options{object_index}})); + + while (($options{object_index} = $self->{results}->{$oid_cbQosParentObjectsIndex}->{$oid_cbQosParentObjectsIndex . '.' . $options{policy_index} . '.' . $options{object_index}}) != 0) { + my $config_index = $self->{results}->{$oid_cbQosConfigIndex}->{$oid_cbQosConfigIndex . '.' . $options{policy_index} . '.' . $options{object_index}}; + + my $tmp_name = ''; + # try to find policy_map or class_map + if (defined($self->{results}->{$oid_cbQosCMName}->{$oid_cbQosCMName . '.' . $config_index})) { + $tmp_name = $self->{results}->{$oid_cbQosCMName}->{$oid_cbQosCMName . '.' . $config_index}; + } elsif (defined($self->{results}->{$oid_cbQosPolicyMapName}->{$oid_cbQosPolicyMapName . '.' . $config_index})) { + $tmp_name = $self->{results}->{$oid_cbQosPolicyMapName}->{$oid_cbQosPolicyMapName . '.' . $config_index}; + } + + $qos_data->{shaping} = $options{link_shaping}->{$options{policy_index} . '.' . $options{object_index}} + if (!defined($qos_data->{shaping}) && defined($options{link_shaping}->{$options{policy_index} . '.' . $options{object_index}})); + + $qos_data->{complete_name} = $tmp_name . ':' . $qos_data->{complete_name}; + } + + return $qos_data; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{interface_classmap} = {}; + $self->{classmap} = {}; + $self->{total} = { drop_usage => 0, total_usage => 0 }; + + my $request_oids = [ + { oid => $self->{oids_label}->{$self->{option_results}->{oid_filter}} }, + { oid => $oid_cbQosPolicyMapName }, + { oid => $oid_cbQosIfIndex }, + { oid => $oid_cbQosConfigIndex }, + { oid => $oid_cbQosCMName }, + { oid => $oid_cbQosQueueingCfgBandwidth }, + { oid => $oid_cbQosQueueingCfgBandwidthUnits }, + { oid => $oid_cbQosCMStatsEntry }, + { oid => $oid_cbQosParentObjectsIndex }, + { oid => $oid_cbQosTSCfgEntry }, + ]; + push @$request_oids, { oid => $self->{oids_label}->{$self->{option_results}->{oid_display}} } + if ($self->{option_results}->{oid_filter} ne $self->{option_results}->{oid_display}); + $self->{results} = $options{snmp}->get_multiple_table(oids => $request_oids); + + my %classmap_name = (); + foreach (keys %{$self->{results}->{$oid_cbQosConfigIndex}}) { + if (defined($self->{results}->{$oid_cbQosCMName}->{$oid_cbQosCMName . '.' . $self->{results}->{$oid_cbQosConfigIndex}->{$_}})) { + /(\d+\.\d+)$/; + $classmap_name{$1} = $self->{results}->{$oid_cbQosCMName}->{$oid_cbQosCMName . '.' . $self->{results}->{$oid_cbQosConfigIndex}->{$_}}; + } + } + my ($link_queueing, $link_shaping) = ({}, {}); + foreach (keys %{$self->{results}->{$oid_cbQosParentObjectsIndex}}) { + /(\d+)\.(\d+)$/; + my $config_index = $self->{results}->{$oid_cbQosConfigIndex}->{$oid_cbQosConfigIndex . '.' . $1 . '.' . $2}; + if (defined($self->{results}->{$oid_cbQosQueueingCfgBandwidth}->{$oid_cbQosQueueingCfgBandwidth . '.' . $config_index})) { + $link_queueing->{$1 . '.' . $self->{results}->{$oid_cbQosParentObjectsIndex}->{$_}} = $config_index; + } elsif (defined($self->{results}->{$oid_cbQosTSCfgEntry}->{$mapping2->{cbQosTSCfgRate}->{oid} . '.' . $config_index})) { + $link_shaping->{$1 . '.' . $self->{results}->{$oid_cbQosParentObjectsIndex}->{$_}} = $config_index; + } + } + + foreach (keys %{$self->{results}->{$oid_cbQosCMStatsEntry}}) { + next if (!/$mapping->{cbQosCMPrePolicyByte}->{oid}\.(\d+)\.(\d+)/); + + my ($policy_index, $qos_object_index) = ($1, $2); + + my $class_name = $classmap_name{$policy_index . '.' . $qos_object_index}; + my $if_index = $self->{results}->{$oid_cbQosIfIndex}->{$oid_cbQosIfIndex . '.' . $policy_index}; + if (!defined($self->{results}->{$self->{oids_label}->{$self->{option_results}->{oid_display}}}->{$self->{oids_label}->{$self->{option_results}->{oid_display}} . '.' . $if_index})) { + $self->{output}->output_add(long_msg => "skipping interface index '" . $if_index . "': no display name.", debug => 1); + next; + } + my $interface_display = $self->{results}->{$self->{oids_label}->{$self->{option_results}->{oid_display}}}->{$self->{oids_label}->{$self->{option_results}->{oid_display}} . '.' . $if_index}; + + if (!defined($self->{results}->{$self->{oids_label}->{$self->{option_results}->{oid_filter}}}->{$self->{oids_label}->{$self->{option_results}->{oid_filter}} . '.' . $if_index})) { + $self->{output}->output_add(long_msg => "skipping interface index '" . $if_index . "': no filter name.", debug => 1); + next; + } + + my $qos_data = $self->build_qos_information(class_name => $class_name, policy_index => $policy_index, object_index => $qos_object_index, + link_queueing => $link_queueing, link_shaping => $link_shaping); + + my $interface_filter = $self->{results}->{$self->{oids_label}->{$self->{option_results}->{oid_filter}}}->{$self->{oids_label}->{$self->{option_results}->{oid_filter}} . '.' . $if_index}; + my $name = $interface_filter . ':' . $qos_data->{complete_name}; + + if (defined($self->{option_results}->{filter_source}) && $self->{option_results}->{filter_source} ne '' && + $name !~ /$self->{option_results}->{filter_source}/) { + $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter source.", debug => 1); + next; + } + + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_cbQosCMStatsEntry}, instance => $policy_index . '.' . $qos_object_index); + my $traffic_usage = (defined($result->{cbQosCMPostPolicyByte64}) && $result->{cbQosCMPostPolicyByte64} =~ /[1-9]/) ? + $result->{cbQosCMPostPolicyByte64} : (($result->{cbQosCMPostPolicyByteOverflow} << 32) + $result->{cbQosCMPostPolicyByte}); + my $drop_usage = (defined($result->{cbQosCMDropByte64}) && $result->{cbQosCMDropByte64} =~ /[1-9]/) ? + $result->{cbQosCMDropByte64} : (($result->{cbQosCMDropByteOverflow} << 32) + $result->{cbQosCMDropByte}); + my $total = 'unknown'; + if (defined($qos_data->{shaping})) { + my $result_shaping = $options{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$oid_cbQosTSCfgEntry}, instance => $qos_data->{shaping}); + $total = defined($result_shaping->{cbQosTSCfgRate64}) ? $result_shaping->{cbQosTSCfgRate64} : $result_shaping->{cbQosTSCfgRate}; + } + + $self->{interface_classmap}->{$policy_index . '.' . $qos_object_index} = { + display => $name, + traffic_usage => $traffic_usage * 8, drop_usage => $drop_usage * 8, total => $total + }; + $self->{classmap}->{$class_name} = { display => $class_name, drop_usage => 0, traffic_usage => 0} if (!defined($self->{classmap}->{$class_name})); + $self->{classmap}->{$class_name}->{traffic_usage} += $traffic_usage * 8; + $self->{classmap}->{$class_name}->{drop_usage} += $drop_usage * 8; + + $self->{total}->{traffic_usage} += $traffic_usage * 8; + $self->{total}->{drop_usage} += $drop_usage * 8; + } + + $self->{cache_name} = "cisco_qos_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_source}) ? md5_hex($self->{option_results}->{filter_source}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + if (scalar(keys %{$self->{interface_classmap}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "Cannot found classmap."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check QoS. + +=over 8 + +=item B<--filter-source> + +Filter interface name and class-map (can be a regexp). +Example of a source (interfacename:servicepolicy:classmap:...): FastEthernet1:Visioconference + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^(total-traffic)$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'int-cmap-traffic', 'int-cmap-drop', +'cmap-traffic', 'cmap-drop', 'total-traffic', 'total-drop'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'int-cmap-traffic', 'int-cmap-drop', +'cmap-traffic', 'cmap-drop', 'total-traffic', 'total-drop'. + +=item B<--units-traffic> + +Units of thresholds for the traffic (Default: '%') ('%', 'b/s'). +Only for --warning-int-traffic and --critical-int-traffic options. + +=item B<--oid-filter> + +Choose OID used to filter interface (default: ifName) (values: ifDesc, ifAlias, ifName). + +=item B<--oid-display> + +Choose OID used to display interface (default: ifName) (values: ifDesc, ifAlias, ifName). + +=back + +=cut diff --git a/hardware/pdu/emerson/snmp/mode/psusage.pm b/hardware/pdu/emerson/snmp/mode/psusage.pm index 3e581086d..5fe252145 100644 --- a/hardware/pdu/emerson/snmp/mode/psusage.pm +++ b/hardware/pdu/emerson/snmp/mode/psusage.pm @@ -31,12 +31,13 @@ sub set_counters { $self->{maps_counters_type} = [ { name => 'ps', type => 1, cb_prefix_output => 'prefix_ps_output', message_multiple => 'All power sources are ok' }, + { name => 'line', type => 1, cb_prefix_output => 'prefix_line_output', message_multiple => 'All power source lines are ok' }, ]; $self->{maps_counters}->{ps} = [ { label => 'power', set => { key_values => [ { name => 'PwrTotal' }, { name => 'display' } ], - output_template => 'total input power : %s W', output_error_template => "total input power : %s", + output_template => 'Total input power : %s W', output_error_template => "total input power : %s", perfdatas => [ { label => 'power', value => 'PwrTotal_absolute', template => '%s', unit => 'W', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, @@ -62,6 +63,26 @@ sub set_counters { } }, ]; + $self->{maps_counters}->{line} = [ + { label => 'line-load', set => { + key_values => [ { name => 'load' }, { name => 'display' } ], + output_template => 'Load : %.2f %%', output_error_template => "Load : %s", + perfdatas => [ + { label => 'line_load', value => 'load_absolute', template => '%.2f', + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'line-current', set => { + key_values => [ { name => 'current' }, { name => 'display' } ], + output_template => 'Current : %.2f A', output_error_template => "Current : %s", + perfdatas => [ + { label => 'line_current', value => 'current_absolute', template => '%.2f', + unit => 'A', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; } sub prefix_ps_output { @@ -70,6 +91,12 @@ sub prefix_ps_output { return "Power source '" . $options{instance_value}->{display} . "' "; } +sub prefix_line_output { + my ($self, %options) = @_; + + return "Power source line '" . $options{instance_value}->{display} . "' "; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); @@ -84,14 +111,22 @@ sub new { return $self; } +my %map_phase = (1 => 'phase1', 2 => 'phase2', 3 => 'phase3'); + my $mapping = { lgpPduPsEntrySysAssignLabel => { oid => '.1.3.6.1.4.1.476.1.42.3.8.30.20.1.15' }, lgpPduPsEntryEnergyAccum => { oid => '.1.3.6.1.4.1.476.1.42.3.8.30.20.1.50' }, # 0.1 Kilowatt-Hour lgpPduPsEntryPwrTotal => { oid => '.1.3.6.1.4.1.476.1.42.3.8.30.20.1.65' }, # Watt lgpPduPsEntryEcNeutral => { oid => '.1.3.6.1.4.1.476.1.42.3.8.30.20.1.70' }, # 0.1 Amp-AC-RMS }; +my $mapping2 = { + lgpPduPsLineEntryLine => { oid => '.1.3.6.1.4.1.476.1.42.3.8.30.40.1.15', map => \%map_phase }, + lgpPduPsLineEntryEcHundredths => { oid => '.1.3.6.1.4.1.476.1.42.3.8.30.40.1.22' }, # 0.01 A + lgpPduPsLineEntryEcUsedBeforeAlarm => { oid => '.1.3.6.1.4.1.476.1.42.3.8.30.40.1.39' }, # % +}; my $oid_lgpPduEntryUsrLabel = '.1.3.6.1.4.1.476.1.42.3.8.20.1.10'; my $oid_lgpPduPsEntry = '.1.3.6.1.4.1.476.1.42.3.8.30.20.1'; +my $oid_lgpPduPsLineEntry = '.1.3.6.1.4.1.476.1.42.3.8.30.40.1'; sub manage_selection { my ($self, %options) = @_; @@ -103,6 +138,7 @@ sub manage_selection { $self->{ps} = {}; $self->{results} = $options{snmp}->get_multiple_table(oids => [ { oid => $oid_lgpPduEntryUsrLabel }, { oid => $oid_lgpPduPsEntry }, + { oid => $oid_lgpPduPsLineEntry } ], nothing_quit => 1); foreach my $oid (keys %{$self->{results}->{$oid_lgpPduPsEntry}}) { @@ -127,6 +163,20 @@ sub manage_selection { EcNeutral => $result->{lgpPduPsEntryEcNeutral} * 0.1}; } + $self->{line} = {}; + foreach my $oid (keys %{$self->{results}->{$oid_lgpPduPsLineEntry}}) { + next if ($oid !~ /^$mapping2->{lgpPduPsLineEntryEcUsedBeforeAlarm}->{oid}\.(\d+)\.(\d+)\.(\d+)/); + my ($pdu_index, $ps_index, $line_index) = ($1, $2, $3); + my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$oid_lgpPduPsLineEntry}, instance => $pdu_index . '.' . $ps_index . '.' . $line_index); + next if (!defined($self->{ps}->{$pdu_index . '.' . $ps_index})); + + $self->{line}->{$pdu_index . '.' . $ps_index . '.' . $line_index} = { + display => $self->{ps}->{$pdu_index . '.' . $ps_index}->{display} . '/' . $result->{lgpPduPsLineEntryLine}, + current => $result->{lgpPduPsLineEntryEcHundredths} * 0.01, + load => $result->{lgpPduPsLineEntryEcUsedBeforeAlarm}, + }; + } + if (scalar(keys %{$self->{ps}}) <= 0) { $self->{output}->add_option_msg(short_msg => "Cannot found power sources."); $self->{output}->option_exit(); @@ -155,12 +205,14 @@ Example: --filter-counters='^(power|energy)$' =item B<--warning-*> Threshold warning. -Can be: 'power', 'energy', 'current-neutral'. +Can be: 'power', 'energy', 'current-neutral', +'line-load', 'line-current'. =item B<--critical-*> Threshold critical. -Can be: 'power', 'energy', 'current-neutral'. +Can be: 'power', 'energy', 'current-neutral', +'line-load', 'line-current'. =back diff --git a/network/checkpoint/mode/hastate.pm b/network/checkpoint/mode/hastate.pm index 61fa3f2cd..862e30651 100644 --- a/network/checkpoint/mode/hastate.pm +++ b/network/checkpoint/mode/hastate.pm @@ -20,70 +20,131 @@ package network::checkpoint::mode::hastate; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + my $msg = "HA State: '" . $self->{result_values}->{hastate} . "' "; + $msg .= "Role: '" . $self->{result_values}->{role} . "' "; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + $self->{result_values}->{hastate} = $options{new_datas}->{$self->{instance} . '_hastate'}; + $self->{result_values}->{role} = $options{new_datas}->{$self->{instance} . '_role'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'high_availability', type => 0 }, + ]; + $self->{maps_counters}->{high_availability} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'hastate' }, { name => 'role' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{hastate} !~ /(UP|working)/' }, + "no-ha-status:s" => { name => 'no_ha_status', default => 'UNKNOWN' }, + }); + + return $self; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach ('warning_status', 'critical_status') { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + my %map_status = ( 0 => 'Member is UP and working', 1 => 'Problem preventing role switching', 2 => 'HA is down', ); -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; - - $self->{version} = '1.0'; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); -} - -sub run { +sub manage_selection { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - + my $oid_haInstalled = '.1.3.6.1.4.1.2620.1.5.2.0'; my $oid_haState = '.1.3.6.1.4.1.2620.1.5.6.0'; my $oid_haStatCode = '.1.3.6.1.4.1.2620.1.5.101.0'; my $oid_haStarted = '.1.3.6.1.4.1.2620.1.5.5.0'; - - my $result = $self->{snmp}->get_leef(oids => [$oid_haInstalled, $oid_haState, $oid_haStatCode, $oid_haStarted], nothing_quit => 1); - + + $self->{high_availability} = {}; + + my $result = $options{snmp}->get_leef(oids => [$oid_haInstalled, $oid_haState, $oid_haStatCode, $oid_haStarted], + nothing_quit => 1); + if ($result->{$oid_haInstalled} < 1 or $result->{$oid_haStarted} eq "no") { - $self->{output}->output_add(severity => 'UNKNOWN', + $self->{output}->output_add(severity => $self->{option_results}->{no_ha_state}, short_msg => sprintf("Looks like HA is not started, or not installed .."), - long_msg => sprintf("HA Installed : '%u' HA Started : '%s'", $result->{$oid_haInstalled}, $result->{$oid_haStarted}), + long_msg => sprintf("HA Installed : '%u' HA Started : '%s'", + $result->{$oid_haInstalled}, $result->{$oid_haStarted}), ); $self->{output}->display(); $self->{output}->exit(); } - - my $status = $result->{$oid_haStatCode}; - - if ($status < 1 ) { - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("'%s'. State : '%s'", $map_status{$status}, $result->{$oid_haState}), - ); - } elsif ($status == 1) { - $self->{output}->output_add(severity => 'WARNING', - short_msg => sprintf("'%s'. State : '%s'", $map_status{$status}, $result->{$oid_haState}), - ); - - } else { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("'%s'. State : '%s'", $map_status{$status}, $result->{$oid_haState}), - ); - } - - $self->{output}->display(); - $self->{output}->exit(); + $self->{high_availability} = { hastate => $map_status{$result->{$oid_haStatCode}}, + role => $result->{$oid_haState} }; } 1; @@ -94,7 +155,20 @@ __END__ Check HA State of a Checkpoint node (chkpnt.mib). +=item B<--warning-status> + +Trigger warning on %{role} or %{hastate} values +e.g --warning-status '%{role} !~ /master/' will warn when failover occurs + +=item B<--critical-status> + +Trigger critical on %{role} or %{hastate} values +(default: '%{hastate} !~ /(UP|working)/') + +=item B<--no-ha-status> + +Status to return when HA not running or not installed (default: 'UNKNOWN') + =back =cut - diff --git a/network/cisco/standard/snmp/plugin.pm b/network/cisco/standard/snmp/plugin.pm index 558abceaa..a4d1950ae 100644 --- a/network/cisco/standard/snmp/plugin.pm +++ b/network/cisco/standard/snmp/plugin.pm @@ -39,6 +39,7 @@ sub new { 'list-interfaces' => 'snmp_standard::mode::listinterfaces', 'memory' => 'centreon::common::cisco::standard::snmp::mode::memory', 'memory-flash' => 'centreon::common::cisco::standard::snmp::mode::memoryflash', + 'qos-usage' => 'centreon::common::cisco::standard::snmp::mode::qosusage', 'spanning-tree' => 'snmp_standard::mode::spanningtree', 'stack' => 'centreon::common::cisco::standard::snmp::mode::stack', ); diff --git a/storage/emc/symmetrix/dmx34/local/mode/components/disk.pm b/storage/emc/symmetrix/dmx34/local/mode/components/disk.pm index 01f7e9c54..5a3161007 100644 --- a/storage/emc/symmetrix/dmx34/local/mode/components/disk.pm +++ b/storage/emc/symmetrix/dmx34/local/mode/components/disk.pm @@ -93,22 +93,23 @@ sub check { $self->{output}->output_add(long_msg => sprintf("all devices are ready")); } - return if ($content !~ /(\S+) hot spares are configured, (\S+) are invoked/msi); - my ($total, $used) = ($1, $2); + return if ($content !~ /(\S+) hot spares are configured,\s*(\S+)\s+are invoked,\s*(\S+)\s+are not ready/msi); + my ($total, $used, $not_ready) = ($1, $2, $3); $used = 0 if ($used =~ /none/i); + $not_ready = 0 if ($not_ready =~ /none/i); - my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'disk', instance => '1', value => $total - $used); + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'disk', instance => '1', value => $total - $used - $not_ready); $self->{output}->output_add(long_msg => sprintf("'%s' spare disk availables on '%s'", - $total - $used, $total)); + $total - $used - $not_ready, $total)); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("'%s' spare disk availables on '%s'", - $total - $used, $total)); + $total - $used - $not_ready, $total)); } $self->{output}->perfdata_add(label => "disk_spare_available", - value => $total - $used, + value => $total - $used - $not_ready, warning => $warn, critical => $crit, min => 0, max => $total); }