diff --git a/etcd/etcd.go b/etcd/etcd.go index 8ab598863..3a6c3a000 100644 --- a/etcd/etcd.go +++ b/etcd/etcd.go @@ -22,6 +22,7 @@ const ( v2machineKVPrefix = "/_etcd/machines" v2Prefix = "/v2/keys" v2machinePrefix = "/v2/machines" + v2LeaderPrefix = "/v2/leader" raftPrefix = "/raft" ) @@ -77,6 +78,7 @@ func New(c *config.Config, id int) *Server { m.Handle(v2Prefix+"/", handlerErr(s.serveValue)) m.Handle("/raft", s.t) m.Handle(v2machinePrefix, handlerErr(s.serveMachines)) + m.Handle(v2LeaderPrefix, handlerErr(s.serveLeader)) s.Handler = m return s } diff --git a/etcd/v2_http.go b/etcd/v2_http.go index e8c724f8e..9edd7421d 100644 --- a/etcd/v2_http.go +++ b/etcd/v2_http.go @@ -43,6 +43,17 @@ func (s *Server) serveMachines(w http.ResponseWriter, r *http.Request) error { return nil } +func (s *Server) serveLeader(w http.ResponseWriter, r *http.Request) error { + if r.Method != "GET" { + return allow(w, "GET") + } + if laddr, ok := s.t.urls[s.node.Leader()]; ok { + w.Write([]byte(laddr)) + return nil + } + return fmt.Errorf("no leader") +} + type handlerErr func(w http.ResponseWriter, r *http.Request) error func (eh handlerErr) ServeHTTP(w http.ResponseWriter, r *http.Request) { diff --git a/etcd/v2_http_endpoint_test.go b/etcd/v2_http_endpoint_test.go index 03db95e73..e9f7c75ac 100644 --- a/etcd/v2_http_endpoint_test.go +++ b/etcd/v2_http_endpoint_test.go @@ -42,3 +42,40 @@ func TestMachinesEndPoint(t *testing.T) { } afterTest(t) } + +func TestLeaderEndPoint(t *testing.T) { + es, hs := buildCluster(3) + waitCluster(t, es) + + us := make([]string, len(hs)) + for i := range hs { + us[i] = hs[i].URL + } + // todo(xiangli) change this to raft port... + w := hs[0].URL + "/raft" + + for i := range hs { + r, err := http.Get(hs[i].URL + v2LeaderPrefix) + if err != nil { + t.Errorf("%v", err) + break + } + b, err := ioutil.ReadAll(r.Body) + r.Body.Close() + if err != nil { + t.Errorf("%v", err) + break + } + if string(b) != w { + t.Errorf("leader = %v, want %v", string(b), w) + } + } + + for i := range es { + es[len(es)-i-1].Stop() + } + for i := range hs { + hs[len(hs)-i-1].Close() + } + afterTest(t) +}