diff --git a/server/peer_server_handlers.go b/server/peer_server_handlers.go index a8219c7a8..0a04f0bde 100644 --- a/server/peer_server_handlers.go +++ b/server/peer_server_handlers.go @@ -223,8 +223,9 @@ func (ps *PeerServer) setClusterConfigHttpHandler(w http.ResponseWriter, req *ht // Retrieves a list of peers and standbys. func (ps *PeerServer) getMachinesHttpHandler(w http.ResponseWriter, req *http.Request) { machines := make([]*machineMessage, 0) + leader := ps.raftServer.Leader() for _, name := range ps.registry.Names() { - machines = append(machines, ps.getMachineMessage(name)) + machines = append(machines, ps.getMachineMessage(name, leader)) } json.NewEncoder(w).Encode(&machines) } @@ -232,21 +233,27 @@ func (ps *PeerServer) getMachinesHttpHandler(w http.ResponseWriter, req *http.Re // Retrieve single peer or standby. func (ps *PeerServer) getMachineHttpHandler(w http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) - json.NewEncoder(w).Encode(ps.getMachineMessage(vars["name"])) + m := ps.getMachineMessage(vars["name"], ps.raftServer.Leader()) + json.NewEncoder(w).Encode(m) } -func (ps *PeerServer) getMachineMessage(name string) *machineMessage { +func (ps *PeerServer) getMachineMessage(name string, leader string) *machineMessage { if !ps.registry.Exists(name) { return nil } clientURL, _ := ps.registry.ClientURL(name) peerURL, _ := ps.registry.PeerURL(name) - return &machineMessage{ + msg := &machineMessage{ Name: name, + State: raft.Follower, ClientURL: clientURL, PeerURL: peerURL, } + if name == leader { + msg.State = raft.Leader + } + return msg } // Response to the name request @@ -298,6 +305,7 @@ func (ps *PeerServer) UpgradeHttpHandler(w http.ResponseWriter, req *http.Reques // machineMessage represents information about a peer or standby in the registry. type machineMessage struct { Name string `json:"name"` + State string `json:"state"` ClientURL string `json:"clientURL"` PeerURL string `json:"peerURL"` } diff --git a/tests/functional/cluster_config_test.go b/tests/functional/cluster_config_test.go index c75ce1de4..c531fb1cb 100644 --- a/tests/functional/cluster_config_test.go +++ b/tests/functional/cluster_config_test.go @@ -2,6 +2,7 @@ package test import ( "bytes" + "encoding/json" "os" "testing" "time" @@ -27,3 +28,25 @@ func TestClusterConfig(t *testing.T) { assert.Equal(t, body["activeSize"], 3) assert.Equal(t, body["promoteDelay"], 60) } + +// TestGetMachines tests '/v2/admin/machines' sends back messages of all machines. +func TestGetMachines(t *testing.T) { + _, etcds, err := CreateCluster(3, &os.ProcAttr{Files: []*os.File{nil, os.Stdout, os.Stderr}}, false) + assert.NoError(t, err) + defer DestroyCluster(etcds) + + time.Sleep(1 * time.Second) + + resp, err := tests.Get("http://localhost:7001/v2/admin/machines") + if !assert.Equal(t, err, nil) { + t.FailNow() + } + assert.Equal(t, resp.StatusCode, 200) + machines := make([]map[string]interface{}, 0) + b := tests.ReadBody(resp) + json.Unmarshal(b, &machines) + assert.Equal(t, len(machines), 3) + if machines[0]["state"] != "leader" && machines[1]["state"] != "leader" && machines[2]["state"] != "leader" { + t.Errorf("no leader in the cluster") + } +}