Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion Private/Invoke-PfbApiRequest.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,15 @@ function Invoke-PfbApiRequest {
# HTTP timeout handling — default to 30s if the connection object predates this field
$restParams['TimeoutSec'] = if ($Array.HttpTimeoutMs) { [int][Math]::Ceiling($Array.HttpTimeoutMs / 1000.0) } else { 30 }

# If the caller set a page-size/limit query param (every Get-Pfb* cmdlet's -Limit maps to
# this), treat it as a hard cap on the running total across pages -- Purity//FB REST treats
# `limit` as page size only and keeps returning a continuation_token even once the caller's
# desired item count has been reached, so AutoPaginate must stop itself.
$requestedLimit = $null
if ($QueryParams -and $QueryParams.ContainsKey('limit') -and [int]$QueryParams['limit'] -gt 0) {
$requestedLimit = [int]$QueryParams['limit']
}

$allItems = [System.Collections.Generic.List[object]]::new()
$totalItemCount = $null
$hasMore = $true
Expand Down Expand Up @@ -211,7 +220,8 @@ function Invoke-PfbApiRequest {
}

# Handle pagination
if ($AutoPaginate -and $response.continuation_token) {
$limitReached = ($null -ne $requestedLimit -and $allItems.Count -ge $requestedLimit)
if ($AutoPaginate -and $response.continuation_token -and -not $limitReached) {
# Update the URI with continuation token
if (-not $QueryParams) { $QueryParams = @{} }
$QueryParams['continuation_token'] = $response.continuation_token
Expand All @@ -224,6 +234,12 @@ function Invoke-PfbApiRequest {
}
}

# The last page fetched may have overshot the requested limit (server-side page size is
# independent of it) -- trim so callers get exactly what they asked for.
if ($null -ne $requestedLimit -and $allItems.Count -gt $requestedLimit) {
$allItems = $allItems.GetRange(0, $requestedLimit)
}

# If TotalOnly was requested and we got a count but no items, return the count
if ($allItems.Count -eq 0 -and $null -ne $totalItemCount) {
return [PSCustomObject]@{ total_item_count = $totalItemCount }
Expand Down
67 changes: 67 additions & 0 deletions Tests/Invoke-PfbApiRequest.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,70 @@ Describe 'Invoke-PfbApiRequest - HttpTimeoutMs is applied' {
}
}
}

Describe 'Invoke-PfbApiRequest - AutoPaginate honors -Limit' {
It 'stops paginating and trims results once the running total reaches the requested limit' {
$script:pageCallCount = 0
Mock -ModuleName PureStorageFlashBladePowerShell Invoke-RestMethod {
$script:pageCallCount++
switch ($script:pageCallCount) {
1 {
[PSCustomObject]@{
items = @(1..6 | ForEach-Object { [PSCustomObject]@{ name = "fs$_" } })
continuation_token = 'token-page-2'
}
}
2 {
[PSCustomObject]@{
items = @(7..12 | ForEach-Object { [PSCustomObject]@{ name = "fs$_" } })
continuation_token = 'token-page-3'
}
}
default {
throw "Unexpected extra page request (call #$script:pageCallCount) -- the -Limit guard should have stopped pagination after call #2"
}
}
} -ParameterFilter { $Uri -like '*file-systems*' }

$script:result = InModuleScope PureStorageFlashBladePowerShell {
$array = [PSCustomObject]@{
Endpoint = 'fb.test'; ApiVersion = '2.26'; AuthToken = 'tok'
ApiToken = $null; AuthMethod = 'ApiToken'; SkipCertificateCheck = $false
}
Invoke-PfbApiRequest -Array $array -Method GET -Endpoint 'file-systems' -QueryParams @{ limit = 10 } -AutoPaginate
}

$script:result.Count | Should -Be 10
$script:pageCallCount | Should -Be 2
Should -Invoke -ModuleName PureStorageFlashBladePowerShell Invoke-RestMethod -Times 2 -Exactly -ParameterFilter { $Uri -like '*file-systems*' }
}

It 'still auto-paginates the full collection when no -Limit is given' {
$script:pageCallCount2 = 0
Mock -ModuleName PureStorageFlashBladePowerShell Invoke-RestMethod {
$script:pageCallCount2++
if ($script:pageCallCount2 -eq 1) {
[PSCustomObject]@{
items = @(1..6 | ForEach-Object { [PSCustomObject]@{ name = "fs$_" } })
continuation_token = 'token-page-2'
}
}
else {
[PSCustomObject]@{
items = @(7..9 | ForEach-Object { [PSCustomObject]@{ name = "fs$_" } })
}
}
} -ParameterFilter { $Uri -like '*file-systems*' }

$script:result2 = InModuleScope PureStorageFlashBladePowerShell {
$array = [PSCustomObject]@{
Endpoint = 'fb.test'; ApiVersion = '2.26'; AuthToken = 'tok'
ApiToken = $null; AuthMethod = 'ApiToken'; SkipCertificateCheck = $false
}
Invoke-PfbApiRequest -Array $array -Method GET -Endpoint 'file-systems' -QueryParams @{} -AutoPaginate
}

$script:result2.Count | Should -Be 9
$script:pageCallCount2 | Should -Be 2
}
}