etcdserver: add member endpoint to peerurl

This commit is contained in:
Xiang Li
2014-10-23 15:53:27 -07:00
parent 4089475c90
commit 02551c277d
2 changed files with 60 additions and 17 deletions

View File

@@ -41,11 +41,14 @@ import (
)
const (
// prefixes of client endpoint
keysPrefix = "/v2/keys"
deprecatedMachinesPrefix = "/v2/machines"
adminMembersPrefix = "/v2/admin/members/"
raftPrefix = "/raft"
statsPrefix = "/v2/stats"
// prefixes of peer endpoint
raftPrefix = "/raft"
membersPrefix = "/members"
// time to wait for response from EtcdServer requests
defaultServerTimeout = 500 * time.Millisecond
@@ -91,6 +94,7 @@ func NewPeerHandler(server *etcdserver.EtcdServer) http.Handler {
}
mux := http.NewServeMux()
mux.HandleFunc(raftPrefix, sh.serveRaft)
mux.HandleFunc(membersPrefix, sh.serveMembers)
mux.HandleFunc("/", http.NotFound)
return mux
}
@@ -306,6 +310,13 @@ func (h serverHandler) serveRaft(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
}
func (h serverHandler) serveMembers(w http.ResponseWriter, r *http.Request) {
if !allowMethod(w, r.Method, "GET") {
return
}
h.serveAdminMembers(w, r)
}
// parseKeyRequest converts a received http.Request on keysPrefix to
// a server Request, performing validation of supplied fields as appropriate.
// If any validation fails, an empty Request and non-nil error is returned.

View File

@@ -988,6 +988,34 @@ func TestServeRaft(t *testing.T) {
}
}
func TestServeMembersFails(t *testing.T) {
tests := []struct {
method string
wcode int
}{
{
"POST",
http.StatusMethodNotAllowed,
},
{
"DELETE",
http.StatusMethodNotAllowed,
},
{
"BAD",
http.StatusMethodNotAllowed,
},
}
for i, tt := range tests {
h := &serverHandler{}
rw := httptest.NewRecorder()
h.serveMembers(rw, &http.Request{Method: tt.method})
if rw.Code != tt.wcode {
t.Errorf("#%d: code=%d, want %d", i, rw.Code, tt.wcode)
}
}
}
// resServer implements the etcd.Server interface for testing.
// It returns the given responsefrom any Do calls, and nil error
type resServer struct {
@@ -1532,7 +1560,7 @@ func (s *serverRecorder) RemoveMember(_ context.Context, id uint64) error {
return nil
}
func TestServeAdminMembersGet(t *testing.T) {
func TestServeAdminMembersAndMembersGet(t *testing.T) {
memb1 := etcdserver.Member{ID: 1, Attributes: etcdserver.Attributes{ClientURLs: []string{"http://localhost:8080"}}}
memb2 := etcdserver.Member{ID: 2, Attributes: etcdserver.Attributes{ClientURLs: []string{"http://localhost:8081"}}}
cluster := &fakeCluster{
@@ -1566,22 +1594,26 @@ func TestServeAdminMembersGet(t *testing.T) {
{path.Join(adminMembersPrefix, "100"), http.StatusNotFound, "text/plain; charset=utf-8", "member not found\n"},
}
for i, tt := range tests {
req, err := http.NewRequest("GET", mustNewURL(t, tt.path).String(), nil)
if err != nil {
t.Fatal(err)
}
rw := httptest.NewRecorder()
h.serveAdminMembers(rw, req)
funcs := []func(w http.ResponseWriter, r *http.Request){h.serveAdminMembers, h.serveMembers}
if rw.Code != tt.wcode {
t.Errorf("#%d: code=%d, want %d", i, rw.Code, tt.wcode)
}
if gct := rw.Header().Get("Content-Type"); gct != tt.wct {
t.Errorf("#%d: content-type = %s, want %s", i, gct, tt.wct)
}
if rw.Body.String() != tt.wbody {
t.Errorf("#%d: body = %s, want %s", i, rw.Body.String(), tt.wbody)
for i, tt := range tests {
for j, f := range funcs {
req, err := http.NewRequest("GET", mustNewURL(t, tt.path).String(), nil)
if err != nil {
t.Fatal(err)
}
rw := httptest.NewRecorder()
f(rw, req)
if rw.Code != tt.wcode {
t.Errorf("#%d.%d: code=%d, want %d", i, j, rw.Code, tt.wcode)
}
if gct := rw.Header().Get("Content-Type"); gct != tt.wct {
t.Errorf("#%d.%d: content-type = %s, want %s", i, j, gct, tt.wct)
}
if rw.Body.String() != tt.wbody {
t.Errorf("#%d.%d: body = %s, want %s", i, j, rw.Body.String(), tt.wbody)
}
}
}
}