From 770b9e5db8f9d9614d0f8a7da6f1360476d8b5f0 Mon Sep 17 00:00:00 2001 From: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com> Date: Fri, 2 Apr 2021 11:06:55 -0400 Subject: [PATCH 1/5] Add flag/annotation override for default template --- agent-inject/agent/agent.go | 13 +++ agent-inject/agent/annotations.go | 9 ++ agent-inject/agent/annotations_test.go | 110 ++++++++++++++++--- agent-inject/agent/config.go | 18 ++- agent-inject/agent/config_test.go | 10 +- agent-inject/agent/container_sidecar_test.go | 29 ++++- agent-inject/handler.go | 2 + agent-inject/handler_test.go | 41 +++++-- subcommand/injector/command.go | 10 ++ subcommand/injector/flags.go | 9 ++ subcommand/injector/flags_test.go | 1 + 11 files changed, 212 insertions(+), 40 deletions(-) diff --git a/agent-inject/agent/agent.go b/agent-inject/agent/agent.go index d585f64c..3c8c501d 100644 --- a/agent-inject/agent/agent.go +++ b/agent-inject/agent/agent.go @@ -38,6 +38,10 @@ type Agent struct { // configure the Vault Agent container. Annotations map[string]string + // DefaultTemplate is the default template to be used when + // no custom template is specified via annotations. + DefaultTemplate string + // ImageName is the name of the Vault image to use for the // sidecar container. ImageName string @@ -248,6 +252,7 @@ func New(pod *corev1.Pod, patches []*jsonpatch.JsonPatchOperation) (*Agent, erro Annotations: pod.Annotations, ConfigMapName: pod.Annotations[AnnotationAgentConfigMap], ImageName: pod.Annotations[AnnotationAgentImage], + DefaultTemplate: pod.Annotations[AnnotationAgentInjectDefaultTemplate], LimitsCPU: pod.Annotations[AnnotationAgentLimitsCPU], LimitsMem: pod.Annotations[AnnotationAgentLimitsMem], Namespace: pod.Annotations[AnnotationAgentRequestNamespace], @@ -348,6 +353,14 @@ func New(pod *corev1.Pod, patches []*jsonpatch.JsonPatchOperation) (*Agent, erro return agent, err } + agent.DefaultTemplate = strings.ToLower(agent.DefaultTemplate) + switch agent.DefaultTemplate { + case "map": + case "json": + default: + return agent, fmt.Errorf("invalid default template type: %s", agent.DefaultTemplate) + } + agent.VaultAgentCache = VaultAgentCache{ Enable: agentCacheEnable, ListenerPort: pod.Annotations[AnnotationAgentCacheListenerPort], diff --git a/agent-inject/agent/annotations.go b/agent-inject/agent/annotations.go index d0b1f4eb..3ab3a92f 100644 --- a/agent-inject/agent/annotations.go +++ b/agent-inject/agent/annotations.go @@ -45,6 +45,10 @@ const ( // If not provided, a default generic template is used. AnnotationAgentInjectTemplate = "vault.hashicorp.com/agent-inject-template" + // AnnotationAgentInjectDefaultTemplate sets the default template type. Possible values + // are "json" and "map". + AnnotationAgentInjectDefaultTemplate = "vault.hashicorp.com/agent-inject-default-template" + // AnnotationAgentInjectToken is the annotation key for injecting the token // from auth/token/lookup-self AnnotationAgentInjectToken = "vault.hashicorp.com/agent-inject-token" @@ -227,6 +231,7 @@ type AgentConfig struct { SameID bool SetSecurityContext bool ProxyAddress string + DefaultTemplate string } // Init configures the expected annotations required to create a new instance @@ -371,6 +376,10 @@ func Init(pod *corev1.Pod, cfg AgentConfig) error { pod.ObjectMeta.Annotations[AnnotationAgentCacheExitOnErr] = strconv.FormatBool(DefaultAgentCacheExitOnErr) } + if _, ok := pod.ObjectMeta.Annotations[AnnotationAgentInjectDefaultTemplate]; !ok { + pod.ObjectMeta.Annotations[AnnotationAgentInjectDefaultTemplate] = cfg.DefaultTemplate + } + return nil } diff --git a/agent-inject/agent/annotations_test.go b/agent-inject/agent/annotations_test.go index 8467e519..bf858eb8 100644 --- a/agent-inject/agent/annotations_test.go +++ b/agent-inject/agent/annotations_test.go @@ -20,7 +20,7 @@ func TestInitCanSet(t *testing.T) { agentConfig := AgentConfig{ "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "http://proxy:3128", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "http://proxy:3128", "map", } err := Init(pod, agentConfig) if err != nil { @@ -57,7 +57,7 @@ func TestInitDefaults(t *testing.T) { agentConfig := AgentConfig{ "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "", "", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) if err != nil { @@ -91,7 +91,7 @@ func TestInitError(t *testing.T) { agentConfig := AgentConfig{ "image", "", DefaultVaultAuthType, "authPath", "namespace", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) if err == nil { @@ -155,7 +155,7 @@ func TestSecretAnnotationsWithPreserveCaseSensitivityFlagOff(t *testing.T) { agentConfig := AgentConfig{ "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) if err != nil { @@ -206,7 +206,7 @@ func TestSecretAnnotationsWithPreserveCaseSensitivityFlagOn(t *testing.T) { agentConfig := AgentConfig{ "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) if err != nil { @@ -293,7 +293,7 @@ func TestSecretLocationFileAnnotations(t *testing.T) { agentConfig := AgentConfig{ "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) if err != nil { @@ -378,7 +378,7 @@ func TestSecretTemplateAnnotations(t *testing.T) { agentConfig := AgentConfig{ "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) if err != nil { @@ -438,7 +438,7 @@ func TestTemplateShortcuts(t *testing.T) { pod := testPod(tt.annotations) agentConfig := AgentConfig{ "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) if err != nil { @@ -498,7 +498,7 @@ func TestSecretCommandAnnotations(t *testing.T) { pod := testPod(tt.annotations) agentConfig := AgentConfig{ "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) if err != nil { @@ -631,7 +631,7 @@ func TestCouldErrorAnnotations(t *testing.T) { agentConfig := AgentConfig{ "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) if err != nil { @@ -652,7 +652,7 @@ func TestInitEmptyPod(t *testing.T) { agentConfig := AgentConfig{ "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) if err == nil { @@ -681,7 +681,7 @@ func TestVaultNamespaceAnnotation(t *testing.T) { agentConfig := AgentConfig{ "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) if err != nil { @@ -841,7 +841,7 @@ func TestAuthConfigAnnotations(t *testing.T) { agentConfig := AgentConfig{ "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) if err != nil { @@ -856,3 +856,87 @@ func TestAuthConfigAnnotations(t *testing.T) { require.Equal(t, agent.Vault.AuthConfig, tt.expectedAuthConfig, "expected AuthConfig %v, got %v", tt.expectedAuthConfig, agent.Vault.AuthConfig) } } + +func TestDefaultTemplateOverride(t *testing.T) { + tests := []struct { + annotations map[string]string + expectedValue string + expectedErr bool + }{ + { + map[string]string{ + "vault.hashicorp.com/agent-inject-default-template": "json", + }, + "json", + false, + }, + { + map[string]string{ + "vault.hashicorp.com/agent-inject-default-template": "JSON", + }, + "json", + false, + }, + { + map[string]string{ + "vault.hashicorp.com/agent-inject-default-template": "map", + }, + "map", + false, + }, + { + map[string]string{ + "vault.hashicorp.com/agent-inject-default-template": "MAP", + }, + "map", + false, + }, + { + map[string]string{ + "vault.hashicorp.com/agent-inject-default-template": "foobar", + }, + "", + true, + }, + { + map[string]string{ + "vault.hashicorp.com/agent-inject-default-template": "jsn", + }, + "", + true, + }, + { + map[string]string{ + "vault.hashicorp.com/agent-inject-default-template": "", + }, + "", + true, + }, + } + + for _, tt := range tests { + pod := testPod(tt.annotations) + var patches []*jsonpatch.JsonPatchOperation + + agentConfig := AgentConfig{ + "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", + } + err := Init(pod, agentConfig) + if err != nil { + t.Errorf("got error, shouldn't have: %s", err) + } + + agent, err := New(pod, patches) + if err != nil && !tt.expectedErr { + t.Errorf("got error, shouldn't have: %s", err) + } else if err == nil && tt.expectedErr { + t.Error("got no error, should have") + } + + if !tt.expectedErr { + require.Equal(t, agent.DefaultTemplate, tt.expectedValue, + "expected %v, got %v", tt.expectedValue, agent.DefaultTemplate) + } + } +} diff --git a/agent-inject/agent/config.go b/agent-inject/agent/config.go index 8ef00276..d2323e3a 100644 --- a/agent-inject/agent/config.go +++ b/agent-inject/agent/config.go @@ -8,11 +8,12 @@ import ( ) const ( - DefaultTemplate = "{{ with secret \"%s\" }}{{ range $k, $v := .Data }}{{ $k }}: {{ $v }}\n{{ end }}{{ end }}" - TokenTemplate = "{{ with secret \"auth/token/lookup-self\" }}{{ .Data.id }}\n{{ end }}" - TokenSecret = "auth/token/lookup-self" - PidFile = "/home/vault/.pid" - TokenFile = "/home/vault/.vault-token" + DefaultMapTemplate = "{{ with secret \"%s\" }}{{ range $k, $v := .Data }}{{ $k }}: {{ $v }}\n{{ end }}{{ end }}" + DefaultJSONTemplate = "{{ with secret \"%s\" }}{{ .Data | toJSON }}\n{{ end }}" + TokenTemplate = "{{ with secret \"auth/token/lookup-self\" }}{{ .Data.id }}\n{{ end }}" + TokenSecret = "auth/token/lookup-self" + PidFile = "/home/vault/.pid" + TokenFile = "/home/vault/.vault-token" ) // Config is the top level struct that composes a Vault Agent @@ -103,7 +104,12 @@ func (a *Agent) newTemplateConfigs() []*Template { for _, secret := range a.Secrets { template := secret.Template if template == "" { - template = fmt.Sprintf(DefaultTemplate, secret.Path) + switch a.DefaultTemplate { + case "json": + template = fmt.Sprintf(DefaultJSONTemplate, secret.Path) + case "map": + template = fmt.Sprintf(DefaultMapTemplate, secret.Path) + } } filePathAndName := fmt.Sprintf("%s/%s", secret.MountPath, secret.Name) diff --git a/agent-inject/agent/config_test.go b/agent-inject/agent/config_test.go index cf5e4504..ea01dd5d 100644 --- a/agent-inject/agent/config_test.go +++ b/agent-inject/agent/config_test.go @@ -45,7 +45,7 @@ func TestNewConfig(t *testing.T) { agentConfig := AgentConfig{ "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "http://proxy:3128", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "http://proxy:3128", "map", } err := Init(pod, agentConfig) if err != nil { @@ -211,7 +211,7 @@ func TestFilePathAndName(t *testing.T) { agentConfig := AgentConfig{ "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) if err != nil { @@ -243,7 +243,7 @@ func TestConfigVaultAgentCacheNotEnabledByDefault(t *testing.T) { agentConfig := AgentConfig{ "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) if err != nil { @@ -282,7 +282,7 @@ func TestConfigVaultAgentCache(t *testing.T) { agentConfig := AgentConfig{ "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) if err != nil { @@ -414,7 +414,7 @@ func TestConfigVaultAgentCache_persistent(t *testing.T) { agentConfig := AgentConfig{ "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", + DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", } err := Init(pod, agentConfig) require.NoError(t, err, "got error initialising pod: %s", err) diff --git a/agent-inject/agent/container_sidecar_test.go b/agent-inject/agent/container_sidecar_test.go index a62da839..12278e8f 100644 --- a/agent-inject/agent/container_sidecar_test.go +++ b/agent-inject/agent/container_sidecar_test.go @@ -40,8 +40,11 @@ func TestContainerSidecarVolume(t *testing.T) { pod := testPod(annotations) var patches []*jsonpatch.JsonPatchOperation + agentConfig := AgentConfig{"foobar-image", "http://foobar:1234", DefaultVaultAuthType, + "test", "test", true, "1000", "100", DefaultAgentRunAsSameUser, + DefaultAgentSetSecurityContext, "", "map"} - err := Init(pod, AgentConfig{"foobar-image", "http://foobar:1234", DefaultVaultAuthType, "test", "test", true, "1000", "100", DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, ""}) + err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) } @@ -102,7 +105,11 @@ func TestContainerSidecar(t *testing.T) { pod := testPod(annotations) var patches []*jsonpatch.JsonPatchOperation - err := Init(pod, AgentConfig{"foobar-image", "http://foobar:1234", DefaultVaultAuthType, "test", "test", false, "1000", "100", DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "http://proxy:3128"}) + agentConfig := AgentConfig{"foobar-image", "http://foobar:1234", DefaultVaultAuthType, + "test", "test", false, "1000", "100", DefaultAgentRunAsSameUser, + DefaultAgentSetSecurityContext, "http://proxy:3128", "map"} + + err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) } @@ -215,7 +222,11 @@ func TestContainerSidecarRevokeHook(t *testing.T) { pod := testPod(annotations) var patches []*jsonpatch.JsonPatchOperation - err := Init(pod, AgentConfig{"foobar-image", "http://foobar:1234", DefaultVaultAuthType, "test", "test", tt.revokeFlag, "1000", "100", DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, ""}) + agentConfig := AgentConfig{"foobar-image", "http://foobar:1234", DefaultVaultAuthType, + "test", "test", tt.revokeFlag, "1000", "100", DefaultAgentRunAsSameUser, + DefaultAgentSetSecurityContext, "", "map"} + + err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) } @@ -264,7 +275,11 @@ func TestContainerSidecarConfigMap(t *testing.T) { pod := testPod(annotations) var patches []*jsonpatch.JsonPatchOperation - err := Init(pod, AgentConfig{"foobar-image", "http://foobar:1234", DefaultVaultAuthType, "test", "test", true, "1000", "100", DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, ""}) + agentConfig := AgentConfig{"foobar-image", "http://foobar:1234", DefaultVaultAuthType, + "test", "test", true, "1000", "100", DefaultAgentRunAsSameUser, + DefaultAgentSetSecurityContext, "", "map"} + + err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) } @@ -960,7 +975,11 @@ func TestContainerCache(t *testing.T) { pod := testPod(tt.annotations) var patches []*jsonpatch.JsonPatchOperation - err := Init(pod, AgentConfig{"foobar-image", "http://foobar:1234", DefaultVaultAuthType, "test", "test", true, "1000", "100", DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, ""}) + agentConfig := AgentConfig{"foobar-image", "http://foobar:1234", DefaultVaultAuthType, + "test", "test", true, "1000", "100", DefaultAgentRunAsSameUser, + DefaultAgentSetSecurityContext, "", "map"} + + err := Init(pod, agentConfig) require.NoError(t, err) agent, err := New(pod, patches) diff --git a/agent-inject/handler.go b/agent-inject/handler.go index e0361e5f..da7a2d35 100644 --- a/agent-inject/handler.go +++ b/agent-inject/handler.go @@ -48,6 +48,7 @@ type Handler struct { GroupID string SameID bool SetSecurityContext bool + DefaultTemplate string } // Handle is the http.HandlerFunc implementation that actually handles the @@ -154,6 +155,7 @@ func (h *Handler) Mutate(req *v1beta1.AdmissionRequest) *v1beta1.AdmissionRespon GroupID: h.GroupID, SameID: h.SameID, SetSecurityContext: h.SetSecurityContext, + DefaultTemplate: h.DefaultTemplate, } err = agent.Init(&pod, cfg) if err != nil { diff --git a/agent-inject/handler_test.go b/agent-inject/handler_test.go index b718f851..d36e6b21 100644 --- a/agent-inject/handler_test.go +++ b/agent-inject/handler_test.go @@ -57,7 +57,7 @@ func TestHandlerHandle(t *testing.T) { }{ { "kube-system namespace", - Handler{Log: hclog.Default().Named("handler")}, + Handler{Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, v1beta1.AdmissionRequest{ Namespace: metav1.NamespaceSystem, Object: encodeRaw(t, &corev1.Pod{ @@ -76,7 +76,7 @@ func TestHandlerHandle(t *testing.T) { { "already injected", - Handler{Log: hclog.Default().Named("handler")}, + Handler{Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, v1beta1.AdmissionRequest{ Object: encodeRaw(t, &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ @@ -106,7 +106,7 @@ func TestHandlerHandle(t *testing.T) { { "injection disabled", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler")}, + Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -125,7 +125,7 @@ func TestHandlerHandle(t *testing.T) { { "basic pod injection", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), ProxyAddress: "http://proxy:3128"}, + Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), ProxyAddress: "http://proxy:3128", DefaultTemplate: "map"}, v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -177,7 +177,7 @@ func TestHandlerHandle(t *testing.T) { { "init first ", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler")}, + Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -238,7 +238,7 @@ func TestHandlerHandle(t *testing.T) { { "configmap pod injection", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler")}, + Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -294,7 +294,7 @@ func TestHandlerHandle(t *testing.T) { { "tls pod injection", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler")}, + Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -355,7 +355,7 @@ func TestHandlerHandle(t *testing.T) { { "tls no configmap pod injection", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler")}, + Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -412,7 +412,7 @@ func TestHandlerHandle(t *testing.T) { { "tls no configmap no init pod injection", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler")}, + Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -458,7 +458,7 @@ func TestHandlerHandle(t *testing.T) { { "tls no configmap init only pod injection", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler")}, + Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -508,7 +508,7 @@ func TestHandlerHandle(t *testing.T) { { "copy volume mounts pod injection", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler")}, + Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -558,6 +558,25 @@ func TestHandlerHandle(t *testing.T) { }, }, }, + { + "invalid default template", + Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, + v1beta1.AdmissionRequest{ + Namespace: "foo", + Object: encodeRaw(t, &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + agent.AnnotationAgentInject: "true", + agent.AnnotationVaultRole: "demo", + agent.AnnotationAgentInjectDefaultTemplate: "foobar", + }, + }, + Spec: basicSpec, + }), + }, + "invalid default template type", + nil, + }, } for _, tt := range cases { diff --git a/subcommand/injector/command.go b/subcommand/injector/command.go index 5418d0be..8a68f4f2 100644 --- a/subcommand/injector/command.go +++ b/subcommand/injector/command.go @@ -51,6 +51,7 @@ type Command struct { flagSetSecurityContext bool // Set SecurityContext in injected containers flagTelemetryPath string // Path under which to expose metrics flagUseLeaderElector bool // Use leader elector code + flagDefaultTemplate string // Toggles which default template to use flagSet *flag.FlagSet @@ -79,6 +80,14 @@ func (c *Command) Run(args []string) int { return 1 } + switch c.flagDefaultTemplate { + case "map": + case "json": + default: + c.UI.Error(fmt.Sprintf("Invalid default flag type: %s", c.flagDefaultTemplate)) + return 1 + } + // We must have an in-cluster K8S client config, err := rest.InClusterConfig() if err != nil { @@ -157,6 +166,7 @@ func (c *Command) Run(args []string) int { GroupID: c.flagRunAsGroup, SameID: c.flagRunAsSameUser, SetSecurityContext: c.flagSetSecurityContext, + DefaultTemplate: c.flagDefaultTemplate, } mux := http.NewServeMux() diff --git a/subcommand/injector/flags.go b/subcommand/injector/flags.go index 7411afab..0a56a5a0 100644 --- a/subcommand/injector/flags.go +++ b/subcommand/injector/flags.go @@ -77,6 +77,9 @@ type Specification struct { // UseLeaderElector is the AGENT_INJECT_USE_LEADER_ELECTOR environment variable. UseLeaderElector string `split_words:"true"` + + // DefaultTemplate is the AGENT_INJECT_DEFAULT_TEMPLATE environment variable. + DefaultTemplate string `split_words:"true"` } func (c *Command) init() { @@ -120,6 +123,8 @@ func (c *Command) init() { "Path under which to expose metrics") c.flagSet.BoolVar(&c.flagUseLeaderElector, "use-leader-elector", agent.DefaultAgentUseLeaderElector, fmt.Sprintf("Use leader elector to coordinate multiple replicas when updating CA and Certs with auto-tls")) + c.flagSet.StringVar(&c.flagDefaultTemplate, "default-template", "map", + "Sets the default template type (map or json). Defaults to map.") c.help = flags.Usage(help, c.flagSet) } @@ -241,5 +246,9 @@ func (c *Command) parseEnvs() error { } } + if envs.DefaultTemplate != "" { + c.flagDefaultTemplate = envs.DefaultTemplate + } + return nil } diff --git a/subcommand/injector/flags_test.go b/subcommand/injector/flags_test.go index 6645d4a4..9060850e 100644 --- a/subcommand/injector/flags_test.go +++ b/subcommand/injector/flags_test.go @@ -125,6 +125,7 @@ func TestCommandEnvs(t *testing.T) { {env: "AGENT_INJECT_RUN_AS_USER", value: "1000", cmdPtr: &cmd.flagRunAsUser}, {env: "AGENT_INJECT_RUN_AS_GROUP", value: "1001", cmdPtr: &cmd.flagRunAsGroup}, {env: "AGENT_INJECT_TELEMETRY_PATH", value: "/metrics", cmdPtr: &cmd.flagTelemetryPath}, + {env: "AGENT_INJECT_DEFAULT_TEMPLATE", value: "json", cmdPtr: &cmd.flagDefaultTemplate}, } for _, tt := range tests { From 892e192385e036a42356be104a1370a7081faecd Mon Sep 17 00:00:00 2001 From: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com> Date: Fri, 2 Apr 2021 11:07:46 -0400 Subject: [PATCH 2/5] Update deployment --- deploy/injector-deployment.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deploy/injector-deployment.yaml b/deploy/injector-deployment.yaml index b55ae4a5..40d86bbc 100644 --- a/deploy/injector-deployment.yaml +++ b/deploy/injector-deployment.yaml @@ -76,6 +76,8 @@ spec: value: "vault-agent-injector-svc,vault-agent-injector-svc.$(NAMESPACE),vault-agent-injector-svc.$(NAMESPACE).svc" - name: AGENT_INJECT_USE_LEADER_ELECTOR value: "true" + - name: AGENT_INJECT_DEFAULT_TEMPLATE + value: "map" args: - agent-inject - 2>&1 From 0bcaaa46bb474ac0b6a4dcd514df92a745b32c31 Mon Sep 17 00:00:00 2001 From: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com> Date: Fri, 2 Apr 2021 14:05:55 -0400 Subject: [PATCH 3/5] Fix test --- agent-inject/agent/annotations_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/agent-inject/agent/annotations_test.go b/agent-inject/agent/annotations_test.go index 56f0a79a..cd1faf7c 100644 --- a/agent-inject/agent/annotations_test.go +++ b/agent-inject/agent/annotations_test.go @@ -934,6 +934,7 @@ func TestDefaultTemplateOverride(t *testing.T) { agentConfig := AgentConfig{ "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", + DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, } err := Init(pod, agentConfig) if err != nil { From 8e7e974743c649350f97608f41ae59ed7b77b53e Mon Sep 17 00:00:00 2001 From: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com> Date: Fri, 2 Apr 2021 14:28:05 -0400 Subject: [PATCH 4/5] Clean up test structs --- agent-inject/agent/annotations_test.go | 114 +++++++++---------------- agent-inject/handler_test.go | 36 +++++--- 2 files changed, 65 insertions(+), 85 deletions(-) diff --git a/agent-inject/agent/annotations_test.go b/agent-inject/agent/annotations_test.go index cd1faf7c..4cc6ffc3 100644 --- a/agent-inject/agent/annotations_test.go +++ b/agent-inject/agent/annotations_test.go @@ -14,15 +14,32 @@ import ( "github.com/stretchr/testify/require" ) +func basicAgentConfig() AgentConfig { + return AgentConfig{ + Image: "foobar-image", + Address: "http://foobar:8200", + AuthType: DefaultVaultAuthType, + AuthPath: "test", + Namespace: "test", + RevokeOnShutdown: true, + UserID: "100", + GroupID: "1000", + SameID: DefaultAgentRunAsSameUser, + SetSecurityContext: DefaultAgentSetSecurityContext, + ProxyAddress: "http://proxy:3128", + DefaultTemplate: "map", + ResourceRequestCPU: DefaultResourceRequestCPU, + ResourceRequestMem: DefaultResourceRequestMem, + ResourceLimitCPU: DefaultResourceLimitCPU, + ResourceLimitMem: DefaultResourceLimitMem, + } +} + func TestInitCanSet(t *testing.T) { annotations := make(map[string]string) pod := testPod(annotations) - agentConfig := AgentConfig{ - "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "http://proxy:3128", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) @@ -56,11 +73,12 @@ func TestInitDefaults(t *testing.T) { annotations := make(map[string]string) pod := testPod(annotations) - agentConfig := AgentConfig{ - "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "", "", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() + agentConfig.Image = "" + agentConfig.UserID = "" + agentConfig.GroupID = "" + agentConfig.ProxyAddress = "" + err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) @@ -91,11 +109,9 @@ func TestInitError(t *testing.T) { annotations := make(map[string]string) pod := testPod(annotations) - agentConfig := AgentConfig{ - "image", "", DefaultVaultAuthType, "authPath", "namespace", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() + agentConfig.Address = "" + err := Init(pod, agentConfig) if err == nil { t.Error("expected error no address, got none") @@ -156,11 +172,7 @@ func TestSecretAnnotationsWithPreserveCaseSensitivityFlagOff(t *testing.T) { pod := testPod(annotation) var patches []*jsonpatch.JsonPatchOperation - agentConfig := AgentConfig{ - "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) @@ -208,11 +220,7 @@ func TestSecretAnnotationsWithPreserveCaseSensitivityFlagOn(t *testing.T) { pod := testPod(annotation) var patches []*jsonpatch.JsonPatchOperation - agentConfig := AgentConfig{ - "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) @@ -296,11 +304,7 @@ func TestSecretLocationFileAnnotations(t *testing.T) { pod := testPod(tt.annotations) var patches []*jsonpatch.JsonPatchOperation - agentConfig := AgentConfig{ - "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) @@ -382,11 +386,7 @@ func TestSecretTemplateAnnotations(t *testing.T) { pod := testPod(tt.annotations) var patches []*jsonpatch.JsonPatchOperation - agentConfig := AgentConfig{ - "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) @@ -443,11 +443,7 @@ func TestTemplateShortcuts(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pod := testPod(tt.annotations) - agentConfig := AgentConfig{ - "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) @@ -504,11 +500,7 @@ func TestSecretCommandAnnotations(t *testing.T) { for _, tt := range tests { pod := testPod(tt.annotations) - agentConfig := AgentConfig{ - "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) @@ -637,12 +629,7 @@ func TestCouldErrorAnnotations(t *testing.T) { annotations := map[string]string{tt.key: tt.value} pod := testPod(annotations) var patches []*jsonpatch.JsonPatchOperation - - agentConfig := AgentConfig{ - "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) @@ -659,12 +646,7 @@ func TestCouldErrorAnnotations(t *testing.T) { func TestInitEmptyPod(t *testing.T) { var pod *corev1.Pod - - agentConfig := AgentConfig{ - "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err == nil { t.Errorf("got no error, should have") @@ -690,11 +672,7 @@ func TestVaultNamespaceAnnotation(t *testing.T) { pod := testPod(annotation) var patches []*jsonpatch.JsonPatchOperation - agentConfig := AgentConfig{ - "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) @@ -851,11 +829,7 @@ func TestAuthConfigAnnotations(t *testing.T) { pod := testPod(tt.annotations) var patches []*jsonpatch.JsonPatchOperation - agentConfig := AgentConfig{ - "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) @@ -931,11 +905,7 @@ func TestDefaultTemplateOverride(t *testing.T) { pod := testPod(tt.annotations) var patches []*jsonpatch.JsonPatchOperation - agentConfig := AgentConfig{ - "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) diff --git a/agent-inject/handler_test.go b/agent-inject/handler_test.go index d36e6b21..e3b7b9a5 100644 --- a/agent-inject/handler_test.go +++ b/agent-inject/handler_test.go @@ -16,6 +16,16 @@ import ( "k8s.io/apimachinery/pkg/runtime" ) +func basicHandler() Handler { + return Handler{ + VaultAddress: "https://vault:8200", + VaultAuthPath: "kubernetes", + ImageVault: "vault", + Log: hclog.Default().Named("handler"), + DefaultTemplate: "map", + } +} + func TestHandlerHandle(t *testing.T) { basicSpec := corev1.PodSpec{ InitContainers: []corev1.Container{ @@ -57,7 +67,7 @@ func TestHandlerHandle(t *testing.T) { }{ { "kube-system namespace", - Handler{Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, + basicHandler(), v1beta1.AdmissionRequest{ Namespace: metav1.NamespaceSystem, Object: encodeRaw(t, &corev1.Pod{ @@ -76,7 +86,7 @@ func TestHandlerHandle(t *testing.T) { { "already injected", - Handler{Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, + basicHandler(), v1beta1.AdmissionRequest{ Object: encodeRaw(t, &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ @@ -94,7 +104,7 @@ func TestHandlerHandle(t *testing.T) { { "no injection by default", - Handler{Log: hclog.Default().Named("handler")}, + basicHandler(), v1beta1.AdmissionRequest{ Object: encodeRaw(t, &corev1.Pod{ Spec: basicSpec, @@ -106,7 +116,7 @@ func TestHandlerHandle(t *testing.T) { { "injection disabled", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, + basicHandler(), v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -125,7 +135,7 @@ func TestHandlerHandle(t *testing.T) { { "basic pod injection", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), ProxyAddress: "http://proxy:3128", DefaultTemplate: "map"}, + basicHandler(), v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -177,7 +187,7 @@ func TestHandlerHandle(t *testing.T) { { "init first ", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, + basicHandler(), v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -238,7 +248,7 @@ func TestHandlerHandle(t *testing.T) { { "configmap pod injection", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, + basicHandler(), v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -294,7 +304,7 @@ func TestHandlerHandle(t *testing.T) { { "tls pod injection", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, + basicHandler(), v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -355,7 +365,7 @@ func TestHandlerHandle(t *testing.T) { { "tls no configmap pod injection", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, + basicHandler(), v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -412,7 +422,7 @@ func TestHandlerHandle(t *testing.T) { { "tls no configmap no init pod injection", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, + basicHandler(), v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -458,7 +468,7 @@ func TestHandlerHandle(t *testing.T) { { "tls no configmap init only pod injection", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, + basicHandler(), v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -508,7 +518,7 @@ func TestHandlerHandle(t *testing.T) { { "copy volume mounts pod injection", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, + basicHandler(), v1beta1.AdmissionRequest{ Namespace: "test", Object: encodeRaw(t, &corev1.Pod{ @@ -560,7 +570,7 @@ func TestHandlerHandle(t *testing.T) { }, { "invalid default template", - Handler{VaultAddress: "https://vault:8200", VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), DefaultTemplate: "map"}, + basicHandler(), v1beta1.AdmissionRequest{ Namespace: "foo", Object: encodeRaw(t, &corev1.Pod{ From 34f8b0bb969dc77619f933cde96b376affcd9766 Mon Sep 17 00:00:00 2001 From: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com> Date: Mon, 5 Apr 2021 10:20:48 -0400 Subject: [PATCH 5/5] Update per review --- agent-inject/agent/annotations.go | 2 +- agent-inject/agent/annotations_test.go | 14 ++------- agent-inject/agent/config.go | 15 +++++----- agent-inject/agent/config_test.go | 30 ++++---------------- agent-inject/agent/container_sidecar_test.go | 6 ++-- agent-inject/handler_test.go | 2 +- subcommand/injector/flags.go | 6 ++-- 7 files changed, 23 insertions(+), 52 deletions(-) diff --git a/agent-inject/agent/annotations.go b/agent-inject/agent/annotations.go index fa40b354..5dd0eb46 100644 --- a/agent-inject/agent/annotations.go +++ b/agent-inject/agent/annotations.go @@ -48,7 +48,7 @@ const ( // AnnotationAgentInjectDefaultTemplate sets the default template type. Possible values // are "json" and "map". AnnotationAgentInjectDefaultTemplate = "vault.hashicorp.com/agent-inject-default-template" - + // AnnotationAgentInjectTemplateFile is the optional key annotation that configures Vault // Agent what template on disk to use for rendering the secrets. The name // of the template is any unique string after "vault.hashicorp.com/agent-inject-template-file-", diff --git a/agent-inject/agent/annotations_test.go b/agent-inject/agent/annotations_test.go index eb9adb8c..0d332efd 100644 --- a/agent-inject/agent/annotations_test.go +++ b/agent-inject/agent/annotations_test.go @@ -27,7 +27,7 @@ func basicAgentConfig() AgentConfig { SameID: DefaultAgentRunAsSameUser, SetSecurityContext: DefaultAgentSetSecurityContext, ProxyAddress: "http://proxy:3128", - DefaultTemplate: "map", + DefaultTemplate: DefaultTemplateType, ResourceRequestCPU: DefaultResourceRequestCPU, ResourceRequestMem: DefaultResourceRequestMem, ResourceLimitCPU: DefaultResourceLimitCPU, @@ -512,11 +512,7 @@ func TestSecretMixedTemplatesAnnotations(t *testing.T) { } for _, tt := range tests { pod := testPod(tt.annotations) - agentConfig := AgentConfig{ - "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "", "", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) @@ -577,11 +573,7 @@ func TestSecretTemplateFileAnnotations(t *testing.T) { pod := testPod(tt.annotations) var patches []*jsonpatch.JsonPatchOperation - agentConfig := AgentConfig{ - "", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "", "", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) diff --git a/agent-inject/agent/config.go b/agent-inject/agent/config.go index c7ef679a..c456737d 100644 --- a/agent-inject/agent/config.go +++ b/agent-inject/agent/config.go @@ -10,6 +10,7 @@ import ( const ( DefaultMapTemplate = "{{ with secret \"%s\" }}{{ range $k, $v := .Data }}{{ $k }}: {{ $v }}\n{{ end }}{{ end }}" DefaultJSONTemplate = "{{ with secret \"%s\" }}{{ .Data | toJSON }}\n{{ end }}" + DefaultTemplateType = "map" TokenTemplate = "{{ with secret \"auth/token/lookup-self\" }}{{ .Data.id }}\n{{ end }}" TokenSecret = "auth/token/lookup-self" PidFile = "/home/vault/.pid" @@ -104,18 +105,16 @@ func (a *Agent) newTemplateConfigs() []*Template { var templates []*Template for _, secret := range a.Secrets { template := secret.Template - if template == "" { - switch a.DefaultTemplate { - case "json": - template = fmt.Sprintf(DefaultJSONTemplate, secret.Path) - case "map": - template = fmt.Sprintf(DefaultMapTemplate, secret.Path) - templateFile := secret.TemplateFile if templateFile == "" { template = secret.Template if template == "" { - template = fmt.Sprintf(DefaultTemplate, secret.Path) + switch a.DefaultTemplate { + case "json": + template = fmt.Sprintf(DefaultJSONTemplate, secret.Path) + case "map": + template = fmt.Sprintf(DefaultMapTemplate, secret.Path) + } } } diff --git a/agent-inject/agent/config_test.go b/agent-inject/agent/config_test.go index d6b8943d..5bc739a3 100644 --- a/agent-inject/agent/config_test.go +++ b/agent-inject/agent/config_test.go @@ -47,11 +47,7 @@ func TestNewConfig(t *testing.T) { pod := testPod(annotations) var patches []*jsonpatch.JsonPatchOperation - agentConfig := AgentConfig{ - "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "http://proxy:3128", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error initialising pod, shouldn't have: %s", err) @@ -221,11 +217,7 @@ func TestFilePathAndName(t *testing.T) { pod := testPod(tt.annotations) var patches []*jsonpatch.JsonPatchOperation - agentConfig := AgentConfig{ - "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error initialising pod, shouldn't have: %s", err) @@ -254,11 +246,7 @@ func TestConfigVaultAgentCacheNotEnabledByDefault(t *testing.T) { pod := testPod(annotations) var patches []*jsonpatch.JsonPatchOperation - agentConfig := AgentConfig{ - "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error initialising pod, shouldn't have: %s", err) @@ -294,11 +282,7 @@ func TestConfigVaultAgentCache(t *testing.T) { pod := testPod(annotations) var patches []*jsonpatch.JsonPatchOperation - agentConfig := AgentConfig{ - "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) if err != nil { t.Errorf("got error initialising pod, shouldn't have: %s", err) @@ -427,11 +411,7 @@ func TestConfigVaultAgentCache_persistent(t *testing.T) { pod := testPod(tt.annotations) var patches []*jsonpatch.JsonPatchOperation - agentConfig := AgentConfig{ - "foobar-image", "http://foobar:8200", DefaultVaultAuthType, "test", "test", true, "100", "1000", - DefaultAgentRunAsSameUser, DefaultAgentSetSecurityContext, "", "map", - DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, - } + agentConfig := basicAgentConfig() err := Init(pod, agentConfig) require.NoError(t, err, "got error initialising pod: %s", err) diff --git a/agent-inject/agent/container_sidecar_test.go b/agent-inject/agent/container_sidecar_test.go index 8f71b18b..63b4efd4 100644 --- a/agent-inject/agent/container_sidecar_test.go +++ b/agent-inject/agent/container_sidecar_test.go @@ -113,7 +113,7 @@ func TestContainerSidecar(t *testing.T) { DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, } - err := Init(pod, agentConfig) + err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) } @@ -232,7 +232,7 @@ func TestContainerSidecarRevokeHook(t *testing.T) { DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, } - err := Init(pod, agentConfig) + err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) } @@ -287,7 +287,7 @@ func TestContainerSidecarConfigMap(t *testing.T) { DefaultResourceRequestCPU, DefaultResourceRequestMem, DefaultResourceLimitCPU, DefaultResourceLimitMem, } - err := Init(pod, agentConfig) + err := Init(pod, agentConfig) if err != nil { t.Errorf("got error, shouldn't have: %s", err) } diff --git a/agent-inject/handler_test.go b/agent-inject/handler_test.go index e3b7b9a5..8fe2ae5a 100644 --- a/agent-inject/handler_test.go +++ b/agent-inject/handler_test.go @@ -22,7 +22,7 @@ func basicHandler() Handler { VaultAuthPath: "kubernetes", ImageVault: "vault", Log: hclog.Default().Named("handler"), - DefaultTemplate: "map", + DefaultTemplate: agent.DefaultTemplateType, } } diff --git a/subcommand/injector/flags.go b/subcommand/injector/flags.go index f7650a31..f6f250d6 100644 --- a/subcommand/injector/flags.go +++ b/subcommand/injector/flags.go @@ -134,8 +134,8 @@ func (c *Command) init() { c.flagSet.StringVar(&c.flagTelemetryPath, "telemetry-path", "", "Path under which to expose metrics") c.flagSet.BoolVar(&c.flagUseLeaderElector, "use-leader-elector", agent.DefaultAgentUseLeaderElector, - fmt.Sprintf("Use leader elector to coordinate multiple replicas when updating CA and Certs with auto-tls")) - c.flagSet.StringVar(&c.flagDefaultTemplate, "default-template", "map", + "Use leader elector to coordinate multiple replicas when updating CA and Certs with auto-tls") + c.flagSet.StringVar(&c.flagDefaultTemplate, "default-template", agent.DefaultTemplateType, "Sets the default template type (map or json). Defaults to map.") c.flagSet.StringVar(&c.flagResourceRequestCPU, "cpu-request", agent.DefaultResourceRequestCPU, @@ -270,7 +270,7 @@ func (c *Command) parseEnvs() error { if envs.DefaultTemplate != "" { c.flagDefaultTemplate = envs.DefaultTemplate - } + } if envs.ResourceRequestCPU != "" { c.flagResourceRequestCPU = envs.ResourceRequestCPU