diff --git a/etcdctl/command/cluster_health.go b/etcdctl/command/cluster_health.go index 549a70506..303e06f37 100644 --- a/etcdctl/command/cluster_health.go +++ b/etcdctl/command/cluster_health.go @@ -10,6 +10,7 @@ import ( "github.com/coreos/etcd/Godeps/_workspace/src/github.com/codegangsta/cli" "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" + "github.com/coreos/etcd/client" ) func NewClusterHealthCommand() cli.Command { @@ -44,7 +45,8 @@ func handleClusterHealth(c *cli.Context) { Transport: tr, } - mi := mustNewMembersAPI(c) + cln := mustNewClientNoSync(c) + mi := client.NewMembersAPI(cln) ms, err := mi.List(context.TODO()) if err != nil { fmt.Println("cluster may be unhealthy: failed to list members") @@ -54,6 +56,11 @@ func handleClusterHealth(c *cli.Context) { for { health := false for _, m := range ms { + if len(m.ClientURLs) == 0 { + fmt.Printf("member %s is unreachable: no available published client urls\n", m.ID) + continue + } + checked := false for _, url := range m.ClientURLs { resp, err := hc.Get(url + "/health") diff --git a/etcdctl/command/util.go b/etcdctl/command/util.go index ac6dbeda1..b8f329873 100644 --- a/etcdctl/command/util.go +++ b/etcdctl/command/util.go @@ -181,36 +181,7 @@ func mustNewMembersAPI(c *cli.Context) client.MembersAPI { } func mustNewClient(c *cli.Context) client.Client { - eps, err := getEndpoints(c) - if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - os.Exit(1) - } - - tr, err := getTransport(c) - if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - os.Exit(1) - } - - cfg := client.Config{ - Transport: tr, - Endpoints: eps, - HeaderTimeoutPerRequest: c.GlobalDuration("timeout"), - } - - uFlag := c.GlobalString("username") - if uFlag != "" { - username, password, err := getUsernamePasswordFromFlag(uFlag) - if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - os.Exit(1) - } - cfg.Username = username - cfg.Password = password - } - - hc, err := client.New(cfg) + hc, err := newClient(c) if err != nil { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(1) @@ -223,7 +194,7 @@ func mustNewClient(c *cli.Context) client.Client { if err != nil { if err == client.ErrNoEndpoints { fmt.Fprintf(os.Stderr, "etcd cluster has no published client endpoints.\n") - fmt.Fprintf(os.Stderr, "Try '--no-sync' if you want to access non-published client endpoints(%s).\n", strings.Join(eps, ",")) + fmt.Fprintf(os.Stderr, "Try '--no-sync' if you want to access non-published client endpoints(%s).\n", strings.Join(hc.Endpoints(), ",")) } handleError(ExitServerError, err) os.Exit(1) @@ -237,3 +208,48 @@ func mustNewClient(c *cli.Context) client.Client { return hc } + +func mustNewClientNoSync(c *cli.Context) client.Client { + hc, err := newClient(c) + if err != nil { + fmt.Fprintln(os.Stderr, err.Error()) + os.Exit(1) + } + + if c.GlobalBool("debug") { + fmt.Fprintf(os.Stderr, "Cluster-Endpoints: %s\n", strings.Join(hc.Endpoints(), ", ")) + client.EnablecURLDebug() + } + + return hc +} + +func newClient(c *cli.Context) (client.Client, error) { + eps, err := getEndpoints(c) + if err != nil { + return nil, err + } + + tr, err := getTransport(c) + if err != nil { + return nil, err + } + + cfg := client.Config{ + Transport: tr, + Endpoints: eps, + HeaderTimeoutPerRequest: c.GlobalDuration("timeout"), + } + + uFlag := c.GlobalString("username") + if uFlag != "" { + username, password, err := getUsernamePasswordFromFlag(uFlag) + if err != nil { + return nil, err + } + cfg.Username = username + cfg.Password = password + } + + return client.New(cfg) +}