parsePolicyDiffFromMessage extracts policy diff counts from ValidationResult Prefers structured PolicyDiff field, falls back to message parsing for backward compatibility
(result *vsa.ValidationResult)
| 762 | // parsePolicyDiffFromMessage extracts policy diff counts from ValidationResult |
| 763 | // Prefers structured PolicyDiff field, falls back to message parsing for backward compatibility |
| 764 | func parsePolicyDiffFromMessage(result *vsa.ValidationResult) (added, removed, changed int, hasDiff bool) { |
| 765 | if result == nil { |
| 766 | return 0, 0, 0, false |
| 767 | } |
| 768 | |
| 769 | // Prefer structured PolicyDiff field if available |
| 770 | if result.PolicyDiff != nil { |
| 771 | return result.PolicyDiff.Added, result.PolicyDiff.Removed, result.PolicyDiff.Changed, true |
| 772 | } |
| 773 | |
| 774 | // Fallback to message parsing for backward compatibility (e.g., old ValidationResult without PolicyDiff) |
| 775 | message := result.Message |
| 776 | if !strings.Contains(message, "Policy mismatch") { |
| 777 | return 0, 0, 0, false |
| 778 | } |
| 779 | |
| 780 | // Look for pattern: "X added, Y removed, Z changed" |
| 781 | // Example: "❌ Policy mismatch detected — 1 added, 0 removed, 0 changed; 1 differences" |
| 782 | // Note: Uses em dash (—) not hyphen (-) |
| 783 | parts := strings.Split(message, "—") |
| 784 | if len(parts) < 2 { |
| 785 | // Try with regular dash as fallback |
| 786 | parts = strings.Split(message, "-") |
| 787 | if len(parts) < 2 { |
| 788 | return 0, 0, 0, true |
| 789 | } |
| 790 | } |
| 791 | |
| 792 | diffPart := parts[1] |
| 793 | // Extract numbers - handle both "1 added, 0 removed, 0 changed" and "1 added, 0 removed, 0 changed;" |
| 794 | _, err := fmt.Sscanf(diffPart, "%d added, %d removed, %d changed", &added, &removed, &changed) |
| 795 | if err != nil { |
| 796 | // If parsing fails, still return hasDiff=true to indicate policy mismatch exists |
| 797 | return 0, 0, 0, true |
| 798 | } |
| 799 | return added, removed, changed, true |
| 800 | } |
| 801 | |
| 802 | // processVSAResult processes a VSA validation result and updates the image status and aggregated data |
| 803 | func processVSAResult(vsaResult *vsa.ValidationResult, imgStatus *ImageStatus, data *AllSectionsData, shortDigest string) { |
no outgoing calls