feat: new plugin hpe primera api (#5115)

Refs: Ctor-665
This commit is contained in:
omercier 2024-08-07 11:38:57 +02:00 committed by GitHub
parent 5fd1df4c39
commit 2696c3c37f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 2749 additions and 6 deletions

View File

@ -0,0 +1,4 @@
{
"dependencies": [
]
}

View File

@ -0,0 +1,9 @@
{
"pkg_name": "centreon-plugin-Hardware-Storage-Hpe-Primera-Restapi",
"pkg_summary": "Centreon Plugin",
"plugin_name": "centreon_hpe_primera_restapi.pl",
"files": [
"centreon/plugins/script_custom.pm",
"storage/hp/primera/restapi/"
]
}

View File

@ -0,0 +1,4 @@
{
"dependencies": [
]
}

View File

@ -210,7 +210,7 @@ Filter disks by name (can be a regexp).
Define the conditions to match for the status to be UNKNOWN.
You can use the following variables: %{status}, %{name}
=item B<--warning--status>
=item B<--warning-status>
Define the conditions to match for the status to be WARNING (default: '%{status} =~ /reparing|formatting/i').
You can use the following variables: %{status}, %{name}

View File

@ -118,7 +118,7 @@ Specify the command to execute (required).
Define the conditions to match for the status to be UNKNOWN.
You can use the following variables: %{status}, %{name}
=item B<--warning--status>
=item B<--warning-status>
Define the conditions to match for the status to be WARNING.
You can use the following variables: %{status}, %{name}

View File

@ -243,7 +243,7 @@ Filter disks by name (can be a regexp).
Define the conditions to match for the status to be UNKNOWN (default: '%{status} =~ /unknown/i').
You can use the following variables: %{status}, %{name}
=item B<--warning--status>
=item B<--warning-status>
Define the conditions to match for the status to be WARNING (default: '%{status} =~ /noReady|busy|hwFailureOk|hwFailurePerf|Protected|rebuilding/i').
You can use the following variables: %{status}, %{name}

View File

@ -208,7 +208,7 @@ JOBQ selection. Example: --jobq="QGPL:QBASE" --jobq="QGPL:QPGMR"
Define the conditions to match for the status to be UNKNOWN.
You can use the following variables: %{status}, %{name}, %{library}
=item B<--warning--status>
=item B<--warning-status>
Define the conditions to match for the status to be WARNING.
You can use the following variables: %{status}, %{name}, %{library}

View File

@ -190,7 +190,7 @@ Filter subsystems by library (can be a regexp).
Define the conditions to match for the status to be UNKNOWN.
You can use the following variables: %{status}, %{name}, %{library}
=item B<--warning--status>
=item B<--warning-status>
Define the conditions to match for the status to be WARNING (default: '%{status} =~ /ending|restricted|starting/i').
You can use the following variables: %{status}, %{name}, %{library}

View File

@ -0,0 +1,239 @@
#
# Copyright 2024 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 storage::hp::primera::restapi::custom::api;
use strict;
use warnings;
use centreon::plugins::http;
use centreon::plugins::statefile;
use JSON::XS;
use Digest::MD5 qw(md5_hex);
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 => {
'api-username:s' => { name => 'api_username' },
'api-password:s' => { name => 'api_password' },
'hostname:s' => { name => 'hostname' },
'port:s' => { name => 'port', default => 443 },
'proto:s' => { name => 'proto', default => 'https' },
'timeout:s' => { name => 'timeout', default => 30 },
'unknown-http-status:s' => { name => 'unknown_http_status', default => '%{http_code} < 200 or %{http_code} >= 300' },
'warning-http-status:s' => { name => 'warning_http_status' },
'critical-http-status:s' => { name => 'critical_http_status' }
});
}
$options{options}->add_help(package => __PACKAGE__, sections => 'HPE PRIMERA API OPTIONS', once => 1);
$self->{output} = $options{output};
$self->{http} = centreon::plugins::http->new(%options, default_backend => 'curl');
$self->{cache} = centreon::plugins::statefile->new(%options);
return $self;
}
sub set_options {
my ($self, %options) = @_;
$self->{option_results} = $options{option_results};
}
sub set_defaults {}
sub check_options {
my ($self, %options) = @_;
if (centreon::plugins::misc::is_empty($self->{option_results}->{hostname})) {
$self->{output}->add_option_msg(short_msg => 'Need to specify --hostname option.');
$self->{output}->option_exit();
}
if (centreon::plugins::misc::is_empty($self->{option_results}->{api_username})) {
$self->{output}->add_option_msg(short_msg => 'Need to specify --api-username option.');
$self->{output}->option_exit();
}
if (centreon::plugins::misc::is_empty($self->{option_results}->{api_password})) {
$self->{output}->add_option_msg(short_msg => 'Need to specify --api-password option.');
$self->{output}->option_exit();
}
$self->{http}->set_options(%{$self->{option_results}});
$self->{http}->add_header(key => 'Accept', value => 'application/json');
$self->{cache}->check_options(option_results => $self->{option_results});
return 0;
}
sub get_connection_info {
my ($self, %options) = @_;
return $self->{option_results}->{hostname} . ':' . $self->{option_results}->{port};
}
sub get_token {
my ($self, %options) = @_;
my $has_cache_file = $self->{cache}->read(statefile => 'hpe_primera_' . md5_hex($self->get_connection_info() . '_' . $self->{option_results}->{api_username}));
my $auth_key = $self->{cache}->get(name => 'auth_key');
if ($has_cache_file == 0 || !defined($auth_key) || $auth_key eq '' ) {
my $json_request = {
user => $self->{option_results}->{api_username},
password => $self->{option_results}->{api_password}
};
my $encoded;
eval {
$encoded = encode_json($json_request);
};
if ($@) {
$self->{output}->add_option_msg(short_msg => 'An error occurred while encoding the credentials to a JSON string.');
$self->{output}->option_exit();
}
my $content = $self->{http}->request(
method => 'POST',
url_path => '/api/v1/credentials',
query_form_post => $encoded,
unknown_status => $self->{option_results}->{unknown_http_status},
warning_status => $self->{option_results}->{warning_http_status},
critical_status => $self->{option_results}->{critical_http_status},
header => ['Content-Type: application/json']
);
my $decoded;
eval {
$decoded = JSON::XS->new->utf8->decode($content);
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "An error occurred while decoding the response ('$content').");
$self->{output}->option_exit();
}
$auth_key = $decoded->{key};
my $data = {
updated => time(),
auth_key => $auth_key
};
$self->{cache}->write(data => $data);
}
return $auth_key;
}
sub clean_token {
my ($self, %options) = @_;
my $data = { updated => time() };
$self->{cache}->write(data => $data);
}
sub request_api {
my ($self, %options) = @_;
my $get_param = [];
if (defined($options{get_param})) {
$get_param = $options{get_param};
}
my $token = $self->get_token();
my ($content) = $self->{http}->request(
url_path => $options{endpoint},
get_param => $get_param,
header => [ 'Authorization: Bearer ' . $token ],
unknown_status => '',
warning_status => '',
critical_status => ''
);
if (!defined($content) || $content eq '') {
$self->{output}->add_option_msg(short_msg => "API returns empty content [code: '" . $self->{http}->get_code() . "'] [message: '" . $self->{http}->get_message() . "']");
$self->{output}->option_exit();
}
my $decoded;
eval {
$decoded = JSON::XS->new->allow_nonref(1)->utf8->decode($content);
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot decode response (add --debug option to display returned content)");
$self->{output}->option_exit();
}
return $decoded;
}
1;
__END__
=head1 NAME
HPE Primera REST API
=head1 HPE Primera API OPTIONS
HPE Primera REST API
=over 8
=item B<--hostname>
Address of the server that hosts the API.
=item B<--port>
Define the TCP port to use to reach the API (default: 443).
=item B<--proto>
Define the protocol to reach the API (default: 'https').
=item B<--api-username>
Define the username for authentication.
=item B<--api-password>
Define the password associated with the username.
=item B<--timeout>
Define the timeout in seconds for HTTP requests (default: 30).
=back
=head1 DESCRIPTION
B<custom>.
=cut

View File

@ -0,0 +1,241 @@
#
# Copyright 2024 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 storage::hp::primera::restapi::mode::capacity;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
sub custom_space_usage_output {
my ($self, %options) = @_;
my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total});
my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used});
my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free});
return sprintf(
'space usage total: %s used: %s (%.2f%%) free: %s (%.2f%%)',
$total_size_value . " " . $total_size_unit,
$total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used},
$total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}
);
}
sub storage_long_output {
my ($self, %options) = @_;
return sprintf(
"checking storage '%s'",
$options{instance_value}->{type}
);
}
sub prefix_storage_output {
my ($self, %options) = @_;
return sprintf(
"storage '%s' ",
$options{instance_value}->{type}
);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{
name => 'storages', type => 3, cb_prefix_output => 'prefix_storage_output', cb_long_output => 'storage_long_output', indent_long_output => ' ', message_multiple => 'All storage capacities are ok',
group => [
{ name => 'space', type => 0 },
{ name => 'efficiency', type => 0, skipped_code => { -10 => 1 } }
]
}
];
$self->{maps_counters}->{space} = [
{ label => 'space-usage', nlabel => 'storage.space.usage.bytes', set => {
key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ],
closure_custom_output => $self->can('custom_space_usage_output'),
perfdatas => [
{ template => '%d', min => 0, max => 'total', unit => 'B', cast_int => 1, label_extra_instance => 1 }
]
}
},
{ label => 'space-usage-free', nlabel => 'storage.space.free.bytes', display_ok => 0, set => {
key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' } ],
closure_custom_output => $self->can('custom_space_usage_output'),
perfdatas => [
{ template => '%d', min => 0, max => 'total', unit => 'B', cast_int => 1, label_extra_instance => 1 }
]
}
},
{ label => 'space-usage-prct', nlabel => 'storage.space.usage.percentage', display_ok => 0, set => {
key_values => [ { name => 'prct_used' }, { name => 'used' }, { name => 'free' }, { name => 'prct_free' }, { name => 'total' } ],
closure_custom_output => $self->can('custom_space_usage_output'),
perfdatas => [
{ template => '%.2f', min => 0, max => 100, unit => '%', label_extra_instance => 1 }
]
}
},
{ label => 'space-unavailable', nlabel => 'storage.space.unavailable.bytes', set => {
key_values => [ { name => 'unavailable' } ],
output_template => 'unavailable: %s %s',
output_change_bytes => 1,
perfdatas => [
{ template => '%s', unit => 'B', min => 0, label_extra_instance => 1 }
]
}
},
{ label => 'space-failed', nlabel => 'storage.space.failed.bytes', set => {
key_values => [ { name => 'failed' } ],
output_template => 'failed: %s %s',
output_change_bytes => 1,
perfdatas => [
{ template => '%s', unit => 'B', min => 0, label_extra_instance => 1 }
]
}
}
];
$self->{maps_counters}->{efficiency} = [
{ label => 'compaction', nlabel => 'storage.space.compaction.ratio.count', set => {
key_values => [ { name => 'compaction' } ],
output_template => 'compaction: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1 }
]
}
},
{ label => 'deduplication', nlabel => 'storage.space.deduplication.ratio.count', set => {
key_values => [ { name => 'deduplication' } ],
output_template => 'deduplication: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1 }
]
}
},
{ label => 'compression', nlabel => 'storage.space.compression.ratio.count', set => {
key_values => [ { name => 'compression' } ],
output_template => 'compression: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1 }
]
}
},
{ label => 'data-reduction', nlabel => 'storage.space.data_reduction.ratio.count', set => {
key_values => [ { name => 'data_reduction' } ],
output_template => 'data reduction: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1 }
]
}
},
{ label => 'overprovisioning', nlabel => 'storage.space.overprovisioning.ratio.count', set => {
key_values => [ { name => 'overprovisioning' } ],
output_template => 'overprovisioning: %s',
perfdatas => [
{ template => '%s', min => 0, label_extra_instance => 1 }
]
}
}
];
}
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-type:s' => { name => 'filter_type' }
});
return $self;
}
sub manage_selection {
my ($self, %options) = @_;
my $response = $options{custom}->request_api(
endpoint => '/api/v1/capacity'
);
for my $type (keys %{$response}) {
next if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne ''
&& $type !~ /$self->{option_results}->{filter_type}/);
my $total = $response->{$type}->{totalMiB} * 1024 * 1024;
my $free = $response->{$type}->{freeMiB} * 1024 * 1024;
my $unavailable = $response->{$type}->{unavailableCapacityMiB} * 1024 * 1024;
my $failed = $response->{$type}->{failedCapacityMiB} * 1024 * 1024;
$self->{storages}->{$type} = {
type => $type,
space => {
total => $total,
free => $free,
used => $total - $free,
unavailable => $unavailable,
prct_used => ($total - $free) * 100 / $total,
prct_free => $free * 100 / $total,
failed => $failed
}
};
my $shortcut = $response->{$type}->{allocated}->{volumes}->{capacityEfficiency};
$self->{storages}->{$type}->{efficiency}->{compaction} = $shortcut->{compaction} if defined($shortcut->{compaction});
$self->{storages}->{$type}->{efficiency}->{deduplication} = $shortcut->{deduplication} if defined($shortcut->{deduplication});
$self->{storages}->{$type}->{efficiency}->{compression} = $shortcut->{compression} if defined($shortcut->{compression});
$self->{storages}->{$type}->{efficiency}->{data_reduction} = $shortcut->{dataReduction} if defined($shortcut->{dataReduction});
$self->{storages}->{$type}->{efficiency}->{overprovisioning} = $shortcut->{overProvisioning} if defined($shortcut->{overProvisioning});
}
if (scalar(keys %{$self->{storages}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "Couldn't get capacity information");
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check storage capacity per storage type.
=over 8
=item B<--filter-type>
Filter storage by type (regular expression).
The known types are: allCapacity, FCCapacity, SSDCapacity and NLCapacity.
=item B<--warning-*> B<--critical-*>
Thresholds that can apply to:
- Space oriented metrics: 'space-usage', 'space-usage-free', 'space-usage-prct', 'space-unavailable', 'space-failed',
- Storage optimization metrics: 'compaction', 'deduplication', 'compression', 'data-reduction', 'overprovisioning'.
=back
=cut

View File

@ -0,0 +1,288 @@
#
# Copyright 2024 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 storage::hp::primera::restapi::mode::diskstatus;
use base qw(centreon::plugins::templates::counter);
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng);
use strict;
use warnings;
my %map_state = (
1 => 'normal',
2 => 'degraded',
3 => 'new',
4 => 'failed',
99 => 'unknown'
);
sub custom_status_output {
my ($self, %options) = @_;
return sprintf(
"Disk #%s (%s/%s, serial: %s) located %s is %s",
$self->{result_values}->{id},
$self->{result_values}->{manufacturer},
$self->{result_values}->{model},
$self->{result_values}->{serial},
$self->{result_values}->{position},
$self->{result_values}->{status}
);
}
sub prefix_global_output {
my ($self, %options) = @_;
return 'Disks ';
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', cb_prefix_output => 'prefix_global_output', type => 0 },
{ name => 'disks', type => 1, message_multiple => 'All disks are ok' }
];
$self->{maps_counters}->{global} = [
{ label => 'disks-total', nlabel => 'disks.total.count', set => {
key_values => [ { name => 'total' } ],
output_template => 'total: %s',
perfdatas => [
{ template => '%s', min => 0 }
]
}
},
{ label => 'disks-normal', nlabel => 'disks.normal.count', set => {
key_values => [ { name => 'normal' }, { name => 'total' } ],
output_template => 'normal: %s',
perfdatas => [
{ template => '%s', min => 0, max => 'total' }
]
}
},
{ label => 'disks-degraded', nlabel => 'disks.degraded.count', set => {
key_values => [ { name => 'degraded' }, { name => 'total' } ],
output_template => 'degraded: %s',
perfdatas => [
{ template => '%s', min => 0, max => 'total' }
]
}
},
{ label => 'disks-new', nlabel => 'disks.new.count', set => {
key_values => [ { name => 'new' }, { name => 'total' } ],
output_template => 'new: %s',
perfdatas => [
{ template => '%s', min => 0, max => 'total' }
]
}
},
{ label => 'disks-failed', nlabel => 'disks.failed.count', set => {
key_values => [ { name => 'failed' }, { name => 'total' } ],
output_template => 'failed: %s',
perfdatas => [
{ template => '%s', min => 0, max => 'total' }
]
}
},
{ label => 'disks-unknown', nlabel => 'disks.unknown.count', set => {
key_values => [ { name => 'unknown' }, { name => 'total' } ],
output_template => 'unknown: %s',
perfdatas => [
{ template => '%s', min => 0, max => 'total' }
]
}
}
];
$self->{maps_counters}->{disks} = [
{
label => 'status',
type => 2,
warning_default => '%{status} =~ /^(new|degraded|unknown)$/',
critical_default => '%{status} =~ /failed/',
unknown_default => '%{status} =~ /NOT_DOCUMENTED$/',
set => {
key_values => [ { name => 'status' }, { name => 'id' }, { name => 'manufacturer' }, { name => 'model' }, { name => 'serial' }, { name => 'position' } ],
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
}
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-id:s' => { name => 'filter_id' },
'filter-manufacturer:s' => { name => 'filter_manufacturer' },
'filter-model:s' => { name => 'filter_model' },
'filter-position:s' => { name => 'filter_position' },
'filter-serial:s' => { name => 'filter_serial' }
});
return $self;
}
sub manage_selection {
my ($self, %options) = @_;
my $api_response = $options{custom}->request_api(
endpoint => '/api/v1/disks'
);
my $disks = $api_response->{members};
$self->{global} = {
total => 0,
normal => 0,
degraded => 0,
new => 0,
failed => 0,
unknown => 0
};
for my $disk (@{$disks}) {
my $disk_intro = "disk #" . $disk->{id} . " (" . $disk->{manufacturer} . "/" . $disk->{model}
. ", serial: " . $disk->{serialNumber} . ") located '" . $disk->{position};
# skip if filtered by id
if (defined($self->{option_results}->{filter_id})
and $self->{option_results}->{filter_id} ne ''
and $disk->{id} !~ /$self->{option_results}->{filter_id}/) {
$self->{output}->output_add(long_msg => "Skipping $disk_intro because the id does not match the filter.", debug => 1);
next;
}
# skip if filtered by manufacturer
if (defined($self->{option_results}->{filter_manufacturer})
and $self->{option_results}->{filter_manufacturer} ne ''
and $disk->{manufacturer} !~ /$self->{option_results}->{filter_manufacturer}/) {
$self->{output}->output_add(long_msg => "Skipping $disk_intro because the manufacturer does not match the filter.", debug => 1);
next;
}
# skip if filtered by model
if (defined($self->{option_results}->{filter_model})
and $self->{option_results}->{filter_model} ne ''
and $disk->{model} !~ /$self->{option_results}->{filter_model}/) {
$self->{output}->output_add(long_msg => "Skipping $disk_intro because the model does not match the filter.", debug => 1);
next;
}
# skip if filtered by position
if (defined($self->{option_results}->{filter_position})
and $self->{option_results}->{filter_position} ne ''
and $disk->{position} !~ /$self->{option_results}->{filter_position}/) {
$self->{output}->output_add(long_msg => "Skipping $disk_intro because the position does not match the filter.", debug => 1);
next;
}
# skip if filtered by serial
if (defined($self->{option_results}->{filter_serial})
and $self->{option_results}->{filter_serial} ne ''
and $disk->{serial} !~ /$self->{option_results}->{filter_serial}/) {
$self->{output}->output_add(long_msg => "Skipping $disk_intro because the serial does not match the filter.", debug => 1);
next;
}
my $state = defined($map_state{$disk->{state}}) ? $map_state{$disk->{state}} : 'NOT_DOCUMENTED';
# increment adequate global counters
$self->{global}->{total} = $self->{global}->{total} + 1;
$self->{global}->{$state} = $self->{global}->{$state} + 1;
# add the instance
$self->{disks}->{ $disk->{id} } = {
status => $state,
position => $disk->{position},
id => $disk->{id},
manufacturer => $disk->{manufacturer},
model => $disk->{model},
serial => $disk->{serialNumber}
};
}
}
1;
__END__
=head1 MODE
Monitor the states of the physical disks.
=over 8
=item B<--filter-id>
Define which disks should be monitored based on their IDs.
This option will be treated as a regular expression.
=item B<--filter-manufacturer>
Define which volumes should be monitored based on the disk manufacturer.
This option will be treated as a regular expression.
=item B<--filter-model>
Define which volumes should be monitored based on the disk model.
This option will be treated as a regular expression.
=item B<--filter-serial>
Define which volumes should be monitored based on the disk serial number.
This option will be treated as a regular expression.
=item B<--filter-position>
Define which volumes should be monitored based on the disk position.
The position is composed of 3 integers, separated by colons:
- Cage number where the physical disk is in.
- Magazine number where the physical disk is in.
- For DC4 cages, disk position within the magazine. For non-DC4 cages, 0.
Example: 7:5:0
This option will be treated as a regular expression.
=item B<--warning-status>
Define the condition to match for the returned status to be WARNING.
Default: '%{status} =~ /^(new|degraded|unknown)$/'
=item B<--critical-status>
Define the condition to match for the returned status to be CRITICAL.
Default: '%{status} =~ /failed/'
=item B<--unknown-status>
Define the condition to match for the returned status to be UNKNOWN.
Default: '%{status} =~ /NOT_DOCUMENTED$/'
=item B<--warning-*> B<--critical-*>
Thresholds. '*' may stand for 'disks-total', 'disks-normal', 'disks-degraded', 'disks-new',
'disks-failed', 'disks-unknown'.
=back
=cut

View File

@ -0,0 +1,304 @@
#
# Copyright 2024 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 storage::hp::primera::restapi::mode::diskusage;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
sub custom_usage_output {
my ($self, %options) = @_;
my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total});
my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used});
my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free});
return sprintf(
"Used: %s of %s (%.2f%%) Free: %s (%.2f%%)",
$total_used_value . " " . $total_used_unit,
$total_size_value . " " . $total_size_unit,
$self->{result_values}->{prct_used},
$total_free_value . " " . $total_free_unit,
$self->{result_values}->{prct_free}
);
}
sub custom_global_total_usage_output {
my ($self, %options) = @_;
my ($used_human, $used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used});
my ($total_human, $total_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total});
my $msg = "Total Used: $used_human $used_unit / $total_human $total_unit" ;
return $msg;
}
sub custom_global_total_free_output {
my ($self, %options) = @_;
my ($free_human, $free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free});
my $msg = "Total Free: $free_human $free_unit" ;
return $msg;
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0 },
{ name => 'disk', type => 1, cb_prefix_output => 'prefix_disk_output', message_multiple => 'All disks are ok' },
];
$self->{maps_counters}->{global} = [
{
label => 'total-usage',
nlabel => 'disks.total.space.usage.bytes',
set => {
key_values => [ { name => 'used' }, { name => 'total' } ],
closure_custom_output => $self->can('custom_global_total_usage_output'),
perfdatas => [
{ template => '%s', min => 0, max => 'total' }
]
}
},
{
label => 'total-usage-prct',
nlabel => 'disks.total.space.usage.percent',
set => {
key_values => [ { name => 'used_prct' }],
output_template => 'Total percentage used: %.2f %%',
perfdatas => [
{ template => '%s', uom => '%', min => 0, max => 100 }
]
}
},
{
label => 'total-free',
nlabel => 'disks.total.space.free.bytes',
set => {
key_values => [ { name => 'free' }, { name => 'total' } ],
closure_custom_output => $self->can('custom_global_total_free_output'),
perfdatas => [
{ template => '%s', min => 0, max => 'total' }
]
}
}
];
$self->{maps_counters}->{disk} = [
{ label => 'usage', nlabel => 'disk.space.usage.bytes', set => {
key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' }, { name => 'id' }, { name => 'position' }, { name => 'manufacturer' }, { name => 'model' }, { name => 'serial' } ],
closure_custom_output => $self->can('custom_usage_output'),
perfdatas => [
{ template => '%d', min => 0, max => 'total', unit => 'B', cast_int => 1, label_extra_instance => 1, instance_use => 'id' }
]
}
},
{ label => 'usage-free', display_ok => 0, nlabel => 'disk.space.free.bytes', set => {
key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' }, { name => 'id' }, { name => 'position' }, { name => 'manufacturer' }, { name => 'model' }, { name => 'serial' } ],
closure_custom_output => $self->can('custom_usage_output'),
perfdatas => [
{ template => '%d', min => 0, max => 'total', unit => 'B', cast_int => 1, label_extra_instance => 1, instance_use => 'id' }
]
}
},
{ label => 'usage-prct', display_ok => 0, nlabel => 'disk.space.usage.percentage', set => {
key_values => [ { name => 'prct_used' }, { name => 'id' }, { name => 'position' }, { name => 'manufacturer' }, { name => 'model' }, { name => 'serial' } ],
output_template => 'Used : %.2f %%',
perfdatas => [
{ template => '%.2f', min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'id' }
]
}
}
];
}
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-id:s' => { name => 'filter_id' },
'filter-manufacturer:s' => { name => 'filter_manufacturer' },
'filter-model:s' => { name => 'filter_model' },
'filter-serial:s' => { name => 'filter_serial' },
'filter-position:s' => { name => 'filter_position' },
});
return $self;
}
sub prefix_disk_output {
my ($self, %options) = @_;
#return "Disk '" . $options{instance_value}->{display} . "' ";
return sprintf(
"Disk #%s (%s/%s, serial: %s) located %s has ",
$options{instance_value}->{id},
$options{instance_value}->{manufacturer},
$options{instance_value}->{model},
$options{instance_value}->{serial},
$options{instance_value}->{position}
);
}
sub manage_selection {
my ($self, %options) = @_;
my $response = $options{custom}->request_api(
endpoint => '/api/v1/disks'
);
my $disks = $response->{members};
$self->{global} = {
total => 0,
free => 0,
used => 0,
used_prct => 0
};
$self->{disk} = {};
for my $disk (@{$disks}) {
my $disk_intro = "disk #" . $disk->{id} . " (" . $disk->{manufacturer} . "/" . $disk->{model}
. ", serial: " . $disk->{serialNumber} . ") located '" . $disk->{position};
# skip if filtered by id
if (defined($self->{option_results}->{filter_id})
and $self->{option_results}->{filter_id} ne ''
and $disk->{id} !~ /$self->{option_results}->{filter_id}/) {
$self->{output}->output_add(long_msg => "Skipping $disk_intro because the id does not match the filter.", debug => 1);
next;
}
# skip if filtered by manufacturer
if (defined($self->{option_results}->{filter_manufacturer})
and $self->{option_results}->{filter_manufacturer} ne ''
and $disk->{manufacturer} !~ /$self->{option_results}->{filter_manufacturer}/) {
$self->{output}->output_add(long_msg => "Skipping $disk_intro because the manufacturer does not match the filter.", debug => 1);
next;
}
# skip if filtered by model
if (defined($self->{option_results}->{filter_model})
and $self->{option_results}->{filter_model} ne ''
and $disk->{model} !~ /$self->{option_results}->{filter_model}/) {
$self->{output}->output_add(long_msg => "Skipping $disk_intro because the model does not match the filter.", debug => 1);
next;
}
# skip if filtered by position
if (defined($self->{option_results}->{filter_position})
and $self->{option_results}->{filter_position} ne ''
and $disk->{position} !~ /$self->{option_results}->{filter_position}/) {
$self->{output}->output_add(long_msg => "Skipping $disk_intro because the position does not match the filter.", debug => 1);
next;
}
# skip if filtered by serial
if (defined($self->{option_results}->{filter_serial})
and $self->{option_results}->{filter_serial} ne ''
and $disk->{serial} !~ /$self->{option_results}->{filter_serial}/) {
$self->{output}->output_add(long_msg => "Skipping $disk_intro because the serial does not match the filter.", debug => 1);
next;
}
my $total = $disk->{totalSizeMiB} * 1024 * 1024;
my $free = $disk->{freeSizeMiB} * 1024 * 1024;
my $used = $total - $free;
$self->{global}->{total} = $self->{global}->{total} + $total;
$self->{global}->{free} = $self->{global}->{free} + $free;
$self->{global}->{used} = $self->{global}->{used} + $used;
$self->{disk}->{$disk->{id}} = {
id => $disk->{id},
total => $total,
used => $used,
free => $free,
prct_used => $used * 100 / $total,
prct_free => $free * 100 / $total,
manufacturer => $disk->{manufacturer},
model => $disk->{model},
serial => $disk->{serialNumber},
position => $disk->{position}
};
}
$self->{global}->{used_prct} = $self->{global}->{used} * 100 / $self->{global}->{total} if ($self->{global}->{total} > 0);
if (scalar(keys %{$self->{disk}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "No disk found.");
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check disk usage.
=over 8
=item B<--filter-counters>
Define which counters (filtered by regular expression) should be monitored.
Example: --filter-counters='^usage$'
=item B<--filter-id>
Define which disks should be monitored based on their IDs.
This option will be treated as a regular expression.
=item B<--filter-manufacturer>
Define which volumes should be monitored based on the disk manufacturer.
This option will be treated as a regular expression.
=item B<--filter-model>
Define which volumes should be monitored based on the disk model.
This option will be treated as a regular expression.
=item B<--filter-serial>
Define which volumes should be monitored based on the disk serial number.
This option will be treated as a regular expression.
=item B<--filter-position>
Define which volumes should be monitored based on the disk position.
The position is composed of 3 integers, separated by colons:
- Cage number where the physical disk is in.
- Magazine number where the physical disk is in.
- For DC4 cages, disk position within the magazine. For non-DC4 cages, 0.
Example: 7:5:0
This option will be treated as a regular expression.
=item B<--warning-*> B<--critical-*>
Thresholds for disk usage metrics. * may be replaced with:
- For individual disks: 'usage' (B), 'usage-free' (B), 'usage-prct' (%).
- For global statistics: 'total-usage' (B), 'total-free' (B), 'total-usage-prct' (%).
=back
=cut

View File

@ -0,0 +1,208 @@
#
# Copyright 2024 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 storage::hp::primera::restapi::mode::licenses;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
sub custom_license_output {
my ($self, %options) = @_;
my $message;
if (!defined($self->{result_values}->{expires_seconds})) {
$message = $self->{result_values}->{name} . ' has permanent license';
} elsif ($self->{result_values}->{expires_seconds} == 0) {
$message = sprintf(
"%s license has expired.",
$self->{result_values}->{name}
);
} else {
$message = sprintf(
"%s license expires in %s.",
$self->{result_values}->{name},
centreon::plugins::misc::change_seconds(value => $self->{result_values}->{expires_seconds})
);
}
return $message;
}
sub custom_license_perfdata {
my ($self, %options) = @_;
return if ($self->{result_values}->{expires_seconds} eq 'permanent');
$self->{output}->perfdata_add(
nlabel => $self->{nlabel},
unit => 's',
instances => $self->{result_values}->{name},
value => $self->{result_values}->{expires_seconds},
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}),
min => 0
);
}
sub custom_license_threshold {
my ($self, %options) = @_;
return 'ok' if (!defined($self->{result_values}->{expires_seconds}));
return $self->{perfdata}->threshold_check(
value => $self->{result_values}->{expires_seconds},
threshold => [
{ label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' },
{ label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' }
]
);
}
sub prefix_license_output {
my ($self, %options) = @_;
return "License '" . $options{instance_value}->{name} . "' expires: " . $options{instance_value}->{expiration_human} . ". ";
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0 },
{ name => 'license_expiration', type => 1, cb_prefix_output => 'prefix_license_output', message_multiple => 'All licenses are ok'} #, cb_prefix_output => 'prefix_license_output'
];
$self->{maps_counters}->{global} = [
{
label => 'total',
nlabel => 'licenses.total.count',
set => {
key_values => [ { name => 'total' } ],
output_template => 'Number of licenses: %s',
perfdatas => [
{ template => '%s', min => 0 }
]
}
},
{
label => 'expired',
nlabel => 'licenses.expired.count',
set => {
key_values => [ { name => 'expired' }, { name => 'total' } ],
output_template => 'Number of expired licenses: %s',
perfdatas => [
{ template => '%s', min => 0, max => 'total' }
]
}
}
];
$self->{maps_counters}->{license_expiration} = [
{ label => 'license-expiration', nlabel => 'license.expiration.seconds', set => {
key_values => [ { name => 'name' }, { name => 'expires_seconds' }, { name => 'expiration_status' }, { name => 'expiration_human' }],
closure_custom_output => $self->can('custom_license_output'),
closure_custom_perfdata => $self->can('custom_license_perfdata'),
closure_custom_threshold_check => $self->can('custom_license_threshold')
}
}
];
}
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' }
});
return $self;
}
sub manage_selection {
my ($self, %options) = @_;
my $response = $options{custom}->request_api(
endpoint => '/api/v1/system'
);
my $licenses = $response->{licenseInfo}->{licenses};
my ($total_licenses, $expired_licenses) = (0, 0);
for my $license_item (@{$licenses}) {
# skip if filter does not match
next if (defined($self->{option_results}->{filter_name})
and $self->{option_results}->{filter_name} ne ''
and $license_item->{name} !~ /$self->{option_results}->{filter_name}/);
$total_licenses = $total_licenses + 1;
$self->{license_expiration}->{$license_item->{name}} = {
name => $license_item->{name},
expiration_human => defined($license_item->{expiryTime8601}) ? $license_item->{expiryTime8601} : 'never'
};
my $license_status = 'valid';
if (defined($license_item->{expiryTimeSec})) {
if ($license_item->{expiryTimeSec} > time()) {
$self->{license_expiration}->{$license_item->{name}}->{expires_seconds} = $license_item->{expiryTimeSec} - time();
} else {
$self->{license_expiration}->{$license_item->{name}}->{expires_seconds} = 0;
$license_status = 'expired';
$expired_licenses = $expired_licenses + 1;
}
}
$self->{license_expiration}->{$license_item->{name}}->{expiration_status} = $license_status;
}
$self->{global} = {
total => $total_licenses,
expired => $expired_licenses
};
if (scalar(keys %{$self->{license_expiration}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "Couldn't get information about licenses");
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check storage capacities.
=over 8
=item B<--filter-name>
Filter licenses by name (regular expression).
=item B<--warning-*> B<--critical-*>
Thresholds for counters and license validity remaining time in seconds.
* may be replaced with:
'total': applies to the total number of licenses.
'expired': applies to the number of expired licenses.
'license-expiration': applies to the remaining time in seconds until the licenses will expire.
=back
=cut

View File

@ -0,0 +1,111 @@
#
# Copyright 2024 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 storage::hp::primera::restapi::mode::listdisks;
use strict;
use warnings;
use base qw(centreon::plugins::mode);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub run {
my ($self, %options) = @_;
my $response = $options{custom}->request_api( endpoint => '/api/v1/disks' );
my $disks = $response->{members};
$self->{disks} = [];
for my $disk (@{$disks}) {
push @{$self->{disks}}, {
id => $disk->{id},
position => $disk->{position},
size => $disk->{totalSizeMiB},
manufacturer => $disk->{manufacturer},
model => $disk->{model},
serial => $disk->{serialNumber}
};
$self->{output}->output_add(
long_msg => sprintf(
"[id: %s][position: %s][size: %s][manufacturer: %s][model: %s][serial: %s]",
$disk->{id},
$disk->{position},
$disk->{totalSizeMiB},
$disk->{manufacturer},
$disk->{model},
$disk->{serialNumber}
)
);
}
if (!defined($options{disco_show})) {
$self->{output}->output_add(severity => 'OK', short_msg => 'Disks:');
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
}
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements => [ 'id', 'position','size', 'manufacturer', 'model', 'serial' ]);
}
sub disco_show {
my ($self, %options) = @_;
$options{disco_show} = 1;
$self->run(%options);
for my $disk (@{$self->{disks}}) {
$self->{output}->add_disco_entry(
id => $disk->{id},
position => $disk->{position},
size => $disk->{size},
manufacturer => $disk->{manufacturer},
model => $disk->{model},
serial => $disk->{serial}
);
}
}
1;
__END__
=head1 MODE
List physical disks using the HPE Primera REST API.
=back
=cut

View File

@ -0,0 +1,105 @@
#
# Copyright 2024 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 storage::hp::primera::restapi::mode::listvolumes;
use strict;
use warnings;
use base qw(centreon::plugins::mode);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
}
sub run {
my ($self, %options) = @_;
my $response = $options{custom}->request_api( endpoint => '/api/v1/volumes' );
my $volumes = $response->{members};
$self->{volumes} = [];
for my $disk (@{$volumes}) {
push @{$self->{volumes}}, {
id => $disk->{id},
name => $disk->{name},
size => $disk->{sizeMiB},
state => $disk->{state}
};
$self->{output}->output_add(
long_msg => sprintf(
"[id: %s][name: %s][size: %s][state: %s]",
$disk->{id},
$disk->{name},
$disk->{sizeMiB},
$disk->{state}
)
);
}
if (!defined($options{disco_show})) {
$self->{output}->output_add(severity => 'OK', short_msg => 'Volumes:');
$self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1);
}
}
sub disco_format {
my ($self, %options) = @_;
$self->{output}->add_disco_format(elements => [ 'id', 'name','size', 'state' ]);
}
sub disco_show {
my ($self, %options) = @_;
$options{disco_show} = 1;
$self->run(%options);
for my $disk (@{$self->{volumes}}) {
$self->{output}->add_disco_entry(
id => $disk->{id},
name => $disk->{name},
size => $disk->{size},
state => $disk->{state}
);
}
}
1;
__END__
=head1 MODE
List physical volumes using the HPE Primera REST API.
=back
=cut

View File

@ -0,0 +1,215 @@
#
# Copyright 2024 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 storage::hp::primera::restapi::mode::nodes;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold catalog_status_calc catalog_status_threshold_ng);
sub custom_node_output {
my ($self, %options) = @_;
return sprintf(
"node %s is %s",
$self->{result_values}->{id},
$self->{result_values}->{status}
);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0, skipped_code => { -10 => 1 } },
{ name => 'nodes', type => 1, message_multiple => 'All nodes are online.' },
];
$self->{maps_counters}->{global} = [
{
label => 'total',
nlabel => 'nodes.total.count',
set => {
key_values => [ { name => 'total' } ],
output_template => 'Total number of nodes: %s',
perfdatas => [
{ template => '%s', min => 0 }
]
}
},
{
label => 'online',
nlabel => 'nodes.online.count',
set => {
key_values => [ { name => 'online' }, { name => 'total' } ],
output_template => 'Number of online nodes: %s',
perfdatas => [
{ template => '%s', min => 0, max => 'total' }
]
}
},
{
label => 'offline',
nlabel => 'nodes.offline.count',
set => {
key_values => [ { name => 'offline' }, { name => 'total' } ],
output_template => 'Number of offline nodes: %s',
perfdatas => [
{ template => '%s', min => 0, max => 'total' }
]
}
}
];
$self->{maps_counters}->{nodes} = [
{
label => 'node-status',
type => 2,
warning_default => '%{status} !~ /^online$/',
set => {
key_values => [ { name => 'status' }, { name => 'id' } ],
closure_custom_output => $self->can('custom_node_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => \&catalog_status_threshold_ng
}
}
];
}
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-node:s' => { name => 'filter_node' }
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
}
sub manage_selection {
my ($self, %options) = @_;
my $response = $options{custom}->request_api(
endpoint => '/api/v1/system'
);
my $total_nodes = 0;
my $online_nodes = 0;
my $offline_nodes = 0;
# Typical content of onlineNodes is [0, 1]
# This is the list of the nodes that are currently connected
# Each number is the ID of a node
# %online_nodes_statuses associates 'online' to every online node with the node ID as key.
# Example {'0' => 'online', '1' => 'online'} if both nodes are online (corresponding to input [0, 1])
# Example {'0' => 'online'} if only the node of ID 0 is online (corresponding to input [0])
my %online_nodes_statuses = map { $_ => 'online' } @{ $response->{onlineNodes} };
# Typical content of clusterNodes is [0, 1]
# %all_nodes_statuses uses this data and the data from %online_nodes_statuses to give the status of all nodes
# Example: {[0] => 'online', [1] => 'offline'}
my %all_nodes_statuses = map {$_ => defined($online_nodes_statuses{$_}) ? $online_nodes_statuses{$_} : 'offline'} @{ $response->{clusterNodes} };
for my $node (keys(%all_nodes_statuses)) {
next if (defined($self->{option_results}->{filter_node})
and $self->{option_results}->{filter_node} ne ''
and $node !~ /$self->{option_results}->{filter_node}/);
$total_nodes = $total_nodes + 1;
if ($all_nodes_statuses{$node} eq 'online') {
$online_nodes = $online_nodes + 1;
} else {
$offline_nodes = $offline_nodes + 1;
}
$self->{nodes}->{$node} = {
id => $node,
status => $all_nodes_statuses{$node}
}
}
$self->{global} = {
total => $total_nodes,
online => $online_nodes,
offline => $offline_nodes
}
}
1;
__END__
=head1 MODE
Check if the configured nodes of the HPE Primera cluster are all online.
=over 8
=item B<--filter-node>
Define which nodes (filtered by regular expression) should be monitored.
Example: --filter-node='^(0|1)$'
=item B<--warning-node-status>
Define the conditions to match for the status to be WARNING. (default: '%{status} ne "online"').
You can use the %{status} variables.
=item B<--critical-node-status>
Define the conditions to match for the status to be CRITICAL
You can use the %{status} variables.
=item B<--warning-total>
Thresholds for the total number of nodes.
=item B<--critical-total>
Thresholds for the total number of nodes.
=item B<--warning-online>
Thresholds for the number of online nodes.
=item B<--critical-online>
Thresholds for the number of online nodes.
=item B<--warning-offline>
Thresholds for the number of offline nodes.
=item B<--critical-offline>
Thresholds for the number of offline nodes.
=back
=cut

View File

@ -0,0 +1,174 @@
#
# Copyright 2024 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 storage::hp::primera::restapi::mode::volumeusage;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
sub custom_usage_output {
my ($self, %options) = @_;
my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total});
my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used});
my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free});
return sprintf(
"Usage Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)",
$total_size_value . " " . $total_size_unit,
$total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used},
$total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}
);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'volume', type => 1, cb_prefix_output => 'prefix_volume_output', message_multiple => 'All volumes are ok' },
];
$self->{maps_counters}->{volume} = [
{ label => 'usage', nlabel => 'volume.space.usage.bytes', set => {
key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' }, { name => 'name' }, { name => 'id' } ],
closure_custom_output => $self->can('custom_usage_output'),
perfdatas => [
{ template => '%d', min => 0, max => 'total', unit => 'B', cast_int => 1, label_extra_instance => 1, instance_use => 'name' }
]
}
},
{ label => 'usage-free', display_ok => 0, nlabel => 'volume.space.free.bytes', set => {
key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' }, , { name => 'name' }, { name => 'id' } ],
closure_custom_output => $self->can('custom_usage_output'),
perfdatas => [
{ template => '%d', min => 0, max => 'total', unit => 'B', cast_int => 1, label_extra_instance => 1, instance_use => 'name' }
]
}
},
{ label => 'usage-prct', display_ok => 0, nlabel => 'volume.space.usage.percentage', set => {
key_values => [ { name => 'prct_used' }, { name => 'name' }, { name => 'id' } ],
output_template => 'Used : %.2f %%',
perfdatas => [
{ template => '%.2f', min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'name' }
]
}
}
];
}
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-id:s' => { name => 'filter_id' },
'filter-name:s' => { name => 'filter_name' }
});
return $self;
}
sub prefix_volume_output {
my ($self, %options) = @_;
return "Volume '" . $options{instance_value}->{name} . "' (#" . $options{instance_value}->{id} . ") ";
}
sub manage_selection {
my ($self, %options) = @_;
my $response = $options{custom}->request_api(endpoint => '/api/v1/volumes');
my $volumes = $response->{members};
$self->{volume} = {};
for my $volume (@{$volumes}) {
my $name = $volume->{name};
my $id = $volume->{id};
if (defined($self->{option_results}->{filter_name}) and $self->{option_results}->{filter_name} ne '' and
$name !~ /$self->{option_results}->{filter_name}/) {
$self->{output}->output_add(long_msg => "Skipping volume named '" . $name . "': not matching filter /" . $self->{option_results}->{filter_name} . "/.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_id}) and $self->{option_results}->{filter_id} ne '' and
$id !~ /$self->{option_results}->{filter_id}/) {
$self->{output}->output_add(long_msg => "Skipping volume #" . $id . ": not matching filter /" . $self->{option_results}->{filter_id} . "/.", debug => 1);
next;
}
my $total = $volume->{sizeMiB} * 1024 * 1024;
my $snap_used = $volume->{snapshotSpace}->{usedMiB};
my $adm_used = $volume->{adminSpace}->{usedMiB};
my $usr_used = $volume->{userSpace}->{usedMiB};
my $used = ($snap_used + $adm_used + $usr_used) * 1024 * 1024;
$self->{volume}->{$name} = {
id => $id,
name => $name,
total => $total,
used => $used,
free => ($total - $used) >= 0 ? ($total - $used) : 0,
prct_used => $used * 100 / $total,
prct_free => (100 - ($used * 100 / $total) >= 0) ? (100 - ($used * 100 / $total)) : 0
};
}
if (scalar(keys %{$self->{volume}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "No volume found.");
$self->{output}->option_exit();
}
}
1;
__END__
=head1 MODE
Check volume usage.
=over 8
=item B<--filter-counters>
Define which counters (filtered by regular expression) should be monitored.
Example: --filter-counters='^usage$'
=item B<--filter-id>
Define which volumes should be monitored based on their IDs.
This option will be treated as a regular expression.
=item B<--filter-name>
Define which volumes should be monitored based on the volume names.
This option will be treated as a regular expression.
=item B<--warning-*> B<--critical-*>
Thresholds for volume usage metrics.
* may be replaced with:
'usage' (B), 'usage-free' (B), 'usage-prct' (%).
=back
=cut

View File

@ -0,0 +1,55 @@
#
# Copyright 2024 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 storage::hp::primera::restapi::plugin;
use strict;
use warnings;
use base qw(centreon::plugins::script_custom);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{modes} = {
'capacity' => 'storage::hp::primera::restapi::mode::capacity',
'disk-status' => 'storage::hp::primera::restapi::mode::diskstatus',
'disk-usage' => 'storage::hp::primera::restapi::mode::diskusage',
'licenses' => 'storage::hp::primera::restapi::mode::licenses',
'list-disks' => 'storage::hp::primera::restapi::mode::listdisks',
'list-volumes' => 'storage::hp::primera::restapi::mode::listvolumes',
'nodes' => 'storage::hp::primera::restapi::mode::nodes',
'volume-usage' => 'storage::hp::primera::restapi::mode::volumeusage',
};
$self->{custom_modes}->{api} = 'storage::hp::primera::restapi::custom::api';
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Monitor HPE Primera storage controller.
=cut

View File

@ -1,7 +1,9 @@
--add-sysdesc
--api-filter-orgs
--api-password
--api-password
--api-token
--api-username
--api-version
--cacert-file
--cert-pkcs12
@ -20,6 +22,7 @@
--force-oid
--get-param
--ignore-orgs-api-disabled
--jobq
--legacy-api-beta
--lookup-perfdatas-nagios
--map-speed-dsl
@ -55,14 +58,19 @@ Centreon
cpu-utilization-1m
cpu-utilization-5m
cpu-utilization-5s
DC4
Datacore
FCCapacity
Fortigate
Fortinet
HPE
HashiCorp
ISAM
IMEI
IpAddr
ISAM
Iwsva
JOBQ
Loggly
MBean
MIB
@ -75,16 +83,19 @@ module-cellradio-rsrq
module-cellradio-snr
modules-cellradio-detected
Mosquitto
NLCapacity
NTLMv2
NagVis
Nagios
Netscaler
OID
PKCS1
Primera
QoS
RestAPI
RRDCached
SNMP
SSDCapacity
SSH
Sansymphony
SureBackup
@ -93,14 +104,16 @@ TrendMicro
UCD
VDSL2
VM
Veeam
VPN
Veeam
WSMAN
XPath
allCapacity
api.meraki.com
cardtemperature
connections-dhcp
connections-dns
deduplication
datasource
deltaps
df
@ -114,6 +127,8 @@ in-bcast
in-mcast
in-ucast
interface-dsl-name
jobqueue
jobqueues
keepass
ldap
license-instances-usage-prct
@ -122,9 +137,11 @@ oneaccess-sys-mib
out-bcast
out-mcast
out-ucast
overprovisioning
perfdata
powershell
powershell.exe
prct
proto
psu
queue-messages-inflighted

View File

@ -0,0 +1,54 @@
*** Settings ***
Documentation HPE Primera Storage REST API
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}hpe-primera.mockoon.json
${HOSTNAME} 127.0.0.1
${APIPORT} 3000
${CMD} ${CENTREON_PLUGINS}
... --plugin=storage::hp::primera::restapi::plugin
... --mode=capacity
... --hostname=${HOSTNAME}
... --api-username=toto
... --api-password=toto
... --proto=http
... --port=${APIPORT}
... --custommode=api
... --statefile-dir=/dev/shm/
*** Test Cases ***
Capacity ${tc}
[Tags] storage api hpe hp
${output} Run ${CMD} ${extraoptions}
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${expected_result}
... Wrong output result for command:\n${CMD} ${extraoptions}\n\nObtained:\n${output}\n\nExpected:\n${expected_result}\n
... values=False
... collapse_spaces=True
Examples: tc extraoptions expected_result --
... 1 --filter-type=allCapacity OK: storage 'allCapacity' space usage total: 378.60 TB used: 127.11 TB (33.57%) free: 251.50 TB (66.43%), unavailable: 0.00 B, failed: 0.00 B - compaction: 1.66, deduplication: 1.02, compression: 1.37, data reduction: 1.37, overprovisioning: 0.45 | 'allCapacity#storage.space.usage.bytes'=139755014586368B;;;0;416278967746560 'allCapacity#storage.space.free.bytes'=276523953160192B;;;0;416278967746560 'allCapacity#storage.space.usage.percentage'=33.57%;;;0;100 'allCapacity#storage.space.unavailable.bytes'=0B;;;0; 'allCapacity#storage.space.failed.bytes'=0B;;;0; 'allCapacity#storage.space.compaction.ratio.count'=1.66;;;0; 'allCapacity#storage.space.deduplication.ratio.count'=1.02;;;0; 'allCapacity#storage.space.compression.ratio.count'=1.37;;;0; 'allCapacity#storage.space.data_reduction.ratio.count'=1.37;;;0; 'allCapacity#storage.space.overprovisioning.ratio.count'=0.45;;;0;
... 2 --filter-type=FCCapacity OK: storage 'FCCapacity' space usage total: 104.72 TB used: 25.69 TB (24.53%) free: 79.03 TB (75.47%), unavailable: 0.00 B, failed: 0.00 B - compaction: 1.98, deduplication: 0, data reduction: 0, overprovisioning: 0.39 | 'FCCapacity#storage.space.usage.bytes'=28242631196672B;;;0;115139483271168 'FCCapacity#storage.space.free.bytes'=86896852074496B;;;0;115139483271168 'FCCapacity#storage.space.usage.percentage'=24.53%;;;0;100 'FCCapacity#storage.space.unavailable.bytes'=0B;;;0; 'FCCapacity#storage.space.failed.bytes'=0B;;;0; 'FCCapacity#storage.space.compaction.ratio.count'=1.98;;;0; 'FCCapacity#storage.space.deduplication.ratio.count'=0;;;0; 'FCCapacity#storage.space.data_reduction.ratio.count'=0;;;0; 'FCCapacity#storage.space.overprovisioning.ratio.count'=0.39;;;0;
... 3 --filter-type=SSDCapacity OK: storage 'SSDCapacity' space usage total: 24.43 TB used: 10.23 TB (41.88%) free: 14.20 TB (58.12%), unavailable: 0.00 B, failed: 0.00 B - compaction: 2.12, deduplication: 1.02, compression: 1.37, data reduction: 1.37, overprovisioning: 0.54 | 'SSDCapacity#storage.space.usage.bytes'=11250666831872B;;;0;26862872952832 'SSDCapacity#storage.space.free.bytes'=15612206120960B;;;0;26862872952832 'SSDCapacity#storage.space.usage.percentage'=41.88%;;;0;100 'SSDCapacity#storage.space.unavailable.bytes'=0B;;;0; 'SSDCapacity#storage.space.failed.bytes'=0B;;;0; 'SSDCapacity#storage.space.compaction.ratio.count'=2.12;;;0; 'SSDCapacity#storage.space.deduplication.ratio.count'=1.02;;;0; 'SSDCapacity#storage.space.compression.ratio.count'=1.37;;;0; 'SSDCapacity#storage.space.data_reduction.ratio.count'=1.37;;;0; 'SSDCapacity#storage.space.overprovisioning.ratio.count'=0.54;;;0;
... 4 --filter-type=NLCapacity OK: storage 'NLCapacity' space usage total: 249.45 TB used: 91.19 TB (36.55%) free: 158.27 TB (63.45%), unavailable: 0.00 B, failed: 0.00 B - compaction: 1.51, deduplication: 0, data reduction: 0, overprovisioning: 0.47 | 'NLCapacity#storage.space.usage.bytes'=100261716557824B;;;0;274276611522560 'NLCapacity#storage.space.free.bytes'=174014894964736B;;;0;274276611522560 'NLCapacity#storage.space.usage.percentage'=36.55%;;;0;100 'NLCapacity#storage.space.unavailable.bytes'=0B;;;0; 'NLCapacity#storage.space.failed.bytes'=0B;;;0; 'NLCapacity#storage.space.compaction.ratio.count'=1.51;;;0; 'NLCapacity#storage.space.deduplication.ratio.count'=0;;;0; 'NLCapacity#storage.space.data_reduction.ratio.count'=0;;;0; 'NLCapacity#storage.space.overprovisioning.ratio.count'=0.47;;;0;
... 5 --filter-type=allCapacity --warning-compaction=2: WARNING: storage 'allCapacity' compaction: 1.66 | 'allCapacity#storage.space.usage.bytes'=139755014586368B;;;0;416278967746560 'allCapacity#storage.space.free.bytes'=276523953160192B;;;0;416278967746560 'allCapacity#storage.space.usage.percentage'=33.57%;;;0;100 'allCapacity#storage.space.unavailable.bytes'=0B;;;0; 'allCapacity#storage.space.failed.bytes'=0B;;;0; 'allCapacity#storage.space.compaction.ratio.count'=1.66;2:;;0; 'allCapacity#storage.space.deduplication.ratio.count'=1.02;;;0; 'allCapacity#storage.space.compression.ratio.count'=1.37;;;0; 'allCapacity#storage.space.data_reduction.ratio.count'=1.37;;;0; 'allCapacity#storage.space.overprovisioning.ratio.count'=0.45;;;0;
... 6 --filter-type=allCapacity --critical-deduplication=2: CRITICAL: storage 'allCapacity' deduplication: 1.02 | 'allCapacity#storage.space.usage.bytes'=139755014586368B;;;0;416278967746560 'allCapacity#storage.space.free.bytes'=276523953160192B;;;0;416278967746560 'allCapacity#storage.space.usage.percentage'=33.57%;;;0;100 'allCapacity#storage.space.unavailable.bytes'=0B;;;0; 'allCapacity#storage.space.failed.bytes'=0B;;;0; 'allCapacity#storage.space.compaction.ratio.count'=1.66;;;0; 'allCapacity#storage.space.deduplication.ratio.count'=1.02;;2:;0; 'allCapacity#storage.space.compression.ratio.count'=1.37;;;0; 'allCapacity#storage.space.data_reduction.ratio.count'=1.37;;;0; 'allCapacity#storage.space.overprovisioning.ratio.count'=0.45;;;0;
... 7 --filter-type=allCapacity --warning-data-reduction=2: WARNING: storage 'allCapacity' data reduction: 1.37 | 'allCapacity#storage.space.usage.bytes'=139755014586368B;;;0;416278967746560 'allCapacity#storage.space.free.bytes'=276523953160192B;;;0;416278967746560 'allCapacity#storage.space.usage.percentage'=33.57%;;;0;100 'allCapacity#storage.space.unavailable.bytes'=0B;;;0; 'allCapacity#storage.space.failed.bytes'=0B;;;0; 'allCapacity#storage.space.compaction.ratio.count'=1.66;;;0; 'allCapacity#storage.space.deduplication.ratio.count'=1.02;;;0; 'allCapacity#storage.space.compression.ratio.count'=1.37;;;0; 'allCapacity#storage.space.data_reduction.ratio.count'=1.37;2:;;0; 'allCapacity#storage.space.overprovisioning.ratio.count'=0.45;;;0;
... 8 --filter-type=allCapacity --critical-overprovisioning=20 OK: storage 'allCapacity' space usage total: 378.60 TB used: 127.11 TB (33.57%) free: 251.50 TB (66.43%), unavailable: 0.00 B, failed: 0.00 B - compaction: 1.66, deduplication: 1.02, compression: 1.37, data reduction: 1.37, overprovisioning: 0.45 | 'allCapacity#storage.space.usage.bytes'=139755014586368B;;;0;416278967746560 'allCapacity#storage.space.free.bytes'=276523953160192B;;;0;416278967746560 'allCapacity#storage.space.usage.percentage'=33.57%;;;0;100 'allCapacity#storage.space.unavailable.bytes'=0B;;;0; 'allCapacity#storage.space.failed.bytes'=0B;;;0; 'allCapacity#storage.space.compaction.ratio.count'=1.66;;;0; 'allCapacity#storage.space.deduplication.ratio.count'=1.02;;;0; 'allCapacity#storage.space.compression.ratio.count'=1.37;;;0; 'allCapacity#storage.space.data_reduction.ratio.count'=1.37;;;0; 'allCapacity#storage.space.overprovisioning.ratio.count'=0.45;;0:20;0;
... 9 --critical-deduplication=2: CRITICAL: storage 'FCCapacity' deduplication: 0 - storage 'NLCapacity' deduplication: 0 - storage 'SSDCapacity' deduplication: 1.02 - storage 'allCapacity' deduplication: 1.02 | 'FCCapacity#storage.space.usage.bytes'=28242631196672B;;;0;115139483271168 'FCCapacity#storage.space.free.bytes'=86896852074496B;;;0;115139483271168 'FCCapacity#storage.space.usage.percentage'=24.53%;;;0;100 'FCCapacity#storage.space.unavailable.bytes'=0B;;;0; 'FCCapacity#storage.space.failed.bytes'=0B;;;0; 'FCCapacity#storage.space.compaction.ratio.count'=1.98;;;0; 'FCCapacity#storage.space.deduplication.ratio.count'=0;;2:;0; 'FCCapacity#storage.space.data_reduction.ratio.count'=0;;;0; 'FCCapacity#storage.space.overprovisioning.ratio.count'=0.39;;;0; 'NLCapacity#storage.space.usage.bytes'=100261716557824B;;;0;274276611522560 'NLCapacity#storage.space.free.bytes'=174014894964736B;;;0;274276611522560 'NLCapacity#storage.space.usage.percentage'=36.55%;;;0;100 'NLCapacity#storage.space.unavailable.bytes'=0B;;;0; 'NLCapacity#storage.space.failed.bytes'=0B;;;0; 'NLCapacity#storage.space.compaction.ratio.count'=1.51;;;0; 'NLCapacity#storage.space.deduplication.ratio.count'=0;;2:;0; 'NLCapacity#storage.space.data_reduction.ratio.count'=0;;;0; 'NLCapacity#storage.space.overprovisioning.ratio.count'=0.47;;;0; 'SSDCapacity#storage.space.usage.bytes'=11250666831872B;;;0;26862872952832 'SSDCapacity#storage.space.free.bytes'=15612206120960B;;;0;26862872952832 'SSDCapacity#storage.space.usage.percentage'=41.88%;;;0;100 'SSDCapacity#storage.space.unavailable.bytes'=0B;;;0; 'SSDCapacity#storage.space.failed.bytes'=0B;;;0; 'SSDCapacity#storage.space.compaction.ratio.count'=2.12;;;0; 'SSDCapacity#storage.space.deduplication.ratio.count'=1.02;;2:;0; 'SSDCapacity#storage.space.compression.ratio.count'=1.37;;;0; 'SSDCapacity#storage.space.data_reduction.ratio.count'=1.37;;;0; 'SSDCapacity#storage.space.overprovisioning.ratio.count'=0.54;;;0; 'allCapacity#storage.space.usage.bytes'=139755014586368B;;;0;416278967746560 'allCapacity#storage.space.free.bytes'=276523953160192B;;;0;416278967746560 'allCapacity#storage.space.usage.percentage'=33.57%;;;0;100 'allCapacity#storage.space.unavailable.bytes'=0B;;;0; 'allCapacity#storage.space.failed.bytes'=0B;;;0; 'allCapacity#storage.space.compaction.ratio.count'=1.66;;;0; 'allCapacity#storage.space.deduplication.ratio.count'=1.02;;2:;0; 'allCapacity#storage.space.compression.ratio.count'=1.37;;;0; 'allCapacity#storage.space.data_reduction.ratio.count'=1.37;;;0; 'allCapacity#storage.space.overprovisioning.ratio.count'=0.45;;;0;
... 10 --filter-type=allCapacity --warning-space-usage=180 WARNING: storage 'allCapacity' space usage total: 378.60 TB used: 127.11 TB (33.57%) free: 251.50 TB (66.43%) | 'allCapacity#storage.space.usage.bytes'=139755014586368B;0:180;;0;416278967746560 'allCapacity#storage.space.free.bytes'=276523953160192B;;;0;416278967746560 'allCapacity#storage.space.usage.percentage'=33.57%;;;0;100 'allCapacity#storage.space.unavailable.bytes'=0B;;;0; 'allCapacity#storage.space.failed.bytes'=0B;;;0; 'allCapacity#storage.space.compaction.ratio.count'=1.66;;;0; 'allCapacity#storage.space.deduplication.ratio.count'=1.02;;;0; 'allCapacity#storage.space.compression.ratio.count'=1.37;;;0; 'allCapacity#storage.space.data_reduction.ratio.count'=1.37;;;0; 'allCapacity#storage.space.overprovisioning.ratio.count'=0.45;;;0;
... 11 --filter-type=allCapacity --critical-space-usage-free=180 CRITICAL: storage 'allCapacity' space usage total: 378.60 TB used: 127.11 TB (33.57%) free: 251.50 TB (66.43%) | 'allCapacity#storage.space.usage.bytes'=139755014586368B;;;0;416278967746560 'allCapacity#storage.space.free.bytes'=276523953160192B;;0:180;0;416278967746560 'allCapacity#storage.space.usage.percentage'=33.57%;;;0;100 'allCapacity#storage.space.unavailable.bytes'=0B;;;0; 'allCapacity#storage.space.failed.bytes'=0B;;;0; 'allCapacity#storage.space.compaction.ratio.count'=1.66;;;0; 'allCapacity#storage.space.deduplication.ratio.count'=1.02;;;0; 'allCapacity#storage.space.compression.ratio.count'=1.37;;;0; 'allCapacity#storage.space.data_reduction.ratio.count'=1.37;;;0; 'allCapacity#storage.space.overprovisioning.ratio.count'=0.45;;;0;
... 12 --filter-type=allCapacity --warning-space-usage-prct=20 WARNING: storage 'allCapacity' space usage total: 378.60 TB used: 127.11 TB (33.57%) free: 251.50 TB (66.43%) | 'allCapacity#storage.space.usage.bytes'=139755014586368B;;;0;416278967746560 'allCapacity#storage.space.free.bytes'=276523953160192B;;;0;416278967746560 'allCapacity#storage.space.usage.percentage'=33.57%;0:20;;0;100 'allCapacity#storage.space.unavailable.bytes'=0B;;;0; 'allCapacity#storage.space.failed.bytes'=0B;;;0; 'allCapacity#storage.space.compaction.ratio.count'=1.66;;;0; 'allCapacity#storage.space.deduplication.ratio.count'=1.02;;;0; 'allCapacity#storage.space.compression.ratio.count'=1.37;;;0; 'allCapacity#storage.space.data_reduction.ratio.count'=1.37;;;0; 'allCapacity#storage.space.overprovisioning.ratio.count'=0.45;;;0;
... 13 --filter-type=allCapacity --critical-space-unavailable=20 OK: storage 'allCapacity' space usage total: 378.60 TB used: 127.11 TB (33.57%) free: 251.50 TB (66.43%), unavailable: 0.00 B, failed: 0.00 B - compaction: 1.66, deduplication: 1.02, compression: 1.37, data reduction: 1.37, overprovisioning: 0.45 | 'allCapacity#storage.space.usage.bytes'=139755014586368B;;;0;416278967746560 'allCapacity#storage.space.free.bytes'=276523953160192B;;;0;416278967746560 'allCapacity#storage.space.usage.percentage'=33.57%;;;0;100 'allCapacity#storage.space.unavailable.bytes'=0B;;0:20;0; 'allCapacity#storage.space.failed.bytes'=0B;;;0; 'allCapacity#storage.space.compaction.ratio.count'=1.66;;;0; 'allCapacity#storage.space.deduplication.ratio.count'=1.02;;;0; 'allCapacity#storage.space.compression.ratio.count'=1.37;;;0; 'allCapacity#storage.space.data_reduction.ratio.count'=1.37;;;0; 'allCapacity#storage.space.overprovisioning.ratio.count'=0.45;;;0;
... 14 --filter-type=allCapacity --critical-space-failed=20 OK: storage 'allCapacity' space usage total: 378.60 TB used: 127.11 TB (33.57%) free: 251.50 TB (66.43%), unavailable: 0.00 B, failed: 0.00 B - compaction: 1.66, deduplication: 1.02, compression: 1.37, data reduction: 1.37, overprovisioning: 0.45 | 'allCapacity#storage.space.usage.bytes'=139755014586368B;;;0;416278967746560 'allCapacity#storage.space.free.bytes'=276523953160192B;;;0;416278967746560 'allCapacity#storage.space.usage.percentage'=33.57%;;;0;100 'allCapacity#storage.space.unavailable.bytes'=0B;;;0; 'allCapacity#storage.space.failed.bytes'=0B;;0:20;0; 'allCapacity#storage.space.compaction.ratio.count'=1.66;;;0; 'allCapacity#storage.space.deduplication.ratio.count'=1.02;;;0; 'allCapacity#storage.space.compression.ratio.count'=1.37;;;0; 'allCapacity#storage.space.data_reduction.ratio.count'=1.37;;;0; 'allCapacity#storage.space.overprovisioning.ratio.count'=0.45;;;0;

View File

@ -0,0 +1,49 @@
*** Settings ***
Documentation HPE Primera Storage REST API
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}hpe-primera.mockoon.json
${HOSTNAME} 127.0.0.1
${APIPORT} 3000
${CMD} ${CENTREON_PLUGINS}
... --plugin=storage::hp::primera::restapi::plugin
... --mode disk-status
... --hostname=${HOSTNAME}
... --api-username=toto
... --api-password=toto
... --proto=http
... --port=${APIPORT}
... --custommode=api
... --statefile-dir=/dev/shm/
*** Test Cases ***
Diskstatus ${tc}
[Tags] storage api hpe hp
${output} Run ${CMD} ${extraoptions}
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${expected_result}
... Wrong output result for command:\n${CMD} ${extraoptions}\n\nObtained:\n${output}\n\nExpected:\n${expected_result}\n
... values=False
... collapse_spaces=True
Examples: tc extraoptions expected_result --
... 1 ${EMPTY} CRITICAL: Disk #73 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SWLT) located 7:5:0 is failed WARNING: Disk #75 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SSKT) located 8:1:0 is unknown - Disk #78 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4TLLT) located 8:4:0 is new - Disk #79 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N1TT) located 8:5:0 is new - Disk #81 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N8UT) located 8:7:0 is degraded | 'disks.total.count'=82;;;0; 'disks.normal.count'=77;;;0;82 'disks.degraded.count'=1;;;0;82 'disks.new.count'=2;;;0;82 'disks.failed.count'=1;;;0;82 'disks.unknown.count'=1;;;0;82
... 2 --critical-status='' WARNING: Disk #75 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SSKT) located 8:1:0 is unknown - Disk #78 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4TLLT) located 8:4:0 is new - Disk #79 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N1TT) located 8:5:0 is new - Disk #81 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N8UT) located 8:7:0 is degraded | 'disks.total.count'=82;;;0; 'disks.normal.count'=77;;;0;82 'disks.degraded.count'=1;;;0;82 'disks.new.count'=2;;;0;82 'disks.failed.count'=1;;;0;82 'disks.unknown.count'=1;;;0;82
... 3 --warning-status='' CRITICAL: Disk #73 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SWLT) located 7:5:0 is failed | 'disks.total.count'=82;;;0; 'disks.normal.count'=77;;;0;82 'disks.degraded.count'=1;;;0;82 'disks.new.count'=2;;;0;82 'disks.failed.count'=1;;;0;82 'disks.unknown.count'=1;;;0;82
... 4 --warning-disks-new=0 CRITICAL: Disk #73 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SWLT) located 7:5:0 is failed WARNING: Disks new: 2 - Disk #75 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SSKT) located 8:1:0 is unknown - Disk #78 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4TLLT) located 8:4:0 is new - Disk #79 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N1TT) located 8:5:0 is new - Disk #81 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N8UT) located 8:7:0 is degraded | 'disks.total.count'=82;;;0; 'disks.normal.count'=77;;;0;82 'disks.degraded.count'=1;;;0;82 'disks.new.count'=2;0:0;;0;82 'disks.failed.count'=1;;;0;82 'disks.unknown.count'=1;;;0;82
... 5 --warning-disks-total=83:83 CRITICAL: Disk #73 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SWLT) located 7:5:0 is failed WARNING: Disks total: 82 - Disk #75 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SSKT) located 8:1:0 is unknown - Disk #78 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4TLLT) located 8:4:0 is new - Disk #79 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N1TT) located 8:5:0 is new - Disk #81 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N8UT) located 8:7:0 is degraded | 'disks.total.count'=82;83:83;;0; 'disks.normal.count'=77;;;0;82 'disks.degraded.count'=1;;;0;82 'disks.new.count'=2;;;0;82 'disks.failed.count'=1;;;0;82 'disks.unknown.count'=1;;;0;82
... 6 --critical-disks-failed=0 CRITICAL: Disks failed: 1 - Disk #73 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SWLT) located 7:5:0 is failed WARNING: Disk #75 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SSKT) located 8:1:0 is unknown - Disk #78 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4TLLT) located 8:4:0 is new - Disk #79 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N1TT) located 8:5:0 is new - Disk #81 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N8UT) located 8:7:0 is degraded | 'disks.total.count'=82;;;0; 'disks.normal.count'=77;;;0;82 'disks.degraded.count'=1;;;0;82 'disks.new.count'=2;;;0;82 'disks.failed.count'=1;;0:0;0;82 'disks.unknown.count'=1;;;0;82
... 7 --warning-disks-degraded=0 CRITICAL: Disk #73 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SWLT) located 7:5:0 is failed WARNING: Disks degraded: 1 - Disk #75 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SSKT) located 8:1:0 is unknown - Disk #78 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4TLLT) located 8:4:0 is new - Disk #79 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N1TT) located 8:5:0 is new - Disk #81 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N8UT) located 8:7:0 is degraded | 'disks.total.count'=82;;;0; 'disks.normal.count'=77;;;0;82 'disks.degraded.count'=1;0:0;;0;82 'disks.new.count'=2;;;0;82 'disks.failed.count'=1;;;0;82 'disks.unknown.count'=1;;;0;82
... 8 --warning-disks-unknown=0 CRITICAL: Disk #73 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SWLT) located 7:5:0 is failed WARNING: Disks unknown: 1 - Disk #75 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SSKT) located 8:1:0 is unknown - Disk #78 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4TLLT) located 8:4:0 is new - Disk #79 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N1TT) located 8:5:0 is new - Disk #81 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N8UT) located 8:7:0 is degraded | 'disks.total.count'=82;;;0; 'disks.normal.count'=77;;;0;82 'disks.degraded.count'=1;;;0;82 'disks.new.count'=2;;;0;82 'disks.failed.count'=1;;;0;82 'disks.unknown.count'=1;0:0;;0;82
... 9 --warning-disks-normal=82:82 CRITICAL: Disk #73 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SWLT) located 7:5:0 is failed WARNING: Disks normal: 77 - Disk #75 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4SSKT) located 8:1:0 is unknown - Disk #78 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4TLLT) located 8:4:0 is new - Disk #79 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N1TT) located 8:5:0 is new - Disk #81 (WDC/WLEB14T0S5xeF7.2, serial: 9MJ4N8UT) located 8:7:0 is degraded | 'disks.total.count'=82;;;0; 'disks.normal.count'=77;82:82;;0;82 'disks.degraded.count'=1;;;0;82 'disks.new.count'=2;;;0;82 'disks.failed.count'=1;;;0;82 'disks.unknown.count'=1;;;0;82

View File

@ -0,0 +1,53 @@
*** Settings ***
Documentation HPE Primera Storage REST API
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}hpe-primera.mockoon.json
${HOSTNAME} 127.0.0.1
${APIPORT} 3000
${CMD} ${CENTREON_PLUGINS}
... --plugin=storage::hp::primera::restapi::plugin
... --mode=disk-usage
... --hostname=${HOSTNAME}
... --api-username=toto
... --api-password=toto
... --proto=http
... --port=${APIPORT}
... --custommode=api
... --statefile-dir=/dev/shm/
*** Test Cases ***
Disk Usage ${tc}
[Tags] storage api hpe hp
${output} Run ${CMD} ${extraoptions}
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${expected_result}
... Wrong output result for command:\n${CMD} ${extraoptions}\n\nObtained:\n${output}\n\nExpected:\n${expected_result}\n
... values=False
... collapse_spaces=True
Examples: tc extraoptions expected_result --
... 1 --filter-manufacturer=SAMSUNG --filter-counters='^usage$' OK: All disks are ok | '0#disk.space.usage.bytes'=652835028992B;;;0;1918776639488 '1#disk.space.usage.bytes'=651761287168B;;;0;1918776639488 '14#disk.space.usage.bytes'=1006096089088B;;;0;1918776639488 '15#disk.space.usage.bytes'=1006096089088B;;;0;1918776639488 '2#disk.space.usage.bytes'=652835028992B;;;0;1918776639488 '26#disk.space.usage.bytes'=1006096089088B;;;0;1918776639488 '27#disk.space.usage.bytes'=1006096089088B;;;0;1918776639488 '3#disk.space.usage.bytes'=651761287168B;;;0;1918776639488 '38#disk.space.usage.bytes'=651761287168B;;;0;1918776639488 '39#disk.space.usage.bytes'=650687545344B;;;0;1918776639488 '40#disk.space.usage.bytes'=651761287168B;;;0;1918776639488 '41#disk.space.usage.bytes'=650687545344B;;;0;1918776639488 '50#disk.space.usage.bytes'=1006096089088B;;;0;1918776639488 '51#disk.space.usage.bytes'=1006096089088B;;;0;1918776639488
... 2 --filter-manufacturer=SAMSUNG --filter-counters='^usage-free$' OK: All disks are ok | '0#disk.space.free.bytes'=652835028992B;;;0;1918776639488 '1#disk.space.free.bytes'=651761287168B;;;0;1918776639488 '14#disk.space.free.bytes'=1006096089088B;;;0;1918776639488 '15#disk.space.free.bytes'=1006096089088B;;;0;1918776639488 '2#disk.space.free.bytes'=652835028992B;;;0;1918776639488 '26#disk.space.free.bytes'=1006096089088B;;;0;1918776639488 '27#disk.space.free.bytes'=1006096089088B;;;0;1918776639488 '3#disk.space.free.bytes'=651761287168B;;;0;1918776639488 '38#disk.space.free.bytes'=651761287168B;;;0;1918776639488 '39#disk.space.free.bytes'=650687545344B;;;0;1918776639488 '40#disk.space.free.bytes'=651761287168B;;;0;1918776639488 '41#disk.space.free.bytes'=650687545344B;;;0;1918776639488 '50#disk.space.free.bytes'=1006096089088B;;;0;1918776639488 '51#disk.space.free.bytes'=1006096089088B;;;0;1918776639488
... 3 --filter-manufacturer=SAMSUNG --filter-counters='^usage-prct$' OK: All disks are ok | '0#disk.space.usage.percentage'=34.02%;;;0;100 '1#disk.space.usage.percentage'=33.97%;;;0;100 '14#disk.space.usage.percentage'=52.43%;;;0;100 '15#disk.space.usage.percentage'=52.43%;;;0;100 '2#disk.space.usage.percentage'=34.02%;;;0;100 '26#disk.space.usage.percentage'=52.43%;;;0;100 '27#disk.space.usage.percentage'=52.43%;;;0;100 '3#disk.space.usage.percentage'=33.97%;;;0;100 '38#disk.space.usage.percentage'=33.97%;;;0;100 '39#disk.space.usage.percentage'=33.91%;;;0;100 '40#disk.space.usage.percentage'=33.97%;;;0;100 '41#disk.space.usage.percentage'=33.91%;;;0;100 '50#disk.space.usage.percentage'=52.43%;;;0;100 '51#disk.space.usage.percentage'=52.43%;;;0;100
... 4 --filter-manufacturer=SAMSUNG --filter-counters='total' OK: Total Used: 10.23 TB / 24.43 TB, Total percentage used: 41.88 %, Total Free: 14.20 TB | 'disks.total.space.usage.bytes'=11250666831872;;;0;26862872952832 'disks.total.space.usage.percent'=41.8818450715485;;;0;100 'disks.total.space.free.bytes'=15612206120960;;;0;26862872952832
... 5 --filter-manufacturer=SAMSUNG --filter-counters='total' --warning-total-usage=5 WARNING: Total Used: 10.23 TB / 24.43 TB | 'disks.total.space.usage.bytes'=11250666831872;0:5;;0;26862872952832 'disks.total.space.usage.percent'=41.8818450715485;;;0;100 'disks.total.space.free.bytes'=15612206120960;;;0;26862872952832
... 6 --filter-manufacturer=SAMSUNG --filter-counters='total' --critical-total-usage=5 CRITICAL: Total Used: 10.23 TB / 24.43 TB | 'disks.total.space.usage.bytes'=11250666831872;;0:5;0;26862872952832 'disks.total.space.usage.percent'=41.8818450715485;;;0;100 'disks.total.space.free.bytes'=15612206120960;;;0;26862872952832
... 7 --filter-manufacturer=SAMSUNG --filter-counters='total' --warning-total-usage-prct=35 WARNING: Total percentage used: 41.88 % | 'disks.total.space.usage.bytes'=11250666831872;;;0;26862872952832 'disks.total.space.usage.percent'=41.8818450715485;0:35;;0;100 'disks.total.space.free.bytes'=15612206120960;;;0;26862872952832
... 8 --filter-manufacturer=SAMSUNG --filter-counters='total' --critical-total-usage-prct=35 CRITICAL: Total percentage used: 41.88 % | 'disks.total.space.usage.bytes'=11250666831872;;;0;26862872952832 'disks.total.space.usage.percent'=41.8818450715485;;0:35;0;100 'disks.total.space.free.bytes'=15612206120960;;;0;26862872952832
... 9 --filter-manufacturer=SAMSUNG --filter-counters='^usage$' --warning-usage=1000000000000 WARNING: Disk #14 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600288) located 2:0:0 has Used: 937.00 GB of 1.75 TB (52.43%) Free: 850.00 GB (47.57%) - Disk #15 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600290) located 2:1:0 has Used: 937.00 GB of 1.75 TB (52.43%) Free: 850.00 GB (47.57%) - Disk #26 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600289) located 3:0:0 has Used: 937.00 GB of 1.75 TB (52.43%) Free: 850.00 GB (47.57%) - Disk #27 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600293) located 3:1:0 has Used: 937.00 GB of 1.75 TB (52.43%) Free: 850.00 GB (47.57%) - Disk #50 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600297) located 5:0:0 has Used: 937.00 GB of 1.75 TB (52.43%) Free: 850.00 GB (47.57%) - Disk #51 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600287) located 5:1:0 has Used: 937.00 GB of 1.75 TB (52.43%) Free: 850.00 GB (47.57%) | '0#disk.space.usage.bytes'=652835028992B;0:1000000000000;;0;1918776639488 '1#disk.space.usage.bytes'=651761287168B;0:1000000000000;;0;1918776639488 '14#disk.space.usage.bytes'=1006096089088B;0:1000000000000;;0;1918776639488 '15#disk.space.usage.bytes'=1006096089088B;0:1000000000000;;0;1918776639488 '2#disk.space.usage.bytes'=652835028992B;0:1000000000000;;0;1918776639488 '26#disk.space.usage.bytes'=1006096089088B;0:1000000000000;;0;1918776639488 '27#disk.space.usage.bytes'=1006096089088B;0:1000000000000;;0;1918776639488 '3#disk.space.usage.bytes'=651761287168B;0:1000000000000;;0;1918776639488 '38#disk.space.usage.bytes'=651761287168B;0:1000000000000;;0;1918776639488 '39#disk.space.usage.bytes'=650687545344B;0:1000000000000;;0;1918776639488 '40#disk.space.usage.bytes'=651761287168B;0:1000000000000;;0;1918776639488 '41#disk.space.usage.bytes'=650687545344B;0:1000000000000;;0;1918776639488 '50#disk.space.usage.bytes'=1006096089088B;0:1000000000000;;0;1918776639488 '51#disk.space.usage.bytes'=1006096089088B;0:1000000000000;;0;1918776639488
... 10 --filter-manufacturer=SAMSUNG --filter-counters='^usage$' --critical-usage=1000000000000 CRITICAL: Disk #14 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600288) located 2:0:0 has Used: 937.00 GB of 1.75 TB (52.43%) Free: 850.00 GB (47.57%) - Disk #15 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600290) located 2:1:0 has Used: 937.00 GB of 1.75 TB (52.43%) Free: 850.00 GB (47.57%) - Disk #26 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600289) located 3:0:0 has Used: 937.00 GB of 1.75 TB (52.43%) Free: 850.00 GB (47.57%) - Disk #27 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600293) located 3:1:0 has Used: 937.00 GB of 1.75 TB (52.43%) Free: 850.00 GB (47.57%) - Disk #50 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600297) located 5:0:0 has Used: 937.00 GB of 1.75 TB (52.43%) Free: 850.00 GB (47.57%) - Disk #51 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600287) located 5:1:0 has Used: 937.00 GB of 1.75 TB (52.43%) Free: 850.00 GB (47.57%) | '0#disk.space.usage.bytes'=652835028992B;;0:1000000000000;0;1918776639488 '1#disk.space.usage.bytes'=651761287168B;;0:1000000000000;0;1918776639488 '14#disk.space.usage.bytes'=1006096089088B;;0:1000000000000;0;1918776639488 '15#disk.space.usage.bytes'=1006096089088B;;0:1000000000000;0;1918776639488 '2#disk.space.usage.bytes'=652835028992B;;0:1000000000000;0;1918776639488 '26#disk.space.usage.bytes'=1006096089088B;;0:1000000000000;0;1918776639488 '27#disk.space.usage.bytes'=1006096089088B;;0:1000000000000;0;1918776639488 '3#disk.space.usage.bytes'=651761287168B;;0:1000000000000;0;1918776639488 '38#disk.space.usage.bytes'=651761287168B;;0:1000000000000;0;1918776639488 '39#disk.space.usage.bytes'=650687545344B;;0:1000000000000;0;1918776639488 '40#disk.space.usage.bytes'=651761287168B;;0:1000000000000;0;1918776639488 '41#disk.space.usage.bytes'=650687545344B;;0:1000000000000;0;1918776639488 '50#disk.space.usage.bytes'=1006096089088B;;0:1000000000000;0;1918776639488 '51#disk.space.usage.bytes'=1006096089088B;;0:1000000000000;0;1918776639488
... 11 --filter-manufacturer=SAMSUNG --filter-counters='^usage-prct$' --warning-usage-prct=35 WARNING: Disk #14 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600288) located 2:0:0 has Used : 52.43 % - Disk #15 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600290) located 2:1:0 has Used : 52.43 % - Disk #26 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600289) located 3:0:0 has Used : 52.43 % - Disk #27 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600293) located 3:1:0 has Used : 52.43 % - Disk #50 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600297) located 5:0:0 has Used : 52.43 % - Disk #51 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600287) located 5:1:0 has Used : 52.43 % | '0#disk.space.usage.percentage'=34.02%;0:35;;0;100 '1#disk.space.usage.percentage'=33.97%;0:35;;0;100 '14#disk.space.usage.percentage'=52.43%;0:35;;0;100 '15#disk.space.usage.percentage'=52.43%;0:35;;0;100 '2#disk.space.usage.percentage'=34.02%;0:35;;0;100 '26#disk.space.usage.percentage'=52.43%;0:35;;0;100 '27#disk.space.usage.percentage'=52.43%;0:35;;0;100 '3#disk.space.usage.percentage'=33.97%;0:35;;0;100 '38#disk.space.usage.percentage'=33.97%;0:35;;0;100 '39#disk.space.usage.percentage'=33.91%;0:35;;0;100 '40#disk.space.usage.percentage'=33.97%;0:35;;0;100 '41#disk.space.usage.percentage'=33.91%;0:35;;0;100 '50#disk.space.usage.percentage'=52.43%;0:35;;0;100 '51#disk.space.usage.percentage'=52.43%;0:35;;0;100
... 12 --filter-manufacturer=SAMSUNG --filter-counters='^usage-prct$' --critical-usage-prct=35 CRITICAL: Disk #14 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600288) located 2:0:0 has Used : 52.43 % - Disk #15 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600290) located 2:1:0 has Used : 52.43 % - Disk #26 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600289) located 3:0:0 has Used : 52.43 % - Disk #27 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600293) located 3:1:0 has Used : 52.43 % - Disk #50 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600297) located 5:0:0 has Used : 52.43 % - Disk #51 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600287) located 5:1:0 has Used : 52.43 % | '0#disk.space.usage.percentage'=34.02%;;0:35;0;100 '1#disk.space.usage.percentage'=33.97%;;0:35;0;100 '14#disk.space.usage.percentage'=52.43%;;0:35;0;100 '15#disk.space.usage.percentage'=52.43%;;0:35;0;100 '2#disk.space.usage.percentage'=34.02%;;0:35;0;100 '26#disk.space.usage.percentage'=52.43%;;0:35;0;100 '27#disk.space.usage.percentage'=52.43%;;0:35;0;100 '3#disk.space.usage.percentage'=33.97%;;0:35;0;100 '38#disk.space.usage.percentage'=33.97%;;0:35;0;100 '39#disk.space.usage.percentage'=33.91%;;0:35;0;100 '40#disk.space.usage.percentage'=33.97%;;0:35;0;100 '41#disk.space.usage.percentage'=33.91%;;0:35;0;100 '50#disk.space.usage.percentage'=52.43%;;0:35;0;100 '51#disk.space.usage.percentage'=52.43%;;0:35;0;100
... 13 --filter-manufacturer=SAMSUNG --filter-counters='^usage-free$' --warning-usage-free=1000000000000: WARNING: Disk #0 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600283) located 0:0:0 has Used: 608.00 GB of 1.75 TB (34.02%) Free: 1.15 TB (65.98%) - Disk #1 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600286) located 0:1:0 has Used: 607.00 GB of 1.75 TB (33.97%) Free: 1.15 TB (66.03%) - Disk #2 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600197) located 0:2:0 has Used: 608.00 GB of 1.75 TB (34.02%) Free: 1.15 TB (65.98%) - Disk #3 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600285) located 0:3:0 has Used: 607.00 GB of 1.75 TB (33.97%) Free: 1.15 TB (66.03%) - Disk #38 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600303) located 4:0:0 has Used: 607.00 GB of 1.75 TB (33.97%) Free: 1.15 TB (66.03%) - Disk #39 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600302) located 4:1:0 has Used: 606.00 GB of 1.75 TB (33.91%) Free: 1.15 TB (66.09%) - Disk #40 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600296) located 4:2:0 has Used: 607.00 GB of 1.75 TB (33.97%) Free: 1.15 TB (66.03%) - Disk #41 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600291) located 4:3:0 has Used: 606.00 GB of 1.75 TB (33.91%) Free: 1.15 TB (66.09%) | '0#disk.space.free.bytes'=652835028992B;1000000000000:;;0;1918776639488 '1#disk.space.free.bytes'=651761287168B;1000000000000:;;0;1918776639488 '14#disk.space.free.bytes'=1006096089088B;1000000000000:;;0;1918776639488 '15#disk.space.free.bytes'=1006096089088B;1000000000000:;;0;1918776639488 '2#disk.space.free.bytes'=652835028992B;1000000000000:;;0;1918776639488 '26#disk.space.free.bytes'=1006096089088B;1000000000000:;;0;1918776639488 '27#disk.space.free.bytes'=1006096089088B;1000000000000:;;0;1918776639488 '3#disk.space.free.bytes'=651761287168B;1000000000000:;;0;1918776639488 '38#disk.space.free.bytes'=651761287168B;1000000000000:;;0;1918776639488 '39#disk.space.free.bytes'=650687545344B;1000000000000:;;0;1918776639488 '40#disk.space.free.bytes'=651761287168B;1000000000000:;;0;1918776639488 '41#disk.space.free.bytes'=650687545344B;1000000000000:;;0;1918776639488 '50#disk.space.free.bytes'=1006096089088B;1000000000000:;;0;1918776639488 '51#disk.space.free.bytes'=1006096089088B;1000000000000:;;0;1918776639488
... 14 --filter-manufacturer=SAMSUNG --filter-counters='^usage-free$' --critical-usage-free=1000000000000: CRITICAL: Disk #0 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600283) located 0:0:0 has Used: 608.00 GB of 1.75 TB (34.02%) Free: 1.15 TB (65.98%) - Disk #1 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600286) located 0:1:0 has Used: 607.00 GB of 1.75 TB (33.97%) Free: 1.15 TB (66.03%) - Disk #2 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600197) located 0:2:0 has Used: 608.00 GB of 1.75 TB (34.02%) Free: 1.15 TB (65.98%) - Disk #3 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600285) located 0:3:0 has Used: 607.00 GB of 1.75 TB (33.97%) Free: 1.15 TB (66.03%) - Disk #38 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600303) located 4:0:0 has Used: 607.00 GB of 1.75 TB (33.97%) Free: 1.15 TB (66.03%) - Disk #39 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600302) located 4:1:0 has Used: 606.00 GB of 1.75 TB (33.91%) Free: 1.15 TB (66.09%) - Disk #40 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600296) located 4:2:0 has Used: 607.00 GB of 1.75 TB (33.97%) Free: 1.15 TB (66.03%) - Disk #41 (SAMSUNG/ARFA1920S5xnFTRI, serial: 0T600291) located 4:3:0 has Used: 606.00 GB of 1.75 TB (33.91%) Free: 1.15 TB (66.09%) | '0#disk.space.free.bytes'=652835028992B;;1000000000000:;0;1918776639488 '1#disk.space.free.bytes'=651761287168B;;1000000000000:;0;1918776639488 '14#disk.space.free.bytes'=1006096089088B;;1000000000000:;0;1918776639488 '15#disk.space.free.bytes'=1006096089088B;;1000000000000:;0;1918776639488 '2#disk.space.free.bytes'=652835028992B;;1000000000000:;0;1918776639488 '26#disk.space.free.bytes'=1006096089088B;;1000000000000:;0;1918776639488 '27#disk.space.free.bytes'=1006096089088B;;1000000000000:;0;1918776639488 '3#disk.space.free.bytes'=651761287168B;;1000000000000:;0;1918776639488 '38#disk.space.free.bytes'=651761287168B;;1000000000000:;0;1918776639488 '39#disk.space.free.bytes'=650687545344B;;1000000000000:;0;1918776639488 '40#disk.space.free.bytes'=651761287168B;;1000000000000:;0;1918776639488 '41#disk.space.free.bytes'=650687545344B;;1000000000000:;0;1918776639488 '50#disk.space.free.bytes'=1006096089088B;;1000000000000:;0;1918776639488 '51#disk.space.free.bytes'=1006096089088B;;1000000000000:;0;1918776639488

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,47 @@
*** Settings ***
Documentation HPE Primera Storage REST API
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}hpe-primera.mockoon.json
${HOSTNAME} 127.0.0.1
${APIPORT} 3000
${CMD} ${CENTREON_PLUGINS}
... --plugin=storage::hp::primera::restapi::plugin
... --mode=licenses
... --hostname=${HOSTNAME}
... --api-username=toto
... --api-password=toto
... --proto=http
... --port=${APIPORT}
... --custommode=api
... --statefile-dir=/dev/shm/
*** Test Cases ***
Licenses ${tc}
[Tags] storage api hpe hp
${output} Run ${CMD} ${extraoptions}
${output} Strip String ${output}
Should Match Regexp
... ${output}
... ${expected_result}
... Wrong output result for command:\n${CMD} ${extraoptions}\n\nObtained:\n${output}\n\nExpected:\n${expected_result}\n
... values=False
Examples: tc extraoptions expected_result --
... 1 ${EMPTY} OK: Number of licenses: 25, Number of expired licenses: 1 - All licenses are ok \| 'licenses.total.count'=25;;;0; 'licenses.expired.count'=1;;;0;25 'Adaptive Flash Cache#Adaptive Flash Cache#license.expiration.seconds'=0s;;;0; 'Autonomic Rebalance#Autonomic Rebalance#license.expiration.seconds'=[0-9]+s;;;0;
... 2 --critical-license-expiration=86400: CRITICAL: License 'Adaptive Flash Cache' expires: 2024-07-14. Adaptive Flash Cache license has expired. \| 'licenses.total.count'=25;;;0; 'licenses.expired.count'=1;;;0;25 'Adaptive Flash Cache#Adaptive Flash Cache#license.expiration.seconds'=0s;;86400:;0; 'Autonomic Rebalance#Autonomic Rebalance#license.expiration.seconds'=[0-9]+s;;86400:;0;
... 3 --warning-license-expiration=86400: WARNING: License 'Adaptive Flash Cache' expires: 2024-07-14. Adaptive Flash Cache license has expired. \| 'licenses.total.count'=25;;;0; 'licenses.expired.count'=1;;;0;25 'Adaptive Flash Cache#Adaptive Flash Cache#license.expiration.seconds'=0s;86400:;;0; 'Autonomic Rebalance#Autonomic Rebalance#license.expiration.seconds'=[0-9]+s;86400:;;0;
... 4 --warning-expired=0:0 WARNING: Number of expired licenses: 1 \| 'licenses.total.count'=25;;;0; 'licenses.expired.count'=1;0:0;;0;25 'Adaptive Flash Cache#Adaptive Flash Cache#license.expiration.seconds'=0s;;;0; 'Autonomic Rebalance#Autonomic Rebalance#license.expiration.seconds'=[0-9]+s;;;0;
... 5 --critical-license-expiration=86400: --warning-license-expiration=1296000: CRITICAL: License 'Adaptive Flash Cache' expires: 2024-07-14. Adaptive Flash Cache license has expired. \| 'licenses.total.count'=25;;;0; 'licenses.expired.count'=1;;;0;25 'Adaptive Flash Cache#Adaptive Flash Cache#license.expiration.seconds'=0s;1296000:;86400:;0; 'Autonomic Rebalance#Autonomic Rebalance#license.expiration.seconds'=[0-9]+s;1296000:;86400:;0;
... 6 --critical-license-expiration=86400: --warning-license-expiration=86400: CRITICAL: License 'Adaptive Flash Cache' expires: 2024-07-14. Adaptive Flash Cache license has expired. \| 'licenses.total.count'=25;;;0; 'licenses.expired.count'=1;;;0;25 'Adaptive Flash Cache#Adaptive Flash Cache#license.expiration.seconds'=0s;86400:;86400:;0; 'Autonomic Rebalance#Autonomic Rebalance#license.expiration.seconds'=[0-9]+s;86400:;86400:;0;
... 7 --critical-license-expiration=86400: --warning-license-expiration=1296000: --warning-expired=0:0 CRITICAL: License 'Adaptive Flash Cache' expires: 2024-07-14. Adaptive Flash Cache license has expired. WARNING: Number of expired licenses: 1 \| 'licenses.total.count'=25;;;0; 'licenses.expired.count'=1;0:0;;0;25 'Adaptive Flash Cache#Adaptive Flash Cache#license.expiration.seconds'=0s;1296000:;86400:;0; 'Autonomic Rebalance#Autonomic Rebalance#license.expiration.seconds'=[0-9]+s;1296000:;86400:;0;
... 8 --critical-expired=0:0 CRITICAL: Number of expired licenses: 1 \| 'licenses.total.count'=25;;;0; 'licenses.expired.count'=1;;0:0;0;25 'Adaptive Flash Cache#Adaptive Flash Cache#license.expiration.seconds'=0s;;;0; 'Autonomic Rebalance#Autonomic Rebalance#license.expiration.seconds'=[0-9]+s;;;0;
... 9 --filter-name='Autonomic Rebalance' OK: Number of licenses: 1, Number of expired licenses: 0 - License 'Autonomic Rebalance' expires: 2284-05-21. Autonomic Rebalance license expires in .*. \| 'licenses.total.count'=1;;;0; 'licenses.expired.count'=0;;;0;1 'Autonomic Rebalance#Autonomic Rebalance#license.expiration.seconds'=[0-9]+s;;;0;

View File

@ -0,0 +1,44 @@
*** Settings ***
Documentation HPE Primera Storage REST API
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}hpe-primera.mockoon.json
${HOSTNAME} 127.0.0.1
${APIPORT} 3000
${CMD} ${CENTREON_PLUGINS}
... --plugin=storage::hp::primera::restapi::plugin
... --mode=list-disks
... --hostname=${HOSTNAME}
... --api-username=toto
... --api-password=toto
... --proto=http
... --port=${APIPORT}
... --custommode=api
... --statefile-dir=/dev/shm/
...
*** Test Cases ***
List-Disks ${tc}
[Tags] storage api hpe hp
${output} Run ${CMD} ${extraoptions} | wc -l
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${expected_result}
... Wrong output result for command:\n${CMD} ${extraoptions}\n\nObtained:\n${output}\n\nExpected:\n${expected_result}\n
... values=False
... collapse_spaces=True
Examples: tc extraoptions expected_result --
... 1 ${EMPTY} 83
... 2 --disco-show 85
... 3 --disco-format 9

View File

@ -0,0 +1,44 @@
*** Settings ***
Documentation HPE Primera Storage REST API
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}hpe-primera.mockoon.json
${HOSTNAME} 127.0.0.1
${APIPORT} 3000
${CMD} ${CENTREON_PLUGINS}
... --plugin=storage::hp::primera::restapi::plugin
... --mode=list-volumes
... --hostname=${HOSTNAME}
... --api-username=toto
... --api-password=toto
... --proto=http
... --port=${APIPORT}
... --custommode=api
... --statefile-dir=/dev/shm/
...
*** Test Cases ***
List-Volumes ${tc}
[Tags] storage api hpe hp
${output} Run ${CMD} ${extraoptions} | wc -l
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${expected_result}
... Wrong output result for command:\n${CMD} ${extraoptions}\n\nObtained:\n${output}\n\nExpected:\n${expected_result}\n
... values=False
... collapse_spaces=True
Examples: tc extraoptions expected_result --
... 1 ${EMPTY} 18
... 2 --disco-show 20
... 3 --disco-format 7

View File

@ -0,0 +1,44 @@
*** Settings ***
Documentation HPE Primera Storage REST API
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}hpe-primera.mockoon.json
${HOSTNAME} 127.0.0.1
${APIPORT} 3000
${CMD} ${CENTREON_PLUGINS}
... --plugin=storage::hp::primera::restapi::plugin
... --mode=nodes
... --hostname=${HOSTNAME}
... --api-username=toto
... --api-password=toto
... --proto=http
... --port=${APIPORT}
... --custommode=api
... --statefile-dir=/dev/shm/
*** Test Cases ***
Nodes ${tc}
[Tags] storage api hpe hp
${output} Run ${CMD} ${extraoptions}
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${expected_result}
... Wrong output result for command:\n${CMD} ${extraoptions}\n\nObtained:\n${output}\n\nExpected:\n${expected_result}\n
... values=False
... collapse_spaces=True
Examples: tc extraoptions expected_result --
... 1 ${EMPTY} WARNING: node 0 is offline | 'nodes.total.count'=2;;;0; 'nodes.online.count'=1;;;0;2 'nodes.offline.count'=1;;;0;2
... 2 --warning-node-status='${PERCENT}\\{status\\} ne "offline"' WARNING: node 1 is online | 'nodes.total.count'=2;;;0; 'nodes.online.count'=1;;;0;2 'nodes.offline.count'=1;;;0;2
... 3 --warning-online=2:2 WARNING: Number of online nodes: 1 - node 0 is offline | 'nodes.total.count'=2;;;0; 'nodes.online.count'=1;2:2;;0;2 'nodes.offline.count'=1;;;0;2
... 4 --critical-online=2:2 CRITICAL: Number of online nodes: 1 WARNING: node 0 is offline | 'nodes.total.count'=2;;;0; 'nodes.online.count'=1;;2:2;0;2 'nodes.offline.count'=1;;;0;2
... 5 --critical-offline=0:0 CRITICAL: Number of offline nodes: 1 WARNING: node 0 is offline | 'nodes.total.count'=2;;;0; 'nodes.online.count'=1;;;0;2 'nodes.offline.count'=1;;0:0;0;2

View File

@ -0,0 +1,52 @@
*** Settings ***
Documentation HPE Primera Storage REST API
Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}..${/}resources/import.resource
Suite Setup Start Mockoon ${MOCKOON_JSON}
Suite Teardown Stop Mockoon
Test Timeout 120s
*** Variables ***
${MOCKOON_JSON} ${CURDIR}${/}hpe-primera.mockoon.json
${HOSTNAME} 127.0.0.1
${APIPORT} 3000
${CMD} ${CENTREON_PLUGINS}
... --plugin=storage::hp::primera::restapi::plugin
... --mode=volume-usage
... --hostname=${HOSTNAME}
... --api-username=toto
... --api-password=toto
... --proto=http
... --port=${APIPORT}
... --custommode=api
... --statefile-dir=/dev/shm/
*** Test Cases ***
Volumeusage ${tc}
[Tags] storage api hpe hp
${output} Run ${CMD} ${extraoptions}
${output} Strip String ${output}
Should Be Equal As Strings
... ${output}
... ${expected_result}
... Wrong output result for command:\n${CMD} ${extraoptions}\n\nObtained:\n${output}\n\nExpected:\n${expected_result}\n
... values=False
... collapse_spaces=True
Examples: tc extraoptions expected_result --
... 1 ${EMPTY} OK: All volumes are ok | '.mgmtdata#volume.space.usage.bytes'=549755813888B;;;0;549755813888 '.mgmtdata#volume.space.free.bytes'=0B;;;0;549755813888 '.mgmtdata#volume.space.usage.percentage'=100.00%;;;0;100 '.shared.SSD_r6_0#volume.space.usage.bytes'=166599852032B;;;0;70368744177664 '.shared.SSD_r6_0#volume.space.free.bytes'=70202144325632B;;;0;70368744177664 '.shared.SSD_r6_0#volume.space.usage.percentage'=0.24%;;;0;100 '.srdata#volume.space.usage.bytes'=225485783040B;;;0;225485783040 '.srdata#volume.space.free.bytes'=0B;;;0;225485783040 '.srdata#volume.space.usage.percentage'=100.00%;;;0;100 'DR-WOO-SSD01#volume.space.usage.bytes'=4327029604352B;;;0;6047313952768 'DR-WOO-SSD01#volume.space.free.bytes'=1720284348416B;;;0;6047313952768 'DR-WOO-SSD01#volume.space.usage.percentage'=71.55%;;;0;100 'DR-WOO-SSD02#volume.space.usage.bytes'=1137753194496B;;;0;5497558138880 'DR-WOO-SSD02#volume.space.free.bytes'=4359804944384B;;;0;5497558138880 'DR-WOO-SSD02#volume.space.usage.percentage'=20.70%;;;0;100 'JHDFB_NL01#volume.space.usage.bytes'=537547243520B;;;0;5497558138880 'JHDFB_NL01#volume.space.free.bytes'=4960010895360B;;;0;5497558138880 'JHDFB_NL01#volume.space.usage.percentage'=9.78%;;;0;100 'LZRFEE_NL01#volume.space.usage.bytes'=24082603048960B;;;0;32985348833280 'LZRFEE_NL01#volume.space.free.bytes'=8902745784320B;;;0;32985348833280 'LZRFEE_NL01#volume.space.usage.percentage'=73.01%;;;0;100 'LZRFEE_NL02#volume.space.usage.bytes'=25421404962816B;;;0;32985348833280 'LZRFEE_NL02#volume.space.free.bytes'=7563943870464B;;;0;32985348833280 'LZRFEE_NL02#volume.space.usage.percentage'=77.07%;;;0;100 'LZRFEE_NL03#volume.space.usage.bytes'=1756681469952B;;;0;6047313952768 'LZRFEE_NL03#volume.space.free.bytes'=4290632482816B;;;0;6047313952768 'LZRFEE_NL03#volume.space.usage.percentage'=29.05%;;;0;100 'LZRFEE_NL2024#volume.space.usage.bytes'=462308769792B;;;0;6034429050880 'LZRFEE_NL2024#volume.space.free.bytes'=5572120281088B;;;0;6034429050880 'LZRFEE_NL2024#volume.space.usage.percentage'=7.66%;;;0;100 'QUPODHDG01#volume.space.usage.bytes'=74894540800B;;;0;343597383680 'QUPODHDG01#volume.space.free.bytes'=268702842880B;;;0;343597383680 'QUPODHDG01#volume.space.usage.percentage'=21.80%;;;0;100 'Quorum-.0#volume.space.usage.bytes'=424673280B;;;0;107374182400 'Quorum-.0#volume.space.free.bytes'=106949509120B;;;0;107374182400 'Quorum-.0#volume.space.usage.percentage'=0.40%;;;0;100 'Quorum-.1#volume.space.usage.bytes'=3145728B;;;0;107374182400 'Quorum-.1#volume.space.free.bytes'=107371036672B;;;0;107374182400 'Quorum-.1#volume.space.usage.percentage'=0.00%;;;0;100 'YLBQFC#volume.space.usage.bytes'=2059163140096B;;;0;4398046511104 'YLBQFC#volume.space.free.bytes'=2338883371008B;;;0;4398046511104 'YLBQFC#volume.space.usage.percentage'=46.82%;;;0;100 'YLBQG01#volume.space.usage.bytes'=357328486400B;;;0;1099511627776 'YLBQG01#volume.space.free.bytes'=742183141376B;;;0;1099511627776 'YLBQG01#volume.space.usage.percentage'=32.50%;;;0;100 'YLBQYLBQ01#volume.space.usage.bytes'=13838988607488B;;;0;21990232555520 'YLBQYLBQ01#volume.space.free.bytes'=8151243948032B;;;0;21990232555520 'YLBQYLBQ01#volume.space.usage.percentage'=62.93%;;;0;100 'admin#volume.space.usage.bytes'=10737418240B;;;0;10737418240 'admin#volume.space.free.bytes'=0B;;;0;10737418240 'admin#volume.space.usage.percentage'=100.00%;;;0;100
... 2 --filter-name=LZRFEE_NL03 OK: Volume 'LZRFEE_NL03' (#14) Usage Total: 5.50 TB Used: 1.60 TB (29.05%) Free: 3.90 TB (70.95%) | 'LZRFEE_NL03#volume.space.usage.bytes'=1756681469952B;;;0;6047313952768 'LZRFEE_NL03#volume.space.free.bytes'=4290632482816B;;;0;6047313952768 'LZRFEE_NL03#volume.space.usage.percentage'=29.05%;;;0;100
... 3 --filter-counters='^usage$' OK: All volumes are ok | '.mgmtdata#volume.space.usage.bytes'=549755813888B;;;0;549755813888 '.shared.SSD_r6_0#volume.space.usage.bytes'=166599852032B;;;0;70368744177664 '.srdata#volume.space.usage.bytes'=225485783040B;;;0;225485783040 'DR-WOO-SSD01#volume.space.usage.bytes'=4327029604352B;;;0;6047313952768 'DR-WOO-SSD02#volume.space.usage.bytes'=1137753194496B;;;0;5497558138880 'JHDFB_NL01#volume.space.usage.bytes'=537547243520B;;;0;5497558138880 'LZRFEE_NL01#volume.space.usage.bytes'=24082603048960B;;;0;32985348833280 'LZRFEE_NL02#volume.space.usage.bytes'=25421404962816B;;;0;32985348833280 'LZRFEE_NL03#volume.space.usage.bytes'=1756681469952B;;;0;6047313952768 'LZRFEE_NL2024#volume.space.usage.bytes'=462308769792B;;;0;6034429050880 'QUPODHDG01#volume.space.usage.bytes'=74894540800B;;;0;343597383680 'Quorum-.0#volume.space.usage.bytes'=424673280B;;;0;107374182400 'Quorum-.1#volume.space.usage.bytes'=3145728B;;;0;107374182400 'YLBQFC#volume.space.usage.bytes'=2059163140096B;;;0;4398046511104 'YLBQG01#volume.space.usage.bytes'=357328486400B;;;0;1099511627776 'YLBQYLBQ01#volume.space.usage.bytes'=13838988607488B;;;0;21990232555520 'admin#volume.space.usage.bytes'=10737418240B;;;0;10737418240
... 4 --warning-usage-prct='70' --filter-name=LZRFEE WARNING: Volume 'LZRFEE_NL01' (#12) Used : 73.01 % - Volume 'LZRFEE_NL02' (#13) Used : 77.07 % | 'LZRFEE_NL01#volume.space.usage.bytes'=24082603048960B;;;0;32985348833280 'LZRFEE_NL01#volume.space.free.bytes'=8902745784320B;;;0;32985348833280 'LZRFEE_NL01#volume.space.usage.percentage'=73.01%;0:70;;0;100 'LZRFEE_NL02#volume.space.usage.bytes'=25421404962816B;;;0;32985348833280 'LZRFEE_NL02#volume.space.free.bytes'=7563943870464B;;;0;32985348833280 'LZRFEE_NL02#volume.space.usage.percentage'=77.07%;0:70;;0;100 'LZRFEE_NL03#volume.space.usage.bytes'=1756681469952B;;;0;6047313952768 'LZRFEE_NL03#volume.space.free.bytes'=4290632482816B;;;0;6047313952768 'LZRFEE_NL03#volume.space.usage.percentage'=29.05%;0:70;;0;100 'LZRFEE_NL2024#volume.space.usage.bytes'=462308769792B;;;0;6034429050880 'LZRFEE_NL2024#volume.space.free.bytes'=5572120281088B;;;0;6034429050880 'LZRFEE_NL2024#volume.space.usage.percentage'=7.66%;0:70;;0;100
... 5 --critical-usage-prct='70' --filter-name=LZRFEE CRITICAL: Volume 'LZRFEE_NL01' (#12) Used : 73.01 % - Volume 'LZRFEE_NL02' (#13) Used : 77.07 % | 'LZRFEE_NL01#volume.space.usage.bytes'=24082603048960B;;;0;32985348833280 'LZRFEE_NL01#volume.space.free.bytes'=8902745784320B;;;0;32985348833280 'LZRFEE_NL01#volume.space.usage.percentage'=73.01%;;0:70;0;100 'LZRFEE_NL02#volume.space.usage.bytes'=25421404962816B;;;0;32985348833280 'LZRFEE_NL02#volume.space.free.bytes'=7563943870464B;;;0;32985348833280 'LZRFEE_NL02#volume.space.usage.percentage'=77.07%;;0:70;0;100 'LZRFEE_NL03#volume.space.usage.bytes'=1756681469952B;;;0;6047313952768 'LZRFEE_NL03#volume.space.free.bytes'=4290632482816B;;;0;6047313952768 'LZRFEE_NL03#volume.space.usage.percentage'=29.05%;;0:70;0;100 'LZRFEE_NL2024#volume.space.usage.bytes'=462308769792B;;;0;6034429050880 'LZRFEE_NL2024#volume.space.free.bytes'=5572120281088B;;;0;6034429050880 'LZRFEE_NL2024#volume.space.usage.percentage'=7.66%;;0:70;0;100
... 6 --warning-usage='70' --filter-name=LZRFEE WARNING: Volume 'LZRFEE_NL01' (#12) Usage Total: 30.00 TB Used: 21.90 TB (73.01%) Free: 8.10 TB (26.99%) - Volume 'LZRFEE_NL02' (#13) Usage Total: 30.00 TB Used: 23.12 TB (77.07%) Free: 6.88 TB (22.93%) - Volume 'LZRFEE_NL03' (#14) Usage Total: 5.50 TB Used: 1.60 TB (29.05%) Free: 3.90 TB (70.95%) - Volume 'LZRFEE_NL2024' (#15) Usage Total: 5.49 TB Used: 430.56 GB (7.66%) Free: 5.07 TB (92.34%) | 'LZRFEE_NL01#volume.space.usage.bytes'=24082603048960B;0:70;;0;32985348833280 'LZRFEE_NL01#volume.space.free.bytes'=8902745784320B;;;0;32985348833280 'LZRFEE_NL01#volume.space.usage.percentage'=73.01%;;;0;100 'LZRFEE_NL02#volume.space.usage.bytes'=25421404962816B;0:70;;0;32985348833280 'LZRFEE_NL02#volume.space.free.bytes'=7563943870464B;;;0;32985348833280 'LZRFEE_NL02#volume.space.usage.percentage'=77.07%;;;0;100 'LZRFEE_NL03#volume.space.usage.bytes'=1756681469952B;0:70;;0;6047313952768 'LZRFEE_NL03#volume.space.free.bytes'=4290632482816B;;;0;6047313952768 'LZRFEE_NL03#volume.space.usage.percentage'=29.05%;;;0;100 'LZRFEE_NL2024#volume.space.usage.bytes'=462308769792B;0:70;;0;6034429050880 'LZRFEE_NL2024#volume.space.free.bytes'=5572120281088B;;;0;6034429050880 'LZRFEE_NL2024#volume.space.usage.percentage'=7.66%;;;0;100
... 7 --critical-usage='70' --filter-name=LZRFEE CRITICAL: Volume 'LZRFEE_NL01' (#12) Usage Total: 30.00 TB Used: 21.90 TB (73.01%) Free: 8.10 TB (26.99%) - Volume 'LZRFEE_NL02' (#13) Usage Total: 30.00 TB Used: 23.12 TB (77.07%) Free: 6.88 TB (22.93%) - Volume 'LZRFEE_NL03' (#14) Usage Total: 5.50 TB Used: 1.60 TB (29.05%) Free: 3.90 TB (70.95%) - Volume 'LZRFEE_NL2024' (#15) Usage Total: 5.49 TB Used: 430.56 GB (7.66%) Free: 5.07 TB (92.34%) | 'LZRFEE_NL01#volume.space.usage.bytes'=24082603048960B;;0:70;0;32985348833280 'LZRFEE_NL01#volume.space.free.bytes'=8902745784320B;;;0;32985348833280 'LZRFEE_NL01#volume.space.usage.percentage'=73.01%;;;0;100 'LZRFEE_NL02#volume.space.usage.bytes'=25421404962816B;;0:70;0;32985348833280 'LZRFEE_NL02#volume.space.free.bytes'=7563943870464B;;;0;32985348833280 'LZRFEE_NL02#volume.space.usage.percentage'=77.07%;;;0;100 'LZRFEE_NL03#volume.space.usage.bytes'=1756681469952B;;0:70;0;6047313952768 'LZRFEE_NL03#volume.space.free.bytes'=4290632482816B;;;0;6047313952768 'LZRFEE_NL03#volume.space.usage.percentage'=29.05%;;;0;100 'LZRFEE_NL2024#volume.space.usage.bytes'=462308769792B;;0:70;0;6034429050880 'LZRFEE_NL2024#volume.space.free.bytes'=5572120281088B;;;0;6034429050880 'LZRFEE_NL2024#volume.space.usage.percentage'=7.66%;;;0;100
... 8 --warning-usage-free='10:' --filter-name=LZRFEE OK: All volumes are ok | 'LZRFEE_NL01#volume.space.usage.bytes'=24082603048960B;;;0;32985348833280 'LZRFEE_NL01#volume.space.free.bytes'=8902745784320B;10:;;0;32985348833280 'LZRFEE_NL01#volume.space.usage.percentage'=73.01%;;;0;100 'LZRFEE_NL02#volume.space.usage.bytes'=25421404962816B;;;0;32985348833280 'LZRFEE_NL02#volume.space.free.bytes'=7563943870464B;10:;;0;32985348833280 'LZRFEE_NL02#volume.space.usage.percentage'=77.07%;;;0;100 'LZRFEE_NL03#volume.space.usage.bytes'=1756681469952B;;;0;6047313952768 'LZRFEE_NL03#volume.space.free.bytes'=4290632482816B;10:;;0;6047313952768 'LZRFEE_NL03#volume.space.usage.percentage'=29.05%;;;0;100 'LZRFEE_NL2024#volume.space.usage.bytes'=462308769792B;;;0;6034429050880 'LZRFEE_NL2024#volume.space.free.bytes'=5572120281088B;10:;;0;6034429050880 'LZRFEE_NL2024#volume.space.usage.percentage'=7.66%;;;0;100
... 9 --critical-usage-free='10:' --filter-name=LZRFEE OK: All volumes are ok | 'LZRFEE_NL01#volume.space.usage.bytes'=24082603048960B;;;0;32985348833280 'LZRFEE_NL01#volume.space.free.bytes'=8902745784320B;;10:;0;32985348833280 'LZRFEE_NL01#volume.space.usage.percentage'=73.01%;;;0;100 'LZRFEE_NL02#volume.space.usage.bytes'=25421404962816B;;;0;32985348833280 'LZRFEE_NL02#volume.space.free.bytes'=7563943870464B;;10:;0;32985348833280 'LZRFEE_NL02#volume.space.usage.percentage'=77.07%;;;0;100 'LZRFEE_NL03#volume.space.usage.bytes'=1756681469952B;;;0;6047313952768 'LZRFEE_NL03#volume.space.free.bytes'=4290632482816B;;10:;0;6047313952768 'LZRFEE_NL03#volume.space.usage.percentage'=29.05%;;;0;100 'LZRFEE_NL2024#volume.space.usage.bytes'=462308769792B;;;0;6034429050880 'LZRFEE_NL2024#volume.space.free.bytes'=5572120281088B;;10:;0;6034429050880 'LZRFEE_NL2024#volume.space.usage.percentage'=7.66%;;;0;100
... 10 --warning-usage='70' --filter-id='^14$' WARNING: Volume 'LZRFEE_NL03' (#14) Usage Total: 5.50 TB Used: 1.60 TB (29.05%) Free: 3.90 TB (70.95%) | 'LZRFEE_NL03#volume.space.usage.bytes'=1756681469952B;0:70;;0;6047313952768 'LZRFEE_NL03#volume.space.free.bytes'=4290632482816B;;;0;6047313952768 'LZRFEE_NL03#volume.space.usage.percentage'=29.05%;;;0;100
... 11 --critical-usage='70' --filter-id='^14$' CRITICAL: Volume 'LZRFEE_NL03' (#14) Usage Total: 5.50 TB Used: 1.60 TB (29.05%) Free: 3.90 TB (70.95%) | 'LZRFEE_NL03#volume.space.usage.bytes'=1756681469952B;;0:70;0;6047313952768 'LZRFEE_NL03#volume.space.free.bytes'=4290632482816B;;;0;6047313952768 'LZRFEE_NL03#volume.space.usage.percentage'=29.05%;;;0;100
... 12 --warning-usage-free='10:' --filter-id='^14$' OK: Volume 'LZRFEE_NL03' (#14) Usage Total: 5.50 TB Used: 1.60 TB (29.05%) Free: 3.90 TB (70.95%) | 'LZRFEE_NL03#volume.space.usage.bytes'=1756681469952B;;;0;6047313952768 'LZRFEE_NL03#volume.space.free.bytes'=4290632482816B;10:;;0;6047313952768 'LZRFEE_NL03#volume.space.usage.percentage'=29.05%;;;0;100
... 13 --critical-usage-free='10:' --filter-id='^14$' OK: Volume 'LZRFEE_NL03' (#14) Usage Total: 5.50 TB Used: 1.60 TB (29.05%) Free: 3.90 TB (70.95%) | 'LZRFEE_NL03#volume.space.usage.bytes'=1756681469952B;;;0;6047313952768 'LZRFEE_NL03#volume.space.free.bytes'=4290632482816B;;10:;0;6047313952768 'LZRFEE_NL03#volume.space.usage.percentage'=29.05%;;;0;100