diff --git a/src/centreon/common/redfish/restapi/mode/components/drive.pm b/src/centreon/common/redfish/restapi/mode/components/drive.pm new file mode 100644 index 000000000..42c09556a --- /dev/null +++ b/src/centreon/common/redfish/restapi/mode/components/drive.pm @@ -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; diff --git a/src/centreon/common/redfish/restapi/mode/components/sc.pm b/src/centreon/common/redfish/restapi/mode/components/sc.pm new file mode 100644 index 000000000..04896346b --- /dev/null +++ b/src/centreon/common/redfish/restapi/mode/components/sc.pm @@ -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; diff --git a/src/centreon/common/redfish/restapi/mode/components/storage.pm b/src/centreon/common/redfish/restapi/mode/components/storage.pm new file mode 100644 index 000000000..f27bb50fe --- /dev/null +++ b/src/centreon/common/redfish/restapi/mode/components/storage.pm @@ -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; diff --git a/src/centreon/common/redfish/restapi/mode/components/volume.pm b/src/centreon/common/redfish/restapi/mode/components/volume.pm new file mode 100644 index 000000000..29dd7fbf9 --- /dev/null +++ b/src/centreon/common/redfish/restapi/mode/components/volume.pm @@ -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; diff --git a/src/centreon/common/redfish/restapi/mode/hardware.pm b/src/centreon/common/redfish/restapi/mode/hardware.pm index b7a46bdaf..ea838db72 100644 --- a/src/centreon/common/redfish/restapi/mode/hardware.pm +++ b/src/centreon/common/redfish/restapi/mode/hardware.pm @@ -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> diff --git a/src/hardware/server/hp/ilo/restapi/custom/api.pm b/src/hardware/server/hp/ilo/restapi/custom/api.pm index ee2bd25de..f8523a0f2 100644 --- a/src/hardware/server/hp/ilo/restapi/custom/api.pm +++ b/src/hardware/server/hp/ilo/restapi/custom/api.pm @@ -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();