From aa0d2502f8dd467102b106ae415c2bf4c5a4d03b Mon Sep 17 00:00:00 2001 From: Kyle Havlovitz Date: Thu, 9 Feb 2017 20:00:38 -0500 Subject: [PATCH] Convert snapshot command to use base.Command --- command/base/command.go | 3 +++ command/snapshot_inspect.go | 13 +++++---- command/snapshot_inspect_test.go | 20 +++++++++----- command/snapshot_restore.go | 25 ++++++----------- command/snapshot_restore_test.go | 17 +++++++++--- command/snapshot_save.go | 27 +++++++------------ command/snapshot_save_test.go | 17 +++++++++--- commands.go | 15 ++++++++--- .../snapshot/restore.html.markdown.erb | 1 + .../commands/snapshot/save.html.markdown.erb | 3 ++- 10 files changed, 81 insertions(+), 60 deletions(-) diff --git a/command/base/command.go b/command/base/command.go index 87cc37ba4a..804564b02e 100644 --- a/command/base/command.go +++ b/command/base/command.go @@ -136,6 +136,9 @@ func (c *Command) Parse(args []string) error { // Help returns the help for this flagSet. func (c *Command) Help() string { + if c.flagSet == nil { + return "" + } return c.helpFlagsFor(c.flagSet) } diff --git a/command/snapshot_inspect.go b/command/snapshot_inspect.go index aaeab2445f..88b5680835 100644 --- a/command/snapshot_inspect.go +++ b/command/snapshot_inspect.go @@ -2,20 +2,19 @@ package command import ( "bytes" - "flag" "fmt" "os" "strings" "text/tabwriter" + "github.com/hashicorp/consul/command/base" "github.com/hashicorp/consul/snapshot" - "github.com/mitchellh/cli" ) // SnapshotInspectCommand is a Command implementation that is used to display // metadata about a snapshot file type SnapshotInspectCommand struct { - Ui cli.Ui + base.Command } func (c *SnapshotInspectCommand) Help() string { @@ -35,15 +34,15 @@ Usage: consul snapshot inspect [options] FILE } func (c *SnapshotInspectCommand) Run(args []string) int { - cmdFlags := flag.NewFlagSet("get", flag.ContinueOnError) - cmdFlags.Usage = func() { c.Ui.Output(c.Help()) } - if err := cmdFlags.Parse(args); err != nil { + flagSet := c.Command.NewFlagSet(c) + + if err := c.Command.Parse(args); err != nil { return 1 } var file string - args = cmdFlags.Args() + args = flagSet.Args() switch len(args) { case 0: c.Ui.Error("Missing FILE argument") diff --git a/command/snapshot_inspect_test.go b/command/snapshot_inspect_test.go index 557d3ba822..282927469d 100644 --- a/command/snapshot_inspect_test.go +++ b/command/snapshot_inspect_test.go @@ -8,9 +8,20 @@ import ( "strings" "testing" + "github.com/hashicorp/consul/command/base" "github.com/mitchellh/cli" ) +func testSnapshotInspectCommand(t *testing.T) (*cli.MockUi, *SnapshotInspectCommand) { + ui := new(cli.MockUi) + return ui, &SnapshotInspectCommand{ + Command: base.Command{ + Ui: ui, + Flags: base.FlagSetNone, + }, + } +} + func TestSnapshotInspectCommand_implements(t *testing.T) { var _ cli.Command = &SnapshotInspectCommand{} } @@ -20,8 +31,7 @@ func TestSnapshotInspectCommand_noTabs(t *testing.T) { } func TestSnapshotInspectCommand_Validation(t *testing.T) { - ui := new(cli.MockUi) - c := &SnapshotInspectCommand{Ui: ui} + ui, c := testSnapshotInspectCommand(t) cases := map[string]struct { args []string @@ -63,8 +73,6 @@ func TestSnapshotInspectCommand_Run(t *testing.T) { defer srv.Shutdown() waitForLeader(t, srv.httpAddr) - ui := new(cli.MockUi) - dir, err := ioutil.TempDir("", "snapshot") if err != nil { t.Fatalf("err: %v", err) @@ -93,10 +101,10 @@ func TestSnapshotInspectCommand_Run(t *testing.T) { } // Inspect the snapshot - inspect := &SnapshotInspectCommand{Ui: ui} + ui, c := testSnapshotInspectCommand(t) args := []string{file} - code := inspect.Run(args) + code := c.Run(args) if code != 0 { t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String()) } diff --git a/command/snapshot_restore.go b/command/snapshot_restore.go index 7ca8ff6655..ade002b38d 100644 --- a/command/snapshot_restore.go +++ b/command/snapshot_restore.go @@ -1,19 +1,17 @@ package command import ( - "flag" "fmt" "os" "strings" - "github.com/hashicorp/consul/api" - "github.com/mitchellh/cli" + "github.com/hashicorp/consul/command/base" ) // SnapshotRestoreCommand is a Command implementation that is used to restore // the state of the Consul servers for disaster recovery. type SnapshotRestoreCommand struct { - Ui cli.Ui + base.Command } func (c *SnapshotRestoreCommand) Help() string { @@ -38,24 +36,21 @@ Usage: consul snapshot restore [options] FILE For a full list of options and examples, please see the Consul documentation. -` + apiOptsText +` + c.Command.Help() return strings.TrimSpace(helpText) } func (c *SnapshotRestoreCommand) Run(args []string) int { - cmdFlags := flag.NewFlagSet("get", flag.ContinueOnError) - cmdFlags.Usage = func() { c.Ui.Output(c.Help()) } - datacenter := cmdFlags.String("datacenter", "", "") - token := cmdFlags.String("token", "", "") - httpAddr := HTTPAddrFlag(cmdFlags) - if err := cmdFlags.Parse(args); err != nil { + flagSet := c.Command.NewFlagSet(c) + + if err := c.Command.Parse(args); err != nil { return 1 } var file string - args = cmdFlags.Args() + args = flagSet.Args() switch len(args) { case 0: c.Ui.Error("Missing FILE argument") @@ -68,11 +63,7 @@ func (c *SnapshotRestoreCommand) Run(args []string) int { } // Create and test the HTTP client - conf := api.DefaultConfig() - conf.Datacenter = *datacenter - conf.Address = *httpAddr - conf.Token = *token - client, err := api.NewClient(conf) + client, err := c.Command.HTTPClient() if err != nil { c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err)) return 1 diff --git a/command/snapshot_restore_test.go b/command/snapshot_restore_test.go index e9f1b4ae6b..c8013bdb49 100644 --- a/command/snapshot_restore_test.go +++ b/command/snapshot_restore_test.go @@ -8,9 +8,20 @@ import ( "strings" "testing" + "github.com/hashicorp/consul/command/base" "github.com/mitchellh/cli" ) +func testSnapshotRestoreCommand(t *testing.T) (*cli.MockUi, *SnapshotRestoreCommand) { + ui := new(cli.MockUi) + return ui, &SnapshotRestoreCommand{ + Command: base.Command{ + Ui: ui, + Flags: base.FlagSetHTTP, + }, + } +} + func TestSnapshotRestoreCommand_implements(t *testing.T) { var _ cli.Command = &SnapshotRestoreCommand{} } @@ -20,8 +31,7 @@ func TestSnapshotRestoreCommand_noTabs(t *testing.T) { } func TestSnapshotRestoreCommand_Validation(t *testing.T) { - ui := new(cli.MockUi) - c := &SnapshotRestoreCommand{Ui: ui} + ui, c := testSnapshotRestoreCommand(t) cases := map[string]struct { args []string @@ -63,8 +73,7 @@ func TestSnapshotRestoreCommand_Run(t *testing.T) { defer srv.Shutdown() waitForLeader(t, srv.httpAddr) - ui := new(cli.MockUi) - c := &SnapshotSaveCommand{Ui: ui} + ui, c := testSnapshotRestoreCommand(t) dir, err := ioutil.TempDir("", "snapshot") if err != nil { diff --git a/command/snapshot_save.go b/command/snapshot_save.go index ddfa56a118..7a325a80a6 100644 --- a/command/snapshot_save.go +++ b/command/snapshot_save.go @@ -1,21 +1,20 @@ package command import ( - "flag" "fmt" "io" "os" "strings" "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/command/base" "github.com/hashicorp/consul/snapshot" - "github.com/mitchellh/cli" ) // SnapshotSaveCommand is a Command implementation that is used to save the // state of the Consul servers for disaster recovery. type SnapshotSaveCommand struct { - Ui cli.Ui + base.Command } func (c *SnapshotSaveCommand) Help() string { @@ -40,25 +39,21 @@ Usage: consul snapshot save [options] FILE For a full list of options and examples, please see the Consul documentation. -` + apiOptsText +` + c.Command.Help() return strings.TrimSpace(helpText) } func (c *SnapshotSaveCommand) Run(args []string) int { - cmdFlags := flag.NewFlagSet("get", flag.ContinueOnError) - cmdFlags.Usage = func() { c.Ui.Output(c.Help()) } - datacenter := cmdFlags.String("datacenter", "", "") - token := cmdFlags.String("token", "", "") - stale := cmdFlags.Bool("stale", false, "") - httpAddr := HTTPAddrFlag(cmdFlags) - if err := cmdFlags.Parse(args); err != nil { + flagSet := c.Command.NewFlagSet(c) + + if err := c.Command.Parse(args); err != nil { return 1 } var file string - args = cmdFlags.Args() + args = flagSet.Args() switch len(args) { case 0: c.Ui.Error("Missing FILE argument") @@ -71,11 +66,7 @@ func (c *SnapshotSaveCommand) Run(args []string) int { } // Create and test the HTTP client - conf := api.DefaultConfig() - conf.Datacenter = *datacenter - conf.Address = *httpAddr - conf.Token = *token - client, err := api.NewClient(conf) + client, err := c.Command.HTTPClient() if err != nil { c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err)) return 1 @@ -83,7 +74,7 @@ func (c *SnapshotSaveCommand) Run(args []string) int { // Take the snapshot. snap, qm, err := client.Snapshot().Save(&api.QueryOptions{ - AllowStale: *stale, + AllowStale: c.Command.HTTPStale(), }) if err != nil { c.Ui.Error(fmt.Sprintf("Error saving snapshot: %s", err)) diff --git a/command/snapshot_save_test.go b/command/snapshot_save_test.go index e1eeb87c63..d4edf37aac 100644 --- a/command/snapshot_save_test.go +++ b/command/snapshot_save_test.go @@ -7,9 +7,20 @@ import ( "strings" "testing" + "github.com/hashicorp/consul/command/base" "github.com/mitchellh/cli" ) +func testSnapshotSaveCommand(t *testing.T) (*cli.MockUi, *SnapshotSaveCommand) { + ui := new(cli.MockUi) + return ui, &SnapshotSaveCommand{ + Command: base.Command{ + Ui: ui, + Flags: base.FlagSetHTTP, + }, + } +} + func TestSnapshotSaveCommand_implements(t *testing.T) { var _ cli.Command = &SnapshotSaveCommand{} } @@ -19,8 +30,7 @@ func TestSnapshotSaveCommand_noTabs(t *testing.T) { } func TestSnapshotSaveCommand_Validation(t *testing.T) { - ui := new(cli.MockUi) - c := &SnapshotSaveCommand{Ui: ui} + ui, c := testSnapshotSaveCommand(t) cases := map[string]struct { args []string @@ -62,8 +72,7 @@ func TestSnapshotSaveCommand_Run(t *testing.T) { defer srv.Shutdown() waitForLeader(t, srv.httpAddr) - ui := new(cli.MockUi) - c := &SnapshotSaveCommand{Ui: ui} + ui, c := testSnapshotSaveCommand(t) dir, err := ioutil.TempDir("", "snapshot") if err != nil { diff --git a/commands.go b/commands.go index fe090bfa6c..e339c5642e 100644 --- a/commands.go +++ b/commands.go @@ -203,19 +203,28 @@ func init() { "snapshot restore": func() (cli.Command, error) { return &command.SnapshotRestoreCommand{ - Ui: ui, + Command: base.Command{ + Flags: base.FlagSetHTTP, + Ui: ui, + }, }, nil }, "snapshot save": func() (cli.Command, error) { return &command.SnapshotSaveCommand{ - Ui: ui, + Command: base.Command{ + Flags: base.FlagSetHTTP, + Ui: ui, + }, }, nil }, "snapshot inspect": func() (cli.Command, error) { return &command.SnapshotInspectCommand{ - Ui: ui, + Command: base.Command{ + Flags: base.FlagSetNone, + Ui: ui, + }, }, nil }, diff --git a/website/source/docs/commands/snapshot/restore.html.markdown.erb b/website/source/docs/commands/snapshot/restore.html.markdown.erb index 8a28440ad3..27c0f6e5b0 100644 --- a/website/source/docs/commands/snapshot/restore.html.markdown.erb +++ b/website/source/docs/commands/snapshot/restore.html.markdown.erb @@ -28,6 +28,7 @@ Usage: `consul snapshot restore [options] FILE` #### API Options <%= partial "docs/commands/http_api_options_client" %> +<%= partial "docs/commands/http_api_options_server" %> ## Examples diff --git a/website/source/docs/commands/snapshot/save.html.markdown.erb b/website/source/docs/commands/snapshot/save.html.markdown.erb index e6029172ad..14033c8e18 100644 --- a/website/source/docs/commands/snapshot/save.html.markdown.erb +++ b/website/source/docs/commands/snapshot/save.html.markdown.erb @@ -23,6 +23,7 @@ Usage: `consul snapshot save [options] FILE` #### API Options <%= partial "docs/commands/http_api_options_client" %> +<%= partial "docs/commands/http_api_options_server" %> ## Examples @@ -41,7 +42,7 @@ After the snapshot is written to the given file it is read back and verified for integrity. To create a potentially stale snapshot from any available server, use the stale -consisentcy mode: +consistency mode: ```text $ consul snapshot save -stale backup.snap