Centralize -Filter/-Sort/-Limit/-TotalOnly query params (#32) - #49
Merged
dmann000 merged 8 commits intoJul 24, 2026
Conversation
) Adds Private/Add-PfbCommonQueryParams.ps1 with the shared helper that centralizes -Filter/-Sort/-Limit/-TotalOnly/-Names/-Ids parameter handling across all 30 Get-Pfb* cmdlets. Includes comprehensive Pester tests covering all scalar parameters individually, ContainsKey semantics (including -Limit 0 edge case), Names/Ids array joining, and in-place hashtable mutation. All 24 tests pass.
Replace the hand-rolled filter/sort/limit/total_only/names/ids mapping in Get-PfbBucket, Get-PfbBucketPerformance, and Get-PfbBucketS3Performance with the shared Add-PfbCommonQueryParams helper introduced in Task 1. Cmdlet-specific query params (-Destroyed, -StartTime/-EndTime/-Resolution) are left untouched.
Replace the hand-rolled filter/sort/limit/total_only/names/ids block in Get-PfbFileLock, Get-PfbFileLockClient, Get-PfbFileSystem, and Get-PfbFileSystemExport with the shared Add-PfbCommonQueryParams helper, matching the pattern already used by the Bucket cmdlets. Part of dmann000#32.
Replace the hand-rolled filter/sort/limit/total_only(/names/ids) block in Get-PfbFileSystemGroupPerformance, Get-PfbFileSystemSession, Get-PfbFileSystemStorageClass, Get-PfbFileSystemUserPerformance, and Get-PfbOpenFile with the shared Add-PfbCommonQueryParams helper. Get-PfbFileSystemGroupPerformance and Get-PfbFileSystemUserPerformance keep their file_system_names/file_system_ids query keys as cmdlet-specific lines (not routed through -Names/-Ids) since that differs from the generic names/ids convention the helper hardcodes. Part of dmann000#32.
…yParams (dmann000#32) Replaces the hand-rolled filter/sort/limit/total_only/names/ids query-param blocks in Get-PfbFileSystemSnapshot, Get-PfbFileSystemSnapshotTransfer, and Get-PfbFileSystemReplicaLinkTransfer with calls to the shared helper. All three use the generic names/ids wire keys, so no cmdlet-specific naming divergence applies here.
…n000#32) Replaces the hand-rolled filter/sort/limit/total_only query-param blocks in Get-PfbObjectStoreAccessPolicy(Action|Role|Rule|User) with calls to the shared Add-PfbCommonQueryParams helper. Get-PfbObjectStoreAccessPolicyRole and -User use non-generic policy_names/policy_ids/member_names/member_ids wire keys, so the helper is called without -Names/-Ids there; Rule mixes a generic 'names' key (from -Name) with non-generic policy_names/policy_ids (from -PolicyName/-PolicyId), so only -Names is passed through. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…n000#32) Get-PfbObjectStoreAccount, Get-PfbObjectStoreAccountExport, Get-PfbObjectStoreRemoteCredential, and Get-PfbObjectStoreRole use generic names/ids wire keys, so their end{} blocks now route -Names/-Ids through the shared helper. Get-PfbObjectStoreRoleAccessPolicy maps its Role/Member name and id params to non-generic role_names/role_ids/member_names/member_ids wire keys, so the helper is called without -Names/-Ids and those four lines are left as the cmdlet's own untouched query-param assignments.
…QueryParams (dmann000#32) Final migration batch: Get-PfbObjectStoreTrustPolicy, Get-PfbObjectStoreTrustPolicyRule, Get-PfbObjectStoreUserAccessPolicy, Get-PfbRealm, and Get-PfbServer now route their Filter/Sort/Limit/TotalOnly (and generic Names/Ids where applicable) query-param assembly through the shared helper, matching the prior 25-cmdlet migration. Completeness sweep confirms all 30 originally-identified Get-Pfb* cmdlets now call Add-PfbCommonQueryParams, with no hand-rolled total_only assignments remaining outside Private/Add-PfbCommonQueryParams.ps1.
This was referenced Jul 23, 2026
This was referenced Jul 25, 2026
juemerson-at-purestorage
added a commit
that referenced
this pull request
Jul 25, 2026
…and parser gaps (#53) * fix(tools): teach the parameter inventory two wire-name idioms it could not see tools/lib/PfbCmdletParamTools.ps1 resolved a parameter's REST wire name only from a literal `$body['k'] = $Param` / `$queryParams['k'] = $Param` index assignment in the cmdlet's own body. Two very common idioms were therefore invisible, and every parameter they cover was classified AttributesOnly/TypedUnresolved. Downstream, Get-PfbParameterCoverageGaps requires EVERY parameter on EVERY cmdlet calling an endpoint to be Surface='Typed', so one unresolved parameter pushed the whole endpoint into the notVerified bucket and out of gap analysis entirely. 1. The shared Private/Add-PfbCommonQueryParams.ps1 helper (issue #32/PR #49, extended to ~196 cmdlets by issue #33/PR #51) assigns -Filter/-Sort/-Limit/ -TotalOnly/-Names/-Ids on the caller's behalf, so migrated cmdlets contain no literal key at all. This made a pure mechanical refactor look like a 39% improvement: on PR #51's tree the headline missing-field count FELL 932 -> 571 while notVerified endpoints ROSE 194 -> 349. Added Get-PfbCommonQueryParamMap (a documented hardcoded mirror of the helper) plus Get-PfbCommonQueryParamHelperWireName. -Filter/-Sort/-Limit/-TotalOnly are matched by PARAMETER NAME (the helper reads them from the caller's $PSBoundParameters, and the call must actually forward it); -Names/-Ids by the variable passed to that argument, which the existing accumulator retry already traces from the parameter. Runs LAST so the non-generic keys those cmdlets deliberately kept as explicit lines (policy_names, file_system_names, ...) still win. 2. The hashtable-literal initializer `$queryParams = @{ 'names' = $Name }` -- the dominant shape across New-Pfb*/Remove-Pfb*/Update-Pfb* -- was only ever matched in its IndexExpressionAst form. Added Get-PfbHashtableLiteralWireNameForParameter, top-level pairs only: in `$body = @{ group = @{ name = $GroupName } }` the wire field is `group`, so crediting the inner `name` would mis-name the field and collide with every other sub-object's `name`. Also extracted the RHS shape test (Test-PfbWireValueIsParameter) and the parser's StatementAst unwrapping (Resolve-PfbSingleExpression) so both paths share one deliberately shape-exact matcher rather than duplicating it -- a pipeline transform is still refused rather than guessed at. Measured, generating the report from each tools/lib against each cmdlet tree (reporting only; no Public/, Private/, Data/ or Reports/ change): | gaps | notVerified | missing fields | uncovered baseline main | 254 | 194 | 932 | 117 baseline PR #51 | 132 | 349 | 571 | 117 fix 1 only main | 282 | 164 | 1019 | 117 fix 1 only PR #51 | 286 | 157 | 1029 | 117 both fixes main | 343 | 101 | 1370 | 117 both fixes PR #51 | 347 | 94 | 1380 | 117 The 155-endpoint main-vs-PR#51 spread closes to 7, zero endpoints newly become notVerified in any transition, and no already-resolved wire name changes. The residual 7 are cmdlets PR #51 gave query parameters to that had none on main (Get-PfbDns, Get-PfbAdminSetting, ...), which sidesteps a separate pre-existing bug in tools/lib/PfbApiDriftTools.ps1: `@($inventoryByCmdlet[$cmdletName])` yields @($null) for a cmdlet with zero inventory rows, wrongly marking its endpoint notVerified. That accounts for 37 of the remaining 101 and is left for its own change. Tests: 24 new cases in Tests/PfbCmdletParamTools.Tests.ps1 over synthetic Public/-shaped fixtures, including a mapping-table-vs-helper sync test that derives the contract from Private/Add-PfbCommonQueryParams.ps1's own AST so the hardcoded mirror cannot silently drift (mutation-verified: it fails when the helper gains a key). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(tools): stop discarding parameterless cmdlets and nested reference objects Two more instances of the same failure mode PR #53 opened for -- the drift report going quieter, which reads as better -- found while scoping the "make the drift report actionable" work. 1. Null-vs-empty conflation in Get-PfbParameterCoverageGaps. The per-cmdlet inventory lookup is a Group-Object -AsHashTable, which returns $null for an absent key, and @($null) is a ONE-element array whose element is $null. The surface loop therefore ran once with $row = $null, read $null.Surface -ne 'Typed' as true, and discarded the endpoint into notVerified. A cmdlet contributes zero inventory rows when every parameter it declares is -Array/-Attributes (both inventory-exempt) -- the exact shape of the -Attributes-only write cmdlets -- and nothing contradicting full mapping means vacuously fully mapped, not unmappable. 36 endpoints leave notVerified, including PATCH /arrays, PATCH /password-policies and PATCH /support with 18/19/12 previously invisible missing fields. 2. Nested single-key reference objects, `$body['account'] = @{ name = $Account }`, are now credited to their OUTER key. The capability map records top-level body properties only, so `account.name` is not a field it can track and `account` is the field such a parameter actually covers. Two parameters resolving to the same outer key (by name, by id) is correct, not a collision to suppress. Resolves 13 (cmdlet, parameter) pairs across 9 cmdlets, and via the notVerified gate 6 more endpoints. New resolver runs strictly after both direct-assignment passes, so it can only turn an unresolved parameter Typed, never rename an already-resolved wire name (measured: 0 wire-name changes, 0 Typed -> non-Typed regressions). Combined, notVerified 101 -> 59 with 0 newly-notVerified, reported missing fields 1370 -> 1538 with 0 fields removed, and the residual 7-endpoint notVerified spread against PR #51's tip closes to 0. Measured, not asserted; report regenerated to scratch paths only -- committed Data/ and Reports/ artifacts unchanged. Live-array testing not applicable: tools/ and Tests/ only, no runtime surface, no Public//Private/ change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #32. 30
Get-Pfb*cmdlets each hand-rolled an identical block mapping-Filter/-Sort/-Limit/-TotalOnly(and, where applicable, accumulated-Name/-Idpipeline input) onto the$queryParamshashtable passed toInvoke-PfbApiRequest. This adds one shared private helper and migrates all30 cmdlets onto it — pure internal refactor, no public parameter/behavior
change intended beyond one deliberate fix noted below.
New helper:
Private/Add-PfbCommonQueryParams.ps1, with 24 Pester testscovering each scalar independently,
-Names/-Idsjoining, and in-placehashtable mutation.
Migrated (30 cmdlets, in 7 batches): Bucket (3) · FileSystem (9) ·
FileSystemSnapshot/Replication (3) · ObjectStore (15) · Realm · Server.
Intentional behavior change: the helper checks
.ContainsKey()on thefour scalars instead of truthiness, so an explicit
-Limit 0is now sent tothe API where the old per-cmdlet
if ($Limit -gt 0)guard silently droppedit. (An empty-string
-Filter ''is unaffected in practice —ConvertTo-PfbQueryStringalready strips null/empty values before they reach the wire.)
Wire-key handling: several cmdlets map their Name/Id-equivalent params to
non-generic wire keys (
file_system_names/ids,policy_names/ids,role_names/ids,member_names/ids) instead of the helper's genericnames/ids. Those are left as the cmdlet's own untouched lines rather thanbeing routed through the helper, so the actual wire format sent to the array
is unchanged. One cmdlet (
Get-PfbObjectStoreAccessPolicyRule) mixes both —handled by passing only the generic-keyed param through the helper.
Out of scope (follow-up candidate): ~55 other
Get-Pfb*cmdlets withouta
-TotalOnlyparam still hand-rollfilter/sort/limitand weren'ttouched here, per the issue's own scoping.
Test plan
Add-PfbCommonQueryParams(24/24 passing)Get-PfbFileSystemSession.Tests.ps1,ObjectStoreAccessPolicyAssociations.Tests.ps1confirmed correct query strings for
-Limit/-Sort/-Filter/-TotalOnlyand every non-generic/mixed wire-key case
call the helper, zero leftover hand-rolled
total_onlyassignmentsNotes
Live-testing incidentally reproduced the
-Limit/AutoPaginatepaginationbug already tracked and fixed by #30 (PR #48, still open) — no file overlap
with that PR, confirmed no conflict either way this merges.