Private/New-KadenOperatorModelApplyOutcome.ps1
|
function Get-KadenOperatorFileFingerprint { <# .SYNOPSIS Read an operator-file hash without throwing. #> param( [Parameter(Mandatory = $true)] [string]$LiteralPath ) if (-not (Test-Path -LiteralPath $LiteralPath -PathType Leaf)) { return [pscustomobject]@{ State = 'missing' Hash = $null } } try { return [pscustomobject]@{ State = 'available' Hash = (Get-KadenRawFileSha256 -LiteralPath $LiteralPath) } } catch { return [pscustomobject]@{ State = 'unreadable' Hash = $null } } } function Test-KadenOperatorFileBytesUnchanged { <# .SYNOPSIS True only when both fingerprints are available and equal, or both are missing. #> param( [Parameter(Mandatory = $true)]$Before, [Parameter(Mandatory = $true)]$After ) if ($Before.State -eq 'missing' -and $After.State -eq 'missing') { return $true } if ($Before.State -ne 'available' -or $After.State -ne 'available') { return $false } return ($Before.Hash -eq $After.Hash) } function New-KadenOperatorModelApplyReceipt { <# .SYNOPSIS Build the apply receipt from files the apply step tuned. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Builds an in-memory receipt. It does not change files.')] param( [Parameter(Mandatory = $true)] [AllowEmptyCollection()] [object[]]$TunedFiles, [Parameter(Mandatory = $true)] [string]$OperatorFile ) $entries = New-Object System.Collections.Generic.List[object] foreach ($file in @($TunedFiles)) { $entries.Add([pscustomobject]@{ Path = [string]$file.Path Model = [string]$file.Model OperatorInput = [string]$file.OperatorInput Source = 'operator-supplied' }) } return [pscustomobject]@{ Producer = 'operator-apply' DistinctFrom = 'maintainer-sync' OperatorFile = $OperatorFile Entries = @($entries.ToArray()) } } function Get-KadenOperatorModelApplyFinalStatus { <# .SYNOPSIS Choose applied, skipped, or failed from the write counts. #> param( [Parameter(Mandatory = $true)][int]$WriteFailures, [Parameter(Mandatory = $true)][int]$TunedCount, [Parameter(Mandatory = $true)][int]$NotTunedCount, [Parameter(Mandatory = $true)][bool]$Changed ) if ($WriteFailures -gt 0 -and $TunedCount -gt 0) { return [pscustomobject]@{ Status = 'failed' Reason = 'apply failed partway: tuned files and untouched files are both recorded' } } if ($WriteFailures -gt 0) { return [pscustomobject]@{ Status = 'failed' Reason = 'managed agents could not be tuned' } } if ($TunedCount -gt 0 -and $NotTunedCount -gt 0) { return [pscustomobject]@{ Status = 'applied' Reason = 'operator choices written where the managed agents are still installed; skipped entries are recorded' } } if ($TunedCount -gt 0 -and $Changed) { return [pscustomobject]@{ Status = 'applied' Reason = 'operator choices written to managed agent frontmatter' } } if ($TunedCount -gt 0) { return [pscustomobject]@{ Status = 'applied' Reason = 'operator choices already present' } } return [pscustomobject]@{ Status = 'skipped' Reason = 'the latest update no longer installs this agent' } } function New-KadenOperatorModelApplyOutcome { <# .SYNOPSIS Build the recorded apply outcome, including its receipt. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Builds an in-memory outcome. It does not change files.')] param( [Parameter(Mandatory = $true)][string]$Status, [Parameter(Mandatory = $true)][string]$Reason, [Parameter(Mandatory = $true)][string]$Path, [Parameter(Mandatory = $true)][string]$OperatorFile, [Parameter(Mandatory = $true)][bool]$OperatorFileBytesUnchanged, [Parameter(Mandatory = $true)][bool]$Changed, [Parameter(Mandatory = $true)][AllowEmptyCollection()][object[]]$Stacks, [Parameter(Mandatory = $true)][AllowEmptyCollection()][object[]]$TunedFiles, [Parameter(Mandatory = $true)][AllowEmptyCollection()][object[]]$NotTuned ) return [pscustomobject]@{ Status = $Status Reason = $Reason Path = $Path OperatorFile = $OperatorFile OperatorFileBytesUnchanged = $OperatorFileBytesUnchanged Changed = $Changed Escalation = 'none' SelectionPrecedence = 'invocation-override, agent-frontmatter, parent-model' Stacks = @($Stacks) TunedFiles = @($TunedFiles) NotTuned = @($NotTuned) Receipt = (New-KadenOperatorModelApplyReceipt -TunedFiles $TunedFiles -OperatorFile $OperatorFile) } } |