From 3db08b1c25e424fe4180205f12d5194f9154cb6d Mon Sep 17 00:00:00 2001 From: David Roller Date: Thu, 2 Apr 2020 18:36:27 -0400 Subject: [PATCH] added extra-secret annotation for adding kube-secrets --- agent-inject/agent/agent.go | 13 ++++++++ agent-inject/agent/annotations.go | 4 +++ agent-inject/agent/container_init_sidecar.go | 8 +++++ agent-inject/agent/container_sidecar.go | 8 +++++ agent-inject/agent/container_sidecar_test.go | 10 ++++++- agent-inject/agent/container_volume.go | 31 +++++++++++++++----- 6 files changed, 65 insertions(+), 9 deletions(-) diff --git a/agent-inject/agent/agent.go b/agent-inject/agent/agent.go index 9a655717..24db00e7 100644 --- a/agent-inject/agent/agent.go +++ b/agent-inject/agent/agent.go @@ -104,6 +104,10 @@ type Agent struct { // RunAsGroup is the group ID to run the Vault agent container(s) as. RunAsGroup int64 + + // ExtraSecret is the Kubernetes secret to mount as a volume in the Vault agent container + // which can be referenced by the Agent config for secrets. Mounted at /vault/custom/ + ExtraSecret string } type Secret struct { @@ -193,6 +197,7 @@ func New(pod *corev1.Pod, patches []*jsonpatch.JsonPatchOperation) (*Agent, erro ServiceAccountName: saName, ServiceAccountPath: saPath, Status: pod.Annotations[AnnotationAgentStatus], + ExtraSecret: pod.Annotations[AnnotationAgentExtraSecret], Vault: Vault{ Address: pod.Annotations[AnnotationVaultService], AuthPath: pod.Annotations[AnnotationVaultAuthPath], @@ -319,6 +324,14 @@ func (a *Agent) Patch() ([]byte, error) { "/spec/volumes")...) } + // Add ExtraSecret if one was provided + if a.ExtraSecret != "" { + a.Patches = append(a.Patches, addVolumes( + a.Pod.Spec.Volumes, + []corev1.Volume{a.ContainerExtraSecretVolume()}, + "/spec/volumes")...) + } + // Add TLS Secret if one was provided if a.Vault.TLSSecret != "" { a.Patches = append(a.Patches, addVolumes( diff --git a/agent-inject/agent/annotations.go b/agent-inject/agent/annotations.go index 43464d14..a7724965 100644 --- a/agent-inject/agent/annotations.go +++ b/agent-inject/agent/annotations.go @@ -71,6 +71,10 @@ const ( // configuration file and templates can be found. AnnotationAgentConfigMap = "vault.hashicorp.com/agent-configmap" + // AnnotationAgentExtraSecret is the name of a Kubernetes secret that will be mounted + // into the Vault agent container so that the agent config can reference secrets. + AnnotationAgentExtraSecret = "vault.hashicorp.com/agent-extra-secret" + // AnnotationAgentLimitsCPU sets the CPU limit on the Vault Agent containers. AnnotationAgentLimitsCPU = "vault.hashicorp.com/agent-limits-cpu" diff --git a/agent-inject/agent/container_init_sidecar.go b/agent-inject/agent/container_init_sidecar.go index 94cf9813..3c9cdb4b 100644 --- a/agent-inject/agent/container_init_sidecar.go +++ b/agent-inject/agent/container_init_sidecar.go @@ -26,6 +26,14 @@ func (a *Agent) ContainerInitSidecar() (corev1.Container, error) { } volumeMounts = append(volumeMounts, a.ContainerVolumeMounts()...) + if a.ExtraSecret != "" { + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: extraSecretVolumeName, + MountPath: extraSecretVolumePath, + ReadOnly: true, + }) + } + arg := DefaultContainerArg if a.ConfigMapName != "" { diff --git a/agent-inject/agent/container_sidecar.go b/agent-inject/agent/container_sidecar.go index d152b12b..56e66f1a 100644 --- a/agent-inject/agent/container_sidecar.go +++ b/agent-inject/agent/container_sidecar.go @@ -38,6 +38,14 @@ func (a *Agent) ContainerSidecar() (corev1.Container, error) { } volumeMounts = append(volumeMounts, a.ContainerVolumeMounts()...) + if a.ExtraSecret != "" { + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: extraSecretVolumeName, + MountPath: extraSecretVolumePath, + ReadOnly: true, + }) + } + arg := DefaultContainerArg if a.ConfigMapName != "" { diff --git a/agent-inject/agent/container_sidecar_test.go b/agent-inject/agent/container_sidecar_test.go index ebff2690..41b8c4bb 100644 --- a/agent-inject/agent/container_sidecar_test.go +++ b/agent-inject/agent/container_sidecar_test.go @@ -27,6 +27,9 @@ func TestContainerSidecarVolume(t *testing.T) { AnnotationVaultSecretVolumePath: "/etc/default_path", fmt.Sprintf("%s-%s", AnnotationAgentInjectSecret, "secret3"): "secret/secret3", + + // Test adding an extra secret from Kube secrets for reference by Agent config + fmt.Sprintf("%s", AnnotationAgentExtraSecret): "extrasecret", } pod := testPod(annotations) @@ -45,7 +48,7 @@ func TestContainerSidecarVolume(t *testing.T) { container, err := agent.ContainerSidecar() // One token volume mount, one config volume mount and two secrets volume mounts - require.Equal(t, 4, len(container.VolumeMounts)) + require.Equal(t, 5, len(container.VolumeMounts)) require.Equal( t, @@ -70,6 +73,11 @@ func TestContainerSidecarVolume(t *testing.T) { MountPath: "/etc/container_environment", ReadOnly: false, }, + corev1.VolumeMount{ + Name: extraSecretVolumeName, + MountPath: extraSecretVolumePath, + ReadOnly: true, + }, }, container.VolumeMounts, ) diff --git a/agent-inject/agent/container_volume.go b/agent-inject/agent/container_volume.go index 052c4f92..b4172867 100644 --- a/agent-inject/agent/container_volume.go +++ b/agent-inject/agent/container_volume.go @@ -8,14 +8,16 @@ import ( ) const ( - tokenVolumeName = "home" - tokenVolumePath = "/home/vault" - configVolumeName = "vault-config" - configVolumePath = "/vault/configs" - secretVolumeName = "vault-secrets" - tlsSecretVolumeName = "vault-tls-secrets" - tlsSecretVolumePath = "/vault/tls" - secretVolumePath = "/vault/secrets" + tokenVolumeName = "home" + tokenVolumePath = "/home/vault" + configVolumeName = "vault-config" + configVolumePath = "/vault/configs" + secretVolumeName = "vault-secrets" + tlsSecretVolumeName = "vault-tls-secrets" + tlsSecretVolumePath = "/vault/tls" + secretVolumePath = "/vault/secrets" + extraSecretVolumeName = "extra-secrets" + extraSecretVolumePath = "/vault/custom" ) func (a *Agent) getUniqueMountPaths() []string { @@ -86,6 +88,19 @@ func (a *Agent) ContainerConfigMapVolume() corev1.Volume { } } +// ContainerExtraSecretVolume returns a volume to mount a Kube secret +// if the user supplied one. +func (a *Agent) ContainerExtraSecretVolume() corev1.Volume { + return corev1.Volume{ + Name: extraSecretVolumeName, + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: a.ExtraSecret, + }, + }, + } +} + // ContainerTLSSecretVolume returns a volume to mount TLS secrets // if the user supplied any. func (a *Agent) ContainerTLSSecretVolume() corev1.Volume {