Skip to content

Commit

Permalink
ctlv3: add 'endpoint hash' command
Browse files Browse the repository at this point in the history
Signed-off-by: Gyu-Ho Lee <[email protected]>
  • Loading branch information
gyuho committed Aug 2, 2017
1 parent 5d4a750 commit 6f58550
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 0 deletions.
43 changes: 43 additions & 0 deletions etcdctl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,49 @@ Get the status for all endpoints in the cluster associated with the default endp
+------------------------+------------------+----------------+---------+-----------+-----------+------------+
```

### ENDPOINT HASH

ENDPOINT HASH fetches the backend state of each endpoint.

#### Output

##### Simple format

Prints a humanized table of each endpoint URL and backend hash.

##### JSON format

Prints a line of JSON encoding each endpoint URL and backend hash.

#### Examples

Get the hash for the default endpoint:

```bash
./etcdctl endpoint hash
# 127.0.0.1:2379, 1084519789
```

Get the status for the default endpoint as JSON:

```bash
./etcdctl -w json endpoint hash
# [{"Endpoint":"127.0.0.1:2379","Hash":{"header":{"cluster_id":14841639068965178418,"member_id":10276657743932975437,"revision":1,"raft_term":3},"hash":1084519789,"compact_revision":-1}}]
```

Get the status for all endpoints in the cluster associated with the default endpoint:

```bash
./etcdctl -w table endpoint --cluster hash
+------------------------+------------+
| ENDPOINT | HASH |
+------------------------+------------+
| http://127.0.0.1:12379 | 1084519789 |
| http://127.0.0.1:22379 | 1084519789 |
| http://127.0.0.1:32379 | 1084519789 |
+------------------------+------------+
```

### ALARM \<subcommand\>

Provides alarm related commands
Expand Down
41 changes: 41 additions & 0 deletions etcdctl/ctlv3/command/ep_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
)

var epClusterEndpoints bool
var epHashRev int64

// NewEndpointCommand returns the cobra command for "endpoint".
func NewEndpointCommand() *cobra.Command {
Expand All @@ -39,6 +40,7 @@ func NewEndpointCommand() *cobra.Command {
ec.PersistentFlags().BoolVar(&epClusterEndpoints, "cluster", false, "use all endpoints from the cluster member list")
ec.AddCommand(newEpHealthCommand())
ec.AddCommand(newEpStatusCommand())
ec.AddCommand(newEpHashCommand())

return ec
}
Expand All @@ -64,6 +66,16 @@ The items in the lists are endpoint, ID, version, db size, is leader, raft term,
}
}

func newEpHashCommand() *cobra.Command {
hc := &cobra.Command{
Use: "hash",
Short: "Prints out backend database states specified in `--endpoints` flag",
Run: epHashCommandFunc,
}
hc.PersistentFlags().Int64Var(&epHashRev, "rev", 0, "if non-zero, hash keys at or below the given revision")
return hc
}

// epHealthCommandFunc executes the "endpoint-health" command.
func epHealthCommandFunc(cmd *cobra.Command, args []string) {
flags.SetPflagsFromEnv("ETCDCTL", cmd.InheritedFlags())
Expand Down Expand Up @@ -151,6 +163,35 @@ func epStatusCommandFunc(cmd *cobra.Command, args []string) {
}
}

type epHash struct {
Ep string `json:"Endpoint"`
Resp *v3.HashKVResponse `json:"Hash"`
}

func epHashCommandFunc(cmd *cobra.Command, args []string) {
c := mustClientFromCmd(cmd)

hashList := []epHash{}
var err error
for _, ep := range endpointsFromCluster(cmd) {
ctx, cancel := commandCtx(cmd)
resp, serr := c.HashKV(ctx, ep, epHashRev)
cancel()
if serr != nil {
err = serr
fmt.Fprintf(os.Stderr, "Failed to get the hash of endpoint %s (%v)\n", ep, serr)
continue
}
hashList = append(hashList, epHash{Ep: ep, Resp: resp})
}

display.EndpointHash(hashList)

if err != nil {
os.Exit(ExitError)
}
}

func endpointsFromCluster(cmd *cobra.Command) []string {
if !epClusterEndpoints {
endpoints, err := cmd.Flags().GetStringSlice("endpoints")
Expand Down
13 changes: 13 additions & 0 deletions etcdctl/ctlv3/command/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type printer interface {
MemberList(v3.MemberListResponse)

EndpointStatus([]epStatus)
EndpointHash([]epHash)
MoveLeader(leader, target uint64, r v3.MoveLeaderResponse)

Alarm(v3.AlarmResponse)
Expand Down Expand Up @@ -146,6 +147,7 @@ func newPrinterUnsupported(n string) printer {
}

func (p *printerUnsupported) EndpointStatus([]epStatus) { p.p(nil) }
func (p *printerUnsupported) EndpointHash([]epHash) { p.p(nil) }
func (p *printerUnsupported) DBStatus(dbstatus) { p.p(nil) }

func (p *printerUnsupported) MoveLeader(leader, target uint64, r v3.MoveLeaderResponse) { p.p(nil) }
Expand Down Expand Up @@ -184,6 +186,17 @@ func makeEndpointStatusTable(statusList []epStatus) (hdr []string, rows [][]stri
return
}

func makeEndpointHashTable(hashList []epHash) (hdr []string, rows [][]string) {
hdr = []string{"endpoint", "hash"}
for _, h := range hashList {
rows = append(rows, []string{
h.Ep,
fmt.Sprint(h.Resp.Hash),
})
}
return
}

func makeDBStatusTable(ds dbstatus) (hdr []string, rows [][]string) {
hdr = []string{"hash", "revision", "total keys", "total size"}
rows = append(rows, []string{
Expand Down
9 changes: 9 additions & 0 deletions etcdctl/ctlv3/command/printer_fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,15 @@ func (p *fieldsPrinter) EndpointStatus(eps []epStatus) {
}
}

func (p *fieldsPrinter) EndpointHash(hs []epHash) {
for _, h := range hs {
p.hdr(h.Resp.Header)
fmt.Printf("\"Endpoint\" : %q\n", h.Ep)
fmt.Println(`"Hash" :`, h.Resp.Hash)
fmt.Println()
}
}

func (p *fieldsPrinter) Alarm(r v3.AlarmResponse) {
p.hdr(r.Header)
for _, a := range r.Alarms {
Expand Down
1 change: 1 addition & 0 deletions etcdctl/ctlv3/command/printer_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func newJSONPrinter() printer {
}

func (p *jsonPrinter) EndpointStatus(r []epStatus) { printJSON(r) }
func (p *jsonPrinter) EndpointHash(r []epHash) { printJSON(r) }
func (p *jsonPrinter) DBStatus(r dbstatus) { printJSON(r) }

func printJSON(v interface{}) {
Expand Down
7 changes: 7 additions & 0 deletions etcdctl/ctlv3/command/printer_simple.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ func (s *simplePrinter) EndpointStatus(statusList []epStatus) {
}
}

func (s *simplePrinter) EndpointHash(hashList []epHash) {
_, rows := makeEndpointHashTable(hashList)
for _, row := range rows {
fmt.Println(strings.Join(row, ", "))
}
}

func (s *simplePrinter) DBStatus(ds dbstatus) {
_, rows := makeDBStatusTable(ds)
for _, row := range rows {
Expand Down
10 changes: 10 additions & 0 deletions etcdctl/ctlv3/command/printer_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ func (tp *tablePrinter) EndpointStatus(r []epStatus) {
table.SetAlignment(tablewriter.ALIGN_RIGHT)
table.Render()
}
func (tp *tablePrinter) EndpointHash(r []epHash) {
hdr, rows := makeEndpointHashTable(r)
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader(hdr)
for _, row := range rows {
table.Append(row)
}
table.SetAlignment(tablewriter.ALIGN_RIGHT)
table.Render()
}
func (tp *tablePrinter) DBStatus(r dbstatus) {
hdr, rows := makeDBStatusTable(r)
table := tablewriter.NewWriter(os.Stdout)
Expand Down

0 comments on commit 6f58550

Please sign in to comment.