mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 18:35:44 +03:00
command: adding client-servers command
This commit is contained in:
96
command/client_servers.go
Normal file
96
command/client_servers.go
Normal 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
|
||||
}
|
||||
73
command/client_servers_test.go
Normal file
73
command/client_servers_test.go
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user