Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add report summary table #8177

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ trivy config [flags] DIR
--k8s-version string specify k8s version to validate outdated api by it (example: 1.21.0)
--misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
--module-dir string specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
--no-summary hide summary table
-o, --output string output file name
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
--password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
Expand Down
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_convert.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ trivy convert [flags] RESULT_JSON
--ignore-policy string specify the Rego file path to evaluate each vulnerability
--ignorefile string specify .trivyignore file (default ".trivyignore")
--list-all-pkgs output all packages in the JSON report regardless of vulnerability
--no-summary hide summary table
-o, --output string output file name
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
--report string specify a report format for the output (all,summary) (default "all")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ trivy filesystem [flags] PATH
--misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
--module-dir string specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
--no-progress suppress progress bar
--no-summary hide summary table
--offline-scan do not issue API requests to identify dependencies
-o, --output string output file name
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
Expand Down
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_image.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ trivy image [flags] IMAGE_NAME
--misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
--module-dir string specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
--no-progress suppress progress bar
--no-summary hide summary table
--offline-scan do not issue API requests to identify dependencies
-o, --output string output file name
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ trivy kubernetes [flags] [CONTEXT]
--list-all-pkgs output all packages in the JSON report regardless of vulnerability
--misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
--no-progress suppress progress bar
--no-summary hide summary table
--node-collector-imageref string indicate the image reference for the node-collector scan job (default "ghcr.io/aquasecurity/node-collector:0.3.1")
--node-collector-namespace string specify the namespace in which the node-collector job should be deployed (default "trivy-temp")
--offline-scan do not issue API requests to identify dependencies
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ trivy repository [flags] (REPO_PATH | REPO_URL)
--misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
--module-dir string specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
--no-progress suppress progress bar
--no-summary hide summary table
--offline-scan do not issue API requests to identify dependencies
-o, --output string output file name
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
Expand Down
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_rootfs.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ trivy rootfs [flags] ROOTDIR
--misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
--module-dir string specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
--no-progress suppress progress bar
--no-summary hide summary table
--offline-scan do not issue API requests to identify dependencies
-o, --output string output file name
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
Expand Down
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_sbom.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ trivy sbom [flags] SBOM_PATH
--java-db-repository strings OCI repository(ies) to retrieve trivy-java-db in order of priority (default [mirror.gcr.io/aquasec/trivy-java-db:1,ghcr.io/aquasecurity/trivy-java-db:1])
--list-all-pkgs output all packages in the JSON report regardless of vulnerability
--no-progress suppress progress bar
--no-summary hide summary table
--offline-scan do not issue API requests to identify dependencies
-o, --output string output file name
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
Expand Down
1 change: 1 addition & 0 deletions docs/docs/references/configuration/cli/trivy_vm.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ trivy vm [flags] VM_IMAGE
--misconfig-scanners strings comma-separated list of misconfig scanners to use for misconfiguration scanning (default [azure-arm,cloudformation,dockerfile,helm,kubernetes,terraform,terraformplan-json,terraformplan-snapshot])
--module-dir string specify directory to the wasm modules that will be loaded (default "$HOME/.trivy/modules")
--no-progress suppress progress bar
--no-summary hide summary table
--offline-scan do not issue API requests to identify dependencies
-o, --output string output file name
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
Expand Down
3 changes: 3 additions & 0 deletions docs/docs/references/configuration/config-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,9 @@ ignorefile: ".trivyignore"
# Same as '--list-all-pkgs'
list-all-pkgs: false

# Same as '--no-summary'
no-summary: false

# Same as '--output'
output: ""

Expand Down
17 changes: 17 additions & 0 deletions pkg/flag/report_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ var (
ConfigName: "scan.show-suppressed",
Usage: "[EXPERIMENTAL] show suppressed vulnerabilities",
}
NoSummaryFlag = Flag[bool]{
Name: "no-summary",
ConfigName: "no-summary",
Usage: "hide summary table",
}
)

// ReportFlagGroup composes common printer flag structs
Expand All @@ -128,6 +133,7 @@ type ReportFlagGroup struct {
Severity *Flag[[]string]
Compliance *Flag[string]
ShowSuppressed *Flag[bool]
NoSummary *Flag[bool]
}

type ReportOptions struct {
Expand All @@ -145,6 +151,7 @@ type ReportOptions struct {
Severities []dbTypes.Severity
Compliance spec.ComplianceSpec
ShowSuppressed bool
NoSummary bool
}

func NewReportFlagGroup() *ReportFlagGroup {
Expand All @@ -163,6 +170,7 @@ func NewReportFlagGroup() *ReportFlagGroup {
Severity: SeverityFlag.Clone(),
Compliance: ComplianceFlag.Clone(),
ShowSuppressed: ShowSuppressedFlag.Clone(),
NoSummary: NoSummaryFlag.Clone(),
}
}

Expand All @@ -186,6 +194,7 @@ func (f *ReportFlagGroup) Flags() []Flagger {
f.Severity,
f.Compliance,
f.ShowSuppressed,
f.NoSummary,
}
}

Expand All @@ -198,6 +207,7 @@ func (f *ReportFlagGroup) ToOptions() (ReportOptions, error) {
template := f.Template.Value()
dependencyTree := f.DependencyTree.Value()
listAllPkgs := f.ListAllPkgs.Value()
noSummary := f.NoSummary.Value()

if template != "" {
if format == "" {
Expand Down Expand Up @@ -227,6 +237,12 @@ func (f *ReportFlagGroup) ToOptions() (ReportOptions, error) {
}
}

// "--so-summary" option is available only with "--format table".
if noSummary && format != types.FormatTable {
noSummary = false
log.Warn(`"--no-summary" can be used only with "--format table".`)
}

cs, err := loadComplianceTypes(f.Compliance.Value())
if err != nil {
return ReportOptions{}, xerrors.Errorf("unable to load compliance spec: %w", err)
Expand Down Expand Up @@ -259,6 +275,7 @@ func (f *ReportFlagGroup) ToOptions() (ReportOptions, error) {
Severities: toSeverity(f.Severity.Value()),
Compliance: cs,
ShowSuppressed: f.ShowSuppressed.Value(),
NoSummary: noSummary,
}, nil
}

Expand Down
17 changes: 17 additions & 0 deletions pkg/flag/report_flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func TestReportFlagGroup_ToOptions(t *testing.T) {
compliance string
debug bool
pkgTypes string
noSummary bool
}
tests := []struct {
name string
Expand Down Expand Up @@ -115,6 +116,20 @@ func TestReportFlagGroup_ToOptions(t *testing.T) {
ListAllPkgs: true,
},
},
{
name: "invalid option combination: --no-summary with --format json",
fields: fields{
format: "json",
noSummary: true,
},
wantLogs: []string{
`"--no-summary" can be used only with "--format table".`,
},
want: flag.ReportOptions{
Format: "json",
NoSummary: false,
},
},
{
name: "happy path with output plugin args",
fields: fields{
Expand Down Expand Up @@ -184,6 +199,7 @@ func TestReportFlagGroup_ToOptions(t *testing.T) {
setValue(flag.OutputPluginArgFlag.ConfigName, tt.fields.outputPluginArgs)
setValue(flag.SeverityFlag.ConfigName, tt.fields.severities)
setValue(flag.ComplianceFlag.ConfigName, tt.fields.compliance)
setValue(flag.NoSummaryFlag.ConfigName, tt.fields.noSummary)

// Assert options
f := &flag.ReportFlagGroup{
Expand All @@ -199,6 +215,7 @@ func TestReportFlagGroup_ToOptions(t *testing.T) {
OutputPluginArg: flag.OutputPluginArgFlag.Clone(),
Severity: flag.SeverityFlag.Clone(),
Compliance: flag.ComplianceFlag.Clone(),
NoSummary: flag.NoSummaryFlag.Clone(),
}

got, err := f.ToOptions()
Expand Down
86 changes: 86 additions & 0 deletions pkg/report/table/summary.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package table

import (
"github.com/aquasecurity/table"
"github.com/aquasecurity/trivy/pkg/types"
)

type Scanner interface {
Header() string
Alignment() table.Alignment

// Count returns the number of findings, but -1 if the scanner is not applicable
Count(result types.Result) int
}

func NewScanner(scanner types.Scanner) Scanner {
switch scanner {
case types.VulnerabilityScanner:
return VulnerabilityScanner{}
case types.MisconfigScanner:
return MisconfigScanner{}
case types.SecretScanner:
return SecretScanner{}
case types.LicenseScanner:
return LicenseScanner{}
}
return nil
}

type scannerAlignment struct{}

func (s scannerAlignment) Alignment() table.Alignment {
return table.AlignCenter
}

type VulnerabilityScanner struct{ scannerAlignment }

func (s VulnerabilityScanner) Header() string {
return "Vulnerabilities"
}

func (s VulnerabilityScanner) Count(result types.Result) int {
if result.Class == types.ClassOSPkg || result.Class == types.ClassLangPkg {
return len(result.Vulnerabilities)
}
return -1
}

type MisconfigScanner struct{ scannerAlignment }

func (s MisconfigScanner) Header() string {
return "Misconfigurations"
}

func (s MisconfigScanner) Count(result types.Result) int {
if result.Class == types.ClassConfig {
return len(result.Misconfigurations)
}
return -1
}

type SecretScanner struct{ scannerAlignment }

func (s SecretScanner) Header() string {
return "Secrets"
}

func (s SecretScanner) Count(result types.Result) int {
if result.Class == types.ClassSecret {
return len(result.Secrets)
}
return -1
}

type LicenseScanner struct{ scannerAlignment }

func (s LicenseScanner) Header() string {
return "Licenses"
}

func (s LicenseScanner) Count(result types.Result) int {
if result.Class == types.ClassLicense {
return len(result.Licenses)
}
return -1
}
Loading
Loading