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

Vault sidecar type annotation #496

Open
wants to merge 6 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
17 changes: 17 additions & 0 deletions agent-inject/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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
}

Expand Down
31 changes: 31 additions & 0 deletions agent-inject/agent/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -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".
Expand Down Expand Up @@ -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") {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if a.SidecarType != "" && !(a.SidecarType == "agent" || a.SidecarType == "proxy") {
if a.SidecarType != "" && (a.SidecarType == "agent" || a.SidecarType == "proxy") {

I think you meant if a.SidecarType is not empty, and a.SidecarType is "agent" or "proxy", then return a.SidecarType?

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
}
14 changes: 14 additions & 0 deletions agent-inject/agent/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"`
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion agent-inject/agent/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"]`,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you revert the accidental space?

},
&Telemetry{
UsageGaugePeriod: "10m",
Expand Down
4 changes: 2 additions & 2 deletions agent-inject/agent/container_init_sidecar.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ 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{
Name: configVolumeName,
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 != "" {
Expand Down
6 changes: 3 additions & 3 deletions agent-inject/agent/container_sidecar.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -62,15 +62,15 @@ 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{
Name: configVolumeName,
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 != "" {
Expand Down
5 changes: 3 additions & 2 deletions agent-inject/agent/container_sidecar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add different test cases under TestContainerSidecar() to test varying annotation sets containing 2 new annotations?

// 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"

func TestContainerSidecar(t *testing.T) {
annotations := map[string]string{
AnnotationVaultRole: "foobar",
}
pod := testPod(annotations)

if container.Args[0] != arg {
t.Errorf("arg value wrong, should have been %s, got %s", arg, container.Args[0])
Comment on lines +288 to +290
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we also add a similar assertion for agent.ProxyUseAutoAuthToken?

}

if container.Resources.Limits.Cpu().String() != DefaultResourceLimitCPU {
Expand Down