1package restore
2
3import (
4	"flag"
5	"fmt"
6	"os"
7
8	"github.com/hashicorp/consul/command/flags"
9	"github.com/mitchellh/cli"
10)
11
12func New(ui cli.Ui) *cmd {
13	c := &cmd{UI: ui}
14	c.init()
15	return c
16}
17
18type cmd struct {
19	UI    cli.Ui
20	flags *flag.FlagSet
21	http  *flags.HTTPFlags
22	help  string
23}
24
25func (c *cmd) init() {
26	c.flags = flag.NewFlagSet("", flag.ContinueOnError)
27	c.http = &flags.HTTPFlags{}
28	flags.Merge(c.flags, c.http.ClientFlags())
29	flags.Merge(c.flags, c.http.ServerFlags())
30	c.help = flags.Usage(help, c.flags)
31}
32
33func (c *cmd) Run(args []string) int {
34	if err := c.flags.Parse(args); err != nil {
35		return 1
36	}
37
38	var file string
39
40	args = c.flags.Args()
41	switch len(args) {
42	case 0:
43		c.UI.Error("Missing FILE argument")
44		return 1
45	case 1:
46		file = args[0]
47	default:
48		c.UI.Error(fmt.Sprintf("Too many arguments (expected 1, got %d)", len(args)))
49		return 1
50	}
51
52	// Create and test the HTTP client
53	client, err := c.http.APIClient()
54	if err != nil {
55		c.UI.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
56		return 1
57	}
58
59	// Open the file.
60	f, err := os.Open(file)
61	if err != nil {
62		c.UI.Error(fmt.Sprintf("Error opening snapshot file: %s", err))
63		return 1
64	}
65	defer f.Close()
66
67	// Restore the snapshot.
68	err = client.Snapshot().Restore(nil, f)
69	if err != nil {
70		c.UI.Error(fmt.Sprintf("Error restoring snapshot: %s", err))
71		return 1
72	}
73
74	c.UI.Info("Restored snapshot")
75	return 0
76}
77
78func (c *cmd) Synopsis() string {
79	return synopsis
80}
81
82func (c *cmd) Help() string {
83	return c.help
84}
85
86const synopsis = "Restores snapshot of Consul server state"
87const help = `
88Usage: consul snapshot restore [options] FILE
89
90  Restores an atomic, point-in-time snapshot of the state of the Consul servers
91  which includes key/value entries, service catalog, prepared queries, sessions,
92  and ACLs.
93
94  Restores involve a potentially dangerous low-level Raft operation that is not
95  designed to handle server failures during a restore. This command is primarily
96  intended to be used when recovering from a disaster, restoring into a fresh
97  cluster of Consul servers.
98
99  If ACLs are enabled, a management token must be supplied in order to perform
100  snapshot operations.
101
102  To restore a snapshot from the file "backup.snap":
103
104    $ consul snapshot restore backup.snap
105
106  For a full list of options and examples, please see the Consul documentation.
107`
108