etcdhttp: add /v2/machines endpoint

This commit is contained in:
Yicheng Qin 2014-09-08 16:34:29 -07:00
parent b8f2db36dd
commit 0c1d1b7aeb
3 changed files with 60 additions and 2 deletions

View File

@ -11,6 +11,7 @@ import (
"log"
"net/http"
"net/url"
"sort"
"strconv"
"strings"
"time"
@ -27,7 +28,10 @@ import (
"github.com/coreos/etcd/third_party/code.google.com/p/go.net/context"
)
const keysPrefix = "/v2/keys"
const (
keysPrefix = "/v2/keys"
machinesPrefix = "/v2/machines"
)
type Peers map[int64][]string
@ -36,7 +40,12 @@ func (ps Peers) Pick(id int64) string {
if len(addrs) == 0 {
return ""
}
return fmt.Sprintf("http://%s", addrs[rand.Intn(len(addrs))])
return addScheme(addrs[rand.Intn(len(addrs))])
}
// TODO: improve this when implementing TLS
func addScheme(addr string) string {
return fmt.Sprintf("http://%s", addr)
}
// Set parses command line sets of names to ips formatted like:
@ -138,6 +147,7 @@ func httpPost(url string, data []byte) bool {
type Handler struct {
Timeout time.Duration
Server *etcdserver.Server
Peers Peers
}
func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
@ -156,6 +166,8 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.serveRaft(ctx, w, r)
case strings.HasPrefix(r.URL.Path, keysPrefix):
h.serveKeys(ctx, w, r)
case strings.HasPrefix(r.URL.Path, machinesPrefix):
h.serveMachines(w, r)
default:
http.NotFound(w, r)
}
@ -188,6 +200,19 @@ func (h Handler) serveKeys(ctx context.Context, w http.ResponseWriter, r *http.R
}
}
// serveMachines responds address list in the format '0.0.0.0, 1.1.1.1'.
// TODO: rethink the format of machine list because it is not json format.
func (h Handler) serveMachines(w http.ResponseWriter, r *http.Request) {
urls := make([]string, 0)
for _, addrs := range h.Peers {
for _, addr := range addrs {
urls = append(urls, addScheme(addr))
}
}
sort.Sort(sort.StringSlice(urls))
w.Write([]byte(strings.Join(urls, ", ")))
}
func (h Handler) serveRaft(ctx context.Context, w http.ResponseWriter, r *http.Request) {
b, err := ioutil.ReadAll(r.Body)
if err != nil {

View File

@ -347,3 +347,35 @@ func TestWaitForEventCancelledContext(t *testing.T) {
t.Fatalf("nil err returned with cancelled context!")
}
}
func TestV2MachinesEndpoint(t *testing.T) {
h := Handler{Peers: Peers{}}
s := httptest.NewServer(h)
defer s.Close()
resp, err := http.Get(s.URL + machinesPrefix)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != http.StatusOK {
t.Errorf("StatusCode = %d, expected %d", resp.StatusCode, http.StatusOK)
}
}
func TestServeMachines(t *testing.T) {
peers := Peers{}
peers.Set("0xBEEF0=localhost:8080&0xBEEF1=localhost:8081&0xBEEF2=localhost:8082")
h := Handler{Peers: peers}
writer := httptest.NewRecorder()
h.serveMachines(writer, nil)
w := "http://localhost:8080, http://localhost:8081, http://localhost:8082"
if g := writer.Body.String(); g != w {
t.Errorf("data = %s, want %s", g, w)
}
if writer.Code != http.StatusOK {
t.Errorf("header = %d, want %d", writer.Code, http.StatusOK)
}
}

View File

@ -70,6 +70,7 @@ func main() {
h := &etcdhttp.Handler{
Timeout: *timeout,
Server: s,
Peers: peers,
}
http.Handle("/", h)
log.Fatal(http.ListenAndServe(*laddr, nil))