Merge pull request #2417 from centreon/fix-2339

Fix #2339
This commit is contained in:
qgarnier 2020-12-08 09:59:26 +01:00 committed by GitHub
commit fa0432a9ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 125 additions and 94 deletions

View File

@ -18,13 +18,13 @@
# limitations under the License.
#
package storage::hp::p2000::xmlapi::custom;
package storage::hp::p2000::xmlapi::custom::api;
use strict;
use warnings;
use centreon::plugins::http;
use XML::XPath;
use Digest::MD5 qw(md5_hex);
use XML::LibXML::Simple;
sub new {
my ($class, %options) = @_;
@ -116,38 +116,34 @@ sub build_options_for_httplib {
sub check_login {
my ($self, %options) = @_;
my ($xpath, $nodeset);
my $xml;
eval {
$xpath = XML::XPath->new(xml => $options{content});
$nodeset = $xpath->find("//OBJECT[\@basetype='status']//PROPERTY[\@name='return-code']");
$SIG{__WARN__} = sub {};
$xml = XMLin($options{content}, ForceArray => [], KeyAttr => []);
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot parse login response: $@");
$self->{output}->option_exit();
}
if (scalar($nodeset->get_nodelist) == 0) {
$self->{output}->output_add(severity => 'UNKNOWN',
short_msg => 'Cannot find login response.');
$self->{output}->display();
$self->{output}->exit();
if (!defined($xml->{OBJECT}) || !defined($xml->{OBJECT}->{PROPERTY})) {
$self->{output}->add_option_msg(short_msg => 'Cannot find login response');
$self->{output}->option_exit();
}
foreach my $node ($nodeset->get_nodelist()) {
if ($node->string_value != 1) {
$self->{output}->output_add(severity => 'UNKNOWN',
short_msg => 'Login authentification failed (return-code: ' . $node->string_value . ').');
$self->{output}->display();
$self->{output}->exit();
}
my ($session_id, $return_code);
foreach (@{$xml->{OBJECT}->{PROPERTY}}) {
$return_code = $_->{content} if ($_->{name} eq 'return-code');
$session_id = $_->{content} if ($_->{name} eq 'response');
}
$nodeset = $xpath->find("//OBJECT[\@basetype='status']//PROPERTY[\@name='response']");
my @nodes = $nodeset->get_nodelist();
my $node = shift(@nodes);
$self->{session_id} = $node->string_value;
if ($return_code != 1) {
$self->{output}->add_option_msg(short_msg => 'Login authentification failed (return-code: ' . $return_code . ').');
$self->{output}->option_exit();
}
$self->{session_id} = $session_id;
$self->{logon} = 1;
}
@ -175,12 +171,12 @@ sub get_infos {
$self->login();
my $cmd = $options{cmd};
$cmd =~ s/ /\//g;
my ($unknown_status, $warning_status, $critical_status) = ($self->{unknown_http_status}, $self->{warning_http_status}, $self->{critical_http_status});
if (defined($options{no_quit}) && $options{no_quit} == 1) {
($unknown_status, $warning_status, $critical_status) = ('', '', '');
}
my $response = $self->{http}->request(
my ($response) = $self->{http}->request(
url_path => $self->{url_path} . $cmd,
header => [
'Cookie: wbisessionkey=' . $self->{session_id} . '; wbiusername=' . $self->{username},
@ -188,19 +184,20 @@ sub get_infos {
],
unknown_status => $unknown_status,
warning_status => $warning_status,
critical_status => $critical_status,
critical_status => $critical_status
);
my $xml;
eval {
$xpath = XML::XPath->new(xml => $response);
$nodeset = $xpath->find("//OBJECT[\@basetype='" . $options{base_type} . "']");
$SIG{__WARN__} = sub {};
$xml = XMLin($response, ForceArray => ['OBJECT'], KeyAttr => []);
};
if ($@) {
return ({}, 0) if (defined($options{no_quit}) && $options{no_quit} == 1);
$self->{output}->add_option_msg(short_msg => "Cannot parse 'cmd' response: $@");
$self->{output}->option_exit();
}
# Check if there is an error
#<OBJECT basetype="status" name="status" oid="1">
#<PROPERTY name="response-type" type="enumeration" size="12" draw="false" sort="nosort" display-name="Response Type">Error</PROPERTY>
@ -209,38 +206,44 @@ sub get_infos {
#<PROPERTY name="return-code" type="int32" size="5" draw="false" sort="nosort" display-name="Return Code">-10028</PROPERTY>
#<PROPERTY name="component-id" type="string" size="80" draw="false" sort="nosort" display-name="Component ID"></PROPERTY>
#</OBJECT>
if (my $nodestatus = $xpath->find("//OBJECT[\@basetype='status']//PROPERTY[\@name='return-code']")) {
my @nodes = $nodestatus->get_nodelist();
my $node = shift @nodes;
my $return_code = $node->string_value;
if ($return_code != 0) {
$nodestatus = $xpath->find("//OBJECT[\@basetype='status']//PROPERTY[\@name='response']");
@nodes = $nodestatus->get_nodelist();
$node = shift @nodes;
return ({}, 0, $node->string_value) if (defined($options{no_quit}) && $options{no_quit} == 1);
$self->{output}->add_option_msg(short_msg => $node->string_value);
$self->{output}->option_exit();
}
}
my $results = {};
foreach my $node ($nodeset->get_nodelist()) {
my $properties = {};
$results = [] if (!defined($options{key}));
foreach my $obj (@{$xml->{OBJECT}}) {
if ($obj->{basetype} eq 'status') {
my ($return_code, $response) = (-1, 'n/a');
foreach my $prop (@{$obj->{PROPERTY}}) {
$return_code = $prop->{content} if ($prop->{name} eq 'return-code');
$response = $prop->{content} if ($prop->{name} eq 'response');
}
foreach my $prop_node ($node->getChildNodes()) {
my $prop_name = $prop_node->getAttribute('name');
if (defined($prop_name) && ($prop_name eq $options{key} ||
$prop_name =~ /$options{properties_name}/)) {
$properties->{$prop_name} = $prop_node->string_value;
if ($return_code != 0) {
return ({}, 0) if (defined($options{no_quit}) && $options{no_quit} == 1);
$self->{output}->add_option_msg(short_msg => $response);
$self->{output}->option_exit();
}
}
if (defined($properties->{$options{key}})) {
$results->{$properties->{$options{key}}} = $properties;
if ($obj->{basetype} eq $options{base_type}) {
my $properties = {};
foreach (keys %$obj) {
$properties->{$_} = $obj->{$_} if (/$options{properties_name}/);
}
foreach my $prop (@{$obj->{PROPERTY}}) {
if (defined($prop->{name}) &&
((defined($options{key}) && $prop->{name} eq $options{key}) || $prop->{name} =~ /$options{properties_name}/)) {
$properties->{ $prop->{name} } = $prop->{content};
}
}
if (defined($options{key})) {
$results->{ $properties->{ $options{key} } } = $properties
if (defined($properties->{ $options{key} }));
} else {
push @$results, $properties;
}
}
}
return ($results, 1);
}
@ -254,7 +257,7 @@ sub login {
$self->build_options_for_httplib();
$self->{http}->set_options(%{$self->{option_results}});
# Login First
my $md5_hash = md5_hex($self->{username} . '_' . $self->{password});
my $response = $self->{http}->request(
@ -263,6 +266,7 @@ sub login {
warning_status => $self->{warning_http_status},
critical_status => $self->{critical_http_status},
);
$self->check_login(content => $response);
}

View File

@ -52,13 +52,18 @@ sub check {
my $state = $health{$results->{$disk_id}->{'health-numeric'}};
$self->{output}->output_add(long_msg => sprintf("disk '%s' status is %s [instance: %s]",
$disk_id, $state, $disk_id)
);
$self->{output}->output_add(
long_msg => sprintf(
"disk '%s' status is %s [instance: %s]",
$disk_id, $state, $disk_id
)
);
my $exit = $self->get_severity(label => 'default', section => 'disk', value => $state);
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Disk '%s' status is '%s'", $disk_id, $state));
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("Disk '%s' status is '%s'", $disk_id, $state)
);
}
}
}

View File

@ -48,16 +48,21 @@ sub check {
foreach my $enc_id (keys %$results) {
next if ($self->check_filter(section => 'enclosure', instance => $enc_id));
$self->{components}->{enclosure}->{total}++;
my $state = $health{$results->{$enc_id}->{'health-numeric'}};
$self->{output}->output_add(long_msg => sprintf("enclosure '%s' status is %s [instance: %s] [reason: %s]",
$enc_id, $state, $enc_id, $results->{$enc_id}->{'health-reason'})
);
$self->{output}->output_add(
long_msg => sprintf(
"enclosure '%s' status is %s [instance: %s] [reason: %s]",
$enc_id, $state, $enc_id, $results->{$enc_id}->{'health-reason'}
)
);
my $exit = $self->get_severity(label => 'default', section => 'enclosure', value => $state);
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'", $enc_id, $state));
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("Enclosure '%s' status is '%s'", $enc_id, $state)
);
}
}
}

View File

@ -30,20 +30,32 @@ sub check {
$self->{components}->{fru} = {name => 'frus', total => 0, skip => 0};
return if ($self->check_filter(section => 'fru'));
my ($results) = $self->{custom}->get_infos(
my ($entries) = $self->{custom}->get_infos(
cmd => 'show frus',
base_type => 'enclosure-fru',
key => 'fru-location',
properties_name => '^(fru-status|fru-location)$',
properties_name => '^fru-status|fru-location|oid$',
no_quit => 1,
);
foreach my $part_number (keys %$results) {
my $instance = $results->{$part_number}->{'fru-location'};
my ($results, $duplicated) = ({}, {});
foreach (@$entries) {
my $name = $_->{'fru-location'};
$name = $_->{'fru-location'} . ':' . $_->{oid} if (defined($duplicated->{$name}));
if (defined($results->{$name})) {
$duplicated->{$name} = 1;
my $instance = $results->{$name}->{'fru-location'} . ':' . $results->{$name}->{oid};
$results->{$instance} = $results->{$name};
delete $results->{$name};
$name = $_->{'fru-location'} . ':' . $_->{oid};
}
$results->{$name} = $_;
}
foreach my $instance (keys %$results) {
next if ($self->check_filter(section => 'fru', instance => $instance));
$self->{components}->{fru}->{total}++;
my $state = $results->{$part_number}->{'fru-status'};
my $state = $results->{$instance}->{'fru-status'};
$self->{output}->output_add(
long_msg => sprintf(

View File

@ -48,7 +48,7 @@ sub check {
cmd => 'show sensor-status',
base_type => 'sensors',
key => 'sensor-name',
properties_name => '^(value|sensor-type|status)$'
properties_name => '^(?:value|sensor-type|status)$'
);
#<OBJECT basetype="sensors" name="sensor" oid="22" format="rows">

View File

@ -40,13 +40,18 @@ sub check_vdisk {
my $state = $health{$options{results}->{$vdisk_id}->{'health-numeric'}};
$self->{output}->output_add(long_msg => sprintf("vdisk '%s' status is %s [instance: %s]",
$vdisk_id, $state, $vdisk_id)
);
$self->{output}->output_add(
long_msg => sprintf(
"vdisk '%s' status is %s [instance: %s]",
$vdisk_id, $state, $vdisk_id
)
);
my $exit = $self->get_severity(label => 'default', section => 'vdisk', value => $state);
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'", $vdisk_id, $state));
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("Vdisk '%s' status is '%s'", $vdisk_id, $state)
);
}
}
}
@ -63,7 +68,7 @@ sub check {
base_type => 'virtual-disks',
key => 'name',
properties_name => '^health-numeric$',
no_quit => 1,
no_quit => 1
);
if ($code == 0) {
($results) = $self->{custom}->get_infos(
@ -71,7 +76,7 @@ sub check {
base_type => 'disk-groups',
key => 'name',
properties_name => '^health-numeric$',
no_quit => 1,
no_quit => 1
);
}

View File

@ -39,19 +39,19 @@ sub set_system {
['ok', 'OK'],
['degraded', 'WARNING'],
['failed|fault', 'CRITICAL'],
['unknown|not available', 'UNKNOWN'],
['unknown|not available', 'UNKNOWN']
],
fru => [
['ok', 'OK'],
['absent', 'WARNING'],
['fault', 'CRITICAL'],
['not available', 'UNKNOWN'],
['not available', 'UNKNOWN']
],
sensor => [
['ok', 'OK'],
['warning|not installed|unavailable', 'WARNING'],
['error|unrecoverable', 'CRITICAL'],
['unknown|unsupported', 'UNKNOWN'],
['unknown|unsupported', 'UNKNOWN']
],
};
@ -70,7 +70,7 @@ sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
});

View File

@ -31,13 +31,13 @@ sub new {
bless $self, $class;
$self->{version} = '0.1';
%{$self->{modes}} = (
$self->{modes} = {
'health' => 'storage::hp::p2000::xmlapi::mode::health',
'list-volumes' => 'storage::hp::p2000::xmlapi::mode::listvolumes',
'vdisks' => 'storage::hp::p2000::xmlapi::mode::vdisks',
'volume-stats' => 'storage::hp::p2000::xmlapi::mode::volumesstats',
);
$self->{custom_modes}{p2000xml} = 'storage::hp::p2000::xmlapi::custom';
'volume-stats' => 'storage::hp::p2000::xmlapi::mode::volumesstats'
};
$self->{custom_modes}->{p2000xml} = 'storage::hp::p2000::xmlapi::custom::api';
return $self;
}