diff --git a/command/commands.go b/command/commands.go index e9335a44ef..76812dfb98 100644 --- a/command/commands.go +++ b/command/commands.go @@ -24,6 +24,7 @@ import ( "github.com/hashicorp/consul/command/kvput" "github.com/hashicorp/consul/command/leave" "github.com/hashicorp/consul/command/lock" + "github.com/hashicorp/consul/command/maint" "github.com/hashicorp/consul/command/validate" "github.com/hashicorp/consul/version" "github.com/mitchellh/cli" @@ -127,12 +128,7 @@ func init() { }, "maint": func() (cli.Command, error) { - return &MaintCommand{ - BaseCommand: BaseCommand{ - Flags: FlagSetClientHTTP, - UI: ui, - }, - }, nil + return maint.New(ui), nil }, "members": func() (cli.Command, error) { diff --git a/command/maint.go b/command/maint/maint.go similarity index 80% rename from command/maint.go rename to command/maint/maint.go index 6043e9a850..fbc7e3c64b 100644 --- a/command/maint.go +++ b/command/maint/maint.go @@ -1,14 +1,21 @@ -package command +package maint import ( + "flag" "fmt" "strings" + + "github.com/hashicorp/consul/command/flags" + "github.com/mitchellh/cli" ) -// MaintCommand is a Command implementation that enables or disables +// cmd is a Command implementation that enables or disables // node or service maintenance mode. -type MaintCommand struct { - BaseCommand +type cmd struct { + UI cli.Ui + usage string + flags *flag.FlagSet + http *flags.HTTPFlags // flags enable bool @@ -17,50 +24,35 @@ type MaintCommand struct { serviceID string } -func (c *MaintCommand) initFlags() { - c.InitFlagSet() - c.FlagSet.BoolVar(&c.enable, "enable", false, +func New(ui cli.Ui) *cmd { + c := &cmd{UI: ui} + c.init() + return c +} + +func (c *cmd) init() { + c.flags = flag.NewFlagSet("", flag.ContinueOnError) + c.http = &flags.HTTPFlags{} + flags.Merge(c.flags, c.http.ClientFlags()) + + c.flags.BoolVar(&c.enable, "enable", false, "Enable maintenance mode.") - c.FlagSet.BoolVar(&c.disable, "disable", false, + c.flags.BoolVar(&c.disable, "disable", false, "Disable maintenance mode.") - c.FlagSet.StringVar(&c.reason, "reason", "", + c.flags.StringVar(&c.reason, "reason", "", "Text describing the maintenance reason.") - c.FlagSet.StringVar(&c.serviceID, "service", "", + c.flags.StringVar(&c.serviceID, "service", "", "Control maintenance mode for a specific service ID.") -} - -func (c *MaintCommand) Help() string { - c.initFlags() - return c.HelpCommand(` -Usage: consul maint [options] - Places a node or service into maintenance mode. During maintenance mode, - the node or service will be excluded from all queries through the DNS - or API interfaces, effectively taking it out of the pool of available - nodes. This is done by registering an additional critical health check. - - When enabling maintenance mode for a node or service, you may optionally - specify a reason string. This string will appear in the "Notes" field - of the critical health check which is registered against the node or - service. If no reason is provided, a default value will be used. - - Maintenance mode is persistent, and will be restored in the event of an - agent restart. It is therefore required to disable maintenance mode on - a given node or service before it will be placed back into the pool. - - By default, we operate on the node as a whole. By specifying the - "-service" argument, this behavior can be changed to enable or disable - only a specific service. - - If no arguments are given, the agent's maintenance status will be shown. - This will return blank if nothing is currently under maintenance. + c.usage = flags.Usage(usage, c.flags, c.http.ClientFlags(), nil) +} -`) +func (c *cmd) Help() string { + return c.usage } -func (c *MaintCommand) Run(args []string) int { - c.initFlags() - if err := c.FlagSet.Parse(args); err != nil { +func (c *cmd) Run(args []string) int { + if err := c.flags.Parse(args); err != nil { return 1 } @@ -79,7 +71,7 @@ func (c *MaintCommand) Run(args []string) int { } // Create and test the HTTP client - client, err := c.HTTPClient() + client, err := c.http.APIClient() if err != nil { c.UI.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err)) return 1 @@ -159,6 +151,31 @@ func (c *MaintCommand) Run(args []string) int { return 0 } -func (c *MaintCommand) Synopsis() string { +func (c *cmd) Synopsis() string { return "Controls node or service maintenance mode" } + +const usage = `Usage: consul maint [options] + + Places a node or service into maintenance mode. During maintenance mode, + the node or service will be excluded from all queries through the DNS + or API interfaces, effectively taking it out of the pool of available + nodes. This is done by registering an additional critical health check. + + When enabling maintenance mode for a node or service, you may optionally + specify a reason string. This string will appear in the "Notes" field + of the critical health check which is registered against the node or + service. If no reason is provided, a default value will be used. + + Maintenance mode is persistent, and will be restored in the event of an + agent restart. It is therefore required to disable maintenance mode on + a given node or service before it will be placed back into the pool. + + By default, we operate on the node as a whole. By specifying the + "-service" argument, this behavior can be changed to enable or disable + only a specific service. + + If no arguments are given, the agent's maintenance status will be shown. + This will return blank if nothing is currently under maintenance. + +` diff --git a/command/maint_test.go b/command/maint/maint_test.go similarity index 89% rename from command/maint_test.go rename to command/maint/maint_test.go index 495b8aee68..34d28cff57 100644 --- a/command/maint_test.go +++ b/command/maint/maint_test.go @@ -1,4 +1,4 @@ -package command +package maint import ( "strings" @@ -9,24 +9,11 @@ import ( "github.com/mitchellh/cli" ) -func testMaintCommand(t *testing.T) (*cli.MockUi, *MaintCommand) { - ui := cli.NewMockUi() - return ui, &MaintCommand{ - BaseCommand: BaseCommand{ - UI: ui, - Flags: FlagSetClientHTTP, - }, - } -} - -func TestMaintCommand_implements(t *testing.T) { - t.Parallel() - var _ cli.Command = &MaintCommand{} -} - func TestMaintCommandRun_ConflictingArgs(t *testing.T) { t.Parallel() - _, c := testMaintCommand(t) + ui := cli.NewMockUi() + c := New(ui) + c.flags.SetOutput(ui.ErrorWriter) if code := c.Run([]string{"-enable", "-disable"}); code != 1 { t.Fatalf("expected return code 1, got %d", code) @@ -66,7 +53,9 @@ func TestMaintCommandRun_NoArgs(t *testing.T) { a.EnableNodeMaintenance("broken 2", "") // Run consul maint with no args (list mode) - ui, c := testMaintCommand(t) + ui := cli.NewMockUi() + c := New(ui) + c.flags.SetOutput(ui.ErrorWriter) args := []string{"-http-addr=" + a.HTTPAddr()} code := c.Run(args) @@ -97,7 +86,9 @@ func TestMaintCommandRun_EnableNodeMaintenance(t *testing.T) { a := agent.NewTestAgent(t.Name(), ``) defer a.Shutdown() - ui, c := testMaintCommand(t) + ui := cli.NewMockUi() + c := New(ui) + c.flags.SetOutput(ui.ErrorWriter) args := []string{ "-http-addr=" + a.HTTPAddr(), @@ -119,7 +110,9 @@ func TestMaintCommandRun_DisableNodeMaintenance(t *testing.T) { a := agent.NewTestAgent(t.Name(), ``) defer a.Shutdown() - ui, c := testMaintCommand(t) + ui := cli.NewMockUi() + c := New(ui) + c.flags.SetOutput(ui.ErrorWriter) args := []string{ "-http-addr=" + a.HTTPAddr(), @@ -149,7 +142,9 @@ func TestMaintCommandRun_EnableServiceMaintenance(t *testing.T) { t.Fatalf("err: %v", err) } - ui, c := testMaintCommand(t) + ui := cli.NewMockUi() + c := New(ui) + c.flags.SetOutput(ui.ErrorWriter) args := []string{ "-http-addr=" + a.HTTPAddr(), @@ -181,7 +176,9 @@ func TestMaintCommandRun_DisableServiceMaintenance(t *testing.T) { t.Fatalf("err: %v", err) } - ui, c := testMaintCommand(t) + ui := cli.NewMockUi() + c := New(ui) + c.flags.SetOutput(ui.ErrorWriter) args := []string{ "-http-addr=" + a.HTTPAddr(), @@ -203,7 +200,9 @@ func TestMaintCommandRun_ServiceMaintenance_NoService(t *testing.T) { a := agent.NewTestAgent(t.Name(), ``) defer a.Shutdown() - ui, c := testMaintCommand(t) + ui := cli.NewMockUi() + c := New(ui) + c.flags.SetOutput(ui.ErrorWriter) args := []string{ "-http-addr=" + a.HTTPAddr(),