diff --git a/network/f5/bigip/mode/nodestatus.pm b/network/f5/bigip/mode/nodestatus.pm index 587740560..3b4ccfa88 100644 --- a/network/f5/bigip/mode/nodestatus.pm +++ b/network/f5/bigip/mode/nodestatus.pm @@ -1,5 +1,5 @@ ################################################################################ -# Copyright 2005-2013 MERETHIS +# Copyright 2005-2014 MERETHIS # Centreon is developped by : Julien Mathis and Romain Le Merlus under # GPL Licence 2.0. # @@ -39,30 +39,47 @@ use base qw(centreon::plugins::mode); use strict; use warnings; - -my $oid_ltmNodeAddrStatusName = '.1.3.6.1.4.1.3375.2.2.4.3.2.1.7'; -my $oid_ltmNodeAddrStatusAvailState = '.1.3.6.1.4.1.3375.2.2.4.3.2.1.3'; -my $oid_ltmNodeAddrStatusDetailReason = '.1.3.6.1.4.1.3375.2.2.4.3.2.1.6'; +use centreon::plugins::values; my $thresholds = { node => [ ['none', 'CRITICAL'], ['green', 'OK'], ['yellow', 'WARNING'], - ['critical', 'CRITICAL'], + ['red', 'CRITICAL'], ['blue', 'UNKNOWN'], ['gray', 'UNKNOWN'], ], }; +my $instance_mode; -my %map_node_status = ( - 0 => 'none', - 1 => 'green', - 2 => 'yellow', - 3 => 'red', - 4 => 'blue', # unknown - 5 => 'gray', -); +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) = @_; + + return $instance_mode->get_severity(section => 'node', value => $self->{result_values}->{AvailState}); +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{AvailState} = $options{new_datas}->{$self->{instance} . '_AvailState'}; + return 0; +} sub new { my ($class, %options) = @_; @@ -71,29 +88,50 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, + { + "filter-name:s" => { name => 'filter_name' }, "threshold-overload:s@" => { name => 'threshold_overload' }, }); - $self->{node_id_selected} = []; - + + 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; } 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} = {}; foreach my $val (@{$self->{option_results}->{threshold_overload}}) { - if ($val !~ /^(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong treshold-overload option '" . $val . "'."); + if ($val !~ /^(.*?),(.*?),(.*)$/) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); $self->{output}->option_exit(); } - my ($section, $status, $filter) = ('node', $1, $2); + 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}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); $self->{output}->option_exit(); } $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); @@ -101,70 +139,62 @@ sub check_options { } } -sub manage_selection { - my ($self, %options) = @_; - - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_ltmNodeAddrStatusName}})) { - next if ($oid !~ /^$oid_ltmNodeAddrStatusName\.(.*)$/); - my $instance = $1; - - # Get all without a name - if (!defined($self->{option_results}->{name})) { - push @{$self->{node_id_selected}}, $instance; - next; - } - - $self->{results}->{$oid_ltmNodeAddrStatusName}->{$oid} = $self->{results}->{$oid_ltmNodeAddrStatusName}->{$oid}; - if (!defined($self->{option_results}->{use_regexp}) && $self->{results}->{$oid_ltmNodeAddrStatusName}->{$oid} eq $self->{option_results}->{name}) { - push @{$self->{node_id_selected}}, $instance; - } - if (defined($self->{option_results}->{use_regexp}) && $self->{results}->{$oid_ltmNodeAddrStatusName}->{$oid} =~ /$self->{option_results}->{name}/) { - push @{$self->{node_id_selected}}, $instance; - } - } - - if (scalar(@{$self->{node_id_selected}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No node found for name '" . $self->{option_results}->{name} . "'."); - $self->{output}->option_exit(); - } -} - sub run { my ($self, %options) = @_; # $options{snmp} = snmp object $self->{snmp} = $options{snmp}; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_ltmNodeAddrStatusName }, - { oid => $oid_ltmNodeAddrStatusAvailState }, - { oid => $oid_ltmNodeAddrStatusDetailReason }, - ], - nothing_quit => 1); $self->manage_selection(); my $multiple = 1; - if (scalar(@{$self->{node_id_selected}}) == 1) { + if (scalar(keys %{$self->{node}}) == 1) { $multiple = 0; } + if ($multiple == 1) { $self->{output}->output_add(severity => 'OK', - short_msg => 'All Nodes are ok.'); + short_msg => 'All Nodes are ok'); } - foreach my $instance (sort @{$self->{node_id_selected}}) { - my $name = $self->{results}->{$oid_ltmNodeAddrStatusName}->{$oid_ltmNodeAddrStatusName . '.' . $instance}; - my $status = defined($self->{results}->{$oid_ltmNodeAddrStatusAvailState}->{$oid_ltmNodeAddrStatusAvailState . '.' . $instance}) ? - $self->{results}->{$oid_ltmNodeAddrStatusAvailState}->{$oid_ltmNodeAddrStatusAvailState . '.' . $instance} : 4; - my $reason = defined($self->{results}->{$oid_ltmNodeAddrStatusDetailReason}->{$oid_ltmNodeAddrStatusDetailReason . '.' . $instance}) ? - $self->{results}->{$oid_ltmNodeAddrStatusDetailReason}->{$oid_ltmNodeAddrStatusDetailReason . '.' . $instance} : 'unknown'; + 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); - $self->{output}->output_add(long_msg => sprintf("Node '%s' status is %s [reason = %s]", - $name, $map_node_status{$status}, $reason)); - my $exit = $self->get_severity(section => 'node', value => $map_node_status{$status}); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || $multiple == 0) { + my ($value_check) = $obj->execute(values => $self->{N}->{$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"); + 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 => sprintf("Node '%s' status is %s", - $name, $map_node_status{$status})); + 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"); } } @@ -194,6 +224,78 @@ sub get_severity { return $status; } +my %map_node_status = ( + 0 => 'none', + 1 => 'green', + 2 => 'yellow', + 3 => 'red', + 4 => 'blue', # unknown + 5 => 'gray', +); +my %map_node_enabled = ( + 0 => 'none', + 1 => 'enabled', + 2 => 'disabled', + 3 => 'disabledbyparent', +); + +# New OIDS +my $mapping = { + new => { + AvailState => { oid => '.1.3.6.1.4.1.3375.2.2.4.3.2.1.3', map => \%map_node_status }, + EnabledState => { oid => '.1.3.6.1.4.1.3375.2.2.4.3.2.1.4', map => \%map_node_enabled }, + StatusReason => { oid => '.1.3.6.1.4.1.3375.2.2.4.3.2.1.6' }, + Name => { oid => '.1.3.6.1.4.1.3375.2.2.4.3.2.1.7' }, + }, + old => { + AvailState => { oid => '.1.3.6.1.4.1.3375.2.2.4.1.2.1.13', map => \%map_node_status }, + EnabledState => { oid => '.1.3.6.1.4.1.3375.2.2.4.1.2.1.14', map => \%map_node_enabled }, + StatusReason => { oid => '.1.3.6.1.4.1.3375.2.2.4.1.2.1.16' }, + Name => { oid => '.1.3.6.1.4.1.3375.2.2.4.1.2.1.17' }, + }, +}; +my $oid_ltmNodeAddrStatusEntry = '.1.3.6.1.4.1.3375.2.2.4.3.2.1'; # new +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 => [ + { oid => $oid_ltmNodeAddrEntry, start => $mapping->{old}->{AvailState}->{oid} }, + { oid => $oid_ltmNodeAddrStatusEntry, start => $mapping->{new}->{AvailState}->{oid} }, + ], + , nothing_quit => 1); + + my ($branch, $map) = ($oid_ltmNodeAddrStatusEntry, 'new'); + if (!defined($self->{results}->{$oid_ltmNodeAddrStatusEntry})) { + ($branch, $map) = ($oid_ltmNodeAddrEntry, 'old'); + } + + $self->{node} = {}; + foreach my $oid (keys %{$self->{results}->{$branch}}) { + next if ($oid !~ /^$mapping->{$map}->{Name}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping->{$map}, results => $self->{results}->{$branch}, instance => $instance); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{Name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $result->{Name} . "': no matching filter id."); + next; + } + if ($result->{EnabledState} !~ /enabled/) { + $self->{output}->output_add(long_msg => "Skipping '" . $result->{Name} . "': state is '$result->{EnabledState}'."); + next; + } + + $self->{node}->{$instance} = { %$result }; + } + + if (scalar(keys %{$self->{node}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No entry found."); + $self->{output}->option_exit(); + } +} + 1; __END__ @@ -204,21 +306,16 @@ Check Nodes status. =over 8 -=item B<--name> +=item B<--filter-name> -Set the node name. - -=item B<--regexp> - -Allows to use regexp to filter node name (with option --name). +Filter by name (regexp can be used). =item B<--threshold-overload> -Set to overload default threshold values (syntax: status,regexp) +Set to overload default threshold values (syntax: section,status,regexp) It used before default thresholds (order stays). -Example: --threshold-overload='CRITICAL,^(?!(green)$)' +Example: --threshold-overload='node,CRITICAL,^(?!(green)$)' =back =cut - \ No newline at end of file diff --git a/network/f5/bigip/mode/poolstatus.pm b/network/f5/bigip/mode/poolstatus.pm index 96fbabd91..190e65e7d 100644 --- a/network/f5/bigip/mode/poolstatus.pm +++ b/network/f5/bigip/mode/poolstatus.pm @@ -49,7 +49,7 @@ my $thresholds = { ['none', 'CRITICAL'], ['green', 'OK'], ['yellow', 'WARNING'], - ['critical', 'CRITICAL'], + ['red', 'CRITICAL'], ['blue', 'UNKNOWN'], ['gray', 'UNKNOWN'], ], diff --git a/network/f5/bigip/mode/virtualserverstatus.pm b/network/f5/bigip/mode/virtualserverstatus.pm index e880904f8..3ee9e1bac 100644 --- a/network/f5/bigip/mode/virtualserverstatus.pm +++ b/network/f5/bigip/mode/virtualserverstatus.pm @@ -49,7 +49,7 @@ my $thresholds = { ['none', 'CRITICAL'], ['green', 'OK'], ['yellow', 'WARNING'], - ['critical', 'CRITICAL'], + ['red', 'CRITICAL'], ['blue', 'UNKNOWN'], ['gray', 'UNKNOWN'], ],