-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
kv_undelete.go
129 lines (102 loc) · 2.75 KB
/
kv_undelete.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package command
import (
"fmt"
"strings"
"github.com/mitchellh/cli"
"github.com/posener/complete"
)
var (
_ cli.Command = (*KVUndeleteCommand)(nil)
_ cli.CommandAutocomplete = (*KVUndeleteCommand)(nil)
)
type KVUndeleteCommand struct {
*BaseCommand
flagVersions []string
}
func (c *KVUndeleteCommand) Synopsis() string {
return "Undeletes versions in the KV store"
}
func (c *KVUndeleteCommand) Help() string {
helpText := `
Usage: vault kv undelete [options] KEY
Undeletes the data for the provided version and path in the key-value store.
This restores the data, allowing it to be returned on get requests.
To undelete version 3 of key "foo":
$ vault kv undelete -versions=3 secret/foo
Additional flags and more advanced use cases are detailed below.
` + c.Flags().Help()
return strings.TrimSpace(helpText)
}
func (c *KVUndeleteCommand) Flags() *FlagSets {
set := c.flagSet(FlagSetHTTP | FlagSetOutputFormat)
// Common Options
f := set.NewFlagSet("Common Options")
f.StringSliceVar(&StringSliceVar{
Name: "versions",
Target: &c.flagVersions,
Default: nil,
Usage: `Specifies the version numbers to undelete.`,
})
return set
}
func (c *KVUndeleteCommand) AutocompleteArgs() complete.Predictor {
return nil
}
func (c *KVUndeleteCommand) AutocompleteFlags() complete.Flags {
return c.Flags().Completions()
}
func (c *KVUndeleteCommand) Run(args []string) int {
f := c.Flags()
if err := f.Parse(args); err != nil {
c.UI.Error(err.Error())
return 1
}
args = f.Args()
switch {
case len(args) < 1:
c.UI.Error(fmt.Sprintf("Not enough arguments (expected 1, got %d)", len(args)))
return 1
case len(args) > 1:
c.UI.Error(fmt.Sprintf("Too many arguments (expected 1, got %d)", len(args)))
return 1
}
if len(c.flagVersions) == 0 {
c.UI.Error("No versions provided, use the \"-versions\" flag to specify the version to undelete.")
return 1
}
client, err := c.Client()
if err != nil {
c.UI.Error(err.Error())
return 2
}
path := sanitizePath(args[0])
mountPath, v2, err := isKVv2(path, client)
if err != nil {
c.UI.Error(err.Error())
return 2
}
if !v2 {
c.UI.Error("Undelete not supported on KV Version 1")
return 1
}
path = addPrefixToVKVPath(path, mountPath, "undelete")
data := map[string]interface{}{
"versions": kvParseVersionsFlags(c.flagVersions),
}
secret, err := client.Logical().Write(path, data)
if err != nil {
c.UI.Error(fmt.Sprintf("Error writing data to %s: %s", path, err))
if secret != nil {
OutputSecret(c.UI, secret)
}
return 2
}
if secret == nil {
// Don't output anything unless using the "table" format
if Format(c.UI) == "table" {
c.UI.Info(fmt.Sprintf("Success! Data written to: %s", path))
}
return 0
}
return OutputSecret(c.UI, secret)
}