Skip to content

Commit 3d3a3d6

Browse files
authored
refactor(report): write tables after rendering all results (aquasecurity#8357)
1 parent 036ab75 commit 3d3a3d6

File tree

12 files changed

+238
-215
lines changed

12 files changed

+238
-215
lines changed

pkg/compliance/report/table.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ const (
2929
func (tw TableWriter) Write(ctx context.Context, report *ComplianceReport) error {
3030
switch tw.Report {
3131
case allReport:
32-
t := pkgReport.Writer{
32+
t := pkgReport.NewWriter(pkgReport.Options{
3333
Output: tw.Output,
3434
Severities: tw.Severities,
35-
}
35+
})
3636
for _, cr := range report.Results {
3737
r := types.Report{Results: cr.Results}
3838
err := t.Write(ctx, r)

pkg/k8s/report/table.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ func InfraColumns() []string {
5151
func (tw TableWriter) Write(ctx context.Context, report Report) error {
5252
switch tw.Report {
5353
case AllReport:
54-
t := pkgReport.Writer{
54+
t := pkgReport.NewWriter(pkgReport.Options{
5555
Output: tw.Output,
5656
Severities: tw.Severities,
57-
}
57+
})
5858
for i, r := range report.Resources {
5959
if r.Report.Results.Failed() {
6060
updateTargetContext(&report.Resources[i])

pkg/report/table/licensing.go

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20,46 +20,43 @@ import (
2020
type pkgLicenseRenderer struct {
2121
w *bytes.Buffer
2222
tableWriter *table.Table
23-
result types.Result
2423
isTerminal bool
2524
severities []dbTypes.Severity
2625
once *sync.Once
2726
}
2827

29-
func NewPkgLicenseRenderer(result types.Result, isTerminal bool, severities []dbTypes.Severity) pkgLicenseRenderer {
30-
buf := bytes.NewBuffer([]byte{})
31-
return pkgLicenseRenderer{
28+
func NewPkgLicenseRenderer(buf *bytes.Buffer, isTerminal bool, severities []dbTypes.Severity) *pkgLicenseRenderer {
29+
return &pkgLicenseRenderer{
3230
w: buf,
3331
tableWriter: newTableWriter(buf, isTerminal),
34-
result: result,
3532
isTerminal: isTerminal,
3633
severities: severities,
3734
once: new(sync.Once),
3835
}
3936
}
4037

41-
func (r pkgLicenseRenderer) Render() string {
38+
func (r *pkgLicenseRenderer) Render(result types.Result) {
4239
// Trivy doesn't currently support showing suppressed licenses
4340
// So just skip this result
44-
if len(r.result.Licenses) == 0 {
45-
return ""
41+
if len(result.Licenses) == 0 {
42+
return
4643
}
4744

4845
r.setHeaders()
49-
r.setRows()
46+
r.setRows(result.Licenses)
5047

51-
total, summaries := summarize(r.severities, r.countSeverities())
48+
total, summaries := summarize(r.severities, r.countSeverities(result.Licenses))
5249

53-
target := r.result.Target + " (license)"
50+
target := result.Target + " (license)"
5451
RenderTarget(r.w, target, r.isTerminal)
5552
r.printf("Total: %d (%s)\n\n", total, strings.Join(summaries, ", "))
5653

5754
r.tableWriter.Render()
5855

59-
return r.w.String()
56+
return
6057
}
6158

62-
func (r pkgLicenseRenderer) setHeaders() {
59+
func (r *pkgLicenseRenderer) setHeaders() {
6360
header := []string{
6461
"Package",
6562
"License",
@@ -69,8 +66,8 @@ func (r pkgLicenseRenderer) setHeaders() {
6966
r.tableWriter.SetHeaders(header...)
7067
}
7168

72-
func (r pkgLicenseRenderer) setRows() {
73-
for _, l := range r.result.Licenses {
69+
func (r *pkgLicenseRenderer) setRows(licenses []types.DetectedLicense) {
70+
for _, l := range licenses {
7471
var row []string
7572
if r.isTerminal {
7673
row = []string{
@@ -91,9 +88,9 @@ func (r pkgLicenseRenderer) setRows() {
9188
}
9289
}
9390

94-
func (r pkgLicenseRenderer) countSeverities() map[string]int {
91+
func (r *pkgLicenseRenderer) countSeverities(licenses []types.DetectedLicense) map[string]int {
9592
severityCount := make(map[string]int)
96-
for _, l := range r.result.Licenses {
93+
for _, l := range licenses {
9794
severityCount[l.Severity]++
9895
}
9996
return severityCount
@@ -107,46 +104,43 @@ func (r *pkgLicenseRenderer) printf(format string, args ...any) {
107104
type fileLicenseRenderer struct {
108105
w *bytes.Buffer
109106
tableWriter *table.Table
110-
result types.Result
111107
isTerminal bool
112108
severities []dbTypes.Severity
113109
once *sync.Once
114110
}
115111

116-
func NewFileLicenseRenderer(result types.Result, isTerminal bool, severities []dbTypes.Severity) fileLicenseRenderer {
117-
buf := bytes.NewBuffer([]byte{})
118-
return fileLicenseRenderer{
112+
func NewFileLicenseRenderer(buf *bytes.Buffer, isTerminal bool, severities []dbTypes.Severity) *fileLicenseRenderer {
113+
return &fileLicenseRenderer{
119114
w: buf,
120115
tableWriter: newTableWriter(buf, isTerminal),
121-
result: result,
122116
isTerminal: isTerminal,
123117
severities: severities,
124118
once: new(sync.Once),
125119
}
126120
}
127121

128-
func (r fileLicenseRenderer) Render() string {
122+
func (r *fileLicenseRenderer) Render(result types.Result) {
129123
// Trivy doesn't currently support showing suppressed licenses
130124
// So just skip this result
131-
if len(r.result.Licenses) == 0 {
132-
return ""
125+
if len(result.Licenses) == 0 {
126+
return
133127
}
134128

135129
r.setHeaders()
136-
r.setRows()
130+
r.setRows(result.Licenses)
137131

138-
total, summaries := summarize(r.severities, r.countSeverities())
132+
total, summaries := summarize(r.severities, r.countSeverities(result.Licenses))
139133

140-
target := r.result.Target + " (license)"
134+
target := result.Target + " (license)"
141135
RenderTarget(r.w, target, r.isTerminal)
142136
r.printf("Total: %d (%s)\n\n", total, strings.Join(summaries, ", "))
143137

144138
r.tableWriter.Render()
145139

146-
return r.w.String()
140+
return
147141
}
148142

149-
func (r fileLicenseRenderer) setHeaders() {
143+
func (r *fileLicenseRenderer) setHeaders() {
150144
header := []string{
151145
"Classification",
152146
"Severity",
@@ -156,10 +150,10 @@ func (r fileLicenseRenderer) setHeaders() {
156150
r.tableWriter.SetHeaders(header...)
157151
}
158152

159-
func (r fileLicenseRenderer) setRows() {
160-
sort.Slice(r.result.Licenses, func(i, j int) bool {
161-
a := r.result.Licenses[i]
162-
b := r.result.Licenses[j]
153+
func (r *fileLicenseRenderer) setRows(licenses []types.DetectedLicense) {
154+
sort.Slice(licenses, func(i, j int) bool {
155+
a := licenses[i]
156+
b := licenses[j]
163157
if a.Severity != b.Severity {
164158
return 0 < dbTypes.CompareSeverityString(b.Severity, a.Severity)
165159
}
@@ -172,7 +166,7 @@ func (r fileLicenseRenderer) setRows() {
172166
return a.FilePath < b.FilePath
173167
})
174168

175-
for _, l := range r.result.Licenses {
169+
for _, l := range licenses {
176170
var row []string
177171
if r.isTerminal {
178172
row = []string{
@@ -193,9 +187,9 @@ func (r fileLicenseRenderer) setRows() {
193187
}
194188
}
195189

196-
func (r fileLicenseRenderer) countSeverities() map[string]int {
190+
func (r *fileLicenseRenderer) countSeverities(licenses []types.DetectedLicense) map[string]int {
197191
severityCount := make(map[string]int)
198-
for _, l := range r.result.Licenses {
192+
for _, l := range licenses {
199193
severityCount[l.Severity]++
200194
}
201195
return severityCount

pkg/report/table/misconfig.go

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ const (
2525

2626
type misconfigRenderer struct {
2727
w *bytes.Buffer
28-
result types.Result
2928
severities []dbTypes.Severity
3029
trace bool
3130
includeNonFailures bool
@@ -34,7 +33,7 @@ type misconfigRenderer struct {
3433
renderCause []ftypes.ConfigType
3534
}
3635

37-
func NewMisconfigRenderer(result types.Result, severities []dbTypes.Severity, trace, includeNonFailures, ansi bool, renderCause []ftypes.ConfigType) *misconfigRenderer {
36+
func NewMisconfigRenderer(buf *bytes.Buffer, severities []dbTypes.Severity, trace, includeNonFailures, ansi bool, renderCause []ftypes.ConfigType) *misconfigRenderer {
3837
width, _, err := term.GetSize(0)
3938
if err != nil || width == 0 {
4039
width = 40
@@ -44,8 +43,7 @@ func NewMisconfigRenderer(result types.Result, severities []dbTypes.Severity, tr
4443
}
4544

4645
return &misconfigRenderer{
47-
w: bytes.NewBuffer([]byte{}),
48-
result: result,
46+
w: buf,
4947
severities: severities,
5048
trace: trace,
5149
includeNonFailures: includeNonFailures,
@@ -55,36 +53,36 @@ func NewMisconfigRenderer(result types.Result, severities []dbTypes.Severity, tr
5553
}
5654
}
5755

58-
func (r *misconfigRenderer) Render() string {
56+
func (r *misconfigRenderer) Render(result types.Result) {
5957
// Trivy doesn't currently support showing suppressed misconfigs
6058
// So just skip this result
61-
if len(r.result.Misconfigurations) == 0 {
62-
return ""
59+
if len(result.Misconfigurations) == 0 {
60+
return
6361
}
64-
target := fmt.Sprintf("%s (%s)", r.result.Target, r.result.Type)
62+
target := fmt.Sprintf("%s (%s)", result.Target, result.Type)
6563
RenderTarget(r.w, target, r.ansi)
6664

67-
total, summaries := summarize(r.severities, r.countSeverities())
65+
total, summaries := summarize(r.severities, r.countSeverities(result.Misconfigurations))
6866

69-
summary := r.result.MisconfSummary
67+
summary := result.MisconfSummary
7068
r.printf("Tests: %d (SUCCESSES: %d, FAILURES: %d)\n",
7169
summary.Successes+summary.Failures, summary.Successes, summary.Failures)
7270
r.printf("Failures: %d (%s)\n\n", total, strings.Join(summaries, ", "))
7371

74-
for _, m := range r.result.Misconfigurations {
75-
r.renderSingle(m)
72+
for _, m := range result.Misconfigurations {
73+
r.renderSingle(result.Target, result.Type, m)
7674
}
7775

7876
// For debugging
7977
if r.trace {
80-
r.outputTrace()
78+
r.outputTrace(result.Target, result.Misconfigurations)
8179
}
82-
return r.w.String()
80+
return
8381
}
8482

85-
func (r *misconfigRenderer) countSeverities() map[string]int {
83+
func (r *misconfigRenderer) countSeverities(misconfigs []types.DetectedMisconfiguration) map[string]int {
8684
severityCount := make(map[string]int)
87-
for _, misconf := range r.result.Misconfigurations {
85+
for _, misconf := range misconfigs {
8886
if misconf.Status == types.MisconfStatusFailure {
8987
severityCount[misconf.Severity]++
9088
}
@@ -110,10 +108,10 @@ func (r *misconfigRenderer) printSingleDivider() {
110108
r.printf("<dim>%s\r\n", strings.Repeat("─", r.width))
111109
}
112110

113-
func (r *misconfigRenderer) renderSingle(misconf types.DetectedMisconfiguration) {
111+
func (r *misconfigRenderer) renderSingle(target string, typ ftypes.TargetType, misconf types.DetectedMisconfiguration) {
114112
r.renderSummary(misconf)
115-
r.renderCode(misconf)
116-
r.renderMisconfCause(misconf)
113+
r.renderCode(target, misconf)
114+
r.renderMisconfCause(typ, misconf)
117115
r.printf("\r\n\r\n")
118116
}
119117

@@ -160,7 +158,7 @@ func (r *misconfigRenderer) renderSummary(misconf types.DetectedMisconfiguration
160158
r.printSingleDivider()
161159
}
162160

163-
func (r *misconfigRenderer) renderCode(misconf types.DetectedMisconfiguration) {
161+
func (r *misconfigRenderer) renderCode(target string, misconf types.DetectedMisconfiguration) {
164162
// highlight code if we can...
165163
if lines := misconf.CauseMetadata.Code.Lines; len(lines) > 0 {
166164

@@ -171,7 +169,7 @@ func (r *misconfigRenderer) renderCode(misconf types.DetectedMisconfiguration) {
171169
lineInfo = tml.Sprintf("%s<blue>-%d", lineInfo, misconf.CauseMetadata.EndLine)
172170
}
173171
}
174-
r.printf(" <blue>%s%s\r\n", r.result.Target, lineInfo)
172+
r.printf(" <blue>%s%s\r\n", target, lineInfo)
175173
for i, occ := range misconf.CauseMetadata.Occurrences {
176174
lineInfo := fmt.Sprintf("%d-%d", occ.Location.StartLine, occ.Location.EndLine)
177175
if occ.Location.StartLine >= occ.Location.EndLine {
@@ -218,8 +216,8 @@ func (r *misconfigRenderer) renderCode(misconf types.DetectedMisconfiguration) {
218216
}
219217
}
220218

221-
func (r *misconfigRenderer) renderMisconfCause(misconf types.DetectedMisconfiguration) {
222-
if !slices.Contains(r.renderCause, r.result.Type) {
219+
func (r *misconfigRenderer) renderMisconfCause(typ ftypes.TargetType, misconf types.DetectedMisconfiguration) {
220+
if !slices.Contains(r.renderCause, typ) {
223221
return
224222
}
225223

@@ -239,12 +237,12 @@ func (r *misconfigRenderer) renderMisconfCause(misconf types.DetectedMisconfigur
239237
r.printSingleDivider()
240238
}
241239

242-
func (r *misconfigRenderer) outputTrace() {
240+
func (r *misconfigRenderer) outputTrace(target string, misconfigs []types.DetectedMisconfiguration) {
243241
blue := color.New(color.FgBlue).SprintFunc()
244242
green := color.New(color.FgGreen).SprintfFunc()
245243
red := color.New(color.FgRed).SprintfFunc()
246244

247-
for _, misconf := range r.result.Misconfigurations {
245+
for _, misconf := range misconfigs {
248246
if len(misconf.Traces) == 0 {
249247
continue
250248
}
@@ -255,7 +253,7 @@ func (r *misconfigRenderer) outputTrace() {
255253
}
256254

257255
r.println(c("\nID: %s", misconf.ID))
258-
r.println(c("File: %s", r.result.Target))
256+
r.println(c("File: %s", target))
259257
r.println(c("Namespace: %s", misconf.Namespace))
260258
r.println(c("Query: %s", misconf.Query))
261259
r.println(c("Message: %s", misconf.Message))

pkg/report/table/misconfig_test.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package table_test
22

33
import (
4+
"bytes"
45
"strings"
56
"testing"
67

@@ -13,12 +14,10 @@ import (
1314
)
1415

1516
func TestMisconfigRenderer(t *testing.T) {
16-
1717
type args struct {
1818
includeNonFailures bool
1919
renderCause []ftypes.ConfigType
2020
}
21-
2221
tests := []struct {
2322
name string
2423
input types.Result
@@ -450,12 +449,16 @@ resource "aws_s3_bucket" "this" {
450449
},
451450
}
452451

453-
for _, test := range tests {
454-
t.Run(test.name, func(t *testing.T) {
455-
severities := []dbTypes.Severity{dbTypes.SeverityLow, dbTypes.SeverityMedium, dbTypes.SeverityHigh,
456-
dbTypes.SeverityCritical}
457-
renderer := table.NewMisconfigRenderer(test.input, severities, false, test.args.includeNonFailures, false, test.args.renderCause)
458-
assert.Equal(t, test.want, strings.ReplaceAll(renderer.Render(), "\r\n", "\n"))
452+
for _, tt := range tests {
453+
t.Run(tt.name, func(t *testing.T) {
454+
severities := []dbTypes.Severity{
455+
dbTypes.SeverityLow, dbTypes.SeverityMedium, dbTypes.SeverityHigh,
456+
dbTypes.SeverityCritical,
457+
}
458+
buf := bytes.NewBuffer([]byte{})
459+
renderer := table.NewMisconfigRenderer(buf, severities, false, tt.args.includeNonFailures, false, tt.args.renderCause)
460+
renderer.Render(tt.input)
461+
assert.Equal(t, tt.want, strings.ReplaceAll(buf.String(), "\r\n", "\n"))
459462
})
460463
}
461464
}

0 commit comments

Comments
 (0)