diff --git a/pkg/commands/app.go b/pkg/commands/app.go index 7f9937c236..4b93ed4fe1 100644 --- a/pkg/commands/app.go +++ b/pkg/commands/app.go @@ -252,11 +252,11 @@ var ( EnvVars: []string{"TRIVY_POLICY_NAMESPACES"}, } - includeSuccesses = cli.BoolFlag{ - Name: "include-successes", - Usage: "include successes of misconfigurations", + includeNonFailures = cli.BoolFlag{ + Name: "include-non-failures", + Usage: "include successes and exceptions", Value: false, - EnvVars: []string{"TRIVY_INCLUDE_SUCCESSES"}, + EnvVars: []string{"TRIVY_INCLUDE_NON_FAILURES"}, } traceFlag = cli.BoolFlag{ @@ -297,8 +297,6 @@ var ( &cacheBackendFlag, stringSliceFlag(skipFiles), stringSliceFlag(skipDirs), - stringSliceFlag(configPolicy), - stringSliceFlag(policyNamespaces), } // deprecated options @@ -477,7 +475,7 @@ func NewFilesystemCommand() *cli.Command { stringSliceFlag(skipFiles), stringSliceFlag(skipDirs), stringSliceFlag(configPolicy), - &policyNamespaces, + stringSliceFlag(policyNamespaces), }, } } @@ -613,7 +611,7 @@ func NewConfigCommand() *cli.Command { stringSliceFlag(configPolicyAlias), stringSliceFlag(filePatterns), stringSliceFlag(policyNamespaces), - &includeSuccesses, + &includeNonFailures, &traceFlag, }, } diff --git a/pkg/commands/artifact/run.go b/pkg/commands/artifact/run.go index 9d6bb2b42d..00789d4709 100644 --- a/pkg/commands/artifact/run.go +++ b/pkg/commands/artifact/run.go @@ -75,13 +75,13 @@ func runWithTimeout(ctx context.Context, opt Option, initializeScanner Initializ } if err = pkgReport.Write(report, pkgReport.Option{ - Format: opt.Format, - Output: opt.Output, - Severities: opt.Severities, - OutputTemplate: opt.Template, - Light: opt.Light, - IncludeSuccesses: opt.IncludeSuccesses, - Trace: opt.Trace, + Format: opt.Format, + Output: opt.Output, + Severities: opt.Severities, + OutputTemplate: opt.Template, + Light: opt.Light, + IncludeNonFailures: opt.IncludeNonFailures, + Trace: opt.Trace, }); err != nil { return xerrors.Errorf("unable to write results: %w", err) } @@ -193,7 +193,7 @@ func filter(ctx context.Context, opt Option, report pkgReport.Report) (pkgReport for i := range results { resultClient.FillVulnerabilityInfo(results[i].Vulnerabilities, results[i].Type) vulns, misconfSummary, misconfs, err := resultClient.Filter(ctx, results[i].Vulnerabilities, results[i].Misconfigurations, - opt.Severities, opt.IgnoreUnfixed, opt.IncludeSuccesses, opt.IgnoreFile, opt.IgnorePolicy) + opt.Severities, opt.IgnoreUnfixed, opt.IncludeNonFailures, opt.IgnoreFile, opt.IgnorePolicy) if err != nil { return pkgReport.Report{}, xerrors.Errorf("unable to filter vulnerabilities: %w", err) } diff --git a/pkg/commands/client/run.go b/pkg/commands/client/run.go index ddfd062bc2..c2fec18f1a 100644 --- a/pkg/commands/client/run.go +++ b/pkg/commands/client/run.go @@ -71,7 +71,7 @@ func runWithTimeout(ctx context.Context, opt Option) error { results := report.Results for i := range results { vulns, misconfSummary, misconfs, err := resultClient.Filter(ctx, results[i].Vulnerabilities, results[i].Misconfigurations, - opt.Severities, opt.IgnoreUnfixed, opt.IncludeSuccesses, opt.IgnoreFile, opt.IgnorePolicy) + opt.Severities, opt.IgnoreUnfixed, opt.IncludeNonFailures, opt.IgnoreFile, opt.IgnorePolicy) if err != nil { return xerrors.Errorf("filter error: %w", err) } @@ -81,13 +81,13 @@ func runWithTimeout(ctx context.Context, opt Option) error { } if err = pkgReport.Write(report, pkgReport.Option{ - Format: opt.Format, - Output: opt.Output, - Severities: opt.Severities, - OutputTemplate: opt.Template, - Light: false, - IncludeSuccesses: opt.IncludeSuccesses, - Trace: opt.Trace, + Format: opt.Format, + Output: opt.Output, + Severities: opt.Severities, + OutputTemplate: opt.Template, + Light: false, + IncludeNonFailures: opt.IncludeNonFailures, + Trace: opt.Trace, }); err != nil { return xerrors.Errorf("unable to write results: %w", err) } diff --git a/pkg/commands/option/config.go b/pkg/commands/option/config.go index 50a00c1451..d6f27adb52 100644 --- a/pkg/commands/option/config.go +++ b/pkg/commands/option/config.go @@ -6,10 +6,10 @@ import ( // ConfigOption holds the options for config scanning type ConfigOption struct { - FilePatterns []string - IncludeSuccesses bool - SkipPolicyUpdate bool - Trace bool + FilePatterns []string + IncludeNonFailures bool + SkipPolicyUpdate bool + Trace bool // Rego PolicyPaths []string @@ -20,12 +20,12 @@ type ConfigOption struct { // NewConfigOption is the factory method to return config scanning options func NewConfigOption(c *cli.Context) ConfigOption { return ConfigOption{ - IncludeSuccesses: c.Bool("include-successes"), - SkipPolicyUpdate: c.Bool("skip-policy-update"), - Trace: c.Bool("trace"), - FilePatterns: c.StringSlice("file-patterns"), - PolicyPaths: c.StringSlice("config-policy"), - DataPaths: c.StringSlice("config-data"), - PolicyNamespaces: c.StringSlice("policy-namespaces"), + IncludeNonFailures: c.Bool("include-non-failures"), + SkipPolicyUpdate: c.Bool("skip-policy-update"), + Trace: c.Bool("trace"), + FilePatterns: c.StringSlice("file-patterns"), + PolicyPaths: c.StringSlice("config-policy"), + DataPaths: c.StringSlice("config-data"), + PolicyNamespaces: c.StringSlice("policy-namespaces"), } } diff --git a/pkg/report/table.go b/pkg/report/table.go index 5e40ee68b4..0f56a8f06c 100644 --- a/pkg/report/table.go +++ b/pkg/report/table.go @@ -24,8 +24,8 @@ type TableWriter struct { Light bool // For misconfigurations - IncludeSuccesses bool - Trace bool + IncludeNonFailures bool + Trace bool } // Write writes the result on standard output @@ -125,7 +125,7 @@ func (tw TableWriter) writeMisconfigurations(table *tablewriter.Table, misconfs tablewriter.ALIGN_CENTER, tablewriter.ALIGN_CENTER, tablewriter.ALIGN_LEFT} header := []string{"Type", "Misconf ID", "Check", "Severity", "Status", "Message"} - if !tw.IncludeSuccesses { + if !tw.IncludeNonFailures { // Remove status statusPos := 4 alignment = append(alignment[:statusPos], alignment[statusPos+1:]...) @@ -185,20 +185,24 @@ func (tw TableWriter) setMisconfRows(table *tablewriter.Table, misconfs []types. } } - var row []string + severity := misconf.Severity + status := string(misconf.Status) if tw.Output == os.Stdout { - if misconf.Status == types.StatusPassed { - row = []string{misconf.Type, misconf.ID, misconf.Title, color.New(color.FgGreen).Sprint(misconf.Severity), - color.New(color.FgGreen).Sprint(misconf.Status), misconf.Message} - } else { - row = []string{misconf.Type, misconf.ID, misconf.Title, dbTypes.ColorizeSeverity(misconf.Severity), - color.New(color.FgRed).Sprint(misconf.Status), misconf.Message} + switch misconf.Status { + case types.StatusPassed: + severity = color.New(color.FgGreen).Sprint(misconf.Severity) + status = color.New(color.FgGreen).Sprint(misconf.Status) + case types.StatusException: + severity = color.New(color.FgMagenta).Sprint(misconf.Severity) + status = color.New(color.FgMagenta).Sprint(misconf.Status) + case types.StatusFailure: + severity = dbTypes.ColorizeSeverity(severity) + status = color.New(color.FgRed).Sprint(misconf.Status) } - } else { - row = []string{misconf.Type, misconf.ID, misconf.Title, misconf.Severity, string(misconf.Status), misconf.Message} } - if !tw.IncludeSuccesses { + row := []string{misconf.Type, misconf.ID, misconf.Title, severity, status, misconf.Message} + if !tw.IncludeNonFailures { // Remove status row = append(row[:4], row[5:]...) } diff --git a/pkg/report/table_test.go b/pkg/report/table_test.go index 86e9a452df..d8d9a243aa 100644 --- a/pkg/report/table_test.go +++ b/pkg/report/table_test.go @@ -13,11 +13,11 @@ import ( func TestReportWriter_Table(t *testing.T) { testCases := []struct { - name string - results report.Results - expectedOutput string - light bool - includeSuccesses bool + name string + results report.Results + expectedOutput string + light bool + includeNonFailures bool }{ { name: "happy path full", @@ -169,8 +169,8 @@ func TestReportWriter_Table(t *testing.T) { `, }, { - name: "happy path misconfigurations with successes", - includeSuccesses: true, + name: "happy path misconfigurations with successes", + includeNonFailures: true, results: report.Results{ { Target: "test", @@ -216,10 +216,10 @@ func TestReportWriter_Table(t *testing.T) { t.Run(tc.name, func(t *testing.T) { tableWritten := bytes.Buffer{} err := report.Write(report.Report{Results: tc.results}, report.Option{ - Format: "table", - Output: &tableWritten, - Light: tc.light, - IncludeSuccesses: tc.includeSuccesses, + Format: "table", + Output: &tableWritten, + Light: tc.light, + IncludeNonFailures: tc.includeNonFailures, }) assert.NoError(t, err) assert.Equal(t, tc.expectedOutput, tableWritten.String(), tc.name) diff --git a/pkg/report/writer.go b/pkg/report/writer.go index f5fdfff5f0..c352a3cf13 100644 --- a/pkg/report/writer.go +++ b/pkg/report/writer.go @@ -88,8 +88,8 @@ type Option struct { Light bool // For misconfigurations - IncludeSuccesses bool - Trace bool + IncludeNonFailures bool + Trace bool } // Write writes the result to output, format as passed in argument @@ -98,11 +98,11 @@ func Write(report Report, option Option) error { switch option.Format { case "table": writer = &TableWriter{ - Output: option.Output, - Severities: option.Severities, - Light: option.Light, - IncludeSuccesses: option.IncludeSuccesses, - Trace: option.Trace, + Output: option.Output, + Severities: option.Severities, + Light: option.Light, + IncludeNonFailures: option.IncludeNonFailures, + Trace: option.Trace, } case "json": writer = &JSONWriter{Output: option.Output} diff --git a/pkg/result/result.go b/pkg/result/result.go index 9c13419264..c82c5894ec 100644 --- a/pkg/result/result.go +++ b/pkg/result/result.go @@ -140,12 +140,12 @@ func (c Client) getPrimaryURL(vulnID string, refs []string, source string) strin // Filter filter out the vulnerabilities func (c Client) Filter(ctx context.Context, vulns []types.DetectedVulnerability, misconfs []types.DetectedMisconfiguration, - severities []dbTypes.Severity, ignoreUnfixed, includeSuccesses bool, ignoreFile, policyFile string) ( + severities []dbTypes.Severity, ignoreUnfixed, includeNonFailures bool, ignoreFile, policyFile string) ( []types.DetectedVulnerability, *report.MisconfSummary, []types.DetectedMisconfiguration, error) { ignoredIDs := getIgnoredIDs(ignoreFile) filteredVulns := filterVulnerabilities(vulns, severities, ignoreUnfixed, ignoredIDs) - misconfSummary, filteredMisconfs := filterMisconfigurations(misconfs, severities, includeSuccesses, ignoredIDs) + misconfSummary, filteredMisconfs := filterMisconfigurations(misconfs, severities, includeNonFailures, ignoredIDs) if policyFile != "" { var err error @@ -192,7 +192,7 @@ func filterVulnerabilities(vulns []types.DetectedVulnerability, severities []dbT } func filterMisconfigurations(misconfs []types.DetectedMisconfiguration, severities []dbTypes.Severity, - includeSuccesses bool, ignoredIDs []string) (*report.MisconfSummary, []types.DetectedMisconfiguration) { + includeNonFailures bool, ignoredIDs []string) (*report.MisconfSummary, []types.DetectedMisconfiguration) { var filtered []types.DetectedMisconfiguration summary := new(report.MisconfSummary) @@ -204,9 +204,10 @@ func filterMisconfigurations(misconfs []types.DetectedMisconfiguration, severiti continue } + // Count successes, failures, and exceptions summarize(misconf.Status, summary) - if misconf.Status != types.StatusFailure && !includeSuccesses { + if misconf.Status != types.StatusFailure && !includeNonFailures { continue } filtered = append(filtered, misconf)