-
Notifications
You must be signed in to change notification settings - Fork 262
/
control.go
132 lines (115 loc) · 3.79 KB
/
control.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package controldisplay
import (
"fmt"
"strings"
"github.com/spf13/viper"
typehelpers "github.com/turbot/go-kit/types"
"github.com/turbot/steampipe/pkg/constants"
"github.com/turbot/steampipe/pkg/control/controlexecute"
)
type ControlRenderer struct {
run *controlexecute.ControlRun
parent *GroupRenderer
maxFailedControls int
maxTotalControls int
// screen width
width int
colorGenerator *controlexecute.DimensionColorGenerator
lastChild bool
}
func NewControlRenderer(run *controlexecute.ControlRun, parent *GroupRenderer) *ControlRenderer {
r := &ControlRenderer{
run: run,
parent: parent,
maxFailedControls: parent.maxFailedControls,
maxTotalControls: parent.maxTotalControls,
colorGenerator: parent.resultTree.DimensionColorGenerator,
width: parent.width,
}
r.lastChild = r.isLastChild()
return r
}
// are we the last child of our parent?
// this affects the tree rendering
func (r ControlRenderer) isLastChild() bool {
if r.parent.group == nil || r.parent.group.GroupItem == nil {
return true
}
siblings := r.parent.group.GroupItem.GetChildren()
return r.run.Control.Name() == siblings[len(siblings)-1].Name()
}
// get the indent inherited from our parent
// - this will depend on whether we are our parents last child
func (r ControlRenderer) parentIndent() string {
if r.lastChild {
return r.parent.lastChildIndent()
}
return r.parent.childIndent()
}
// indent before first result
func (r ControlRenderer) preResultIndent() string {
// when we do not have any rows, do not add a '|' to indent
if viper.GetBool(constants.ArgDryRun) || len(r.run.Rows) == 0 {
return r.parentIndent()
}
return r.parentIndent() + "| "
}
// indent before first result
func (r ControlRenderer) resultIndent() string {
return r.parentIndent()
}
// indent after last result
func (r ControlRenderer) postResultIndent() string {
return r.parentIndent()
}
func (r ControlRenderer) Render() string {
var controlStrings []string
// use group heading renderer to render the control title and counts
controlHeadingRenderer := NewGroupHeadingRenderer(typehelpers.SafeString(r.run.Control.Title),
r.run.Summary.FailedCount(),
r.run.Summary.TotalCount(),
r.maxFailedControls,
r.maxTotalControls,
r.width,
r.parent.childGroupIndent())
// set the severity on the heading renderer
controlHeadingRenderer.severity = typehelpers.SafeString(r.run.Control.Severity)
// get formatted indents
formattedPostResultIndent := fmt.Sprintf("%s", ControlColors.Indent(r.postResultIndent()))
formattedPreResultIndent := fmt.Sprintf("%s", ControlColors.Indent(r.preResultIndent()))
controlStrings = append(controlStrings,
controlHeadingRenderer.Render(),
// newline after control heading
formattedPreResultIndent)
// if the control is in error, render an error
if r.run.GetError() != nil {
errorRenderer := NewErrorRenderer(r.run.GetError(), r.width, r.parentIndent())
controlStrings = append(controlStrings,
errorRenderer.Render(),
// newline after error
formattedPostResultIndent)
}
// now render the results (if any)
var resultStrings []string
for _, row := range r.run.Rows {
resultRenderer := NewResultRenderer(
row.Status,
row.Reason,
row.Dimensions,
r.colorGenerator,
r.width,
r.resultIndent())
// the result renderer may not render the result - in quiet mode only failures are rendered
if resultString := resultRenderer.Render(); resultString != "" {
resultStrings = append(resultStrings, resultString)
}
}
// newline after results
if len(resultStrings) > 0 {
controlStrings = append(controlStrings, resultStrings...)
if len(r.run.Rows) > 0 || r.run.GetError() != nil {
controlStrings = append(controlStrings, formattedPostResultIndent)
}
}
return strings.Join(controlStrings, "\n")
}