@@ -52,24 +52,16 @@ const (
5252 DefaultFallbackEnabled = true
5353)
5454
55- // Helper functions for color-aware output
56- func printVSAStatus (w io.Writer , message string , status string ) {
57- if utils .ColorEnabled {
58- // No emojis - just output the message
59- fmt .Fprintf (w , "%s\n " , message )
60- } else {
61- fmt .Fprintf (w , "[%s] %s\n " , strings .ToUpper (status ), message )
62- }
63- }
55+ // Constants for validation status
56+ const (
57+ unknownReason = "unknown"
58+ )
6459
60+ // Helper function for color-aware output
6561func printVSAInfo (w io.Writer , message string ) {
6662 fmt .Fprintf (w , "[INFO] %s\n " , message )
6763}
6864
69- func printVSAWarning (w io.Writer , message string ) {
70- fmt .Fprintf (w , "[WARNING] %s\n " , message )
71- }
72-
7365// validateVSAData holds the command data
7466type validateVSAData struct {
7567 // Input options
@@ -592,7 +584,7 @@ func shortenImageDigest(imageRef string) string {
592584// extractFallbackReason extracts the reason for fallback from ValidationResult
593585func extractFallbackReason (result * vsa.ValidationResult ) string {
594586 if result == nil {
595- return "unknown"
587+ return unknownReason
596588 }
597589
598590 message := result .Message
@@ -612,7 +604,7 @@ func extractFallbackReason(result *vsa.ValidationResult) string {
612604 return "retrieval failed"
613605 }
614606
615- return "unknown"
607+ return unknownReason
616608}
617609
618610// parsePolicyDiffFromMessage extracts policy diff counts from formatted message
@@ -643,6 +635,44 @@ func parsePolicyDiffFromMessage(message string) (added, removed, changed int, ha
643635 return added , removed , changed , true
644636}
645637
638+ // processVSAResult processes a VSA validation result and updates the image status and aggregated data
639+ func processVSAResult (vsaResult * vsa.ValidationResult , imgStatus * ImageStatus , data * AllSectionsData , shortDigest string ) {
640+ if vsaResult .Passed {
641+ imgStatus .VSAStatus = "PASSED"
642+ data .VSAPassed ++
643+ } else {
644+ reason := extractFallbackReason (vsaResult )
645+ imgStatus .VSAStatus = fmt .Sprintf ("FAILED(reason=%s)" , reason )
646+ data .VSAFailed ++
647+ data .FallbackReasons [reason ] = true
648+ }
649+
650+ // Aggregate signature status
651+ if ! vsaResult .SignatureVerified {
652+ data .SignatureStatus = "NOT VERIFIED"
653+ }
654+
655+ // Aggregate predicate status
656+ if vsaResult .PredicateOutcome == "passed" {
657+ data .PredicatePassed ++
658+ } else if vsaResult .PredicateOutcome != "" {
659+ data .PredicateFailed ++
660+ }
661+
662+ // Check for policy diff (parse from message once)
663+ if strings .Contains (vsaResult .Message , "Policy mismatch" ) {
664+ data .HasPolicyDiff = true
665+ data .AffectedImages = append (data .AffectedImages , shortDigest )
666+ added , removed , changed , _ := parsePolicyDiffFromMessage (vsaResult .Message )
667+ data .PolicyDiffCounts [shortDigest ] = PolicyDiffCounts {
668+ Added : added , Removed : removed , Changed : changed ,
669+ }
670+ data .PolicyMismatches ++
671+ } else if vsaResult .Passed {
672+ data .PolicyMatches ++
673+ }
674+ }
675+
646676// aggregateAllSectionsData - Single pass aggregation, collects all data needed
647677func aggregateAllSectionsData (allResults []vsa.ComponentResult ) AllSectionsData {
648678 data := AllSectionsData {
@@ -664,40 +694,7 @@ func aggregateAllSectionsData(allResults []vsa.ComponentResult) AllSectionsData
664694
665695 // Process VSA result
666696 if result .Result != nil {
667- if result .Result .Passed {
668- imgStatus .VSAStatus = "PASSED"
669- data .VSAPassed ++
670- } else {
671- reason := extractFallbackReason (result .Result )
672- imgStatus .VSAStatus = fmt .Sprintf ("FAILED(reason=%s)" , reason )
673- data .VSAFailed ++
674- data .FallbackReasons [reason ] = true
675- }
676-
677- // Aggregate signature status
678- if ! result .Result .SignatureVerified {
679- data .SignatureStatus = "NOT VERIFIED"
680- }
681-
682- // Aggregate predicate status
683- if result .Result .PredicateOutcome == "passed" {
684- data .PredicatePassed ++
685- } else if result .Result .PredicateOutcome != "" {
686- data .PredicateFailed ++
687- }
688-
689- // Check for policy diff (parse from message once)
690- if strings .Contains (result .Result .Message , "Policy mismatch" ) {
691- data .HasPolicyDiff = true
692- data .AffectedImages = append (data .AffectedImages , shortDigest )
693- added , removed , changed , _ := parsePolicyDiffFromMessage (result .Result .Message )
694- data .PolicyDiffCounts [shortDigest ] = PolicyDiffCounts {
695- Added : added , Removed : removed , Changed : changed ,
696- }
697- data .PolicyMismatches ++
698- } else if result .Result .Passed {
699- data .PolicyMatches ++
700- }
697+ processVSAResult (result .Result , & imgStatus , & data , shortDigest )
701698 }
702699
703700 // Handle fallback
@@ -947,95 +944,6 @@ func displayComponentResults(allResults []vsa.ComponentResult, data *validateVSA
947944 return nil
948945}
949946
950- // displayFallbackResult displays fallback validation results
951- // It shows VSA result first (why fallback was triggered), then the fallback image validation result
952- func displayFallbackResult (result vsa.ComponentResult , data * validateVSAData ) {
953- // Display VSA result first (shows why fallback was triggered)
954- if result .Result != nil {
955- displayVSAFailureResult (result , data )
956- }
957-
958- // Then display fallback image validation result
959- printVSAInfo (os .Stdout , " 🔄 Fallback validation used" )
960- if result .FallbackResult != nil {
961- displayImageValidationResult (* result .FallbackResult )
962- } else {
963- printVSAWarning (os .Stdout , " No fallback result available" )
964- }
965- }
966-
967- // displayImageValidationResult displays image validation results from a validate_utils.Result
968- // This matches the format used by the validate image command
969- func displayImageValidationResult (result validate_utils.Result ) {
970- if result .Err != nil {
971- printVSAStatus (os .Stdout , fmt .Sprintf (" Image validation error: %v" , result .Err ), "failure" )
972- return
973- }
974-
975- component := result .Component
976-
977- // Display overall status
978- if component .Success {
979- printVSAStatus (os .Stdout , " Image validation passed" , "success" )
980- } else {
981- printVSAStatus (os .Stdout , " ❌ Image validation failed" , "failure" )
982- }
983-
984- // Display summary counts
985- if len (component .Violations ) > 0 || len (component .Warnings ) > 0 || component .SuccessCount > 0 {
986- printVSAInfo (os .Stdout , fmt .Sprintf (" Violations: %d, Warnings: %d, Successes: %d" ,
987- len (component .Violations ), len (component .Warnings ), component .SuccessCount ))
988- }
989-
990- // Display violations
991- if len (component .Violations ) > 0 {
992- for _ , violation := range component .Violations {
993- code := "unknown"
994- if c , ok := violation .Metadata ["code" ]; ok {
995- code = fmt .Sprintf ("%v" , c )
996- }
997- printVSAStatus (os .Stdout , fmt .Sprintf (" [Violation] %s: %s" , code , violation .Message ), "failure" )
998- }
999- }
1000-
1001- // Display warnings
1002- if len (component .Warnings ) > 0 {
1003- for _ , warning := range component .Warnings {
1004- code := "unknown"
1005- if c , ok := warning .Metadata ["code" ]; ok {
1006- code = fmt .Sprintf ("%v" , c )
1007- }
1008- printVSAWarning (os .Stdout , fmt .Sprintf (" [Warning] %s: %s" , code , warning .Message ))
1009- }
1010- }
1011- }
1012-
1013- // displayVSASuccessResult displays VSA success results
1014- func displayVSASuccessResult (result vsa.ComponentResult , data * validateVSAData ) {
1015- printVSAStatus (os .Stdout , fmt .Sprintf ("Passed: %s" , result .Result .Message ), "success" )
1016- if result .Result .SignatureVerified {
1017- printVSAInfo (os .Stdout , " 🔐 Signature verified" )
1018- } else if ! data .ignoreSignatureVerification {
1019- printVSAWarning (os .Stdout , " Signature verification requested but not performed" )
1020- }
1021- if result .Result .PredicateOutcome != "" {
1022- printVSAInfo (os .Stdout , fmt .Sprintf (" Predicate Status: %s" , result .Result .PredicateOutcome ))
1023- }
1024- }
1025-
1026- // displayVSAFailureResult displays VSA failure results
1027- func displayVSAFailureResult (result vsa.ComponentResult , data * validateVSAData ) {
1028- if result .Result .SignatureVerified {
1029- printVSAInfo (os .Stdout , " 🔐 Signature verified" )
1030- } else if ! data .ignoreSignatureVerification {
1031- printVSAWarning (os .Stdout , "Signature verification requested but not performed" )
1032- }
1033- if result .Result .PredicateOutcome != "" {
1034- printVSAInfo (os .Stdout , fmt .Sprintf (" Predicate Status: %s" , result .Result .PredicateOutcome ))
1035- }
1036- printVSAStatus (os .Stdout , fmt .Sprintf ("Failed: %s" , result .Result .Message ), "failure" )
1037- }
1038-
1039947// handleSnapshotOutput handles output formatting for snapshot validation
1040948// When fallback components exist, it uses WriteReport (same format as validate image command)
1041949// Otherwise, it uses the VSA report format to avoid conflicts
@@ -1098,7 +1006,7 @@ func handleSnapshotOutput(allResults []vsa.ComponentResult, data *validateVSADat
10981006 }
10991007
11001008 // No fallback components - use VSA report format
1101- report := createVSAReport (allResults , data )
1009+ report := createVSAReport (allResults )
11021010 return writeOutputToFormats (report , data , fs )
11031011}
11041012
@@ -1338,14 +1246,20 @@ func (r *VSAReport) PrintText(writer io.Writer) error {
13381246
13391247 if result .Error != nil {
13401248 fmt .Fprintf (writer , " Error: %v\n " , result .Error )
1341- } else if result .FallbackResult != nil {
1249+ continue
1250+ }
1251+
1252+ if result .FallbackResult != nil {
13421253 fmt .Fprintf (writer , " Fallback used\n " )
13431254 if result .FallbackResult .Component .Success {
13441255 fmt .Fprintf (writer , " Fallback succeeded\n " )
13451256 } else {
13461257 fmt .Fprintf (writer , " Fallback failed\n " )
13471258 }
1348- } else if result .Result != nil {
1259+ continue
1260+ }
1261+
1262+ if result .Result != nil {
13491263 if result .Result .Passed {
13501264 fmt .Fprintf (writer , " VSA validation passed\n " )
13511265 } else {
@@ -1403,25 +1317,33 @@ func writeOutputToFormats(formatter OutputFormatter, data *validateVSAData, fs a
14031317}
14041318
14051319// createVSAReport creates a report structure from VSA validation results
1406- func createVSAReport (results []vsa.ComponentResult , data * validateVSAData ) * VSAReport {
1320+ func createVSAReport (results []vsa.ComponentResult ) * VSAReport {
14071321 successCount := 0
14081322 failureCount := 0
14091323 fallbackCount := 0
14101324
14111325 for _ , result := range results {
14121326 if result .Error != nil {
14131327 failureCount ++
1414- } else if result .FallbackResult != nil {
1328+ continue
1329+ }
1330+
1331+ if result .FallbackResult != nil {
14151332 fallbackCount ++
14161333 if result .FallbackResult .Component .Success {
14171334 successCount ++
14181335 } else {
14191336 failureCount ++
14201337 }
1421- } else if result .Result != nil && result .Result .Passed {
1422- successCount ++
1423- } else if result .Result != nil && ! result .Result .Passed {
1424- failureCount ++
1338+ continue
1339+ }
1340+
1341+ if result .Result != nil {
1342+ if result .Result .Passed {
1343+ successCount ++
1344+ } else {
1345+ failureCount ++
1346+ }
14251347 }
14261348 }
14271349
0 commit comments