break change: refacto hddtemp plugin

This commit is contained in:
garnier-quentin 2020-04-02 16:31:23 +02:00 committed by Lotfi zaouche
parent 7d8165d521
commit d749650aba
12 changed files with 744 additions and 611 deletions

264
apps/hddtemp/custom/cli.pm Normal file
View File

@ -0,0 +1,264 @@
#
# Copyright 2020 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::hddtemp::custom::cli;
use strict;
use warnings;
use centreon::plugins::ssh;
use centreon::plugins::misc;
sub new {
my ($class, %options) = @_;
my $self = {};
bless $self, $class;
if (!defined($options{output})) {
print "Class Custom: Need to specify 'output' argument.\n";
exit 3;
}
if (!defined($options{options})) {
$options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument.");
$options{output}->option_exit();
}
if (!defined($options{noptions})) {
$options{options}->add_options(arguments => {
'hostname:s' => { name => 'hostname' },
'timeout:s' => { name => 'timeout', default => 45 },
'command-drives:s' => { name => 'command_drives' },
'command-path-drives:s' => { name => 'command_path_drives' },
'command-options-drives:s' => { name => 'command_options_drives' },
'command-hddtemp:s' => { name => 'command_hddtemp' },
'command-path-hddtemp:s' => { name => 'command_path_hddtemp' },
'command-options-hddtemp:s' => { name => 'command_options_hddtemp' },
'sudo:s' => { name => 'sudo' }
});
}
$options{options}->add_help(package => __PACKAGE__, sections => 'CLI OPTIONS', once => 1);
$self->{output} = $options{output};
$self->{mode} = $options{mode};
$self->{ssh} = centreon::plugins::ssh->new(%options);
return $self;
}
sub set_options {
my ($self, %options) = @_;
$self->{option_results} = $options{option_results};
}
sub set_defaults {
my ($self, %options) = @_;
foreach (keys %{$options{default}}) {
if ($_ eq $self->{mode}) {
for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) {
foreach my $opt (keys %{$options{default}->{$_}[$i]}) {
if (!defined($self->{option_results}->{$opt}[$i])) {
$self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt};
}
}
}
}
}
}
sub check_options {
my ($self, %options) = @_;
if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') {
$self->{ssh}->check_options(option_results => $self->{option_results});
}
return 0;
}
sub list_drives {
my ($self, %options) = @_;
my $stdout;
if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') {
($stdout) = $self->{ssh}->execute(
hostname => $self->{option_results}->{hostname},
command => defined($self->{option_results}->{command_drives}) && $self->{option_results}->{command_drives} ne '' ? $self->{option_results}->{command_drives} : 'lsblk',
command_path => $self->{option_results}->{command_path_drives},
command_options => defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options_drives} ne '' ? $self->{option_results}->{command_options_drives} : '-I 8 -d -o NAME -p -n',
timeout => $self->{option_results}->{timeout}
);
} else {
($stdout) = centreon::plugins::misc::execute(
output => $self->{output},
options => { timeout => $self->{option_results}->{timeout} },
command => defined($self->{option_results}->{command_drives}) && $self->{option_results}->{command_drives} ne '' ? $self->{option_results}->{command_drives} : 'lsblk',
command_path => $self->{option_results}->{command_path_drives},
command_options => defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options_drives} ne '' ? $self->{option_results}->{command_options_drives} : '-I 8 -d -o NAME -p -n'
);
}
$self->{output}->output_add(long_msg => "command response: $stdout", debug => 1);
my $drives = {};
$drives->{$_} = {} foreach (split /\n/, $stdout);
return $drives;
}
sub get_drives_information {
my ($self, %options) = @_;
my $drives = $self->list_drives();
my $cmd_options = '-u C ' . join(' ', keys %$drives);
my ($stdout, $exit_code);
if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') {
($stdout, $exit_code) = $self->{ssh}->execute(
hostname => $self->{option_results}->{hostname},
sudo => $self->{option_results}->{sudo},
command => defined($self->{option_results}->{command_hddtemp}) && $self->{option_results}->{command_hddtemp} ne '' ? $self->{option_results}->{command_hddtemp} : 'hddtemp',
command_path => $self->{option_results}->{command_path_hddtemp},
command_options => defined($self->{option_results}->{command_options_hddtemp}) && $self->{option_results}->{command_options_hddtemp} ne '' ? $self->{option_results}->{command_options_hddtemp} : $cmd_options,
timeout => $self->{option_results}->{timeout},
no_quit => 1
);
} else {
($stdout, $exit_code) = centreon::plugins::misc::execute(
output => $self->{output},
options => { timeout => $self->{option_results}->{timeout} },
sudo => $self->{option_results}->{sudo},
command => defined($self->{option_results}->{command_hddtemp}) && $self->{option_results}->{command_hddtemp} ne '' ? $self->{option_results}->{command_hddtemp} : 'hddtemp',
command_path => $self->{option_results}->{command_path_hddtemp},
command_options => defined($self->{option_results}->{command_options_hddtemp}) && $self->{option_results}->{command_options_hddtemp} ne '' ? $self->{option_results}->{command_options_hddtemp} : $cmd_options . ' 2> /dev/null',
no_quit => 1,
);
}
# exit values can be: 0/1. Need root permissions.
if ($exit_code != 0 && $exit_code != 1) {
$self->{output}->add_option_msg(short_msg => sprintf('command execution error [exit code: %s]', $exit_code));
$self->{output}->option_exit();
}
# OK:
# /dev/sda: SanDisk ...: 32 C
# ERROR:
# message on stderr. So if we don't catch stderr and we have nothing, surely error. for example:
# /dev/sda: open: Permission denied
# UNKNOWN:
# /dev/sda: SanDisk ...: no sensor
# SLEEP:
# /dev/sda: SanDisk ...: drive is sleeping
# NOSENSOR:
# /dev/sda: SanDisk ...: drive supported, but it doesn't have a temperature sensor
# NOT_APPLICABLE:
# /dev/sda: SanDisk ...: misc message
foreach my $name (keys %$drives) {
if ($stdout =~ /^$name:.*?:\s+(\d+).*?C/m) {
$drives->{$name}->{status} = 'ok';
$drives->{$name}->{temperature_unit} = 'C';
$drives->{$name}->{temperature} = $1;
} elsif ($stdout =~ /^$name:.*?:\s+(.*)$/m) {
my $message = $1;
$drives->{$name}->{status} = 'notApplicable';
$drives->{$name}->{status} = 'unknown' if ($message =~ /no sensor/i);
$drives->{$name}->{status} = 'driveSleep' if ($message =~ /drive is sleeping/i);
$drives->{$name}->{status} = 'noSensor' if ($message =~ /drive supported, but it doesn't have a temperature sensor/i);
} else {
$drives->{$name}->{status} = 'error';
}
}
return $drives;
}
1;
__END__
=head1 NAME
ssh
=head1 SYNOPSIS
my ssh
=head1 CLI OPTIONS
=over 8
=item B<--hostname>
Hostname to query (ssh mode).
=item B<--timeout>
Timeout in seconds for the command (Default: 45).
=item You can override command for drives listing.
By default, we use 'lsblk -I 8 -d -o NAME -p -n':
=over 16
=item B<--command-drives>
Command to get information. Used it you have output in a file.
=item B<--command-path-drives>
Command path.
=item B<--command-options-drives>
Command options.
=back
=item You can override command hddtemp used.
By default, we use 'hddtemp -u C /dev/sda /dev/sdb ...' built with the result of drives command:
=over 16
=item B<--command-hddtemp>
Command to get information. Used it you have output in a file.
=item B<--command-path-hddtemp>
Command path.
=item B<--command-options-hddtemp>
Command options.
=item B<--sudo>
Sudo hddtemp command.
=back
=back
=head1 DESCRIPTION
B<custom>.
=cut

198
apps/hddtemp/custom/tcp.pm Normal file
View File

@ -0,0 +1,198 @@
#
# Copyright 2020 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::hddtemp::custom::tcp;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
use IO::Socket;
sub new {
my ($class, %options) = @_;
my $self = {};
bless $self, $class;
if (!defined($options{output})) {
print "Class Custom: Need to specify 'output' argument.\n";
exit 3;
}
if (!defined($options{options})) {
$options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument.");
$options{output}->option_exit();
}
if (!defined($options{noptions})) {
$options{options}->add_options(arguments => {
'hostname:s' => { name => 'hostname' },
'port:s' => { name => 'port' },
'timeout:s' => { name => 'timeout' }
});
}
$options{options}->add_help(package => __PACKAGE__, sections => 'CUSTOM TCP OPTIONS', once => 1);
$self->{output} = $options{output};
$self->{mode} = $options{mode};
return $self;
}
sub set_options {
my ($self, %options) = @_;
$self->{option_results} = $options{option_results};
}
sub set_defaults {
my ($self, %options) = @_;
foreach (keys %{$options{default}}) {
if ($_ eq $self->{mode}) {
for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) {
foreach my $opt (keys %{$options{default}->{$_}[$i]}) {
if (!defined($self->{option_results}->{$opt}[$i])) {
$self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt};
}
}
}
}
}
}
sub check_options {
my ($self, %options) = @_;
$self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : '';
$self->{port} = (defined($self->{option_results}->{port})) && $self->{option_results}->{port} =~ /(\d+)/ ? $1 : 7634;
$self->{timeout} = (defined($self->{option_results}->{timeout})) && $self->{option_results}->{timeout} =~ /(\d+)/ ? $1 : 30;
if ($self->{hostname} eq '') {
$self->{output}->add_option_msg(short_msg => 'Need to specify --hostname option.');
$self->{output}->option_exit();
}
return 0;
}
sub get_hddtemp_drives {
my ($self, %options) = @_;
my $socket = new IO::Socket::INET(
Proto => 'tcp',
PeerAddr => $self->{hostname},
PeerPort => $self->{port},
Timeout => $self->{timeout}
);
if (!defined($socket)) {
$self->{output}->add_option_msg(short_msg => "could not connect: $@");
$self->{output}->option_exit();
}
my $line;
eval {
local $SIG{ALRM} = sub { die 'Timeout'; };
alarm($self->{timeout});
$line = <$socket>;
alarm(0);
};
$socket->shutdown(2);
if ($@) {
$self->{output}->add_option_msg(short_msg => 'cannot get informations: ' . $@);
$self->{output}->option_exit();
}
return $line;
}
sub list_drives {
my ($self, %options) = @_;
my $line = $self->get_hddtemp_drives();
my $drives = {};
while ($line =~ /\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|/msg) {
$drives->{$1} = {};
}
return $drives;
}
sub get_drives_information {
my ($self, %options) = @_;
my $line = $self->get_hddtemp_drives();
#|/dev/sda|SanDisk ....|33|C|
#|/dev/sda|Scan .... |NA|*|
my $mapping_errors = {
NA => 'notApplicable',
UNK => 'unknown',
NOS => 'noSensor',
SLP => 'driveSleep',
ERR => 'error'
};
my $drives = {};
while ($line =~ /\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|/msg) {
my ($name, $value, $unit) = ($1, $3, $4);
if ($value =~ /\d+/) {
$drives->{$name} = { temperature => $value, temperature_unit => $unit, status => 'ok' };
} else {
$drives->{$name} = { status => $mapping_errors->{$value} };
}
}
return $drives;
}
1;
__END__
=head1 NAME
Hddtemp
=head1 CUSTOM TCP OPTIONS
Hddtemp tcp
=over 8
=item B<--hostname>
Hostname or IP address.
=item B<--port>
Port used (Default: 7634)
=item B<--timeout>
Set timeout in seconds (Default: 30).
=back
=head1 DESCRIPTION
B<custom>.
=cut

View File

@ -1,184 +0,0 @@
#
# Copyright 2020 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::hddtemp::local::mode::temperature;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
use centreon::plugins::misc;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments =>
{
"hostname:s" => { name => 'hostname' },
"remote" => { name => 'remote' },
"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', default => 'hddtemp' },
"command-path:s" => { name => 'command_path', default => '/usr/sbin' },
"command-options:s" => { name => 'command_options', default => '-u' },
"warning:s" => { name => 'warning' },
"critical:s" => { name => 'critical' },
"disks:s" => { name => 'disks' },
"unit:s" => { name => 'unit', default => 'C' }
});
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->{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->{critical} . "'.");
$self->{output}->option_exit();
}
if (!defined($self->{option_results}->{disks}) || $self->{option_results}->{disks} eq '') {
$self->{output}->add_option_msg(short_msg => "Need to specify hdd (ex. /dev/sda).");
$self->{output}->option_exit();
}
#### Create command_options
if (defined($self->{option_results}->{unit})) {
$self->{option_results}->{command_options} .= $self->{option_results}->{unit};
}
$self->{option_results}->{command_options} .= ' ' . $self->{option_results}->{disks};
$self->{option_results}->{command_options} .= ' 2>&1';
}
sub run {
my ($self, %options) = @_;
my $total_size = 0;
my $stdout = centreon::plugins::misc::execute(output => $self->{output},
options => $self->{option_results},
sudo => $self->{option_results}->{sudo},
command => $self->{option_results}->{command},
command_path => $self->{option_results}->{command_path},
command_options => $self->{option_results}->{command_options});
$self->{output}->output_add(severity => 'OK',
short_msg => "All temperatures are ok.");
foreach (split(/\n/, $stdout)) {
next if (!/(.*): (.*): ([0-9]*)/);
my ($disk, $model, $temp) = ($1, $2, $3);
my $exit_code = $self->{perfdata}->threshold_check(value => $temp,
threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]);
$self->{output}->output_add(long_msg => sprintf("%s: %s", $disk, $temp . '°' . $self->{option_results}->{unit}));
if (!$self->{output}->is_status(litteral => 1, value => $exit_code, compare => 'ok')) {
$self->{output}->output_add(severity => $exit_code,
short_msg => sprintf("'%s' temp is %s", $disk, $temp . '°' . $self->{option_results}->{unit}));
}
$self->{output}->perfdata_add(label => $disk, unit => $self->{option_results}->{unit},
value => $temp,
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 hdd temperature with hddtemp.
=over 8
=item B<--disks>
Disks to check (ex: /dev/sda)
=item B<--unit>
Temperature unit (default: C).
=item B<--warning>
Threshold warning in °.
=item B<--critical>
Threshold critical in °.
=item B<--remote>
Execute command remotely in 'ssh'.
=item B<--hostname>
Hostname to query (need --remote).
=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 (Default: 'hddtemp').
Can be changed if you have output in a file.
=item B<--command-path>
Command path (Default: '/usr/sbin').
=item B<--command-options>
Command options (Default: '-u').
=back
=cut

View File

@ -1,48 +0,0 @@
#
# Copyright 2020 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::hddtemp::local::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} = '0.1';
%{$self->{modes}} = (
'temperature' => 'apps::hddtemp::local::mode::temperature',
);
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check Linux through local commands (the plugin can use SSH).
=cut

View File

@ -0,0 +1,97 @@
#
# Copyright 2020 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::hddtemp::mode::listdrives;
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;
$options{options}->add_options(arguments => {});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub manage_selection {
my ($self, %options) = @_;
return $options{custom}->list_drives();
}
sub run {
my ($self, %options) = @_;
my $drives = $self->manage_selection(%options);
foreach (sort keys %$drives) {
$self->{output}->output_add(long_msg =>
sprintf(
'[name = %s]',
$_
)
);
}
$self->{output}->output_add(
severity => 'OK',
short_msg => 'List drives:'
);
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
$self->{output}->exit();
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements => ['name']);
}
sub disco_show {
my ($self, %options) = @_;
my $drives = $self->manage_selection(%options);
foreach (sort keys %$drives) {
$self->{output}->add_disco_entry(name => $_);
}
}
1;
__END__
=head1 MODE
List queues.
=over 8
=back
=cut

View File

@ -0,0 +1,169 @@
#
# Copyright 2020 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::hddtemp::mode::temperatures;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold catalog_status_calc);
sub custom_status_output {
my ($self, %options) = @_;
return sprintf(
'status: %s',
$self->{result_values}->{status},
);
}
sub custom_temperature_output {
my ($self, %options) = @_;
return sprintf('temperature: %s %s',
$self->{result_values}->{temperature_absolute},
$self->{result_values}->{temperature_unit_absolute}
);
}
sub custom_temperature_perfdata {
my ($self, %options) = @_;
$self->{output}->perfdata_add(
nlabel => 'drive.temperature.' . ($self->{result_values}->{temperature_unit_absolute} eq 'C' ? 'celsius' : 'fahrenheit'),
instances => $self->{result_values}->{display_absolute},
unit => $self->{result_values}->{temperature_unit_absolute},
value => $self->{result_values}->{temperature_absolute},
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
);
}
sub prefix_drive_output {
my ($self, %options) = @_;
return "Drive '" . $options{instance_value}->{display} . "' ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'drives', type => 1, cb_prefix_output => 'prefix_drive_output', skipped_code => { -10 => 1 } }
];
$self->{maps_counters}->{drives} = [
{ label => 'status', threshold => 0, set => {
key_values => [ { name => 'status' }, { name => 'display' } ],
closure_custom_calc => \&catalog_status_calc,
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold
}
},
{ label => 'temperature', set => {
key_values => [ { name => 'temperature' }, { name => 'temperature_unit' }, { name => 'display' } ],
closure_custom_output => $self->can('custom_temperature_output'),
closure_custom_perfdata => $self->can('custom_temperature_perfdata')
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
'filter-name:s' => { name => 'filter_name' },
'unknown-status:s' => { name => 'unknown_status', default => '' },
'warning-status:s' => { name => 'warning_status', default => '' },
'critical-status:s' => { name => 'critical_status', default => '%{status} !~ /ok/i' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
$self->change_macros(macros => ['unknown_status', 'warning_status', 'critical_status']);
}
sub manage_selection {
my ($self, %options) = @_;
my $results = $options{custom}->get_drives_information();
$self->{drives} = {};
foreach (keys %$results) {
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$_ !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg => "skipping drive '" . $_ . "': no matching filter.", debug => 1);
next;
}
$self->{drives}->{$_} = {
display => $_,
%{$results->{$_}}
};
}
}
1;
__END__
=head1 MODE
Check drive temperatures.
=over 8
=item B<--filter-name>
Filter drive name (Can use regexp).
=item B<--unknown-status>
Set unknown threshold for status.
Can used special variables like: %{status}, %{display}
=item B<--warning-status>
Set warning threshold for status.
Can used special variables like: %{status}, %{display}
=item B<--critical-status>
Set critical threshold for status (Default: '%{status} !~ /ok/i').
Can used special variables like: %{status}, %{display}
=item B<--warning-*> B<--critical-*>
Thresholds.
Can be: 'temperature'.
=back
=cut

View File

@ -18,23 +18,25 @@
# limitations under the License.
#
package apps::hddtemp::remote::plugin;
package apps::hddtemp::plugin;
use strict;
use warnings;
use base qw(centreon::plugins::script_simple);
use base qw(centreon::plugins::script_custom);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{version} = '0.1';
$self->{version} = '1.0';
%{$self->{modes}} = (
'temperature' => 'apps::hddtemp::remote::mode::temperature',
'list-drives' => 'apps::hddtemp::remote::mode::listdrives',
'list-drives' => 'apps::hddtemp::mode::listdrives',
'temperatures' => 'apps::hddtemp::mode::temperatures'
);
$self->{custom_modes}{tcp} = 'apps::hddtemp::custom::tcp';
$self->{custom_modes}{cli} = 'apps::hddtemp::custom::cli';
return $self;
}
@ -44,6 +46,9 @@ __END__
=head1 PLUGIN DESCRIPTION
Check HDDTEMP Status throuh TCP Socket
Check drives temperature with hddtemp.
Two custom modes availables:
'tcp' (remotely with hddtemp in daemon mode)
'command' (with hddtemp command. you can execute locally or through ssh).
=cut

View File

@ -1,160 +0,0 @@
#
# Copyright 2020 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::hddtemp::remote::mode::listdrives;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
use IO::Socket;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments =>
{
"hostname:s" => { name => 'hostname' },
"port:s" => { name => 'port', default => '7634' },
"timeout:s" => { name => 'timeout', default => '10' },
"filter-name:s" => { name => 'filter_name', },
});
$self->{result} = {};
$self->{hostname} = undef;
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
if (!defined($self->{option_results}->{hostname})) {
$self->{output}->add_option_msg(short_msg => "Please set the hostname option");
$self->{output}->option_exit();
}
}
sub manage_selection {
my ($self, %options) = @_;
my $oSocketConn = new IO::Socket::INET ( Proto => 'tcp',
PeerAddr => $self->{option_results}->{hostname},
PeerPort => $self->{option_results}->{port},
Timeout => $self->{option_results}->{timeout},
);
if (!defined($oSocketConn)) {
$self->{output}->add_option_msg(short_msg => "Could not connect.");
$self->{output}->option_exit();
}
#|/dev/sda|SD280813AS|35|C|#|/dev/sdb|ST2000CD005-1CH134|35|C|
my $line;
eval {
local $SIG{ALRM} = sub { die "Timeout by signal ALARM\n"; };
alarm(10);
$line = <$oSocketConn>;
alarm(0);
};
$oSocketConn->shutdown(2);
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot get informations.");
$self->{output}->option_exit();
}
while ($line =~ /\|([^|]+)\|([^|]+)\|([^|]+)\|(C|F)\|/g) {
my ($drive, $serial, $temperature, $unit) = ($1, $2, $3, $4);
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$drive !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg => "Skipping drive '" . $drive . "': no matching filter name");
next;
}
$self->{result}->{$drive} = {serial => $serial, temperature => $temperature, unit => $unit};
}
}
sub run {
my ($self, %options) = @_;
$self->manage_selection();
foreach my $name (sort(keys %{$self->{result}})) {
$self->{output}->output_add(long_msg => "'" . $name . "' [temperature = " . $self->{result}->{$name}->{temperature} . $self->{result}->{$name}->{unit} . ']');
}
$self->{output}->output_add(severity => 'OK',
short_msg => 'List Drives:');
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
$self->{output}->exit();
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements => ['name', 'temperature']);
}
sub disco_show {
my ($self, %options) = @_;
$self->manage_selection();
foreach my $name (sort(keys %{$self->{result}})) {
$self->{output}->add_disco_entry(name => $name,
temperature => $self->{result}->{$name}->{temperature}
);
}
}
1;
__END__
=head1 MODE
List HDDTEMP Harddrives
=over 8
=item B<--hostname>
IP Address or FQDN of the Server
=item B<--port>
Port used by Hddtemp (Default: 7634)
=item B<--timeout>
Set Timeout for Socketconnect
=item B<--filter-name>
Filter Harddrive name (regexp can be used).
=back
=cut

View File

@ -1,210 +0,0 @@
#
# Copyright 2020 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::hddtemp::remote::mode::temperature;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
use IO::Socket;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments => {
"hostname:s" => { name => 'hostname' },
"port:s" => { name => 'port', default => '7634' },
"timeout:s" => { name => 'timeout', default => '10' },
"name:s" => { name => 'name' },
"warning:s" => { name => 'warning' },
"critical:s" => { name => 'critical' },
"regexp" => { name => 'use_regexp' },
"regexp-isensitive" => { name => 'use_regexpi' },
});
$self->{result} = {};
$self->{hostname} = undef;
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
if (!defined($self->{option_results}->{hostname})) {
$self->{output}->add_option_msg(short_msg => "Please set the hostname option");
$self->{output}->option_exit();
}
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 manage_selection {
my ($self, %options) = @_;
my $oSocketConn = new IO::Socket::INET (
Proto => 'tcp',
PeerAddr => $self->{option_results}->{hostname},
PeerPort => $self->{option_results}->{port},
Timeout => $self->{option_results}->{timeout},
);
if (!defined($oSocketConn)) {
$self->{output}->add_option_msg(short_msg => "Could not connect.");
$self->{output}->option_exit();
}
#|/dev/sda|SD280813AS|35|C|#|/dev/sdb|ST2000CD005-1CH134|35|C|
my $line;
eval {
local $SIG{ALRM} = sub { die "Timeout by signal ALARM\n"; };
alarm(10);
$line = <$oSocketConn>;
alarm(0);
};
$oSocketConn->shutdown(2);
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot get informations.");
$self->{output}->option_exit();
}
while ($line =~ /\|([^|]+)\|([^|]+)\|([^|]+)\|(C|F)\|/g) {
my ($drive, $serial, $temperature, $unit) = ($1, $2, $3, $4);
next if (defined($self->{option_results}->{name}) && defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi})
&& $drive !~ /$self->{option_results}->{name}/i);
next if (defined($self->{option_results}->{name}) && defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi})
&& $drive !~ /$self->{option_results}->{name}/);
next if (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi})
&& $drive ne $self->{option_results}->{name});
$self->{result}->{$drive} = {serial => $serial, temperature => $temperature, unit => $unit};
}
if (scalar(keys %{$self->{result}}) <= 0) {
if (defined($self->{option_results}->{name})) {
$self->{output}->add_option_msg(short_msg => "No drives found for name '" . $self->{option_results}->{name} . "'.");
} else {
$self->{output}->add_option_msg(short_msg => "No drives found.");
}
$self->{output}->option_exit();
}
}
sub run {
my ($self, %options) = @_;
$self->manage_selection();
if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})) {
$self->{output}->output_add(severity => 'OK',
short_msg => 'All Harddrive Temperatures are ok.');
};
foreach my $name (sort(keys %{$self->{result}})) {
my $exit = $self->{perfdata}->threshold_check(value => $self->{result}->{$name}->{temperature}, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]);
$self->{output}->output_add(long_msg => sprintf("Harddrive '%s' Temperature : %s%s",
$name,
$self->{result}->{$name}->{temperature},
$self->{result}->{$name}->{unit}));
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp}))) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Harddrive '%s' Temperature : %s%s",
$name,
$self->{result}->{$name}->{temperature},
$self->{result}->{$name}->{unit}));
}
my $extra_label;
$extra_label = '_' . $name if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp}));
$self->{output}->perfdata_add(
label => 'temp',
intances => $extra_label,
unit => $self->{result}->{$name}->{unit},
value => sprintf("%.2f", $self->{result}->{$name}->{temperature}),
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 HDDTEMP Temperature by Socket Connect
=over 8
=item B<--hostname>
IP Address or FQDN of the Server
=item B<--port>
Port used by Hddtemp (Default: 7634)
=item B<--timeout>
Set Timeout for Socketconnect
=item B<--warning>
Warning Threshold for Temperature
=item B<--critical>
Critical Threshold for Temperature
=item B<--name>
Set the Harddrive name (empty means 'check all Harddrives')
=item B<--regexp>
Allows to use regexp to filter Harddrive (with option --name).
=item B<--regexp-isensitive>
Allows to use regexp non case-sensitive (with --regexp).
=back
=cut

View File

@ -138,7 +138,7 @@ sub execute {
$self->{output}->option_exit();
}
if ($exit_code != 0) {
if ($exit_code != 0 && (!defined($options{no_quit}) || $options{no_quit} != 1)) {
$self->{output}->add_option_msg(short_msg => sprintf('command execution error [exit code: %s]', $exit_code));
$self->{output}->option_exit();
}

View File

@ -81,7 +81,8 @@ sub execute {
ssh_path => $self->{ssh_path},
ssh_option => $self->{ssh_option},
timeout => $options{timeout}
}
},
no_quit => $options{no_quit}
);
if (defined($options{ssh_pipe}) && $options{ssh_pipe} == 1) {

View File

@ -83,7 +83,8 @@ sub execute {
ssh_path => $self->{ssh_path},
ssh_option => $self->{ssh_option},
timeout => $options{timeout}
}
},
no_quit => $options{no_quit}
);
if (defined($options{ssh_pipe}) && $options{ssh_pipe} == 1) {