modules/normalizers/Normalize-AdoConsumption.ps1
|
#Requires -Version 7.4 [CmdletBinding()] param () . "$PSScriptRoot\..\shared\Schema.ps1" . "$PSScriptRoot\..\shared\Canonicalize.ps1" function Get-PropertyValue { param ([object]$Obj, [string]$Name, [object]$Default = $null) if ($null -eq $Obj) { return $Default } $p = $Obj.PSObject.Properties[$Name] if ($null -eq $p -or $null -eq $p.Value) { return $Default } return $p.Value } function Convert-ToStringArray { param ([object]$Value) if ($null -eq $Value) { return @() } $items = [System.Collections.Generic.List[string]]::new() if ($Value -is [string]) { if (-not [string]::IsNullOrWhiteSpace($Value)) { $items.Add($Value.Trim()) | Out-Null } } else { foreach ($item in @($Value)) { if ($null -eq $item) { continue } $text = [string]$item if (-not [string]::IsNullOrWhiteSpace($text)) { $items.Add($text.Trim()) | Out-Null } } } return @($items) } function Convert-ToNullableDouble { param ([object]$Value) if ($null -eq $Value) { return $null } $parsed = 0.0 if ([double]::TryParse([string]$Value, [System.Globalization.NumberStyles]::Float -bor [System.Globalization.NumberStyles]::AllowThousands, [System.Globalization.CultureInfo]::InvariantCulture, [ref]$parsed)) { return [double]$parsed } return $null } function Normalize-AdoConsumption { [CmdletBinding()] param ( [Parameter(Mandatory)] [PSCustomObject] $ToolResult ) if ($ToolResult.Status -notin @('Success', 'PartialSuccess') -or -not $ToolResult.Findings) { return @() } $runId = [guid]::NewGuid().ToString() $normalized = [System.Collections.Generic.List[PSCustomObject]]::new() foreach ($finding in @($ToolResult.Findings)) { $rawId = if ($finding.PSObject.Properties['ResourceId'] -and $finding.ResourceId) { [string]$finding.ResourceId } else { '' } if ([string]::IsNullOrWhiteSpace($rawId)) { continue } $canonicalId = $rawId.ToLowerInvariant() try { $canonicalId = (ConvertTo-CanonicalEntityId -RawId $rawId -EntityType 'AdoProject').CanonicalId } catch { $canonicalId = $rawId.ToLowerInvariant() } $severity = switch -Regex ([string]$finding.Severity) { '^(?i)critical$' { 'Critical' } '^(?i)high$' { 'High' } '^(?i)medium$' { 'Medium' } '^(?i)low$' { 'Low' } default { 'Info' } } $ruleId = if ($finding.PSObject.Properties['RuleId'] -and $finding.RuleId) { [string]$finding.RuleId } else { '' } $pillar = [string](Get-PropertyValue -Obj $finding -Name 'Pillar' -Default '') $impact = [string](Get-PropertyValue -Obj $finding -Name 'Impact' -Default '') $effort = [string](Get-PropertyValue -Obj $finding -Name 'Effort' -Default '') $deepLinkUrl = [string](Get-PropertyValue -Obj $finding -Name 'DeepLinkUrl' -Default '') $evidenceUris = @(Convert-ToStringArray (Get-PropertyValue -Obj $finding -Name 'EvidenceUris' -Default @())) $baselineTags = @(Convert-ToStringArray (Get-PropertyValue -Obj $finding -Name 'BaselineTags' -Default @())) $entityRefs = @(Convert-ToStringArray (Get-PropertyValue -Obj $finding -Name 'EntityRefs' -Default @())) $scoreDelta = Convert-ToNullableDouble (Get-PropertyValue -Obj $finding -Name 'ScoreDelta' -Default $null) $toolVersion = [string](Get-PropertyValue -Obj $finding -Name 'ToolVersion' -Default (Get-PropertyValue -Obj $ToolResult -Name 'ToolVersion' -Default '')) $row = New-FindingRow -Id ([string]$finding.Id) ` -Source 'ado-consumption' -EntityId $canonicalId -EntityType 'AdoProject' ` -Title ([string]$finding.Title) -Compliant ([bool]$finding.Compliant) -ProvenanceRunId $runId ` -Platform 'ADO' -Category ([string]$finding.Category) -Severity $severity ` -Detail ([string]$finding.Detail) -Remediation ([string]$finding.Remediation) ` -LearnMoreUrl ([string]$finding.LearnMoreUrl) -ResourceId $rawId -RuleId $ruleId ` -Pillar $pillar -Impact $impact -Effort $effort -DeepLinkUrl $deepLinkUrl ` -EvidenceUris $evidenceUris -BaselineTags $baselineTags -ScoreDelta $scoreDelta ` -EntityRefs $entityRefs -ToolVersion $toolVersion if ($null -ne $row) { $normalized.Add($row) } } return @($normalized) } |