Skip to content

Commit 576eb12

Browse files
Merge pull request #140 from juemerson-at-purestorage/fix/issue-106-part-2
Give New-PfbApiClient a typed body and require legal-hold `released`
2 parents 7304acb + 750e46c commit 576eb12

13 files changed

Lines changed: 306 additions & 139 deletions

‎Public/Admin/New-PfbApiClient.ps1‎

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,74 @@ function New-PfbApiClient {
44
Creates a new API client on the FlashBlade.
55
.DESCRIPTION
66
The New-PfbApiClient cmdlet creates a new API client on the connected Pure Storage
7-
FlashBlade. API clients are used for OAuth2 authentication and require at minimum
8-
a public key and a maximum role assignment.
7+
FlashBlade. API clients require a public key. On REST 2.0-2.18, they also require
8+
a maximum role assignment; from REST 2.19 onward, max_role is deprecated in favour
9+
of access_policies.
10+
11+
The typed parameters and the raw -Attributes hashtable are mutually exclusive: they
12+
live in separate parameter sets, so PowerShell rejects a mixed invocation at bind time
13+
rather than letting -Attributes silently override an explicitly supplied value.
914
.PARAMETER Name
1015
The name of the API client to create.
16+
.PARAMETER PublicKey
17+
The public key for the API client. Required by the API client's POST body schema.
18+
.PARAMETER MaxRole
19+
The maximum role assignment for the API client. The API requires this on REST 2.0-2.18;
20+
it is deprecated in favour of access_policies from REST 2.19 onward.
1121
.PARAMETER Attributes
12-
A hashtable defining the API client properties, including the public key and role.
22+
A raw hashtable defining the API client properties. This parameter is mutually exclusive
23+
with the typed parameters. When using -Attributes, the caller is responsible for supplying
24+
the required public_key (and max_role on REST 2.0-2.18).
1325
.PARAMETER Array
1426
The FlashBlade connection object. If not specified, the default connection is used.
1527
.EXAMPLE
16-
New-PfbApiClient -Name 'automation-client' -Attributes @{ max_role = @{ name = 'storage_admin' }; public_key = $key }
28+
New-PfbApiClient -Name 'automation-client' -PublicKey $key -MaxRole 'storage_admin'
1729
1830
Creates a new API client with the storage_admin role and the specified public key.
1931
.EXAMPLE
20-
New-PfbApiClient -Name 'readonly-client' -Attributes @{ max_role = @{ name = 'readonly' }; public_key = $key }
32+
New-PfbApiClient -Name 'readonly-client' -PublicKey $key
2133
22-
Creates a new read-only API client.
34+
Creates a new API client with the specified public key. On REST 2.0-2.18, supply
35+
-MaxRole as well; from REST 2.19 onward, max_role is deprecated in favour of access_policies.
2336
.EXAMPLE
2437
New-PfbApiClient -Name 'ops-client' -Attributes @{ max_role = @{ name = 'ops_admin' }; public_key = $key } -Confirm:$false
2538
26-
Creates a new API client without prompting for confirmation.
39+
Creates a new API client from a hand-rolled body without prompting for confirmation.
40+
When using -Attributes, the caller is responsible for supplying the required public_key.
2741
#>
28-
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
42+
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium',
43+
DefaultParameterSetName = 'Typed')]
2944
param(
30-
[Parameter(Mandatory, Position = 0)]
45+
[Parameter(ParameterSetName = 'Typed', Mandatory, Position = 0)]
46+
[Parameter(ParameterSetName = 'Attributes', Mandatory, Position = 0)]
3147
[string]$Name,
3248

33-
[Parameter()]
49+
[Parameter(ParameterSetName = 'Typed', Mandatory)]
50+
[string]$PublicKey,
51+
52+
[Parameter(ParameterSetName = 'Typed')]
53+
[string]$MaxRole,
54+
55+
[Parameter(ParameterSetName = 'Attributes', Mandatory)]
3456
[hashtable]$Attributes,
3557

3658
[Parameter()] [PSCustomObject]$Array
3759
)
3860

3961
Assert-PfbConnection -Array ([ref]$Array)
4062

41-
$body = if ($Attributes) { $Attributes } else { @{} }
63+
if ($PSCmdlet.ParameterSetName -eq 'Attributes') {
64+
$body = $Attributes.Clone()
65+
}
66+
else {
67+
$body = @{ public_key = $PublicKey }
68+
# max_role is a scalar reference ({id, name, resource_type}); resource_type
69+
# is readOnly and must never be sent.
70+
if ($PSBoundParameters.ContainsKey('MaxRole')) {
71+
$body['max_role'] = @{ name = $MaxRole }
72+
}
73+
}
74+
4275
$queryParams = @{ 'names' = $Name }
4376

4477
if ($PSCmdlet.ShouldProcess($Name, 'Create API client')) {

‎Public/Misc/Update-PfbLegalHoldEntity.ps1‎

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,22 @@ function Update-PfbLegalHoldEntity {
33
.SYNOPSIS
44
Updates a held entity under a legal hold on the FlashBlade.
55
.DESCRIPTION
6-
The Update-PfbLegalHoldEntity cmdlet modifies the properties of an entity that is
7-
subject to a legal hold on the connected Pure Storage FlashBlade. Identify the
8-
held entity by name and supply the changed properties via Attributes.
6+
The Update-PfbLegalHoldEntity cmdlet applies or releases a legal hold over a
7+
file-system path on the connected Pure Storage FlashBlade. `released` is required
8+
by the API, so -Released must always be supplied: `$true` releases the hold,
9+
`$false` applies it.
10+
11+
A held entity has no name of its own -- `LegalHoldHeldEntity` carries only
12+
`file_system`, `legal_hold`, `path` and `status` -- so it is addressed by the
13+
file system plus the path, together with -Recursive. Measured on a live array
14+
(Purity//FB 4.8.2, REST 2.26): a request naming only the hold is rejected with
15+
"Either names or ids query parameter is required", and one naming the file system
16+
and path but omitting -Recursive is rejected with "Can't apply or release legal
17+
holds to directories without the recursive flag provided". Both directions behave
18+
identically here, so a release is symmetric with an apply rather than special.
919
.PARAMETER Name
10-
The name of the held entity to update.
20+
The name of the legal hold. Sent as `names`, which the endpoint declares but which
21+
does not on its own identify a held entity -- see the description above.
1122
.PARAMETER FileSystemIds
1223
The IDs of the file systems whose held entities to update.
1324
.PARAMETER FileSystemNames
@@ -20,25 +31,30 @@ function Update-PfbLegalHoldEntity {
2031
If set to `true`, the update is applied recursively to the specified path or file
2132
system.
2233
.PARAMETER Released
23-
If set to `true`, the held entity is released from its legal hold.
34+
Required by the API on REST 2.17 and later. `$true` releases the held entity from its
35+
legal hold; `$false` applies or keeps the legal hold.
2436
.PARAMETER Attributes
2537
A hashtable of attributes to update on the held entity. `PATCH
2638
/legal-holds/held-entities` accepts no request body, so nothing supplied here is sent
2739
to the array. Use the typed query parameters above instead.
2840
.PARAMETER Array
2941
The FlashBlade connection object. If not specified, the default connection is used.
3042
.EXAMPLE
31-
Update-PfbLegalHoldEntity -Name "fs1" -Released $true
43+
Update-PfbLegalHoldEntity -Name 'pslivetest-hold-1' -FileSystemNames 'pslivetest-fs-1' -Paths '/' -Recursive $true -Released $true
3244
33-
Releases the held entity named "fs1" from its legal hold.
45+
Releases the held entity named "pslivetest-hold-1" from its legal hold. The file-system
46+
name, path, and recursive flag are all required together for this release request.
3447
.EXAMPLE
35-
Update-PfbLegalHoldEntity -Name "bucket1" -Recursive $false
48+
Update-PfbLegalHoldEntity -Name 'pslivetest-hold-1' -FileSystemNames 'pslivetest-fs-1' -Paths '/' -Recursive $true -Released $false
3649
37-
Updates the held entity named "bucket1" without applying the change recursively.
50+
Applies the legal hold to the same path. This is the release example with -Released
51+
flipped -- the two directions take the same arguments.
3852
.EXAMPLE
39-
Update-PfbLegalHoldEntity -Name "fs1" -Attributes @{ hold_type = 'litigation' }
53+
Update-PfbLegalHoldEntity -Name 'pslivetest-hold-1' -FileSystemIds '10314f42-020d-7080-8013-000ddt400090' -Paths '/' -Recursive $true -Released $true
4054
41-
Updates the held entity using a raw attributes hashtable.
55+
Releases the hold identifying the file system by ID instead of by name. Note that
56+
`file_system_ids` refers to the file system, which has an ID; the held entity itself
57+
does not, so -Ids is not a substitute for this form.
4258
#>
4359
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
4460
param(
@@ -60,8 +76,8 @@ function Update-PfbLegalHoldEntity {
6076
[Parameter()]
6177
[Nullable[bool]]$Recursive,
6278

63-
[Parameter()]
64-
[Nullable[bool]]$Released,
79+
[Parameter(Mandatory)]
80+
[bool]$Released,
6581

6682
[Parameter()]
6783
[hashtable]$Attributes,
@@ -88,7 +104,9 @@ function Update-PfbLegalHoldEntity {
88104
if ($PSBoundParameters.ContainsKey('Ids')) { $queryParams['ids'] = $Ids -join ',' }
89105
if ($PSBoundParameters.ContainsKey('Paths')) { $queryParams['paths'] = $Paths -join ',' }
90106
if ($PSBoundParameters.ContainsKey('Recursive')) { $queryParams['recursive'] = $Recursive }
91-
if ($PSBoundParameters.ContainsKey('Released')) { $queryParams['released'] = $Released }
107+
# Unlike optional parameters, released is required by the spec, so no legal request omits it;
108+
# the usual ContainsKey distinction between omitted and supplied as false cannot arise here.
109+
$queryParams['released'] = $Released
92110

93111
if ($PSCmdlet.ShouldProcess($Name, 'Update legal hold entity')) {
94112
Invoke-PfbApiRequest -Array $Array -Method PATCH -Endpoint 'legal-holds/held-entities' -Body $body -QueryParams $queryParams

‎Reports/PfbApiDriftReport.json‎

Lines changed: 41 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -9267,9 +9267,9 @@
92679267
"enumStatus": "no-spec-enum-found",
92689268
"target": {
92699269
"file": "Public/Admin/New-PfbApiClient.ps1",
9270-
"paramBlockLine": 36,
9270+
"paramBlockLine": 58,
92719271
"payloadVariable": "body",
9272-
"assignmentStyle": "unknown",
9272+
"assignmentStyle": "literal",
92739273
"hasAttributes": true
92749274
}
92759275
},
@@ -9284,9 +9284,9 @@
92849284
"enumStatus": "no-spec-enum-found",
92859285
"target": {
92869286
"file": "Public/Admin/New-PfbApiClient.ps1",
9287-
"paramBlockLine": 36,
9287+
"paramBlockLine": 58,
92889288
"payloadVariable": "body",
9289-
"assignmentStyle": "unknown",
9289+
"assignmentStyle": "literal",
92909290
"hasAttributes": true
92919291
}
92929292
},
@@ -9301,43 +9301,9 @@
93019301
"enumStatus": "no-spec-enum-found",
93029302
"target": {
93039303
"file": "Public/Admin/New-PfbApiClient.ps1",
9304-
"paramBlockLine": 36,
9305-
"payloadVariable": "body",
9306-
"assignmentStyle": "unknown",
9307-
"hasAttributes": true
9308-
}
9309-
},
9310-
{
9311-
"name": "max_role",
9312-
"type": null,
9313-
"format": null,
9314-
"specRequired": false,
9315-
"synopsis": "Deprecated.",
9316-
"suggestedPowerShellType": "[object]",
9317-
"enumValues": [],
9318-
"enumStatus": "no-spec-enum-found",
9319-
"target": {
9320-
"file": "Public/Admin/New-PfbApiClient.ps1",
9321-
"paramBlockLine": 36,
9322-
"payloadVariable": "body",
9323-
"assignmentStyle": "unknown",
9324-
"hasAttributes": true
9325-
}
9326-
},
9327-
{
9328-
"name": "public_key",
9329-
"type": "string",
9330-
"format": null,
9331-
"specRequired": true,
9332-
"synopsis": "The API client's PEM formatted (Base64 encoded) RSA public key.",
9333-
"suggestedPowerShellType": "[string]",
9334-
"enumValues": [],
9335-
"enumStatus": "no-spec-enum-found",
9336-
"target": {
9337-
"file": "Public/Admin/New-PfbApiClient.ps1",
9338-
"paramBlockLine": 36,
9304+
"paramBlockLine": 58,
93399305
"payloadVariable": "body",
9340-
"assignmentStyle": "unknown",
9306+
"assignmentStyle": "literal",
93419307
"hasAttributes": true
93429308
}
93439309
}
@@ -15532,17 +15498,6 @@
1553215498
],
1553315499
"annotations": []
1553415500
},
15535-
{
15536-
"name": "max_role",
15537-
"endpointCount": 2,
15538-
"queryEndpointCount": 0,
15539-
"bodyEndpointCount": 2,
15540-
"endpoints": [
15541-
"PATCH /api-clients",
15542-
"POST /api-clients"
15543-
],
15544-
"annotations": []
15545-
},
1554615501
{
1554715502
"name": "member_sids",
1554815503
"endpointCount": 2,
@@ -15686,17 +15641,6 @@
1568615641
],
1568715642
"annotations": []
1568815643
},
15689-
{
15690-
"name": "public_key",
15691-
"endpointCount": 2,
15692-
"queryEndpointCount": 0,
15693-
"bodyEndpointCount": 2,
15694-
"endpoints": [
15695-
"POST /api-clients",
15696-
"POST /public-keys"
15697-
],
15698-
"annotations": []
15699-
},
1570015644
{
1570115645
"name": "qos_configurations",
1570215646
"endpointCount": 2,
@@ -16679,6 +16623,16 @@
1667916623
],
1668016624
"annotations": []
1668116625
},
16626+
{
16627+
"name": "max_role",
16628+
"endpointCount": 1,
16629+
"queryEndpointCount": 0,
16630+
"bodyEndpointCount": 1,
16631+
"endpoints": [
16632+
"PATCH /api-clients"
16633+
],
16634+
"annotations": []
16635+
},
1668216636
{
1668316637
"name": "max_session_duration",
1668416638
"endpointCount": 1,
@@ -16929,6 +16883,16 @@
1692916883
],
1693016884
"annotations": []
1693116885
},
16886+
{
16887+
"name": "public_key",
16888+
"endpointCount": 1,
16889+
"queryEndpointCount": 0,
16890+
"bodyEndpointCount": 1,
16891+
"endpoints": [
16892+
"POST /public-keys"
16893+
],
16894+
"annotations": []
16895+
},
1693216896
{
1693316897
"name": "purity_defined",
1693416898
"endpointCount": 1,
@@ -19246,6 +19210,14 @@
1924619210
"Remove-PfbFileSystemSession"
1924719211
]
1924819212
},
19213+
{
19214+
"name": "public_key",
19215+
"cmdletCount": 2,
19216+
"cmdlets": [
19217+
"New-PfbApiClient",
19218+
"Update-PfbAdmin"
19219+
]
19220+
},
1924919221
{
1925019222
"name": "recursive",
1925119223
"cmdletCount": 2,
@@ -19558,6 +19530,13 @@
1955819530
"Update-PfbAdmin"
1955919531
]
1956019532
},
19533+
{
19534+
"name": "max_role",
19535+
"cmdletCount": 1,
19536+
"cmdlets": [
19537+
"New-PfbApiClient"
19538+
]
19539+
},
1956119540
{
1956219541
"name": "max_session_duration",
1956319542
"cmdletCount": 1,
@@ -19663,13 +19642,6 @@
1966319642
"Get-PfbArrayPerformance"
1966419643
]
1966519644
},
19666-
{
19667-
"name": "public_key",
19668-
"cmdletCount": 1,
19669-
"cmdlets": [
19670-
"Update-PfbAdmin"
19671-
]
19672-
},
1967319645
{
1967419646
"name": "rdma_enabled",
1967519647
"cmdletCount": 1,
@@ -20072,11 +20044,6 @@
2007220044
"cmdletCount": 0,
2007320045
"cmdlets": []
2007420046
},
20075-
{
20076-
"name": "max_role",
20077-
"cmdletCount": 0,
20078-
"cmdlets": []
20079-
},
2008020047
{
2008120048
"name": "member_sids",
2008220049
"cmdletCount": 0,

‎Reports/PfbApiDriftReport.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ This report accepts **false positives in order to eliminate false negatives**. A
2222

2323
- Uncovered endpoints: 95
2424
- Endpoints with parameter gaps: 439
25-
- Missing body properties (addable): 426
25+
- Missing body properties (addable): 424
2626
- Missing query parameters (addable): 880
2727
- Read-only body fields (not addable -- see the Read-only fields section below): 384
2828
- Phantom fields silently excluded (accumulated in the capability map, absent from the newest analysed spec): 40
@@ -414,7 +414,7 @@ Endpoints an existing cmdlet already calls, where the capability map knows of a
414414
| `POST /admins/api-tokens` | New-PfbApiToken | context_names | | `high` | |
415415
| `POST /admins/management-access-policies` | New-PfbAdminManagementAccessPolicy | context_names | | `high` | POST/PATCH/DELETE return 403 regardless of account; not an implementation bug |
416416
| `POST /admins/ssh-certificate-authority-policies` | New-PfbAdminSshCaPolicy | context_names | | `high` | |
417-
| `POST /api-clients` | New-PfbApiClient | | access_policies, access_token_ttl_in_ms, issuer, max_role, public_key | `high` | |
417+
| `POST /api-clients` | New-PfbApiClient | | access_policies, access_token_ttl_in_ms, issuer | `high` | |
418418
| `POST /array-connections` | New-PfbArrayConnection | context_names | | `high` | |
419419
| `POST /arrays/erasures` | New-PfbArrayErasure | eradicate_all_data, preserve_configuration_data, skip_phonehome_check | | `high` | |
420420
| `POST /arrays/ssh-certificate-authority-policies` | New-PfbArraySshCaPolicy | context_names | | `high` | |

0 commit comments

Comments
 (0)