diff --git a/etcdserver/cluster.go b/etcdserver/cluster.go index 793b63bad..ffb40ff39 100644 --- a/etcdserver/cluster.go +++ b/etcdserver/cluster.go @@ -112,3 +112,17 @@ func (c Cluster) Endpoints() []string { sort.Strings(endpoints) return endpoints } + +// ClientURLs returns a list of all client addresses. Each address is prefixed +// with the scheme (currently "http://"). The returned list is sorted in +// ascending lexicographical order. +func (c Cluster) ClientURLs() []string { + urls := make([]string, 0) + for _, p := range c { + for _, url := range p.ClientURLs { + urls = append(urls, addScheme(url)) + } + } + sort.Strings(urls) + return urls +} diff --git a/etcdserver/cluster_test.go b/etcdserver/cluster_test.go index 7ddf6d461..dc05832d9 100644 --- a/etcdserver/cluster_test.go +++ b/etcdserver/cluster_test.go @@ -1,6 +1,7 @@ package etcdserver import ( + "reflect" "testing" ) @@ -141,3 +142,62 @@ func TestClusterAddBad(t *testing.T) { } } } + +func TestClusterClientURLs(t *testing.T) { + tests := []struct { + mems []Member + wurls []string + }{ + // single peer with a single address + { + mems: []Member{ + {ID: 1, ClientURLs: []string{"192.0.2.1"}}, + }, + wurls: []string{"http://192.0.2.1"}, + }, + + // single peer with a single address with a port + { + mems: []Member{ + {ID: 1, ClientURLs: []string{"192.0.2.1:8001"}}, + }, + wurls: []string{"http://192.0.2.1:8001"}, + }, + + // several members explicitly unsorted + { + mems: []Member{ + {ID: 2, ClientURLs: []string{"192.0.2.3", "192.0.2.4"}}, + {ID: 3, ClientURLs: []string{"192.0.2.5", "192.0.2.6"}}, + {ID: 1, ClientURLs: []string{"192.0.2.1", "192.0.2.2"}}, + }, + wurls: []string{"http://192.0.2.1", "http://192.0.2.2", "http://192.0.2.3", "http://192.0.2.4", "http://192.0.2.5", "http://192.0.2.6"}, + }, + + // no members + { + mems: []Member{}, + wurls: []string{}, + }, + + // peer with no endpoints + { + mems: []Member{ + {ID: 3, ClientURLs: []string{}}, + }, + wurls: []string{}, + }, + } + + for i, tt := range tests { + c := Cluster{} + if err := c.AddSlice(tt.mems); err != nil { + t.Errorf("AddSlice error: %v", err) + continue + } + urls := c.ClientURLs() + if !reflect.DeepEqual(urls, tt.wurls) { + t.Errorf("#%d: ClientURLs = %v, want %v", i, tt.wurls, urls) + } + } +} diff --git a/etcdserver/etcdhttp/http.go b/etcdserver/etcdhttp/http.go index db9e4249f..e250e026d 100644 --- a/etcdserver/etcdhttp/http.go +++ b/etcdserver/etcdhttp/http.go @@ -115,7 +115,7 @@ func (h serverHandler) serveMachines(w http.ResponseWriter, r *http.Request) { if !allowMethod(w, r.Method, "GET", "HEAD") { return } - endpoints := h.clusterStore.Get().Endpoints() + endpoints := h.clusterStore.Get().ClientURLs() w.Write([]byte(strings.Join(endpoints, ", "))) } diff --git a/etcdserver/etcdhttp/http_test.go b/etcdserver/etcdhttp/http_test.go index 7e60e53bb..2e2b4cd92 100644 --- a/etcdserver/etcdhttp/http_test.go +++ b/etcdserver/etcdhttp/http_test.go @@ -612,9 +612,9 @@ func TestV2MachinesEndpoint(t *testing.T) { func TestServeMachines(t *testing.T) { cluster := &fakeCluster{ members: []etcdserver.Member{ - {ID: 0xBEEF0, PeerURLs: []string{"localhost:8080"}}, - {ID: 0xBEEF1, PeerURLs: []string{"localhost:8081"}}, - {ID: 0xBEEF2, PeerURLs: []string{"localhost:8082"}}, + {ID: 0xBEEF0, ClientURLs: []string{"localhost:8080"}}, + {ID: 0xBEEF1, ClientURLs: []string{"localhost:8081"}}, + {ID: 0xBEEF2, ClientURLs: []string{"localhost:8082"}}, }, }