(plugin) hardware::server::hp::ilo::restapi - add storage components (#4204)

This commit is contained in:
qgarnier 2023-02-08 10:15:46 +00:00 committed by GitHub
parent 48332cf908
commit 3c7c0418ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 353 additions and 2 deletions

View File

@ -0,0 +1,84 @@
#
# Copyright 2023 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::redfish::restapi::mode::components::drive;
use strict;
use warnings;
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'));
$self->get_storages() if (!defined($self->{storages}));
foreach my $storage (@{$self->{storages}}) {
$storage->{'@odata.id'} =~ /Systems\/(\d+)\//;
my $system_id = $1;
my $system_name = 'system:' . $1;
my $storage_name = $storage->{Id};
foreach (@{$storage->{Drives}}) {
my $drive = $self->get_drive(drive => $_);
my $instance = $system_id . '.' . $storage->{Id} . '.' . $drive->{Id};
$drive->{Status}->{Health} = defined($drive->{Status}->{Health}) ? $drive->{Status}->{Health} : 'n/a';
$drive->{Status}->{State} = defined($drive->{Status}->{State}) ? $drive->{Status}->{State} : 'n/a';
next if ($self->check_filter(section => 'drive', instance => $instance));
$self->{components}->{drive}->{total}++;
$self->{output}->output_add(
long_msg => sprintf(
"drive '%s/%s/%s' status is '%s' [instance: %s, state: %s, location: %s]",
$system_name,
$storage_name,
$drive->{Id},
$drive->{Status}->{Health},
$instance,
$drive->{Status}->{State},
$drive->{PhysicalLocation}->{PartLocation}->{ServiceLabel}
)
);
my $exit = $self->get_severity(label => 'state', section => 'drive.state', value => $drive->{Status}->{State});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("Drive '%s/%s/%s' state is '%s'", $system_name, $storage_name, $drive->{Id}, $drive->{Status}->{State})
);
}
$exit = $self->get_severity(label => 'status', section => 'drive.status', value => $drive->{Status}->{Health});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("Drive '%s/%s/%s' status is '%s'", $system_name, $storage_name, $drive->{Id}, $drive->{Status}->{Health})
);
}
}
}
}
1;

View File

@ -0,0 +1,78 @@
#
# Copyright 2023 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::redfish::restapi::mode::components::sc;
use strict;
use warnings;
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => 'checking storage controllers');
$self->{components}->{sc} = { name => 'sc', total => 0, skip => 0 };
return if ($self->check_filter(section => 'sc'));
$self->get_storages() if (!defined($self->{storages}));
foreach my $storage (@{$self->{storages}}) {
$storage->{'@odata.id'} =~ /Systems\/(\d+)\//;
my $system_id = $1;
my $system_name = 'system:' . $1;
my $storage_name = $storage->{Id};
foreach my $sc (@{$storage->{StorageControllers}}) {
my $instance .= $system_id . '.' . $storage->{Id} . '.' . $sc->{MemberId};
my $sc_name = $sc->{MemberId};
$sc->{Status}->{Health} = defined($sc->{Status}->{Health}) ? $sc->{Status}->{Health} : 'n/a';
$sc->{Status}->{State} = defined($sc->{Status}->{State}) ? $sc->{Status}->{State} : 'n/a';
next if ($self->check_filter(section => 'sc', instance => $instance));
$self->{components}->{sc}->{total}++;
$self->{output}->output_add(
long_msg => sprintf(
"storage controller '%s/%s/%s' status is '%s' [instance: %s, state: %s]",
$system_name, $storage_name, $sc_name, $sc->{Status}->{Health}, $instance, $sc->{Status}->{State}
)
);
my $exit = $self->get_severity(label => 'state', section => 'sc.state', value => $sc->{Status}->{State});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("Storage controller '%s/%s/%s' state is '%s'", $system_name, $storage_name, $sc_name, $sc->{Status}->{State})
);
}
$exit = $self->get_severity(label => 'status', section => 'sc.status', value => $sc->{Status}->{Health});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("Storage controller '%s/%s/%s' status is '%s'", $system_name, $storage_name, $sc_name, $sc->{Status}->{Health})
);
}
}
}
}
1;

View File

@ -0,0 +1,73 @@
#
# Copyright 2023 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::redfish::restapi::mode::components::storage;
use strict;
use warnings;
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => 'checking storages');
$self->{components}->{storage} = { name => 'storages', total => 0, skip => 0 };
return if ($self->check_filter(section => 'storage'));
$self->get_storages() if (!defined($self->{storages}));
foreach my $storage (@{$self->{storages}}) {
$storage->{'@odata.id'} =~ /Systems\/(\d+)\//;
my $system_id = $1;
my $system_name = 'system:' . $1;
my $storage_name = $storage->{Id};
my $instance = $system_id . '.' . $storage->{Id};
$storage->{Status}->{Health} = defined($storage->{Status}->{HealthRollup}) ? $storage->{Status}->{HealthRollup} : 'n/a';
$storage->{Status}->{State} = defined($storage->{Status}->{State}) ? $storage->{Status}->{State} : 'n/a';
next if ($self->check_filter(section => 'storage', instance => $instance));
$self->{components}->{storage}->{total}++;
$self->{output}->output_add(
long_msg => sprintf(
"storage '%s/%s' status is '%s' [instance: %s, state: %s]",
$system_name, $storage_name, $storage->{Status}->{HealthRollup}, $instance, $storage->{Status}->{State}
)
);
my $exit = $self->get_severity(label => 'state', section => 'storage.state', value => $storage->{Status}->{State});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("Storage '%s/%s' state is '%s'", $system_name, $storage_name, $storage->{Status}->{State})
);
}
$exit = $self->get_severity(label => 'status', section => 'storage.status', value => $storage->{Status}->{HealthRollup});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("Storage '%s/%s' status is '%s'", $system_name, $storage_name, $storage->{Status}->{HealthRollup})
);
}
}
}
1;

View File

@ -0,0 +1,78 @@
#
# Copyright 2023 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::redfish::restapi::mode::components::volume;
use strict;
use warnings;
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => 'checking volumes');
$self->{components}->{volume} = { name => 'volumes', total => 0, skip => 0 };
return if ($self->check_filter(section => 'volume'));
$self->get_storages() if (!defined($self->{storages}));
foreach my $storage (@{$self->{storages}}) {
$storage->{'@odata.id'} =~ /Systems\/(\d+)\//;
my $system_id = $1;
my $system_name = 'system:' . $1;
my $storage_name = $storage->{Id};
my $volumes = $self->get_volumes(storage => $storage);
foreach my $volume (@$volumes) {
my $instance = $system_id . '.' . $storage->{Id} . '.' . $volume->{Id};
$volume->{Status}->{Health} = defined($volume->{Status}->{Health}) ? $volume->{Status}->{Health} : 'n/a';
$volume->{Status}->{State} = defined($volume->{Status}->{State}) ? $volume->{Status}->{State} : 'n/a';
next if ($self->check_filter(section => 'volume', instance => $instance));
$self->{components}->{volume}->{total}++;
$self->{output}->output_add(
long_msg => sprintf(
"volume '%s/%s/%s' status is '%s' [instance: %s, state: %s]",
$system_name, $storage_name, $volume->{Id}, $volume->{Status}->{Health}, $instance, $volume->{Status}->{State}
)
);
my $exit = $self->get_severity(label => 'state', section => 'volume.state', value => $volume->{Status}->{State});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("Volume '%s/%s/%s' state is '%s'", $system_name, $storage_name, $volume->{Id}, $volume->{Status}->{State})
);
}
$exit = $self->get_severity(label => 'status', section => 'volume.status', value => $volume->{Status}->{Health});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("Volume '%s/%s/%s' status is '%s'", $system_name, $storage_name, $volume->{Id}, $volume->{Status}->{Health})
);
}
}
}
}
1;

View File

@ -51,7 +51,7 @@ sub set_system {
$self->{components_exec_load} = 0;
$self->{components_path} = 'centreon::common::redfish::restapi::mode::components';
$self->{components_module} = ['chassis', 'device', 'fan', 'psu', 'temperature'];
$self->{components_module} = ['chassis', 'device', 'drive', 'fan', 'psu', 'sc', 'storage', 'temperature', 'volume'];
}
sub new {
@ -106,6 +106,43 @@ sub get_chassis {
}
}
sub get_drive {
my ($self, %options) = @_;
return {} if (!defined($options{drive}->{'@odata.id'}));
return $self->{custom}->request_api(url_path => $options{drive}->{'@odata.id'});
}
sub get_volumes {
my ($self, %options) = @_;
return [] if (!defined($options{storage}->{Volumes}->{'@odata.id'}));
my $volumes = $self->{custom}->request_api(url_path => $options{storage}->{Volumes}->{'@odata.id'});
my $result = [];
foreach my $volume (@{$volumes->{Members}}) {
my $volume_detailed = $self->{custom}->request_api(url_path => $volume->{'@odata.id'});
push @$result, $volume_detailed;
}
return $result;
}
sub get_storages {
my ($self, %options) = @_;
$self->{storages} = [];
my $systems = $self->{custom}->request_api(url_path => '/redfish/v1/Systems');
foreach my $system (@{$systems->{Members}}) {
my $storages = $self->{custom}->request_api(url_path => $system->{'@odata.id'} . '/Storage/');
foreach my $storage (@{$storages->{Members}}) {
my $storage_detailed = $self->{custom}->request_api(url_path => $storage->{'@odata.id'});
push @{$self->{storages}}, $storage_detailed;
}
}
}
sub execute_custom {
my ($self, %options) = @_;
@ -123,7 +160,7 @@ Check hardware.
=item B<--component>
Which component to check (Default: '.*').
Can be: 'chassis', 'device', 'fan', 'psu', 'temperature'.
Can be: 'chassis', 'device', 'drive', 'fan', 'psu', 'sc', 'storage', 'temperature', 'volume'.
=item B<--filter>

View File

@ -209,6 +209,7 @@ sub request_api {
$self->{output}->add_option_msg(short_msg => "Error while retrieving data (add --debug option for detailed message)");
$self->{output}->option_exit();
}
if ($self->{http}->get_code() < 200 || $self->{http}->get_code() >= 300) {
$self->{output}->add_option_msg(short_msg => 'api request error: ' . (defined($decoded->{type}) ? $decoded->{type} : 'unknown'));
$self->{output}->option_exit();