173 lines
10 KiB
PowerShell
173 lines
10 KiB
PowerShell
#region Remove-RackpadOrphanedObject
|
|
Function Remove-RackpadOrphanedObject
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Deletes objects that this solution previously created and that are no longer present within the desired state.
|
|
|
|
.DESCRIPTION
|
|
Pruning is deliberately narrow. Only objects recorded within the managed state document are eligible, which means that any
|
|
object created by hand within the Rackpad user interface is never touched.
|
|
|
|
An entry becomes eligible when it exists within the state document but was not registered as observed during the current run.
|
|
Deletion is performed in the supplied order so that dependent objects are removed before the objects that they reference.
|
|
|
|
A status code of 404 is treated as success because the target object has already been removed, which keeps the operation
|
|
idempotent.
|
|
|
|
.PARAMETER Session
|
|
The session object produced by Connect-RackpadInstance.
|
|
|
|
.PARAMETER ManagedState
|
|
The state object produced by Get-RackpadManagedState.
|
|
|
|
.PARAMETER PruneOrder
|
|
An ordered dictionary mapping entity type to collection route. Entity types are processed in the order supplied.
|
|
|
|
.EXAMPLE
|
|
$PruneOrder = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
|
$PruneOrder.'ip-assignment' = 'ip-assignments'
|
|
$PruneOrder.'port-link' = 'port-links'
|
|
$PruneOrder.'port' = 'ports'
|
|
|
|
$PruneResultList = Remove-RackpadOrphanedObject -Session $RackpadSession -ManagedState $ManagedState -PruneOrder $PruneOrder
|
|
|
|
.NOTES
|
|
Author: Grace Solutions
|
|
Version: 2026.08.02.0000
|
|
#>
|
|
|
|
[CmdletBinding(SupportsShouldProcess=$True)]
|
|
Param
|
|
(
|
|
[Parameter(Mandatory=$True)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[PSObject]$Session,
|
|
|
|
[Parameter(Mandatory=$True)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[PSObject]$ManagedState,
|
|
|
|
[Parameter(Mandatory=$True)]
|
|
[ValidateNotNullOrEmpty()]
|
|
[System.Collections.Specialized.OrderedDictionary]$PruneOrder
|
|
)
|
|
|
|
Try
|
|
{
|
|
$PruneResultList = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
|
|
|
|
#region Build the list of orphaned entries in the supplied deletion order
|
|
$OrphanedEntryList = New-Object -TypeName 'System.Collections.Generic.List[PSObject]'
|
|
|
|
ForEach ($PruneOrderEntry In $PruneOrder.GetEnumerator())
|
|
{
|
|
$EntityTypeKey = "$($PruneOrderEntry.Key)".ToLowerInvariant()
|
|
|
|
Switch ($ManagedState.EntryTable.ContainsKey($EntityTypeKey))
|
|
{
|
|
{($_ -eq $True)}
|
|
{
|
|
$ObservedKeySet = New-Object -TypeName 'System.Collections.Generic.HashSet[System.String]'
|
|
|
|
Switch ($ManagedState.ObservedTable.ContainsKey($EntityTypeKey))
|
|
{
|
|
{($_ -eq $True)}
|
|
{
|
|
$ObservedKeySet = $ManagedState.ObservedTable[$EntityTypeKey]
|
|
}
|
|
}
|
|
|
|
ForEach ($RecordedEntry In $ManagedState.EntryTable[$EntityTypeKey].GetEnumerator())
|
|
{
|
|
Switch ($ObservedKeySet.Contains("$($RecordedEntry.Key)"))
|
|
{
|
|
{($_ -eq $False)}
|
|
{
|
|
$OrphanedEntryProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
|
$OrphanedEntryProperties.EntityType = "$($EntityTypeKey)"
|
|
$OrphanedEntryProperties.CollectionRoute = "$($PruneOrderEntry.Value)"
|
|
$OrphanedEntryProperties.NaturalKey = "$($RecordedEntry.Key)"
|
|
$OrphanedEntryProperties.Identifier = "$($RecordedEntry.Value)"
|
|
|
|
$OrphanedEntryList.Add((New-Object -TypeName 'System.Management.Automation.PSObject' -Property ($OrphanedEntryProperties)))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
Write-Verbose -Message "[$([System.DateTime]::UtcNow.ToString('yyyy/MM/dd HH:mm:ss.FFF'))] - [INFO] - $($OrphanedEntryList.Count) previously created object(s) are eligible for pruning."
|
|
|
|
#region Delete each orphaned entry
|
|
$OrphanedEntryListCount = $OrphanedEntryList.Count
|
|
|
|
For ($OrphanedEntryIndex = 0; $OrphanedEntryIndex -lt $OrphanedEntryListCount; $OrphanedEntryIndex++)
|
|
{
|
|
$OrphanedEntry = $OrphanedEntryList[$OrphanedEntryIndex]
|
|
|
|
$WriteProgressParameters = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
|
$WriteProgressParameters.Activity = 'Pruning previously created Rackpad objects'
|
|
$WriteProgressParameters.Status = "Removing $($OrphanedEntry.EntityType) `"$($OrphanedEntry.NaturalKey)`" ($($OrphanedEntryIndex + 1) of $($OrphanedEntryListCount))"
|
|
$WriteProgressParameters.PercentComplete = [System.Math]::Round((($OrphanedEntryIndex + 1) / $OrphanedEntryListCount) * 100, 2)
|
|
$WriteProgressParameters.Id = 30
|
|
|
|
$Null = Write-Progress @WriteProgressParameters
|
|
|
|
$DeletionRoute = "$($OrphanedEntry.CollectionRoute)/$($OrphanedEntry.Identifier)"
|
|
|
|
$PruneResultProperties = New-Object -TypeName 'System.Collections.Specialized.OrderedDictionary'
|
|
$PruneResultProperties.EntityType = "$($OrphanedEntry.EntityType)"
|
|
$PruneResultProperties.NaturalKey = "$($OrphanedEntry.NaturalKey)"
|
|
$PruneResultProperties.Identifier = "$($OrphanedEntry.Identifier)"
|
|
$PruneResultProperties.Action = 'Deleted'
|
|
$PruneResultProperties.ErrorMessage = $Null
|
|
|
|
Switch ($PSCmdlet.ShouldProcess("$($OrphanedEntry.EntityType) `"$($OrphanedEntry.NaturalKey)`"", "Delete using DELETE /api/$($DeletionRoute)"))
|
|
{
|
|
{($_ -eq $True)}
|
|
{
|
|
$DeletionResponse = Invoke-RackpadRequest -Session ($Session) -Route ($DeletionRoute) -Method 'DELETE' -AcceptableStatusCodeList @('404')
|
|
|
|
Switch ($DeletionResponse.IsSuccess)
|
|
{
|
|
{($_ -eq $True)}
|
|
{
|
|
$Null = $ManagedState.EntryTable["$($OrphanedEntry.EntityType)"].Remove("$($OrphanedEntry.NaturalKey)")
|
|
|
|
Write-Verbose -Message "[$([System.DateTime]::UtcNow.ToString('yyyy/MM/dd HH:mm:ss.FFF'))] - [INFO] - Pruned $($OrphanedEntry.EntityType) `"$($OrphanedEntry.NaturalKey)`". [Identifier: $($OrphanedEntry.Identifier)]"
|
|
}
|
|
|
|
{($_ -eq $False)}
|
|
{
|
|
$PruneResultProperties.Action = 'Failed'
|
|
$PruneResultProperties.ErrorMessage = "$($DeletionResponse.StatusDescription) $($DeletionResponse.ErrorMessage)".Trim()
|
|
|
|
Write-Warning -Message "[$([System.DateTime]::UtcNow.ToString('yyyy/MM/dd HH:mm:ss.FFF'))] - [WARNING] - Failed to prune $($OrphanedEntry.EntityType) `"$($OrphanedEntry.NaturalKey)`". [Status Code: $($DeletionResponse.StatusCode)] [$($PruneResultProperties.ErrorMessage)]"
|
|
}
|
|
}
|
|
}
|
|
|
|
{($_ -eq $False)}
|
|
{
|
|
$PruneResultProperties.Action = 'WhatIf'
|
|
}
|
|
}
|
|
|
|
$PruneResultList.Add((New-Object -TypeName 'System.Management.Automation.PSObject' -Property ($PruneResultProperties)))
|
|
}
|
|
|
|
$Null = Write-Progress -Activity 'Pruning previously created Rackpad objects' -Id 30 -Completed
|
|
#endregion
|
|
|
|
Write-Output -InputObject ($PruneResultList)
|
|
}
|
|
Catch
|
|
{
|
|
Throw
|
|
}
|
|
}
|
|
#endregion
|