Skip to content

Commit

Permalink
Delimiter annotation (#664)
Browse files Browse the repository at this point in the history
Co-authored-by: Caitlin Elfring <[email protected]>
Co-authored-by: Theron Voran <[email protected]>
  • Loading branch information
3 people authored Nov 5, 2024
1 parent fce3297 commit 1063509
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 34 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Changes:
* `k8s.io/utils` v0.0.0-20240502163921-fe8a2dddb1d0 => v0.0.0-20240711033017-18e509b52bc8
* `sigs.k8s.io/controller-runtime` v0.18.4 => v0.19.1

Features:
* Add annotations for customizing template delimiters [GH-664](https://github.com/hashicorp/vault-k8s/pull/664)

Bugs:
* Disable handling update on pods [GH-619](https://github.com/hashicorp/vault-k8s/pull/619)

Expand Down
6 changes: 6 additions & 0 deletions agent-inject/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,12 @@ type Secret struct {
// ErrMissingKey is used to control how the template behaves when attempting
// to index a struct or a map key that does not exist
ErrMissingKey bool

// LeftDelimiter is the optional left delimiter to use when rendering a templated secret
LeftDelimiter string

// RightDelimiter is the optional right delimiter to use when rendering a templated secret
RightDelimiter string
}

type Vault struct {
Expand Down
18 changes: 18 additions & 0 deletions agent-inject/agent/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,22 @@ const (
// If not provided, the template content key annotation is used.
AnnotationAgentInjectTemplateFile = "vault.hashicorp.com/agent-inject-template-file"

// AnnotationAgentInjectTemplateLeftDelim is the key annotation that configures Vault
// Agent what left delimiter to use for rendering the secrets. The name
// of the template is any unique string after "vault.hashicorp.com/agent-template-left-delim-",
// such as "vault.hashicorp.com/agent-template-left-delim-foobar". This should map
// to the same unique value provided in "vault.hashicorp.com/agent-inject-secret-".
// If not provided, a default left delimiter is used as defined by https://www.vaultproject.io/docs/agent/template#left_delimiter
AnnotationAgentInjectTemplateLeftDelim = "vault.hashicorp.com/agent-template-left-delim"

// AnnotationAgentInjectTemplateRightDelim is the key annotation that configures Vault
// Agent what right delimiter to use for rendering the secrets. The name
// of the template is any unique string after "vault.hashicorp.com/agent-template-right-delim-",
// such as "vault.hashicorp.com/agent-template-right-delim-foobar". This should map
// to the same unique value provided in "vault.hashicorp.com/agent-inject-secret-".
// If not provided, a default right delimiter is used as defined by https://www.vaultproject.io/docs/agent/template#right_delimiter
AnnotationAgentInjectTemplateRightDelim = "vault.hashicorp.com/agent-template-right-delim"

// AnnotationAgentInjectToken is the annotation key for injecting the
// auto-auth token into the secrets volume (e.g. /vault/secrets/token)
AnnotationAgentInjectToken = "vault.hashicorp.com/agent-inject-token"
Expand Down Expand Up @@ -646,6 +662,8 @@ func (a *Agent) secrets() ([]*Secret, error) {
}
secret.MountPath = a.annotationsSecretValue(AnnotationVaultSecretVolumePath, secret.RawName, a.Annotations[AnnotationVaultSecretVolumePath])
secret.Command = a.annotationsSecretValue(AnnotationAgentInjectCommand, secret.RawName, "")
secret.LeftDelimiter = a.annotationsSecretValue(AnnotationAgentInjectTemplateLeftDelim, secret.RawName, "")
secret.RightDelimiter = a.annotationsSecretValue(AnnotationAgentInjectTemplateRightDelim, secret.RawName, "")
secret.FilePathAndName = a.annotationsSecretValue(AnnotationAgentInjectFile, secret.RawName, "")
secret.FilePermission = a.annotationsSecretValue(AnnotationAgentInjectFilePermission, secret.RawName, "")

Expand Down
116 changes: 92 additions & 24 deletions agent-inject/agent/annotations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,39 +461,107 @@ func TestSecretMixedTemplatesAnnotations(t *testing.T) {

"vault.hashicorp.com/agent-inject-template-only-template": "onlyTemplate",
"vault.hashicorp.com/agent-inject-template-file-only-template-file": "onlyTemplateFile",

"vault.hashicorp.com/agent-inject-secret-barfoo": "test1",
"vault.hashicorp.com/agent-inject-template-barfoo": "",
"vault.hashicorp.com/agent-template-left-delim-barfoo": "${",
"vault.hashicorp.com/agent-template-right-delim-barfoo": "}",
"vault.hashicorp.com/agent-inject-template-file-barfoo": "/etc/config.tmpl",

"vault.hashicorp.com/agent-inject-secret-test3": "test3",
"vault.hashicorp.com/agent-inject-template-test3": "foobarTemplate3",
"vault.hashicorp.com/agent-inject-template-file-test3": "",
"vault.hashicorp.com/agent-template-left-delim-test3": "",
"vault.hashicorp.com/agent-template-right-delim-test3": "",

"vault.hashicorp.com/agent-inject-template-only-template-2": "onlyTemplate2",
"vault.hashicorp.com/agent-template-left-delim-only-template-2": "${",
"vault.hashicorp.com/agent-template-right-delim-only-template-2": "}",

"vault.hashicorp.com/agent-inject-template-file-only-template-file-2": "onlyTemplateFile2",
"vault.hashicorp.com/agent-template-left-delim-only-template-file-2": "${",
"vault.hashicorp.com/agent-template-right-delim-only-template-file-2": "}",
},
map[string]Secret{
"foobar": {
Name: "foobar",
RawName: "foobar",
Path: "test1",
Template: "",
TemplateFile: "/etc/config.tmpl",
MountPath: secretVolumePath,
Name: "foobar",
RawName: "foobar",
Path: "test1",
Template: "",
LeftDelimiter: "",
RightDelimiter: "",
TemplateFile: "/etc/config.tmpl",
MountPath: secretVolumePath,
},
"test2": {
Name: "test2",
RawName: "test2",
Path: "test2",
Template: "foobarTemplate",
TemplateFile: "",
MountPath: secretVolumePath,
Name: "test2",
RawName: "test2",
Path: "test2",
Template: "foobarTemplate",
LeftDelimiter: "",
RightDelimiter: "",
TemplateFile: "",
MountPath: secretVolumePath,
},
"only-template": {
Name: "only-template",
RawName: "only-template",
Path: "",
Template: "onlyTemplate",
TemplateFile: "",
MountPath: secretVolumePath,
Name: "only-template",
RawName: "only-template",
Path: "",
Template: "onlyTemplate",
LeftDelimiter: "",
RightDelimiter: "",
TemplateFile: "",
MountPath: secretVolumePath,
},
"only-template-file": {
Name: "only-template-file",
RawName: "only-template-file",
Path: "",
Template: "",
TemplateFile: "onlyTemplateFile",
MountPath: secretVolumePath,
Name: "only-template-file",
RawName: "only-template-file",
Path: "",
Template: "",
LeftDelimiter: "",
RightDelimiter: "",
TemplateFile: "onlyTemplateFile",
MountPath: secretVolumePath,
},
"barfoo": {
Name: "barfoo",
RawName: "barfoo",
Path: "test1",
Template: "",
LeftDelimiter: "${",
RightDelimiter: "}",
TemplateFile: "/etc/config.tmpl",
MountPath: secretVolumePath,
},
"test3": {
Name: "test3",
RawName: "test3",
Path: "test3",
Template: "foobarTemplate3",
LeftDelimiter: "",
RightDelimiter: "",
TemplateFile: "",
MountPath: secretVolumePath,
},
"only-template-2": {
Name: "only-template-2",
RawName: "only-template-2",
Path: "",
Template: "onlyTemplate2",
LeftDelimiter: "${",
RightDelimiter: "}",
TemplateFile: "",
MountPath: secretVolumePath,
},
"only-template-file-2": {
Name: "only-template-file-2",
RawName: "only-template-file-2",
Path: "",
Template: "",
LeftDelimiter: "${",
RightDelimiter: "}",
TemplateFile: "onlyTemplateFile2",
MountPath: secretVolumePath,
},
},
},
Expand Down
16 changes: 14 additions & 2 deletions agent-inject/agent/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
const (
DefaultMapTemplate = "{{ with secret \"%s\" }}{{ range $k, $v := .Data }}{{ $k }}: {{ $v }}\n{{ end }}{{ end }}"
DefaultJSONTemplate = "{{ with secret \"%s\" }}{{ .Data | toJSON }}\n{{ end }}"
DefaultLeftDelim = "{{"
DefaultRightDelim = "}}"
DefaultTemplateType = "map"
PidFile = "/home/vault/.pid"
TokenFile = "/home/vault/.vault-token"
Expand Down Expand Up @@ -195,6 +197,16 @@ func (a *Agent) newTemplateConfigs() []*Template {
}
}

leftDelim := secret.LeftDelimiter
if leftDelim == "" {
leftDelim = DefaultLeftDelim
}

rightDelim := secret.RightDelimiter
if rightDelim == "" {
rightDelim = DefaultRightDelim
}

filePathAndName := fmt.Sprintf("%s/%s", secret.MountPath, secret.Name)
if secret.FilePathAndName != "" {
filePathAndName = filepath.Join(secret.MountPath, secret.FilePathAndName)
Expand All @@ -204,8 +216,8 @@ func (a *Agent) newTemplateConfigs() []*Template {
Source: templateFile,
Contents: template,
Destination: filePathAndName,
LeftDelim: "{{",
RightDelim: "}}",
LeftDelim: leftDelim,
RightDelim: rightDelim,
Command: secret.Command,
ErrMissingKey: secret.ErrMissingKey,
}
Expand Down
29 changes: 21 additions & 8 deletions agent-inject/agent/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ func TestNewConfig(t *testing.T) {

"vault.hashicorp.com/agent-inject-command-bar": "pkill -HUP app",

"vault.hashicorp.com/agent-inject-secret-baz": "db/creds/baz",
"vault.hashicorp.com/agent-inject-template-baz": `[[ with secret "db/creds/baz" ]][[ range $k, $v := .Data ]][[ $k ]]: [[ $v ]]\n[[ end ]][[ end ]]`,
"vault.hashicorp.com/agent-template-left-delim-baz": "[[",
"vault.hashicorp.com/agent-template-right-delim-baz": "]]",

AnnotationAgentCacheEnable: "true",
}

Expand Down Expand Up @@ -121,8 +126,8 @@ func TestNewConfig(t *testing.T) {
t.Error("agent Cache should be disabled for init containers")
}

if len(config.Templates) != 6 {
t.Errorf("expected 4 template, got %d", len(config.Templates))
if len(config.Templates) != 7 {
t.Errorf("expected 7 templates, got %d", len(config.Templates))
}

for _, template := range config.Templates {
Expand All @@ -134,6 +139,10 @@ func TestNewConfig(t *testing.T) {
if template.Contents != "template foo" {
t.Errorf("expected template contents to be %s, got %s", "template foo", template.Contents)
}

if template.LeftDelim != DefaultLeftDelim || template.RightDelim != DefaultRightDelim {
t.Errorf("expected default delimiters to be %s (left) and %s (right), got %s (left) and %s (right)", DefaultLeftDelim, DefaultRightDelim, template.LeftDelim, template.RightDelim)
}
} else if strings.Contains(template.Destination, "bar") {
if template.Destination != "/vault/secrets/bar" {
t.Errorf("expected template destination to be %s, got %s", "/vault/secrets/bar", template.Destination)
Expand Down Expand Up @@ -170,6 +179,10 @@ func TestNewConfig(t *testing.T) {
if template.Destination != "/vault/secrets/just-template-file" {
t.Errorf("expected template destination to be %s, got %s", "/vault/secrets/just-template-file", template.Destination)
}
} else if strings.Contains(template.Destination, "baz") {
if template.LeftDelim != "[[" || template.RightDelim != "]]" {
t.Errorf("expected default delimiters to be %s (left) and %s (right), got %s (left) and %s (right)", "[[", "]]", template.LeftDelim, template.RightDelim)
}
} else {
t.Error("shouldn't have got here")
}
Expand Down Expand Up @@ -627,7 +640,7 @@ func TestConfigVaultAgentTemplateConfig(t *testing.T) {
AnnotationTemplateConfigExitOnRetryFailure: "true",
},
&TemplateConfig{
ExitOnRetryFailure: true,
ExitOnRetryFailure: true,
MaxConnectionsPerHost: 0,
},
},
Expand All @@ -637,7 +650,7 @@ func TestConfigVaultAgentTemplateConfig(t *testing.T) {
AnnotationTemplateConfigExitOnRetryFailure: "false",
},
&TemplateConfig{
ExitOnRetryFailure: false,
ExitOnRetryFailure: false,
MaxConnectionsPerHost: 0,
},
},
Expand All @@ -647,9 +660,9 @@ func TestConfigVaultAgentTemplateConfig(t *testing.T) {
AnnotationTemplateConfigStaticSecretRenderInterval: "10s",
},
&TemplateConfig{
ExitOnRetryFailure: true,
ExitOnRetryFailure: true,
StaticSecretRenderInterval: "10s",
MaxConnectionsPerHost: 0,
MaxConnectionsPerHost: 0,
},
},
{
Expand All @@ -658,15 +671,15 @@ func TestConfigVaultAgentTemplateConfig(t *testing.T) {
AnnotationTemplateConfigMaxConnectionsPerHost: "100",
},
&TemplateConfig{
ExitOnRetryFailure: true,
ExitOnRetryFailure: true,
MaxConnectionsPerHost: 100,
},
},
{
"template_config_empty",
map[string]string{},
&TemplateConfig{
ExitOnRetryFailure: true,
ExitOnRetryFailure: true,
MaxConnectionsPerHost: 0,
},
},
Expand Down

0 comments on commit 1063509

Please sign in to comment.