diff --git a/command/agent/coordinate_endpoint.go b/command/agent/coordinate_endpoint.go index 29a204d6e..f4543ecff 100644 --- a/command/agent/coordinate_endpoint.go +++ b/command/agent/coordinate_endpoint.go @@ -3,6 +3,7 @@ package agent import ( "github.com/hashicorp/consul/consul/structs" "net/http" + "sort" ) // coordinateDisabled handles all the endpoints when coordinates are not enabled, @@ -13,11 +14,35 @@ func coordinateDisabled(resp http.ResponseWriter, req *http.Request) (interface{ return nil, nil } +// sorter wraps a coordinate list and implements the sort.Interface to sort by +// node name. +type sorter struct { + coordinates []structs.Coordinate +} + +// See sort.Interface. +func (s *sorter) Len() int { + return len(s.coordinates) +} + +// See sort.Interface. +func (s *sorter) Swap(i, j int) { + s.coordinates[i], s.coordinates[j] = s.coordinates[j], s.coordinates[i] +} + +// See sort.Interface. +func (s *sorter) Less(i, j int) bool { + return s.coordinates[i].Node < s.coordinates[j].Node +} + // CoordinateDatacenters returns the WAN nodes in each datacenter, along with // raw network coordinates. func (s *HTTPServer) CoordinateDatacenters(resp http.ResponseWriter, req *http.Request) (interface{}, error) { var out []structs.DatacenterMap if err := s.agent.RPC("Coordinate.ListDatacenters", struct{}{}, &out); err != nil { + for i := range out { + sort.Sort(&sorter{out[i].Coordinates}) + } return nil, err } return out, nil @@ -34,6 +59,7 @@ func (s *HTTPServer) CoordinateNodes(resp http.ResponseWriter, req *http.Request var out structs.IndexedCoordinates defer setMeta(resp, &out.QueryMeta) if err := s.agent.RPC("Coordinate.ListNodes", &args, &out); err != nil { + sort.Sort(&sorter{out.Coordinates}) return nil, err } return out.Coordinates, nil diff --git a/command/agent/coordinate_endpoint_test.go b/command/agent/coordinate_endpoint_test.go index 3594aa986..5c5dd08ac 100644 --- a/command/agent/coordinate_endpoint_test.go +++ b/command/agent/coordinate_endpoint_test.go @@ -70,7 +70,7 @@ func TestCoordinate_Nodes(t *testing.T) { } time.Sleep(200 * time.Millisecond) - // Query back and check the nodes are present. + // Query back and check the nodes are present and sorted correctly. req, err := http.NewRequest("GET", "/v1/coordinate/nodes?dc=dc1", nil) if err != nil { t.Fatalf("err: %v", err) diff --git a/consul/coordinate_endpoint.go b/consul/coordinate_endpoint.go index 4de54eceb..2d197be39 100644 --- a/consul/coordinate_endpoint.go +++ b/consul/coordinate_endpoint.go @@ -135,27 +135,6 @@ func (c *Coordinate) Get(args *structs.NodeSpecificRequest, }) } -// sorter wraps a coordinate list and implements the sort.Interface to sort by -// node name. -type sorter struct { - coordinates []structs.Coordinate -} - -// See sort.Interface. -func (s *sorter) Len() int { - return len(s.coordinates) -} - -// See sort.Interface. -func (s *sorter) Swap(i, j int) { - s.coordinates[i], s.coordinates[j] = s.coordinates[j], s.coordinates[i] -} - -// See sort.Interface. -func (s *sorter) Less(i, j int) bool { - return s.coordinates[i].Node < s.coordinates[j].Node -} - // ListDatacenters returns the list of datacenters and their respective nodes // and the raw coordinates of those nodes (if no coordinates are available for // any of the nodes, the node list may be empty). @@ -172,16 +151,13 @@ func (c *Coordinate) ListDatacenters(args *struct{}, reply *[]structs.Datacenter sort.Strings(dcs) maps := c.srv.getDatacenterMaps(dcs) - // Strip the datacenter suffixes from all the node names and then sort - // the sub-lists. + // Strip the datacenter suffixes from all the node names. for i := range maps { suffix := fmt.Sprintf(".%s", maps[i].Datacenter) for j := range maps[i].Coordinates { node := maps[i].Coordinates[j].Node maps[i].Coordinates[j].Node = strings.TrimSuffix(node, suffix) } - - sort.Sort(&sorter{maps[i].Coordinates}) } *reply = maps @@ -202,7 +178,6 @@ func (c *Coordinate) ListNodes(args *structs.DCSpecificRequest, reply *structs.I func() error { var err error reply.Index, reply.Coordinates, err = state.Coordinates() - sort.Sort(&sorter{reply.Coordinates}) return err }) } diff --git a/consul/coordinate_endpoint_test.go b/consul/coordinate_endpoint_test.go index 385994a88..977fd303f 100644 --- a/consul/coordinate_endpoint_test.go +++ b/consul/coordinate_endpoint_test.go @@ -270,8 +270,7 @@ func TestCoordinate_ListNodes(t *testing.T) { } time.Sleep(2 * s1.config.CoordinateUpdatePeriod) - // Now query back for all the nodes and make sure they are sorted - // properly. + // Now query back for all the nodes. arg := structs.DCSpecificRequest{ Datacenter: "dc1", }