diff --git a/command/commands.go b/command/commands.go index f044a2ffd..295a611ab 100644 --- a/command/commands.go +++ b/command/commands.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/consul/command/event" execmd "github.com/hashicorp/consul/command/exec" + "github.com/hashicorp/consul/command/forceleave" "github.com/hashicorp/consul/command/info" "github.com/hashicorp/consul/command/join" "github.com/hashicorp/consul/command/keygen" @@ -91,12 +92,7 @@ func init() { }, "force-leave": func() (cli.Command, error) { - return &ForceLeaveCommand{ - BaseCommand: BaseCommand{ - Flags: FlagSetClientHTTP, - UI: ui, - }, - }, nil + return forceleave.New(ui), nil }, "info": func() (cli.Command, error) { diff --git a/command/force_leave.go b/command/forceleave/forceleave.go similarity index 51% rename from command/force_leave.go rename to command/forceleave/forceleave.go index 1e9a45b51..6359c56c5 100644 --- a/command/force_leave.go +++ b/command/forceleave/forceleave.go @@ -1,22 +1,38 @@ -package command +package forceleave import ( + "flag" "fmt" + + "github.com/hashicorp/consul/command/flags" + "github.com/mitchellh/cli" ) -// ForceLeaveCommand is a Command implementation that tells a running Consul -// to force a member to enter the "left" state. -type ForceLeaveCommand struct { - BaseCommand +func New(ui cli.Ui) *cmd { + c := &cmd{UI: ui} + c.initFlags() + return c } -func (c *ForceLeaveCommand) Run(args []string) int { - c.InitFlagSet() - if err := c.FlagSet.Parse(args); err != nil { +type cmd struct { + UI cli.Ui + flags *flag.FlagSet + http *flags.HTTPFlags +} + +func (c *cmd) initFlags() { + c.flags = flag.NewFlagSet("", flag.ContinueOnError) + c.http = &flags.HTTPFlags{} + flags.Merge(c.flags, c.http.ClientFlags()) + flags.Merge(c.flags, c.http.ServerFlags()) +} + +func (c *cmd) Run(args []string) int { + if err := c.flags.Parse(args); err != nil { return 1 } - nodes := c.FlagSet.Args() + nodes := c.flags.Args() if len(nodes) != 1 { c.UI.Error("A single node name must be specified to force leave.") c.UI.Error("") @@ -24,7 +40,7 @@ func (c *ForceLeaveCommand) Run(args []string) int { return 1 } - 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 @@ -39,21 +55,19 @@ func (c *ForceLeaveCommand) Run(args []string) int { return 0 } -func (c *ForceLeaveCommand) Help() string { - c.InitFlagSet() - return c.HelpCommand(` -Usage: consul force-leave [options] name +func (c *cmd) Synopsis() string { + return "Forces a member of the cluster to enter the \"left\" state" +} + +func (c *cmd) Help() string { + s := `Usage: consul force-leave [options] name Forces a member of a Consul cluster to enter the "left" state. Note that if the member is still actually alive, it will eventually rejoin the cluster. This command is most useful for cleaning out "failed" nodes that are never coming back. If you do not force leave a failed node, Consul will attempt to reconnect to those failed nodes for some period of - time before eventually reaping them. + time before eventually reaping them.` -`) -} - -func (c *ForceLeaveCommand) Synopsis() string { - return "Forces a member of the cluster to enter the \"left\" state" + return flags.Usage(s, c.flags, c.http.ClientFlags(), c.http.ServerFlags()) } diff --git a/command/force_leave_test.go b/command/forceleave/forceleave_test.go similarity index 78% rename from command/force_leave_test.go rename to command/forceleave/forceleave_test.go index 14438becb..5d5a146e5 100644 --- a/command/force_leave_test.go +++ b/command/forceleave/forceleave_test.go @@ -1,4 +1,4 @@ -package command +package forceleave import ( "strings" @@ -10,19 +10,11 @@ import ( "github.com/mitchellh/cli" ) -func testForceLeaveCommand(t *testing.T) (*cli.MockUi, *ForceLeaveCommand) { - ui := cli.NewMockUi() - return ui, &ForceLeaveCommand{ - BaseCommand: BaseCommand{ - UI: ui, - Flags: FlagSetClientHTTP, - }, - } -} - -func TestForceLeaveCommand_implements(t *testing.T) { +func TestForceLeaveCommand_noTabs(t *testing.T) { t.Parallel() - var _ cli.Command = &ForceLeaveCommand{} + if strings.ContainsRune(New(nil).Help(), '\t') { + t.Fatal("usage has tabs") + } } func TestForceLeaveCommandRun(t *testing.T) { @@ -40,7 +32,8 @@ func TestForceLeaveCommandRun(t *testing.T) { // Forcibly shutdown a2 so that it appears "failed" in a1 a2.Shutdown() - ui, c := testForceLeaveCommand(t) + ui := cli.NewMockUi() + c := New(ui) args := []string{ "-http-addr=" + a1.HTTPAddr(), a2.Config.NodeName, @@ -66,7 +59,7 @@ func TestForceLeaveCommandRun(t *testing.T) { func TestForceLeaveCommandRun_noAddrs(t *testing.T) { t.Parallel() ui := cli.NewMockUi() - ui, c := testForceLeaveCommand(t) + c := New(ui) args := []string{"-http-addr=foo"} code := c.Run(args)