mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-05 20:40:16 -08:00
fix(k8s): show report for --report all (#8613)
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user