client: add member update

This commit is contained in:
Xiang Li 2015-07-01 13:38:03 -07:00 committed by Yicheng Qin
parent 9f9661f513
commit 6e3769d39e
2 changed files with 76 additions and 4 deletions

View File

@ -67,11 +67,11 @@ func (c *memberCollection) UnmarshalJSON(data []byte) error {
return nil
}
type memberCreateRequest struct {
type memberCreateOrUpdateRequest struct {
PeerURLs types.URLs
}
func (m *memberCreateRequest) MarshalJSON() ([]byte, error) {
func (m *memberCreateOrUpdateRequest) MarshalJSON() ([]byte, error) {
s := struct {
PeerURLs []string `json:"peerURLs"`
}{
@ -102,6 +102,9 @@ type MembersAPI interface {
// Remove demotes an existing Member out of the cluster.
Remove(ctx context.Context, mID string) error
// Update instructs etcd to update an existing Member in the cluster.
Update(ctx context.Context, mID string, peerURLs []string) error
}
type httpMembersAPI struct {
@ -159,6 +162,33 @@ func (m *httpMembersAPI) Add(ctx context.Context, peerURL string) (*Member, erro
return &memb, nil
}
func (m *httpMembersAPI) Update(ctx context.Context, memberID string, peerURLs []string) error {
urls, err := types.NewURLs(peerURLs)
if err != nil {
return err
}
req := &membersAPIActionUpdate{peerURLs: urls, memberID: memberID}
resp, body, err := m.client.Do(ctx, req)
if err != nil {
return err
}
if err := assertStatusCode(resp.StatusCode, http.StatusNoContent, http.StatusNotFound, http.StatusConflict); err != nil {
return err
}
if resp.StatusCode != http.StatusNoContent {
var merr membersError
if err := json.Unmarshal(body, &merr); err != nil {
return err
}
return merr
}
return nil
}
func (m *httpMembersAPI) Remove(ctx context.Context, memberID string) error {
req := &membersAPIActionRemove{memberID: memberID}
resp, _, err := m.client.Do(ctx, req)
@ -194,13 +224,28 @@ type membersAPIActionAdd struct {
func (a *membersAPIActionAdd) HTTPRequest(ep url.URL) *http.Request {
u := v2MembersURL(ep)
m := memberCreateRequest{PeerURLs: a.peerURLs}
m := memberCreateOrUpdateRequest{PeerURLs: a.peerURLs}
b, _ := json.Marshal(&m)
req, _ := http.NewRequest("POST", u.String(), bytes.NewReader(b))
req.Header.Set("Content-Type", "application/json")
return req
}
type membersAPIActionUpdate struct {
memberID string
peerURLs types.URLs
}
func (a *membersAPIActionUpdate) HTTPRequest(ep url.URL) *http.Request {
u := v2MembersURL(ep)
m := memberCreateOrUpdateRequest{PeerURLs: a.peerURLs}
u.Path = path.Join(u.Path, a.memberID)
b, _ := json.Marshal(&m)
req, _ := http.NewRequest("PUT", u.String(), bytes.NewReader(b))
req.Header.Set("Content-Type", "application/json")
return req
}
func assertStatusCode(got int, want ...int) (err error) {
for _, w := range want {
if w == got {

View File

@ -70,6 +70,33 @@ func TestMembersAPIActionAdd(t *testing.T) {
}
}
func TestMembersAPIActionUpdate(t *testing.T) {
ep := url.URL{Scheme: "http", Host: "example.com"}
act := &membersAPIActionUpdate{
memberID: "0xabcd",
peerURLs: types.URLs([]url.URL{
url.URL{Scheme: "https", Host: "127.0.0.1:8081"},
url.URL{Scheme: "http", Host: "127.0.0.1:8080"},
}),
}
wantURL := &url.URL{
Scheme: "http",
Host: "example.com",
Path: "/v2/members/0xabcd",
}
wantHeader := http.Header{
"Content-Type": []string{"application/json"},
}
wantBody := []byte(`{"peerURLs":["https://127.0.0.1:8081","http://127.0.0.1:8080"]}`)
got := *act.HTTPRequest(ep)
err := assertRequest(got, "PUT", wantURL, wantHeader, wantBody)
if err != nil {
t.Error(err.Error())
}
}
func TestMembersAPIActionRemove(t *testing.T) {
ep := url.URL{Scheme: "http", Host: "example.com"}
act := &membersAPIActionRemove{memberID: "XXX"}
@ -260,7 +287,7 @@ func TestMemberCollectionUnmarshal(t *testing.T) {
}
func TestMemberCreateRequestMarshal(t *testing.T) {
req := memberCreateRequest{
req := memberCreateOrUpdateRequest{
PeerURLs: types.URLs([]url.URL{
url.URL{Scheme: "http", Host: "127.0.0.1:8081"},
url.URL{Scheme: "https", Host: "127.0.0.1:8080"},