From 397e2f5b642d460e4177c680cdd135b85d7c59d2 Mon Sep 17 00:00:00 2001 From: Brian Gates Date: Sun, 3 May 2026 15:28:50 -0400 Subject: [PATCH 1/3] Refactor pod capacity retrieval and space calculations --- PureStoragePlugin.pm | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/PureStoragePlugin.pm b/PureStoragePlugin.pm index 65a13b1..5699df4 100644 --- a/PureStoragePlugin.pm +++ b/PureStoragePlugin.pm @@ -1700,33 +1700,40 @@ sub status { my $total; my $used; - # If using pod with quota, get pod-specific capacity + # Pod-backed stores: GET pods (not pods/space) — pods/space omits quota_limit and any + # capacity ceiling, which produced invalid total/free for REST consumers on current FA APIs. if ( defined $scfg->{ podname } && $scfg->{ podname } ne '' ) { my $podname = $scfg->{ podname }; - $logger->( P_VERB, "Getting pod quota for pod: $podname", $scfg ); + $logger->( P_VERB, "Getting pod capacity for pod: $podname", $scfg ); my $action = { - name => 'get pod space', - type => 'pods/space', + name => 'get pod', + type => 'pods', method => 'GET', params => { names => $podname } }; my $response = purestorage_api_call( $scfg, $action, 0, $storeid ); my $pod = $response->{ items }->[0]; - if ( $pod ) { + $fatal->( "Pod \"$podname\" not found", $scfg ) unless $pod; - # Use quota_limit if set and non-zero, otherwise fall back to array capacity - # quota_limit = 0 or undef means unlimited (no quota) - my $quota = $pod->{ quota_limit }; - $total = ( defined( $quota ) && $quota > 0 ) ? $quota : $pod->{ capacity }; - $used = $pod->{ space }->{ total_physical }; + my $space = $pod->{ space } // {}; + my $quota = $pod->{ quota_limit }; - my $quota_str = defined( $quota ) ? ( $quota > 0 ? $quota : 'unlimited' ) : 'not set'; - $logger->( P_VERB, "Pod quota_limit: $quota_str", $scfg ); + if ( defined( $quota ) && $quota > 0 ) { + $total = $quota; + # Pod quotas are logical (provisioned) limits on Purity 6.4+. + $used = $space->{ used_provisioned } // $space->{ total_used } // $space->{ total_physical } // 0; } else { - $fatal->( "Pod \"$podname\" not found", $scfg ); + my $arr_response = purestorage_api_call( $scfg, { name => 'get array space', type => 'arrays/space', method => 'GET' }, 0, $storeid ); + my $array = $arr_response->{ items }->[0]; + $fatal->( 'PureStorage API :: No array space data', $scfg ) unless $array; + $total = $array->{ capacity } // 0; + $used = $space->{ total_physical } // 0; } + + my $quota_str = defined( $quota ) ? ( $quota > 0 ? $quota : 'unlimited' ) : 'not set'; + $logger->( P_VERB, "Pod quota_limit: $quota_str", $scfg ); } else { # Get array-wide capacity @@ -1740,8 +1747,13 @@ sub status { $used = $array->{ space }->{ total_physical }; } - # Calculate free space + $total //= 0; + $used //= 0; + $used = $total if $used > $total; + + # Calculate free space (clamp so REST/UI integrations never see negative free) my $free = $total - $used; + $free = 0 if $free < 0; # Mark storage as active my $active = 1; From ed358b13c589ca3263cad5c43c758bc2fb539f49 Mon Sep 17 00:00:00 2001 From: Brian Gates Date: Sun, 3 May 2026 16:27:05 -0400 Subject: [PATCH 2/3] Fix purestorage pod status totals, usage scope, and space metrics --- PureStoragePlugin.pm | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/PureStoragePlugin.pm b/PureStoragePlugin.pm index 5699df4..c6e0338 100644 --- a/PureStoragePlugin.pm +++ b/PureStoragePlugin.pm @@ -1723,13 +1723,19 @@ sub status { if ( defined( $quota ) && $quota > 0 ) { $total = $quota; # Pod quotas are logical (provisioned) limits on Purity 6.4+. + # Prefer total_used over deprecated total_physical on pod space (FA REST 2.x). $used = $space->{ used_provisioned } // $space->{ total_used } // $space->{ total_physical } // 0; } else { my $arr_response = purestorage_api_call( $scfg, { name => 'get array space', type => 'arrays/space', method => 'GET' }, 0, $storeid ); my $array = $arr_response->{ items }->[0]; $fatal->( 'PureStorage API :: No array space data', $scfg ) unless $array; + unless ( defined $array->{ capacity } ) { + $logger->( P_WARN, 'arrays/space response missing capacity; reporting total as 0', $scfg ); + } $total = $array->{ capacity } // 0; - $used = $space->{ total_physical } // 0; + # Same scope as non-pod status: capacity and usage both from arrays/space (array-wide). + my $arr_space = $array->{ space } // {}; + $used = $arr_space->{ total_used } // $arr_space->{ total_physical } // 0; } my $quota_str = defined( $quota ) ? ( $quota > 0 ? $quota : 'unlimited' ) : 'not set'; @@ -1740,11 +1746,14 @@ sub status { my $response = purestorage_api_call( $scfg, { name => 'get array space', type => 'arrays/space', method => 'GET' }, 0, $storeid ); my $array = $response->{ items }->[0]; - $total = $array->{ capacity }; + unless ( defined $array->{ capacity } ) { + $logger->( P_WARN, 'arrays/space response missing capacity; reporting total as 0', $scfg ); + } + $total = $array->{ capacity } // 0; - # total_physical - physically used space on the array (after deduplication and compression) - # total_used - logically used space (before deduplication and compression) - $used = $array->{ space }->{ total_physical }; + # Prefer total_used (FA REST 2.x); total_physical deprecated for same metric on newer arrays. + my $arr_space = $array->{ space } // {}; + $used = $arr_space->{ total_used } // $arr_space->{ total_physical } // 0; } $total //= 0; From f7d06166fccb209b472e53bb449e0713c5cc7cf3 Mon Sep 17 00:00:00 2001 From: Brian Gates Date: Sun, 3 May 2026 16:48:34 -0400 Subject: [PATCH 3/3] Run Perltidy and fix linting issues --- PureStoragePlugin.pm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/PureStoragePlugin.pm b/PureStoragePlugin.pm index c6e0338..b173434 100644 --- a/PureStoragePlugin.pm +++ b/PureStoragePlugin.pm @@ -1722,17 +1722,20 @@ sub status { if ( defined( $quota ) && $quota > 0 ) { $total = $quota; + # Pod quotas are logical (provisioned) limits on Purity 6.4+. # Prefer total_used over deprecated total_physical on pod space (FA REST 2.x). $used = $space->{ used_provisioned } // $space->{ total_used } // $space->{ total_physical } // 0; } else { my $arr_response = purestorage_api_call( $scfg, { name => 'get array space', type => 'arrays/space', method => 'GET' }, 0, $storeid ); - my $array = $arr_response->{ items }->[0]; + my $array = $arr_response->{ items }->[0]; $fatal->( 'PureStorage API :: No array space data', $scfg ) unless $array; unless ( defined $array->{ capacity } ) { $logger->( P_WARN, 'arrays/space response missing capacity; reporting total as 0', $scfg ); } + $total = $array->{ capacity } // 0; + # Same scope as non-pod status: capacity and usage both from arrays/space (array-wide). my $arr_space = $array->{ space } // {}; $used = $arr_space->{ total_used } // $arr_space->{ total_physical } // 0; @@ -1749,6 +1752,7 @@ sub status { unless ( defined $array->{ capacity } ) { $logger->( P_WARN, 'arrays/space response missing capacity; reporting total as 0', $scfg ); } + $total = $array->{ capacity } // 0; # Prefer total_used (FA REST 2.x); total_physical deprecated for same metric on newer arrays.