-
Notifications
You must be signed in to change notification settings - Fork 24
/
cli.go
100 lines (87 loc) · 2.97 KB
/
cli.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
package exporter
import (
"bytes"
"context"
"fmt"
"strings"
"github.com/gookit/color"
"github.com/jetstack/preflight/pkg/packaging"
"github.com/jetstack/preflight/pkg/results"
)
// CLIExporter is an Exporter that outputs a report in Command Line Interface format
type CLIExporter struct {
}
// NewCLIExporter creates a new CLIExporter
func NewCLIExporter() *CLIExporter {
return &CLIExporter{}
}
// Export writes the CLI report to a buffer
func (e *CLIExporter) Export(ctx context.Context, policyManifest *packaging.PolicyManifest, intermediateJSON []byte, results *results.ResultCollection) (*bytes.Buffer, error) {
// formatters
fmtTitle1 := color.New(color.OpBold, color.FgWhite).Render
fmtTitle2 := color.New(color.OpBold, color.FgBlue).Render
fmtTitle3 := color.New(color.OpBold, color.FgBlue).Render
fmtError := color.FgRed.Render
fmtImportant := color.OpBold.Render
fmtConsole := color.New(color.BgGray, color.FgWhite).Render
resultsByID := results.ByID()
writer := bytes.NewBuffer([]byte{})
fmt.Fprintln(writer, "_____")
fmt.Fprintf(writer, "%s - %s\n\n", fmtTitle1(policyManifest.ID), fmtImportant(policyManifest.Name))
fmt.Fprintf(writer, " %s\n", policyManifest.Description)
for _, section := range policyManifest.Sections {
fmt.Fprintf(writer, " %s - %s\n\n", fmtTitle2(section.ID), fmtImportant(section.Name))
fmt.Fprintf(writer, " %s\n", section.Description)
for _, rule := range section.Rules {
icon := color.FgYellow.Sprint("!")
var info interface{}
result := resultsByID[ruleToResult(rule.ID)]
if result != nil {
if result.IsFailureState() {
icon = color.FgRed.Sprint("✗")
} else if result.IsSuccessState() {
icon = color.FgGreen.Sprint("✓")
} else {
icon = color.FgBlue.Sprint("+")
info = result.Value
}
}
fmt.Fprintf(writer, " %s - %s -> %s\n\n", fmtTitle3(rule.ID), fmtImportant(rule.Name), icon)
fmt.Fprintf(writer, " %s\n", rule.Description)
if len(rule.Remediation) > 0 {
fmt.Fprintf(writer, " Remediation: %s", rule.Remediation)
fmt.Fprintln(writer)
}
if len(rule.Links) > 0 {
fmt.Fprintf(writer, " Reference: \n")
for idx, link := range rule.Links {
fmt.Fprintf(writer, " %d: %s \n", idx, link)
}
fmt.Fprintln(writer)
}
if info != nil {
fmt.Fprintln(writer)
fmt.Fprintln(writer, " Information:")
fmt.Fprintf(writer, " %+v\n", fmtConsole(info))
}
fmt.Fprintln(writer)
}
}
failedRules := results.ListFailing()
if len(failedRules) > 0 {
fmt.Fprintln(writer)
fmt.Fprintf(writer, fmtError("%d rules failed: "), len(failedRules))
links := make([]string, len(failedRules))
for idx, f := range failedRules {
id := resultToRule(f.ID)
links[idx] = id
}
fmt.Fprintln(writer, strings.Join(links, ", "))
}
fmt.Fprintln(writer, "_____")
return writer, nil
}
// FileExtension returns the file extension for this exporter's format
func (e *CLIExporter) FileExtension() string {
return ""
}