Skip to content

Commit 237116d

Browse files
kstrifonoffkstrifonoff
authored and
kstrifonoff
committed
etcdctl: fix json output
Fixed an issue related to the printing of IDs in decimal or hexadecimal formats. Signed-off-by: Kirill Trifonov <[email protected]> Signed-off-by: kstrifonoff <[email protected]>
1 parent 022b9b2 commit 237116d

File tree

1 file changed

+66
-42
lines changed

1 file changed

+66
-42
lines changed

Diff for: etcdctl/ctlv3/command/printer_json.go

+66-42
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,18 @@ import (
1818
"encoding/json"
1919
"fmt"
2020
"os"
21-
"strconv"
22-
"strings"
2321

2422
clientv3 "go.etcd.io/etcd/client/v3"
23+
"slices"
2524
)
2625

2726
type jsonPrinter struct {
2827
isHex bool
2928
printer
3029
}
3130

31+
var hexFields = []string{"cluster_id", "member_id", "ID", "leader"}
32+
3233
func newJSONPrinter(isHex bool) printer {
3334
return &jsonPrinter{
3435
isHex: isHex,
@@ -37,12 +38,32 @@ func newJSONPrinter(isHex bool) printer {
3738
}
3839

3940
func (p *jsonPrinter) EndpointHealth(r []epHealth) { printJSON(r) }
40-
func (p *jsonPrinter) EndpointStatus(r []epStatus) { printJSON(r) }
41-
func (p *jsonPrinter) EndpointHashKV(r []epHashKV) { printJSON(r) }
41+
func (p *jsonPrinter) EndpointStatus(r []epStatus) {
42+
if p.isHex {
43+
printWithHexJSON(r)
44+
} else {
45+
printJSON(r)
46+
}
47+
}
48+
func (p *jsonPrinter) EndpointHashKV(r []epHashKV) {
49+
if p.isHex {
50+
printWithHexJSON(r)
51+
} else {
52+
printJSON(r)
53+
}
54+
}
55+
56+
func (p *jsonPrinter) MemberAdd(r clientv3.MemberAddResponse) {
57+
if p.isHex {
58+
printWithHexJSON(r)
59+
} else {
60+
printJSON(r)
61+
}
62+
}
4263

4364
func (p *jsonPrinter) MemberList(r clientv3.MemberListResponse) {
4465
if p.isHex {
45-
printMemberListWithHexJSON(r)
66+
printWithHexJSON(r)
4667
} else {
4768
printJSON(r)
4869
}
@@ -57,44 +78,47 @@ func printJSON(v any) {
5778
fmt.Println(string(b))
5879
}
5980

60-
func printMemberListWithHexJSON(r clientv3.MemberListResponse) {
61-
var buffer strings.Builder
62-
var b []byte
63-
buffer.WriteString("{\"header\":{\"cluster_id\":\"")
64-
b = strconv.AppendUint(nil, r.Header.ClusterId, 16)
65-
buffer.Write(b)
66-
buffer.WriteString("\",\"member_id\":\"")
67-
b = strconv.AppendUint(nil, r.Header.MemberId, 16)
68-
buffer.Write(b)
69-
buffer.WriteString("\",\"raft_term\":")
70-
b = strconv.AppendUint(nil, r.Header.RaftTerm, 10)
71-
buffer.Write(b)
72-
buffer.WriteByte('}')
73-
for i := 0; i < len(r.Members); i++ {
74-
if i == 0 {
75-
buffer.WriteString(",\"members\":[{\"ID\":\"")
76-
} else {
77-
buffer.WriteString(",{\"ID\":\"")
78-
}
79-
b = strconv.AppendUint(nil, r.Members[i].ID, 16)
80-
buffer.Write(b)
81-
buffer.WriteString("\",\"name\":\"" + r.Members[i].Name + "\"," + "\"peerURLs\":")
82-
b, err := json.Marshal(r.Members[i].PeerURLs)
83-
if err != nil {
84-
return
81+
func convertFieldsToHex(data interface{}, keysToConvert []string) {
82+
switch v := data.(type) {
83+
case map[string]interface{}:
84+
for key, val := range v {
85+
if contains(keysToConvert, key) {
86+
if num, ok := val.(float64); ok {
87+
v[key] = fmt.Sprintf("%x", uint64(num))
88+
}
89+
}
90+
convertFieldsToHex(val, keysToConvert)
8591
}
86-
buffer.Write(b)
87-
buffer.WriteString(",\"clientURLs\":")
88-
b, err = json.Marshal(r.Members[i].ClientURLs)
89-
if err != nil {
90-
return
91-
}
92-
buffer.Write(b)
93-
buffer.WriteByte('}')
94-
if i == len(r.Members)-1 {
95-
buffer.WriteString("]")
92+
case []interface{}:
93+
for _, item := range v {
94+
convertFieldsToHex(item, keysToConvert)
9695
}
9796
}
98-
buffer.WriteString("}")
99-
fmt.Println(buffer.String())
97+
}
98+
99+
func contains(slice []string, s string) bool {
100+
return slices.Contains(slice, s)
101+
}
102+
103+
func printWithHexJSON(v any) {
104+
b, err := json.Marshal(v)
105+
if err != nil {
106+
fmt.Fprintf(os.Stderr, "%v\n", err)
107+
return
108+
}
109+
110+
var data interface{}
111+
if err := json.Unmarshal(b, &data); err != nil {
112+
fmt.Fprintf(os.Stderr, "%v\n", err)
113+
return
114+
}
115+
116+
convertFieldsToHex(data, hexFields)
117+
118+
b, err = json.Marshal(data)
119+
if err != nil {
120+
fmt.Fprintf(os.Stderr, "%v\n", err)
121+
return
122+
}
123+
fmt.Println(string(b))
100124
}

0 commit comments

Comments
 (0)