Convert snapshot command to use base.Command

pull/2726/head
Kyle Havlovitz 2017-02-09 20:00:38 -05:00
parent 8236af47ba
commit aa0d2502f8
No known key found for this signature in database
GPG Key ID: 8A5E6B173056AD6C
10 changed files with 81 additions and 60 deletions

View File

@ -136,6 +136,9 @@ func (c *Command) Parse(args []string) error {
// Help returns the help for this flagSet. // Help returns the help for this flagSet.
func (c *Command) Help() string { func (c *Command) Help() string {
if c.flagSet == nil {
return ""
}
return c.helpFlagsFor(c.flagSet) return c.helpFlagsFor(c.flagSet)
} }

View File

@ -2,20 +2,19 @@ package command
import ( import (
"bytes" "bytes"
"flag"
"fmt" "fmt"
"os" "os"
"strings" "strings"
"text/tabwriter" "text/tabwriter"
"github.com/hashicorp/consul/command/base"
"github.com/hashicorp/consul/snapshot" "github.com/hashicorp/consul/snapshot"
"github.com/mitchellh/cli"
) )
// SnapshotInspectCommand is a Command implementation that is used to display // SnapshotInspectCommand is a Command implementation that is used to display
// metadata about a snapshot file // metadata about a snapshot file
type SnapshotInspectCommand struct { type SnapshotInspectCommand struct {
Ui cli.Ui base.Command
} }
func (c *SnapshotInspectCommand) Help() string { func (c *SnapshotInspectCommand) Help() string {
@ -35,15 +34,15 @@ Usage: consul snapshot inspect [options] FILE
} }
func (c *SnapshotInspectCommand) Run(args []string) int { func (c *SnapshotInspectCommand) Run(args []string) int {
cmdFlags := flag.NewFlagSet("get", flag.ContinueOnError) flagSet := c.Command.NewFlagSet(c)
cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
if err := cmdFlags.Parse(args); err != nil { if err := c.Command.Parse(args); err != nil {
return 1 return 1
} }
var file string var file string
args = cmdFlags.Args() args = flagSet.Args()
switch len(args) { switch len(args) {
case 0: case 0:
c.Ui.Error("Missing FILE argument") c.Ui.Error("Missing FILE argument")

View File

@ -8,9 +8,20 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/hashicorp/consul/command/base"
"github.com/mitchellh/cli" "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) { func TestSnapshotInspectCommand_implements(t *testing.T) {
var _ cli.Command = &SnapshotInspectCommand{} var _ cli.Command = &SnapshotInspectCommand{}
} }
@ -20,8 +31,7 @@ func TestSnapshotInspectCommand_noTabs(t *testing.T) {
} }
func TestSnapshotInspectCommand_Validation(t *testing.T) { func TestSnapshotInspectCommand_Validation(t *testing.T) {
ui := new(cli.MockUi) ui, c := testSnapshotInspectCommand(t)
c := &SnapshotInspectCommand{Ui: ui}
cases := map[string]struct { cases := map[string]struct {
args []string args []string
@ -63,8 +73,6 @@ func TestSnapshotInspectCommand_Run(t *testing.T) {
defer srv.Shutdown() defer srv.Shutdown()
waitForLeader(t, srv.httpAddr) waitForLeader(t, srv.httpAddr)
ui := new(cli.MockUi)
dir, err := ioutil.TempDir("", "snapshot") dir, err := ioutil.TempDir("", "snapshot")
if err != nil { if err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
@ -93,10 +101,10 @@ func TestSnapshotInspectCommand_Run(t *testing.T) {
} }
// Inspect the snapshot // Inspect the snapshot
inspect := &SnapshotInspectCommand{Ui: ui} ui, c := testSnapshotInspectCommand(t)
args := []string{file} args := []string{file}
code := inspect.Run(args) code := c.Run(args)
if code != 0 { if code != 0 {
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String()) t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
} }

View File

@ -1,19 +1,17 @@
package command package command
import ( import (
"flag"
"fmt" "fmt"
"os" "os"
"strings" "strings"
"github.com/hashicorp/consul/api" "github.com/hashicorp/consul/command/base"
"github.com/mitchellh/cli"
) )
// SnapshotRestoreCommand is a Command implementation that is used to restore // SnapshotRestoreCommand is a Command implementation that is used to restore
// the state of the Consul servers for disaster recovery. // the state of the Consul servers for disaster recovery.
type SnapshotRestoreCommand struct { type SnapshotRestoreCommand struct {
Ui cli.Ui base.Command
} }
func (c *SnapshotRestoreCommand) Help() string { 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. For a full list of options and examples, please see the Consul documentation.
` + apiOptsText ` + c.Command.Help()
return strings.TrimSpace(helpText) return strings.TrimSpace(helpText)
} }
func (c *SnapshotRestoreCommand) Run(args []string) int { func (c *SnapshotRestoreCommand) Run(args []string) int {
cmdFlags := flag.NewFlagSet("get", flag.ContinueOnError) flagSet := c.Command.NewFlagSet(c)
cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
datacenter := cmdFlags.String("datacenter", "", "") if err := c.Command.Parse(args); err != nil {
token := cmdFlags.String("token", "", "")
httpAddr := HTTPAddrFlag(cmdFlags)
if err := cmdFlags.Parse(args); err != nil {
return 1 return 1
} }
var file string var file string
args = cmdFlags.Args() args = flagSet.Args()
switch len(args) { switch len(args) {
case 0: case 0:
c.Ui.Error("Missing FILE argument") c.Ui.Error("Missing FILE argument")
@ -68,11 +63,7 @@ func (c *SnapshotRestoreCommand) Run(args []string) int {
} }
// Create and test the HTTP client // Create and test the HTTP client
conf := api.DefaultConfig() client, err := c.Command.HTTPClient()
conf.Datacenter = *datacenter
conf.Address = *httpAddr
conf.Token = *token
client, err := api.NewClient(conf)
if err != nil { if err != nil {
c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err)) c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
return 1 return 1

View File

@ -8,9 +8,20 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/hashicorp/consul/command/base"
"github.com/mitchellh/cli" "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) { func TestSnapshotRestoreCommand_implements(t *testing.T) {
var _ cli.Command = &SnapshotRestoreCommand{} var _ cli.Command = &SnapshotRestoreCommand{}
} }
@ -20,8 +31,7 @@ func TestSnapshotRestoreCommand_noTabs(t *testing.T) {
} }
func TestSnapshotRestoreCommand_Validation(t *testing.T) { func TestSnapshotRestoreCommand_Validation(t *testing.T) {
ui := new(cli.MockUi) ui, c := testSnapshotRestoreCommand(t)
c := &SnapshotRestoreCommand{Ui: ui}
cases := map[string]struct { cases := map[string]struct {
args []string args []string
@ -63,8 +73,7 @@ func TestSnapshotRestoreCommand_Run(t *testing.T) {
defer srv.Shutdown() defer srv.Shutdown()
waitForLeader(t, srv.httpAddr) waitForLeader(t, srv.httpAddr)
ui := new(cli.MockUi) ui, c := testSnapshotRestoreCommand(t)
c := &SnapshotSaveCommand{Ui: ui}
dir, err := ioutil.TempDir("", "snapshot") dir, err := ioutil.TempDir("", "snapshot")
if err != nil { if err != nil {

View File

@ -1,21 +1,20 @@
package command package command
import ( import (
"flag"
"fmt" "fmt"
"io" "io"
"os" "os"
"strings" "strings"
"github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/command/base"
"github.com/hashicorp/consul/snapshot" "github.com/hashicorp/consul/snapshot"
"github.com/mitchellh/cli"
) )
// SnapshotSaveCommand is a Command implementation that is used to save the // SnapshotSaveCommand is a Command implementation that is used to save the
// state of the Consul servers for disaster recovery. // state of the Consul servers for disaster recovery.
type SnapshotSaveCommand struct { type SnapshotSaveCommand struct {
Ui cli.Ui base.Command
} }
func (c *SnapshotSaveCommand) Help() string { 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. For a full list of options and examples, please see the Consul documentation.
` + apiOptsText ` + c.Command.Help()
return strings.TrimSpace(helpText) return strings.TrimSpace(helpText)
} }
func (c *SnapshotSaveCommand) Run(args []string) int { func (c *SnapshotSaveCommand) Run(args []string) int {
cmdFlags := flag.NewFlagSet("get", flag.ContinueOnError) flagSet := c.Command.NewFlagSet(c)
cmdFlags.Usage = func() { c.Ui.Output(c.Help()) }
datacenter := cmdFlags.String("datacenter", "", "") if err := c.Command.Parse(args); err != nil {
token := cmdFlags.String("token", "", "")
stale := cmdFlags.Bool("stale", false, "")
httpAddr := HTTPAddrFlag(cmdFlags)
if err := cmdFlags.Parse(args); err != nil {
return 1 return 1
} }
var file string var file string
args = cmdFlags.Args() args = flagSet.Args()
switch len(args) { switch len(args) {
case 0: case 0:
c.Ui.Error("Missing FILE argument") c.Ui.Error("Missing FILE argument")
@ -71,11 +66,7 @@ func (c *SnapshotSaveCommand) Run(args []string) int {
} }
// Create and test the HTTP client // Create and test the HTTP client
conf := api.DefaultConfig() client, err := c.Command.HTTPClient()
conf.Datacenter = *datacenter
conf.Address = *httpAddr
conf.Token = *token
client, err := api.NewClient(conf)
if err != nil { if err != nil {
c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err)) c.Ui.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
return 1 return 1
@ -83,7 +74,7 @@ func (c *SnapshotSaveCommand) Run(args []string) int {
// Take the snapshot. // Take the snapshot.
snap, qm, err := client.Snapshot().Save(&api.QueryOptions{ snap, qm, err := client.Snapshot().Save(&api.QueryOptions{
AllowStale: *stale, AllowStale: c.Command.HTTPStale(),
}) })
if err != nil { if err != nil {
c.Ui.Error(fmt.Sprintf("Error saving snapshot: %s", err)) c.Ui.Error(fmt.Sprintf("Error saving snapshot: %s", err))

View File

@ -7,9 +7,20 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/hashicorp/consul/command/base"
"github.com/mitchellh/cli" "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) { func TestSnapshotSaveCommand_implements(t *testing.T) {
var _ cli.Command = &SnapshotSaveCommand{} var _ cli.Command = &SnapshotSaveCommand{}
} }
@ -19,8 +30,7 @@ func TestSnapshotSaveCommand_noTabs(t *testing.T) {
} }
func TestSnapshotSaveCommand_Validation(t *testing.T) { func TestSnapshotSaveCommand_Validation(t *testing.T) {
ui := new(cli.MockUi) ui, c := testSnapshotSaveCommand(t)
c := &SnapshotSaveCommand{Ui: ui}
cases := map[string]struct { cases := map[string]struct {
args []string args []string
@ -62,8 +72,7 @@ func TestSnapshotSaveCommand_Run(t *testing.T) {
defer srv.Shutdown() defer srv.Shutdown()
waitForLeader(t, srv.httpAddr) waitForLeader(t, srv.httpAddr)
ui := new(cli.MockUi) ui, c := testSnapshotSaveCommand(t)
c := &SnapshotSaveCommand{Ui: ui}
dir, err := ioutil.TempDir("", "snapshot") dir, err := ioutil.TempDir("", "snapshot")
if err != nil { if err != nil {

View File

@ -203,19 +203,28 @@ func init() {
"snapshot restore": func() (cli.Command, error) { "snapshot restore": func() (cli.Command, error) {
return &command.SnapshotRestoreCommand{ return &command.SnapshotRestoreCommand{
Command: base.Command{
Flags: base.FlagSetHTTP,
Ui: ui, Ui: ui,
},
}, nil }, nil
}, },
"snapshot save": func() (cli.Command, error) { "snapshot save": func() (cli.Command, error) {
return &command.SnapshotSaveCommand{ return &command.SnapshotSaveCommand{
Command: base.Command{
Flags: base.FlagSetHTTP,
Ui: ui, Ui: ui,
},
}, nil }, nil
}, },
"snapshot inspect": func() (cli.Command, error) { "snapshot inspect": func() (cli.Command, error) {
return &command.SnapshotInspectCommand{ return &command.SnapshotInspectCommand{
Command: base.Command{
Flags: base.FlagSetNone,
Ui: ui, Ui: ui,
},
}, nil }, nil
}, },

View File

@ -28,6 +28,7 @@ Usage: `consul snapshot restore [options] FILE`
#### API Options #### API Options
<%= partial "docs/commands/http_api_options_client" %> <%= partial "docs/commands/http_api_options_client" %>
<%= partial "docs/commands/http_api_options_server" %>
## Examples ## Examples

View File

@ -23,6 +23,7 @@ Usage: `consul snapshot save [options] FILE`
#### API Options #### API Options
<%= partial "docs/commands/http_api_options_client" %> <%= partial "docs/commands/http_api_options_client" %>
<%= partial "docs/commands/http_api_options_server" %>
## Examples ## Examples
@ -41,7 +42,7 @@ After the snapshot is written to the given file it is read back and verified for
integrity. integrity.
To create a potentially stale snapshot from any available server, use the stale To create a potentially stale snapshot from any available server, use the stale
consisentcy mode: consistency mode:
```text ```text
$ consul snapshot save -stale backup.snap $ consul snapshot save -stale backup.snap