Merge pull request #5053 from xiang90/ctl_i
etcdctl: move endpoint-heath and status into endpoint commandrelease-3.0
commit
2985396768
|
@ -46,7 +46,7 @@ type Maintenance interface {
|
||||||
// times with different endpoints.
|
// times with different endpoints.
|
||||||
Defragment(ctx context.Context, endpoint string) (*DefragmentResponse, error)
|
Defragment(ctx context.Context, endpoint string) (*DefragmentResponse, error)
|
||||||
|
|
||||||
// Status gets the status of the member.
|
// Status gets the status of the endpoint.
|
||||||
Status(ctx context.Context, endpoint string) (*StatusResponse, error)
|
Status(ctx context.Context, endpoint string) (*StatusResponse, error)
|
||||||
|
|
||||||
// Snapshot provides a reader for a snapshot of a backend.
|
// Snapshot provides a reader for a snapshot of a backend.
|
||||||
|
|
|
@ -532,7 +532,7 @@ func ctlV3Version(cx ctlCtx) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ctlV3EpHealth(cx ctlCtx) error {
|
func ctlV3EpHealth(cx ctlCtx) error {
|
||||||
cmdArgs := append(ctlV3PrefixArgs(cx.epc, cx.dialTimeout), "endpoint-health")
|
cmdArgs := append(ctlV3PrefixArgs(cx.epc, cx.dialTimeout), "endpoint health")
|
||||||
lines := make([]string, cx.epc.cfg.clusterSize)
|
lines := make([]string, cx.epc.cfg.clusterSize)
|
||||||
for i := range lines {
|
for i := range lines {
|
||||||
lines[i] = "is healthy"
|
lines[i] = "is healthy"
|
||||||
|
|
|
@ -16,24 +16,45 @@ package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/coreos/etcd/clientv3"
|
v3 "github.com/coreos/etcd/clientv3"
|
||||||
"github.com/coreos/etcd/pkg/flags"
|
"github.com/coreos/etcd/pkg/flags"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewEpHealthCommand returns the cobra command for "endpoint-health".
|
// NewEndpointCommand returns the cobra command for "endpoint".
|
||||||
func NewEpHealthCommand() *cobra.Command {
|
func NewEndpointCommand() *cobra.Command {
|
||||||
|
ec := &cobra.Command{
|
||||||
|
Use: "endpoint",
|
||||||
|
Short: "endpoint is used to check endpoints.",
|
||||||
|
}
|
||||||
|
|
||||||
|
ec.AddCommand(newEpHealthCommand())
|
||||||
|
ec.AddCommand(newEpStatusCommand())
|
||||||
|
|
||||||
|
return ec
|
||||||
|
}
|
||||||
|
|
||||||
|
func newEpHealthCommand() *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "endpoint-health",
|
Use: "health",
|
||||||
Short: "endpoint-health checks the healthiness of endpoints specified in `--endpoints` flag",
|
Short: "health checks the healthiness of endpoints specified in `--endpoints` flag",
|
||||||
Run: epHealthCommandFunc,
|
Run: epHealthCommandFunc,
|
||||||
}
|
}
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newEpStatusCommand() *cobra.Command {
|
||||||
|
return &cobra.Command{
|
||||||
|
Use: "status",
|
||||||
|
Short: "status prints out the status of endpoints specified in `--endpoints` flag",
|
||||||
|
Run: epStatusCommandFunc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// epHealthCommandFunc executes the "endpoint-health" command.
|
// epHealthCommandFunc executes the "endpoint-health" command.
|
||||||
func epHealthCommandFunc(cmd *cobra.Command, args []string) {
|
func epHealthCommandFunc(cmd *cobra.Command, args []string) {
|
||||||
flags.SetPflagsFromEnv("ETCDCTL", cmd.InheritedFlags())
|
flags.SetPflagsFromEnv("ETCDCTL", cmd.InheritedFlags())
|
||||||
|
@ -44,7 +65,7 @@ func epHealthCommandFunc(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
sec := secureCfgFromCmd(cmd)
|
sec := secureCfgFromCmd(cmd)
|
||||||
dt := dialTimeoutFromCmd(cmd)
|
dt := dialTimeoutFromCmd(cmd)
|
||||||
cfgs := []*clientv3.Config{}
|
cfgs := []*v3.Config{}
|
||||||
for _, ep := range endpoints {
|
for _, ep := range endpoints {
|
||||||
cfg, err := newClientCfg([]string{ep}, dt, sec)
|
cfg, err := newClientCfg([]string{ep}, dt, sec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -57,10 +78,10 @@ func epHealthCommandFunc(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
for _, cfg := range cfgs {
|
for _, cfg := range cfgs {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(cfg *clientv3.Config) {
|
go func(cfg *v3.Config) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
ep := cfg.Endpoints[0]
|
ep := cfg.Endpoints[0]
|
||||||
cli, err := clientv3.New(*cfg)
|
cli, err := v3.New(*cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%s is unhealthy: failed to connect: %v\n", ep, err)
|
fmt.Printf("%s is unhealthy: failed to connect: %v\n", ep, err)
|
||||||
return
|
return
|
||||||
|
@ -81,3 +102,32 @@ func epHealthCommandFunc(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type epStatus struct {
|
||||||
|
ep string
|
||||||
|
resp *v3.StatusResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
func epStatusCommandFunc(cmd *cobra.Command, args []string) {
|
||||||
|
c := mustClientFromCmd(cmd)
|
||||||
|
|
||||||
|
statusList := []epStatus{}
|
||||||
|
var err error
|
||||||
|
for _, ep := range c.Endpoints() {
|
||||||
|
ctx, cancel := commandCtx(cmd)
|
||||||
|
resp, serr := c.Status(ctx, ep)
|
||||||
|
cancel()
|
||||||
|
if serr != nil {
|
||||||
|
err = serr
|
||||||
|
fmt.Fprintf(os.Stderr, "Failed to get the status of endpoint %s (%v)\n", ep, serr)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
statusList = append(statusList, epStatus{ep: ep, resp: resp})
|
||||||
|
}
|
||||||
|
|
||||||
|
display.EndpointStatus(statusList)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
os.Exit(ExitError)
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ type printer interface {
|
||||||
|
|
||||||
MemberList(v3.MemberListResponse)
|
MemberList(v3.MemberListResponse)
|
||||||
|
|
||||||
MemberStatus([]statusInfo)
|
EndpointStatus([]epStatus)
|
||||||
|
|
||||||
Alarm(v3.AlarmResponse)
|
Alarm(v3.AlarmResponse)
|
||||||
DBStatus(dbstatus)
|
DBStatus(dbstatus)
|
||||||
|
@ -129,7 +129,7 @@ func (s *simplePrinter) MemberList(resp v3.MemberListResponse) {
|
||||||
table.Render()
|
table.Render()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *simplePrinter) MemberStatus(statusList []statusInfo) {
|
func (s *simplePrinter) EndpointStatus(statusList []epStatus) {
|
||||||
table := tablewriter.NewWriter(os.Stdout)
|
table := tablewriter.NewWriter(os.Stdout)
|
||||||
table.SetHeader([]string{"endpoint", "ID", "version", "db size", "is leader", "raft term", "raft index"})
|
table.SetHeader([]string{"endpoint", "ID", "version", "db size", "is leader", "raft term", "raft index"})
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ func (p *jsonPrinter) Txn(r v3.TxnResponse) { printJSON(r) }
|
||||||
func (p *jsonPrinter) Watch(r v3.WatchResponse) { printJSON(r) }
|
func (p *jsonPrinter) Watch(r v3.WatchResponse) { printJSON(r) }
|
||||||
func (p *jsonPrinter) Alarm(r v3.AlarmResponse) { printJSON(r) }
|
func (p *jsonPrinter) Alarm(r v3.AlarmResponse) { printJSON(r) }
|
||||||
func (p *jsonPrinter) MemberList(r v3.MemberListResponse) { printJSON(r) }
|
func (p *jsonPrinter) MemberList(r v3.MemberListResponse) { printJSON(r) }
|
||||||
func (p *jsonPrinter) MemberStatus(r []statusInfo) { printJSON(r) }
|
func (p *jsonPrinter) EndpointStatus(r []epStatus) { printJSON(r) }
|
||||||
func (p *jsonPrinter) DBStatus(r dbstatus) { printJSON(r) }
|
func (p *jsonPrinter) DBStatus(r dbstatus) { printJSON(r) }
|
||||||
|
|
||||||
func printJSON(v interface{}) {
|
func printJSON(v interface{}) {
|
||||||
|
@ -223,7 +223,7 @@ func (pb *pbPrinter) MemberList(r v3.MemberListResponse) {
|
||||||
ExitWithError(ExitBadFeature, errors.New("only support simple or json as output format"))
|
ExitWithError(ExitBadFeature, errors.New("only support simple or json as output format"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pb *pbPrinter) MemberStatus(r []statusInfo) {
|
func (pb *pbPrinter) EndpointStatus(statusList []epStatus) {
|
||||||
ExitWithError(ExitBadFeature, errors.New("only support simple or json as output format"))
|
ExitWithError(ExitBadFeature, errors.New("only support simple or json as output format"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
// Copyright 2016 CoreOS, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package command
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
v3 "github.com/coreos/etcd/clientv3"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewStatusCommand returns the cobra command for "Status".
|
|
||||||
func NewStatusCommand() *cobra.Command {
|
|
||||||
return &cobra.Command{
|
|
||||||
Use: "status",
|
|
||||||
Short: "status prints out the statuses of the members with given endpoints.",
|
|
||||||
Run: statusCommandFunc,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type statusInfo struct {
|
|
||||||
ep string
|
|
||||||
resp *v3.StatusResponse
|
|
||||||
}
|
|
||||||
|
|
||||||
func statusCommandFunc(cmd *cobra.Command, args []string) {
|
|
||||||
c := mustClientFromCmd(cmd)
|
|
||||||
|
|
||||||
statusList := []statusInfo{}
|
|
||||||
var err error
|
|
||||||
for _, ep := range c.Endpoints() {
|
|
||||||
ctx, cancel := commandCtx(cmd)
|
|
||||||
resp, serr := c.Status(ctx, ep)
|
|
||||||
cancel()
|
|
||||||
if serr != nil {
|
|
||||||
err = serr
|
|
||||||
fmt.Fprintf(os.Stderr, "Failed to get the status of endpoint %s (%v)", ep, serr)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
statusList = append(statusList, statusInfo{ep: ep, resp: resp})
|
|
||||||
}
|
|
||||||
|
|
||||||
display.MemberStatus(statusList)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
os.Exit(ExitError)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -66,12 +66,11 @@ func init() {
|
||||||
command.NewCompactionCommand(),
|
command.NewCompactionCommand(),
|
||||||
command.NewAlarmCommand(),
|
command.NewAlarmCommand(),
|
||||||
command.NewDefragCommand(),
|
command.NewDefragCommand(),
|
||||||
command.NewStatusCommand(),
|
command.NewEndpointCommand(),
|
||||||
command.NewWatchCommand(),
|
command.NewWatchCommand(),
|
||||||
command.NewVersionCommand(),
|
command.NewVersionCommand(),
|
||||||
command.NewLeaseCommand(),
|
command.NewLeaseCommand(),
|
||||||
command.NewMemberCommand(),
|
command.NewMemberCommand(),
|
||||||
command.NewEpHealthCommand(),
|
|
||||||
command.NewSnapshotCommand(),
|
command.NewSnapshotCommand(),
|
||||||
command.NewMakeMirrorCommand(),
|
command.NewMakeMirrorCommand(),
|
||||||
command.NewLockCommand(),
|
command.NewLockCommand(),
|
||||||
|
|
Loading…
Reference in New Issue