|
10 | 10 | [ValidateSet('get', 'set', 'test', 'delete', 'export')] |
11 | 11 | [string]$Operation, |
12 | 12 | [Parameter(ValueFromPipeline)] |
13 | | - $stdinput |
| 13 | + $stdinput, |
| 14 | + [switch]$WhatIf |
14 | 15 | ) |
15 | 16 |
|
16 | 17 | enum Scope { |
@@ -42,6 +43,7 @@ class PSResource { |
42 | 43 | [bool]$preRelease |
43 | 44 | [bool]$_exist |
44 | 45 | [bool]$_inDesiredState |
| 46 | + [object]$_metadata |
45 | 47 |
|
46 | 48 | PSResource([string]$name, [string]$version, [Scope]$scope, [string]$repositoryName, [bool]$preRelease) { |
47 | 49 | $this.name = $name |
@@ -98,14 +100,18 @@ class PSResource { |
98 | 100 | } |
99 | 101 |
|
100 | 102 | [string] ToJson() { |
101 | | - $retVal = ($this | Select-Object -ExcludeProperty _inDesiredState | ConvertTo-Json -Compress -EnumsAsStrings) |
| 103 | + [string[]]$excludeProps = @('_inDesiredState') |
| 104 | + if ($null -eq $this._metadata) { $excludeProps += '_metadata' } |
| 105 | + $retVal = ($this | Select-Object -ExcludeProperty $excludeProps | ConvertTo-Json -Compress -EnumsAsStrings) |
102 | 106 | Write-Trace -message "Serializing PSResource to JSON. Name: $($this.name), Version: $($this.version), Scope: $($this.scope), RepositoryName: $($this.repositoryName), PreRelease: $($this.preRelease), _exist: $($this._exist)" -level debug |
103 | 107 | Write-Trace -message "Serialized JSON: $retVal" -level trace |
104 | 108 | return $retVal |
105 | 109 | } |
106 | 110 |
|
107 | 111 | [string] ToJsonForTest() { |
108 | | - return ($this | ConvertTo-Json -Compress -Depth 5 -EnumsAsStrings) |
| 112 | + [string[]]$excludeProps = @() |
| 113 | + if ($null -eq $this._metadata) { $excludeProps += '_metadata' } |
| 114 | + return ($this | Select-Object -ExcludeProperty $excludeProps | ConvertTo-Json -Compress -Depth 5 -EnumsAsStrings) |
109 | 115 | } |
110 | 116 | } |
111 | 117 |
|
@@ -155,23 +161,29 @@ class PSResourceList { |
155 | 161 | } |
156 | 162 |
|
157 | 163 | [string] ToJson() { |
158 | | - $resourceJson = if ($this.resources) { ($this.resources | ForEach-Object { $_.ToJson() }) -join ',' } else { '' } |
159 | | - $resourceJson = "[$resourceJson]" |
160 | | - $jsonString = "{'repositoryName': '$($this.repositoryName)','resources': $resourceJson}" |
161 | | - $jsonString = $jsonString -replace "'", '"' |
162 | | - $retVal = $jsonString | ConvertFrom-Json | ConvertTo-Json -Compress -EnumsAsStrings |
163 | | - |
| 164 | + $resourceJsonItems = if ($this.resources) { |
| 165 | + @($this.resources | ForEach-Object { $_.ToJson() }) |
| 166 | + } else { @() } |
| 167 | + $resourcesArrayJson = '[' + ($resourceJsonItems -join ',') + ']' |
| 168 | + $repoNameJson = $this.repositoryName | ConvertTo-Json -Compress |
| 169 | + $retVal = "{`"repositoryName`":$repoNameJson,`"resources`":$resourcesArrayJson}" |
164 | 170 | Write-Trace -message "Serializing PSResourceList to JSON. RepositoryName: $($this.repositoryName), TrustedRepository: $($this.trustedRepository), Resources count: $($this.resources.Count)" -level debug |
165 | 171 | Write-Trace -message "Serialized JSON: $retVal" -level trace |
166 | | - |
167 | 172 | return $retVal |
168 | 173 | } |
169 | 174 |
|
170 | 175 | [string] ToJsonForTest() { |
171 | 176 | Write-Trace -message "Serializing PSResourceList to JSON for test output. RepositoryName: $($this.repositoryName), TrustedRepository: $($this.trustedRepository), Resources count: $($this.resources.Count)" -level debug |
172 | | - $jsonForTest = $this | ConvertTo-Json -Compress -Depth 5 -EnumsAsStrings |
173 | | - Write-Trace -message "Serialized JSON: $jsonForTest" -level trace |
174 | | - return $jsonForTest |
| 177 | + $resourceJsonItems = if ($this.resources) { |
| 178 | + @($this.resources | ForEach-Object { $_.ToJsonForTest() }) |
| 179 | + } else { @() } |
| 180 | + $resourcesArrayJson = '[' + ($resourceJsonItems -join ',') + ']' |
| 181 | + $repoNameJson = $this.repositoryName | ConvertTo-Json -Compress |
| 182 | + $trustedStr = ($this.trustedRepository).ToString().ToLower() |
| 183 | + $inDesiredStr = ($this._inDesiredState).ToString().ToLower() |
| 184 | + $retVal = "{`"repositoryName`":$repoNameJson,`"resources`":$resourcesArrayJson,`"trustedRepository`":$trustedStr,`"_inDesiredState`":$inDesiredStr}" |
| 185 | + Write-Trace -message "Serialized JSON: $retVal" -level trace |
| 186 | + return $retVal |
175 | 187 | } |
176 | 188 | } |
177 | 189 |
|
@@ -548,11 +560,61 @@ function ExportOperation { |
548 | 560 | } |
549 | 561 | } |
550 | 562 |
|
551 | | -function SetPSResourceList { |
| 563 | +function WhatIfPSResourceList { |
552 | 564 | param( |
553 | 565 | $inputObj |
554 | 566 | ) |
555 | 567 |
|
| 568 | + $repositoryName = $inputObj.repositoryName |
| 569 | + $currentState = GetPSResourceList -inputObj $inputObj |
| 570 | + $projectedResources = @() |
| 571 | + $inputObj.resources | ForEach-Object { |
| 572 | + $resourceDesiredState = ConvertInputToPSResource -inputObj $_ -repositoryName $repositoryName |
| 573 | + $name = $resourceDesiredState.name |
| 574 | + $version = $resourceDesiredState.version |
| 575 | + $scope = if ($resourceDesiredState.scope) { $resourceDesiredState.scope } else { [Scope]'CurrentUser' } |
| 576 | + $currentResource = $currentState.resources | Where-Object { $_.name -eq $name } | Select-Object -First 1 |
| 577 | + |
| 578 | + if (-not $resourceDesiredState._exist -and $null -ne $currentResource -and $currentResource._exist) { |
| 579 | + $msg = "Would uninstall resource '$name'" |
| 580 | + Write-Trace -message "WhatIf: $msg." -level debug |
| 581 | + $resource = [PSResource]::new($name) |
| 582 | + $resource._metadata = [pscustomobject]@{ whatIf = @($msg) } |
| 583 | + $projectedResources += $resource |
| 584 | + } |
| 585 | + elseif ($resourceDesiredState._exist -and ($null -eq $currentResource -or -not $currentResource._exist)) { |
| 586 | + $versionStr = if ($version) { $version } else { 'latest' } |
| 587 | + $msg = "Would install resource '$name' version '$versionStr'" |
| 588 | + Write-Trace -message "WhatIf: $msg." -level debug |
| 589 | + $resource = [PSResource]::new($name, $versionStr, [Scope]$scope, $repositoryName, $resourceDesiredState.preRelease) |
| 590 | + $resource._metadata = [pscustomobject]@{ whatIf = @($msg) } |
| 591 | + $projectedResources += $resource |
| 592 | + } |
| 593 | + else { |
| 594 | + Write-Trace -message "WhatIf: Resource '$name' is already in desired state." -level debug |
| 595 | + if ($null -ne $currentResource) { |
| 596 | + $projectedResources += $currentResource |
| 597 | + } |
| 598 | + else { |
| 599 | + $projectedResources += $resourceDesiredState |
| 600 | + } |
| 601 | + } |
| 602 | + } |
| 603 | + |
| 604 | + $list = [PSResourceList]::new($repositoryName, $projectedResources, $currentState.trustedRepository) |
| 605 | + $list.ToJson() |
| 606 | +} |
| 607 | + |
| 608 | +function SetPSResourceList { |
| 609 | + param( |
| 610 | + $inputObj, |
| 611 | + [switch]$WhatIf |
| 612 | + ) |
| 613 | + |
| 614 | + if ($WhatIf) { |
| 615 | + return WhatIfPSResourceList -inputObj $inputObj |
| 616 | + } |
| 617 | + |
556 | 618 | $repositoryName = $inputObj.repositoryName |
557 | 619 | $resourcesToUninstall = @() |
558 | 620 | $resourcesToInstall = [System.Collections.Generic.Dictionary[string, psobject]]::new() |
@@ -707,7 +769,7 @@ function SetOperation { |
707 | 769 | Write-Trace -level error -message "Set operation is not implemented for PSResource resource." |
708 | 770 | exit [ExitCode]::SetNotImplemented |
709 | 771 | } |
710 | | - 'psresourcelist' { return SetPSResourceList -inputObj $inputObj } |
| 772 | + 'psresourcelist' { return SetPSResourceList -inputObj $inputObj -WhatIf:$WhatIf } |
711 | 773 | default { |
712 | 774 | Write-Trace -level error -message "Unknown ResourceType: $ResourceType" |
713 | 775 | exit [ExitCode]::UnknownResourceType |
|
0 commit comments