From 8090650e589a8fbbbfe095cd542c9de42fffd927 Mon Sep 17 00:00:00 2001 From: itoussies Date: Mon, 28 Oct 2024 15:29:47 +0100 Subject: [PATCH 1/9] Add logical space usage metrics --- .../netapp/ontap/restapi/mode/volumes.pm | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/storage/netapp/ontap/restapi/mode/volumes.pm b/src/storage/netapp/ontap/restapi/mode/volumes.pm index d3d4719c2d..58dc7d59f9 100644 --- a/src/storage/netapp/ontap/restapi/mode/volumes.pm +++ b/src/storage/netapp/ontap/restapi/mode/volumes.pm @@ -46,6 +46,20 @@ sub custom_usage_output { ); } +sub custom_logical_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total_space}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{logical_used_space}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{logical_free_space}); + return sprintf( + 'logical 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}->{logical_prct_used_space}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{logical_prct_free_space} + ); +} + sub prefix_volume_output { my ($self, %options) = @_; @@ -94,6 +108,33 @@ sub set_counters { ] } }, + { label => 'logical-usage', nlabel => 'volume.logicalspace.usage.bytes', set => { + key_values => [ { name => 'logical_used_space' }, { name => 'logical_free_space' }, { name => 'logical_prct_used_space' }, { name => 'logical_prct_free_space' }, { name => 'total_space' }, { name => 'display' }, ], + closure_custom_output => $self->can('custom_logical_usage_output'), + perfdatas => [ + { template => '%d', min => 0, max => 'total_space', + unit => 'B', cast_int => 1, label_extra_instance => 1 } + ] + } + }, + { label => 'logical-usage-free', nlabel => 'volume.logicalspace.free.bytes', display_ok => 0, set => { + key_values => [ { name => 'logical_free_space' }, { name => 'logical_used_space' }, { name => 'logical_prct_used_space' }, { name => 'logical_prct_free_space' }, { name => 'total_space' }, { name => 'display' }, ], + closure_custom_output => $self->can('custom_logical_usage_output'), + perfdatas => [ + { template => '%d', min => 0, max => 'total_space', + unit => 'B', cast_int => 1, label_extra_instance => 1 } + ] + } + }, + { label => 'logical-usage-prct', nlabel => 'volume.logicalspace.usage.percentage', display_ok => 0, set => { + key_values => [ { name => 'logical_prct_used_space' }, { name => 'logical_used_space' }, { name => 'logical_free_space' }, { name => 'logical_prct_free_space' }, { name => 'total_space' }, { name => 'display' }, ], + closure_custom_output => $self->can('custom_logical_usage_output'), + perfdatas => [ + { template => '%.2f', min => 0, max => 100, + unit => '%', label_extra_instance => 1 } + ] + } + }, { label => 'read', nlabel => 'volume.io.read.usage.bytespersecond', display_ok => 0, set => { key_values => [ { name => 'read' } ], output_template => 'read: %s %s/s', @@ -241,6 +282,11 @@ sub manage_selection { prct_used_space => (defined($_->{space}->{size}) && $_->{space}->{size} > 0) ? (($_->{space}->{size} - $_->{space}->{available}) * 100 / $_->{space}->{size}) : undef, prct_free_space => (defined($_->{space}->{size}) && $_->{space}->{size} > 0) ? $_->{space}->{available} * 100 / $_->{space}->{size} : undef, + logical_used_space => $_->{space}->{logical_space}->{used}, + logical_free_space => $_->{space}->{logical_space}->{available}, + logical_prct_used_space => $_->{space}->{logical_space}->{used_percent}, + logical_prct_free_space => $_->{space}->{logical_space}->{available} / ($_->{space}->{logical_space}->{used} + $_->{space}->{logical_space}->{available}), + read => $_->{metric}->{throughput}->{read}, write => $_->{metric}->{throughput}->{write}, other => $_->{metric}->{throughput}->{other}, @@ -304,6 +350,7 @@ You can use the following variables: %{state}, %{display} Thresholds. Can be: 'usage' (B), 'usage-free' (B), 'usage-prct' (%), +'logical-usage' (B), 'logical-usage-free' (B), 'logical-usage-prct' (%), 'read' (B/s), 'read-iops', 'write' (B/s), 'write-iops', 'read-latency' (ms), 'write-latency' (ms), 'total-latency' (ms), 'other-latency' (ms), 'other' (B/s), 'total' (B/s), From e38590b32f0d4d5a16f4e70ba3ab14e3fc4f9f0e Mon Sep 17 00:00:00 2001 From: itoussies Date: Tue, 29 Oct 2024 09:23:25 +0100 Subject: [PATCH 2/9] Add logical space usage metrics --- src/storage/netapp/ontap/restapi/mode/volumes.pm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/storage/netapp/ontap/restapi/mode/volumes.pm b/src/storage/netapp/ontap/restapi/mode/volumes.pm index 58dc7d59f9..a9c3c433ab 100644 --- a/src/storage/netapp/ontap/restapi/mode/volumes.pm +++ b/src/storage/netapp/ontap/restapi/mode/volumes.pm @@ -285,7 +285,7 @@ sub manage_selection { logical_used_space => $_->{space}->{logical_space}->{used}, logical_free_space => $_->{space}->{logical_space}->{available}, logical_prct_used_space => $_->{space}->{logical_space}->{used_percent}, - logical_prct_free_space => $_->{space}->{logical_space}->{available} / ($_->{space}->{logical_space}->{used} + $_->{space}->{logical_space}->{available}), + logical_prct_free_space => (defined($_->{space}->{size}) && $_->{space}->{size} > 0) ? $_->{space}->{logical_space}->{available} * 100 / $_->{space}->{size} : undef, read => $_->{metric}->{throughput}->{read}, write => $_->{metric}->{throughput}->{write}, @@ -295,10 +295,10 @@ sub manage_selection { write_iops => $_->{metric}->{iops}->{write}, other_iops => $_->{metric}->{iops}->{other}, total_iops => $_->{metric}->{iops}->{total}, - read_latency => $_->{metric}->{latency}->{read} / 1000, - write_latency => $_->{metric}->{latency}->{write} / 1000, - other_latency => $_->{metric}->{latency}->{other} / 1000, - total_latency => $_->{metric}->{latency}->{total} / 1000 + read_latency => (defined($_->{metric}->{latency}->{read})) ? ($_->{metric}->{latency}->{read} / 1000) : undef, + write_latency => (defined($_->{metric}->{latency}->{write})) ? ($_->{metric}->{latency}->{write} / 1000) : undef, + other_latency => (defined($_->{metric}->{latency}->{other})) ? ($_->{metric}->{latency}->{other} / 1000) : undef, + total_latency => (defined($_->{metric}->{latency}->{total})) ? ($_->{metric}->{latency}->{total} / 1000) : undef, }; } From 6282aa74af3dcae83553ed0fe93f00c7ce5ee24d Mon Sep 17 00:00:00 2001 From: itoussies Date: Mon, 4 Nov 2024 21:18:16 +0100 Subject: [PATCH 3/9] Optimize API requests --- .../netapp/ontap/restapi/mode/aggregates.pm | 2 +- .../netapp/ontap/restapi/mode/cluster.pm | 4 +-- .../netapp/ontap/restapi/mode/hardware.pm | 4 +-- .../netapp/ontap/restapi/mode/listvolumes.pm | 2 +- src/storage/netapp/ontap/restapi/mode/luns.pm | 2 +- .../netapp/ontap/restapi/mode/quotas.pm | 2 +- .../netapp/ontap/restapi/mode/snapmirrors.pm | 2 +- .../netapp/ontap/restapi/mode/volumes.pm | 36 +++++++++++++------ 8 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/storage/netapp/ontap/restapi/mode/aggregates.pm b/src/storage/netapp/ontap/restapi/mode/aggregates.pm index b8b8517ccc..7a6a811760 100644 --- a/src/storage/netapp/ontap/restapi/mode/aggregates.pm +++ b/src/storage/netapp/ontap/restapi/mode/aggregates.pm @@ -219,7 +219,7 @@ sub new { sub manage_selection { my ($self, %options) = @_; - my $aggregates = $options{custom}->request_api(endpoint => '/api/storage/aggregates?fields=*'); + my $aggregates = $options{custom}->request_api(endpoint => '/api/storage/aggregates?fields=name,uuid,state,space'); $self->{aggregates} = {}; foreach (@{$aggregates->{records}}) { diff --git a/src/storage/netapp/ontap/restapi/mode/cluster.pm b/src/storage/netapp/ontap/restapi/mode/cluster.pm index 02adca3d14..013c7c88f9 100644 --- a/src/storage/netapp/ontap/restapi/mode/cluster.pm +++ b/src/storage/netapp/ontap/restapi/mode/cluster.pm @@ -195,7 +195,7 @@ sub new { sub manage_selection { my ($self, %options) = @_; - my $cluster = $options{custom}->request_api(endpoint => '/api/cluster?fields=*'); + my $cluster = $options{custom}->request_api(endpoint => '/api/cluster?fields=name,statistics,metric'); $self->{clusters} = { $cluster->{name} => { @@ -219,7 +219,7 @@ sub manage_selection { } }; - my $nodes = $options{custom}->request_api(endpoint => '/api/cluster/nodes?fields=*'); + my $nodes = $options{custom}->request_api(endpoint => '/api/cluster/nodes?fields=name,service_processor'); foreach (@{$nodes->{records}}) { $self->{clusters}->{ $cluster->{name} }->{nodes}->{ $_->{name} } = { display => $_->{name}, diff --git a/src/storage/netapp/ontap/restapi/mode/hardware.pm b/src/storage/netapp/ontap/restapi/mode/hardware.pm index 8ec064039f..e469504d6b 100644 --- a/src/storage/netapp/ontap/restapi/mode/hardware.pm +++ b/src/storage/netapp/ontap/restapi/mode/hardware.pm @@ -68,7 +68,7 @@ sub new { sub get_disks { my ($self, %options) = @_; - return $self->{custom}->request_api(endpoint => '/api/storage/disks?fields=*'); + return $self->{custom}->request_api(endpoint => '/api/storage/disks?fields=name,state,serial_number,bay'); } sub get_shelves { @@ -76,7 +76,7 @@ sub get_shelves { return if (defined($self->{shelves})); - $self->{shelves} = $self->{custom}->request_api(endpoint => '/api/storage/shelves?fields=*'); + $self->{shelves} = $self->{custom}->request_api(endpoint => '/api/storage/shelves?fields=name,state,serial_number,bay,frus'); } sub save_custom { diff --git a/src/storage/netapp/ontap/restapi/mode/listvolumes.pm b/src/storage/netapp/ontap/restapi/mode/listvolumes.pm index 65ccc3ce38..2462f05773 100644 --- a/src/storage/netapp/ontap/restapi/mode/listvolumes.pm +++ b/src/storage/netapp/ontap/restapi/mode/listvolumes.pm @@ -44,7 +44,7 @@ sub check_options { sub manage_selection { my ($self, %options) = @_; - return $options{custom}->request_api(endpoint => '/api/storage/volumes?fields=*'); + return $options{custom}->request_api(endpoint => '/api/storage/volumes?fields=svm,state,name'); } sub run { diff --git a/src/storage/netapp/ontap/restapi/mode/luns.pm b/src/storage/netapp/ontap/restapi/mode/luns.pm index a347305b2a..1e8158c30b 100644 --- a/src/storage/netapp/ontap/restapi/mode/luns.pm +++ b/src/storage/netapp/ontap/restapi/mode/luns.pm @@ -75,7 +75,7 @@ sub new { sub manage_selection { my ($self, %options) = @_; - my $luns = $options{custom}->request_api(endpoint => '/api/storage/luns?fields=*'); + my $luns = $options{custom}->request_api(endpoint => '/api/storage/luns?fields=name,status'); $self->{luns} = {}; foreach (@{$luns->{records}}) { diff --git a/src/storage/netapp/ontap/restapi/mode/quotas.pm b/src/storage/netapp/ontap/restapi/mode/quotas.pm index c64f4737df..d54848299f 100644 --- a/src/storage/netapp/ontap/restapi/mode/quotas.pm +++ b/src/storage/netapp/ontap/restapi/mode/quotas.pm @@ -260,7 +260,7 @@ sub new { sub manage_selection { my ($self, %options) = @_; - my $quotas = $options{custom}->request_api(endpoint => '/api/storage/quota/reports?fields=*'); + my $quotas = $options{custom}->request_api(endpoint => '/api/storage/quota/reports?fields=index,qtree,volume,svm,space'); $self->{duplicated} = {}; diff --git a/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm b/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm index ea62b31ae7..56a80095b4 100644 --- a/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm +++ b/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm @@ -76,7 +76,7 @@ sub new { sub manage_selection { my ($self, %options) = @_; - my $snapmirrors = $options{custom}->request_api(endpoint => '/api/snapmirror/relationships?fields=*'); + my $snapmirrors = $options{custom}->request_api(endpoint => '/api/snapmirror/relationships?fields=source,destination,healthy,state,transfer'); $self->{snapmirrors} = {}; foreach (@{$snapmirrors->{records}}) { diff --git a/src/storage/netapp/ontap/restapi/mode/volumes.pm b/src/storage/netapp/ontap/restapi/mode/volumes.pm index a9c3c433ab..4182683e5d 100644 --- a/src/storage/netapp/ontap/restapi/mode/volumes.pm +++ b/src/storage/netapp/ontap/restapi/mode/volumes.pm @@ -244,6 +244,7 @@ sub new { bless $self, $class; $options{options}->add_options(arguments => { + 'filter-volume-name:s' => { name => 'filter_volume_name' }, 'filter-name:s' => { name => 'filter_name' }, 'filter-vserver-name:s' => { name => 'filter_vserver_name' } }); @@ -254,7 +255,13 @@ sub new { sub manage_selection { my ($self, %options) = @_; - my $volumes = $options{custom}->request_api(endpoint => '/api/storage/volumes?fields=*'); + my $endpoint = '/api/storage/volumes?fields=svm,name,space,metric'; + + if (defined($self->{option_results}->{filter_volume_name}) && $self->{option_results}->{filter_volume_name} ne '' ) { + $endpoint .= '&name=' . $self->{option_results}->{filter_volume_name} + } + + my $volumes = $options{custom}->request_api(endpoint => $endpoint); $self->{volumes} = {}; foreach (@{$volumes->{records}}) { @@ -282,11 +289,6 @@ sub manage_selection { prct_used_space => (defined($_->{space}->{size}) && $_->{space}->{size} > 0) ? (($_->{space}->{size} - $_->{space}->{available}) * 100 / $_->{space}->{size}) : undef, prct_free_space => (defined($_->{space}->{size}) && $_->{space}->{size} > 0) ? $_->{space}->{available} * 100 / $_->{space}->{size} : undef, - logical_used_space => $_->{space}->{logical_space}->{used}, - logical_free_space => $_->{space}->{logical_space}->{available}, - logical_prct_used_space => $_->{space}->{logical_space}->{used_percent}, - logical_prct_free_space => (defined($_->{space}->{size}) && $_->{space}->{size} > 0) ? $_->{space}->{logical_space}->{available} * 100 / $_->{space}->{size} : undef, - read => $_->{metric}->{throughput}->{read}, write => $_->{metric}->{throughput}->{write}, other => $_->{metric}->{throughput}->{other}, @@ -300,6 +302,15 @@ sub manage_selection { other_latency => (defined($_->{metric}->{latency}->{other})) ? ($_->{metric}->{latency}->{other} / 1000) : undef, total_latency => (defined($_->{metric}->{latency}->{total})) ? ($_->{metric}->{latency}->{total} / 1000) : undef, }; + + if (defined($self->{option_results}->{filter_volume_name}) && $self->{option_results}->{filter_volume_name} ne '' ) { + $self->{volumes}->{$name}->{logical_used_space} = $_->{space}->{logical_space}->{used}; + $self->{volumes}->{$name}->{logical_free_space} = $_->{space}->{logical_space}->{available}; + $self->{volumes}->{$name}->{logical_prct_used_space} = $_->{space}->{logical_space}->{used_percent}; + $self->{volumes}->{$name}->{logical_prct_free_space} = (defined($_->{space}->{size}) && $_->{space}->{size} > 0) ? $_->{space}->{logical_space}->{available} * 100 / $_->{space}->{size} : undef; + } + + } if (scalar(keys %{$self->{volumes}}) <= 0) { @@ -321,11 +332,16 @@ Check volumes. =item B<--filter-counters> Only display some counters (regexp can be used). -Example: --filter-counters='^usage$' +Example: --filter-counters='^usage$'. + +=item B<--filter-volume-name> + +Filter the API request by volumes name (* can be used, volumes name are separated by |). Required if you wan to retrive +logical space metrics. =item B<--filter-name> -Filter volumes by volume name (can be a regexp). +Filter the API request result by volume name (can be a regexp). =item B<--filter-vserver-name> @@ -339,12 +355,12 @@ You can use the following variables: %{state}, %{display} =item B<--warning-status> Define the conditions to match for the status to be WARNING. -You can use the following variables: %{state}, %{display} +You can use the following variables: %{state}, %{display}. =item B<--critical-status> Define the conditions to match for the status to be CRITICAL (default: '%{state} !~ /online/i'). -You can use the following variables: %{state}, %{display} +You can use the following variables: %{state}, %{display}. =item B<--warning-*> B<--critical-*> From 0c85e624f01d1fd3a194b7ca83085d2bb85bc17d Mon Sep 17 00:00:00 2001 From: itoussies Date: Mon, 2 Dec 2024 18:21:37 +0100 Subject: [PATCH 4/9] Add logical space usage metrics --- src/storage/netapp/ontap/restapi/mode/volumes.pm | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/storage/netapp/ontap/restapi/mode/volumes.pm b/src/storage/netapp/ontap/restapi/mode/volumes.pm index 4182683e5d..a947148825 100644 --- a/src/storage/netapp/ontap/restapi/mode/volumes.pm +++ b/src/storage/netapp/ontap/restapi/mode/volumes.pm @@ -49,7 +49,7 @@ sub custom_usage_output { sub custom_logical_usage_output { my ($self, %options) = @_; - my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total_space}); + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total_logical_space}); my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{logical_used_space}); my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{logical_free_space}); return sprintf( @@ -109,25 +109,25 @@ sub set_counters { } }, { label => 'logical-usage', nlabel => 'volume.logicalspace.usage.bytes', set => { - key_values => [ { name => 'logical_used_space' }, { name => 'logical_free_space' }, { name => 'logical_prct_used_space' }, { name => 'logical_prct_free_space' }, { name => 'total_space' }, { name => 'display' }, ], + key_values => [ { name => 'logical_used_space' }, { name => 'logical_free_space' }, { name => 'logical_prct_used_space' }, { name => 'logical_prct_free_space' }, { name => 'total_logical_space' }, { name => 'display' }, ], closure_custom_output => $self->can('custom_logical_usage_output'), perfdatas => [ - { template => '%d', min => 0, max => 'total_space', + { template => '%d', min => 0, max => 'total_logical_space', unit => 'B', cast_int => 1, label_extra_instance => 1 } ] } }, { label => 'logical-usage-free', nlabel => 'volume.logicalspace.free.bytes', display_ok => 0, set => { - key_values => [ { name => 'logical_free_space' }, { name => 'logical_used_space' }, { name => 'logical_prct_used_space' }, { name => 'logical_prct_free_space' }, { name => 'total_space' }, { name => 'display' }, ], + key_values => [ { name => 'logical_free_space' }, { name => 'logical_used_space' }, { name => 'logical_prct_used_space' }, { name => 'logical_prct_free_space' }, { name => 'total_logical_space' }, { name => 'display' }, ], closure_custom_output => $self->can('custom_logical_usage_output'), perfdatas => [ - { template => '%d', min => 0, max => 'total_space', + { template => '%d', min => 0, max => 'total_logical_space', unit => 'B', cast_int => 1, label_extra_instance => 1 } ] } }, { label => 'logical-usage-prct', nlabel => 'volume.logicalspace.usage.percentage', display_ok => 0, set => { - key_values => [ { name => 'logical_prct_used_space' }, { name => 'logical_used_space' }, { name => 'logical_free_space' }, { name => 'logical_prct_free_space' }, { name => 'total_space' }, { name => 'display' }, ], + key_values => [ { name => 'logical_prct_used_space' }, { name => 'logical_used_space' }, { name => 'logical_free_space' }, { name => 'logical_prct_free_space' }, { name => 'total_logical_space' }, { name => 'display' }, ], closure_custom_output => $self->can('custom_logical_usage_output'), perfdatas => [ { template => '%.2f', min => 0, max => 100, @@ -304,10 +304,11 @@ sub manage_selection { }; if (defined($self->{option_results}->{filter_volume_name}) && $self->{option_results}->{filter_volume_name} ne '' ) { + $self->{volumes}->{$name}->{total_logical_space} = $_->{space}->{logical_space}->{used} + $_->{space}->{logical_space}->{available}; $self->{volumes}->{$name}->{logical_used_space} = $_->{space}->{logical_space}->{used}; $self->{volumes}->{$name}->{logical_free_space} = $_->{space}->{logical_space}->{available}; $self->{volumes}->{$name}->{logical_prct_used_space} = $_->{space}->{logical_space}->{used_percent}; - $self->{volumes}->{$name}->{logical_prct_free_space} = (defined($_->{space}->{size}) && $_->{space}->{size} > 0) ? $_->{space}->{logical_space}->{available} * 100 / $_->{space}->{size} : undef; + $self->{volumes}->{$name}->{logical_prct_free_space} = 100 - $_->{space}->{logical_space}->{used_percent}; } From 0b6c3f5542973782035a96f1c25d6bed64ec55f6 Mon Sep 17 00:00:00 2001 From: itoussies Date: Mon, 23 Dec 2024 17:18:46 +0100 Subject: [PATCH 5/9] wip --- .../netapp/ontap/restapi/mode/volumes.pm | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/storage/netapp/ontap/restapi/mode/volumes.pm b/src/storage/netapp/ontap/restapi/mode/volumes.pm index a947148825..51e6f73a66 100644 --- a/src/storage/netapp/ontap/restapi/mode/volumes.pm +++ b/src/storage/netapp/ontap/restapi/mode/volumes.pm @@ -333,7 +333,7 @@ Check volumes. =item B<--filter-counters> Only display some counters (regexp can be used). -Example: --filter-counters='^usage$'. +Example: C<--filter-counters='^usage$'>. =item B<--filter-volume-name> @@ -351,27 +351,27 @@ Filter volumes by vserver name (can be a regexp). =item B<--unknown-status> Define the conditions to match for the status to be UNKNOWN. -You can use the following variables: %{state}, %{display} +You can use the following variables: C<%{state}>, C<%{display}> =item B<--warning-status> Define the conditions to match for the status to be WARNING. -You can use the following variables: %{state}, %{display}. +You can use the following variables: C<%{state}>, C<%{display}>. =item B<--critical-status> -Define the conditions to match for the status to be CRITICAL (default: '%{state} !~ /online/i'). -You can use the following variables: %{state}, %{display}. +Define the conditions to match for the status to be CRITICAL (default: C<%{state} !~ /online/i>). +You can use the following variables: C<%{state}>, C<%{display}>. =item B<--warning-*> B<--critical-*> Thresholds. -Can be: 'usage' (B), 'usage-free' (B), 'usage-prct' (%), -'logical-usage' (B), 'logical-usage-free' (B), 'logical-usage-prct' (%), -'read' (B/s), 'read-iops', 'write' (B/s), 'write-iops', -'read-latency' (ms), 'write-latency' (ms), 'total-latency' (ms), -'other-latency' (ms), 'other' (B/s), 'total' (B/s), -'other-iops', 'total-iops'. +Can be: C' (B), C (B), C (%), +C (B), C (B), C (%), +C (B/s), C, C (B/s), C, +C (ms), C (ms), C (ms), +C (ms), C (B/s), C (B/s), +C, C. =back From 25d4c1e8b582a6773592df35cb245dbae3ff4b80 Mon Sep 17 00:00:00 2001 From: itoussies Date: Tue, 24 Dec 2024 18:31:01 +0100 Subject: [PATCH 6/9] enh snapmirrors --- src/storage/netapp/ontap/restapi/mode/snapmirrors.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm b/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm index 56a80095b4..7a6cffdb7a 100644 --- a/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm +++ b/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm @@ -89,7 +89,7 @@ sub manage_selection { $self->{snapmirrors}->{$name} = { display => $name, - healthy => $_->{healthy} =~ /true|1/i ? 'true' : 'false', + healthy => (defined($_->{healthy}) && $_->{healthy} =~ /true|1/i) ? 'true' : 'false', state => $_->{state}, transfer_state => defined($_->{transfer}->{state}) ? $_->{transfer}->{state} : 'n/a' }; From f9c9244e47b2a548541e7b0c546e3d6ccb429895 Mon Sep 17 00:00:00 2001 From: itoussies Date: Tue, 24 Dec 2024 18:31:08 +0100 Subject: [PATCH 7/9] add tests --- .../netapp/ontap/restapi/mode/volumes.pm | 22 +- .../netapp/ontap/restapi/aggregates.robot | 38 ++ .../netapp/ontap/restapi/cluster.robot | 36 ++ .../netapp/ontap/restapi/hardware.robot | 39 ++ tests/storage/netapp/ontap/restapi/luns.robot | 36 ++ .../storage/netapp/ontap/restapi/netapp.json | 522 ++++++++++++++++++ .../storage/netapp/ontap/restapi/quotas.robot | 40 ++ .../netapp/ontap/restapi/snapmirrors.robot | 36 ++ .../netapp/ontap/restapi/volumes.robot | 42 ++ 9 files changed, 800 insertions(+), 11 deletions(-) create mode 100644 tests/storage/netapp/ontap/restapi/aggregates.robot create mode 100644 tests/storage/netapp/ontap/restapi/cluster.robot create mode 100644 tests/storage/netapp/ontap/restapi/hardware.robot create mode 100644 tests/storage/netapp/ontap/restapi/luns.robot create mode 100644 tests/storage/netapp/ontap/restapi/netapp.json create mode 100644 tests/storage/netapp/ontap/restapi/quotas.robot create mode 100644 tests/storage/netapp/ontap/restapi/snapmirrors.robot create mode 100644 tests/storage/netapp/ontap/restapi/volumes.robot diff --git a/src/storage/netapp/ontap/restapi/mode/volumes.pm b/src/storage/netapp/ontap/restapi/mode/volumes.pm index 51e6f73a66..791ebb03ab 100644 --- a/src/storage/netapp/ontap/restapi/mode/volumes.pm +++ b/src/storage/netapp/ontap/restapi/mode/volumes.pm @@ -303,7 +303,7 @@ sub manage_selection { total_latency => (defined($_->{metric}->{latency}->{total})) ? ($_->{metric}->{latency}->{total} / 1000) : undef, }; - if (defined($self->{option_results}->{filter_volume_name}) && $self->{option_results}->{filter_volume_name} ne '' ) { + if (defined($_->{space}->{logical_space})) { $self->{volumes}->{$name}->{total_logical_space} = $_->{space}->{logical_space}->{used} + $_->{space}->{logical_space}->{available}; $self->{volumes}->{$name}->{logical_used_space} = $_->{space}->{logical_space}->{used}; $self->{volumes}->{$name}->{logical_free_space} = $_->{space}->{logical_space}->{available}; @@ -351,27 +351,27 @@ Filter volumes by vserver name (can be a regexp). =item B<--unknown-status> Define the conditions to match for the status to be UNKNOWN. -You can use the following variables: C<%{state}>, C<%{display}> +You can use the following variables: %{state}, %{display} =item B<--warning-status> Define the conditions to match for the status to be WARNING. -You can use the following variables: C<%{state}>, C<%{display}>. +You can use the following variables: %{state}, %{display}. =item B<--critical-status> -Define the conditions to match for the status to be CRITICAL (default: C<%{state} !~ /online/i>). -You can use the following variables: C<%{state}>, C<%{display}>. +Define the conditions to match for the status to be CRITICAL (default: '%{state} !~ /online/i'). +You can use the following variables: %{state}, %{display}. =item B<--warning-*> B<--critical-*> Thresholds. -Can be: C' (B), C (B), C (%), -C (B), C (B), C (%), -C (B/s), C, C (B/s), C, -C (ms), C (ms), C (ms), -C (ms), C (B/s), C (B/s), -C, C. +Can be: usage' (B), usage-free (B), usage-prct (%), +logical-usage (B), logical-usage-free (B), logical-usage-prct (%), +read (B/s), read-iops, write (B/s), write-iops, +read-latency (ms), write-latency (ms), total-latency (ms), +other-latency (ms), other (B/s), total (B/s), +other-iops, total-iops. =back diff --git a/tests/storage/netapp/ontap/restapi/aggregates.robot b/tests/storage/netapp/ontap/restapi/aggregates.robot new file mode 100644 index 0000000000..e17fa3ebd4 --- /dev/null +++ b/tests/storage/netapp/ontap/restapi/aggregates.robot @@ -0,0 +1,38 @@ +*** Settings *** +Documentation Netapp Ontap Restapi Aggregates plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Start Mockoon ${MOCKOON_JSON} +Suite Teardown Stop Mockoon +Test Timeout 120s + + +*** Variables *** +${MOCKOON_JSON} ${CURDIR}${/}netapp.json + +${cmd} ${CENTREON_PLUGINS} +... --plugin=storage::netapp::ontap::restapi::plugin +... --hostname=${HOSTNAME} +... --port=${APIPORT} +... --proto=http +... --api-username=username +... --api-password=password +... --mode=aggregates + + +*** Test Cases *** +Aggregates ${tc} + [Tags] storage netapp ontapp api aggregates mockoon + ${command} Catenate + ... ${CMD} + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: tc extra_options expected_result -- + ... 1 ${EMPTY} OK: Aggregates 'aggregate1' state: online, space usage total: 9.46 GB used: 1.99 MB (0.02%) free: 9.46 GB (100.00%), other : skipped (no value(s)), read iops: 500, write iops: 200, other-iops : skipped (no value(s)), total iops: 1000, read latency: 500 µs, write latency: 200 µs, other-latency : skipped (no value(s)), total latency: 1000 µs | 'aggregate1#aggregate.space.usage.bytes'=2088960B;;;0;10156769280 'aggregate1#aggregate.space.free.bytes'=10156560384B;;;0;10156769280 'aggregate1#aggregate.space.usage.percentage'=0.02%;;;0;100 'aggregate1#aggregate.io.read.usage.bytespersecond'=500B/s;;;; 'aggregate1#aggregate.io.write.usage.bytespersecond'=200B/s;;;0; 'aggregate1#aggregate.io.total.usage.bytespersecond'=1000B/s;;;0; 'aggregate1#aggregate.io.read.usage.iops'=500iops;;;0; 'aggregate1#aggregate.io.write.usage.iops'=200iops;;;0; 'aggregate1#aggregate.io.total.usage.iops'=1000iops;;;0; 'aggregate1#aggregate.io.read.latency.microseconds'=500µs;;;0; 'aggregate1#aggregate.io.write.latency.microseconds'=200µs;;;0; 'aggregate1#aggregate.io.total.latency.microseconds'=1000µs;;;0; + ... 2 --warning-status='\\\%{state} !~ /notonline/i' WARNING: Aggregates 'aggregate1' state: online | 'aggregate1#aggregate.space.usage.bytes'=2088960B;;;0;10156769280 'aggregate1#aggregate.space.free.bytes'=10156560384B;;;0;10156769280 'aggregate1#aggregate.space.usage.percentage'=0.02%;;;0;100 'aggregate1#aggregate.io.read.usage.bytespersecond'=500B/s;;;; 'aggregate1#aggregate.io.write.usage.bytespersecond'=200B/s;;;0; 'aggregate1#aggregate.io.total.usage.bytespersecond'=1000B/s;;;0; 'aggregate1#aggregate.io.read.usage.iops'=500iops;;;0; 'aggregate1#aggregate.io.write.usage.iops'=200iops;;;0; 'aggregate1#aggregate.io.total.usage.iops'=1000iops;;;0; 'aggregate1#aggregate.io.read.latency.microseconds'=500µs;;;0; 'aggregate1#aggregate.io.write.latency.microseconds'=200µs;;;0; 'aggregate1#aggregate.io.total.latency.microseconds'=1000µs;;;0; + ... 3 --critical-status='\\\%{state} !~ /notonline/i' CRITICAL: Aggregates 'aggregate1' state: online | 'aggregate1#aggregate.space.usage.bytes'=2088960B;;;0;10156769280 'aggregate1#aggregate.space.free.bytes'=10156560384B;;;0;10156769280 'aggregate1#aggregate.space.usage.percentage'=0.02%;;;0;100 'aggregate1#aggregate.io.read.usage.bytespersecond'=500B/s;;;; 'aggregate1#aggregate.io.write.usage.bytespersecond'=200B/s;;;0; 'aggregate1#aggregate.io.total.usage.bytespersecond'=1000B/s;;;0; 'aggregate1#aggregate.io.read.usage.iops'=500iops;;;0; 'aggregate1#aggregate.io.write.usage.iops'=200iops;;;0; 'aggregate1#aggregate.io.total.usage.iops'=1000iops;;;0; 'aggregate1#aggregate.io.read.latency.microseconds'=500µs;;;0; 'aggregate1#aggregate.io.write.latency.microseconds'=200µs;;;0; 'aggregate1#aggregate.io.total.latency.microseconds'=1000µs;;;0; + ... 6 --warning-usage-prct=50:50 WARNING: Aggregates 'aggregate1' used : 0.02 % | 'aggregate1#aggregate.space.usage.bytes'=2088960B;;;0;10156769280 'aggregate1#aggregate.space.free.bytes'=10156560384B;;;0;10156769280 'aggregate1#aggregate.space.usage.percentage'=0.02%;50:50;;0;100 'aggregate1#aggregate.io.read.usage.bytespersecond'=500B/s;;;; 'aggregate1#aggregate.io.write.usage.bytespersecond'=200B/s;;;0; 'aggregate1#aggregate.io.total.usage.bytespersecond'=1000B/s;;;0; 'aggregate1#aggregate.io.read.usage.iops'=500iops;;;0; 'aggregate1#aggregate.io.write.usage.iops'=200iops;;;0; 'aggregate1#aggregate.io.total.usage.iops'=1000iops;;;0; 'aggregate1#aggregate.io.read.latency.microseconds'=500µs;;;0; 'aggregate1#aggregate.io.write.latency.microseconds'=200µs;;;0; 'aggregate1#aggregate.io.total.latency.microseconds'=1000µs;;;0; + ... 7 --critical-usage-prct=50:50 CRITICAL: Aggregates 'aggregate1' used : 0.02 % | 'aggregate1#aggregate.space.usage.bytes'=2088960B;;;0;10156769280 'aggregate1#aggregate.space.free.bytes'=10156560384B;;;0;10156769280 'aggregate1#aggregate.space.usage.percentage'=0.02%;;50:50;0;100 'aggregate1#aggregate.io.read.usage.bytespersecond'=500B/s;;;; 'aggregate1#aggregate.io.write.usage.bytespersecond'=200B/s;;;0; 'aggregate1#aggregate.io.total.usage.bytespersecond'=1000B/s;;;0; 'aggregate1#aggregate.io.read.usage.iops'=500iops;;;0; 'aggregate1#aggregate.io.write.usage.iops'=200iops;;;0; 'aggregate1#aggregate.io.total.usage.iops'=1000iops;;;0; 'aggregate1#aggregate.io.read.latency.microseconds'=500µs;;;0; 'aggregate1#aggregate.io.write.latency.microseconds'=200µs;;;0; 'aggregate1#aggregate.io.total.latency.microseconds'=1000µs;;;0; \ No newline at end of file diff --git a/tests/storage/netapp/ontap/restapi/cluster.robot b/tests/storage/netapp/ontap/restapi/cluster.robot new file mode 100644 index 0000000000..e052f5bbc7 --- /dev/null +++ b/tests/storage/netapp/ontap/restapi/cluster.robot @@ -0,0 +1,36 @@ +*** Settings *** +Documentation Netapp Ontap Restapi Cluster plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Start Mockoon ${MOCKOON_JSON} +Suite Teardown Stop Mockoon +Test Timeout 120s + + +*** Variables *** +${MOCKOON_JSON} ${CURDIR}${/}netapp.json + +${cmd} ${CENTREON_PLUGINS} +... --plugin=storage::netapp::ontap::restapi::plugin +... --hostname=${HOSTNAME} +... --port=${APIPORT} +... --proto=http +... --api-username=username +... --api-password=password +... --mode=cluster + + +*** Test Cases *** +Cluster ${tc} + [Tags] storage netapp ontapp api cluster mockoon + ${command} Catenate + ... ${CMD} + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: tc extra_options expected_result -- + ... 1 ${EMPTY} OK: cluster 'cluster1' other : skipped (no value(s)), read iops: 200, write iops: 100, other-iops : skipped (no value(s)), total iops: 1000, read latency: 200 ms, write latency: 100 ms, other-latency : skipped (no value(s)), total latency: 1000 ms - node 'node-01' state: online [link status: string] | 'cluster1#cluster.io.read.usage.bytespersecond'=0B/s;;;; 'cluster1#cluster.io.write.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.total.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.read.usage.iops'=200iops;;;0; 'cluster1#cluster.io.write.usage.iops'=100iops;;;0; 'cluster1#cluster.io.total.usage.iops'=1000iops;;;0; 'cluster.io.read.latency.milliseconds'=200ms;;;0; 'cluster1#cluster.io.write.latency.milliseconds'=100ms;;;0; 'cluster1#cluster.io.total.latency.milliseconds'=1000ms;;;0; + ... 2 --warning-node-status='\\\%{state} !~ /notonline/i' WARNING: cluster 'cluster1' node 'node-01' state: online [link status: string] | 'cluster1#cluster.io.read.usage.bytespersecond'=0B/s;;;; 'cluster1#cluster.io.write.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.total.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.read.usage.iops'=200iops;;;0; 'cluster1#cluster.io.write.usage.iops'=100iops;;;0; 'cluster1#cluster.io.total.usage.iops'=1000iops;;;0; 'cluster.io.read.latency.milliseconds'=200ms;;;0; 'cluster1#cluster.io.write.latency.milliseconds'=100ms;;;0; 'cluster1#cluster.io.total.latency.milliseconds'=1000ms;;;0; + ... 3 --critical-node-status='\\\%{state} !~ /notonline/i' CRITICAL: cluster 'cluster1' node 'node-01' state: online [link status: string] | 'cluster1#cluster.io.read.usage.bytespersecond'=0B/s;;;; 'cluster1#cluster.io.write.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.total.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.read.usage.iops'=200iops;;;0; 'cluster1#cluster.io.write.usage.iops'=100iops;;;0; 'cluster1#cluster.io.total.usage.iops'=1000iops;;;0; 'cluster.io.read.latency.milliseconds'=200ms;;;0; 'cluster1#cluster.io.write.latency.milliseconds'=100ms;;;0; 'cluster1#cluster.io.total.latency.milliseconds'=1000ms;;;0; diff --git a/tests/storage/netapp/ontap/restapi/hardware.robot b/tests/storage/netapp/ontap/restapi/hardware.robot new file mode 100644 index 0000000000..1637795640 --- /dev/null +++ b/tests/storage/netapp/ontap/restapi/hardware.robot @@ -0,0 +1,39 @@ +*** Settings *** +Documentation Netapp Ontap Restapi Quotas plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Start Mockoon ${MOCKOON_JSON} +Suite Teardown Stop Mockoon +Test Timeout 120s + + +*** Variables *** +${MOCKOON_JSON} ${CURDIR}${/}netapp.json + +${cmd} ${CENTREON_PLUGINS} +... --plugin=storage::netapp::ontap::restapi::plugin +... --hostname=${HOSTNAME} +... --port=${APIPORT} +... --proto=http +... --api-username=username +... --api-password=password +... --mode=quotas + + +*** Test Cases *** +Quotas ${tc} + [Tags] storage netapp ontapp api quotas mockoon + ${command} Catenate + ... ${CMD} + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: tc extra_options expected_result -- + ... 1 ${EMPTY} OK: All 4 components are ok [1/1 bays, 1/1 disks, 1/1 frus, 1/1 shelfs]. | 'hardware.bay.count'=1;;;; 'hardware.disk.count'=1;;;; 'hardware.fru.count'=1;;;; 'hardware.shelf.count'=1;;;; + ... 2 --component='bay' OK: All 1 components are ok [1/1 bays]. | 'hardware.bay.count'=1;;;; + ... 3 --component='disk' OK: All 1 components are ok [1/1 disks]. | 'hardware.disk.count'=1;;;; + ... 4 --component='fru' OK: All 1 components are ok [1/1 frus]. | 'hardware.fru.count'=1;;;; + ... 5 --component='shelf' OK: All 1 components are ok [1/1 shelfs]. | 'hardware.shelf.count'=1;;;; + diff --git a/tests/storage/netapp/ontap/restapi/luns.robot b/tests/storage/netapp/ontap/restapi/luns.robot new file mode 100644 index 0000000000..80b9a68af6 --- /dev/null +++ b/tests/storage/netapp/ontap/restapi/luns.robot @@ -0,0 +1,36 @@ +*** Settings *** +Documentation Netapp Ontap Restapi Luns plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Start Mockoon ${MOCKOON_JSON} +Suite Teardown Stop Mockoon +Test Timeout 120s + + +*** Variables *** +${MOCKOON_JSON} ${CURDIR}${/}netapp.json + +${cmd} ${CENTREON_PLUGINS} +... --plugin=storage::netapp::ontap::restapi::plugin +... --hostname=${HOSTNAME} +... --port=${APIPORT} +... --proto=http +... --api-username=username +... --api-password=password +... --mode=luns + + +*** Test Cases *** +Luns ${tc} + [Tags] storage netapp ontapp api luns mockoon + ${command} Catenate + ... ${CMD} + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: tc extra_options expected_result -- + ... 1 ${EMPTY} OK: Lun '/vol/volume1/qtree1/lun1' state: online [container state: string] + ... 2 --warning-status='\\\%{state} !~ /notonline/i' WARNING: Lun '/vol/volume1/qtree1/lun1' state: online [container state: string] + ... 3 --critical-status='\\\%{state} !~ /notonline/i' CRITICAL: Lun '/vol/volume1/qtree1/lun1' state: online [container state: string] diff --git a/tests/storage/netapp/ontap/restapi/netapp.json b/tests/storage/netapp/ontap/restapi/netapp.json new file mode 100644 index 0000000000..895892e75a --- /dev/null +++ b/tests/storage/netapp/ontap/restapi/netapp.json @@ -0,0 +1,522 @@ +{ + "uuid": "ed4ed773-dfc4-4d37-aa5f-6dd89d5fc516", + "lastMigration": 32, + "name": "Netapp", + "endpointPrefix": "api/", + "latency": 0, + "port": 3001, + "hostname": "", + "folders": [], + "routes": [ + { + "uuid": "b092c6f2-c7f9-49a9-8959-8fa6260dbbed", + "type": "http", + "documentation": "", + "method": "get", + "endpoint": "storage/volumes", + "responses": [ + { + "uuid": "ef8f650f-c3cb-4948-b907-3b31a284a065", + "body": "{\r\n \"records\": [\r\n {\r\n \"state\": \"online\",\r\n \"name\": \"volume1\",\r\n \"space\": {\r\n \"auto_adaptive_compression_footprint_data_reduction\": 0,\r\n \"available\": 421353881600,\r\n \"size\": 4398046511104,\r\n \"block_storage_inactive_user_data\": 0,\r\n \"block_storage_inactive_user_data_percent\": 0,\r\n \"capacity_tier_footprint\": 0,\r\n \"capacity_tier_footprint_data_reduction\": 0,\r\n \"compaction_footprint_data_reduction\": 0,\r\n \"cross_volume_dedupe_metafiles_footprint\": 0,\r\n \"cross_volume_dedupe_metafiles_temporary_footprint\": 0,\r\n \"dedupe_metafiles_footprint\": 0,\r\n \"dedupe_metafiles_temporary_footprint\": 0,\r\n \"delayed_free_footprint\": 0,\r\n \"effective_total_footprint\": 0,\r\n \"file_operation_metadata\": 0,\r\n \"filesystem_size\": 0,\r\n \"footprint\": 0,\r\n \"local_tier_footprint\": 0,\r\n \"max_size\": \"string\",\r\n \"logical_space\": {\r\n \"available\": 348998594560,\r\n \"used\": 3169438617600,\r\n \"used_by_afs\": 0,\r\n \"used_by_snapshots\": 0,\r\n \"used_percent\": 90\r\n },\r\n \"metadata\": 0,\r\n \"over_provisioned\": 0,\r\n \"overwrite_reserve\": 0,\r\n \"overwrite_reserve_used\": 0,\r\n \"percent_used\": 0,\r\n \"performance_tier_footprint\": 0,\r\n \"size_available_for_snapshots\": 0,\r\n \"snapmirror_destination_footprint\": 0,\r\n \"snapshot\": {\r\n \"autodelete\": {\r\n \"commitment\": \"string\",\r\n \"defer_delete\": \"string\",\r\n \"delete_order\": \"string\",\r\n \"prefix\": \"string\",\r\n \"trigger\": \"string\"\r\n },\r\n \"autodelete_trigger\": \"string\",\r\n \"reserve_available\": 0,\r\n \"reserve_size\": 0,\r\n \"space_used_percent\": 0,\r\n \"used\": 0\r\n },\r\n \"snapshot_reserve_unusable\": 0,\r\n \"snapshot_spill\": 0,\r\n \"total_footprint\": 0,\r\n \"total_metadata\": 0,\r\n \"total_metadata_footprint\": 0,\r\n \"used\": 3097083330560,\r\n \"user_data\": 0,\r\n \"volume_guarantee_footprint\": 0\r\n },\r\n \"svm\": {\r\n \"name\": \"svm1\",\r\n \"uuid\": \"02c9e252-41be-11e9-81d5-00a0986138f7\"\r\n },\r\n \"uuid\": \"028baa66-41bd-11e9-81d5-00a0986138f7\"\r\n }\r\n ]\r\n}", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "fields", + "value": "svm,name,space,metric", + "invert": false, + "operator": "equals" + }, + { + "target": "query", + "modifier": "name", + "value": "volume1", + "invert": false, + "operator": "equals" + } + ], + "rulesOperator": "AND", + "disableTemplating": false, + "fallbackTo404": false, + "default": false, + "crudKey": "id", + "callbacks": [] + }, + { + "uuid": "2fc4bd82-8f83-4344-bfd7-baa50e6c544a", + "body": "{\r\n \"records\": [\r\n {\r\n \"state\": \"online\",\r\n \"name\": \"volume1\",\r\n \"space\": {\r\n \"auto_adaptive_compression_footprint_data_reduction\": 0,\r\n \"available\": 421353881600,\r\n \"size\": 4398046511104,\r\n \"block_storage_inactive_user_data\": 0,\r\n \"block_storage_inactive_user_data_percent\": 0,\r\n \"capacity_tier_footprint\": 0,\r\n \"capacity_tier_footprint_data_reduction\": 0,\r\n \"compaction_footprint_data_reduction\": 0,\r\n \"cross_volume_dedupe_metafiles_footprint\": 0,\r\n \"cross_volume_dedupe_metafiles_temporary_footprint\": 0,\r\n \"dedupe_metafiles_footprint\": 0,\r\n \"dedupe_metafiles_temporary_footprint\": 0,\r\n \"delayed_free_footprint\": 0,\r\n \"effective_total_footprint\": 0,\r\n \"file_operation_metadata\": 0,\r\n \"filesystem_size\": 0,\r\n \"footprint\": 0,\r\n \"local_tier_footprint\": 0,\r\n \"max_size\": \"string\",\r\n \"metadata\": 0,\r\n \"over_provisioned\": 0,\r\n \"overwrite_reserve\": 0,\r\n \"overwrite_reserve_used\": 0,\r\n \"percent_used\": 0,\r\n \"performance_tier_footprint\": 0,\r\n \"size_available_for_snapshots\": 0,\r\n \"snapmirror_destination_footprint\": 0,\r\n \"snapshot\": {\r\n \"autodelete\": {\r\n \"commitment\": \"string\",\r\n \"defer_delete\": \"string\",\r\n \"delete_order\": \"string\",\r\n \"prefix\": \"string\",\r\n \"trigger\": \"string\"\r\n },\r\n \"autodelete_trigger\": \"string\",\r\n \"reserve_available\": 0,\r\n \"reserve_size\": 0,\r\n \"space_used_percent\": 0,\r\n \"used\": 0\r\n },\r\n \"snapshot_reserve_unusable\": 0,\r\n \"snapshot_spill\": 0,\r\n \"total_footprint\": 0,\r\n \"total_metadata\": 0,\r\n \"total_metadata_footprint\": 0,\r\n \"used\": 3097083330560,\r\n \"user_data\": 0,\r\n \"volume_guarantee_footprint\": 0\r\n },\r\n \"svm\": {\r\n \"name\": \"svm1\",\r\n \"uuid\": \"02c9e252-41be-11e9-81d5-00a0986138f7\"\r\n },\r\n \"uuid\": \"028baa66-41bd-11e9-81d5-00a0986138f7\"\r\n }\r\n ]\r\n}", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "fields", + "value": "svm,name,space,metric", + "invert": false, + "operator": "equals" + } + ], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": true, + "crudKey": "id", + "callbacks": [] + } + ], + "responseMode": null + }, + { + "uuid": "c7fed47d-33b4-49ca-ae60-4a36466b56e2", + "type": "http", + "documentation": "", + "method": "get", + "endpoint": "storage/aggregates", + "responses": [ + { + "uuid": "59a322e4-bb92-4f7c-af6c-d34ce6c0efee", + "body": "{\r\n \"records\": [\r\n {\r\n \"name\": \"aggregate1\",\r\n \"space\": {\r\n \"block_storage\": {\r\n \"aggregate_metadata\": 2655,\r\n \"aggregate_metadata_percent\": 8,\r\n \"available\": 10156560384,\r\n \"data_compacted_count\": 1990000,\r\n \"data_compaction_space_saved\": 1996000,\r\n \"data_compaction_space_saved_percent\": 27,\r\n \"full_threshold_percent\": 0,\r\n \"inactive_user_data\": 304448,\r\n \"inactive_user_data_percent\": 0,\r\n \"performance_tier_cache_used\": 22348,\r\n \"physical_used\": 2461696,\r\n \"physical_used_percent\": 50,\r\n \"size\": 10156769280,\r\n \"used\": 2088960,\r\n \"used_including_snapshot_reserve\": 674685,\r\n \"used_including_snapshot_reserve_percent\": 35,\r\n \"used_percent\": 50,\r\n \"volume_deduplication_shared_count\": 1990000,\r\n \"volume_deduplication_space_saved\": 1996000,\r\n \"volume_deduplication_space_saved_percent\": 27,\r\n \"volume_footprints_percent\": 14\r\n },\r\n \"cloud_storage\": {\r\n \"used\": 402743264\r\n },\r\n \"efficiency\": {\r\n \"logical_used\": 0,\r\n \"ratio\": 0,\r\n \"savings\": 0,\r\n \"wise_tsse_min_used_capacity_pct\": 0\r\n },\r\n \"efficiency_without_snapshots\": {\r\n \"logical_used\": 0,\r\n \"ratio\": 0,\r\n \"savings\": 0\r\n },\r\n \"efficiency_without_snapshots_flexclones\": {\r\n \"logical_used\": 0,\r\n \"ratio\": 0,\r\n \"savings\": 0\r\n },\r\n \"footprint\": 608896,\r\n \"snapshot\": {\r\n \"available\": 2000,\r\n \"reserve_percent\": 20,\r\n \"total\": 5000,\r\n \"used\": 3000,\r\n \"used_percent\": 45\r\n }\r\n },\r\n \"state\": \"online\",\r\n \"uuid\": \"uuid1\"\r\n }\r\n ]\r\n}", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "fields", + "value": "name,uuid,state,space", + "invert": false, + "operator": "equals" + } + ], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": true, + "crudKey": "id", + "callbacks": [] + }, + { + "uuid": "d7113366-3743-4835-840c-50c951325dbc", + "body": "{\r\n \"metric\": {\r\n \"duration\": \"PT15S\",\r\n \"iops\": {\r\n \"read\": 500,\r\n \"total\": 1000,\r\n \"write\": 200\r\n },\r\n \"latency\": {\r\n \"read\": 500,\r\n \"total\": 1000,\r\n \"write\": 200\r\n },\r\n \"throughput\": {\r\n \"read\": 500,\r\n \"total\": 1000,\r\n \"write\": 200\r\n }\r\n }\r\n}", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": false, + "crudKey": "id", + "callbacks": [] + } + ], + "responseMode": null + }, + { + "uuid": "8a4da98b-bb46-4354-99a2-5bedf85f600c", + "type": "http", + "documentation": "", + "method": "get", + "endpoint": "storage/aggregates/uuid1", + "responses": [ + { + "uuid": "e865d16b-1ee0-4869-9cf3-9442dae20e91", + "body": "{\r\n \"metric\": {\r\n \"duration\": \"PT15S\",\r\n \"iops\": {\r\n \"read\": 500,\r\n \"total\": 1000,\r\n \"write\": 200\r\n },\r\n \"latency\": {\r\n \"read\": 500,\r\n \"total\": 1000,\r\n \"write\": 200\r\n },\r\n \"throughput\": {\r\n \"read\": 500,\r\n \"total\": 1000,\r\n \"write\": 200\r\n }\r\n }\r\n}", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "fields", + "value": "metric", + "invert": false, + "operator": "equals" + } + ], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": true, + "crudKey": "id", + "callbacks": [] + } + ], + "responseMode": null + }, + { + "uuid": "b7353636-e212-42db-b9a9-92c8243c8bbe", + "type": "http", + "documentation": "", + "method": "get", + "endpoint": "cluster/nodes", + "responses": [ + { + "uuid": "85d0f9d0-ab71-4b2b-a13f-c51afa1fa740", + "body": "{\r\n \"records\": [\r\n {\r\n \"name\": \"node-01\",\r\n \"service_processor\": {\r\n \"api_service\": {\r\n \"port\": 0\r\n },\r\n \"auto_config\": {\r\n \"ipv4_subnet\": \"ipv4_mgmt\",\r\n \"ipv6_subnet\": \"ipv6_mgmt\"\r\n },\r\n \"backup\": {\r\n \"state\": \"string\",\r\n \"version\": \"11.6\"\r\n },\r\n \"firmware_version\": \"string\",\r\n \"ipv4_interface\": {\r\n \"address\": \"10.0.0.1\",\r\n \"gateway\": \"10.1.1.1\",\r\n \"netmask\": \"255.255.0.0\",\r\n \"setup_state\": \"string\"\r\n },\r\n \"ipv6_interface\": {\r\n \"address\": \"fd20:8b1e:b255:5011:10:141:4:97\",\r\n \"gateway\": \"fd20:8b1e:b255:5011:10::1\",\r\n \"link_local_ip\": \"FE80::/10\",\r\n \"netmask\": 64,\r\n \"router_ip\": \"2001:0db8:85a3:0000:0000:8a2e:0370:7334\",\r\n \"setup_state\": \"string\"\r\n },\r\n \"last_update_state\": \"string\",\r\n \"link_status\": \"string\",\r\n \"mac_address\": \"string\",\r\n \"primary\": {\r\n \"state\": \"string\",\r\n \"version\": \"11.6\"\r\n },\r\n \"ssh_info\": {\r\n \"allowed_addresses\": [\r\n \"10.0.0.32/24\"\r\n ]\r\n },\r\n \"state\": \"online\",\r\n \"type\": \"string\"\r\n }\r\n }\r\n ]\r\n}", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "fields", + "value": "name,service_processor", + "invert": false, + "operator": "equals" + } + ], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": true, + "crudKey": "id", + "callbacks": [] + } + ], + "responseMode": null + }, + { + "uuid": "dd645a12-810b-430b-9dba-a52e860c1389", + "type": "http", + "documentation": "", + "method": "get", + "endpoint": "storage/disks", + "responses": [ + { + "uuid": "05795870-c33f-4bc6-a911-51d1b0d89b14", + "body": "{\r\n \"records\": [\r\n {\r\n \"bay\": 1,\r\n \"name\": \"name1\",\r\n \"serial_number\": \"SERIALNUMBER1\",\r\n \"state\": \"present\"\r\n }\r\n ]\r\n}", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "fields", + "value": "name,state,serial_number,bay", + "invert": false, + "operator": "equals" + } + ], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": true, + "crudKey": "id", + "callbacks": [] + } + ], + "responseMode": null + }, + { + "uuid": "2d1d1ff3-4ba6-4bc2-8f51-0894e08dd7a1", + "type": "http", + "documentation": "", + "method": "get", + "endpoint": "storage/shelves", + "responses": [ + { + "uuid": "44d9f780-3f6b-4a96-82aa-2c8415da3e26", + "body": "{\r\n \"records\": [\r\n {\r\n \"bays\": [\r\n {\r\n \"drawer\": {\r\n \"id\": 1,\r\n \"slot\": 0\r\n },\r\n \"id\": 0,\r\n \"state\": \"ok\",\r\n \"type\": \"single_disk\"\r\n }\r\n ],\r\n \"frus\": [\r\n {\r\n \"firmware_version\": \"0191\",\r\n \"installed\": 1,\r\n \"part_number\": \"111-00690+A2\",\r\n \"psu\": {\r\n \"crest_factor\": 92,\r\n \"model\": \"00\",\r\n \"power_drawn\": 210,\r\n \"power_rating\": 1600\r\n },\r\n \"serial_number\": \"8000166294\",\r\n \"state\": \"ok\",\r\n \"type\": \"module\"\r\n }\r\n ],\r\n \"name\": \"name1\",\r\n \"serial_number\": \"SERIALNUMBER1\",\r\n \"state\": \"ok\"\r\n }\r\n ]\r\n}", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "fields", + "value": "name,state,serial_number,bay,frus", + "invert": false, + "operator": "equals" + } + ], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": true, + "crudKey": "id", + "callbacks": [] + } + ], + "responseMode": null + }, + { + "uuid": "d8a1376f-13eb-4f0a-8cfc-6e27cc9fad44", + "type": "http", + "documentation": "", + "method": "get", + "endpoint": "storage/luns", + "responses": [ + { + "uuid": "a24b1b62-4f9a-4562-b28a-a9312897c224", + "body": "{\r\n \"records\": [\r\n {\r\n \"name\": \"/vol/volume1/qtree1/lun1\",\r\n \"status\": {\r\n \"container_state\": \"string\",\r\n \"state\": \"online\"\r\n }\r\n }\r\n ]\r\n}", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "fields", + "value": "name,status", + "invert": false, + "operator": "equals" + } + ], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": true, + "crudKey": "id", + "callbacks": [] + } + ], + "responseMode": null + }, + { + "uuid": "10b0762f-0ffa-4abc-9a61-e07b4ead2d41", + "type": "http", + "documentation": "", + "method": "get", + "endpoint": "storage/quota/reports", + "responses": [ + { + "uuid": "341450a3-2dde-4d72-9d0b-e18542c13baf", + "body": "{\r\n\r\n \"records\": [\r\n {\r\n \"index\": 0,\r\n \"qtree\": {\r\n \"id\": 1,\r\n \"name\": \"qt1\"\r\n },\r\n \"space\": {\r\n \"hard_limit\": 100,\r\n \"soft_limit\": 90,\r\n \"used\": {\r\n \"hard_limit_percent\": 0,\r\n \"soft_limit_percent\": 0,\r\n \"total\": 50\r\n }\r\n },\r\n \"svm\": {\r\n \"name\": \"svm1\",\r\n \"uuid\": \"02c9e252-41be-11e9-81d5-00a0986138f7\"\r\n },\r\n \"volume\": {\r\n \"_links\": {\r\n \"self\": {\r\n \"href\": \"/api/resourcelink\"\r\n }\r\n },\r\n \"name\": \"volume1\",\r\n \"uuid\": \"028baa66-41bd-11e9-81d5-00a0986138f7\"\r\n }\r\n }\r\n ]\r\n}", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "fields", + "value": "index,qtree,volume,svm,space", + "invert": false, + "operator": "equals" + } + ], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": true, + "crudKey": "id", + "callbacks": [] + } + ], + "responseMode": null + }, + { + "uuid": "98e5a1f9-d66f-4958-9cd7-52a252c6421b", + "type": "http", + "documentation": "", + "method": "get", + "endpoint": "snapmirror/relationships", + "responses": [ + { + "uuid": "331c652b-bc0d-407c-b746-b9c11cdaaaa9", + "body": "{\r\n \"records\": [\r\n {\r\n \"destination\": {\r\n \"cluster\": {\r\n \"_links\": {\r\n \"self\": {\r\n \"href\": \"/api/resourcelink\"\r\n }\r\n },\r\n \"name\": \"cluster1\",\r\n \"uuid\": \"1cd8a442-86d1-11e0-ae1c-123478563412\"\r\n },\r\n \"consistency_group_volumes\": [\r\n {\r\n \"name\": \"volume1\",\r\n \"uuid\": \"028baa66-41bd-11e9-81d5-00a0986138f7\"\r\n }\r\n ],\r\n \"ipspace\": \"Default\",\r\n \"path\": \"svm1:volume1\",\r\n \"svm\": {\r\n \"_links\": {\r\n \"self\": {\r\n \"href\": \"/api/resourcelink\"\r\n }\r\n },\r\n \"name\": \"svm1\",\r\n \"uuid\": \"02c9e252-41be-11e9-81d5-00a0986138f7\"\r\n },\r\n \"uuid\": \"4ea7a442-86d1-11e0-ae1c-123478563412\"\r\n },\r\n \"source\": {\r\n \"cluster\": {\r\n \"_links\": {\r\n \"self\": {\r\n \"href\": \"/api/resourcelink\"\r\n }\r\n },\r\n \"name\": \"cluster1\",\r\n \"uuid\": \"1cd8a442-86d1-11e0-ae1c-123478563412\"\r\n },\r\n \"consistency_group_volumes\": [\r\n {\r\n \"name\": \"volume1\",\r\n \"uuid\": \"028baa66-41bd-11e9-81d5-00a0986138f7\"\r\n }\r\n ],\r\n \"path\": \"svm1:volume1\",\r\n \"svm\": {\r\n \"_links\": {\r\n \"self\": {\r\n \"href\": \"/api/resourcelink\"\r\n }\r\n },\r\n \"name\": \"svm1\",\r\n \"uuid\": \"02c9e252-41be-11e9-81d5-00a0986138f7\"\r\n },\r\n \"uuid\": \"4ea7a442-86d1-11e0-ae1c-123478563412\"\r\n },\r\n \"state\": \"snapmirrored\",\r\n \"transfer\": {\r\n \"end_time\": \"2020-12-02 21:36:19 -0500\",\r\n \"last_updated_time\": \"2023-09-14 18:39:19 -0400\",\r\n \"state\": \"string\",\r\n \"total_duration\": \"PT28M41S\",\r\n \"type\": \"initialize\",\r\n \"uuid\": \"4ea7a442-86d1-11e0-ae1c-123478563412\"\r\n },\r\n \"unhealthy_reason\": [\r\n {\r\n \"arguments\": [],\r\n \"code\": \"6621444\",\r\n \"message\": \"Failed to complete update operation on one or more item relationships.\"\r\n },\r\n {\r\n \"arguments\": [],\r\n \"code\": \"6621445\",\r\n \"message\": \"Group Update failed\"\r\n }\r\n ]\r\n }\r\n ]\r\n}", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "fields", + "value": "source,destination,healthy,state,transfer", + "invert": false, + "operator": "equals" + } + ], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": true, + "crudKey": "id", + "callbacks": [] + } + ], + "responseMode": null + }, + { + "uuid": "39d42600-9290-4c9c-aecc-331a5b8683be", + "type": "http", + "documentation": "", + "method": "get", + "endpoint": "cluster", + "responses": [ + { + "uuid": "1347a6b4-a393-4ff2-84c7-729b23c7f64a", + "body": "{\r\n \"metric\": {\r\n \"_links\": {\r\n \"self\": {\r\n \"href\": \"/api/resourcelink\"\r\n }\r\n },\r\n \"duration\": \"PT15S\",\r\n \"iops\": {\r\n \"read\": 200,\r\n \"total\": 1000,\r\n \"write\": 100\r\n },\r\n \"latency\": {\r\n \"read\": 200,\r\n \"total\": 1000,\r\n \"write\": 100\r\n },\r\n \"status\": \"ok\",\r\n \"throughput\": {\r\n \"read\": 200,\r\n \"total\": 1000,\r\n \"write\": 100\r\n },\r\n \"timestamp\": \"2017-01-25 06:20:13 -0500\"\r\n },\r\n \"name\": \"cluster1\",\r\n \"statistics\": {\r\n \"iops_raw\": {\r\n \"read\": 200,\r\n \"total\": 1000,\r\n \"write\": 100\r\n },\r\n \"latency_raw\": {\r\n \"read\": 200,\r\n \"total\": 1000,\r\n \"write\": 100\r\n },\r\n \"status\": \"ok\",\r\n \"throughput_raw\": {\r\n \"read\": 200,\r\n \"total\": 1000,\r\n \"write\": 100\r\n },\r\n \"timestamp\": \"2017-01-25 06:20:13 -0500\"\r\n }\r\n}", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [ + { + "target": "query", + "modifier": "fields", + "value": "name,statistics,metric", + "invert": false, + "operator": "equals" + } + ], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": true, + "crudKey": "id", + "callbacks": [] + } + ], + "responseMode": null + } + ], + "rootChildren": [ + { + "type": "route", + "uuid": "b092c6f2-c7f9-49a9-8959-8fa6260dbbed" + }, + { + "type": "route", + "uuid": "c7fed47d-33b4-49ca-ae60-4a36466b56e2" + }, + { + "type": "route", + "uuid": "8a4da98b-bb46-4354-99a2-5bedf85f600c" + }, + { + "type": "route", + "uuid": "b7353636-e212-42db-b9a9-92c8243c8bbe" + }, + { + "type": "route", + "uuid": "dd645a12-810b-430b-9dba-a52e860c1389" + }, + { + "type": "route", + "uuid": "2d1d1ff3-4ba6-4bc2-8f51-0894e08dd7a1" + }, + { + "type": "route", + "uuid": "d8a1376f-13eb-4f0a-8cfc-6e27cc9fad44" + }, + { + "type": "route", + "uuid": "10b0762f-0ffa-4abc-9a61-e07b4ead2d41" + }, + { + "type": "route", + "uuid": "98e5a1f9-d66f-4958-9cd7-52a252c6421b" + }, + { + "type": "route", + "uuid": "39d42600-9290-4c9c-aecc-331a5b8683be" + } + ], + "proxyMode": false, + "proxyHost": "", + "proxyRemovePrefix": false, + "tlsOptions": { + "enabled": false, + "type": "CERT", + "pfxPath": "", + "certPath": "", + "keyPath": "", + "caPath": "", + "passphrase": "" + }, + "cors": true, + "headers": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS" + }, + { + "key": "Access-Control-Allow-Headers", + "value": "Content-Type, Origin, Accept, Authorization, Content-Length, X-Requested-With" + } + ], + "proxyReqHeaders": [ + { + "key": "", + "value": "" + } + ], + "proxyResHeaders": [ + { + "key": "", + "value": "" + } + ], + "data": [], + "callbacks": [] +} \ No newline at end of file diff --git a/tests/storage/netapp/ontap/restapi/quotas.robot b/tests/storage/netapp/ontap/restapi/quotas.robot new file mode 100644 index 0000000000..d17c9fa4ff --- /dev/null +++ b/tests/storage/netapp/ontap/restapi/quotas.robot @@ -0,0 +1,40 @@ +*** Settings *** +Documentation Netapp Ontap Restapi Quotas plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Start Mockoon ${MOCKOON_JSON} +Suite Teardown Stop Mockoon +Test Timeout 120s + + +*** Variables *** +${MOCKOON_JSON} ${CURDIR}${/}netapp.json + +${cmd} ${CENTREON_PLUGINS} +... --plugin=storage::netapp::ontap::restapi::plugin +... --hostname=${HOSTNAME} +... --port=${APIPORT} +... --proto=http +... --api-username=username +... --api-password=password +... --mode=quotas + + +*** Test Cases *** +Quotas ${tc} + [Tags] storage netapp ontapp api quotas mockoon + ${command} Catenate + ... ${CMD} + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: tc extra_options expected_result -- + ... 1 ${EMPTY} OK: Quota 'vserver:svm1,volume:volume1,qtree:qt1' total: 100.00 B used: 50.00 B (50.00%) free: 50.00 B (50.00%) | 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.usage.bytes'=50B;0:90;;0;100 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.free.bytes'=50B;;;0;100 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.usage.percentage'=50.00%;;;0;100 + ... 2 --warning-space-usage='1:1' OK: Quota 'vserver:svm1,volume:volume1,qtree:qt1' total: 100.00 B used: 50.00 B (50.00%) free: 50.00 B (50.00%) | 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.usage.bytes'=50B;0:90;;0;100 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.free.bytes'=50B;;;0;100 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.usage.percentage'=50.00%;;;0;100 + ... 3 --critical-space-usage='1:1' CRITICAL: Quota 'vserver:svm1,volume:volume1,qtree:qt1' total: 100.00 B used: 50.00 B (50.00%) free: 50.00 B (50.00%) | 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.usage.bytes'=50B;0:90;1:1;0;100 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.free.bytes'=50B;;;0;100 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.usage.percentage'=50.00%;;;0;100 + ... 4 --warning-space-usage-prct='1:1' WARNING: Quota 'vserver:svm1,volume:volume1,qtree:qt1' total: 100.00 B used: 50.00 B (50.00%) free: 50.00 B (50.00%) | 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.usage.bytes'=50B;0:90;;0;100 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.free.bytes'=50B;;;0;100 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.usage.percentage'=50.00%;1:1;;0;100 + ... 5 --critical-space-usage-prct='1:1' CRITICAL: Quota 'vserver:svm1,volume:volume1,qtree:qt1' total: 100.00 B used: 50.00 B (50.00%) free: 50.00 B (50.00%) | 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.usage.bytes'=50B;0:90;;0;100 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.free.bytes'=50B;;;0;100 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.usage.percentage'=50.00%;;1:1;0;100 + ... 6 --warning-space-usage-free='1:1' WARNING: Quota 'vserver:svm1,volume:volume1,qtree:qt1' total: 100.00 B used: 50.00 B (50.00%) free: 50.00 B (50.00%) | 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.usage.bytes'=50B;0:90;;0;100 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.free.bytes'=50B;1:1;;0;100 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.usage.percentage'=50.00%;;;0;100 + ... 7 --critical-space-usage-free='1:1' CRITICAL: Quota 'vserver:svm1,volume:volume1,qtree:qt1' total: 100.00 B used: 50.00 B (50.00%) free: 50.00 B (50.00%) | 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.usage.bytes'=50B;0:90;;0;100 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.free.bytes'=50B;;1:1;0;100 'vserver:svm1~volume:volume1~qtree:qt1#quota.space.usage.percentage'=50.00%;;;0;100 diff --git a/tests/storage/netapp/ontap/restapi/snapmirrors.robot b/tests/storage/netapp/ontap/restapi/snapmirrors.robot new file mode 100644 index 0000000000..bbee4dd801 --- /dev/null +++ b/tests/storage/netapp/ontap/restapi/snapmirrors.robot @@ -0,0 +1,36 @@ +*** Settings *** +Documentation Netapp Ontap Restapi Snapmirrors plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Start Mockoon ${MOCKOON_JSON} +Suite Teardown Stop Mockoon +Test Timeout 120s + + +*** Variables *** +${MOCKOON_JSON} ${CURDIR}${/}netapp.json + +${cmd} ${CENTREON_PLUGINS} +... --plugin=storage::netapp::ontap::restapi::plugin +... --hostname=${HOSTNAME} +... --port=${APIPORT} +... --proto=http +... --api-username=username +... --api-password=password +... --mode=snapmirrors + + +*** Test Cases *** +Snapmirrors ${tc} + [Tags] storage netapp ontapp api snapmirrors mockoon + ${command} Catenate + ... ${CMD} + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: tc extra_options expected_result -- + ... 1 --critical-status='' OK: Snapmirror 'svm1:volume1-svm1:volume1' healthy: false [state: snapmirrored] [transfer state: string] + ... 2 ${EMPTY} CRITICAL: Snapmirror 'svm1:volume1-svm1:volume1' healthy: false [state: snapmirrored] [transfer state: string] + ... 3 --warning-status='\\\%{healthy} ne "true"' --critical-status='' WARNING: Snapmirror 'svm1:volume1-svm1:volume1' healthy: false [state: snapmirrored] [transfer state: string] diff --git a/tests/storage/netapp/ontap/restapi/volumes.robot b/tests/storage/netapp/ontap/restapi/volumes.robot new file mode 100644 index 0000000000..382f9d22ec --- /dev/null +++ b/tests/storage/netapp/ontap/restapi/volumes.robot @@ -0,0 +1,42 @@ +*** Settings *** +Documentation Netapp Ontap Restapi Volumes plugin + +Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Start Mockoon ${MOCKOON_JSON} +Suite Teardown Stop Mockoon +Test Timeout 120s + + +*** Variables *** +${MOCKOON_JSON} ${CURDIR}${/}netapp.json + +${cmd} ${CENTREON_PLUGINS} +... --plugin=storage::netapp::ontap::restapi::plugin +... --hostname=${HOSTNAME} +... --port=${APIPORT} +... --proto=http +... --api-username=username +... --api-password=password +... --mode=volumes + + +*** Test Cases *** +Volumes ${tc} + [Tags] storage netapp ontapp api volumes mockoon + ${command} Catenate + ... ${CMD} + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: tc extra_options expected_result -- + ... 1 ${EMPTY} OK: Volume 'svm1:volume1' state: online, space usage total: 4.00 TB used: 2.82 TB (90.42%) free: 392.42 GB (9.58%), logical-usage : skipped (no value(s)), logical-usage-free : skipped (no value(s)), logical-usage-prct : skipped (no value(s)), read : skipped (no value(s)), write : skipped (no value(s)), other : skipped (no value(s)), total : skipped (no value(s)), read-iops : skipped (no value(s)), write-iops : skipped (no value(s)), other-iops : skipped (no value(s)), total-iops : skipped (no value(s)), read-latency : skipped (no value(s)), write-latency : skipped (no value(s)), other-latency : skipped (no value(s)), total-latency : skipped (no value(s)) | 'svm1:volume1#volume.space.usage.bytes'=3097083330560B;;;0;4398046511104 'svm1:volume1#volume.space.free.bytes'=421353881600B;;;0;4398046511104 'svm1:volume1#volume.space.usage.percentage'=90.42%;;;0;100 + ... 2 --filter-volume-name='volume1' OK: Volume 'svm1:volume1' state: online, space usage total: 4.00 TB used: 2.82 TB (90.42%) free: 392.42 GB (9.58%), logical space usage total: 3.20 TB used: 2.88 TB (90.00%) free: 325.03 GB (10.00%), read : skipped (no value(s)), write : skipped (no value(s)), other : skipped (no value(s)), total : skipped (no value(s)), read-iops : skipped (no value(s)), write-iops : skipped (no value(s)), other-iops : skipped (no value(s)), total-iops : skipped (no value(s)), read-latency : skipped (no value(s)), write-latency : skipped (no value(s)), other-latency : skipped (no value(s)), total-latency : skipped (no value(s)) | 'svm1:volume1#volume.space.usage.bytes'=3097083330560B;;;0;4398046511104 'svm1:volume1#volume.space.free.bytes'=421353881600B;;;0;4398046511104 'svm1:volume1#volume.space.usage.percentage'=90.42%;;;0;100 'svm1:volume1#volume.logicalspace.usage.bytes'=3169438617600B;;;0;3518437212160 'svm1:volume1#volume.logicalspace.free.bytes'=348998594560B;;;0;3518437212160 'svm1:volume1#volume.logicalspace.usage.percentage'=90.00%;;;0;100 + ... 3 --filter-name='volume1' OK: Volume 'svm1:volume1' state: online, space usage total: 4.00 TB used: 2.82 TB (90.42%) free: 392.42 GB (9.58%), logical-usage : skipped (no value(s)), logical-usage-free : skipped (no value(s)), logical-usage-prct : skipped (no value(s)), read : skipped (no value(s)), write : skipped (no value(s)), other : skipped (no value(s)), total : skipped (no value(s)), read-iops : skipped (no value(s)), write-iops : skipped (no value(s)), other-iops : skipped (no value(s)), total-iops : skipped (no value(s)), read-latency : skipped (no value(s)), write-latency : skipped (no value(s)), other-latency : skipped (no value(s)), total-latency : skipped (no value(s)) | 'svm1:volume1#volume.space.usage.bytes'=3097083330560B;;;0;4398046511104 'svm1:volume1#volume.space.free.bytes'=421353881600B;;;0;4398046511104 'svm1:volume1#volume.space.usage.percentage'=90.42%;;;0;100 + ... 4 --warning-status='\\\%{state} !~ /notonline/i' WARNING: Volume 'svm1:volume1' state: online | 'svm1:volume1#volume.space.usage.bytes'=3097083330560B;;;0;4398046511104 'svm1:volume1#volume.space.free.bytes'=421353881600B;;;0;4398046511104 'svm1:volume1#volume.space.usage.percentage'=90.42%;;;0;100 + ... 5 --critical-status='\\\%{state} !~ /notonline/i' CRITICAL: Volume 'svm1:volume1' state: online | 'svm1:volume1#volume.space.usage.bytes'=3097083330560B;;;0;4398046511104 'svm1:volume1#volume.space.free.bytes'=421353881600B;;;0;4398046511104 'svm1:volume1#volume.space.usage.percentage'=90.42%;;;0;100 + ... 6 --warning-usage-prct=50 WARNING: Volume 'svm1:volume1' space usage total: 4.00 TB used: 2.82 TB (90.42%) free: 392.42 GB (9.58%) | 'svm1:volume1#volume.space.usage.bytes'=3097083330560B;;;0;4398046511104 'svm1:volume1#volume.space.free.bytes'=421353881600B;;;0;4398046511104 'svm1:volume1#volume.space.usage.percentage'=90.42%;0:50;;0;100 + ... 7 --critical-usage-prct=50 CRITICAL: Volume 'svm1:volume1' space usage total: 4.00 TB used: 2.82 TB (90.42%) free: 392.42 GB (9.58%) | 'svm1:volume1#volume.space.usage.bytes'=3097083330560B;;;0;4398046511104 'svm1:volume1#volume.space.free.bytes'=421353881600B;;;0;4398046511104 'svm1:volume1#volume.space.usage.percentage'=90.42%;;0:50;0;100 + ... 8 --filter-volume-name='volume1' --warning-logical-usage-prct=50 WARNING: Volume 'svm1:volume1' logical space usage total: 3.20 TB used: 2.88 TB (90.00%) free: 325.03 GB (10.00%) | 'svm1:volume1#volume.space.usage.bytes'=3097083330560B;;;0;4398046511104 'svm1:volume1#volume.space.free.bytes'=421353881600B;;;0;4398046511104 'svm1:volume1#volume.space.usage.percentage'=90.42%;;;0;100 'svm1:volume1#volume.logicalspace.usage.bytes'=3169438617600B;;;0;3518437212160 'svm1:volume1#volume.logicalspace.free.bytes'=348998594560B;;;0;3518437212160 'svm1:volume1#volume.logicalspace.usage.percentage'=90.00%;0:50;;0;100 + ... 9 --filter-volume-name='volume1' --critical-logical-usage-prct=50 CRITICAL: Volume 'svm1:volume1' logical space usage total: 3.20 TB used: 2.88 TB (90.00%) free: 325.03 GB (10.00%) | 'svm1:volume1#volume.space.usage.bytes'=3097083330560B;;;0;4398046511104 'svm1:volume1#volume.space.free.bytes'=421353881600B;;;0;4398046511104 'svm1:volume1#volume.space.usage.percentage'=90.42%;;;0;100 'svm1:volume1#volume.logicalspace.usage.bytes'=3169438617600B;;;0;3518437212160 'svm1:volume1#volume.logicalspace.free.bytes'=348998594560B;;;0;3518437212160 'svm1:volume1#volume.logicalspace.usage.percentage'=90.00%;;0:50;0;100 From 5d652f5c3511f2af5c2d780471235b22dd9e1e9c Mon Sep 17 00:00:00 2001 From: itoussies Date: Thu, 26 Dec 2024 16:59:28 +0100 Subject: [PATCH 8/9] Add logical space usage metrics & other enhancements --- .../netapp/ontap/restapi/mode/cluster.pm | 8 +- .../ontap/restapi/mode/components/fru.pm | 2 +- .../netapp/ontap/restapi/mode/hardware.pm | 4 +- .../netapp/ontap/restapi/mode/quotas.pm | 4 +- .../netapp/ontap/restapi/mode/snapmirrors.pm | 4 +- tests/resources/spellcheck/stopwords.txt | 137 +++++++----------- .../netapp/ontap/restapi/cluster.robot | 7 +- .../netapp/ontap/restapi/hardware.robot | 8 +- 8 files changed, 72 insertions(+), 102 deletions(-) diff --git a/src/storage/netapp/ontap/restapi/mode/cluster.pm b/src/storage/netapp/ontap/restapi/mode/cluster.pm index 013c7c88f9..a85178bfab 100644 --- a/src/storage/netapp/ontap/restapi/mode/cluster.pm +++ b/src/storage/netapp/ontap/restapi/mode/cluster.pm @@ -245,7 +245,7 @@ Check cluster. =item B<--filter-counters> Only display some counters (regexp can be used). -Example: --filter-counters='node-status' +Example: C<--filter-counters='node-status'> =item B<--unknown-node-status> @@ -265,9 +265,9 @@ You can use the following variables: %{state}, %{link_status}, %{display} =item B<--warning-*> B<--critical-*> Thresholds. -Can be: 'cpu-utilization' (%), 'read' (B/s), 'write' (B/s), 'read-iops', 'write-iops', -'read-latency' (ms), 'write-lantency' (ms), 'other-latency' (ms), 'total-latency' (ms), -'other' (B/s), 'total' (B/s), 'other-iops', 'total-iops'. +Can be: C (%), C (B/s), C (B/s), C, C, +C (ms), C (ms), C (ms), C (ms), +C (B/s), C (B/s), C, C. =back diff --git a/src/storage/netapp/ontap/restapi/mode/components/fru.pm b/src/storage/netapp/ontap/restapi/mode/components/fru.pm index 247320c1f9..14d4877a95 100644 --- a/src/storage/netapp/ontap/restapi/mode/components/fru.pm +++ b/src/storage/netapp/ontap/restapi/mode/components/fru.pm @@ -43,7 +43,7 @@ sub check { next if ($self->check_filter(section => 'shelf', instance => $shelf_instance)); foreach my $fru (@{$shelf->{frus}}) { - my $name = $fru->{type} . ':' . $fru->{id}; + my $name = $fru->{type} . ':' . (defined($fru->{id}) ? $fru->{id} : ''); if ($fru->{installed} !~ /true|1/i) { $self->{output}->output_add( diff --git a/src/storage/netapp/ontap/restapi/mode/hardware.pm b/src/storage/netapp/ontap/restapi/mode/hardware.pm index e469504d6b..5471ec4c9b 100644 --- a/src/storage/netapp/ontap/restapi/mode/hardware.pm +++ b/src/storage/netapp/ontap/restapi/mode/hardware.pm @@ -96,7 +96,7 @@ Check hardware. =item B<--component> Which component to check (default: '.*'). -Can be: 'bay', 'disk', 'fru', 'shelf'. +Can be: C, C, C, C. =item B<--filter> @@ -110,7 +110,7 @@ Define the expected status if no components are found (default: critical). =item B<--threshold-overload> Use this option to override the status returned by the plugin when the status label matches a regular expression (syntax: section,[instance,]status,regexp). -Example: --threshold-overload='fru,OK,error' +Example: C<--threshold-overload='fru,OK,error'> =back diff --git a/src/storage/netapp/ontap/restapi/mode/quotas.pm b/src/storage/netapp/ontap/restapi/mode/quotas.pm index d54848299f..9560680f00 100644 --- a/src/storage/netapp/ontap/restapi/mode/quotas.pm +++ b/src/storage/netapp/ontap/restapi/mode/quotas.pm @@ -318,7 +318,7 @@ Filter by index (identified entry in the /etc/quotas) (can be a regexp). =item B<--filter-vserver> -Filter by vserver name (can be a regexp). +Filter by Vserver name (can be a regexp). =item B<--filter-volume> @@ -326,7 +326,7 @@ Filter by volume name (can be a regexp). =item B<--filter-qtree> -Filter by qtree name (can be a regexp). +Filter by Qtree name (can be a regexp). =item B<--warning-*> B<--critical-*> diff --git a/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm b/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm index 7a6cffdb7a..db1ce4400e 100644 --- a/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm +++ b/src/storage/netapp/ontap/restapi/mode/snapmirrors.pm @@ -107,13 +107,13 @@ __END__ =head1 MODE -Check snapmirrors. +Check SnapMirrors. =over 8 =item B<--filter-name> -Filter snapmirror name (can be a regexp). +Filter SnapMirror name (can be a regexp). =item B<--unknown-status> diff --git a/tests/resources/spellcheck/stopwords.txt b/tests/resources/spellcheck/stopwords.txt index dec2236406..ffd837cfc4 100644 --- a/tests/resources/spellcheck/stopwords.txt +++ b/tests/resources/spellcheck/stopwords.txt @@ -1,175 +1,145 @@ 2c 3COM 3CX ---3cx-version ---add-fc-fe-errors ---add-qos-limit ---add-sysdesc +7210SAS +7750SR +ACS ADSL Alcatel allCapacity Ansible ---api-filter-orgs api.meraki.com ---api-password ---api-path ---api-token ---api-username ---api-version +AppearTV ASAM Avigilon +Avocent +aws +AWSCLI Backbox ---cacert-file +base64 +blocked-by-uf cardtemperature +centreon Centreon ---cert-pkcs12 ---cert-pwd -connections-dhcp -connections-dns -cpu-utilization-1m -cpu-utilization-5m -cpu-utilization-5s ---critical-backend-congestions ---critical-backend-outstanding-io ---critical-bytesallocatedpercentage ---critical-na +centreonvault +CloudWatch +CPUs Datacore datasource DC4 dcdiag deduplication deltaps +dev df ---dfsr dfsrevent ---display-transform-dst ---display-transform-src ---dyn-mode +--diskpath +dns-resolve-time -EncodedCommand +env +ESX eth ---exclude-fs fanspeed FCCapacity ---filter-fs ---filter-imei ---filter-vdom ---filter-vm ---force-64bits-counters ---force-counters32 ---force-counters64 ---force-oid Fortigate Fortinet frsevent ---get-param HashiCorp hashicorpvault HPE +Huawei ifAlias +includeAllDisks ifDesc ifName ---ignore-orgs-api-disabled IMEI in-bcast in-crc in-fcserror in-mcast -InputFormat -interface-dsl-name +InterrupibleSleep in-ucast +iops IpAddr ipv4 ipv6 ISAM Iwsva ---jobq +jmeter +JMeter JOBQ jobqueue jobqueues journalctl kccevent keepass +Keysight Kubernetes ldap ---legacy-api-beta -license-instances-usage-prct Loggly ---lookup-perfdatas-nagios +LUN +LUNs machineaccount ---map-speed-dsl MBean +Mbps +McAfee memAvailReal memBuffer memTotalReal Meraki MIB -module-cellradio-csq -module-cellradio-rscp -module-cellradio-rsrp -module-cellradio-rsrq -module-cellradio-snr -modules-cellradio-detected Mosquitto ---mqtt MQTT ---mqtt-allow-insecure ---mqtt-ca-certificate ---mqtt-password ---mqtt-port ---mqtt-ssl ---mqtt-ssl-certificate ---mqtt-ssl-key ---mqtt-timeout ---mqtt-username multiple nagios Nagios NagVis ---nagvis-perfdata Netscaler net-snmp NLCapacity ---noeventlog -NoLogo ---nomachineaccount ---ntlmv2 NTLMv2 NTP ---oid +NVOS OID ---oid-display ---oid-extra-display ---oid-filter +OIDs okta oneaccess-sys-mib +OpenMetrics out-bcast out-fc-wait out-mcast out-ucast overprovisioning ---patch-redhat perfdata physicaldrive PKCS1 powershell powershell.exe +PPID prct Primera +Procurve proto psu QoS -queue-messages-inflighted +Qtree RestAPI RFC1628 RRDCached Sansymphony ---scope-datacenter +SAS +scenarii sfp.temperature +SkyHigh +SnapMirror +SnapMirrors SNMP -space-usage-prct ---sql-errors-exit +snmpd.conf SSDCapacity SSH +statefile SureBackup systemd SysVol @@ -177,32 +147,31 @@ TCP teampass Teldat timeframe -topic-messages-inflighted -total-offline-prct -total-online-prct -total-oper-down +TiMOS +tmnxSasAlarmInputDescription total-oper-up -tower-cli +total-oper-down TrendMicro +tsdb-version UCD UDP +UninterrupibleSleep +uniq uptime ---urlpath usage-prct userpass ---use-ucd v1 v2 VDSL2 Veeam VeloCloud +Vserver VM VMware VPN vSAN ---warning-backend-congestions ---warning-backend-outstanding-io ---warning-bytesallocatedpercentage ---warning-na +vSphere +WLAN +WLC WSMAN -XPath +XPath \ No newline at end of file diff --git a/tests/storage/netapp/ontap/restapi/cluster.robot b/tests/storage/netapp/ontap/restapi/cluster.robot index e052f5bbc7..f1a51a038d 100644 --- a/tests/storage/netapp/ontap/restapi/cluster.robot +++ b/tests/storage/netapp/ontap/restapi/cluster.robot @@ -31,6 +31,7 @@ Cluster ${tc} Ctn Run Command And Check Result As Strings ${command} ${expected_result} Examples: tc extra_options expected_result -- - ... 1 ${EMPTY} OK: cluster 'cluster1' other : skipped (no value(s)), read iops: 200, write iops: 100, other-iops : skipped (no value(s)), total iops: 1000, read latency: 200 ms, write latency: 100 ms, other-latency : skipped (no value(s)), total latency: 1000 ms - node 'node-01' state: online [link status: string] | 'cluster1#cluster.io.read.usage.bytespersecond'=0B/s;;;; 'cluster1#cluster.io.write.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.total.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.read.usage.iops'=200iops;;;0; 'cluster1#cluster.io.write.usage.iops'=100iops;;;0; 'cluster1#cluster.io.total.usage.iops'=1000iops;;;0; 'cluster.io.read.latency.milliseconds'=200ms;;;0; 'cluster1#cluster.io.write.latency.milliseconds'=100ms;;;0; 'cluster1#cluster.io.total.latency.milliseconds'=1000ms;;;0; - ... 2 --warning-node-status='\\\%{state} !~ /notonline/i' WARNING: cluster 'cluster1' node 'node-01' state: online [link status: string] | 'cluster1#cluster.io.read.usage.bytespersecond'=0B/s;;;; 'cluster1#cluster.io.write.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.total.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.read.usage.iops'=200iops;;;0; 'cluster1#cluster.io.write.usage.iops'=100iops;;;0; 'cluster1#cluster.io.total.usage.iops'=1000iops;;;0; 'cluster.io.read.latency.milliseconds'=200ms;;;0; 'cluster1#cluster.io.write.latency.milliseconds'=100ms;;;0; 'cluster1#cluster.io.total.latency.milliseconds'=1000ms;;;0; - ... 3 --critical-node-status='\\\%{state} !~ /notonline/i' CRITICAL: cluster 'cluster1' node 'node-01' state: online [link status: string] | 'cluster1#cluster.io.read.usage.bytespersecond'=0B/s;;;; 'cluster1#cluster.io.write.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.total.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.read.usage.iops'=200iops;;;0; 'cluster1#cluster.io.write.usage.iops'=100iops;;;0; 'cluster1#cluster.io.total.usage.iops'=1000iops;;;0; 'cluster.io.read.latency.milliseconds'=200ms;;;0; 'cluster1#cluster.io.write.latency.milliseconds'=100ms;;;0; 'cluster1#cluster.io.total.latency.milliseconds'=1000ms;;;0; + ... 1 ${EMPTY} OK: cluster 'cluster1' read : Buffer creation, write : Buffer creation, other : skipped (no value(s)), total : Buffer creation, read iops: 200, write iops: 100, other-iops : skipped (no value(s)), total iops: 1000, read latency: 200 ms, write latency: 100 ms, other-latency : skipped (no value(s)), total latency: 1000 ms - node 'node-01' state: online [link status: string] | 'cluster1#cluster.io.read.usage.iops'=200iops;;;0; 'cluster1#cluster.io.write.usage.iops'=100iops;;;0; 'cluster1#cluster.io.total.usage.iops'=1000iops;;;0; 'cluster.io.read.latency.milliseconds'=200ms;;;0; 'cluster1#cluster.io.write.latency.milliseconds'=100ms;;;0; 'cluster1#cluster.io.total.latency.milliseconds'=1000ms;;;0; + ... 2 ${EMPTY} OK: cluster 'cluster1' other : skipped (no value(s)), read iops: 200, write iops: 100, other-iops : skipped (no value(s)), total iops: 1000, read latency: 200 ms, write latency: 100 ms, other-latency : skipped (no value(s)), total latency: 1000 ms - node 'node-01' state: online [link status: string] | 'cluster1#cluster.io.read.usage.bytespersecond'=0B/s;;;; 'cluster1#cluster.io.write.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.total.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.read.usage.iops'=200iops;;;0; 'cluster1#cluster.io.write.usage.iops'=100iops;;;0; 'cluster1#cluster.io.total.usage.iops'=1000iops;;;0; 'cluster.io.read.latency.milliseconds'=200ms;;;0; 'cluster1#cluster.io.write.latency.milliseconds'=100ms;;;0; 'cluster1#cluster.io.total.latency.milliseconds'=1000ms;;;0; + ... 3 --warning-node-status='\\\%{state} !~ /notonline/i' WARNING: cluster 'cluster1' node 'node-01' state: online [link status: string] | 'cluster1#cluster.io.read.usage.bytespersecond'=0B/s;;;; 'cluster1#cluster.io.write.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.total.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.read.usage.iops'=200iops;;;0; 'cluster1#cluster.io.write.usage.iops'=100iops;;;0; 'cluster1#cluster.io.total.usage.iops'=1000iops;;;0; 'cluster.io.read.latency.milliseconds'=200ms;;;0; 'cluster1#cluster.io.write.latency.milliseconds'=100ms;;;0; 'cluster1#cluster.io.total.latency.milliseconds'=1000ms;;;0; + ... 4 --critical-node-status='\\\%{state} !~ /notonline/i' CRITICAL: cluster 'cluster1' node 'node-01' state: online [link status: string] | 'cluster1#cluster.io.read.usage.bytespersecond'=0B/s;;;; 'cluster1#cluster.io.write.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.total.usage.bytespersecond'=0B/s;;;0; 'cluster1#cluster.io.read.usage.iops'=200iops;;;0; 'cluster1#cluster.io.write.usage.iops'=100iops;;;0; 'cluster1#cluster.io.total.usage.iops'=1000iops;;;0; 'cluster.io.read.latency.milliseconds'=200ms;;;0; 'cluster1#cluster.io.write.latency.milliseconds'=100ms;;;0; 'cluster1#cluster.io.total.latency.milliseconds'=1000ms;;;0; diff --git a/tests/storage/netapp/ontap/restapi/hardware.robot b/tests/storage/netapp/ontap/restapi/hardware.robot index 1637795640..daade8f7ef 100644 --- a/tests/storage/netapp/ontap/restapi/hardware.robot +++ b/tests/storage/netapp/ontap/restapi/hardware.robot @@ -1,5 +1,5 @@ *** Settings *** -Documentation Netapp Ontap Restapi Quotas plugin +Documentation Netapp Ontap Restapi Hardware plugin Resource ${CURDIR}${/}..${/}..${/}..${/}..${/}resources/import.resource @@ -18,12 +18,12 @@ ${cmd} ${CENTREON_PLUGINS} ... --proto=http ... --api-username=username ... --api-password=password -... --mode=quotas +... --mode=hardware *** Test Cases *** -Quotas ${tc} - [Tags] storage netapp ontapp api quotas mockoon +Hardware ${tc} + [Tags] storage netapp ontapp api hardware mockoon ${command} Catenate ... ${CMD} ... ${extra_options} From bb8232ea0042597c315628acab04cc2d25b4c66f Mon Sep 17 00:00:00 2001 From: itoussies Date: Thu, 26 Dec 2024 17:09:21 +0100 Subject: [PATCH 9/9] Add logical space usage metrics & other enhancements --- src/storage/netapp/ontap/restapi/mode/volumes.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storage/netapp/ontap/restapi/mode/volumes.pm b/src/storage/netapp/ontap/restapi/mode/volumes.pm index 791ebb03ab..ef4fc882c4 100644 --- a/src/storage/netapp/ontap/restapi/mode/volumes.pm +++ b/src/storage/netapp/ontap/restapi/mode/volumes.pm @@ -337,7 +337,7 @@ Example: C<--filter-counters='^usage$'>. =item B<--filter-volume-name> -Filter the API request by volumes name (* can be used, volumes name are separated by |). Required if you wan to retrive +Filter the API request by volumes name (* can be used, volumes name are separated by |). Required if you wan to retrieve logical space metrics. =item B<--filter-name> @@ -346,7 +346,7 @@ Filter the API request result by volume name (can be a regexp). =item B<--filter-vserver-name> -Filter volumes by vserver name (can be a regexp). +Filter volumes by Vserver name (can be a regexp). =item B<--unknown-status>