Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enable templating keys with vault secrets #510

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cmd/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import (
"strings"
"testing"

"github.com/argoproj-labs/argocd-vault-plugin/pkg/helpers"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/vault"

"github.com/argoproj-labs/argocd-vault-plugin/pkg/helpers"
)

var roleid, secretid string
Expand Down
13 changes: 13 additions & 0 deletions fixtures/input/nonempty/secret_path_annotation_key_value.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: v1
kind: Secret
metadata:
annotations:
avp.kubernetes.io/path: secret/testing
avp.kubernetes.io/kv-version: "1"
name: example-secret-key-value-annotation-path
namespace: <namespace>
type: Opaque
data:
SECRET_KEY: <secret-var-value>
<secret-var-value>: SECRET_VAL
<secret-var-value2>: <secret-var-value>
12 changes: 12 additions & 0 deletions fixtures/input/nonempty/secret_path_key_value.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Secret
metadata:
annotations:
avp.kubernetes.io/kv-version: "1"
name: example-secret-key-value
namespace: default
type: Opaque
data:
SECRET_KEY: <path:secret/testing#secret-var-value>
<path:secret/testing#secret-var-value#version>: SECRET_VAL
<path:secret/testing#secret-var-value2>: <path:secret/testing#secret-var-value>
27 changes: 27 additions & 0 deletions fixtures/output/all.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,20 @@ metadata:
type: Opaque
---
apiVersion: v1
data:
SECRET_KEY: dGVzdC1wYXNzd29yZA==
dGVzdC1wYXNzd29yZA==: SECRET_VAL
dGVzdC1wYXNzd29yZDI=: dGVzdC1wYXNzd29yZA==
kind: Secret
metadata:
annotations:
avp.kubernetes.io/kv-version: "1"
avp.kubernetes.io/path: secret/testing
name: example-secret-key-value-annotation-path
namespace: test-namespace
type: Opaque
---
apiVersion: v1
data:
SECRET_VAR: dGVzdC1wYXNzd29yZA==
kind: Secret
Expand All @@ -246,6 +260,19 @@ metadata:
type: Opaque
---
apiVersion: v1
data:
SECRET_KEY: dGVzdC1wYXNzd29yZA==
dGVzdC1wYXNzd29yZA==: SECRET_VAL
dGVzdC1wYXNzd29yZDI=: dGVzdC1wYXNzd29yZA==
kind: Secret
metadata:
annotations:
avp.kubernetes.io/kv-version: "1"
name: example-secret-key-value
namespace: default
type: Opaque
---
apiVersion: v1
data:
PORT: 80
kind: Secret
Expand Down
13 changes: 10 additions & 3 deletions pkg/kube/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import (
"strconv"
"strings"

k8yaml "k8s.io/apimachinery/pkg/util/yaml"

"github.com/argoproj-labs/argocd-vault-plugin/pkg/types"
"github.com/argoproj-labs/argocd-vault-plugin/pkg/utils"
k8yaml "k8s.io/apimachinery/pkg/util/yaml"
)

type missingKeyError struct {
Expand Down Expand Up @@ -91,11 +92,17 @@ func replaceInner(

r.replacementErrors = append(r.replacementErrors, err...)
}

keyReplacement := false
if genericPlaceholder.FindString(key) != "" {
keyReplacement = true
replacementKey, _ := replacerFunc(key, key, *r)
obj[replacementKey.(string)] = replacement
delete(obj, key)
}
if removeKey {
utils.VerboseToStdErr("removing key %s due to %s being set on the containing manifest", key, types.AVPRemoveMissingAnnotation)
delete(obj, key)
} else {
} else if keyReplacement == false {
obj[key] = replacement
}
}
Expand Down
106 changes: 106 additions & 0 deletions pkg/kube/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,112 @@ func TestGenericReplacement_multiString(t *testing.T) {
assertSuccessfulReplacement(&dummyResource, &expected, t)
}

func TestGenericReplacement_keyReplacement(t *testing.T) {
dummyResource := Resource{
TemplateData: map[string]interface{}{
"<name>": "default",
"namespace": "test",
},
Data: map[string]interface{}{
"namespace": "default",
"name": "app",
"tag": "latest",
},
Annotations: map[string]string{
(types.AVPPathAnnotation): "",
},
}

replaceInner(&dummyResource, &dummyResource.TemplateData, genericReplacement)

expected := Resource{
TemplateData: map[string]interface{}{
"app": "default",
"namespace": "test",
},
Data: map[string]interface{}{
"namespace": "default",
"name": "app",
"tag": "latest",
},

replacementErrors: []error{},
}

assertSuccessfulReplacement(&dummyResource, &expected, t)
}

func TestGenericReplacement_keyAndValueReplacement(t *testing.T) {
dummyResource := Resource{
TemplateData: map[string]interface{}{
"<name>": "default",
"tag": "<tag>",
"<tag>": "<name>",
},
Data: map[string]interface{}{
"namespace": "default",
"name": "app",
"tag": "latest",
},
Annotations: map[string]string{
(types.AVPPathAnnotation): "",
},
}

replaceInner(&dummyResource, &dummyResource.TemplateData, genericReplacement)

expected := Resource{
TemplateData: map[string]interface{}{
"app": "default",
"tag": "latest",
"latest": "app",
},
Data: map[string]interface{}{
"namespace": "default",
"name": "app",
"tag": "latest",
},
replacementErrors: []error{},
}

assertSuccessfulReplacement(&dummyResource, &expected, t)
}
func TestGenericReplacement_keyAndValueReplacementNoPathAnnotation(t *testing.T) {
mv := helpers.MockVault{}
mv.LoadData(map[string]interface{}{
"version": "one",
})
dummyResource := Resource{
TemplateData: map[string]interface{}{
"<path:blah/blah#version>": "default",
"version": "<path:blah/blah#version>",
},
Data: map[string]interface{}{
"namespace": "default",
"name": "app",
"tag": "latest",
},
Backend: &mv,
Annotations: map[string]string{},
}

replaceInner(&dummyResource, &dummyResource.TemplateData, genericReplacement)

expected := Resource{
TemplateData: map[string]interface{}{
"one": "default",
"version": "one",
},
Data: map[string]interface{}{
"namespace": "default",
"name": "app",
"tag": "latest",
},
replacementErrors: []error{},
}

assertSuccessfulReplacement(&dummyResource, &expected, t)
}
func TestGenericReplacement_Base64(t *testing.T) {
dummyResource := Resource{
TemplateData: map[string]interface{}{
Expand Down