-
Notifications
You must be signed in to change notification settings - Fork 2
/
summary.go
111 lines (97 loc) · 2.34 KB
/
summary.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package report
import (
"fmt"
"io"
"strconv"
"strings"
"github.com/samber/lo"
"golang.org/x/xerrors"
"github.com/khulnasoft-lab/table"
)
func BuildSummary(cr *ComplianceReport) *SummaryReport {
var ccma []ControlCheckSummary
for _, control := range cr.Results {
ccm := ControlCheckSummary{
ID: control.ID,
Name: control.Name,
Severity: control.Severity,
}
if !strings.Contains(control.Name, "Manual") {
ccm.TotalFail = lo.ToPtr(len(control.Results))
}
ccma = append(ccma, ccm)
}
return &SummaryReport{
ID: cr.ID,
Title: cr.Title,
SummaryControls: ccma,
}
}
type SummaryWriter struct {
Output io.Writer
}
func NewSummaryWriter(output io.Writer) SummaryWriter {
return SummaryWriter{
Output: output,
}
}
// Write writes the results in a summarized table format
func (s SummaryWriter) Write(report *ComplianceReport) error {
if _, err := fmt.Fprintln(s.Output); err != nil {
return xerrors.Errorf("failed to write summary report: %w", err)
}
if _, err := fmt.Fprintf(s.Output, "Summary Report for compliance: %s\n", report.Title); err != nil {
return xerrors.Errorf("failed to write summary report: %w", err)
}
sr := BuildSummary(report)
t := table.New(s.Output)
t.SetRowLines(false)
configureHeader(t, s.columns())
for _, summaryControl := range sr.SummaryControls {
rowParts := s.generateSummary(summaryControl)
t.AddRow(rowParts...)
}
t.Render()
return nil
}
func (s SummaryWriter) columns() []string {
return []string{
ControlIDColumn,
SeverityColumn,
ControlNameColumn,
StatusColumn,
IssuesColumn,
}
}
func (s SummaryWriter) generateSummary(summaryControls ControlCheckSummary) []string {
// "-" means manual checks
numOfIssues := "-"
status := "-"
if summaryControls.TotalFail != nil {
if *summaryControls.TotalFail == 0 {
status = "PASS"
} else {
status = "FAIL"
}
numOfIssues = strconv.Itoa(*summaryControls.TotalFail)
}
return []string{
summaryControls.ID,
summaryControls.Severity,
summaryControls.Name,
status,
numOfIssues,
}
}
func configureHeader(t *table.Table, columnHeading []string) {
headerAlignment := []table.Alignment{
table.AlignLeft,
table.AlignCenter,
table.AlignLeft,
table.AlignCenter,
table.AlignCenter,
}
t.SetHeaders(columnHeading...)
t.SetAlignment(headerAlignment...)
t.SetAutoMergeHeaders(true)
}