diff --git a/centreon-plugins/apps/jenkins/mode/jobstate.pm b/centreon-plugins/apps/jenkins/mode/jobstate.pm index 88fbaab76..3db09d98c 100644 --- a/centreon-plugins/apps/jenkins/mode/jobstate.pm +++ b/centreon-plugins/apps/jenkins/mode/jobstate.pm @@ -157,6 +157,10 @@ Specify https if needed (Default: 'http') Set path to get Jenkins information +=item B <--credentials> + +Required to use username/password authentication method + =item B<--username> Specify username for API authentification diff --git a/centreon-plugins/centreon/common/emc/navisphere/mode/disk.pm b/centreon-plugins/centreon/common/emc/navisphere/mode/disk.pm index d5c7b1fcf..676b9f4bd 100644 --- a/centreon-plugins/centreon/common/emc/navisphere/mode/disk.pm +++ b/centreon-plugins/centreon/common/emc/navisphere/mode/disk.pm @@ -20,133 +20,14 @@ package centreon::common::emc::navisphere::mode::disk; -sub get_absolute { - my ($self, %options) = @_; - my $name = $options{instance} . '_' . $options{label}; - my $value; - - $self->{new_datas}->{$name} = $1; - - $self->{old_datas}->{$name} = $self->{statefile_value}->get(name => $name); - return undef if (!defined($self->{old_datas}->{$name})); - - # Reward... put to 0 - if ($self->{old_datas}->{$name} > $self->{new_datas}->{$name}) { - $self->{old_datas}->{$name} = 0; - } - - $value = ($self->{new_datas}->{$name} - $self->{old_datas}->{$name}); - - return ($value, $value); -} - -sub get_bytes_per_seconds { - my ($self, %options) = @_; - my $name = $options{instance} . '_' . $options{label}; - my $value; - - $self->{new_datas}->{$name} = $1; - if (!defined($self->{old_datas}->{last_timestamp})) { - $self->{old_datas}->{last_timestamp} = $self->{statefile_value}->get(name => 'last_timestamp'); - } - $self->{old_datas}->{$name} = $self->{statefile_value}->get(name => $name); - return undef if (!defined($self->{old_datas}->{last_timestamp}) || !defined($self->{old_datas}->{$name})); - - # Reward... put to 0 - if ($self->{old_datas}->{$name} > $self->{new_datas}->{$name}) { - $self->{old_datas}->{$name} = 0; - } - # At least one second - my $delta_time = $self->{new_datas}->{last_timestamp} - $self->{old_datas}->{last_timestamp}; - if ($delta_time <= 0) { - $delta_time = 1; - } - - $value = ($self->{new_datas}->{$name} - $self->{old_datas}->{$name}) / $delta_time; - my ($scale_value, $scale_unit) = $self->{perfdata}->change_bytes(value => $value); - - return ($value, $scale_value . ' ' . $scale_unit); -} - -sub get_utils { - my ($self, %options) = @_; - my $name = $options{instance} . '_' . $options{label}; - my $value; - - $self->{new_datas}->{$name . '_busy'} = $1; - $self->{new_datas}->{$name . '_idle'} = $2; - - $self->{old_datas}->{$name . '_busy'} = $self->{statefile_value}->get(name => $name . '_busy'); - $self->{old_datas}->{$name . '_idle'} = $self->{statefile_value}->get(name => $name . '_idle'); - return undef if (!defined($self->{old_datas}->{$name . '_busy'}) || !defined($self->{old_datas}->{$name . '_idle'})); - - # Reward... put to 0 - if ($self->{old_datas}->{$name . '_busy'} > $self->{new_datas}->{$name . '_busy'}) { - $self->{old_datas}->{$name . '_busy'} = 0; - } - if ($self->{old_datas}->{$name . '_idle'} > $self->{new_datas}->{$name . '_idle'}) { - $self->{old_datas}->{$name . '_idle'} = 0; - } - - my $total_ticks = ($self->{new_datas}->{$name . '_idle'} - $self->{old_datas}->{$name . '_idle'}) + - ($self->{new_datas}->{$name . '_busy'} - $self->{old_datas}->{$name . '_busy'}); - if ($total_ticks <= 0) { - return (0, 0); - } - $value = ($self->{new_datas}->{$name . '_busy'} - $self->{old_datas}->{$name . '_busy'}) * 100 / $total_ticks; - - return ($value, $value); -} - -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::statefile; use centreon::plugins::misc; +use Digest::MD5 qw(md5_hex); -my $maps_counters = { - hard_read_errors => { thresholds => { - warning_hard_read_errors => { label => 'warning-hard-read-errors', exit_value => 'warning' }, - critical_hard_read_errors => { label => 'critical-hard-read-errors', exit_value => 'critical' }, - }, - matching => 'Hard Read Errors:\s+(\d+)', closure => \&get_absolute, - output_msg => 'Hard Read Errors : %d', perfdata => '%s', - unit => '', - }, - hard_write_errors => { thresholds => { - warning_hard_write_errors => { label => 'warning-hard-write-errors', exit_value => 'warning' }, - critical_hard_write_errors => { label => 'critical-hard-write-errors', exit_value => 'critical' }, - }, - matching => 'Hard Write Errors:\s+(\d+)', closure => \&get_absolute, - output_msg => 'Hard Write Errors : %d', perfdata => '%s', - unit => '', - }, - write_io => { thresholds => { - warning_write_io => { label => 'warning-write-io', exit_value => 'warning' }, - critical_write_io => { label => 'critical-write-io', exit_value => 'critical' }, - }, - matching => 'Kbytes Written:\s+(\d+)', closure => \&get_bytes_per_seconds, - output_msg => 'Write I/O : %s', perfdata => '%d', - unit => 'B', - }, - read_io => { thresholds => { - warning_read_io => { label => 'warning-read-io', exit_value => 'warning' }, - critical_read_io => { label => 'critical-read-io', exit_value => 'critical' }, - }, - matching => 'Kbytes Read:\s+(\d+)', closure => \&get_bytes_per_seconds, - output_msg => 'Read I/O : %s', perfdata => '%d', - unit => 'B', - }, - utils => { thresholds => { - warning_utils => { label => 'warning-utils', exit_value => 'warning' }, - critical_utils => { label => 'critical-utils', exit_value => 'critical' }, - }, - matching => 'Busy Ticks:\s+(\d+).*Idle Ticks:\s+(\d+)', closure => \&get_utils, - output_msg => 'Utils : %.2f %%', perfdata => '%.2f', - unit => '%', - }, -}; +my $instance_mode; my @states = ( ['^enabled$' , 'OK'], @@ -168,92 +49,147 @@ my @states = ( ['^.*$' , 'CRITICAL'], ); +sub custom_threshold_check { + my ($self, %options) = @_; + + foreach (@states) { + if ($self->{result_values}->{state} =~ /$_->[0]/i) { + return $_->[1]; + } + } + + return 'ok'; +} + +sub custom_state_output { + my ($self, %options) = @_; + + my $msg = sprintf("state is '%s'", $self->{result_values}->{state}); + return $msg; +} + +sub custom_state_calc { + my ($self, %options) = @_; + + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_utils_calc { + my ($self, %options) = @_; + + my $diff_busy = $options{new_datas}->{$self->{instance} . '_busy_ticks'} - $options{old_datas}->{$self->{instance} . '_busy_ticks'}; + my $diff_idle = $options{new_datas}->{$self->{instance} . '_idle_ticks'} - $options{old_datas}->{$self->{instance} . '_idle_ticks'}; + + $self->{result_values}->{utils} = $diff_busy * 100 / ($diff_busy + $diff_idle); + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + 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 disks are OK', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{disk} = [ + { label => 'state', threshold => 0, set => { + key_values => [ { name => 'state' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_state_calc'), + closure_custom_output => $self->can('custom_state_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_threshold_check'), + } + }, + { label => 'hard-read-errors', set => { + key_values => [ { name => 'hard_read_errors', diff => 1 }, { name => 'display' } ], + output_template => 'Hard Read Errors : %d', + perfdatas => [ + { label => 'hard_read_errors', value => 'hard_read_errors_absolute', template => '%d', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'hard-write-errors', set => { + key_values => [ { name => 'hard_write_errors', diff => 1 }, { name => 'display' } ], + output_template => 'Hard Write Errors : %d', + perfdatas => [ + { label => 'hard_write_errors', value => 'hard_write_errors_absolute', template => '%d', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'read-io', set => { + key_values => [ { name => 'read_io', diff => 1 }, { name => 'display' } ], + output_template => 'Read I/O : %s %s/s', + per_second => 1, output_change_bytes => 1, + perfdatas => [ + { label => 'read_io', value => 'read_io_absolute', template => '%s', + min => 0, unit => 'B/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-io', set => { + key_values => [ { name => 'write_io', diff => 1 }, { name => 'display' } ], + output_template => 'Write I/O : %s %s/s', + per_second => 1, output_change_bytes => 1, + perfdatas => [ + { label => 'write_io', value => 'write_io_absolute', template => '%s', + min => 0, unit => 'B/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'utils', set => { + key_values => [ { name => 'busy_ticks', diff => 1 }, { name => 'idle_ticks', diff => 1 }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_utils_calc'), + output_template => 'Utils : %.2f %%', output_use => 'utils', + perfdatas => [ + { label => 'utils', value => 'utils', template => '%.2f', + min => 0, max => 100, unit => '%%', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + ]; +} + +sub prefix_disk_output { + my ($self, %options) = @_; + + return "Disk '" . $options{instance_value}->{display} . "' "; +} + sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "threshold-overload:s@" => { name => 'threshold_overload' }, "filter-raidgroupid:s" => { name => 'filter_raidgroupid', }, "filter-disk:s" => { name => 'filter_disk', }, }); - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - $options{options}->add_options(arguments => { - $maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name }, - }); - } - } - - $self->{statefile_value} = centreon::plugins::statefile->new(%options); return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'."); - $self->{output}->option_exit(); - } - } - } + $self->SUPER::check_options(%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 ($filter, $threshold) = ($1, $2); - if ($self->{output}->is_litteral_status(status => $threshold) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); - $self->{output}->option_exit(); - } - $self->{overload_th}->{$filter} = $threshold; - } - - $self->{statefile_value}->check_options(%options); + $instance_mode = $self; } -sub get_severity { +sub manage_selection { my ($self, %options) = @_; - my $status = 'unknown'; - foreach my $entry (@states) { - if ($options{value} =~ /${$entry}[0]/i) { - $status = ${$entry}[1]; - foreach my $filter (keys %{$self->{overload_th}}) { - if (${$entry}[0] =~ /$filter/i) { - $status = $self->{overload_th}->{$filter}; - last; - } - } - last; - } - } - - return $status; -} - -sub run { - my ($self, %options) = @_; - my $clariion = $options{custom}; - - my $response = $clariion->execute_command(cmd => 'getdisk -state -bytrd -bytwrt -hw -hr -busyticks -idleticks -rg'); - - my ($total_num_disks, $skip_num_disks) = (0, 0); - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "cache_clariion_" . $clariion->{hostname} . '_' . $self->{mode}); - $self->{new_datas}->{last_timestamp} = time(); + $self->{disk} = {}; + $self->{cache_name} = "cache_clariion_" . $options{custom}->{hostname} . '_' . $options{custom}->{mode} . '_' . + (defined($self->{option_results}->{filter_disk}) ? md5_hex($self->{option_results}->{filter_disk}) : md5_hex('all')); + + my $response = $options{custom}->execute_command(cmd => 'getdisk -state -bytrd -bytwrt -hw -hr -busyticks -idleticks -rg'); #Bus 1 Enclosure 7 Disk 13 #State: Enabled @@ -274,77 +210,31 @@ sub run { # First Filters if (defined($self->{option_results}->{filter_disk}) && $self->{option_results}->{filter_disk} ne '' && $disk_instance !~ /$self->{option_results}->{filter_disk}/) { - $skip_num_disks++; - $self->{output}->output_add(long_msg => "Skipping disk '" . $disk_instance . "': no matching filter disk"); + $self->{output}->output_add(long_msg => "skipping disk '" . $disk_instance . "': no matching filter disk", debug => 1); next; } if (defined($self->{option_results}->{filter_raidgroupid}) && $self->{option_results}->{filter_raidgroupid} ne '' && $values =~ /^Raid Group ID:\s+(\S+)/mi && $1 !~ /$self->{option_results}->{filter_raidgroupid}/) { - $skip_num_disks++; - $self->{output}->output_add(long_msg => "Skipping disk '" . $disk_instance . "': no matching filter raid group id"); + $self->{output}->output_add(long_msg => "skipping disk '" . $disk_instance . "': no matching filter raid group id", debug => 1); next; } - $total_num_disks++; - $values =~ /^State:\s+(.*?)(\n|$)/msi; - - my $state = centreon::plugins::misc::trim($1); - my $exit = $self->get_severity(value => $state); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Disk '%s' state is %s", - $disk_instance, $state)); - # Don't check values if in critical/warning - next; + my $datas = {}; + while ($values =~ /^([^\n]*?):(.*?)\n/msgi) { + $datas->{centreon::plugins::misc::trim(lc($1))} = centreon::plugins::misc::trim($2); } - # Work on values. No check if in 'Hot Spare Ready' or 'Unbound' - next if ($state =~ /^(Hot Spare Ready|Unbound)$/i); - - my ($short_msg, $long_msg) = ('', ''); - my @exits; - foreach (keys %{$maps_counters}) { - next if ($values !~ /$maps_counters->{$_}->{matching}/msi); - my ($value_check, $value_output) = &{$maps_counters->{$_}->{closure}}($self, - instance => $disk_instance, label => $_); - next if (!defined($value_check)); - my ($warning, $critical); - - foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) { - my $exit2 = $self->{perfdata}->threshold_check(value => $value_check, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]); - $long_msg .= ' ' . sprintf($maps_counters->{$_}->{output_msg}, $value_output); - if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { - $short_msg .= ' ' . sprintf($maps_counters->{$_}->{output_msg}, $value_output); - } - push @exits, $exit2; - - $warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning'); - $critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical'); - } - - $self->{output}->perfdata_add(label => $_ . '_' . $disk_instance, unit => $maps_counters->{$_}->{unit}, - value => sprintf($maps_counters->{$_}->{perfdata}, $value_check), - warning => $warning, - critical => $critical, - min => 0); - } - - $self->{output}->output_add(long_msg => "Disk '$disk_instance':$long_msg"); - $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 '$disk_instance':$short_msg" - ); - } + $self->{disk}->{$disk_instance} = { + display => $disk_instance, + state => $datas->{state}, + hard_read_errors => $datas->{'hard read errors'}, + hard_write_errors => $datas->{'hard write errors'}, + read_io => defined($datas->{'kbytes read'}) ? $datas->{'kbytes read'} * 1024 : undef, + write_io => defined($datas->{'kbytes write'}) ? $datas->{'kbytes write'} * 1024 : undef, + busy_ticks => $datas->{'busy ticks'}, + idle_ticks => $datas->{'idle ticks'}, + }; } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s disks are ok.", - $total_num_disks . '/' . $skip_num_disks) - ); - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); } 1; @@ -367,11 +257,6 @@ Can be: 'read-errors', 'write-errors', 'read-io', 'write-io', 'utils'. Threshold critical. Can be: 'read-errors', 'write-errors', 'read-io', 'write-io', 'utils'. -=item B<--threshold-overload> - -Set to overload default threshold value. -Example: --threshold-overload='(enabled)=critical' - =item B<--filter-disk> Filter Disk (regexp can be used). diff --git a/centreon-plugins/centreon/common/fastpath/mode/components/fan.pm b/centreon-plugins/centreon/common/fastpath/mode/components/fan.pm new file mode 100644 index 000000000..0309c741f --- /dev/null +++ b/centreon-plugins/centreon/common/fastpath/mode/components/fan.pm @@ -0,0 +1,90 @@ +# +# 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::fastpath::mode::components::fan; + +use strict; +use warnings; + +my %map_fan_status = ( + 1 => 'notpresent', + 2 => 'operational', + 3 => 'failed', + 4 => 'powering', + 5 => 'nopower', + 6 => 'notpowering', + 7 => 'incompatible', +); + +my $mapping = { + boxServicesFanItemState => { oid => '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.6.1.3', map => \%map_fan_status }, + boxServicesFanSpeed => { oid => '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.6.1.4' }, +}; +my $oid_boxServicesFansEntry = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.6.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_boxServicesFansEntry, begin => $mapping->{boxServicesFanItemState}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fans"); + $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; + return if ($self->check_filter(section => 'fan')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesFansEntry}})) { + next if ($oid !~ /^$mapping->{boxServicesFanItemState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_boxServicesFansEntry}, instance => $instance); + + next if ($self->check_filter(section => 'fan', instance => $instance)); + if ($result->{boxServicesFanItemState} =~ /notPresent/i) { + $self->absent_problem(section => 'fan', instance => $instance); + next; + } + + $self->{components}->{fan}->{total}++; + $self->{output}->output_add(long_msg => sprintf("fan '%s' status is '%s' [instance = %s, speed = %s]", + $instance, $result->{boxServicesFanItemState}, $instance, defined($result->{boxServicesFanSpeed}) ? $result->{boxServicesFanSpeed} : 'unknown')); + $exit = $self->get_severity(label => 'default', section => 'fan', value => $result->{boxServicesFanItemState}); + 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->{boxServicesFanItemState})); + next; + } + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $result->{boxServicesFanSpeed}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Fan '%s' is '%s' rpm", $instance, $result->{boxServicesFanSpeed})); + } + $self->{output}->perfdata_add(label => 'fan_' . $instance, unit => 'rpm', + value => $result->{boxServicesFanSpeed}, + warning => $warn, + critical => $crit, min => 0 + ); + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/centreon/common/fastpath/mode/components/psu.pm b/centreon-plugins/centreon/common/fastpath/mode/components/psu.pm new file mode 100644 index 000000000..5b3a7f1d1 --- /dev/null +++ b/centreon-plugins/centreon/common/fastpath/mode/components/psu.pm @@ -0,0 +1,78 @@ +# +# 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::fastpath::mode::components::psu; + +use strict; +use warnings; + +my %map_status = ( + 1 => 'notpresent', + 2 => 'operational', + 3 => 'failed', + 4 => 'powering', + 5 => 'nopower', + 6 => 'notpowering', + 7 => 'incompatible', +); + +my $mapping = { + boxServicesPowSupplyItemState => { oid => '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.7.1.3', map => \%map_status }, +}; +my $oid_boxServicesPowSuppliesEntry = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.7.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_boxServicesPowSuppliesEntry, begin => $mapping->{boxServicesPowSupplyItemState}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; + return if ($self->check_filter(section => 'psu')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesPowSuppliesEntry}})) { + next if ($oid !~ /^$mapping->{boxServicesPowSupplyItemState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_boxServicesPowSuppliesEntry}, instance => $instance); + + next if ($self->check_filter(section => 'psu', instance => $instance)); + if ($result->{boxServicesPowSupplyItemState} =~ /notPresent/i) { + $self->absent_problem(section => 'psu', instance => $instance); + next; + } + + $self->{components}->{psu}->{total}++; + $self->{output}->output_add(long_msg => sprintf("power supply '%s' status is '%s' [instance = %s]", + $instance, $result->{boxServicesPowSupplyItemState}, $instance)); + $exit = $self->get_severity(label => 'default', section => 'psu', value => $result->{boxServicesPowSupplyItemState}); + 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->{boxServicesPowSupplyItemState})); + next; + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/centreon/common/fastpath/mode/components/temperature.pm b/centreon-plugins/centreon/common/fastpath/mode/components/temperature.pm new file mode 100644 index 000000000..10c5b98ab --- /dev/null +++ b/centreon-plugins/centreon/common/fastpath/mode/components/temperature.pm @@ -0,0 +1,99 @@ +# +# 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::fastpath::mode::components::temperature; + +use strict; +use warnings; + +my %map_temp_status = ( + 0 => 'low', + 1 => 'normal', + 2 => 'warning', + 3 => 'critical', + 4 => 'shutdown', + 5 => 'notpresent', + 6 => 'notoperational', +); + +my $mapping1 = { + boxServicesTempSensorState => { oid => '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1.3', map => \%map_temp_status }, + boxServicesTempSensorTemperature => { oid => '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1.4' }, +}; +my $mapping2 = { + boxServicesTempSensorState => { oid => '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1.4', map => \%map_temp_status }, + boxServicesTempSensorTemperature => { oid => '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1.5' }, +}; +my $oid_boxServicesTempSensorsEntry = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_boxServicesTempSensorsEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking temperatures"); + $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; + return if ($self->check_filter(section => 'temperature')); + + my ($result, $exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesTempSensorsEntry}})) { + next if ($oid !~ /^$mapping2->{boxServicesTempSensorState}->{oid}\.(.*)$/); + my $instance = $1; + + if (defined($self->{results}->{$oid_boxServicesTempSensorsEntry}->{$mapping2->{boxServicesTempSensorTemperature}->{oid} . '.' . $instance})) { + $result = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$oid_boxServicesTempSensorsEntry}, instance => $instance); + } else { + $result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$oid_boxServicesTempSensorsEntry}, instance => $instance); + } + + next if ($self->check_filter(section => 'temperature', instance => $instance)); + if ($result->{boxServicesTempSensorState} =~ /notPresent/i) { + $self->absent_problem(section => 'temperature', instance => $instance); + next; + } + + $self->{components}->{temperature}->{total}++; + $self->{output}->output_add(long_msg => sprintf("temperature '%s' status is '%s' [instance = %s, temperature = %s]", + $instance, $result->{boxServicesTempSensorState}, $instance, defined($result->{boxServicesTempSensorTemperature}) ? $result->{boxServicesTempSensorTemperature} : 'unknown')); + $exit = $self->get_severity(section => 'temperature', value => $result->{boxServicesTempSensorState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' status is '%s'", $instance, $result->{boxServicesTempSensorState})); + next; + } + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{boxServicesTempSensorTemperature}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' is '%s' C", $instance, $result->{boxServicesTempSensorTemperature})); + } + $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', + value => $result->{boxServicesTempSensorTemperature}, + warning => $warn, + critical => $crit, min => 0 + ); + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/centreon/common/fastpath/mode/environment.pm b/centreon-plugins/centreon/common/fastpath/mode/environment.pm index d0d25fd97..9c84c05e3 100644 --- a/centreon-plugins/centreon/common/fastpath/mode/environment.pm +++ b/centreon-plugins/centreon/common/fastpath/mode/environment.pm @@ -20,50 +20,50 @@ package centreon::common::fastpath::mode::environment; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -my $oid_boxServicesFansEntry = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.6.1'; -my $oid_boxServicesFanItemState = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.6.1.3'; -my $oid_boxServicesFanSpeed = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.6.1.4'; -my $oid_boxServicesPowSuppliesEntry = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.7.1'; -my $oid_boxServicesPowSupplyItemState = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.7.1.3'; -my $oid_boxServicesTempSensorsEntry = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1'; -my $oid_boxServicesTempSensorTemperature1 = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1.4'; # oid for 6200 series -my $oid_boxServicesTempSensorTemperature2 = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1.5'; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(fan|psu|temperature)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|fan)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + default => [ + ['notpresent', 'OK'], + ['operational', 'OK'], + ['failed', 'CRITICAL'], + ['powering', 'WARNING'], + ['nopower', 'CRITICAL'], + ['notpowering', 'CRITICAL'], + ['incompatible', 'CRITICAL'], + ], + temperature => [ + ['low', 'WARNING'], + ['normal', 'OK'], + ['warning', 'WARNING'], + ['critical', 'CRITICAL'], + ['shutdown', 'CRITICAL'], + ['notpresent', 'OK'], + ['notoperational', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'centreon::common::fastpath::mode::components'; + $self->{components_module} = ['fan', 'psu', 'temperature']; +} -my $thresholds = { - psu => [ - ['notpresent', 'OK'], - ['operational', 'OK'], - ['failed', 'CRITICAL'], - ['powering', 'WARNING'], - ['nopower', 'CRITICAL'], - ['notpowering', 'CRITICAL'], - ['incompatible', 'CRITICAL'], - ], - fan => [ - ['notpresent', 'OK'], - ['operational', 'OK'], - ['failed', 'CRITICAL'], - ['powering', 'WARNING'], - ['nopower', 'CRITICAL'], - ['notpowering', 'CRITICAL'], - ['incompatible', 'CRITICAL'], - ], -}; - -my %map_states = ( - 1 => 'notpresent', - 2 => 'operational', - 3 => 'failed', - 4 => 'powering', - 5 => 'nopower', - 6 => 'notpowering', - 7 => 'incompatible', -); +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) = @_; @@ -73,291 +73,35 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "exclude:s" => { name => 'exclude' }, - "component:s" => { name => 'component', default => 'all' }, - "absent-problem:s" => { name => 'absent' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning-temperature:s" => { name => 'warning_temperature' }, - "critical-temperature:s" => { name => 'critical_temperature' }, }); - - $self->{components} = {}; - $self->{no_components} = undef; + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning_temperature', value => $self->{option_results}->{warning_temperature})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning temperature threshold '" . $self->{option_results}->{warning_temperature} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical_temperature', value => $self->{option_results}->{critical_temperature})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical temperature threshold '" . $self->{option_results}->{critical_temperature} . "'."); - $self->{output}->option_exit(); - } - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } - - $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}; - - # There is a bug with get_leef and snmpv1. - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_boxServicesFansEntry }, - { oid => $oid_boxServicesPowSuppliesEntry }, - { oid => $oid_boxServicesTempSensorsEntry }, - ]); - - if ($self->{option_results}->{component} eq 'all') { - $self->check_fan(); - $self->check_psu(); - $self->check_temperature(); - } elsif ($self->{option_results}->{component} eq 'fan') { - $self->check_fan(); - } elsif ($self->{option_results}->{component} eq 'psu') { - $self->check_psu(); - } elsif ($self->{option_results}->{component} eq 'temperature') { - $self->check_temperature(); - } 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}; - 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; -} - -sub check_fan { - my ($self) = @_; - - $self->{output}->output_add(long_msg => "Checking fans"); - $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'fan')); - - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesFansEntry}})) { - next if ($oid !~ /^$oid_boxServicesFanItemState\.(.*)/); - my $instance = $1; - my $fan_state = $self->{results}->{$oid_boxServicesFansEntry}->{$oid_boxServicesFanItemState . '.' . $instance}; - my $fan_speed = $self->{results}->{$oid_boxServicesFansEntry}->{$oid_boxServicesFanSpeed . '.' . $instance}; - - next if ($self->check_exclude(section => 'fan', instance => $instance)); - next if ($map_states{$fan_state} eq 'notPresent' && - $self->absent_problem(section => 'fan', instance => $instance)); - - $self->{components}->{fan}->{total}++; - $self->{output}->output_add(long_msg => sprintf("Fan '%s' state is %s.", - $instance, $map_states{$fan_state})); - my $exit = $self->get_severity(section => 'fan', value => $map_states{$fan_state}); - 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.", $instance, $map_states{$fan_state})); - } - - $self->{output}->perfdata_add(label => "Fan_$instance", - unit => 'rpm', - value => $fan_speed, - min => 0); - } -} - -sub check_psu { - my ($self) = @_; - - $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')); - - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesPowSuppliesEntry}})) { - next if ($oid !~ /^$oid_boxServicesPowSupplyItemState\.(.*)/); - my $instance = $1; - my $psu_state = $self->{results}->{$oid_boxServicesPowSuppliesEntry}->{$oid_boxServicesPowSupplyItemState . '.' . $instance}; - - next if ($self->check_exclude(section => 'psu', instance => $instance)); - next if ($map_states{$psu_state} eq 'notPresent' && - $self->absent_problem(section => 'psu', instance => $instance)); - - $self->{components}->{psu}->{total}++; - $self->{output}->output_add(long_msg => sprintf("Power supply '%s' state is %s.", - $instance, $map_states{$psu_state})); - my $exit = $self->get_severity(section => 'psu', value => $map_states{$psu_state}); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Power supply '%s' state is %s.", $instance, $map_states{$psu_state})); - } - } -} - -sub check_temperature { - my ($self) = @_; - - $self->{output}->output_add(long_msg => "Checking temperature sensors"); - $self->{components}->{temperature} = {name => 'temperature sensors', total => 0, skip => 0}; - return if ($self->check_exclude(section => 'temperature')); - - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesTempSensorsEntry}})) { - my $instance; - if ($oid =~ /^$oid_boxServicesTempSensorTemperature1\.(.*)/) { - $instance = $1; - } elsif ($oid =~ /^$oid_boxServicesTempSensorTemperature2\.(.*)\.(.*)/) { - $instance = $1 . '.' . $2; - } else { - next; - } - my $temperature; - - if (defined($self->{results}->{$oid_boxServicesTempSensorsEntry}->{$oid_boxServicesTempSensorTemperature1 . '.' . $instance})) { - $temperature = $self->{results}->{$oid_boxServicesTempSensorsEntry}->{$oid_boxServicesTempSensorTemperature1 . '.' . $instance}; - } else { - $temperature = $self->{results}->{$oid_boxServicesTempSensorsEntry}->{$oid_boxServicesTempSensorTemperature2 . '.' . $instance}; - } - - next if ($self->check_exclude(section => 'temperature', instance => $instance)); - - $instance =~ s/(\d+)\.//; - - $self->{components}->{temperature}->{total}++; - $self->{output}->output_add(long_msg => sprintf("Temperature sensor '%s' : %sc.", - $instance, $temperature)); - my $exit = $self->{perfdata}->threshold_check(value => $temperature, threshold => [ { label => 'critical_temperature', 'exit_litteral' => 'critical' }, { label => 'warning_temperature', exit_litteral => 'warning' } ]); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Temperature sensor '%s' : %sc.", $instance, $temperature)); - } - - $self->{output}->perfdata_add(label => "Temperature_$instance", - unit => 'c', - value => $temperature); - } -} - 1; __END__ =head1 MODE -Check environment (FASTPATH-BOXSERVICES-MIB) (Fans, Power Supplies, Temperature). +Check Hardware (Fans, Power Supplies, Temperature) (FASTPATH-BOXSERVICES-MIB). =over 8 =item B<--component> -Which component to check (Default: 'all'). -Can be: 'psu', 'fan', 'temperature'. +Which component to check (Default: '.*'). +Can be: 'fan', 'psu', 'temperature'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=psu) -Can also exclude specific instance: --exclude='fan#fan2_unit1#' +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=psu +Can be specific or global: --absent-problem=psu,1 =item B<--no-component> @@ -366,18 +110,20 @@ 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)$)' +Example: --threshold-overload='psu,CRITICAL,^(?!(operational)$)' -=item B<--warning-temperature> +=item B<--warning> -Warning threshold for temperature in celsius. +Set warning threshold for 'temperature', 'fan' (syntax: type,regexp,threshold) +Example: --warning='fan,1.1,5000' -=item B<--critical-temperature> +=item B<--critical> -Critical threshold for temperature in celsius. +Set critical threshold for 'temperature', 'fan' (syntax: type,regexp,threshold) +Example: --critical='fan,.*,2000' =back -=cut +=cut \ No newline at end of file diff --git a/centreon-plugins/centreon/plugins/script.pm b/centreon-plugins/centreon/plugins/script.pm index ce5fa7c04..1bd77cc03 100644 --- a/centreon-plugins/centreon/plugins/script.pm +++ b/centreon-plugins/centreon/plugins/script.pm @@ -30,7 +30,7 @@ use Pod::Find qw(pod_where); my %handlers = (DIE => {}); -my $global_version = 20160524; +my $global_version = 20160627; my $alternative_fatpacker = 0; sub new { diff --git a/centreon-plugins/centreon/plugins/snmp.pm b/centreon-plugins/centreon/plugins/snmp.pm index 0219b1023..069d8b879 100644 --- a/centreon-plugins/centreon/plugins/snmp.pm +++ b/centreon-plugins/centreon/plugins/snmp.pm @@ -679,7 +679,7 @@ sub check_options { if (!defined($options{option_results}->{snmp_security_name})) { - $self->{output}->add_option_msg(short_msg => "Missing paramater Security Name."); + $self->{output}->add_option_msg(short_msg => "Missing parameter Security Name."); $self->{output}->option_exit(); } diff --git a/centreon-plugins/changelog b/centreon-plugins/changelog index 816435aeb..d4d08dcae 100644 --- a/centreon-plugins/changelog +++ b/centreon-plugins/changelog @@ -1,3 +1,15 @@ +2016-06-27 Quentin Garnier + * Update FAQ: build a standalone perl script + * Plugin added: to check Lenovo S Series (#412) + * Plugin added: to check Digi AnywhereUSB + * Mode added: [netasq] 'ha-nodes' + * Mode removed: [netasq] 'ha-status' + * Fix: [dell n4000]{environment} wrong temperature (#397) + * Fix: [netapp]{cache-age} not working (#422) + * Fix: [cisco wlc]{ap-users} wrong total + * Fix: [tomcat]{memory} problem with java 8 + * Fix: [netapp]{filesys} no values (#415) + 2016-05-24 Quentin Garnier * Can use '/' instead '::' for plugin option (#380) * Mode added: [pacemaker] 'constraints' diff --git a/centreon-plugins/database/mssql/mode/databasessize.pm b/centreon-plugins/database/mssql/mode/databasessize.pm index 6e37a6627..8a0b5cd7d 100644 --- a/centreon-plugins/database/mssql/mode/databasessize.pm +++ b/centreon-plugins/database/mssql/mode/databasessize.pm @@ -20,50 +20,129 @@ package database::mssql::mode::databasessize; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +my $instance_mode; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'database', type => 1, cb_prefix_output => 'prefix_database_output', message_multiple => 'All databases are OK' }, + ]; + + $self->{maps_counters}->{database} = [ + { label => 'database', set => { + key_values => [ { name => 'prct_used' }, { name => 'used' }, { name => 'free' }, { name => 'total' }, { name => 'display' } ], + closure_custom_calc => \&custom_usage_calc, + closure_custom_output => \&custom_usage_output, + closure_custom_perfdata => \&custom_usage_perfdata, + closure_custom_threshold_check => \&custom_usage_threshold, + } + }, + ]; +} + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $label = 'db_' . $self->{result_values}->{display} . '_used'; + my $value_perf = $self->{result_values}->{used}; + if (defined($instance_mode->{option_results}->{free})) { + $label = 'db_' . $self->{result_values}->{display} . '_free'; + $value_perf = $self->{result_values}->{free}; + } + my $extra_label = ''; + $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); + if ($instance_mode->{option_results}->{units} eq '%') { + $total_options{total} = $self->{result_values}->{total}; + $total_options{cast_int} = 1; + } + + $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my ($exit, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + my $msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{prct_used} = $options{new_datas}->{$self->{instance} . '_prct_used'}; + $self->{result_values}->{free} = $options{new_datas}->{$self->{instance} . '_free'}; + + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + + 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 => - { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - "filter:s" => { name => 'filter', }, - "free" => { name => 'free', }, + { + "filter-database:s" => { name => 'filter_database' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, }); - return $self; } +sub prefix_database_output { + my ($self, %options) = @_; + + return "Database '" . $options{instance_value}->{display} . "' "; +} + sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->SUPER::check_options(%options); - if (($self->{perfdata}->threshold_validate(label => 'warning', 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(); - } + $instance_mode = $self; } -sub run { +sub manage_selection { my ($self, %options) = @_; # $options{sql} = sqlmode object $self->{sql} = $options{sql}; - - $self->{output}->output_add(severity => 'OK', - short_msg => "All databases are ok."); - $self->{sql}->connect(); $self->{sql}->query(query => q{DBCC SQLPERF(LOGSPACE)}); @@ -71,7 +150,7 @@ sub run { my @databases_selected; foreach my $row (@$result) { - next if (defined($self->{option_results}->{filter}) && $$row[0] !~ /$self->{option_results}->{filter}/); + next if (defined($self->{option_results}->{filter_database}) && $$row[0] !~ /$self->{option_results}->{filter_database}/); push @databases_selected, $$row[0]; } @@ -83,44 +162,17 @@ sub run { my $size = convert_bytes($size_brut); my $free_brut = $$row[2]; my $free = convert_bytes($free_brut); - my $use = $size - $free; - my $percent_use = ($use / $size) * 100; - my $percent_free = 100 - $percent_use; - my ($use_value, $use_unit) = $self->{perfdata}->change_bytes(value => $use); - $self->{output}->output_add(long_msg => sprintf("DB '%s' Size: %s Used: %.2f %s (%.2f%%) Free: %s (%.2f%%)", $database, $size_brut, $use_value, $use_unit, $percent_use, $free_brut, $percent_free)); - if (defined($self->{option_results}->{free})) { - my $exit_code = $self->{perfdata}->threshold_check(value => $percent_free, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - if (!$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit_code, - short_msg => sprintf("DB '%s' Size: %s Free: %s (%.2f%%)", $database, $size_brut, $free_brut, $percent_use)); - } - $self->{output}->perfdata_add(label => sprintf("db_%s_free",$database), - unit => 'B', - value => int($free), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $size, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $size, cast_int => 1), - min => 0, - max => int($size)); - } else { - my $exit_code = $self->{perfdata}->threshold_check(value => $percent_use, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - if (!$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit_code, - short_msg => sprintf("DB '%s' Size: %s Used: %.2f %s (%.2f%%)", $database, $size_brut, $use_value, $use_unit, $percent_use)); - } - $self->{output}->perfdata_add(label => sprintf("db_%s_used",$database), - unit => 'B', - value => int($use), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $size, cast_int => 1), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $size, cast_int => 1), - min => 0, - max => int($size)); - } + my $used = $size - $free; + my $percent_used = ($used / $size) * 100; + + $self->{database}->{$database} = { used => $used, + free => $free, + total => $size, + prct_used => $percent_used, + display => lc $database }; + } } - - - $self->{output}->display(); - $self->{output}->exit(); } sub convert_bytes { @@ -144,25 +196,29 @@ __END__ =head1 MODE -Check MSSQL databases size. +Check MSSQL Database usage =over 8 -=item B<--warning> +=item B<--warning-database> -Threshold warning in percent used. +Threshold warning. -=item B<--critical> +=item B<--critical-database> -Threshold critical in percent used. +Threshold critical. -=item B<--filter> +=item B<--filter-database> -Filter database. +Filter database by name. Can be a regex + +=item B<--units> + +Default is '%', can be 'B' =item B<--free> -Check free space instead of used space. +Perfdata show free space =back diff --git a/centreon-plugins/database/oracle/mode/rmanbackupage.pm b/centreon-plugins/database/oracle/mode/rmanbackupage.pm index c01fc3634..5a04879d9 100644 --- a/centreon-plugins/database/oracle/mode/rmanbackupage.pm +++ b/centreon-plugins/database/oracle/mode/rmanbackupage.pm @@ -112,9 +112,6 @@ sub run { my $label = $_; $label =~ s/ /-/g; foreach my $row (@$result) { - - next if (defined($already_checked->{$$row[0]})); - if (defined($self->{option_results}->{incremental_level})) { # db incr with incremental level 0 = DB FULL if (/db full/ && $$row[0] =~ /db incr/i && defined($$row[2]) && $$row[2] == 0) { # it's a full. we get @@ -123,11 +120,14 @@ sub run { next if (/db incr/ && $$row[0] =~ /db incr/i && defined($$row[2]) && $$row[2] == 0); # it's a full. we skip. next if ($$row[0] !~ /$_/i); } - - $already_checked->{$$row[0]} = 1; + } else { next if ($$row[0] !~ /$_/i); } + + next if (defined($already_checked->{$$row[0]})); + + $already_checked->{$$row[0]} = 1; $count_backups++; $executed = 1; diff --git a/centreon-plugins/docs/en/user/guide.rst b/centreon-plugins/docs/en/user/guide.rst index d975b00ce..a6bca69b0 100644 --- a/centreon-plugins/docs/en/user/guide.rst +++ b/centreon-plugins/docs/en/user/guide.rst @@ -509,6 +509,8 @@ How can i check the plugin version ? You can check the version of plugins and modes with option ``--version``: :: + $ perl centreon_plugins.pl --version + Global Version: 20160524 $ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --version Plugin Version: 0.1 $ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --mode=storage --version @@ -521,6 +523,58 @@ For example, we want to execute the mode only if the version >= 2.x: $ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --mode=storage --hostname=127.0.0.1 --snmp-version=2c --snmp-community=public --verbose --mode-version='2.x' UNKNOWN: Not good version for plugin mode. Excepted at least: 2.x. Get: 1.0 +------------------------------------- +Can i have one standalone Perl file ? +------------------------------------- + +We have done some tests and it will cost around 4% more of execution time. We are going to create a standalone Linux SNMP plugin. + +Download the Perl module ``App::FatPacker`` on metacpan: +:: + + # tar zxvf App-FatPacker-0.010005.tar.gz + # cd App-FatPacker-0.010005 + # perl Makefile.PL && make && make install + +Create a directory to build it: +:: + + # mkdir -p build/plugin + # cd build + +Clone ``centreon-plugins``: +:: + + # git clone https://github.com/centreon/centreon-plugins.git + +``fatpack`` includes ``pm`` files under the directory ``lib``: +:: + + # mkdir plugin/lib && cd centreon-plugins + +Copy the common files for all plugins: +:: + + # cp -R --parent centreon/plugins/{misc,mode,options,output,perfdata,script,statefile,values}.pm centreon/plugins/templates/ centreon/plugins/alternative/ ../plugin/lib/ + # cp centreon_plugins.pl ../plugin + # sed -i 's/alternative_fatpacker = 0/alternative_fatpacker = 1/' ../plugin/lib/centreon/plugins/script.pm + +Copy files for Linux SNMP plugin: +:: + + # cp -R --parent centreon/plugins/{script_snmp,snmp}.pm os/linux/snmp/ snmp_standard/mode/{cpu,cpudetailed,diskio,diskusage,inodes,interfaces,loadaverage,listdiskspath,listinterfaces,liststorages,memory,processcount,storage,swap,ntp,tcpcon,uptime}.pm ../plugin/lib/ + +Build the standalone Perl file: +:: + + # cd ../plugin + # fatpack file centreon_plugins.pl > centreon_linux_snmp.pl + +The plugin works in the same way: +:: + + # perl centreon_linux_snmp.pl --plugin os::linux::snmp::plugin --mode=processcount --snmp-community public --snmp-version 2c --hostname=127.0.0.1 --process-name='' --process-status='' --process-args='' + *************** Troubleshooting *************** diff --git a/centreon-plugins/docs/fr/user/guide.rst b/centreon-plugins/docs/fr/user/guide.rst index 287b67cf0..6bdc66be1 100644 --- a/centreon-plugins/docs/fr/user/guide.rst +++ b/centreon-plugins/docs/fr/user/guide.rst @@ -509,6 +509,8 @@ Comment puis-je vérifier la version du plugin ? Vous pouvez vérifier la version des plugins et des modes avec l'option ``--version`` : :: + $ perl centreon_plugins.pl --version + Global Version: 20160524 $ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --version Plugin Version: 0.1 $ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --mode=storage --version @@ -521,6 +523,59 @@ Par exemple, nous voulons exécuter le mode seulement si sa version >= 2.x : $ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --mode=storage --hostname=127.0.0.1 --snmp-version=2c --snmp-community=public --verbose --mode-version='2.x' UNKNOWN: Not good version for plugin mode. Excepted at least: 2.x. Get: 1.0 +-------------------------------------------- +Comment puis-je avoir un seul fichier Perl ? +-------------------------------------------- + +Nous avons réalisé des tests et le temps d'éxecution est augmenté d'environ 4%. Nous allons créer un fichier unique pour la sonde Linux SNMP. + +Télécharger le module Perl ``App::FatPacker`` sur metacpan: +:: + + # tar zxvf App-FatPacker-0.010005.tar.gz + # cd App-FatPacker-0.010005 + # perl Makefile.PL && make && make install + +Créer un répertoire de construction: +:: + + # mkdir -p build/plugin + # cd build + +Cloner ``centreon-plugins``: +:: + + # git clone https://github.com/centreon/centreon-plugins.git + +``fatpack`` inclut les fichiers ``pm`` présent dans le répertoire ``lib``: +:: + + # mkdir plugin/lib && cd centreon-plugins + +Copier les fichiers communs à l'ensemble des sondes: +:: + + # cp -R --parent centreon/plugins/{misc,mode,options,output,perfdata,script,statefile,values}.pm centreon/plugins/templates/ centreon/plugins/alternative/ ../plugin/lib/ + # cp centreon_plugins.pl ../plugin + # sed -i 's/alternative_fatpacker = 0/alternative_fatpacker = 1/' ../plugin/lib/centreon/plugins/script.pm + +Copier les fichiers pour la sonde Linux SNMP: +:: + + # cp -R --parent centreon/plugins/{script_snmp,snmp}.pm os/linux/snmp/ snmp_standard/mode/{cpu,cpudetailed,diskio,diskusage,inodes,interfaces,loadaverage,listdiskspath,listinterfaces,liststorages,memory,processcount,storage,swap,ntp,tcpcon,uptime}.pm ../plugin/lib/ + +Construire le fichier Perl unique: +:: + + # cd ../plugin + # fatpack file centreon_plugins.pl > centreon_linux_snmp.pl + +La sonde fonctionne de la même façon: +:: + + # perl centreon_linux_snmp.pl --plugin os::linux::snmp::plugin --mode=processcount --snmp-community public --snmp-version 2c --hostname=127.0.0.1 --process-name='' --process-status='' --process-args='' + + ********* Dépannage ********* diff --git a/centreon-plugins/network/bluecoat/snmp/mode/clientrequests.pm b/centreon-plugins/network/bluecoat/snmp/mode/clientrequests.pm index fb2e1b0cc..18c53c8fe 100644 --- a/centreon-plugins/network/bluecoat/snmp/mode/clientrequests.pm +++ b/centreon-plugins/network/bluecoat/snmp/mode/clientrequests.pm @@ -20,137 +20,112 @@ package network::bluecoat::snmp::mode::clientrequests; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::statefile; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_output' }, + ]; + $self->{maps_counters}->{global} = [ + { label => 'hits', set => { + key_values => [ { name => 'client_http_requests', diff => 1 }, { name => 'client_http_hits', diff => 1 } ], + closure_custom_calc => $self->can('custom_data_calc'), closure_custom_calc_extra_options => { label_ref => 'hits' }, + output_template => 'Hits = %.2f %%', output_use => 'hits_prct', + perfdatas => [ + { label => 'hits', value => 'hits_prct', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'partial-hits', set => { + key_values => [ { name => 'client_http_requests', diff => 1 }, { name => 'client_http_partial_hits', diff => 1 } ], + closure_custom_calc => $self->can('custom_data_calc'), closure_custom_calc_extra_options => { label_ref => 'partial_hits' }, + output_template => 'Partial Hits = %.2f %%', output_use => 'partial_hits_prct', + perfdatas => [ + { label => 'partial_hits', value => 'partial_hits_prct', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'misses', set => { + key_values => [ { name => 'client_http_requests', diff => 1 }, { name => 'client_http_misses', diff => 1 } ], + closure_custom_calc => $self->can('custom_data_calc'), closure_custom_calc_extra_options => { label_ref => 'misses' }, + output_template => 'Misses = %.2f %%', output_use => 'misses_prct', + perfdatas => [ + { label => 'misses', value => 'misses_prct', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'errors', set => { + key_values => [ { name => 'client_http_requests', diff => 1 }, { name => 'client_http_errors', diff => 1 } ], + closure_custom_calc => $self->can('custom_data_calc'), closure_custom_calc_extra_options => { label_ref => 'errors' }, + output_template => 'Errors = %.2f %%', output_use => 'errors_prct', + perfdatas => [ + { label => 'errors', value => 'errors_prct', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Client Requests: "; +} + +sub custom_data_calc { + my ($self, %options) = @_; + + my $label = $options{extra_options}->{label_ref}; + my $delta_value = $options{new_datas}->{$self->{instance} . '_client_http_' . $label} - $options{old_datas}->{$self->{instance} . '_client_http_' . $label}; + my $delta_total = $options{new_datas}->{$self->{instance} . '_client_http_requests'} - $options{old_datas}->{$self->{instance} . '_client_http_requests'}; + + $self->{result_values}->{$label . '_prct'} = 0; + if ($delta_total > 0) { + $self->{result_values}->{$label . '_prct'} = $delta_value * 100 / $delta_total; + } + return 0; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "warning-errors:s" => { name => 'warning_errors' }, - "critical-errors:s" => { name => 'critical_errors' }, - "warning-misses:s" => { name => 'warning_misses' }, - "critical-misses:s" => { name => 'critical_misses' }, }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - + return $self; } -sub check_options { +sub manage_selection { my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning_errors', value => $self->{option_results}->{warning_errors})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning 'errors' threshold '" . $self->{option_results}->{warning_errors} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical_errors', value => $self->{option_results}->{critical_errors})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical 'errors' threshold '" . $self->{option_results}->{critical_errors} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'warning_misses', value => $self->{option_results}->{warning_misses})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning 'misses' threshold '" . $self->{option_results}->{warning_misses} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical_misses', value => $self->{option_results}->{critical_misses})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical 'misses' threshold '" . $self->{option_results}->{critical_misses} . "'."); - $self->{output}->option_exit(); - } - - $self->{statefile_value}->check_options(%options); -} -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(); - - if ($self->{snmp}->is_snmpv1()) { + if ($options{snmp}->is_snmpv1()) { $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); $self->{output}->option_exit(); } + my $result = $options{snmp}->get_leef(oids => ['.1.3.6.1.4.1.3417.2.11.3.1.1.1.0', + '.1.3.6.1.4.1.3417.2.11.3.1.1.2.0', + '.1.3.6.1.4.1.3417.2.11.3.1.1.3.0', + '.1.3.6.1.4.1.3417.2.11.3.1.1.4.0', + '.1.3.6.1.4.1.3417.2.11.3.1.1.5.0'], nothing_quit => 1); - $self->{statefile_value}->read(statefile => 'bluecoat_' . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode}); - my $result = $self->{snmp}->get_leef(oids => ['.1.3.6.1.4.1.3417.2.11.3.1.1.1.0', - '.1.3.6.1.4.1.3417.2.11.3.1.1.2.0', - '.1.3.6.1.4.1.3417.2.11.3.1.1.3.0', - '.1.3.6.1.4.1.3417.2.11.3.1.1.4.0', - '.1.3.6.1.4.1.3417.2.11.3.1.1.5.0'], nothing_quit => 1); - - my $new_datas = {}; - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - my $old_client_http_requests = $self->{statefile_value}->get(name => 'client_http_requests'); - my $old_client_http_hits = $self->{statefile_value}->get(name => 'client_http_hits'); - my $old_client_http_partial_hits = $self->{statefile_value}->get(name => 'client_http_partial_hits'); - my $old_client_http_misses = $self->{statefile_value}->get(name => 'client_http_misses'); - my $old_client_http_errors = $self->{statefile_value}->get(name => 'client_http_errors'); - - $new_datas->{last_timestamp} = time(); - $new_datas->{client_http_requests} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.1.0'}; - $new_datas->{client_http_hits} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.2.0'}; - $new_datas->{client_http_partial_hits} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.3.0'}; - $new_datas->{client_http_misses} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.4.0'}; - $new_datas->{client_http_errors} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.5.0'}; + $self->{cache_name} = "bluecoat_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); - $self->{statefile_value}->write(data => $new_datas); - - if (!defined($old_timestamp) || !defined($old_client_http_misses)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - - if ($new_datas->{client_http_requests} < $old_client_http_requests) { - # We set 0. Has reboot. - $old_client_http_requests = 0; - $old_client_http_hits = 0; - $old_client_http_partial_hits = 0; - $old_client_http_misses = 0; - $old_client_http_errors = 0; - } - - my $delta_http_requests = $new_datas->{client_http_requests} - $old_client_http_requests; - my $prct_misses = sprintf("%.2f", ($new_datas->{client_http_misses} - $old_client_http_misses) * 100 / $delta_http_requests); - my $prct_hits = sprintf("%.2f", ($new_datas->{client_http_hits} - $old_client_http_hits) * 100 / $delta_http_requests); - my $prct_partial_hits = sprintf("%.2f", ($new_datas->{client_http_partial_hits} - $old_client_http_partial_hits) * 100 / $delta_http_requests); - my $prct_errors = sprintf("%.2f", ($new_datas->{client_http_errors} - $old_client_http_errors) * 100 / $delta_http_requests); - - my $exit1 = $self->{perfdata}->threshold_check(value => $prct_errors, threshold => [ { label => 'critical_errors', 'exit_litteral' => 'critical' }, { label => 'warning_errors', exit_litteral => 'warning' } ]); - my $exit2 = $self->{perfdata}->threshold_check(value => $prct_misses, threshold => [ { label => 'critical_misses', 'exit_litteral' => 'critical' }, { label => 'warning_misses', exit_litteral => 'warning' } ]); - my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2 ]); - - $self->{output}->output_add(severity => $exit, - short_msg => "Client Requests: Hits = $prct_hits%, Partial Hits = $prct_partial_hits%, Misses = $prct_misses%, Errors = $prct_errors%"); - $self->{output}->perfdata_add(label => 'hits', unit => '%', - value => $prct_hits, - min => 0); - $self->{output}->perfdata_add(label => 'partial_hits', unit => '%', - value => $prct_partial_hits, - min => 0); - $self->{output}->perfdata_add(label => 'misses', unit => '%', - value => $prct_misses, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_misses'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_misses'), - min => 0); - $self->{output}->perfdata_add(label => 'errors', unit => '%', - value => $prct_errors, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_errors'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_errors'), - min => 0); - - $self->{output}->display(); - $self->{output}->exit(); + $self->{global} = { client_http_requests => $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.1.0'}, + client_http_hits => $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.2.0'}, + client_http_partial_hits => $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.3.0'}, + client_http_misses => $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.4.0'}, + client_http_errors => $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.5.0'} }; } 1; @@ -163,21 +138,20 @@ Check http client requests (in percent by type: hit, partial, misses, errors) =over 8 -=item B<--warning-errors> +=item B<--filter-counters> -Threshold warning of client http errors in percent. +Only display some counters (regexp can be used). +Example: --filter-counters='errors' -=item B<--critical-errors> +=item B<--warning-*> -Threshold critical of client http errors in percent. +Threshold warning. +Can be: errors (%), hits (%), partial-hits (%), misses (%). -=item B<--warning-misses> +=item B<--critical-*> -Threshold warning of client http misses in percent. - -=item B<--critical-misses> - -Threshold critial of client http misses in percent. +Threshold critical. +Can be: errors (%), hits (%), partial-hits (%), misses (%). =back diff --git a/centreon-plugins/network/digi/anywhereusb/snmp/mode/cpu.pm b/centreon-plugins/network/digi/anywhereusb/snmp/mode/cpu.pm new file mode 100644 index 000000000..79602f314 --- /dev/null +++ b/centreon-plugins/network/digi/anywhereusb/snmp/mode/cpu.pm @@ -0,0 +1,99 @@ +# +# 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 network::digi::anywhereusb::snmp::mode::cpu; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; + + my $oid_diCpuUtilization = '.1.3.6.1.4.1.332.11.6.1.6.0'; + my $result = $self->{snmp}->get_leef(oids => [$oid_diCpuUtilization], nothing_quit => 1); + + my $exit = $self->{perfdata}->threshold_check(value => $result->{$oid_diCpuUtilization}, + threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("CPU Usage : %.2f", $result->{$oid_diCpuUtilization})); + $self->{output}->perfdata_add(label => "cpu", + value => $result->{$oid_diCpuUtilization}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check current processor usage. + +=over 8 + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=back + +=cut + \ No newline at end of file diff --git a/centreon-plugins/network/digi/anywhereusb/snmp/mode/memory.pm b/centreon-plugins/network/digi/anywhereusb/snmp/mode/memory.pm new file mode 100644 index 000000000..e6a4270f0 --- /dev/null +++ b/centreon-plugins/network/digi/anywhereusb/snmp/mode/memory.pm @@ -0,0 +1,132 @@ +# +# 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 network::digi::anywhereusb::snmp::mode::memory; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => 'used', unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + + my $msg = sprintf("Memory Usage Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_total'} - $options{new_datas}->{$self->{instance} . '_free'}; + $self->{result_values}->{free} = $options{new_datas}->{$self->{instance} . '_free'}; + $self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 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); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_diTotalMemory = '.1.3.6.1.4.1.332.11.6.1.8.0'; + my $oid_diFreeMemory = '.1.3.6.1.4.1.332.11.6.1.9.0'; + my $result = $options{snmp}->get_leef(oids => [$oid_diTotalMemory, $oid_diFreeMemory], + nothing_quit => 1); + $self->{memory} = { free => $result->{$oid_diFreeMemory}, total => $result->{$oid_diTotalMemory} }; +} + +1; + +__END__ + +=head1 MODE + +Check memory usage. + +=over 8 + +=item B<--warning-usage> + +Threshold warning (in percent). + +=item B<--critical-usage> + +Threshold critical (in percent). + +=back + +=cut \ No newline at end of file diff --git a/centreon-plugins/network/digi/anywhereusb/snmp/plugin.pm b/centreon-plugins/network/digi/anywhereusb/snmp/plugin.pm new file mode 100644 index 000000000..a965548c1 --- /dev/null +++ b/centreon-plugins/network/digi/anywhereusb/snmp/plugin.pm @@ -0,0 +1,51 @@ +# +# 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 network::digi::anywhereusb::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'cpu' => 'network::digi::anywhereusb::snmp::mode::cpu', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::digi::anywhereusb::snmp::mode::memory', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Digi AnywhereUSB equipments in SNMP. + +=cut diff --git a/centreon-plugins/network/h3c/snmp/mode/components/sensor.pm b/centreon-plugins/network/h3c/snmp/mode/components/sensor.pm index 099ccbe85..515c149cb 100644 --- a/centreon-plugins/network/h3c/snmp/mode/components/sensor.pm +++ b/centreon-plugins/network/h3c/snmp/mode/components/sensor.pm @@ -65,44 +65,41 @@ sub check { next; } - next if (!(defined($result2->{EntityExtTemperatureThreshold}) && - $result2->{EntityExtTemperatureThreshold} > 0 && $result2->{EntityExtTemperatureThreshold} < 65535)); - my $name = $self->get_long_name(instance => $instance); $self->{components}->{sensor}->{total}++; - if (defined($result2->{EntityExtTemperatureThreshold}) && - $result2->{EntityExtTemperatureThreshold} > 0 && $result2->{EntityExtTemperatureThreshold} < 65535) { - $self->{output}->output_add(long_msg => sprintf("Sensor '%s' status is '%s' [instance = %s]", - $name, $result->{EntityExtErrorStatus}, $instance)); - $exit = $self->get_severity(section => 'sensor', value => $result->{EntityExtErrorStatus}); - 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'", $name, $result->{EntityExtErrorStatus})); - } - - ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result2->{EntityExtTemperature}); - if ($checked == 0) { - my $crit_th = '~:' . $result2->{EntityExtTemperatureThreshold}; - $self->{perfdata}->threshold_validate(label => 'warning-temperature-instance-' . $instance, value => undef); - $self->{perfdata}->threshold_validate(label => 'critical-temperature-instance-' . $instance, value => $crit_th); - - $exit = $self->{perfdata}->threshold_check(value => $result2->{EntityExtTemperature}, threshold => [ { label => 'critical-temperature-instance-' . $instance, exit_litteral => 'critical' }, - { label => 'warning-temperature-instance-' . $instance, exit_litteral => 'warning' } ]); - $warn = $self->{perfdata}->get_perfdata_for_output(label => 'warning-temperature-instance-' . $instance); - $crit = $self->{perfdata}->get_perfdata_for_output(label => 'critical-temperature-instance-' . $instance); - } - - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Temperature sensor '%s' is %s degree centigrade", $name, $result2->{EntityExtTemperature})); - } - $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', - value => $result2->{EntityExtTemperature}, - warning => $warn, - critical => $crit, - ); + $self->{output}->output_add(long_msg => sprintf("Sensor '%s' status is '%s' [instance = %s]", + $name, $result->{EntityExtErrorStatus}, $instance)); + $exit = $self->get_severity(section => 'sensor', value => $result->{EntityExtErrorStatus}); + 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'", $name, $result->{EntityExtErrorStatus})); } + + next if (defined($result2->{EntityExtTemperature}) && $result2->{EntityExtTemperature} <= 0); + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result2->{EntityExtTemperature}); + if ($checked == 0 && defined($result2->{EntityExtTemperatureThreshold}) && + $result2->{EntityExtTemperatureThreshold} > 0 && $result2->{EntityExtTemperatureThreshold} < 65535) { + my $crit_th = '~:' . $result2->{EntityExtTemperatureThreshold}; + $self->{perfdata}->threshold_validate(label => 'warning-temperature-instance-' . $instance, value => undef); + $self->{perfdata}->threshold_validate(label => 'critical-temperature-instance-' . $instance, value => $crit_th); + + $exit = $self->{perfdata}->threshold_check(value => $result2->{EntityExtTemperature}, threshold => [ { label => 'critical-temperature-instance-' . $instance, exit_litteral => 'critical' }, + { label => 'warning-temperature-instance-' . $instance, exit_litteral => 'warning' } ]); + $warn = $self->{perfdata}->get_perfdata_for_output(label => 'warning-temperature-instance-' . $instance); + $crit = $self->{perfdata}->get_perfdata_for_output(label => 'critical-temperature-instance-' . $instance); + } + + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature sensor '%s' is %s degree centigrade", $name, $result2->{EntityExtTemperature})); + } + $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', + value => $result2->{EntityExtTemperature}, + warning => $warn, + critical => $crit, + ); } } diff --git a/centreon-plugins/storage/emc/clariion/TODO b/centreon-plugins/storage/emc/clariion/TODO deleted file mode 100644 index b9601caa4..000000000 --- a/centreon-plugins/storage/emc/clariion/TODO +++ /dev/null @@ -1,77 +0,0 @@ -=============== -Mode Lun -=============== - -Command to test. All: getlun -uid -state -rg -type -drivetype -capacity -prb -bind - -LOGICAL UNIT NUMBER 3 -UID: 60:06:01:60:F8:C0:1E:00:A2:DC:41:39:8C:0F:E1:11 -State: Bound -RAIDGroup ID: 0 -RAID Type: RAID5 -Drive Type: SATAII -LUN Capacity(Megabytes): 1659491 -LUN Capacity(Blocks): 3398637568 -Prct Rebuilt: 100 -Prct Bound: 100 - -LOGICAL UNIT NUMBER 1 -UID: 60:06:01:60:F8:C0:1E:00:0E:A7:F5:5F:66:10:E1:11 -State: Bound -RAIDGroup ID: 101 -RAID Type: Hot Spare -Drive Type: SATAII -LUN Capacity(Megabytes): 704364 -LUN Capacity(Blocks): 1442538624 -Prct Rebuilt: N/A -Prct Bound: 100 - - -For one lun: getlun 1 -uid -state -rg -type -drivetype -capacity -prb -bind - -UID: 60:06:01:60:F8:C0:1E:00:0E:A7:F5:5F:66:10:E1:11 -State: Bound -RAIDGroup ID: 101 -RAID Type: Hot Spare -Drive Type: SATAII -LUN Capacity(Megabytes): 704364 -LUN Capacity(Blocks): 1442538624 -Prct Rebuilt: N/A -Prct Bound: 100 - -====================== -Mode pour les raid group -====================== - -La commande globale: getrg -type -tcap -ucap -prcntdf -prcntex -state - -RaidGroup ID: 40 -RaidGroup Type: r5 -Raw Capacity (Blocks): 5770154824 -Logical Capacity (Blocks): 4327616118 -Free Capacity (Blocks,non-contiguous): 246 -Percent defragmented: 100 -Percent expanded: 100 -RaidGroup State: Explicit_Remove - Valid_luns - -RaidGroup ID: 103 -RaidGroup Type: hot_spare -Raw Capacity (Blocks): 1442538706 -Logical Capacity (Blocks): 1442538706 -Free Capacity (Blocks,non-contiguous): 82 -Percent defragmented: 100 -Percent expanded: 100 -RaidGroup State: Valid_luns - - -Pour un seul: getrg 109 -type -tcap -ucap -prcntdf -prcntex -state - -RaidGroup ID: 109 -RaidGroup Type: hot_spare -Raw Capacity (Blocks): 1442538706 -Logical Capacity (Blocks): 0 -Free Capacity (Blocks,non-contiguous): 1442538706 -Percent defragmented: 100 -Percent expanded: 100 -RaidGroup State: Valid_luns diff --git a/centreon-plugins/storage/emc/symmetrix/dmx34/local/mode/hardware.pm b/centreon-plugins/storage/emc/symmetrix/dmx34/local/mode/hardware.pm index 9018474ed..010a6a303 100644 --- a/centreon-plugins/storage/emc/symmetrix/dmx34/local/mode/hardware.pm +++ b/centreon-plugins/storage/emc/symmetrix/dmx34/local/mode/hardware.pm @@ -153,10 +153,6 @@ sub send_email { } if (defined($self->{option_results}->{email_smtp_username}) && defined($self->{option_results}->{email_smtp_password})) { $smtp_options{-pass} = $self->{option_results}->{email_smtp_password}; - } - foreach my $option (@{$self->{option_results}->{email_smtp_options}}) { - next if ($option !~ /^(.+?)=(.+)$/); - $smtp_options{-$1} = $2; } ####### @@ -172,6 +168,17 @@ sub send_email { my $subject = $1; my $status = lc($self->{output}->get_litteral_status()); + foreach my $option (@{$self->{option_results}->{email_smtp_options}}) { + next if ($option !~ /^(.+?)=(.+)$/); + my ($label, $value) = ($1, $2); + if ($label =~ /subject/i) { + $value =~ s/%\{status\}/$status/g; + $value =~ s/%\{short_msg\}/$subject/g; + $label = lc($label); + } + $smtp_options{-$label} = $value; + } + my $send_email = 0; $send_email = 1 if ($status ne 'ok'); ####### @@ -216,9 +223,9 @@ sub send_email { } my $result = $mail->send(-to => $smtp_to, -from => $self->{option_results}->{email_smtp_from}, - -subject => $subject, + -subject => defined($smtp_options{-subject}) ? $smtp_options{-subject} : $subject, -body => $stdout, - -attachments => $self->{option_results}->{file_health_env}); + -attachments => $self->{option_results}->{file_health} . ',' . $self->{option_results}->{file_health_env}); $mail->bye(); if ($result == -1) { $self->{output}->add_option_msg(severity => 'UNKNOWN', short_msg => "problem to send the email"); diff --git a/centreon-plugins/storage/emc/symmetrix/vmax/local/mode/hardware.pm b/centreon-plugins/storage/emc/symmetrix/vmax/local/mode/hardware.pm index 8f2b7429a..e8134bf2a 100644 --- a/centreon-plugins/storage/emc/symmetrix/vmax/local/mode/hardware.pm +++ b/centreon-plugins/storage/emc/symmetrix/vmax/local/mode/hardware.pm @@ -49,11 +49,48 @@ sub set_system { $self->{components_module} = ['module', 'temperature', 'director', 'cabling', 'power', 'fabric', 'voltage', 'sparedisk']; } +sub find_files { + my ($self, %options) = @_; + + if (!opendir(DIR, $self->{option_results}->{health_directory})) { + $self->{output}->add_option_msg(short_msg => "Cannot open directory: $!"); + $self->{output}->option_exit(); + } + + my $save_value = 0; + while (my $file = readdir(DIR)) { + next if (! -d $self->{option_results}->{health_directory} . '/' . $file || + $file !~ /$self->{option_results}->{health_directory_pattern}/); + if (hex($1) > $save_value) { + $self->{option_results}->{file_health} = $self->{option_results}->{health_directory} . '/' . $file . '/' . $self->{option_results}->{file_health_name}; + $self->{option_results}->{file_health_env} = $self->{option_results}->{health_directory} . '/' . $file . '/' . $self->{option_results}->{file_health_env_name}; + $save_value = hex($1); + } + } + + closedir(DIR); +} + sub check_options { my ($self, %options) = @_; $self->SUPER::check_options(%options); $self->{statefile_cache}->check_options(%options); + + if (!defined($self->{option_results}->{file_health_name}) || !defined($self->{option_results}->{file_health_env_name})) { + $self->{output}->add_option_msg(short_msg => "Please set option --file-health-name and --file-health-env-name."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{health_directory}) || ! -d $self->{option_results}->{health_directory}) { + $self->{output}->add_option_msg(short_msg => "Please set right option for --health-directory."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{health_directory_pattern})) { + $self->{output}->add_option_msg(short_msg => "Please set option for --health-directory-pattern."); + $self->{output}->option_exit(); + } + + $self->find_files(); } sub new { @@ -64,8 +101,10 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "file-health:s" => { name => 'file_health' }, - "file-health-env:s" => { name => 'file_health_env' }, + "health-directory:s" => { name => 'health_directory' }, + "health-directory-pattern:s" => { name => 'health_directory_pattern' }, + "file-health-name:s" => { name => 'file_health_name', default => 'HealthCheck.log' }, + "file-health-env-name:s" => { name => 'file_health_env_name', default => 'sympl_env_health.log' }, # Email "email-warning:s" => { name => 'email_warning' }, "email-critical:s" => { name => 'email_critical' }, @@ -84,11 +123,6 @@ sub new { sub read_files { my ($self, %options) = @_; - - if (!defined($self->{option_results}->{file_health}) || !defined($self->{option_results}->{file_health_env})) { - $self->{output}->add_option_msg(short_msg => "Please set option --file-health and --file-health-env."); - $self->{output}->option_exit(); - } foreach (('file_health', 'file_health_env')) { $self->{'content_' . $_} = do { @@ -145,10 +179,6 @@ sub send_email { if (defined($self->{option_results}->{email_smtp_username}) && defined($self->{option_results}->{email_smtp_password})) { $smtp_options{-pass} = $self->{option_results}->{email_smtp_password}; } - foreach my $option (@{$self->{option_results}->{email_smtp_options}}) { - next if ($option !~ /^(.+?)=(.+)$/); - $smtp_options{-$1} = $2; - } ####### # Get current data @@ -163,6 +193,17 @@ sub send_email { my $subject = $1; my $status = lc($self->{output}->get_litteral_status()); + foreach my $option (@{$self->{option_results}->{email_smtp_options}}) { + next if ($option !~ /^(.+?)=(.+)$/); + my ($label, $value) = ($1, $2); + if ($label =~ /subject/i) { + $value =~ s/%\{status\}/$status/g; + $value =~ s/%\{short_msg\}/$subject/g; + $label = lc($label); + } + $smtp_options{-$label} = $value; + } + my $send_email = 0; $send_email = 1 if ($status ne 'ok'); ####### @@ -176,7 +217,7 @@ sub send_email { $send_email = 0 if ($status ne 'ok' && defined($prev_output) && $prev_output eq $subject); # recovery email $send_email = 1 if ($status eq 'ok' && defined($prev_status) && $prev_status ne 'ok'); - $self->{statefile_cache}->write(data => $self->{new_datas}); + $self->{statefile_cache}->write(data => $self->{new_datas}); } my $smtp_to = ''; @@ -207,9 +248,9 @@ sub send_email { } my $result = $mail->send(-to => $smtp_to, -from => $self->{option_results}->{email_smtp_from}, - -subject => $subject, + -subject => defined($smtp_options{-subject}) ? $smtp_options{-subject} : $subject, -body => $stdout, - -attachments => $self->{option_results}->{file_health_env}); + -attachments => $self->{option_results}->{file_health} . "," . $self->{option_results}->{file_health_env}); $mail->bye(); if ($result == -1) { $self->{output}->add_option_msg(severity => 'UNKNOWN', short_msg => "problem to send the email"); @@ -259,13 +300,21 @@ Example: --warning='sparedisk,.*,5:' Set critical threshold for disk (syntax: type,regexp,threshold) Example: --critical='sparedisk,.*,3:' -=item B<--file-health> +=item B<--health-directory> -The location of the global storage file status (Should be something like: C:/xxxx/HealthCheck.log). +Location of health files. -=item B<--file-health-env> +=item B<--health-directory-pattern> -The location of the environment storage file status (Should be something like: C:/xxxx/sumpl_env_health.log). +Set pattern to match the most recent directory (getting the hexa value). + +=item B<--file-health-name> + +Name of the global storage file status (Default: HealthCheck.log). + +=item B<--file-health-env-name> + +Name of the environment storage file status (Default: sympl_env_health.log). =back diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/components/array.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/array.pm new file mode 100644 index 000000000..f8c1eb39a --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/array.pm @@ -0,0 +1,60 @@ +# +# 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 storage::ibm::storwize::ssh::mode::components::array; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssh_commands} .= 'echo "==========lsarray=========="; lsarray -delim : ; echo "===============";'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking arrays"); + $self->{components}->{array} = {name => 'arrays', total => 0, skip => 0}; + return if ($self->check_filter(section => 'array')); + + return if ($self->{results} !~ /==========lsarray==.*?\n(.*?)==============/msi); + my $content = $1; + + my $result = $self->get_hasharray(content => $content, delim => ':'); + foreach (@$result) { + next if ($self->check_filter(section => 'array', instance => $_->{mdisk_id})); + $self->{components}->{array}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("array '%s' status is '%s' [instance: %s].", + $_->{mdisk_name}, $_->{status}, + $_->{mdisk_id} + )); + my $exit = $self->get_severity(label => 'default', section => 'array', value => $_->{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Array '%s' status is '%s'", + $_->{mdisk_name}, $_->{status})); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/components/drive.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/drive.pm new file mode 100644 index 000000000..e0afd26d8 --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/drive.pm @@ -0,0 +1,60 @@ +# +# 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 storage::ibm::storwize::ssh::mode::components::drive; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssh_commands} .= 'echo "==========lsdrive=========="; lsdrive -delim : ; echo "===============";'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking drives"); + $self->{components}->{drive} = {name => 'drives', total => 0, skip => 0}; + return if ($self->check_filter(section => 'drive')); + + return if ($self->{results} !~ /==========lsdrive==.*?\n(.*?)==============/msi); + my $content = $1; + + my $result = $self->get_hasharray(content => $content, delim => ':'); + foreach (@$result) { + next if ($self->check_filter(section => 'drive', instance => $_->{id})); + $self->{components}->{drive}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("drive '%s' status is '%s' [instance: %s].", + $_->{id}, $_->{status}, + $_->{id} + )); + my $exit = $self->get_severity(label => 'default', section => 'drive', value => $_->{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Drive '%s' status is '%s'", + $_->{id}, $_->{status})); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/components/enclosure.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/enclosure.pm new file mode 100644 index 000000000..c581613b0 --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/enclosure.pm @@ -0,0 +1,60 @@ +# +# 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 storage::ibm::storwize::ssh::mode::components::enclosure; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssh_commands} .= 'echo "==========lsenclosure=========="; lsenclosure -delim : ; echo "===============";'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking enclosures"); + $self->{components}->{enclosure} = {name => 'enclosures', total => 0, skip => 0}; + return if ($self->check_filter(section => 'enclosure')); + + return if ($self->{results} !~ /==========lsenclosure==.*?\n(.*?)==============/msi); + my $content = $1; + + my $result = $self->get_hasharray(content => $content, delim => ':'); + foreach (@$result) { + next if ($self->check_filter(section => 'enclosure', instance => $_->{id})); + $self->{components}->{enclosure}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("enclosure '%s' status is '%s' [instance: %s].", + $_->{id}, $_->{status}, + $_->{id} + )); + my $exit = $self->get_severity(label => 'default', section => 'enclosure', value => $_->{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Enclosure '%s' status is '%s'", + $_->{id}, $_->{status})); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/components/enclosurebattery.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/enclosurebattery.pm new file mode 100644 index 000000000..75d38992a --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/enclosurebattery.pm @@ -0,0 +1,61 @@ +# +# 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 storage::ibm::storwize::ssh::mode::components::enclosurebattery; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssh_commands} .= 'echo "==========lsenclosurebattery=========="; lsenclosurebattery -delim : ; echo "===============";'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking enclosure batteries"); + $self->{components}->{enclosurebattery} = {name => 'enclosure batteries', total => 0, skip => 0}; + return if ($self->check_filter(section => 'enclosurebattery')); + + return if ($self->{results} !~ /==========lsenclosurebattery==.*?\n(.*?)==============/msi); + my $content = $1; + + my $result = $self->get_hasharray(content => $content, delim => ':'); + foreach (@$result) { + my $instance = $_->{enclosure_id} . '.' . $_->{battery_id}; + next if ($self->check_filter(section => 'enclosurebattery', instance => $instance)); + $self->{components}->{enclosurebattery}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("enclosure battery '%s' status is '%s' [instance: %s].", + $instance, $_->{status}, + $instance + )); + my $exit = $self->get_severity(label => 'default', section => 'enclosurebattery', value => $_->{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Enclosure battery '%s' status is '%s'", + $instance, $_->{status})); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/components/enclosurecanister.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/enclosurecanister.pm new file mode 100644 index 000000000..41c78f2a2 --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/enclosurecanister.pm @@ -0,0 +1,61 @@ +# +# 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 storage::ibm::storwize::ssh::mode::components::enclosurecanister; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssh_commands} .= 'echo "==========lsenclosurecanister=========="; lsenclosurecanister -delim : ; echo "===============";'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking enclosure canisters"); + $self->{components}->{enclosurecanister} = {name => 'enclosure canisters', total => 0, skip => 0}; + return if ($self->check_filter(section => 'enclosurecanister')); + + return if ($self->{results} !~ /==========lsenclosurecanister==.*?\n(.*?)==============/msi); + my $content = $1; + + my $result = $self->get_hasharray(content => $content, delim => ':'); + foreach (@$result) { + my $instance = $_->{enclosure_id} . '.' . $_->{canister_id}; + next if ($self->check_filter(section => 'enclosurecanister', instance => $instance)); + $self->{components}->{enclosurecanister}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("enclosure canister '%s' status is '%s' [instance: %s].", + $instance, $_->{status}, + $instance + )); + my $exit = $self->get_severity(label => 'default', section => 'enclosurecanister', value => $_->{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Enclosure canister '%s' status is '%s'", + $instance, $_->{status})); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/components/enclosurepsu.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/enclosurepsu.pm new file mode 100644 index 000000000..6f56b3b03 --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/enclosurepsu.pm @@ -0,0 +1,61 @@ +# +# 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 storage::ibm::storwize::ssh::mode::components::enclosurepsu; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssh_commands} .= 'echo "==========lsenclosurepsu=========="; lsenclosurepsu -delim : ; echo "===============";'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking enclosure psus"); + $self->{components}->{enclosurepsu} = {name => 'enclosure psus', total => 0, skip => 0}; + return if ($self->check_filter(section => 'enclosurepsu')); + + return if ($self->{results} !~ /==========lsenclosurepsu==.*?\n(.*?)==============/msi); + my $content = $1; + + my $result = $self->get_hasharray(content => $content, delim => ':'); + foreach (@$result) { + my $instance = $_->{enclosure_id} . '.' . $_->{PSU_id}; + next if ($self->check_filter(section => 'enclosurepsu', instance => $instance)); + $self->{components}->{enclosurepsu}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("enclosure power supply '%s' status is '%s' [instance: %s].", + $instance, $_->{status}, + $instance + )); + my $exit = $self->get_severity(label => 'default', section => 'enclosurepsu', value => $_->{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Enclosure power supply '%s' status is '%s'", + $instance, $_->{status})); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/components/host.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/host.pm new file mode 100644 index 000000000..d82f3ee8a --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/host.pm @@ -0,0 +1,60 @@ +# +# 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 storage::ibm::storwize::ssh::mode::components::host; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssh_commands} .= 'echo "==========lshost=========="; lshost -delim : ; echo "===============";'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking hosts"); + $self->{components}->{host} = {name => 'hosts', total => 0, skip => 0}; + return if ($self->check_filter(section => 'host')); + + return if ($self->{results} !~ /==========lshost==.*?\n(.*?)==============/msi); + my $content = $1; + + my $result = $self->get_hasharray(content => $content, delim => ':'); + foreach (@$result) { + next if ($self->check_filter(section => 'host', instance => $_->{id})); + $self->{components}->{host}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("host '%s' status is '%s' [instance: %s].", + $_->{name}, $_->{status}, + $_->{id} + )); + my $exit = $self->get_severity(label => 'default', section => 'host', value => $_->{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Host '%s' status is '%s'", + $_->{name}, $_->{status})); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/components/mdisk.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/mdisk.pm new file mode 100644 index 000000000..fc6423cad --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/mdisk.pm @@ -0,0 +1,60 @@ +# +# 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 storage::ibm::storwize::ssh::mode::components::mdisk; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssh_commands} .= 'echo "==========lsmdisk=========="; lsmdisk -delim : ; echo "===============";'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking mdisks"); + $self->{components}->{mdisk} = {name => 'mdisks', total => 0, skip => 0}; + return if ($self->check_filter(section => 'mdisk')); + + return if ($self->{results} !~ /==========lsmdisk==.*?\n(.*?)==============/msi); + my $content = $1; + + my $result = $self->get_hasharray(content => $content, delim => ':'); + foreach (@$result) { + next if ($self->check_filter(section => 'mdisk', instance => $_->{id})); + $self->{components}->{mdisk}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("mdisk '%s' status is '%s' [instance: %s].", + $_->{name}, $_->{status}, + $_->{id} + )); + my $exit = $self->get_severity(section => 'mdisk', value => $_->{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("MDisk '%s' status is '%s'", + $_->{name}, $_->{status})); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/components/node.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/node.pm new file mode 100644 index 000000000..cfef24c4b --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/node.pm @@ -0,0 +1,60 @@ +# +# 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 storage::ibm::storwize::ssh::mode::components::node; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssh_commands} .= 'echo "==========lsnode=========="; lsnode -delim : ; echo "===============";'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking nodes"); + $self->{components}->{node} = {name => 'nodes', total => 0, skip => 0}; + return if ($self->check_filter(section => 'node')); + + return if ($self->{results} !~ /==========lsnode==.*?\n(.*?)==============/msi); + my $content = $1; + + my $result = $self->get_hasharray(content => $content, delim => ':'); + foreach (@$result) { + next if ($self->check_filter(section => 'node', instance => $_->{id})); + $self->{components}->{node}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("node '%s' status is '%s' [instance: %s].", + $_->{name}, $_->{status}, + $_->{id} + )); + my $exit = $self->get_severity(label => 'default', section => 'node', value => $_->{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Node '%s' status is '%s'", + $_->{name}, $_->{status})); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/components/portfc.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/portfc.pm new file mode 100644 index 000000000..9d7d6c4e1 --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/portfc.pm @@ -0,0 +1,61 @@ +# +# 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 storage::ibm::storwize::ssh::mode::components::portfc; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssh_commands} .= 'echo "==========lsportfc=========="; lsportfc -delim : ; echo "===============";'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking portfc"); + $self->{components}->{portfc} = {name => 'portfc', total => 0, skip => 0}; + return if ($self->check_filter(section => 'portfc')); + + return if ($self->{results} !~ /==========lsportfc==.*?\n(.*?)==============/msi); + my $content = $1; + + my $result = $self->get_hasharray(content => $content, delim => ':'); + foreach (@$result) { + next if ($self->check_filter(section => 'portfc', instance => $_->{id})); + $self->{components}->{portfc}->{total}++; + + my $name = $_->{node_name} . "." . $_->{WWPN}; + $self->{output}->output_add(long_msg => sprintf("portfc '%s' status is '%s' [instance: %s].", + $name, $_->{status}, + $_->{id} + )); + my $exit = $self->get_severity(section => 'portfc', value => $_->{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("PortFC '%s' status is '%s'", + $name, $_->{status})); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/components/portsas.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/portsas.pm new file mode 100644 index 000000000..34b9f838f --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/portsas.pm @@ -0,0 +1,61 @@ +# +# 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 storage::ibm::storwize::ssh::mode::components::portsas; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssh_commands} .= 'echo "==========lsportsas=========="; lsportsas -delim : ; echo "===============";'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking portsas"); + $self->{components}->{portsas} = {name => 'portsas', total => 0, skip => 0}; + return if ($self->check_filter(section => 'portsas')); + + return if ($self->{results} !~ /==========lsportsas==.*?\n(.*?)==============/msi); + my $content = $1; + + my $result = $self->get_hasharray(content => $content, delim => ':'); + foreach (@$result) { + next if ($self->check_filter(section => 'portsas', instance => $_->{id})); + $self->{components}->{portsas}->{total}++; + + my $name = $_->{node_name} . "." . $_->{WWPN}; + $self->{output}->output_add(long_msg => sprintf("port sas '%s' status is '%s' [instance: %s].", + $name, $_->{status}, + $_->{id} + )); + my $exit = $self->get_severity(section => 'portsas', value => $_->{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Port sas '%s' status is '%s'", + $name, $_->{status})); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/components/quorum.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/quorum.pm new file mode 100644 index 000000000..bf01dcf97 --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/quorum.pm @@ -0,0 +1,60 @@ +# +# 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 storage::ibm::storwize::ssh::mode::components::quorum; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssh_commands} .= 'echo "==========lsquorum=========="; lsquorum -delim : ; echo "===============";'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking quorums"); + $self->{components}->{quorum} = {name => 'quorums', total => 0, skip => 0}; + return if ($self->check_filter(section => 'quorum')); + + return if ($self->{results} !~ /==========lsquorum==.*?\n(.*?)==============/msi); + my $content = $1; + + my $result = $self->get_hasharray(content => $content, delim => ':'); + foreach (@$result) { + next if ($self->check_filter(section => 'quorum', instance => $_->{quorum_index})); + $self->{components}->{quorum}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("quorum '%s' status is '%s' [instance: %s].", + $_->{controller_name}, $_->{status}, + $_->{quorum_index} + )); + my $exit = $self->get_severity(label => 'default', section => 'quorum', value => $_->{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Quorum '%s' status is '%s'", + $_->{controller_name}, $_->{status})); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/components/systemstats.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/systemstats.pm new file mode 100644 index 000000000..180f460e4 --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/systemstats.pm @@ -0,0 +1,63 @@ +# +# 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 storage::ibm::storwize::ssh::mode::components::systemstats; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssh_commands} .= 'echo "==========lssystemstats=========="; lssystemstats ; echo "===============";'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking systemstats"); + $self->{components}->{systemstats} = {name => 'systemstats', total => 0, skip => 0}; + return if ($self->check_filter(section => 'systemstats')); + + return if ($self->{results} !~ /==========lssystemstats==.*?\n(.*?)==============/msi); + my $content = $1; + + my $result = $self->get_hasharray(content => $content, delim => '\s+'); + foreach (@$result) { + next if ($self->check_filter(section => 'systemstats', instance => $_->{stat_name})); + $self->{components}->{systemstats}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("system stat '%s' value is '%s' [instance: %s].", + $_->{stat_name}, $_->{stat_current}, + $_->{stat_name} + )); + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'systemstats', instance => $_->{stat_name}, value => $_->{stat_current}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("System stat '%s' value is '%s'", $_->{stat_name}, $_->{stat_current})); + } + $self->{output}->perfdata_add(label => "sstat_" . $_->{stat_name}, + value => $_->{stat_current}, + warning => $warn, + critical => $crit); + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/components/vdisk.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/vdisk.pm new file mode 100644 index 000000000..9fe8c51f3 --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/components/vdisk.pm @@ -0,0 +1,60 @@ +# +# 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 storage::ibm::storwize::ssh::mode::components::vdisk; + +use strict; +use warnings; + +sub load { + my ($self) = @_; + + $self->{ssh_commands} .= 'echo "==========lsvdisk=========="; lsvdisk -delim : ; echo "===============";'; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking vdisks"); + $self->{components}->{vdisk} = {name => 'vdisks', total => 0, skip => 0}; + return if ($self->check_filter(section => 'vdisk')); + + return if ($self->{results} !~ /==========lsvdisk==.*?\n(.*?)==============/msi); + my $content = $1; + + my $result = $self->get_hasharray(content => $content, delim => ':'); + foreach (@$result) { + next if ($self->check_filter(section => 'vdisk', instance => $_->{id})); + $self->{components}->{vdisk}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("vdisk '%s' status is '%s' [instance: %s].", + $_->{name}, $_->{status}, + $_->{id} + )); + my $exit = $self->get_severity(label => 'default', section => 'vdisk', value => $_->{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Vdisk '%s' status is '%s'", + $_->{name}, $_->{status})); + } + } +} + +1; \ No newline at end of file diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/eventlog.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/eventlog.pm new file mode 100644 index 000000000..2ad93623a --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/eventlog.pm @@ -0,0 +1,219 @@ +# +# 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 storage::ibm::storwize::ssh::mode::eventlog; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use DateTime; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning', }, + "critical:s" => { name => 'critical', }, + "filter-event-id:s" => { name => 'filter_event_id' }, + "filter-message:s" => { name => 'filter_message' }, + "retention:s" => { name => 'retention' }, + "hostname:s" => { name => 'hostname' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } + if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') { + $self->{option_results}->{remote} = 1; + } + + my $last_timestamp = ''; + if (defined($self->{option_results}->{retention}) && $self->{option_results}->{retention} =~ /^\d+$/) { + # by default UTC timezone used + my $dt = DateTime->from_epoch(epoch => time() - $self->{option_results}->{retention}); + my $dt_format = sprintf("%d%02d%02d%02d%02d%02d", substr($dt->year(), 2), $dt->month(), $dt->day(), $dt->hour(), $dt->minute(), $dt->second()); + $last_timestamp = 'last_timestamp>=' . $dt_format . ":"; + } + $self->{ls_command} = "lseventlog -message no -alert yes -filtervalue '${last_timestamp}fixed=no' -delim :"; +} + +sub get_hasharray { + my ($self, %options) = @_; + + my $result = []; + return $result if ($options{content} eq ''); + my ($header, @lines) = split /\n/, $options{content}; + my @header_names = split /$options{delim}/, $header; + + for (my $i = 0; $i <= $#lines; $i++) { + my @content = split /$options{delim}/, $lines[$i]; + my $data = {}; + for (my $j = 0; $j <= $#header_names; $j++) { + $data->{$header_names[$j]} = $content[$j]; + } + push @$result, $data; + } + + return $result; +} + +sub run { + my ($self, %options) = @_; + + my $content = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => defined($self->{option_results}->{command}) && $self->{option_results}->{command} ne '' ? $self->{option_results}->{command} : $self->{ls_command} . " ; exit ;", + command_path => $self->{option_results}->{command_path}, + command_options => defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne '' ? $self->{option_results}->{command_options} : undef); + my $result = $self->get_hasharray(content => $content, delim => ':'); + + my ($num_eventlog_checked, $num_errors) = (0, 0); + foreach (@$result) { + $num_eventlog_checked++; + if (defined($self->{option_results}->{filter_message}) && $self->{option_results}->{filter_message} ne '' && + $_->{description} !~ /$self->{option_results}->{filter_message}/) { + $self->{output}->output_add(long_msg => "skipping '" . $_->{description} . "': no matching filter description.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_event_id}) && $self->{option_results}->{filter_event_id} ne '' && + $_->{event_id} !~ /$self->{option_results}->{filter_event_id}/) { + $self->{output}->output_add(long_msg => "skipping '" . $_->{event_id} . "': no matching filter event id.", debug => 1); + next; + } + + $self->{output}->output_add(long_msg => sprintf("%s : %s - %s", + scalar(localtime($_->{last_timestamp})), + $_->{event_id}, $_->{description} + ) + ); + $num_errors++; + } + + $self->{output}->output_add(long_msg => sprintf("Number of message checked: %s", $num_eventlog_checked)); + my $exit = $self->{perfdata}->threshold_check(value => $num_errors, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("%d problem detected (use verbose for more details)", $num_errors) + ); + $self->{output}->perfdata_add(label => 'problems', + value => $num_errors, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check eventlogs. + +=over 8 + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=item B<--filter-event-id> + +Filter on event id. + +=item B<--filter-message> + +Filter on event message. + +=item B<--retention> + +Get eventlog of X last seconds. For the last minutes: --retention=60 + +=item B<--hostname> + +Hostname to query. + +=item B<--ssh-option> + +Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). + +=item B<--ssh-path> + +Specify ssh command path (default: none) + +=item B<--ssh-command> + +Specify ssh command (default: 'ssh'). Useful to use 'plink'. + +=item B<--timeout> + +Timeout in seconds for the command (Default: 30). + +=item B<--sudo> + +Use 'sudo' to execute the command. + +=item B<--command> + +Command to get information. Used it you have output in a file. + +=item B<--command-path> + +Command path. + +=item B<--command-options> + +Command options. + +=back + +=cut + \ No newline at end of file diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/hardware.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/hardware.pm new file mode 100644 index 000000000..89a1bb718 --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/hardware.pm @@ -0,0 +1,214 @@ +# +# 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 storage::ibm::storwize::ssh::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = + '^(array|drive|enclosure|enclosurebattery|enclosurecanister|enclosurepsu|host|portfc|portsas|vdisk|node|quorum|mdisk)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(systemstats)$'; + + $self->{cb_hook2} = 'ssh_execute'; + + $self->{thresholds} = { + default => [ + ['online', 'OK'], + ['offline', 'CRITICAL'], + ['degraded', 'WARNING'], + ['excluded', 'OK'], # lsarray + ['mask', 'OK'], # lshost + ], + portfc => [ + ['active', 'OK'], + ['inactive_unconfigured', 'OK'], + ['.*', 'CRITICAL'], + ], + portsas => [ + ['online', 'OK'], + ['offline_unconfigured', 'OK'], + ['excluded', 'OK'], + ['offline', 'CRITICAL'], + ['degraded', 'WARNING'], + ], + mdisk => [ + ['online', 'OK'], + ['excluded', 'OK'], + ['offline', 'CRITICAL'], + ['degraded_paths', 'WARNING'], + ['degraded_ports', 'WARNING'], + ['degraded', 'WARNING'], + ], + }; + + $self->{components_path} = 'storage::ibm::storwize::ssh::mode::components'; + $self->{components_module} = ['array', 'drive', 'enclosure', 'enclosurebattery', 'enclosurecanister', + 'enclosurepsu', 'host', 'portfc', 'portsas', 'vdisk', 'node', 'quorum', 'mdisk', 'systemstats']; +} + +sub ssh_execute { + my ($self, %options) = @_; + + $self->{results} = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => defined($self->{option_results}->{command}) && $self->{option_results}->{command} ne '' ? $self->{option_results}->{command} : $self->{ssh_commands} . " exit ;", + command_path => $self->{option_results}->{command_path}, + command_options => defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne '' ? $self->{option_results}->{command_options} : undef); +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') { + $self->{option_results}->{remote} = 1; + } +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "hostname:s" => { name => 'hostname' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options' }, + }); + + $self->{ssh_commands} = ''; + return $self; +} + +sub get_hasharray { + my ($self, %options) = @_; + + my $result = []; + return $result if ($options{content} eq ''); + my ($header, @lines) = split /\n/, $options{content}; + my @header_names = split /$options{delim}/, $header; + + for (my $i = 0; $i <= $#lines; $i++) { + my @content = split /$options{delim}/, $lines[$i]; + my $data = {}; + for (my $j = 0; $j <= $#header_names; $j++) { + $data->{$header_names[$j]} = $content[$j]; + } + push @$result, $data; + } + + return $result; +} + +1; + +__END__ + +=head1 MODE + +Check components. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'array', 'drive'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=host --filter=enclosurecanister) +Can also exclude specific instance: --filter=host,10 + +=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='host,.*,OK,degraded' + +=item B<--warning> + +Set warning threshold for temperatures (syntax: type,regexp,threshold) +Example: --warning='systemstats,cpu_pc,30' + +=item B<--critical> + +Set critical threshold for temperatures (syntax: type,regexp,threshold) +Example: --critical='systemstats,cpu_pc,40' + +=item B<--hostname> + +Hostname to query. + +=item B<--ssh-option> + +Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). + +=item B<--ssh-path> + +Specify ssh command path (default: none) + +=item B<--ssh-command> + +Specify ssh command (default: 'ssh'). Useful to use 'plink'. + +=item B<--timeout> + +Timeout in seconds for the command (Default: 30). + +=item B<--sudo> + +Use 'sudo' to execute the command. + +=item B<--command> + +Command to get information. Used it you have output in a file. + +=item B<--command-path> + +Command path. + +=item B<--command-options> + +Command options. + +=back + +=cut diff --git a/centreon-plugins/storage/ibm/storwize/ssh/mode/poolusage.pm b/centreon-plugins/storage/ibm/storwize/ssh/mode/poolusage.pm new file mode 100644 index 000000000..19437b6be --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/mode/poolusage.pm @@ -0,0 +1,349 @@ +# +# 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 storage::ibm::storwize::ssh::mode::poolusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'status : ' . $self->{result_values}->{status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $label = 'used'; + my $value_perf = $self->{result_values}->{used}; + if (defined($instance_mode->{option_results}->{free})) { + $label = 'free'; + $value_perf = $self->{result_values}->{free}; + } + my $extra_label = ''; + $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); + if ($instance_mode->{option_results}->{units} eq '%') { + $total_options{total} = $self->{result_values}->{total}; + $total_options{cast_int} = 1; + } + + $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my ($exit, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + my $msg = sprintf("Usage Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => '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 => 'status' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'usage', set => { + key_values => [ { name => 'display' }, { name => 'used' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /degraded/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /offline/i' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "hostname:s" => { name => 'hostname' }, + "ssh-option:s@" => { name => 'ssh_option' }, + "ssh-path:s" => { name => 'ssh_path' }, + "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') { + $self->{option_results}->{remote} = 1; + } + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_pool_output { + my ($self, %options) = @_; + + return "Pool '" . $options{instance_value}->{display} . "' "; +} + +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 manage_selection { + my ($self, %options) = @_; + + $self->{pool} = {}; + my $content = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => defined($self->{option_results}->{command}) && $self->{option_results}->{command} ne '' ? $self->{option_results}->{command} : "lsmdiskgrp -delim : -bytes ; exit ;", + command_path => $self->{option_results}->{command_path}, + command_options => defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne '' ? $self->{option_results}->{command_options} : undef); + my $result = $self->get_hasharray(content => $content, delim => ':'); + foreach (@$result) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $_->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $_->{name} . "': no matching filter.", debug => 1); + next; + } + + $self->{pool}->{$_->{id}} = { display => $_->{name}, + status => $_->{status}, + total => $_->{used_capacity} + $_->{free_capacity}, used => $_->{used_capacity} + }; + } + + if (scalar(keys %{$self->{pool}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No pool found."); + $self->{output}->option_exit(); + } +} + +sub get_hasharray { + my ($self, %options) = @_; + + my $result = []; + return $result if ($options{content} eq ''); + my ($header, @lines) = split /\n/, $options{content}; + my @header_names = split /$options{delim}/, $header; + + for (my $i = 0; $i <= $#lines; $i++) { + my @content = split /$options{delim}/, $lines[$i]; + my $data = {}; + for (my $j = 0; $j <= $#header_names; $j++) { + $data->{$header_names[$j]} = $content[$j]; + } + push @$result, $data; + } + + return $result; +} + +1; + +__END__ + +=head1 MODE + +Check pool usages. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^status$' + +=item B<--filter-name> + +Filter pool name (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{status} =~ /degraded/i'). +Can used special variables like: %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /offline/i'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'usage'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'usage'. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + +=item B<--free> + +Thresholds are on free space left. + +=item B<--hostname> + +Hostname to query. + +=item B<--ssh-option> + +Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). + +=item B<--ssh-path> + +Specify ssh command path (default: none) + +=item B<--ssh-command> + +Specify ssh command (default: 'ssh'). Useful to use 'plink'. + +=item B<--timeout> + +Timeout in seconds for the command (Default: 30). + +=item B<--sudo> + +Use 'sudo' to execute the command. + +=item B<--command> + +Command to get information. Used it you have output in a file. + +=item B<--command-path> + +Command path. + +=item B<--command-options> + +Command options. + +=back + +=cut diff --git a/centreon-plugins/storage/ibm/storwize/ssh/plugin.pm b/centreon-plugins/storage/ibm/storwize/ssh/plugin.pm new file mode 100644 index 000000000..59d8ca86a --- /dev/null +++ b/centreon-plugins/storage/ibm/storwize/ssh/plugin.pm @@ -0,0 +1,50 @@ +# +# 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 storage::ibm::storwize::ssh::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_simple); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'components' => 'storage::ibm::storwize::ssh::mode::hardware', + 'pool-usage' => 'storage::ibm::storwize::ssh::mode::poolusage', + 'eventlog' => 'storage::ibm::storwize::ssh::mode::eventlog', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check IBM Storwize (v3700, v5000, v7000, SAN Volume Controller) in SSH. + +=cut diff --git a/centreon-plugins/storage/lenovo/sseries/snmp/plugin.pm b/centreon-plugins/storage/lenovo/sseries/snmp/plugin.pm new file mode 100644 index 000000000..f7eb9ec1f --- /dev/null +++ b/centreon-plugins/storage/lenovo/sseries/snmp/plugin.pm @@ -0,0 +1,50 @@ +# +# 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 storage::lenovo::sseries::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'hardware' => 'snmp_standard::mode::hardwarefibrealliance', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Lenovo Storage S Series (S2200 and S3200) in SNMP. + +=cut