-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
kv_helpers.go
152 lines (132 loc) · 3.63 KB
/
kv_helpers.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package command
import (
"errors"
"fmt"
"io"
"path"
"strings"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/sdk/helper/strutil"
)
func kvReadRequest(client *api.Client, path string, params map[string]string) (*api.Secret, error) {
r := client.NewRequest("GET", "/v1/"+path)
for k, v := range params {
r.Params.Set(k, v)
}
resp, err := client.RawRequest(r)
if resp != nil {
defer resp.Body.Close()
}
if resp != nil && resp.StatusCode == 404 {
secret, parseErr := api.ParseSecret(resp.Body)
switch parseErr {
case nil:
case io.EOF:
return nil, nil
default:
return nil, err
}
if secret != nil && (len(secret.Warnings) > 0 || len(secret.Data) > 0) {
return secret, nil
}
return nil, nil
}
if err != nil {
return nil, err
}
return api.ParseSecret(resp.Body)
}
func kvPreflightVersionRequest(client *api.Client, path string) (string, int, error) {
// We don't want to use a wrapping call here so save any custom value and
// restore after
currentWrappingLookupFunc := client.CurrentWrappingLookupFunc()
client.SetWrappingLookupFunc(nil)
defer client.SetWrappingLookupFunc(currentWrappingLookupFunc)
currentOutputCurlString := client.OutputCurlString()
client.SetOutputCurlString(false)
defer client.SetOutputCurlString(currentOutputCurlString)
r := client.NewRequest("GET", "/v1/sys/internal/ui/mounts/"+path)
resp, err := client.RawRequest(r)
if resp != nil {
defer resp.Body.Close()
}
if err != nil {
// If we get a 404 we are using an older version of vault, default to
// version 1
if resp != nil && resp.StatusCode == 404 {
return "", 1, nil
}
return "", 0, err
}
secret, err := api.ParseSecret(resp.Body)
if err != nil {
return "", 0, err
}
if secret == nil {
return "", 0, errors.New("nil response from pre-flight request")
}
var mountPath string
if mountPathRaw, ok := secret.Data["path"]; ok {
mountPath = mountPathRaw.(string)
}
options := secret.Data["options"]
if options == nil {
return mountPath, 1, nil
}
versionRaw := options.(map[string]interface{})["version"]
if versionRaw == nil {
return mountPath, 1, nil
}
version := versionRaw.(string)
switch version {
case "", "1":
return mountPath, 1, nil
case "2":
return mountPath, 2, nil
}
return mountPath, 1, nil
}
func isKVv2(path string, client *api.Client) (string, bool, error) {
mountPath, version, err := kvPreflightVersionRequest(client, path)
if err != nil {
return "", false, err
}
return mountPath, version == 2, nil
}
func addPrefixToVKVPath(p, mountPath, apiPrefix string) string {
switch {
case p == mountPath, p == strings.TrimSuffix(mountPath, "/"):
return path.Join(mountPath, apiPrefix)
default:
p = strings.TrimPrefix(p, mountPath)
return path.Join(mountPath, apiPrefix, p)
}
}
func getHeaderForMap(header string, data map[string]interface{}) string {
maxKey := 0
for k := range data {
if len(k) > maxKey {
maxKey = len(k)
}
}
// 4 for the column spaces and 5 for the len("value")
totalLen := maxKey + 4 + 5
equalSigns := totalLen - (len(header) + 2)
// If we have zero or fewer equal signs bump it back up to two on either
// side of the header.
if equalSigns <= 0 {
equalSigns = 4
}
// If the number of equal signs is not divisible by two add a sign.
if equalSigns%2 != 0 {
equalSigns = equalSigns + 1
}
return fmt.Sprintf("%s %s %s", strings.Repeat("=", equalSigns/2), header, strings.Repeat("=", equalSigns/2))
}
func kvParseVersionsFlags(versions []string) []string {
versionsOut := make([]string, 0, len(versions))
for _, v := range versions {
versionsOut = append(versionsOut, strutil.ParseStringSlice(v, ",")...)
}
return versionsOut
}