Skip to content
This repository was archived by the owner on Oct 9, 2023. It is now read-only.

Commit 9a4ea00

Browse files
authored
Use group attribute for KV version and add DB engine support (#539)
* Continue supporting config kvversion as default arg Signed-off-by: Tim Bauer <[email protected]> * Remove obsolete test Signed-off-by: Tim Bauer <[email protected]> * Add deprecation information Signed-off-by: Tim Bauer <[email protected]> * Remove comment Signed-off-by: Tim Bauer <[email protected]> * Remove comments Signed-off-by: Tim Bauer <[email protected]> --------- Signed-off-by: Tim Bauer <[email protected]>
1 parent f4cadb0 commit 9a4ea00

File tree

4 files changed

+106
-46
lines changed

4 files changed

+106
-46
lines changed

pkg/webhook/config/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ type GCPSecretManagerConfig struct {
114114

115115
type VaultSecretManagerConfig struct {
116116
Role string `json:"role" pflag:",Specifies the vault role to use"`
117-
KVVersion KVVersion `json:"kvVersion" pflag:"-,The KV Engine Version. Defaults to 2. Use 1 for unversioned secrets. Refer to - https://www.vaultproject.io/docs/secrets/kv#kv-secrets-engine."`
117+
KVVersion KVVersion `json:"kvVersion" pflag:"-,DEPRECATED! Use the GroupVersion field of the Secret request instead. The KV Engine Version. Defaults to 2. Use 1 for unversioned secrets. Refer to - https://www.vaultproject.io/docs/secrets/kv#kv-secrets-engine."`
118118
Annotations map[string]string `json:"annotations" pflag:"-,Annotation to be added to user task pod. The annotation can also be used to override default annotations added by Flyte. Useful to customize Vault integration (https://developer.hashicorp.com/vault/docs/platform/k8s/injector/annotations)"`
119119
}
120120

pkg/webhook/utils.go

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,30 +123,44 @@ func AppendVolume(volumes []corev1.Volume, volume corev1.Volume) []corev1.Volume
123123
return append(volumes, volume)
124124
}
125125

126-
func CreateVaultAnnotationsForSecret(secret *core.Secret, kvversion config.KVVersion) (map[string]string, error) {
126+
func CreateVaultAnnotationsForSecret(secret *core.Secret, kvversion config.KVVersion) map[string]string {
127127
// Creates three grouped annotations "agent-inject-secret", "agent-inject-file" and "agent-inject-template"
128128
// for a given secret request and KV engine version. The annotations respectively handle: 1. retrieving the
129129
// secret from a vault path specified in secret.Group, 2. storing it in a file named after secret.Group/secret.Key
130130
// and 3. creating a template that retrieves only secret.Key from the multiple k:v pairs present in a vault secret.
131131
id := string(uuid.NewUUID())
132132

133+
secretVaultAnnotations := map[string]string{
134+
fmt.Sprintf("vault.hashicorp.com/agent-inject-secret-%s", id): secret.Group,
135+
fmt.Sprintf("vault.hashicorp.com/agent-inject-file-%s", id): fmt.Sprintf("%s/%s", secret.Group, secret.Key),
136+
}
137+
133138
// Set the consul template language query depending on the KV Secrets Engine version.
134139
// Version 1 stores plain k:v pairs under .Data, version 2 supports versioned secrets
135140
// and wraps the k:v pairs into an additional subfield.
136141
var query string
137-
if kvversion == config.KVVersion1 {
142+
switch secret.GroupVersion {
143+
case "kv1":
138144
query = ".Data"
139-
} else if kvversion == config.KVVersion2 {
145+
case "kv2":
140146
query = ".Data.data"
141-
} else {
142-
err := fmt.Errorf("unsupported KV Version %v, supported versions are 1 and 2", kvversion)
143-
return nil, err
147+
case "db":
148+
// For the database secrets engine backend we do not want to use the templating
149+
default:
150+
// Deprecated: The config setting KVVersion is deprecated and will be removed in a future release.
151+
// You should instead use the GroupVersion field in the secret definition.
152+
// Support using the legacy KVVersion config if GroupVersion is not set
153+
switch kvversion {
154+
case config.KVVersion1:
155+
query = ".Data"
156+
case config.KVVersion2:
157+
query = ".Data.data"
158+
}
144159
}
145-
template := fmt.Sprintf(`{{- with secret "%s" -}}{{ %s.%s }}{{- end -}}`, secret.Group, query, secret.Key)
146-
secretVaultAnnotations := map[string]string{
147-
fmt.Sprintf("vault.hashicorp.com/agent-inject-secret-%s", id): secret.Group,
148-
fmt.Sprintf("vault.hashicorp.com/agent-inject-file-%s", id): fmt.Sprintf("%s/%s", secret.Group, secret.Key),
149-
fmt.Sprintf("vault.hashicorp.com/agent-inject-template-%s", id): template,
160+
if query != "" {
161+
template := fmt.Sprintf(`{{- with secret "%s" -}}{{ %s.%s }}{{- end -}}`, secret.Group, query, secret.Key)
162+
secretVaultAnnotations[fmt.Sprintf("vault.hashicorp.com/agent-inject-template-%s", id)] = template
163+
150164
}
151-
return secretVaultAnnotations, nil
165+
return secretVaultAnnotations
152166
}

pkg/webhook/vault_secret_manager.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,7 @@ func (i VaultSecretManagerInjector) Inject(ctx context.Context, secret *coreIdl.
6868
"vault.hashicorp.com/agent-pre-populate-only": "true",
6969
}
7070

71-
secretVaultAnnotations, err := CreateVaultAnnotationsForSecret(secret, i.cfg.KVVersion)
72-
// Creating annotations can break with an unsupported KVVersion
73-
if err != nil {
74-
return p, false, err
75-
}
71+
secretVaultAnnotations := CreateVaultAnnotationsForSecret(secret, i.cfg.KVVersion)
7672

7773
p.ObjectMeta.Annotations = utils.UnionMaps(secretVaultAnnotations, commonVaultAnnotations, i.cfg.Annotations, p.ObjectMeta.Annotations)
7874

pkg/webhook/vault_secret_manager_test.go

Lines changed: 78 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ func RetrieveUUID(annotations map[string]string) string {
4545
}
4646

4747
func ExpectedKVv1(uuid string) *corev1.Pod {
48-
// Injects uuid into expected output for KV v1 secrets
4948
expected := &corev1.Pod{
5049
ObjectMeta: metav1.ObjectMeta{
5150
Annotations: map[string]string{
@@ -64,7 +63,6 @@ func ExpectedKVv1(uuid string) *corev1.Pod {
6463
}
6564

6665
func ExpectedKVv2(uuid string) *corev1.Pod {
67-
// Injects uuid into expected output for KV v2 secrets
6866
expected := &corev1.Pod{
6967
ObjectMeta: metav1.ObjectMeta{
7068
Annotations: map[string]string{
@@ -82,8 +80,7 @@ func ExpectedKVv2(uuid string) *corev1.Pod {
8280
return expected
8381
}
8482

85-
func ExpectedKVv3(uuid string) *corev1.Pod {
86-
// Injects uuid into expected output for KV v2 secrets
83+
func ExpectedExtraAnnotation(uuid string) *corev1.Pod {
8784
expected := &corev1.Pod{
8885
ObjectMeta: metav1.ObjectMeta{
8986
Annotations: map[string]string{
@@ -102,8 +99,7 @@ func ExpectedKVv3(uuid string) *corev1.Pod {
10299
return expected
103100
}
104101

105-
func ExpectedKVv4(uuid string) *corev1.Pod {
106-
// Injects uuid into expected output for KV v2 secrets
102+
func ExpectedExistingRoleAnnotation(uuid string) *corev1.Pod {
107103
expected := &corev1.Pod{
108104
ObjectMeta: metav1.ObjectMeta{
109105
Annotations: map[string]string{
@@ -121,8 +117,7 @@ func ExpectedKVv4(uuid string) *corev1.Pod {
121117
return expected
122118
}
123119

124-
func ExpectedKVv5(uuid string) *corev1.Pod {
125-
// Injects uuid into expected output for KV v2 secrets
120+
func ExpectedConfigAnnotation(uuid string) *corev1.Pod {
126121
expected := &corev1.Pod{
127122
ObjectMeta: metav1.ObjectMeta{
128123
Annotations: map[string]string{
@@ -140,6 +135,23 @@ func ExpectedKVv5(uuid string) *corev1.Pod {
140135
return expected
141136
}
142137

138+
func ExpectedDB(uuid string) *corev1.Pod {
139+
expected := &corev1.Pod{
140+
ObjectMeta: metav1.ObjectMeta{
141+
Annotations: map[string]string{
142+
"vault.hashicorp.com/agent-inject": "true",
143+
"vault.hashicorp.com/secret-volume-path": "/etc/flyte/secrets",
144+
"vault.hashicorp.com/role": "flyte",
145+
"vault.hashicorp.com/agent-pre-populate-only": "true",
146+
fmt.Sprintf("vault.hashicorp.com/agent-inject-secret-%s", uuid): "foo",
147+
fmt.Sprintf("vault.hashicorp.com/agent-inject-file-%s", uuid): "foo/bar",
148+
},
149+
},
150+
Spec: PodSpec,
151+
}
152+
return expected
153+
}
154+
143155
func NewInputPod(annotations map[string]string) *corev1.Pod {
144156
// Need to create a new Pod for every test since annotations are otherwise appended to original reference object
145157
p := &corev1.Pod{
@@ -176,70 +188,108 @@ func TestVaultSecretManagerInjector_Inject(t *testing.T) {
176188
wantErr bool
177189
}{
178190
{
179-
name: "KVv1 Secret",
191+
name: "KVv1 Secret Group Version argument overwrites config",
180192
args: args{
181-
cfg: config.VaultSecretManagerConfig{Role: "flyte", KVVersion: config.KVVersion1},
182-
secret: inputSecret,
183-
p: NewInputPod(map[string]string{}),
193+
cfg: config.VaultSecretManagerConfig{Role: "flyte", KVVersion: config.KVVersion2},
194+
secret: &coreIdl.Secret{
195+
Group: "foo",
196+
Key: "bar",
197+
GroupVersion: "kv1",
198+
},
199+
p: NewInputPod(map[string]string{}),
184200
},
185201
want: ExpectedKVv1,
186202
wantErr: false,
187203
},
188204
{
189-
name: "KVv2 Secret",
205+
name: "KVv2 Secret Group Version argument overwrites config",
190206
args: args{
191-
cfg: config.VaultSecretManagerConfig{Role: "flyte", KVVersion: config.KVVersion2},
192-
secret: inputSecret,
193-
p: NewInputPod(map[string]string{}),
207+
cfg: config.VaultSecretManagerConfig{Role: "flyte", KVVersion: config.KVVersion1},
208+
secret: &coreIdl.Secret{
209+
Group: "foo",
210+
Key: "bar",
211+
GroupVersion: "kv2",
212+
},
213+
p: NewInputPod(map[string]string{}),
194214
},
195215
want: ExpectedKVv2,
196216
wantErr: false,
197217
},
198218
{
199-
name: "KVv3 Secret - extra annotations",
219+
name: "Extra annotations from config are added",
200220
args: args{
201221
cfg: config.VaultSecretManagerConfig{Role: "flyte", KVVersion: config.KVVersion2, Annotations: map[string]string{
202222
"vault.hashicorp.com/auth-config-type": "gce",
203223
}},
204224
secret: inputSecret,
205225
p: NewInputPod(map[string]string{}),
206226
},
207-
want: ExpectedKVv3,
227+
want: ExpectedExtraAnnotation,
208228
wantErr: false,
209229
},
210230
{
211-
name: "KVv4 Secret - user override annotation",
231+
name: "Already present annotation is not overwritten",
212232
args: args{
213233
cfg: config.VaultSecretManagerConfig{Role: "flyte", KVVersion: config.KVVersion2, Annotations: map[string]string{}},
214234
secret: inputSecret,
215235
p: NewInputPod(map[string]string{
216236
"vault.hashicorp.com/role": "my-role",
217237
}),
218238
},
219-
want: ExpectedKVv4,
239+
want: ExpectedExistingRoleAnnotation,
220240
wantErr: false,
221241
},
222242
{
223-
name: "KVv5 Secret - system override annotation",
243+
name: "Config annotation overwrites system default annotation",
224244
args: args{
225245
cfg: config.VaultSecretManagerConfig{Role: "flyte", KVVersion: config.KVVersion2, Annotations: map[string]string{
226246
"vault.hashicorp.com/agent-pre-populate-only": "false", // override vault.hashicorp.com/agent-pre-populate-only
227247
}},
228248
secret: inputSecret,
229249
p: NewInputPod(map[string]string{}),
230250
},
231-
want: ExpectedKVv5,
251+
want: ExpectedConfigAnnotation,
232252
wantErr: false,
233253
},
234254
{
235-
name: "Unsupported KV version",
255+
name: "DB Secret backend enginge is supported",
236256
args: args{
237-
cfg: config.VaultSecretManagerConfig{Role: "flyte", KVVersion: 3},
238-
secret: inputSecret,
239-
p: NewInputPod(map[string]string{}),
257+
cfg: config.VaultSecretManagerConfig{Role: "flyte", KVVersion: config.KVVersion1},
258+
secret: &coreIdl.Secret{
259+
Group: "foo",
260+
Key: "bar",
261+
GroupVersion: "db",
262+
},
263+
p: NewInputPod(map[string]string{}),
240264
},
241-
want: nil,
242-
wantErr: true,
265+
want: ExpectedDB,
266+
wantErr: false,
267+
},
268+
{
269+
name: "Legacy config option V1 is still supported",
270+
args: args{
271+
cfg: config.VaultSecretManagerConfig{Role: "flyte", KVVersion: config.KVVersion1},
272+
secret: &coreIdl.Secret{
273+
Group: "foo",
274+
Key: "bar",
275+
},
276+
p: NewInputPod(map[string]string{}),
277+
},
278+
want: ExpectedKVv1,
279+
wantErr: false,
280+
},
281+
{
282+
name: "Legacy config option V2 is still supported",
283+
args: args{
284+
cfg: config.VaultSecretManagerConfig{Role: "flyte", KVVersion: config.KVVersion2},
285+
secret: &coreIdl.Secret{
286+
Group: "foo",
287+
Key: "bar",
288+
},
289+
p: NewInputPod(map[string]string{}),
290+
},
291+
want: ExpectedKVv2,
292+
wantErr: false,
243293
},
244294
}
245295

0 commit comments

Comments
 (0)