-
Notifications
You must be signed in to change notification settings - Fork 458
/
table.go
117 lines (87 loc) · 2.91 KB
/
table.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
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package output
import (
"bytes"
"fmt"
"os"
"strings"
"text/tabwriter"
"github.com/talos-systems/os-runtime/pkg/resource"
"github.com/talos-systems/os-runtime/pkg/state"
"k8s.io/client-go/util/jsonpath"
)
// Table outputs resources in Table view.
type Table struct {
w tabwriter.Writer
withEvents bool
displayType string
dynamicColumns []dynamicColumn
}
type dynamicColumn func(value interface{}) (string, error)
// NewTable initializes table resource output.
func NewTable() *Table {
output := &Table{}
output.w.Init(os.Stdout, 0, 0, 3, ' ', 0)
return output
}
// WriteHeader implements output.Writer interface.
func (table *Table) WriteHeader(definition resource.Resource, withEvents bool) error {
table.withEvents = withEvents
fields := []string{"NAMESPACE", "TYPE", "ID", "VERSION"}
if withEvents {
fields = append([]string{"*"}, fields...)
}
resourceDefinitionSpec := definition.(*resource.Any).Value().(map[string]interface{}) //nolint:errcheck
table.displayType = resourceDefinitionSpec["displayType"].(string) //nolint:errcheck
for _, col := range resourceDefinitionSpec["printColumns"].([]interface{}) {
column := col.(map[string]interface{}) //nolint:errcheck
name := column["name"].(string) //nolint:errcheck
fields = append(fields, strings.ToUpper(name))
expr := jsonpath.New(name)
if err := expr.Parse(column["jsonPath"].(string)); err != nil {
return fmt.Errorf("error parsing column %q jsonpath: %w", name, err)
}
table.dynamicColumns = append(table.dynamicColumns, func(val interface{}) (string, error) {
var buf bytes.Buffer
if e := expr.Execute(&buf, val); e != nil {
return "", e
}
return buf.String(), nil
})
}
fields = append([]string{"NODE"}, fields...)
_, err := fmt.Fprintln(&table.w, strings.Join(fields, "\t"))
return err
}
// WriteResource implements output.Writer interface.
func (table *Table) WriteResource(node string, r resource.Resource, event state.EventType) error {
values := []string{r.Metadata().Namespace(), table.displayType, r.Metadata().ID(), r.Metadata().Version().String()}
if table.withEvents {
var label string
switch event {
case state.Created:
label = "+"
case state.Destroyed:
label = "-"
case state.Updated:
label = " "
}
values = append([]string{label}, values...)
}
for _, dynamicColumn := range table.dynamicColumns {
value, err := dynamicColumn(r.(*resource.Any).Value())
if err != nil {
return err
}
values = append(values, value)
}
values = append([]string{node}, values...)
_, err := fmt.Fprintln(&table.w, strings.Join(values, "\t"))
return err
}
// Flush implements output.Writer interface.
func (table *Table) Flush() error {
return table.w.Flush()
}