LibreDevOpsHelpers.Findings/LibreDevOpsHelpers.Findings.psm1
|
Set-StrictMode -Version Latest # Module-scoped store of findings recorded during a run. Invoke-LdoTfLint / Invoke-LdoTrivy / # Invoke-LdoConftest add to it; Show-LdoFindingsSummary prints them neatly at the end so the # results are not lost in verbose structured logging. $script:LdoFindings = [System.Collections.Generic.List[psobject]]::new() function Add-LdoFinding { <# .SYNOPSIS Records a tool finding for the end-of-run summary. .PARAMETER Tool Name of the tool that produced the result (for example tflint, trivy, conftest). .PARAMETER Target What was checked (for example the stack folder or plan file). .PARAMETER Status PASS, WARN, or FAIL. .PARAMETER Summary Short one-line summary, for example "no findings" or "2 findings". .PARAMETER Detail The captured tool output to show under the summary. .EXAMPLE Add-LdoFinding -Tool trivy -Target ./examples/minimal -Status PASS -Summary 'no HIGH/CRITICAL' .OUTPUTS None #> [CmdletBinding()] [OutputType([void])] param( [Parameter(Mandatory)][ValidateNotNullOrEmpty()][string]$Tool, [Parameter(Mandatory)][ValidateNotNullOrEmpty()][string]$Target, [Parameter(Mandatory)][ValidateSet('PASS', 'WARN', 'FAIL')][string]$Status, [string]$Summary = '', [string]$Detail = '' ) $script:LdoFindings.Add([pscustomobject]@{ Tool = $Tool Target = $Target Status = $Status Summary = $Summary Detail = $Detail }) } function Get-LdoFinding { <# .SYNOPSIS Returns the findings recorded so far. .EXAMPLE Get-LdoFinding .OUTPUTS System.Management.Automation.PSObject[] #> [CmdletBinding()] [OutputType([psobject[]])] param() return $script:LdoFindings.ToArray() } function Clear-LdoFinding { <# .SYNOPSIS Clears the recorded findings (call at the start of a run). .EXAMPLE Clear-LdoFinding .OUTPUTS None #> [CmdletBinding()] [OutputType([void])] param() $script:LdoFindings.Clear() } function Show-LdoFindingsSummary { <# .SYNOPSIS Prints a neat summary of the recorded findings. .DESCRIPTION Writes a status table (one row per recorded finding) followed by the captured detail for any WARN or FAIL result, so scan/lint/policy findings are easy to read without scrolling through verbose logs. Uses Write-Host so it is readable whatever the log format. Does nothing when no findings were recorded. .PARAMETER Title Heading for the summary block. Defaults to 'FINDINGS SUMMARY'. .PARAMETER IncludeDetail Also print the captured detail for PASS results, not just WARN/FAIL. .EXAMPLE Show-LdoFindingsSummary .OUTPUTS None #> [CmdletBinding()] [OutputType([void])] param( [string]$Title = 'FINDINGS SUMMARY', [switch]$IncludeDetail ) $findings = $script:LdoFindings if ($findings.Count -eq 0) { return } $colour = @{ PASS = 'Green'; WARN = 'Yellow'; FAIL = 'Red' } $width = 72 $bar = '=' * $width Write-Host '' Write-Host $bar -ForegroundColor Cyan Write-Host (" {0}" -f $Title) -ForegroundColor Cyan Write-Host $bar -ForegroundColor Cyan foreach ($f in $findings) { $line = "{0,-9} {1,-6} {2}" -f $f.Tool, $f.Status, $f.Target $fg = if ($colour.ContainsKey($f.Status)) { $colour[$f.Status] } else { 'Gray' } Write-Host $line -ForegroundColor $fg if ($f.Summary) { Write-Host (" {0}" -f $f.Summary) -ForegroundColor DarkGray } } # Detail for anything that is not a clean pass (or everything, with -IncludeDetail). foreach ($f in $findings) { $showDetail = $f.Detail -and ($IncludeDetail -or $f.Status -ne 'PASS') if ($showDetail) { Write-Host '' Write-Host ("-- [{0}] {1} ({2}) " -f $f.Tool, $f.Target, $f.Status).PadRight($width, '-') -ForegroundColor Cyan foreach ($detailLine in ($f.Detail -split "`r?`n")) { Write-Host $detailLine } } } Write-Host $bar -ForegroundColor Cyan Write-Host '' } Export-ModuleMember -Function ` Add-LdoFinding, ` Get-LdoFinding, ` Clear-LdoFinding, ` Show-LdoFindingsSummary |