diff --git a/hardware/sensors/hwgste/snmp/mode/components/humidity.pm b/hardware/sensors/hwgste/snmp/mode/components/humidity.pm new file mode 100644 index 000000000..25e4437d9 --- /dev/null +++ b/hardware/sensors/hwgste/snmp/mode/components/humidity.pm @@ -0,0 +1,70 @@ +# +# 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 hardware::sensors::hwgste::snmp::mode::components::humidity; + +use strict; +use warnings; +use hardware::sensors::hwgste::snmp::mode::components::resources qw($mapping); + +my $oid_sensEntry = '.1.3.6.1.4.1.21796.4.1.3.1'; + +sub load {} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking humidity"); + $self->{components}->{humidity} = {name => 'humidity', total => 0, skip => 0}; + return if ($self->check_filter(section => 'humidity')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_sensEntry}})) { + next if ($oid !~ /^$mapping->{sensState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_sensEntry}, instance => $instance); + + next if (!(defined($result->{sensUnit}) && $result->{sensUnit} eq '%')); + next if ($self->check_filter(section => 'humidity', instance => $instance)); + $self->{components}->{humidity}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("humidity '%s' state is '%s' [instance: %s, value: %s]", + $result->{sensName}, $result->{sensState}, $instance, $result->{sensTemp})); + my $exit = $self->get_severity(section => 'humidity', label => 'default', + instance => $instance, value => $result->{sensState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("humidity '%s' state is '%s'", $result->{sensName}, $result->{sensState})); + } + + if ($result->{sensTemp} =~ /\d+/) { + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'humidity', instance => $instance, value => $result->{sensTemp}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("humidity '%s' value is %s %s", $result->{sensName}, $result->{sensTemp}, $result->{sensUnit})); + } + $self->{output}->perfdata_add(label => 'sensor_' . $result->{sensName}, unit => $result->{sensUnit}, + value => $result->{sensTemp}, + warning => $warn, + critical => $crit, min => 0, max => 100); + } + } +} + +1; \ No newline at end of file diff --git a/hardware/sensors/hwgste/snmp/mode/components/resources.pm b/hardware/sensors/hwgste/snmp/mode/components/resources.pm new file mode 100644 index 000000000..197d6a8a8 --- /dev/null +++ b/hardware/sensors/hwgste/snmp/mode/components/resources.pm @@ -0,0 +1,57 @@ +# +# 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 hardware::sensors::hwgste::snmp::mode::components::resources; + +use strict; +use warnings; +use Exporter; + +our %map_sens_unit; +our %map_sens_state; +our $mapping; + +our @ISA = qw(Exporter); +our @EXPORT_OK = qw($mapping); + +%map_sens_state = ( + 0 => 'invalid', + 1 => 'normal', + 2 => 'outOfRangeLo', + 3 => 'outOfRangeHi', + 4 => 'alarmLo', + 5 => 'alarmHi', +); +%map_sens_unit = ( + 0 => '', # none + 1 => 'C', + 2 => 'F', + 3 => 'K', + 4 => '%', +); + +$mapping = { + sensName => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.2' }, + sensState => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.3', map => \%map_sens_state }, + sensTemp => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.4' }, + sensUnit => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.7', map => \%map_sens_unit }, +}; + +1; \ No newline at end of file diff --git a/hardware/sensors/hwgste/snmp/mode/components/temperature.pm b/hardware/sensors/hwgste/snmp/mode/components/temperature.pm new file mode 100644 index 000000000..6df7dadea --- /dev/null +++ b/hardware/sensors/hwgste/snmp/mode/components/temperature.pm @@ -0,0 +1,70 @@ +# +# 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 hardware::sensors::hwgste::snmp::mode::components::temperature; + +use strict; +use warnings; +use hardware::sensors::hwgste::snmp::mode::components::resources qw($mapping); + +my $oid_sensEntry = '.1.3.6.1.4.1.21796.4.1.3.1'; + +sub load {} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking temperature"); + $self->{components}->{temperature} = {name => 'temperature', total => 0, skip => 0}; + return if ($self->check_filter(section => 'temperature')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_sensEntry}})) { + next if ($oid !~ /^$mapping->{sensState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_sensEntry}, instance => $instance); + + next if (!(defined($result->{sensUnit}) && $result->{sensUnit} =~ /C|F|K/i)); + next if ($self->check_filter(section => 'temperature', instance => $instance)); + $self->{components}->{temperature}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("temperature '%s' state is '%s' [instance: %s, value: %s]", + $result->{sensName}, $result->{sensState}, $instance, $result->{sensTemp})); + my $exit = $self->get_severity(section => 'temperature', label => 'default', + instance => $instance, value => $result->{sensState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("temperature '%s' state is '%s'", $result->{sensName}, $result->{sensState})); + } + + if ($result->{sensTemp} =~ /\d+/) { + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{sensTemp}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("temperature '%s' value is %s %s", $result->{sensName}, $result->{sensTemp}, $result->{sensUnit})); + } + $self->{output}->perfdata_add(label => 'sensor_' . $result->{sensName}, unit => $result->{sensUnit}, + value => $result->{sensTemp}, + warning => $warn, + critical => $crit); + } + } +} + +1; \ No newline at end of file diff --git a/hardware/sensors/hwgste/snmp/mode/sensors.pm b/hardware/sensors/hwgste/snmp/mode/sensors.pm index 87a05108c..5794707b0 100644 --- a/hardware/sensors/hwgste/snmp/mode/sensors.pm +++ b/hardware/sensors/hwgste/snmp/mode/sensors.pm @@ -20,226 +20,54 @@ package hardware::sensors::hwgste::snmp::mode::sensors; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -use centreon::plugins::values; -my $thresholds = { - sensor => [ - ['invalid', 'UNKNOWN'], - ['normal', 'OK'], - ['outOfRangeLo', 'WARNING'], - ['outOfRangeHi', 'WARNING'], - ['alarmLo', 'CRITICAL'], - ['alarmHi', 'CRITICAL'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(temperature|humidity)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|humidity)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + default => [ + ['invalid', 'UNKNOWN'], + ['normal', 'OK'], + ['outOfRangeLo', 'WARNING'], + ['outOfRangeHi', 'WARNING'], + ['alarmLo', 'CRITICAL'], + ['alarmHi', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'hardware::sensors::hwgste::snmp::mode::components'; + $self->{components_module} = ['temperature', 'humidity']; +} -my %map_temp_status = ( - 0 => 'invalid', - 1 => 'normal', - 2 => 'outOfRangeLo', - 3 => 'outOfRangeHi', - 4 => 'alarmLo', - 5 => 'alarmHi', -); -my %map_temp_unit = ( - 0 => '', # none - 1 => 'C', - 2 => 'F', - 3 => 'K', - 4 => '%', -); - -my $mapping = { - sensName => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.2' }, - sensState => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.3', map => \%map_temp_status }, - sensTemp => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.4' }, - sensUnit => { oid => '.1.3.6.1.4.1.21796.4.1.3.1.7', map => \%map_temp_unit }, -}; +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + my $oid_sensEntry = '.1.3.6.1.4.1.21796.4.1.3.1'; + push @{$self->{request}}, { oid => $oid_sensEntry }; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1); bless $self, $class; - - $self->{version} = '0.9'; + + $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "filter:s@" => { name => 'filter' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { }); - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - $self->{filter} = []; - foreach my $val (@{$self->{option_results}->{filter}}) { - next if (!defined($val) || $val eq ''); - my @values = split (/,/, $val); - push @{$self->{filter}}, { filter => $values[0], instance => $values[1] }; - } - $self->{overload_th} = {}; - foreach my $val (@{$self->{option_results}->{threshold_overload}}) { - next if (!defined($val) || $val eq ''); - my @values = split (/,/, $val); - if (scalar(@values) < 3) { - $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $instance, $status, $filter); - if (scalar(@values) == 3) { - ($section, $status, $filter) = @values; - $instance = '.*'; - } else { - ($section, $instance, $status, $filter) = @values; - } - if ($self->{output}->is_litteral_status(status => $status) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); - $self->{output}->option_exit(); - } - $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); - push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status, instance => $instance }; - } - - $self->{numeric_threshold} = {}; - foreach my $option (('warning', 'critical')) { - foreach my $val (@{$self->{option_results}->{$option}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $regexp, $value) = ($1, $2, $3); - if ($section !~ /^(sensor)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "' (type must be: sensor)."); - $self->{output}->option_exit(); - } - my $position = 0; - if (defined($self->{numeric_threshold}->{$section})) { - $position = scalar(@{$self->{numeric_threshold}->{$section}}); - } - if (($self->{perfdata}->threshold_validate(label => $option . '-' . $section . '-' . $position, value => $value)) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong $option threshold '" . $value . "'."); - $self->{output}->option_exit(); - } - $self->{numeric_threshold}->{$section} = [] if (!defined($self->{numeric_threshold}->{$section})); - push @{$self->{numeric_threshold}->{$section}}, { label => $option . '-' . $section . '-' . $position, threshold => $option, regexp => $regexp }; - } - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->{index} = {}; - my $oid_sensEntry = '.1.3.6.1.4.1.21796.4.1.3.1'; - - $self->{results} = $self->{snmp}->get_table(oid => $oid_sensEntry, nothing_quit => 1); - foreach my $oid (keys %{$self->{results}}) { - next if ($oid !~ /$mapping->{sensState}->{oid}\.(\d+)$/); - my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); - - next if ($self->check_filter(section => 'sensor', instance => $instance)); - - $self->{output}->output_add(long_msg => sprintf("Sensor '%s' state is '%s' [instance: %s, value: %s]", - $result->{sensName}, $result->{sensState}, $instance, $result->{sensTemp})); - my $exit = $self->get_severity(section => 'sensor', - instance => $instance, value => $result->{sensState}); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Sensor '%s' state is '%s'", $result->{sensName}, $result->{sensState})); - } - - if ($result->{sensTemp} =~ /\d+/) { - my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'sensor', instance => $instance, value => $result->{sensTemp}); - if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit2, - short_msg => sprintf("Sensor '%s' value is %s %s", $result->{sensName}, $result->{sensTemp}, $result->{sensUnit})); - } - $self->{output}->perfdata_add(label => 'sensor_' . $result->{sensName}, unit => $result->{sensUnit}, - value => $result->{sensTemp}, - warning => $warn, - critical => $crit); - } - } - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All sensors are ok.")); - $self->{output}->display(); - $self->{output}->exit(); -} - -sub check_filter { - my ($self, %options) = @_; - - foreach (@{$self->{filter}}) { - if ($options{section} =~ /$_->{filter}/) { - if (!defined($options{instance}) && !defined($_->{instance})) { - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); - return 1; - } elsif (defined($options{instance}) && $options{instance} =~ /$_->{instance}/) { - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); - return 1; - } - } - } - - return 0; -} - - -sub get_severity_numeric { - my ($self, %options) = @_; - my $status = 'OK'; # default - my $thresholds = { warning => undef, critical => undef }; - my $checked = 0; - - if (defined($self->{numeric_threshold}->{$options{section}})) { - my $exits = []; - foreach (@{$self->{numeric_threshold}->{$options{section}}}) { - if ($options{instance} =~ /$_->{regexp}/) { - push @{$exits}, $self->{perfdata}->threshold_check(value => $options{value}, threshold => [ { label => $_->{label}, exit_litteral => $_->{threshold} } ]); - $thresholds->{$_->{threshold}} = $self->{perfdata}->get_perfdata_for_output(label => $_->{label}); - $checked = 1; - } - } - $status = $self->{output}->get_most_critical(status => $exits) if (scalar(@{$exits}) > 0); - } - - return ($status, $thresholds->{warning}, $thresholds->{critical}, $checked); -} - -sub get_severity { - my ($self, %options) = @_; - my $status = 'UNKNOWN'; # default - - if (defined($self->{overload_th}->{$options{section}})) { - foreach (@{$self->{overload_th}->{$options{section}}}) { - if ($options{value} =~ /$_->{filter}/i && - (!defined($options{instance}) || $options{instance} =~ /$_->{instance}/)) { - $status = $_->{status}; - return $status; - } - } - } - my $label = defined($options{label}) ? $options{label} : $options{section}; - foreach (@{$thresholds->{$label}}) { - if ($options{value} =~ /$$_[0]/i) { - $status = $$_[1]; - return $status; - } - } - - return $status; + return $self; } 1; @@ -252,6 +80,11 @@ Check HWg-STE sensors. =over 8 +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'temperature', 'humidity'. + =item B<--filter> Exclude some parts. @@ -265,13 +98,13 @@ Example: --threshold-overload='sensor,CRITICAL,^(?!(normal)$)' =item B<--warning> -Set warning threshold for temperatures (syntax: type,instance,threshold) -Example: --warning='sensor,.*,30' +Set warning threshold for temperature, humidity (syntax: type,instance,threshold) +Example: --warning='temperature,.*,30' =item B<--critical> -Set critical threshold for temperatures (syntax: type,instance,threshold) -Example: --critical='sensor,.*,40' +Set critical threshold for temperature, humidity (syntax: type,instance,threshold) +Example: --critical='humidty,.*,40' =back