public/Undo-OctaRun.ps1
|
function Undo-OctaRun { <# .SYNOPSIS Reverts a prior Octa run using its recorded prior-state snapshots (FR-008). .PARAMETER RunId A specific run id (folder name), or 'latest' for the most recent run. #> [CmdletBinding()] param( [Parameter(Mandatory)][string]$RunId ) $strings = Get-OctaStrings $record = Get-OctaRunRecord -RunId $RunId if (-not $record) { return [pscustomobject]@{ Status = 'NotFound'; Message = ($strings.undoNotFound -f $RunId) } } if ($record.Status -eq 'Undone') { return [pscustomobject]@{ Status = 'AlreadyUndone'; Message = 'This run was already undone.' } } $restored = @() $failed = @() $irreversible = @($record.IrreversibleActionRefs) $snapshots = @($record.ActionSnapshots) | Where-Object { $_ } foreach ($snapshot in $snapshots) { try { Restore-OctaActionSnapshot -Snapshot $snapshot -RunFolder $record.RunFolder $restored += $snapshot.ActionRef Write-Host ($strings.undoRestored -f $snapshot.ActionRef) } catch { $failed += $snapshot.ActionRef } } $couldNotUndo = @($irreversible) + @($failed) foreach ($ref in $couldNotUndo) { Write-Host ($strings.undoIrreversible -f $ref) } # ponytail: only mark the run Undone when every reversible action actually came back. This # used to be unconditional, so a run where every single restore threw still got recorded as # Undone and returned Status = 'Success' - which then made a second --undo attempt answer # 'AlreadyUndone', permanently blocking the retry for a run that was never undone at all. # Verified real: a snapshot pointing at a service that no longer exists restores 0 of 1 # actions and was still reported as a success. $allRestored = ($failed.Count -eq 0) $recordStatus = if ($allRestored) { 'Undone' } else { 'PartiallyUndone' } Add-Member -InputObject $record -MemberType NoteProperty -Name 'Status' -Value $recordStatus -Force Save-OctaRunRecord -RunFolder $record.RunFolder -RunRecord $record $status = if ($allRestored) { 'Success' } elseif ($restored.Count -gt 0) { 'PartiallyUndone' } else { 'Failed' } return [pscustomobject]@{ Status = $status Restored = $restored CouldNotUndo = $couldNotUndo Failed = $failed } } |