Merge pull request #323 from gregory-m/order-agent-members

Sort server-members output using name and tags
This commit is contained in:
Alex Dadgar
2015-10-23 11:38:27 -07:00
3 changed files with 139 additions and 0 deletions

View File

@@ -178,3 +178,22 @@ type AgentMember struct {
DelegateMax uint8
DelegateCur uint8
}
// AgentMembersNameSort implements sort.Interface for []*AgentMembersNameSort
// based on the Name, DC and Region
type AgentMembersNameSort []*AgentMember
func (a AgentMembersNameSort) Len() int { return len(a) }
func (a AgentMembersNameSort) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a AgentMembersNameSort) Less(i, j int) bool {
if a[i].Tags["region"] != a[j].Tags["region"] {
return a[i].Tags["region"] < a[j].Tags["region"]
}
if a[i].Tags["dc"] != a[j].Tags["dc"] {
return a[i].Tags["dc"] < a[j].Tags["dc"]
}
return a[i].Name < a[j].Name
}

View File

@@ -1,6 +1,8 @@
package api
import (
"reflect"
"sort"
"testing"
"github.com/hashicorp/nomad/testutil"
@@ -154,3 +156,117 @@ func TestAgent_SetServers(t *testing.T) {
t.Fatalf("bad server list: %v", out)
}
}
func (a *AgentMember) String() string {
return "{Name: " + a.Name + " Region: " + a.Tags["region"] + " DC: " + a.Tags["dc"] + "}"
}
func TestAgents_Sort(t *testing.T) {
var sortTests = []struct {
in []*AgentMember
out []*AgentMember
}{
{
[]*AgentMember{
&AgentMember{Name: "nomad-2.vac.us-east",
Tags: map[string]string{"region": "us-east", "dc": "us-east-1c"}},
&AgentMember{Name: "nomad-1.global",
Tags: map[string]string{"region": "global", "dc": "dc1"}},
&AgentMember{Name: "nomad-1.vac.us-east",
Tags: map[string]string{"region": "us-east", "dc": "us-east-1c"}},
},
[]*AgentMember{
&AgentMember{Name: "nomad-1.global",
Tags: map[string]string{"region": "global", "dc": "dc1"}},
&AgentMember{Name: "nomad-1.vac.us-east",
Tags: map[string]string{"region": "us-east", "dc": "us-east-1c"}},
&AgentMember{Name: "nomad-2.vac.us-east",
Tags: map[string]string{"region": "us-east", "dc": "us-east-1c"}},
},
},
{
[]*AgentMember{
&AgentMember{Name: "nomad-02.tam.us-east",
Tags: map[string]string{"region": "us-east", "dc": "tampa"}},
&AgentMember{Name: "nomad-02.pal.us-west",
Tags: map[string]string{"region": "us-west", "dc": "palo_alto"}},
&AgentMember{Name: "nomad-01.pal.us-west",
Tags: map[string]string{"region": "us-west", "dc": "palo_alto"}},
&AgentMember{Name: "nomad-01.tam.us-east",
Tags: map[string]string{"region": "us-east", "dc": "tampa"}},
},
[]*AgentMember{
&AgentMember{Name: "nomad-01.tam.us-east",
Tags: map[string]string{"region": "us-east", "dc": "tampa"}},
&AgentMember{Name: "nomad-02.tam.us-east",
Tags: map[string]string{"region": "us-east", "dc": "tampa"}},
&AgentMember{Name: "nomad-01.pal.us-west",
Tags: map[string]string{"region": "us-west", "dc": "palo_alto"}},
&AgentMember{Name: "nomad-02.pal.us-west",
Tags: map[string]string{"region": "us-west", "dc": "palo_alto"}},
},
},
{
[]*AgentMember{
&AgentMember{Name: "nomad-02.tam.us-east",
Tags: map[string]string{"region": "us-east", "dc": "tampa"}},
&AgentMember{Name: "nomad-02.ams.europe",
Tags: map[string]string{"region": "europe", "dc": "amsterdam"}},
&AgentMember{Name: "nomad-01.tam.us-east",
Tags: map[string]string{"region": "us-east", "dc": "tampa"}},
&AgentMember{Name: "nomad-01.ams.europe",
Tags: map[string]string{"region": "europe", "dc": "amsterdam"}},
},
[]*AgentMember{
&AgentMember{Name: "nomad-01.ams.europe",
Tags: map[string]string{"region": "europe", "dc": "amsterdam"}},
&AgentMember{Name: "nomad-02.ams.europe",
Tags: map[string]string{"region": "europe", "dc": "amsterdam"}},
&AgentMember{Name: "nomad-01.tam.us-east",
Tags: map[string]string{"region": "us-east", "dc": "tampa"}},
&AgentMember{Name: "nomad-02.tam.us-east",
Tags: map[string]string{"region": "us-east", "dc": "tampa"}},
},
},
{
[]*AgentMember{
&AgentMember{Name: "nomad-02.ber.europe",
Tags: map[string]string{"region": "europe", "dc": "berlin"}},
&AgentMember{Name: "nomad-02.ams.europe",
Tags: map[string]string{"region": "europe", "dc": "amsterdam"}},
&AgentMember{Name: "nomad-01.ams.europe",
Tags: map[string]string{"region": "europe", "dc": "amsterdam"}},
&AgentMember{Name: "nomad-01.ber.europe",
Tags: map[string]string{"region": "europe", "dc": "berlin"}},
},
[]*AgentMember{
&AgentMember{Name: "nomad-01.ams.europe",
Tags: map[string]string{"region": "europe", "dc": "amsterdam"}},
&AgentMember{Name: "nomad-02.ams.europe",
Tags: map[string]string{"region": "europe", "dc": "amsterdam"}},
&AgentMember{Name: "nomad-01.ber.europe",
Tags: map[string]string{"region": "europe", "dc": "berlin"}},
&AgentMember{Name: "nomad-02.ber.europe",
Tags: map[string]string{"region": "europe", "dc": "berlin"}},
},
},
{
[]*AgentMember{
&AgentMember{Name: "nomad-1.global"},
&AgentMember{Name: "nomad-3.global"},
&AgentMember{Name: "nomad-2.global"},
},
[]*AgentMember{
&AgentMember{Name: "nomad-1.global"},
&AgentMember{Name: "nomad-2.global"},
&AgentMember{Name: "nomad-3.global"},
},
},
}
for _, tt := range sortTests {
sort.Sort(AgentMembersNameSort(tt.in))
if !reflect.DeepEqual(tt.in, tt.out) {
t.Errorf("\necpected: %s\nget : %s", tt.in, tt.out)
}
}
}

View File

@@ -2,6 +2,7 @@ package command
import (
"fmt"
"sort"
"strings"
"github.com/hashicorp/nomad/api"
@@ -68,6 +69,9 @@ func (c *ServerMembersCommand) Run(args []string) int {
return 1
}
// Sort the members
sort.Sort(api.AgentMembersNameSort(mem))
// Format the list
var out []string
if detailed {