command: adding client-servers command

This commit is contained in:
Ryan Uber
2015-09-24 21:31:15 -07:00
parent e6a3b4ec4f
commit 812e125349
3 changed files with 175 additions and 0 deletions

96
command/client_servers.go Normal file
View File

@@ -0,0 +1,96 @@
package command
import (
"fmt"
"strings"
)
type ClientServersCommand struct {
Meta
}
func (c *ClientServersCommand) Help() string {
helpText := `
Usage: nomad client-servers [options] [<address>...]
Query or modify the list of servers on a client node. Client
nodes do not participate in the gossip protocol, and register
with server nodes periodically over the network. This command
can be used to list or modify the set of servers Nomad speaks
to during this process.
Examples
$ nomad client-servers -update foo:4647 bar:4647 baz:4647
General Options:
` + generalOptionsUsage() + `
Client Server Options
-update
Updates the client's server list using the provided
arguments. Multiple server addresses may be passed using
multiple arguments. IMPORTANT: When updating the servers
list, you must specify ALL of the server nodes you wish
to configure. The set is updated atomically.
`
return strings.TrimSpace(helpText)
}
func (c *ClientServersCommand) Synopsis() string {
return "Query or modify the list of client servers"
}
func (c *ClientServersCommand) Run(args []string) int {
var update bool
flags := c.Meta.FlagSet("client-servers", FlagSetClient)
flags.Usage = func() { c.Ui.Output(c.Help()) }
flags.BoolVar(&update, "update", false, "")
if err := flags.Parse(args); err != nil {
return 1
}
// Check the flags for misuse
args = flags.Args()
if len(args) > 0 && !update {
c.Ui.Error(c.Help())
return 1
}
if len(args) == 0 && update {
c.Ui.Error(c.Help())
return 1
}
// Get the HTTP client
client, err := c.Meta.Client()
if err != nil {
c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
return 1
}
if update {
// Set the servers list
if err := client.Agent().SetServers(args); err != nil {
c.Ui.Error(fmt.Sprintf("Error updating server list: %s", err))
return 1
}
return 0
}
// Query the current server list
servers, err := client.Agent().Servers()
if err != nil {
c.Ui.Error(fmt.Sprintf("Error querying server list: %s", err))
return 1
}
// Print the results
for _, server := range servers {
c.Ui.Output(server)
}
return 0
}

View File

@@ -0,0 +1,73 @@
package command
import (
"strings"
"testing"
"github.com/hashicorp/nomad/testutil"
"github.com/mitchellh/cli"
)
func TestClientServersCommand_Implements(t *testing.T) {
var _ cli.Command = &ClientServersCommand{}
}
func TestClientServersCommand_Run(t *testing.T) {
srv, _, url := testServer(t, func(c *testutil.TestServerConfig) {
c.Client.Enabled = true
c.Server.BootstrapExpect = 0
})
defer srv.Stop()
ui := new(cli.MockUi)
cmd := &ClientServersCommand{Meta: Meta{Ui: ui}}
// Set the servers list
code := cmd.Run([]string{"-address=" + url, "-update", "foo", "bar"})
if code != 0 {
t.Fatalf("expected exit 0, got: %d", code)
}
// Query the servers list
code = cmd.Run([]string{"-address=" + url})
if code != 0 {
t.Fatalf("expect exit 0, got: %d", code)
}
out := ui.OutputWriter.String()
if !strings.Contains(out, "foo") {
t.Fatalf("missing foo")
}
if !strings.Contains(out, "bar") {
t.Fatalf("missing bar")
}
}
func TestClientServersCommand_Fails(t *testing.T) {
ui := new(cli.MockUi)
cmd := &ClientServersCommand{Meta: Meta{Ui: ui}}
// Fails on misuse
if code := cmd.Run([]string{"some", "bad", "args"}); code != 1 {
t.Fatalf("expected exit code 1, got: %d", code)
}
if out := ui.ErrorWriter.String(); !strings.Contains(out, cmd.Help()) {
t.Fatalf("expected help output, got: %s", out)
}
ui.ErrorWriter.Reset()
// Fails if updating with no servers
if code := cmd.Run([]string{"-update"}); code != 1 {
t.Fatalf("expected exit 1, got: %d", code)
}
if out := ui.ErrorWriter.String(); !strings.Contains(out, cmd.Help()) {
t.Fatalf("expected help output, got: %s", out)
}
// Fails on connection failure
if code := cmd.Run([]string{"-address=nope"}); code != 1 {
t.Fatalf("expected exit code 1, got: %d", code)
}
if out := ui.ErrorWriter.String(); !strings.Contains(out, "Error querying server list") {
t.Fatalf("expected failed query error, got: %s", out)
}
}

View File

@@ -40,6 +40,12 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory {
}, nil
},
"client-servers": func() (cli.Command, error) {
return &command.ClientServersCommand{
Meta: meta,
}, nil
},
"eval-monitor": func() (cli.Command, error) {
return &command.EvalMonitorCommand{
Meta: meta,