forked from asonawalla/gazette
/
journals_list.go
155 lines (132 loc) · 3.92 KB
/
journals_list.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package main
import (
"context"
"encoding/json"
"fmt"
"io"
"os"
"strings"
"github.com/LiveRamp/gazette/v2/pkg/client"
mbp "github.com/LiveRamp/gazette/v2/pkg/mainboilerplate"
pb "github.com/LiveRamp/gazette/v2/pkg/protocol"
"github.com/LiveRamp/gazette/v2/pkg/protocol/journalspace"
"github.com/gogo/protobuf/proto"
"github.com/olekukonko/tablewriter"
"gopkg.in/yaml.v2"
)
type cmdJournalsList struct {
ListConfig
Stores bool `long:"stores" description:"Show fragment store column"`
}
func init() {
_ = mustAddCmd(cmdJournals, "list", "List journals", `
List journal specifications and status.
Use --selector to supply a LabelSelector which constrains the set of returned
journals. Journal selectors support additional meta-labels "name" and "prefix".
Match JournalSpecs having an exact name:
> --selector "name in (foo/bar, baz/bing)"
Match JournalSpecs having a name prefix (must end in '/'):
> --selector "prefix = my/prefix/"
Results can be output in a variety of --format options:
yaml: Prints a YAML journal hierarchy, compatible with "journals apply"
json: Prints JournalSpecs encoded as JSON
proto: Prints JournalSpecs encoded in protobuf text format
table: Prints as a table (see other flags for column choices)
When output as a journal hierarchy, gazctl will "hoist" the returned collection
of JournalSpecs into a hierarchy of journals having common prefixes and,
typically, common configuration. This hierarchy is simply sugar for and is
exactly equivalent to the original JournalSpecs.
`, &cmdJournalsList{})
}
func (cmd *cmdJournalsList) Execute([]string) error {
startup()
var resp = listJournals(cmd.Selector)
switch cmd.Format {
case "table":
cmd.outputTable(resp)
case "yaml":
cmd.outputYAML(resp)
case "json":
mbp.Must(json.NewEncoder(os.Stdout).Encode(resp), "failed to encode to json")
case "proto":
mbp.Must(proto.MarshalText(os.Stdout, resp), "failed to write output")
}
return nil
}
func (cmd *cmdJournalsList) outputTable(resp *pb.ListResponse) {
var table = tablewriter.NewWriter(os.Stdout)
var headers = []string{"Name"}
if cmd.RF {
headers = append(headers, "RF")
}
if cmd.Primary {
headers = append(headers, "Primary")
}
if cmd.Replicas {
headers = append(headers, "Replicas")
}
if cmd.Stores {
headers = append(headers, "Stores")
}
for _, l := range cmd.Labels {
headers = append(headers, l)
}
table.SetHeader(headers)
for _, j := range resp.Journals {
var primary = "<none>"
var replicas []string
for i, m := range j.Route.Members {
if int32(i) == j.Route.Primary {
primary = m.Suffix
} else {
replicas = append(replicas, m.Suffix)
}
}
var row = []string{
j.Spec.Name.String(),
}
if cmd.RF {
row = append(row, fmt.Sprintf("%d", j.Spec.Replication))
}
if cmd.Primary {
row = append(row, primary)
}
if cmd.Replicas {
row = append(row, strings.Join(replicas, ","))
}
if cmd.Stores {
if len(j.Spec.Fragment.Stores) != 0 {
row = append(row, string(j.Spec.Fragment.Stores[0]))
} else {
row = append(row, "<none>")
}
}
for _, l := range cmd.Labels {
if v := j.Spec.LabelSet.ValuesOf(l); v == nil {
row = append(row, "<none>")
} else {
row = append(row, strings.Join(v, ","))
}
}
table.Append(row)
}
table.Render()
}
func (cmd *cmdJournalsList) outputYAML(resp *pb.ListResponse) {
writeHoistedJournalSpecTree(os.Stdout, resp)
}
func listJournals(s string) *pb.ListResponse {
var err error
var req pb.ListRequest
var ctx = context.Background()
req.Selector, err = pb.ParseLabelSelector(s)
mbp.Must(err, "failed to parse label selector", "selector", s)
resp, err := client.ListAllJournals(ctx, pb.NewJournalClient(journalsCfg.Broker.Dial(ctx)), req)
mbp.Must(err, "failed to list journals")
return resp
}
func writeHoistedJournalSpecTree(w io.Writer, resp *pb.ListResponse) {
b, err := yaml.Marshal(journalspace.FromListResponse(resp))
_, _ = w.Write(b)
mbp.Must(err, "failed to encode journals")
}