diff --git a/pkg/clusteragent/admission/mutate/agent_sidecar/agent_sidecar.go b/pkg/clusteragent/admission/mutate/agent_sidecar/agent_sidecar.go index 7bdaeea8d61f5..41a3b8de830d2 100644 --- a/pkg/clusteragent/admission/mutate/agent_sidecar/agent_sidecar.go +++ b/pkg/clusteragent/admission/mutate/agent_sidecar/agent_sidecar.go @@ -10,8 +10,10 @@ package agentsidecar import ( "errors" + "fmt" dca_ac "github.com/DataDog/datadog-agent/pkg/clusteragent/admission/mutate" "github.com/DataDog/datadog-agent/pkg/config" + apiCommon "github.com/DataDog/datadog-agent/pkg/util/kubernetes/apiserver/common" "github.com/DataDog/datadog-agent/pkg/util/log" authenticationv1 "k8s.io/api/authentication/v1" corev1 "k8s.io/api/core/v1" @@ -61,6 +63,10 @@ func getDefaultSidecarTemplate() *corev1.Container { ddSite = config.DefaultSite } + containerRegistry := config.Datadog.GetString("admission_controller.agent_sidecar.container_registry") + imageName := config.Datadog.GetString("admission_controller.agent_sidecar.image_name") + imageTag := config.Datadog.GetString("admission_controller.agent_sidecar.image_tag") + agentContainer := &corev1.Container{ Env: []corev1.EnvVar{ { @@ -92,7 +98,7 @@ func getDefaultSidecarTemplate() *corev1.Container { }, }, }, - Image: "datadog/agent", + Image: fmt.Sprintf("%s/%s:%s", containerRegistry, imageName, imageTag), ImagePullPolicy: corev1.PullIfNotPresent, Name: agentSidecarContainerName, Resources: corev1.ResourceRequirements{ @@ -107,5 +113,33 @@ func getDefaultSidecarTemplate() *corev1.Container { }, } + clusterAgentEnabled := config.Datadog.GetBool("admission_controller.agent_sidecar.cluster_agent.enabled") + + if clusterAgentEnabled { + clusterAgentCmdPort := config.Datadog.GetInt("cluster_agent.cmd_port") + clusterAgentServiceName := config.Datadog.GetString("cluster_agent.kubernetes_service_name") + + _ = withEnvOverrides(agentContainer, corev1.EnvVar{ + Name: "DD_CLUSTER_AGENT_ENABLED", + Value: "true", + }, corev1.EnvVar{ + Name: "DD_CLUSTER_AGENT_AUTH_TOKEN", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + Key: "token", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "datadog-secret", + }, + }, + }, + }, corev1.EnvVar{ + Name: "DD_CLUSTER_AGENT_URL", + Value: fmt.Sprintf("https://%s.%s.svc.cluster.local:%v", clusterAgentServiceName, apiCommon.GetMyNamespace(), clusterAgentCmdPort), + }, corev1.EnvVar{ + Name: "DD_ORCHESTRATOR_EXPLORER_ENABLED", + Value: "true", + }) + } + return agentContainer } diff --git a/pkg/clusteragent/admission/mutate/agent_sidecar/agent_sidecar_test.go b/pkg/clusteragent/admission/mutate/agent_sidecar/agent_sidecar_test.go index 55aaa95b69625..dd2a805e37c32 100644 --- a/pkg/clusteragent/admission/mutate/agent_sidecar/agent_sidecar_test.go +++ b/pkg/clusteragent/admission/mutate/agent_sidecar/agent_sidecar_test.go @@ -8,7 +8,9 @@ package agentsidecar import ( + "fmt" "github.com/DataDog/datadog-agent/pkg/config" + apicommon "github.com/DataDog/datadog-agent/pkg/util/kubernetes/apiserver/common" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" @@ -253,3 +255,146 @@ func TestInjectAgentSidecar(t *testing.T) { } } + +func TestDefaultSidecarTemplateAgentImage(t *testing.T) { + mockConfig := config.Mock(t) + + tests := []struct { + name string + setConfig func() + expectedImage string + }{ + { + name: "no configuration set", + setConfig: func() {}, + expectedImage: "gcr.io/datadoghq/agent:latest", + }, + { + name: "setting custom registry, image and tag", + setConfig: func() { + mockConfig.SetWithoutSource("admission_controller.agent_sidecar.container_registry", "my-registry") + mockConfig.SetWithoutSource("admission_controller.agent_sidecar.image_name", "my-image") + mockConfig.SetWithoutSource("admission_controller.agent_sidecar.image_tag", "my-tag") + }, + expectedImage: "my-registry/my-image:my-tag", + }, + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + test.setConfig() + sidecar := getDefaultSidecarTemplate() + assert.Equal(tt, test.expectedImage, sidecar.Image) + }) + } +} + +func TestDefaultSidecarTemplateClusterAgentEnvVars(t *testing.T) { + mockConfig := config.Mock(t) + + tests := []struct { + name string + setConfig func() + expectedEnvVars []corev1.EnvVar + unexpectedEnvVars []string + }{ + { + name: "cluster agent not enabled", + setConfig: func() { + mockConfig.SetWithoutSource("admission_controller.agent_sidecar.cluster_agent.enabled", false) + }, + unexpectedEnvVars: []string{ + "DD_CLUSTER_AGENT_ENABLED", + "DD_CLUSTER_AGENT_AUTH_TOKEN", + "DD_CLUSTER_AGENT_URL", + "DD_ORCHESTRATOR_EXPLORER_ENABLED", + }, + }, + { + name: "cluster agent enabled with default values", + setConfig: func() { + mockConfig.SetWithoutSource("admission_controller.agent_sidecar.cluster_agent.enabled", true) + }, + expectedEnvVars: []corev1.EnvVar{ + { + Name: "DD_CLUSTER_AGENT_ENABLED", + Value: "true", + }, + { + Name: "DD_CLUSTER_AGENT_AUTH_TOKEN", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + Key: "token", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "datadog-secret", + }, + }, + }, + }, + { + Name: "DD_CLUSTER_AGENT_URL", + Value: fmt.Sprintf("https://datadog-cluster-agent.%s.svc.cluster.local:5005", apicommon.GetMyNamespace()), + }, + { + Name: "DD_ORCHESTRATOR_EXPLORER_ENABLED", + Value: "true", + }, + }, + }, + { + name: "cluster agent enabled with custom values", + setConfig: func() { + mockConfig.SetWithoutSource("admission_controller.agent_sidecar.cluster_agent.enabled", true) + mockConfig.SetWithoutSource("cluster_agent.cmd_port", 12345) + mockConfig.SetWithoutSource("cluster_agent.kubernetes_service_name", "test-service-name") + }, + expectedEnvVars: []corev1.EnvVar{ + { + Name: "DD_CLUSTER_AGENT_ENABLED", + Value: "true", + }, + { + Name: "DD_CLUSTER_AGENT_AUTH_TOKEN", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + Key: "token", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "datadog-secret", + }, + }, + }, + }, + { + Name: "DD_CLUSTER_AGENT_URL", + Value: fmt.Sprintf("https://test-service-name.%s.svc.cluster.local:12345", apicommon.GetMyNamespace()), + }, + { + Name: "DD_ORCHESTRATOR_EXPLORER_ENABLED", + Value: "true", + }, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + test.setConfig() + sidecar := getDefaultSidecarTemplate() + envVarsMap := make(map[string]corev1.EnvVar) + for _, envVar := range sidecar.Env { + envVarsMap[envVar.Name] = envVar + } + + for _, expectedVar := range test.expectedEnvVars { + _, exist := envVarsMap[expectedVar.Name] + assert.True(t, exist) + assert.Equal(tt, expectedVar, envVarsMap[expectedVar.Name]) + } + + for _, unexpectedVar := range test.unexpectedEnvVars { + _, exist := envVarsMap[unexpectedVar] + assert.False(t, exist) + } + }) + } +} diff --git a/pkg/config/setup/config.go b/pkg/config/setup/config.go index 046a02eb44b50..fe333a2036737 100644 --- a/pkg/config/setup/config.go +++ b/pkg/config/setup/config.go @@ -1081,6 +1081,10 @@ func InitConfig(config pkgconfigmodel.Config) { config.BindEnvAndSetDefault("admission_controller.agent_sidecar.selectors", "[]") // Should be able to parse it to a list of env vars and resource limits config.BindEnvAndSetDefault("admission_controller.agent_sidecar.profiles", "[]") + config.BindEnvAndSetDefault("admission_controller.agent_sidecar.container_registry", "gcr.io/datadoghq") + config.BindEnvAndSetDefault("admission_controller.agent_sidecar.image_name", "agent") + config.BindEnvAndSetDefault("admission_controller.agent_sidecar.image_tag", "latest") + config.BindEnvAndSetDefault("admission_controller.agent_sidecar.cluster_agent.enabled", "true") // Telemetry // Enable telemetry metrics on the internals of the Agent. diff --git a/releasenotes-dca/notes/enable-dca-in-agent-sidecar-80a2a12b482c1a62.yaml b/releasenotes-dca/notes/enable-dca-in-agent-sidecar-80a2a12b482c1a62.yaml new file mode 100644 index 0000000000000..167845d130a4e --- /dev/null +++ b/releasenotes-dca/notes/enable-dca-in-agent-sidecar-80a2a12b482c1a62.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Enable `cluster agent` in injected Agent sidecar container by default. + Set the default configuration for connecting with the `cluster agent`.