fix(k8s): show report for --report all (#8613)

This commit is contained in:
DmitriyLewen
2025-03-27 12:01:50 +06:00
committed by GitHub
parent 548a340075
commit dbb6f28871
2 changed files with 137 additions and 12 deletions

View File

@@ -10,6 +10,7 @@ import (
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
pkgReport "github.com/aquasecurity/trivy/pkg/report/table"
"github.com/aquasecurity/trivy/pkg/types"
)
type TableWriter struct {
@@ -17,6 +18,8 @@ type TableWriter struct {
Output io.Writer
Severities []dbTypes.Severity
ColumnHeading []string
TableMode []types.TableMode // For `--report all` only
}
const (
@@ -54,6 +57,10 @@ func (tw TableWriter) Write(ctx context.Context, report Report) error {
t := pkgReport.NewWriter(pkgReport.Options{
Output: tw.Output,
Severities: tw.Severities,
// k8s has its own summary report, so we only need to show the detailed tables here
TableModes: []types.TableMode{
types.Detailed,
},
})
for i, r := range report.Resources {
if r.Report.Results.Failed() {

View File

@@ -14,15 +14,6 @@ import (
"github.com/aquasecurity/trivy/pkg/types"
)
const (
AllReport = "all"
SummaryReport = "summary"
tableFormat = "table"
jsonFormat = "json"
cycloneDXFormat = "cyclonedx"
)
var (
roleWithMisconfig = report.Resource{
Namespace: "default",
@@ -142,6 +133,44 @@ var (
},
},
}
deployOrionWithSingleMisconfig = report.Resource{
Namespace: "default",
Kind: "Deploy",
Name: "orion",
Results: types.Results{
{
Misconfigurations: []types.DetectedMisconfiguration{
{
ID: "ID100",
Status: types.MisconfStatusFailure,
Severity: "LOW",
},
},
},
},
Report: types.Report{
Results: types.Results{
{
Class: types.ClassConfig,
MisconfSummary: &types.MisconfSummary{
Successes: 0,
Failures: 1,
},
Misconfigurations: []types.DetectedMisconfiguration{
{
ID: "ID100",
Title: "Config file is bad",
Description: "Your config file is not good.",
Message: "Oh no, a bad config.",
PrimaryURL: "https://google.com/search?q=bad%20config",
Status: types.MisconfStatusFailure,
Severity: "LOW",
},
},
},
},
},
}
deployOrionWithVulns = report.Resource{
Namespace: "default",
Kind: "Deploy",
@@ -181,9 +210,43 @@ var (
},
},
}
deployOrionWithSingleVuln = report.Resource{
Namespace: "default",
Kind: "Deploy",
Name: "orion",
Results: types.Results{
{
Vulnerabilities: []types.DetectedVulnerability{
{
PkgID: "foo/bar@v0.0.1",
VulnerabilityID: "CVE-2022-1111",
Vulnerability: dbTypes.Vulnerability{Severity: "LOW"},
},
},
},
},
Report: types.Report{
Results: types.Results{
{
Class: types.ClassLangPkg,
Vulnerabilities: []types.DetectedVulnerability{
{
PkgName: "foo/bar",
VulnerabilityID: "CVE-2022-1111",
InstalledVersion: "v0.0.1",
FixedVersion: "v0.0.2",
PrimaryURL: "https://avd.aquasec.com/nvd/cve-2022-1111",
Vulnerability: dbTypes.Vulnerability{Severity: "LOW"},
},
},
},
},
},
}
)
func TestReportWrite_Summary(t *testing.T) {
func TestReportWrite_Table(t *testing.T) {
allSeverities := []dbTypes.Severity{
dbTypes.SeverityUnknown,
dbTypes.SeverityLow,
@@ -198,6 +261,7 @@ func TestReportWrite_Summary(t *testing.T) {
opt report.Option
scanners types.Scanners
severities []dbTypes.Severity
reportType string
expectedOutput string
}{
{
@@ -208,6 +272,7 @@ func TestReportWrite_Summary(t *testing.T) {
},
scanners: types.Scanners{types.MisconfigScanner},
severities: allSeverities,
reportType: report.SummaryReport,
expectedOutput: `Summary Report for test
=======================
@@ -229,6 +294,29 @@ Infra Assessment
│ │ │ C │ H │ M │ L │ U │
└───────────┴──────────┴───┴───┴───┴───┴───┘
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
},
{
name: "Single misconfig with `--report all`",
report: report.Report{
ClusterName: "test",
Resources: []report.Resource{deployOrionWithSingleMisconfig},
},
scanners: types.Scanners{types.MisconfigScanner},
severities: []dbTypes.Severity{
dbTypes.SeverityCritical,
},
reportType: report.AllReport,
expectedOutput: `namespace: default, deploy: orion ()
====================================
Tests: 1 (SUCCESSES: 0, FAILURES: 1)
Failures: 0 (CRITICAL: 0)
(LOW): Oh no, a bad config.
════════════════════════════════════════
Your config file is not good.
See https://google.com/search?q=bad%20config
────────────────────────────────────────`,
},
{
name: "Only vuln, all serverities",
@@ -238,6 +326,7 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
},
scanners: types.Scanners{types.VulnerabilityScanner},
severities: allSeverities,
reportType: report.SummaryReport,
expectedOutput: `Summary Report for test
=======================
@@ -259,6 +348,27 @@ Infra Assessment
│ │ │ C │ H │ M │ L │ U │
└───────────┴──────────┴───┴───┴───┴───┴───┘
Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
},
{
name: "Single vuln with `--report all`",
report: report.Report{
ClusterName: "test",
Resources: []report.Resource{deployOrionWithSingleVuln},
},
scanners: types.Scanners{types.VulnerabilityScanner},
severities: []dbTypes.Severity{
dbTypes.SeverityLow,
},
reportType: report.AllReport,
expectedOutput: `namespace: default, deploy: orion ()
====================================
Total: 1 (LOW: 1)
┌─────────┬───────────────┬──────────┬─────────┬───────────────────┬───────────────┬───────────────────────────────────────────┐
│ Library │ Vulnerability │ Severity │ Status │ Installed Version │ Fixed Version │ Title │
├─────────┼───────────────┼──────────┼─────────┼───────────────────┼───────────────┼───────────────────────────────────────────┤
│ foo/bar │ CVE-2022-1111 │ LOW │ unknown │ v0.0.1 │ v0.0.2 │ https://avd.aquasec.com/nvd/cve-2022-1111 │
└─────────┴───────────────┴──────────┴─────────┴───────────────────┴───────────────┴───────────────────────────────────────────┘`,
},
{
name: "Only rbac, all serverities",
@@ -268,6 +378,7 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
},
scanners: types.Scanners{types.RBACScanner},
severities: allSeverities,
reportType: report.SummaryReport,
expectedOutput: `Summary Report for test
=======================
@@ -289,6 +400,7 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
},
scanners: types.Scanners{types.SecretScanner},
severities: allSeverities,
reportType: report.SummaryReport,
expectedOutput: `Summary Report for test
=======================
@@ -319,6 +431,7 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
},
scanners: types.Scanners{types.MisconfigScanner},
severities: allSeverities,
reportType: report.SummaryReport,
expectedOutput: `Summary Report for test
=======================
@@ -353,6 +466,7 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
types.SecretScanner,
},
severities: allSeverities,
reportType: report.SummaryReport,
expectedOutput: `Summary Report for test
=======================
@@ -386,6 +500,7 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
types.VulnerabilityScanner,
},
severities: allSeverities,
reportType: report.SummaryReport,
expectedOutput: `Summary Report for test
=======================
@@ -412,11 +527,12 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
t.Setenv("TRIVY_DISABLE_VEX_NOTICE", "true")
output := bytes.Buffer{}
opt := report.Option{
Format: "table",
Report: "summary",
Report: tc.reportType,
Output: &output,
Scanners: tc.scanners,
Severities: tc.severities,
@@ -424,7 +540,9 @@ Severities: C=CRITICAL H=HIGH M=MEDIUM L=LOW U=UNKNOWN`,
err := Write(t.Context(), tc.report, opt)
require.NoError(t, err)
assert.Equal(t, tc.expectedOutput, stripAnsi(output.String()), tc.name)
got := stripAnsi(output.String())
got = strings.ReplaceAll(got, "\r\n", "\n")
assert.Equal(t, tc.expectedOutput, got, tc.name)
})
}
}