diff --git a/agent-inject/agent/agent.go b/agent-inject/agent/agent.go index 99ffb04a..dc32fde8 100644 --- a/agent-inject/agent/agent.go +++ b/agent-inject/agent/agent.go @@ -33,6 +33,8 @@ const ( DefaultAgentCacheExitOnErr = false DefaultAgentUseLeaderElector = false DefaultAgentInjectToken = false + DefaultAgentSidecarType = "agent" + DefaultProxyUseAutoAuthToken = true DefaultTemplateConfigExitOnRetryFailure = true DefaultServiceAccountMount = "/var/run/secrets/vault.hashicorp.com/serviceaccount" DefaultEnableQuit = false @@ -121,6 +123,13 @@ type Agent struct { // container(s). ConfigMapName string + // SidecarType is the type of the sidecar container that is injected into the pod + SidecarType string + + // Use the auto auth token in the sidecar proxy, usable only when SidecarType is set to "proxy" + // acceptable values are boolean true / false and "force" + ProxyUseAutoAuthToken interface{} + // Vault is the structure holding all the Vault specific configurations. Vault Vault @@ -347,6 +356,8 @@ func New(pod *corev1.Pod) (*Agent, error) { agent := &Agent{ Annotations: pod.Annotations, ConfigMapName: pod.Annotations[AnnotationAgentConfigMap], + SidecarType: pod.Annotations[AnnotationAgentSidecarType], + ProxyUseAutoAuthToken: pod.Annotations[AnnotationAgentProxyUseAutoAuthToken], ImageName: pod.Annotations[AnnotationAgentImage], DefaultTemplate: pod.Annotations[AnnotationAgentInjectDefaultTemplate], LimitsCPU: pod.Annotations[AnnotationAgentLimitsCPU], @@ -396,6 +407,9 @@ func New(pod *corev1.Pod) (*Agent, error) { return agent, err } + agent.SidecarType = agent.sidecarType() + agent.ProxyUseAutoAuthToken = agent.proxyUseAutoAuthToken() + agent.Vault.AgentTelemetryConfig = agent.telemetryConfig() agent.InitFirst, err = agent.initFirst() @@ -723,6 +737,9 @@ func (a *Agent) Validate() error { return errors.New("no Vault address found") } } + if a.SidecarType != "" && !(a.SidecarType == "agent" || a.SidecarType == "proxy") { + return errors.New(fmt.Sprintf("Invalid sidecar type, expected one of agent / proxy, got %s", a.SidecarType)) + } return nil } diff --git a/agent-inject/agent/annotations.go b/agent-inject/agent/annotations.go index c904be6c..59543a0c 100644 --- a/agent-inject/agent/annotations.go +++ b/agent-inject/agent/annotations.go @@ -17,6 +17,16 @@ import ( ) const ( + // AnnotationAgentSidecarType is the key of the annotation that controls whether + // a Vault agent or Vault proxy is injected into the pod + // Should be set to one of "agent" / "proxy", defaults to "agent". + AnnotationAgentSidecarType = "vault.hashicorp.com/sidecar-type" + + // AnnotationAgentProxyUseAutoAuthToken is the key of the annotation that controls whether + // the auto auth token should be used in the vault proxy. + // configures the "use_auto_auth_token" key in the "api_proxy" stanza. + AnnotationAgentProxyUseAutoAuthToken = "vault.hashicorp.com/sidecar-proxy-use-auto-auth-token" + // AnnotationAgentStatus is the key of the annotation that is added to // a pod after an injection is done. // There's only one valid status we care about: "injected". @@ -884,3 +894,24 @@ func (a *Agent) authConfig() map[string]interface{} { return authConfig } + +func (a *Agent) sidecarType() string { + if a.SidecarType != "" && !(a.SidecarType == "agent" || a.SidecarType == "proxy") { + return a.SidecarType + } + return DefaultAgentSidecarType +} + +func (a *Agent) proxyUseAutoAuthToken() interface{} { + switch a.ProxyUseAutoAuthToken.(type) { + case bool: + return a.ProxyUseAutoAuthToken.(bool) + case string: + if a.ProxyUseAutoAuthToken == "force" { + return a.ProxyUseAutoAuthToken.(string) + } + default: + return DefaultProxyUseAutoAuthToken + } + return nil +} diff --git a/agent-inject/agent/config.go b/agent-inject/agent/config.go index 387aa897..e3df7085 100644 --- a/agent-inject/agent/config.go +++ b/agent-inject/agent/config.go @@ -33,6 +33,7 @@ type Config struct { DisableIdleConnections []string `json:"disable_idle_connections,omitempty"` DisableKeepAlives []string `json:"disable_keep_alives,omitempty"` Telemetry *Telemetry `json:"telemetry,omitempty"` + ApiProxy *ApiProxy `json:"api_proxy,omitempty"` } // Vault contains configuration for connecting to Vault servers @@ -108,6 +109,12 @@ type Cache struct { Persist *CachePersist `json:"persist,omitempty"` } +type ApiProxy struct { + UseAutoAuthToken interface{} `json:"use_auto_auth_token,omitempty"` + EnforceConsistency string `json:enforce_consistency,omitempty` + WhenInconsistent string `json:when_inconsistent,omitempty` +} + // CachePersist defines the configuration for persistent caching in Vault Agent type CachePersist struct { Type string `json:"type"` @@ -283,6 +290,13 @@ func (a *Agent) newConfig(init bool) ([]byte, error) { } } + // adds the api_proxy stanza to the configuration + if a.SidecarType == "proxy" { + config.ApiProxy = &ApiProxy{ + UseAutoAuthToken: a.ProxyUseAutoAuthToken, + } + } + // If EnableQuit is true, set it on the listener. If a listener hasn't been // defined, set it on a new one. Also add a simple cache stanza since that's // required for an agent listener. diff --git a/agent-inject/agent/config_test.go b/agent-inject/agent/config_test.go index 69c857e4..8878ec1c 100644 --- a/agent-inject/agent/config_test.go +++ b/agent-inject/agent/config_test.go @@ -809,7 +809,7 @@ func TestConfigTelemetry(t *testing.T) { "vault.hashicorp.com/agent-telemetry-stackdriver_location": "useast-1", "vault.hashicorp.com/agent-telemetry-stackdriver_namespace": "foo", "vault.hashicorp.com/agent-telemetry-stackdriver_debug_logs": "false", - "vault.hashicorp.com/agent-telemetry-prefix_filter": `["+vault.token", "-vault.expire", "+vault.expire.num_leases"]`, + "vault.hashicorp.com/agent-telemetry-prefix_filter": `["+vault.token", "-vault.expire", "+vault.expire.num_leases"]`, }, &Telemetry{ UsageGaugePeriod: "10m", diff --git a/agent-inject/agent/container_init_sidecar.go b/agent-inject/agent/container_init_sidecar.go index 82f1a2c3..2ac45138 100644 --- a/agent-inject/agent/container_init_sidecar.go +++ b/agent-inject/agent/container_init_sidecar.go @@ -50,7 +50,7 @@ func (a *Agent) ContainerInitSidecar() (corev1.Container, error) { volumeMounts = append(volumeMounts, a.copyVolumeMounts(a.CopyVolumeMounts)...) } - arg := DefaultContainerArg + arg := fmt.Sprintf(DefaultContainerArg, a.SidecarType) if a.ConfigMapName != "" { volumeMounts = append(volumeMounts, corev1.VolumeMount{ @@ -58,7 +58,7 @@ func (a *Agent) ContainerInitSidecar() (corev1.Container, error) { MountPath: configVolumePath, ReadOnly: true, }) - arg = fmt.Sprintf("touch %s && vault agent -config=%s/config-init.hcl", TokenFile, configVolumePath) + arg = fmt.Sprintf("touch %s && vault %s -config=%s/config-init.hcl", TokenFile, a.SidecarType, configVolumePath) } if a.Vault.TLSSecret != "" { diff --git a/agent-inject/agent/container_sidecar.go b/agent-inject/agent/container_sidecar.go index c89645e0..e2eee9c5 100644 --- a/agent-inject/agent/container_sidecar.go +++ b/agent-inject/agent/container_sidecar.go @@ -20,7 +20,7 @@ const ( DefaultResourceLimitMem = "128Mi" DefaultResourceRequestCPU = "250m" DefaultResourceRequestMem = "64Mi" - DefaultContainerArg = "echo ${VAULT_CONFIG?} | base64 -d > /home/vault/config.json && vault agent -config=/home/vault/config.json" + DefaultContainerArg = "echo ${VAULT_CONFIG?} | base64 -d > /home/vault/config.json && vault %s -config=/home/vault/config.json" DefaultRevokeGrace = 5 DefaultAgentLogLevel = "info" DefaultAgentLogFormat = "standard" @@ -62,7 +62,7 @@ func (a *Agent) ContainerSidecar() (corev1.Container, error) { volumeMounts = append(volumeMounts, a.copyVolumeMounts(a.CopyVolumeMounts)...) } - arg := DefaultContainerArg + arg := fmt.Sprintf(DefaultContainerArg, a.SidecarType) if a.ConfigMapName != "" { volumeMounts = append(volumeMounts, corev1.VolumeMount{ @@ -70,7 +70,7 @@ func (a *Agent) ContainerSidecar() (corev1.Container, error) { MountPath: configVolumePath, ReadOnly: true, }) - arg = fmt.Sprintf("touch %s && vault agent -config=%s/config.hcl", TokenFile, configVolumePath) + arg = fmt.Sprintf("touch %s && vault %s -config=%s/config.hcl", TokenFile, a.SidecarType, configVolumePath) } if a.Vault.TLSSecret != "" { diff --git a/agent-inject/agent/container_sidecar_test.go b/agent-inject/agent/container_sidecar_test.go index de9801b7..f0a4fdf8 100644 --- a/agent-inject/agent/container_sidecar_test.go +++ b/agent-inject/agent/container_sidecar_test.go @@ -285,8 +285,9 @@ func TestContainerSidecar(t *testing.T) { t.Errorf("wrong number of args, got %d, should have been %d", len(container.Args), 1) } - if container.Args[0] != DefaultContainerArg { - t.Errorf("arg value wrong, should have been %s, got %s", DefaultContainerArg, container.Args[0]) + arg := fmt.Sprintf(DefaultContainerArg, agent.SidecarType) + if container.Args[0] != arg { + t.Errorf("arg value wrong, should have been %s, got %s", arg, container.Args[0]) } if container.Resources.Limits.Cpu().String() != DefaultResourceLimitCPU {