From 135ae7ab146d7520b7c8c8bb7b27e0c2413281c6 Mon Sep 17 00:00:00 2001 From: Fanny Jiang Date: Mon, 18 Nov 2024 19:11:36 -0500 Subject: [PATCH 01/11] fix namespaces in DDA w/operator components --- .../datadog/agent/kubernetes_operator.go | 44 ++++++++----------- .../datadog/agentwithoperatorparams/params.go | 4 +- components/datadog/apps/dda/datadogagent.go | 9 +++- components/datadog/operatorparams/params.go | 5 +-- 4 files changed, 28 insertions(+), 34 deletions(-) diff --git a/components/datadog/agent/kubernetes_operator.go b/components/datadog/agent/kubernetes_operator.go index 8b666ab0b..b0f731fd3 100644 --- a/components/datadog/agent/kubernetes_operator.go +++ b/components/datadog/agent/kubernetes_operator.go @@ -15,14 +15,7 @@ import ( func NewDDAWithOperator(e config.Env, resourceName string, kubeProvider *kubernetes.Provider, operatorOpts []operatorparams.Option, ddaOptions ...agentwithoperatorparams.Option) (*KubernetesAgent, error) { return components.NewComponent(e, resourceName, func(comp *KubernetesAgent) error { - - operatorParams, err := operatorparams.NewParams(e, operatorOpts...) - if err != nil { - return err - } - ddaParams, err := agentwithoperatorparams.NewParams(ddaOptions...) - if err != nil { return err } @@ -33,36 +26,37 @@ func NewDDAWithOperator(e config.Env, resourceName string, kubeProvider *kuberne return err } - _, err = dda.K8sAppDefinition(e, kubeProvider, "datadog", ddaParams.FakeIntake, ddaParams.KubeletTLSVerify, e.Ctx().Stack(), ddaParams.DDAConfig, utils.PulumiDependsOn(operatorComp)) + dda, err := dda.K8sAppDefinition(e, kubeProvider, ddaParams.Namespace, ddaParams.FakeIntake, ddaParams.KubeletTLSVerify, e.Ctx().Stack(), ddaParams.DDAConfig, utils.PulumiDependsOn(operatorComp)) if err != nil { return err } - baseName := "dda-linux" + if dda != nil { + baseName := "dda-linux" - comp.LinuxNodeAgent, err = NewKubernetesObjRef(e, baseName+"-nodeAgent", operatorParams.Namespace, "Pod", pulumi.String("appVersion").ToStringOutput(), pulumi.String("Version").ToStringOutput(), map[string]string{"app": baseName + "-datadog"}) + comp.LinuxNodeAgent, err = NewKubernetesObjRef(e, baseName+"-nodeAgent", ddaParams.Namespace, "Pod", pulumi.String("appVersion").ToStringOutput(), pulumi.String("Version").ToStringOutput(), map[string]string{"app": baseName + "-datadog"}) - if err != nil { - return err - } + if err != nil { + return err + } - comp.LinuxClusterAgent, err = NewKubernetesObjRef(e, baseName+"-clusterAgent", operatorParams.Namespace, "Pod", pulumi.String("appVersion").ToStringOutput(), pulumi.String("Version").ToStringOutput(), map[string]string{ - "app": baseName + "-datadog-cluster-agent", - }) + comp.LinuxClusterAgent, err = NewKubernetesObjRef(e, baseName+"-clusterAgent", ddaParams.Namespace, "Pod", pulumi.String("appVersion").ToStringOutput(), pulumi.String("Version").ToStringOutput(), map[string]string{ + "app": baseName + "-datadog-cluster-agent", + }) - if err != nil { - return err - } + if err != nil { + return err + } - comp.LinuxClusterChecks, err = NewKubernetesObjRef(e, baseName+"-clusterChecks", operatorParams.Namespace, "Pod", pulumi.String("appVersion").ToStringOutput(), pulumi.String("version").ToStringOutput(), map[string]string{ - "app": baseName + "-datadog-clusterchecks", - }) + comp.LinuxClusterChecks, err = NewKubernetesObjRef(e, baseName+"-clusterChecks", ddaParams.Namespace, "Pod", pulumi.String("appVersion").ToStringOutput(), pulumi.String("version").ToStringOutput(), map[string]string{ + "app": baseName + "-datadog-clusterchecks", + }) - if err != nil { - return err + if err != nil { + return err + } } - return nil }) } diff --git a/components/datadog/agentwithoperatorparams/params.go b/components/datadog/agentwithoperatorparams/params.go index df0a39ce0..cc0342880 100644 --- a/components/datadog/agentwithoperatorparams/params.go +++ b/components/datadog/agentwithoperatorparams/params.go @@ -20,9 +20,7 @@ type Params struct { type Option = func(*Params) error func NewParams(options ...Option) (*Params, error) { - version := &Params{ - Namespace: "datadog", - } + version := &Params{} return common.ApplyOption(version, options) } diff --git a/components/datadog/apps/dda/datadogagent.go b/components/datadog/apps/dda/datadogagent.go index c83a943e4..27dea9182 100644 --- a/components/datadog/apps/dda/datadogagent.go +++ b/components/datadog/apps/dda/datadogagent.go @@ -84,12 +84,17 @@ func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, namespace configureImagePullSecret(ddaConfig, imagePullSecret) } + ddaName := "datadog-agent" + if e.PipelineID() != "" { + ddaName = fmt.Sprintf("datadog-agent-%s", e.PipelineID()) + } + _, err = apiextensions.NewCustomResource(e.Ctx(), "datadog-agent", &apiextensions.CustomResourceArgs{ ApiVersion: pulumi.String("datadoghq.com/v2alpha1"), Kind: pulumi.String("DatadogAgent"), Metadata: &metav1.ObjectMetaArgs{ - Name: pulumi.String("datadog"), - Namespace: pulumi.String("datadog"), + Name: pulumi.String(ddaName), + Namespace: pulumi.String(namespace), }, OtherFields: ddaConfig, }, opts...) diff --git a/components/datadog/operatorparams/params.go b/components/datadog/operatorparams/params.go index 188fb01b3..8a03d31a4 100644 --- a/components/datadog/operatorparams/params.go +++ b/components/datadog/operatorparams/params.go @@ -24,10 +24,7 @@ type Params struct { type Option = func(*Params) error func NewParams(e config.Env, options ...Option) (*Params, error) { - version := &Params{ - Namespace: "datadog", - OperatorFullImagePath: "gcr.io/datadoghq/operator:latest", - } + version := &Params{} if e.PipelineID() != "" && e.CommitSHA() != "" { options = append(options, WithOperatorFullImagePath(utils.BuildDockerImagePath(fmt.Sprintf("%s/operator", e.InternalRegistry()), fmt.Sprintf("%s-%s", e.PipelineID(), e.CommitSHA())))) From 75195b0216afb40ff1b8b1ede17ca1d9b9a22924 Mon Sep 17 00:00:00 2001 From: Fanny Jiang Date: Thu, 21 Nov 2024 19:48:21 -0500 Subject: [PATCH 02/11] apply review suggestions, refactor --- .../datadog/agent/helm/kubernetes_agent.go | 13 +++--- components/datadog/agent/kubernetes.go | 25 ++++++----- .../datadog/agent/kubernetes_operator.go | 44 +++++++++---------- components/datadog/apps/dda/datadogagent.go | 21 +++++---- components/datadog/operator/operator.go | 15 +++++-- .../kubernetes_object_ref.go | 2 +- 6 files changed, 67 insertions(+), 53 deletions(-) rename components/{datadog/agent => kubernetes}/kubernetes_object_ref.go (98%) diff --git a/components/datadog/agent/helm/kubernetes_agent.go b/components/datadog/agent/helm/kubernetes_agent.go index a0140cf15..4943aa411 100644 --- a/components/datadog/agent/helm/kubernetes_agent.go +++ b/components/datadog/agent/helm/kubernetes_agent.go @@ -1,6 +1,7 @@ package helm import ( + componentskube "github.com/DataDog/test-infra-definitions/components/kubernetes" "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" @@ -43,7 +44,7 @@ func NewKubernetesAgent(e config.Env, resourceName string, kubeProvider *kuberne baseName := "dda-" + platform - comp.LinuxNodeAgent, err = agent.NewKubernetesObjRef(e, baseName+"-nodeAgent", params.Namespace, "Pod", appVersion, version, map[string]string{ + comp.LinuxNodeAgent, err = componentskube.NewKubernetesObjRef(e, baseName+"-nodeAgent", params.Namespace, "Pod", appVersion, version, map[string]string{ "app": baseName + "-datadog", }) @@ -51,7 +52,7 @@ func NewKubernetesAgent(e config.Env, resourceName string, kubeProvider *kuberne return err } - comp.LinuxClusterAgent, err = agent.NewKubernetesObjRef(e, baseName+"-clusterAgent", params.Namespace, "Pod", appVersion, version, map[string]string{ + comp.LinuxClusterAgent, err = componentskube.NewKubernetesObjRef(e, baseName+"-clusterAgent", params.Namespace, "Pod", appVersion, version, map[string]string{ "app": baseName + "-datadog-cluster-agent", }) @@ -59,7 +60,7 @@ func NewKubernetesAgent(e config.Env, resourceName string, kubeProvider *kuberne return err } - comp.LinuxClusterChecks, err = agent.NewKubernetesObjRef(e, baseName+"-clusterChecks", params.Namespace, "Pod", appVersion, version, map[string]string{ + comp.LinuxClusterChecks, err = componentskube.NewKubernetesObjRef(e, baseName+"-clusterChecks", params.Namespace, "Pod", appVersion, version, map[string]string{ "app": baseName + "-datadog-clusterchecks", }) @@ -70,21 +71,21 @@ func NewKubernetesAgent(e config.Env, resourceName string, kubeProvider *kuberne baseName = "dda-" + platform - comp.WindowsNodeAgent, err = agent.NewKubernetesObjRef(e, baseName+"-nodeAgent", params.Namespace, "Pod", appVersion, version, map[string]string{ + comp.WindowsNodeAgent, err = componentskube.NewKubernetesObjRef(e, baseName+"-nodeAgent", params.Namespace, "Pod", appVersion, version, map[string]string{ "app": baseName + "-datadog", }) if err != nil { return err } - comp.WindowsClusterAgent, err = agent.NewKubernetesObjRef(e, baseName+"-clusterAgent", params.Namespace, "Pod", appVersion, version, map[string]string{ + comp.WindowsClusterAgent, err = componentskube.NewKubernetesObjRef(e, baseName+"-clusterAgent", params.Namespace, "Pod", appVersion, version, map[string]string{ "app": baseName + "-datadog-cluster-agent", }) if err != nil { return err } - comp.WindowsClusterChecks, err = agent.NewKubernetesObjRef(e, baseName+"-clusterChecks", params.Namespace, "Pod", appVersion, version, map[string]string{ + comp.WindowsClusterChecks, err = componentskube.NewKubernetesObjRef(e, baseName+"-clusterChecks", params.Namespace, "Pod", appVersion, version, map[string]string{ "app": baseName + "-datadog-clusterchecks", }) if err != nil { diff --git a/components/datadog/agent/kubernetes.go b/components/datadog/agent/kubernetes.go index 3da247593..64b529db2 100644 --- a/components/datadog/agent/kubernetes.go +++ b/components/datadog/agent/kubernetes.go @@ -1,6 +1,7 @@ package agent import ( + "github.com/DataDog/test-infra-definitions/components/kubernetes" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" "github.com/DataDog/test-infra-definitions/components" @@ -9,13 +10,13 @@ import ( type KubernetesAgentOutput struct { components.JSONImporter - LinuxNodeAgent KubernetesObjRefOutput `json:"linuxNodeAgent"` - LinuxClusterAgent KubernetesObjRefOutput `json:"linuxClusterAgent"` - LinuxClusterChecks KubernetesObjRefOutput `json:"linuxClusterChecks"` + LinuxNodeAgent kubernetes.KubernetesObjRefOutput `json:"linuxNodeAgent"` + LinuxClusterAgent kubernetes.KubernetesObjRefOutput `json:"linuxClusterAgent"` + LinuxClusterChecks kubernetes.KubernetesObjRefOutput `json:"linuxClusterChecks"` - WindowsNodeAgent KubernetesObjRefOutput `json:"windowsNodeAgent"` - WindowsClusterAgent KubernetesObjRefOutput `json:"windowsClusterAgent"` - WindowsClusterChecks KubernetesObjRefOutput `json:"windowsClusterChecks"` + WindowsNodeAgent kubernetes.KubernetesObjRefOutput `json:"windowsNodeAgent"` + WindowsClusterAgent kubernetes.KubernetesObjRefOutput `json:"windowsClusterAgent"` + WindowsClusterChecks kubernetes.KubernetesObjRefOutput `json:"windowsClusterChecks"` } // KubernetesAgent is an installer to install the Datadog Agent on a Kubernetes cluster. @@ -23,13 +24,13 @@ type KubernetesAgent struct { pulumi.ResourceState components.Component - LinuxNodeAgent *KubernetesObjectRef `pulumi:"linuxNodeAgent"` - LinuxClusterAgent *KubernetesObjectRef `pulumi:"linuxClusterAgent"` - LinuxClusterChecks *KubernetesObjectRef `pulumi:"linuxClusterChecks"` + LinuxNodeAgent *kubernetes.KubernetesObjectRef `pulumi:"linuxNodeAgent"` + LinuxClusterAgent *kubernetes.KubernetesObjectRef `pulumi:"linuxClusterAgent"` + LinuxClusterChecks *kubernetes.KubernetesObjectRef `pulumi:"linuxClusterChecks"` - WindowsNodeAgent *KubernetesObjectRef `pulumi:"windowsNodeAgent"` - WindowsClusterAgent *KubernetesObjectRef `pulumi:"windowsClusterAgent"` - WindowsClusterChecks *KubernetesObjectRef `pulumi:"windowsClusterChecks"` + WindowsNodeAgent *kubernetes.KubernetesObjectRef `pulumi:"windowsNodeAgent"` + WindowsClusterAgent *kubernetes.KubernetesObjectRef `pulumi:"windowsClusterAgent"` + WindowsClusterChecks *kubernetes.KubernetesObjectRef `pulumi:"windowsClusterChecks"` } func (h *KubernetesAgent) Export(ctx *pulumi.Context, out *KubernetesAgentOutput) error { diff --git a/components/datadog/agent/kubernetes_operator.go b/components/datadog/agent/kubernetes_operator.go index b0f731fd3..a36f6f5a4 100644 --- a/components/datadog/agent/kubernetes_operator.go +++ b/components/datadog/agent/kubernetes_operator.go @@ -1,9 +1,6 @@ package agent import ( - "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes" - "github.com/pulumi/pulumi/sdk/v3/go/pulumi" - "github.com/DataDog/test-infra-definitions/common/config" "github.com/DataDog/test-infra-definitions/common/utils" "github.com/DataDog/test-infra-definitions/components" @@ -11,6 +8,8 @@ import ( "github.com/DataDog/test-infra-definitions/components/datadog/apps/dda" "github.com/DataDog/test-infra-definitions/components/datadog/operator" "github.com/DataDog/test-infra-definitions/components/datadog/operatorparams" + componentskube "github.com/DataDog/test-infra-definitions/components/kubernetes" + "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes" ) func NewDDAWithOperator(e config.Env, resourceName string, kubeProvider *kubernetes.Provider, operatorOpts []operatorparams.Option, ddaOptions ...agentwithoperatorparams.Option) (*KubernetesAgent, error) { @@ -26,37 +25,38 @@ func NewDDAWithOperator(e config.Env, resourceName string, kubeProvider *kuberne return err } - dda, err := dda.K8sAppDefinition(e, kubeProvider, ddaParams.Namespace, ddaParams.FakeIntake, ddaParams.KubeletTLSVerify, e.Ctx().Stack(), ddaParams.DDAConfig, utils.PulumiDependsOn(operatorComp)) + _, ddaRef, err := dda.K8sAppDefinition(e, kubeProvider, ddaParams.Namespace, ddaParams.FakeIntake, ddaParams.KubeletTLSVerify, e.Ctx().Stack(), ddaParams.DDAConfig, utils.PulumiDependsOn(operatorComp)) if err != nil { return err } - if dda != nil { - baseName := "dda-linux" + baseName := "dda-linux" + appVersion := ddaRef.AppVersion + apiVersion := ddaRef.Version - comp.LinuxNodeAgent, err = NewKubernetesObjRef(e, baseName+"-nodeAgent", ddaParams.Namespace, "Pod", pulumi.String("appVersion").ToStringOutput(), pulumi.String("Version").ToStringOutput(), map[string]string{"app": baseName + "-datadog"}) + comp.LinuxNodeAgent, err = componentskube.NewKubernetesObjRef(e, baseName+"-nodeAgent", ddaParams.Namespace, "Pod", appVersion, apiVersion.ToStringOutput(), map[string]string{"app": baseName + "-datadog"}) - if err != nil { - return err - } + if err != nil { + return err + } - comp.LinuxClusterAgent, err = NewKubernetesObjRef(e, baseName+"-clusterAgent", ddaParams.Namespace, "Pod", pulumi.String("appVersion").ToStringOutput(), pulumi.String("Version").ToStringOutput(), map[string]string{ - "app": baseName + "-datadog-cluster-agent", - }) + comp.LinuxClusterAgent, err = componentskube.NewKubernetesObjRef(e, baseName+"-clusterAgent", ddaParams.Namespace, "Pod", appVersion, apiVersion, map[string]string{ + "app": baseName + "-datadog-cluster-agent", + }) - if err != nil { - return err - } + if err != nil { + return err + } - comp.LinuxClusterChecks, err = NewKubernetesObjRef(e, baseName+"-clusterChecks", ddaParams.Namespace, "Pod", pulumi.String("appVersion").ToStringOutput(), pulumi.String("version").ToStringOutput(), map[string]string{ - "app": baseName + "-datadog-clusterchecks", - }) + comp.LinuxClusterChecks, err = componentskube.NewKubernetesObjRef(e, baseName+"-clusterChecks", ddaParams.Namespace, "Pod", appVersion, apiVersion, map[string]string{ + "app": baseName + "-datadog-clusterchecks", + }) - if err != nil { - return err - } + if err != nil { + return err } + return nil }) } diff --git a/components/datadog/apps/dda/datadogagent.go b/components/datadog/apps/dda/datadogagent.go index 27dea9182..6048fc4b9 100644 --- a/components/datadog/apps/dda/datadogagent.go +++ b/components/datadog/apps/dda/datadogagent.go @@ -3,6 +3,7 @@ package dda import ( "encoding/json" "fmt" + "strings" "dario.cat/mergo" "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes" @@ -18,7 +19,7 @@ import ( componentskube "github.com/DataDog/test-infra-definitions/components/kubernetes" ) -func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, namespace string, fakeIntake *fakeintake.Fakeintake, kubeletTLSVerify bool, clusterName string, customDda string, opts ...pulumi.ResourceOption) (*componentskube.Workload, error) { +func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, namespace string, fakeIntake *fakeintake.Fakeintake, kubeletTLSVerify bool, clusterName string, customDda string, opts ...pulumi.ResourceOption) (*componentskube.Workload, *componentskube.KubernetesObjectRef, error) { apiKey := e.AgentAPIKey() appKey := e.AgentAPPKey() baseName := "dda-with-operator" @@ -26,7 +27,7 @@ func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, namespace k8sComponent := &componentskube.Workload{} if err := e.Ctx().RegisterComponentResource("dd:agent-with-operator", "dda", k8sComponent, opts...); err != nil { - return nil, err + return nil, nil, err } opts = append(opts, pulumi.Parent(k8sComponent)) @@ -42,7 +43,7 @@ func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, namespace opts..., ) if err != nil { - return nil, err + return nil, nil, err } opts = append(opts, utils.PulumiDependsOn(ns)) @@ -59,7 +60,7 @@ func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, namespace }, }, opts...) if err != nil { - return nil, err + return nil, nil, err } opts = append(opts, utils.PulumiDependsOn(secret)) @@ -70,7 +71,7 @@ func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, namespace ddaConfig, err = mergeYamlToConfig(ddaConfig, customDda) if err != nil { - return nil, err + return nil, nil, err } // Image pull secrets need to be configured after custom DDA config merge because pulumi.StringOutput cannot be marshalled to JSON @@ -78,7 +79,7 @@ func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, namespace if e.ImagePullRegistry() != "" { imagePullSecret, err = utils.NewImagePullSecret(e, namespace, opts...) if err != nil { - return nil, err + return nil, nil, err } opts = append(opts, utils.PulumiDependsOn(imagePullSecret)) configureImagePullSecret(ddaConfig, imagePullSecret) @@ -86,7 +87,7 @@ func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, namespace ddaName := "datadog-agent" if e.PipelineID() != "" { - ddaName = fmt.Sprintf("datadog-agent-%s", e.PipelineID()) + ddaName = strings.Join([]string{ddaName, e.PipelineID()}, "-") } _, err = apiextensions.NewCustomResource(e.Ctx(), "datadog-agent", &apiextensions.CustomResourceArgs{ @@ -99,10 +100,12 @@ func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, namespace OtherFields: ddaConfig, }, opts...) if err != nil { - return nil, err + return nil, nil, err } - return k8sComponent, nil + ddaRef, err := componentskube.NewKubernetesObjRef(e, baseName, namespace, "DatadogAgent", pulumi.String("").ToStringOutput(), pulumi.String("datadoghq.com/v2alpha1").ToStringOutput(), map[string]string{"app": baseName}) + + return k8sComponent, ddaRef, nil } func buildDDAConfig(baseName string, clusterName string, kubeletTLSVerify bool) kubernetes.UntypedArgs { diff --git a/components/datadog/operator/operator.go b/components/datadog/operator/operator.go index 69c90043d..76a309ff7 100644 --- a/components/datadog/operator/operator.go +++ b/components/datadog/operator/operator.go @@ -1,6 +1,7 @@ package operator import ( + compkubernetes "github.com/DataDog/test-infra-definitions/components/kubernetes" "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" @@ -10,17 +11,19 @@ import ( ) // OperatorOutput is used to import the Operator component -type Output struct { +type OperatorOutput struct { components.JSONImporter + Operator compkubernetes.KubernetesObjectRef `json:"operator"` } // Operator represents an Operator installation type Operator struct { pulumi.ResourceState components.Component + Operator *compkubernetes.KubernetesObjectRef `json:"operator"` } -func (h *Operator) Export(ctx *pulumi.Context, out *Output) error { +func (h *Operator) Export(ctx *pulumi.Context, out *OperatorOutput) error { return components.Export(ctx, h, out) } @@ -32,7 +35,7 @@ func NewOperator(e config.Env, resourceName string, kubeProvider *kubernetes.Pro } pulumiResourceOptions := append(params.PulumiResourceOptions, pulumi.Parent(comp)) - _, err = NewHelmInstallation(e, HelmInstallationArgs{ + release, err := NewHelmInstallation(e, HelmInstallationArgs{ KubeProvider: kubeProvider, Namespace: params.Namespace, ValuesYAML: params.HelmValues, @@ -42,6 +45,12 @@ func NewOperator(e config.Env, resourceName string, kubeProvider *kubernetes.Pro return err } + comp.Operator, err = compkubernetes.NewKubernetesObjRef(e, "datadog-operator", params.Namespace, "Pod", release.LinuxHelmReleaseStatus.AppVersion().Elem(), release.LinuxHelmReleaseStatus.Version().Elem(), map[string]string{"app": "datadog-operator"}) + + if err != nil { + return err + } + return nil }) } diff --git a/components/datadog/agent/kubernetes_object_ref.go b/components/kubernetes/kubernetes_object_ref.go similarity index 98% rename from components/datadog/agent/kubernetes_object_ref.go rename to components/kubernetes/kubernetes_object_ref.go index 7bdcf8b2e..184ce25c9 100644 --- a/components/datadog/agent/kubernetes_object_ref.go +++ b/components/kubernetes/kubernetes_object_ref.go @@ -1,4 +1,4 @@ -package agent +package kubernetes import ( "github.com/pulumi/pulumi/sdk/v3/go/pulumi" From 8355c2d964502974f8334ddf8a13e36226697abc Mon Sep 17 00:00:00 2001 From: Fanny Jiang Date: Thu, 21 Nov 2024 20:15:51 -0500 Subject: [PATCH 03/11] nolint --- components/datadog/apps/dda/datadogagent.go | 3 +++ components/datadog/operator/operator.go | 2 +- components/kubernetes/kubernetes_object_ref.go | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/components/datadog/apps/dda/datadogagent.go b/components/datadog/apps/dda/datadogagent.go index 6048fc4b9..f0a2b4581 100644 --- a/components/datadog/apps/dda/datadogagent.go +++ b/components/datadog/apps/dda/datadogagent.go @@ -104,6 +104,9 @@ func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, namespace } ddaRef, err := componentskube.NewKubernetesObjRef(e, baseName, namespace, "DatadogAgent", pulumi.String("").ToStringOutput(), pulumi.String("datadoghq.com/v2alpha1").ToStringOutput(), map[string]string{"app": baseName}) + if err != nil { + return nil, nil, err + } return k8sComponent, ddaRef, nil } diff --git a/components/datadog/operator/operator.go b/components/datadog/operator/operator.go index 76a309ff7..f08bdf195 100644 --- a/components/datadog/operator/operator.go +++ b/components/datadog/operator/operator.go @@ -11,7 +11,7 @@ import ( ) // OperatorOutput is used to import the Operator component -type OperatorOutput struct { +type OperatorOutput struct { // nolint:revive, We want to keep the name as Output components.JSONImporter Operator compkubernetes.KubernetesObjectRef `json:"operator"` } diff --git a/components/kubernetes/kubernetes_object_ref.go b/components/kubernetes/kubernetes_object_ref.go index 184ce25c9..29d79a1e5 100644 --- a/components/kubernetes/kubernetes_object_ref.go +++ b/components/kubernetes/kubernetes_object_ref.go @@ -7,7 +7,7 @@ import ( "github.com/DataDog/test-infra-definitions/components" ) -type KubernetesObjRefOutput struct { +type KubernetesObjRefOutput struct { // nolint:revive, We want to keep the name as Output components.JSONImporter Namespace string `json:"namespace"` @@ -18,7 +18,7 @@ type KubernetesObjRefOutput struct { LabelSelectors map[string]string `json:"labelSelectors"` } -type KubernetesObjectRef struct { +type KubernetesObjectRef struct { // nolint:revive, We want to keep the name as Output pulumi.ResourceState components.Component From 29112d35e06c24aff4659fb3f1b2976a3d003ff9 Mon Sep 17 00:00:00 2001 From: Fanny Jiang Date: Tue, 3 Dec 2024 14:57:07 -0500 Subject: [PATCH 04/11] add more params --- .../datadog/agent/kubernetes_operator.go | 22 +- .../datadog/agentwithoperatorparams/params.go | 20 +- components/datadog/apps/dda/datadogagent.go | 447 ++++++++++-------- components/datadog/operator/component.go | 27 ++ components/datadog/operator/operator.go | 17 - components/datadog/operatorparams/params.go | 8 + 6 files changed, 310 insertions(+), 231 deletions(-) create mode 100644 components/datadog/operator/component.go diff --git a/components/datadog/agent/kubernetes_operator.go b/components/datadog/agent/kubernetes_operator.go index a36f6f5a4..91b455e83 100644 --- a/components/datadog/agent/kubernetes_operator.go +++ b/components/datadog/agent/kubernetes_operator.go @@ -2,46 +2,38 @@ package agent import ( "github.com/DataDog/test-infra-definitions/common/config" - "github.com/DataDog/test-infra-definitions/common/utils" "github.com/DataDog/test-infra-definitions/components" "github.com/DataDog/test-infra-definitions/components/datadog/agentwithoperatorparams" "github.com/DataDog/test-infra-definitions/components/datadog/apps/dda" - "github.com/DataDog/test-infra-definitions/components/datadog/operator" - "github.com/DataDog/test-infra-definitions/components/datadog/operatorparams" componentskube "github.com/DataDog/test-infra-definitions/components/kubernetes" "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" ) -func NewDDAWithOperator(e config.Env, resourceName string, kubeProvider *kubernetes.Provider, operatorOpts []operatorparams.Option, ddaOptions ...agentwithoperatorparams.Option) (*KubernetesAgent, error) { +func NewDDAWithOperator(e config.Env, resourceName string, kubeProvider *kubernetes.Provider, ddaOptions ...agentwithoperatorparams.Option) (*KubernetesAgent, error) { return components.NewComponent(e, resourceName, func(comp *KubernetesAgent) error { ddaParams, err := agentwithoperatorparams.NewParams(ddaOptions...) if err != nil { return err } - operatorComp, err := operator.NewOperator(e, resourceName, kubeProvider, operatorOpts...) + pulumiResourceOptions := append(ddaParams.PulumiResourceOptions, pulumi.Parent(comp)) - if err != nil { - return err - } - - _, ddaRef, err := dda.K8sAppDefinition(e, kubeProvider, ddaParams.Namespace, ddaParams.FakeIntake, ddaParams.KubeletTLSVerify, e.Ctx().Stack(), ddaParams.DDAConfig, utils.PulumiDependsOn(operatorComp)) + _, err = dda.K8sAppDefinition(e, kubeProvider, ddaOptions, pulumiResourceOptions...) if err != nil { return err } baseName := "dda-linux" - appVersion := ddaRef.AppVersion - apiVersion := ddaRef.Version - comp.LinuxNodeAgent, err = componentskube.NewKubernetesObjRef(e, baseName+"-nodeAgent", ddaParams.Namespace, "Pod", appVersion, apiVersion.ToStringOutput(), map[string]string{"app": baseName + "-datadog"}) + comp.LinuxNodeAgent, err = componentskube.NewKubernetesObjRef(e, baseName+"-nodeAgent", ddaParams.Namespace, "Pod", pulumi.String("").ToStringOutput(), pulumi.String("datadoghq/v2alpha1").ToStringOutput(), map[string]string{"app": baseName + "-datadog"}) if err != nil { return err } - comp.LinuxClusterAgent, err = componentskube.NewKubernetesObjRef(e, baseName+"-clusterAgent", ddaParams.Namespace, "Pod", appVersion, apiVersion, map[string]string{ + comp.LinuxClusterAgent, err = componentskube.NewKubernetesObjRef(e, baseName+"-clusterAgent", ddaParams.Namespace, "Pod", pulumi.String("").ToStringOutput(), pulumi.String("datadoghq/v2alpha1").ToStringOutput(), map[string]string{ "app": baseName + "-datadog-cluster-agent", }) @@ -49,7 +41,7 @@ func NewDDAWithOperator(e config.Env, resourceName string, kubeProvider *kuberne return err } - comp.LinuxClusterChecks, err = componentskube.NewKubernetesObjRef(e, baseName+"-clusterChecks", ddaParams.Namespace, "Pod", appVersion, apiVersion, map[string]string{ + comp.LinuxClusterChecks, err = componentskube.NewKubernetesObjRef(e, baseName+"-clusterChecks", ddaParams.Namespace, "Pod", pulumi.String("").ToStringOutput(), pulumi.String("datadoghq/v2alpha1").ToStringOutput(), map[string]string{ "app": baseName + "-datadog-clusterchecks", }) diff --git a/components/datadog/agentwithoperatorparams/params.go b/components/datadog/agentwithoperatorparams/params.go index cc0342880..40c5c918a 100644 --- a/components/datadog/agentwithoperatorparams/params.go +++ b/components/datadog/agentwithoperatorparams/params.go @@ -13,7 +13,7 @@ type Params struct { Namespace string FakeIntake *fakeintake.Fakeintake - DDAConfig string + DDAConfig DDAConfig KubeletTLSVerify bool } @@ -48,10 +48,10 @@ func WithPulumiResourceOptions(resources ...pulumi.ResourceOption) func(*Params) } } -// WithDDAConfig configures the DatadogAgent resource. -func WithDDAConfig(config string) func(*Params) error { +// WithDDAConfig configures the DatadogAgent custom resource. +func WithDDAConfig(config DDAConfig) func(*Params) error { return func(p *Params) error { - p.DDAConfig = p.DDAConfig + config + p.DDAConfig = config return nil } } @@ -64,3 +64,15 @@ func WithFakeIntake(fakeintake *fakeintake.Fakeintake) func(*Params) error { return nil } } + +// DDAConfig is the DatadogAgent custom resource configuration. +type DDAConfig struct { + // Name of the DatadogAgent custom resource + Name string `json:"name"` + // YamlFilePath file path to the DatadogAgent custom resource YAML + YamlFilePath string `json:"yamlFilePath,omitempty"` + // YamlConfig is the YAML string of the DatadogAgent custom resource + YamlConfig string `json:"YamlConfig,omitempty"` + // MapConfig is the map representation of the DatadogAgent custom resource + MapConfig map[string]interface{} `json:"MapConfig,omitempty"` +} diff --git a/components/datadog/apps/dda/datadogagent.go b/components/datadog/apps/dda/datadogagent.go index f0a2b4581..f4d7a7d9a 100644 --- a/components/datadog/apps/dda/datadogagent.go +++ b/components/datadog/apps/dda/datadogagent.go @@ -1,57 +1,58 @@ package dda import ( - "encoding/json" "fmt" - "strings" "dario.cat/mergo" + "github.com/DataDog/test-infra-definitions/common/config" + "github.com/DataDog/test-infra-definitions/common/utils" + "github.com/DataDog/test-infra-definitions/components/datadog/agentwithoperatorparams" + componentskube "github.com/DataDog/test-infra-definitions/components/kubernetes" "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes" - "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/apiextensions" corev1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/core/v1" metav1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/meta/v1" + "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/yaml" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" - "gopkg.in/yaml.v3" +) - "github.com/DataDog/test-infra-definitions/common/config" - "github.com/DataDog/test-infra-definitions/common/utils" - "github.com/DataDog/test-infra-definitions/components/datadog/fakeintake" - componentskube "github.com/DataDog/test-infra-definitions/components/kubernetes" +const ( + baseName = "agent-with-operator" ) -func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, namespace string, fakeIntake *fakeintake.Fakeintake, kubeletTLSVerify bool, clusterName string, customDda string, opts ...pulumi.ResourceOption) (*componentskube.Workload, *componentskube.KubernetesObjectRef, error) { +type datadogAgentWorkload struct { + ctx *pulumi.Context + opts *agentwithoperatorparams.Params + name string + clusterName string + imagePullSecret *corev1.Secret +} + +func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, ddaOpts []agentwithoperatorparams.Option, opts ...pulumi.ResourceOption) (*componentskube.Workload, error) { + if ddaOpts == nil { + return nil, nil + } apiKey := e.AgentAPIKey() appKey := e.AgentAPPKey() - baseName := "dda-with-operator" + clusterName := e.Ctx().Stack() + + ddaOptions, err := agentwithoperatorparams.NewParams(ddaOpts...) + if err != nil { + return nil, err + } + opts = append(opts, pulumi.Provider(kubeProvider), pulumi.Parent(kubeProvider), pulumi.DeletedWith(kubeProvider)) k8sComponent := &componentskube.Workload{} if err := e.Ctx().RegisterComponentResource("dd:agent-with-operator", "dda", k8sComponent, opts...); err != nil { - return nil, nil, err + return nil, err } opts = append(opts, pulumi.Parent(k8sComponent)) - ns, err := corev1.NewNamespace( - e.Ctx(), - namespace, - &corev1.NamespaceArgs{ - Metadata: metav1.ObjectMetaArgs{ - Name: pulumi.String(namespace), - }, - }, - opts..., - ) - if err != nil { - return nil, nil, err - } - - opts = append(opts, utils.PulumiDependsOn(ns)) - - // Create secret if necessary + // Create datadog-credentials secret if necessary secret, err := corev1.NewSecret(e.Ctx(), "datadog-credentials", &corev1.SecretArgs{ Metadata: metav1.ObjectMetaArgs{ - Namespace: ns.Metadata.Name(), + Namespace: pulumi.String(ddaOptions.Namespace), Name: pulumi.Sprintf("%s-datadog-credentials", baseName), }, StringData: pulumi.StringMap{ @@ -60,215 +61,271 @@ func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, namespace }, }, opts...) if err != nil { - return nil, nil, err + return nil, err } opts = append(opts, utils.PulumiDependsOn(secret)) - ddaConfig := buildDDAConfig(baseName, clusterName, kubeletTLSVerify) - if fakeIntake != nil { - configureFakeIntake(ddaConfig, fakeIntake) - } - ddaConfig, err = mergeYamlToConfig(ddaConfig, customDda) - - if err != nil { - return nil, nil, err - } - - // Image pull secrets need to be configured after custom DDA config merge because pulumi.StringOutput cannot be marshalled to JSON + // Create imagePullSecret var imagePullSecret *corev1.Secret if e.ImagePullRegistry() != "" { - imagePullSecret, err = utils.NewImagePullSecret(e, namespace, opts...) + imagePullSecret, err = utils.NewImagePullSecret(e, ddaOptions.Namespace, opts...) if err != nil { - return nil, nil, err + return nil, err } opts = append(opts, utils.PulumiDependsOn(imagePullSecret)) - configureImagePullSecret(ddaConfig, imagePullSecret) } - ddaName := "datadog-agent" - if e.PipelineID() != "" { - ddaName = strings.Join([]string{ddaName, e.PipelineID()}, "-") + ddaWorkload := datadogAgentWorkload{ + ctx: e.Ctx(), + opts: ddaOptions, + name: ddaOptions.DDAConfig.Name, + clusterName: clusterName, + imagePullSecret: imagePullSecret, } - _, err = apiextensions.NewCustomResource(e.Ctx(), "datadog-agent", &apiextensions.CustomResourceArgs{ - ApiVersion: pulumi.String("datadoghq.com/v2alpha1"), - Kind: pulumi.String("DatadogAgent"), - Metadata: &metav1.ObjectMetaArgs{ - Name: pulumi.String(ddaName), - Namespace: pulumi.String(namespace), - }, - OtherFields: ddaConfig, - }, opts...) - if err != nil { - return nil, nil, err + if err = ddaWorkload.buildDDAConfig(opts...); err != nil { + return nil, err } - ddaRef, err := componentskube.NewKubernetesObjRef(e, baseName, namespace, "DatadogAgent", pulumi.String("").ToStringOutput(), pulumi.String("datadoghq.com/v2alpha1").ToStringOutput(), map[string]string{"app": baseName}) - if err != nil { - return nil, nil, err - } + return k8sComponent, nil +} + +func (d datadogAgentWorkload) buildDDAConfig(opts ...pulumi.ResourceOption) error { + ctx := d.ctx + defaultYamlTransformations := d.defaultDDAYamlTransformations() + + if d.opts.DDAConfig.YamlFilePath != "" { + _, err := yaml.NewConfigGroup(ctx, d.name, &yaml.ConfigGroupArgs{ + Files: []string{d.opts.DDAConfig.YamlFilePath}, + Transformations: defaultYamlTransformations, + }, opts...) + + if err != nil { + return err + } + } else if d.opts.DDAConfig.YamlConfig != "" { + _, err := yaml.NewConfigGroup(ctx, d.name, &yaml.ConfigGroupArgs{ + YAML: []string{d.opts.DDAConfig.YamlConfig}, + Transformations: defaultYamlTransformations, + }, opts...) - return k8sComponent, ddaRef, nil + if err != nil { + return err + } + } else if d.opts.DDAConfig.MapConfig != nil { + _, err := yaml.NewConfigGroup(ctx, d.name, &yaml.ConfigGroupArgs{ + Objs: []map[string]interface{}{d.opts.DDAConfig.MapConfig}, + Transformations: defaultYamlTransformations, + }, opts...) + + if err != nil { + return err + } + } else { + _, err := yaml.NewConfigGroup(ctx, d.name, &yaml.ConfigGroupArgs{ + Objs: []map[string]interface{}{d.defaultDDAConfig()}, + Transformations: d.defaultDDAYamlTransformations(), + }, opts...) + + if err != nil { + return err + } + + } + return nil } -func buildDDAConfig(baseName string, clusterName string, kubeletTLSVerify bool) kubernetes.UntypedArgs { - return kubernetes.UntypedArgs{ - "spec": pulumi.Map{ - "global": pulumi.Map{ - "clusterName": pulumi.String(clusterName), - "kubelet": pulumi.Map{ - "tlsVerify": pulumi.Bool(kubeletTLSVerify), +func (d datadogAgentWorkload) defaultDDAConfig() map[string]interface{} { + return map[string]interface{}{ + "apiVersion": "datadoghq.com/v2alpha1", + "kind": "DatadogAgent", + "metadata": map[string]interface{}{ + "name": d.opts.DDAConfig.Name, + "namespace": d.opts.Namespace, + }, + "spec": map[string]interface{}{ + "global": map[string]interface{}{ + "clusterName": d.clusterName, + "kubelet": map[string]interface{}{ + "tlsVerify": d.opts.KubeletTLSVerify, }, - "credentials": pulumi.Map{ - "apiSecret": pulumi.Map{ - "secretName": pulumi.String(baseName + "-datadog-credentials"), - "keyName": pulumi.String("api-key"), + "credentials": map[string]interface{}{ + "apiSecret": map[string]interface{}{ + "secretName": baseName + "-datadog-credentials", + "keyName": "api-key", }, - "appSecret": pulumi.Map{ - "secretName": pulumi.String(baseName + "-datadog-credentials"), - "keyName": pulumi.String("app-key"), + "appSecret": map[string]interface{}{ + "secretName": baseName + "-datadog-credentials", + "keyName": "app-key", }, }, }, - "features": pulumi.Map{ - "clusterChecks": pulumi.Map{ - "enabled": pulumi.Bool(true), - "useClusterChecksRunners": pulumi.Bool(true), - }, - "dogstatsd": pulumi.Map{ - "tagCardinality": pulumi.String("high"), - }, - "logCollection": pulumi.Map{ - "enabled": pulumi.Bool(true), - "containerCollectAll": pulumi.Bool(true), - "containerCollectUsingFiles": pulumi.Bool(true), - }, - "prometheusScrape": pulumi.Map{ - "enabled": pulumi.Bool(true), - "version": pulumi.Int(2), - }, - "liveProcessCollection": pulumi.Map{ - "enabled": pulumi.Bool(true), - }, - "eventCollection": pulumi.Map{ - "collectKubernetesEvents": pulumi.Bool(false), + "features": map[string]interface{}{ + "clusterChecks": map[string]interface{}{ + "enabled": true, + "useClusterChecksRunners": true, }, }, }, } } -func configureFakeIntake(config kubernetes.UntypedArgs, fakeintake *fakeintake.Fakeintake) { - if fakeintake == nil { - return - } - endpointsEnvVar := pulumi.StringMapArray{ - pulumi.StringMap{ - "name": pulumi.String("DD_DD_URL"), - "value": pulumi.String(fmt.Sprintf("%v", fakeintake.URL)), +func (d datadogAgentWorkload) fakeIntakeEnvVars() []map[string]interface{} { + return []map[string]interface{}{ + { + "name": "DD_DD_URL", + "value": d.opts.FakeIntake.URL, }, - pulumi.StringMap{ - "name": pulumi.String("DD_PROCESS_CONFIG_PROCESS_DD_URL"), - "value": pulumi.String(fmt.Sprintf("%v", fakeintake.URL)), + { + "name": "DD_PROCESS_CONFIG_PROCESS_DD_URL", + "value": d.opts.FakeIntake.URL, }, - pulumi.StringMap{ - "name": pulumi.String("DD_APM_DD_URL"), - "value": pulumi.String(fmt.Sprintf("%v", fakeintake.URL)), + { + "name": "DD_APM_DD_URL", + "value": d.opts.FakeIntake.URL, }, - pulumi.StringMap{ - "name": pulumi.String("DD_SKIP_SSL_VALIDATION"), - "value": pulumi.String("true"), + { + "name": "DD_SKIP_SSL_VALIDATION", + "value": "true", }, - pulumi.StringMap{ - "name": pulumi.String("DD_REMOTE_CONFIGURATION_NO_TLS_VALIDATION"), - "value": pulumi.String("true"), + { + "name": "DD_REMOTE_CONFIGURATION_NO_TLS_VALIDATION", + "value": "true", }, - pulumi.StringMap{ - "name": pulumi.String("DD_LOGS_CONFIG_USE_HTTP"), - "value": pulumi.String("true"), + { + "name": "DD_LOGS_CONFIG_USE_HTTP", + "value": "true", }, } - for _, section := range []string{"nodeAgent", "clusterAgent", "clusterChecksRunner"} { - if _, found := config["spec"].(pulumi.Map)["override"]; !found { - config["spec"].(pulumi.Map)["override"] = pulumi.Map{ - section: pulumi.Map{ - "env": endpointsEnvVar, - }, +} + +func (d datadogAgentWorkload) defaultDDAYamlTransformations() []yaml.Transformation { + return []yaml.Transformation{ + // Override custom DDAConfig with required defaults + func(state map[string]interface{}, opts ...pulumi.ResourceOption) { + defaultDDAConfig := d.defaultDDAConfig() + err := mergo.Merge(&state, defaultDDAConfig) + if err != nil { + d.ctx.Log.Debug(fmt.Sprintf("There was a problem merging the default DDA config: %v", err), nil) } - } else if _, found = config["spec"].(pulumi.Map)["override"].(pulumi.Map)[section]; !found { - config["spec"].(pulumi.Map)["override"].(pulumi.Map)[section] = pulumi.Map{ - "env": endpointsEnvVar, + }, + // Configure metadata + func(state map[string]interface{}, opts ...pulumi.ResourceOption) { + if state["metadata"] == nil { + state["metadata"] = map[string]interface{}{ + "name": d.opts.DDAConfig.Name, + "namespace": d.opts.Namespace, + } } - } else if _, found = config["spec"].(pulumi.Map)["override"].(pulumi.Map)[section].(pulumi.Map)["env"]; !found { - config["spec"].(pulumi.Map)["override"].(pulumi.Map)[section].(pulumi.Map)["env"] = endpointsEnvVar - } else { - config["spec"].(pulumi.Map)["override"].(pulumi.Map)[section].(pulumi.Map)["env"] = append(config["spec"].(pulumi.Map)["override"].(pulumi.Map)[section].(pulumi.Map)["env"].(pulumi.StringMapArray), endpointsEnvVar...) - } - } -} + state["metadata"].(map[string]interface{})["namespace"] = d.opts.Namespace -func configureImagePullSecret(config kubernetes.UntypedArgs, secret *corev1.Secret) { - if secret == nil { - return - } + state["metadata"].(map[string]interface{})["name"] = d.opts.DDAConfig.Name - for _, section := range []string{"nodeAgent", "clusterAgent", "clusterChecksRunner"} { - if _, found := config["spec"].(map[string]interface{})["override"].(map[string]interface{})[section]; !found { - config["spec"].(map[string]interface{})["override"].(map[string]interface{})[section] = pulumi.Map{ - "image": pulumi.Map{ - "pullSecrets": pulumi.MapArray{ - pulumi.Map{ - "name": secret.Metadata.Name(), - }, - }, - }, + if state["spec"].(map[string]interface{})["global"] == nil { + state["spec"].(map[string]interface{})["global"] = map[string]interface{}{ + "clusterName": d.clusterName, + } + } else { + state["spec"].(map[string]interface{})["global"].(map[string]interface{})["clusterName"] = d.clusterName } - } else if _, found = config["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["image"]; !found { - config["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["image"] = pulumi.Map{ - "pullSecrets": pulumi.MapArray{ - pulumi.Map{ - "name": secret.Metadata.Name(), + }, + // Configure global + func(state map[string]interface{}, opts ...pulumi.ResourceOption) { + defaultGlobal := map[string]interface{}{ + "clusterName": d.clusterName, + "kubelet": map[string]interface{}{ + "tlsVerify": d.opts.KubeletTLSVerify, + }, + "credentials": map[string]interface{}{ + "apiSecret": map[string]interface{}{ + "secretName": baseName + "-datadog-credentials", + "keyName": "api-key", + }, + "appSecret": map[string]interface{}{ + "secretName": baseName + "-datadog-credentials", + "keyName": "app-key", }, }, } - } else { - config["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["image"].(map[string]interface{})["pullSecrets"] = pulumi.MapArray{ - pulumi.Map{ - "name": secret.Metadata.Name(), - }, + if state["spec"].(map[string]interface{})["global"] == nil { + state["spec"].(map[string]interface{})["global"] = defaultGlobal + } else { + stateGlobal := state["spec"].(map[string]interface{})["global"].(map[string]interface{}) + for k, v := range defaultGlobal { + if stateGlobal[k] == nil { + stateGlobal[k] = v + } else { + err := mergo.Map(stateGlobal[k], defaultGlobal[k]) + if err != nil { + d.ctx.Log.Debug(fmt.Sprintf("Error merging YAML maps: %v", err), nil) + } + } + } } - } - } -} - -func mergeYamlToConfig(config kubernetes.UntypedArgs, yamlConfig string) (kubernetes.UntypedArgs, error) { - var configMap, yamlMap map[string]interface{} - configJSON, err := json.Marshal(config) - if err != nil { - fmt.Println(fmt.Sprintf("Error marshalling original DDA config: %v)", err)) - return config, err - } - - if err := json.Unmarshal(configJSON, &configMap); err != nil { - return config, fmt.Errorf("error unmarshalling original DDA config: %v", err) - } - if err := yaml.Unmarshal([]byte(yamlConfig), &yamlMap); err != nil { - return config, fmt.Errorf("error unmarshalling new DDA yaml config: %v", err) - } - - if err := mergo.Map(&configMap, yamlMap, mergo.WithOverride); err != nil { - return config, fmt.Errorf("error merging DDA configs: %v", err) - } - - merged, err := json.Marshal(configMap) - if err != nil { - return config, fmt.Errorf("error marshalling merged DDA config: %v", err) - } - - var mergedConfig kubernetes.UntypedArgs - if err = json.Unmarshal(merged, &mergedConfig); err != nil { - return config, fmt.Errorf("error ummarshalling merged DDA config: %v", err) + }, + // Configure Fake Intake + func(state map[string]interface{}, opts ...pulumi.ResourceOption) { + if d.opts.FakeIntake == nil { + return + } + for _, section := range []string{"nodeAgent", "clusterAgent", "clusterChecksRunner"} { + if state["spec"].(map[string]interface{})["override"] == nil { + state["spec"].(map[string]interface{})["override"] = map[string]interface{}{ + section: map[string]interface{}{ + "env": d.fakeIntakeEnvVars(), + }, + } + } + if state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section] == nil { + state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section] = map[string]interface{}{ + "env": d.fakeIntakeEnvVars(), + } + } + if state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["env"] == nil { + state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["env"] = d.fakeIntakeEnvVars() + } + if state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["env"].([]map[string]interface{}) != nil { + env := state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["env"].([]map[string]interface{}) + env = append(env, d.fakeIntakeEnvVars()...) + } + } + }, + // Configure Image pull secret + func(state map[string]interface{}, opts ...pulumi.ResourceOption) { + if d.imagePullSecret == nil { + return + } + for _, section := range []string{"nodeAgent", "clusterAgent", "clusterChecksRunner"} { + if _, found := state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section]; !found { + state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section] = map[string]interface{}{ + "image": map[string]interface{}{ + "pullSecrets": map[string]interface{}{ + "name": d.imagePullSecret.Metadata.Name(), + }, + }, + } + } + if _, found := state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["image"]; !found { + state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["image"] = map[string]interface{}{ + "pullSecrets": []map[string]interface{}{{ + "name": d.imagePullSecret.Metadata.Name(), + }}, + } + } + if _, found := state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["image"]; !found { + state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["image"] = map[string]interface{}{ + "pullSecrets": []map[string]interface{}{{ + "name": d.imagePullSecret.Metadata.Name(), + }}, + } + } + if _, found := state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["image"].(map[string]interface{})["pullSecrets"]; found { + pullSecrets := state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["image"].(map[string]interface{})["pullSecrets"].([]map[string]interface{}) + pullSecrets = append(pullSecrets, map[string]interface{}{ + "name": d.imagePullSecret.Metadata.Name(), + }) + } + } + }, } - - return mergedConfig, nil } diff --git a/components/datadog/operator/component.go b/components/datadog/operator/component.go new file mode 100644 index 000000000..93975be46 --- /dev/null +++ b/components/datadog/operator/component.go @@ -0,0 +1,27 @@ +package operator + +import ( + compkubernetes "github.com/DataDog/test-infra-definitions/components/kubernetes" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + + "github.com/DataDog/test-infra-definitions/components" +) + +// OperatorOutput is used to import the Operator component +type OperatorOutput struct { // nolint:revive, We want to keep the name as Output + components.JSONImporter + + Operator compkubernetes.KubernetesObjRefOutput `pulumi:"operator"` +} + +// Operator represents an Operator installation +type Operator struct { + pulumi.ResourceState + components.Component + + Operator *compkubernetes.KubernetesObjectRef `pulumi:"operator"` +} + +func (o *Operator) Export(ctx *pulumi.Context, out *OperatorOutput) error { + return components.Export(ctx, o, out) +} diff --git a/components/datadog/operator/operator.go b/components/datadog/operator/operator.go index f08bdf195..07d206acf 100644 --- a/components/datadog/operator/operator.go +++ b/components/datadog/operator/operator.go @@ -10,23 +10,6 @@ import ( "github.com/DataDog/test-infra-definitions/components/datadog/operatorparams" ) -// OperatorOutput is used to import the Operator component -type OperatorOutput struct { // nolint:revive, We want to keep the name as Output - components.JSONImporter - Operator compkubernetes.KubernetesObjectRef `json:"operator"` -} - -// Operator represents an Operator installation -type Operator struct { - pulumi.ResourceState - components.Component - Operator *compkubernetes.KubernetesObjectRef `json:"operator"` -} - -func (h *Operator) Export(ctx *pulumi.Context, out *OperatorOutput) error { - return components.Export(ctx, h, out) -} - func NewOperator(e config.Env, resourceName string, kubeProvider *kubernetes.Provider, options ...operatorparams.Option) (*Operator, error) { return components.NewComponent(e, resourceName, func(comp *Operator) error { params, err := operatorparams.NewParams(e, options...) diff --git a/components/datadog/operatorparams/params.go b/components/datadog/operatorparams/params.go index 8a03d31a4..4274a7389 100644 --- a/components/datadog/operatorparams/params.go +++ b/components/datadog/operatorparams/params.go @@ -57,3 +57,11 @@ func WithHelmValues(values string) func(*Params) error { return nil } } + +// WithPulumiResourceOptions sets the resources to depend on. +func WithPulumiResourceOptions(resources ...pulumi.ResourceOption) func(*Params) error { + return func(p *Params) error { + p.PulumiResourceOptions = append(p.PulumiResourceOptions, resources...) + return nil + } +} From 23a0e2816e9c538c54358442b171a9c813465249 Mon Sep 17 00:00:00 2001 From: Fanny Jiang Date: Tue, 3 Dec 2024 17:05:41 -0500 Subject: [PATCH 05/11] add logs_dd_url var for fakeintake --- components/datadog/apps/dda/datadogagent.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/components/datadog/apps/dda/datadogagent.go b/components/datadog/apps/dda/datadogagent.go index f4d7a7d9a..de515e24e 100644 --- a/components/datadog/apps/dda/datadogagent.go +++ b/components/datadog/apps/dda/datadogagent.go @@ -185,15 +185,19 @@ func (d datadogAgentWorkload) fakeIntakeEnvVars() []map[string]interface{} { "value": d.opts.FakeIntake.URL, }, { - "name": "DD_SKIP_SSL_VALIDATION", + "name": "DD_LOGS_CONFIG_LOGS_DD_URL", + "value": d.opts.FakeIntake.URL, + }, + { + "name": "DD_LOGS_CONFIG_USE_HTTP", "value": "true", }, { - "name": "DD_REMOTE_CONFIGURATION_NO_TLS_VALIDATION", + "name": "DD_SKIP_SSL_VALIDATION", "value": "true", }, { - "name": "DD_LOGS_CONFIG_USE_HTTP", + "name": "DD_REMOTE_CONFIGURATION_NO_TLS_VALIDATION", "value": "true", }, } From ea0d6a19b150d15c3d23f259a6c7f97b66d350a7 Mon Sep 17 00:00:00 2001 From: Fanny Jiang Date: Fri, 6 Dec 2024 17:14:14 -0500 Subject: [PATCH 06/11] cleanup --- .../datadog/agent/kubernetes_operator.go | 2 +- .../datadog/agentwithoperatorparams/params.go | 15 +++--------- components/datadog/apps/dda/datadogagent.go | 23 +++++-------------- components/datadog/operatorparams/params.go | 6 ++--- 4 files changed, 13 insertions(+), 33 deletions(-) diff --git a/components/datadog/agent/kubernetes_operator.go b/components/datadog/agent/kubernetes_operator.go index 91b455e83..63fd9cf89 100644 --- a/components/datadog/agent/kubernetes_operator.go +++ b/components/datadog/agent/kubernetes_operator.go @@ -19,7 +19,7 @@ func NewDDAWithOperator(e config.Env, resourceName string, kubeProvider *kuberne pulumiResourceOptions := append(ddaParams.PulumiResourceOptions, pulumi.Parent(comp)) - _, err = dda.K8sAppDefinition(e, kubeProvider, ddaOptions, pulumiResourceOptions...) + _, err = dda.K8sAppDefinition(e, kubeProvider, ddaParams, pulumiResourceOptions...) if err != nil { return err diff --git a/components/datadog/agentwithoperatorparams/params.go b/components/datadog/agentwithoperatorparams/params.go index 40c5c918a..73022bf45 100644 --- a/components/datadog/agentwithoperatorparams/params.go +++ b/components/datadog/agentwithoperatorparams/params.go @@ -11,10 +11,9 @@ import ( type Params struct { PulumiResourceOptions []pulumi.ResourceOption - Namespace string - FakeIntake *fakeintake.Fakeintake - DDAConfig DDAConfig - KubeletTLSVerify bool + Namespace string + FakeIntake *fakeintake.Fakeintake + DDAConfig DDAConfig } type Option = func(*Params) error @@ -32,14 +31,6 @@ func WithNamespace(namespace string) func(*Params) error { } } -// WithTLSKubeletVerify toggles kubelet TLS verification. -func WithTLSKubeletVerify(verify bool) func(*Params) error { - return func(p *Params) error { - p.KubeletTLSVerify = verify - return nil - } -} - // WithPulumiResourceOptions sets the resources to depend on. func WithPulumiResourceOptions(resources ...pulumi.ResourceOption) func(*Params) error { return func(p *Params) error { diff --git a/components/datadog/apps/dda/datadogagent.go b/components/datadog/apps/dda/datadogagent.go index de515e24e..6b7453d05 100644 --- a/components/datadog/apps/dda/datadogagent.go +++ b/components/datadog/apps/dda/datadogagent.go @@ -27,19 +27,14 @@ type datadogAgentWorkload struct { imagePullSecret *corev1.Secret } -func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, ddaOpts []agentwithoperatorparams.Option, opts ...pulumi.ResourceOption) (*componentskube.Workload, error) { - if ddaOpts == nil { +func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, params *agentwithoperatorparams.Params, opts ...pulumi.ResourceOption) (*componentskube.Workload, error) { + if params == nil { return nil, nil } apiKey := e.AgentAPIKey() appKey := e.AgentAPPKey() clusterName := e.Ctx().Stack() - ddaOptions, err := agentwithoperatorparams.NewParams(ddaOpts...) - if err != nil { - return nil, err - } - opts = append(opts, pulumi.Provider(kubeProvider), pulumi.Parent(kubeProvider), pulumi.DeletedWith(kubeProvider)) k8sComponent := &componentskube.Workload{} @@ -52,7 +47,7 @@ func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, ddaOpts [ // Create datadog-credentials secret if necessary secret, err := corev1.NewSecret(e.Ctx(), "datadog-credentials", &corev1.SecretArgs{ Metadata: metav1.ObjectMetaArgs{ - Namespace: pulumi.String(ddaOptions.Namespace), + Namespace: pulumi.String(params.Namespace), Name: pulumi.Sprintf("%s-datadog-credentials", baseName), }, StringData: pulumi.StringMap{ @@ -68,7 +63,7 @@ func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, ddaOpts [ // Create imagePullSecret var imagePullSecret *corev1.Secret if e.ImagePullRegistry() != "" { - imagePullSecret, err = utils.NewImagePullSecret(e, ddaOptions.Namespace, opts...) + imagePullSecret, err = utils.NewImagePullSecret(e, params.Namespace, opts...) if err != nil { return nil, err } @@ -77,8 +72,8 @@ func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, ddaOpts [ ddaWorkload := datadogAgentWorkload{ ctx: e.Ctx(), - opts: ddaOptions, - name: ddaOptions.DDAConfig.Name, + opts: params, + name: params.DDAConfig.Name, clusterName: clusterName, imagePullSecret: imagePullSecret, } @@ -146,9 +141,6 @@ func (d datadogAgentWorkload) defaultDDAConfig() map[string]interface{} { "spec": map[string]interface{}{ "global": map[string]interface{}{ "clusterName": d.clusterName, - "kubelet": map[string]interface{}{ - "tlsVerify": d.opts.KubeletTLSVerify, - }, "credentials": map[string]interface{}{ "apiSecret": map[string]interface{}{ "secretName": baseName + "-datadog-credentials", @@ -237,9 +229,6 @@ func (d datadogAgentWorkload) defaultDDAYamlTransformations() []yaml.Transformat func(state map[string]interface{}, opts ...pulumi.ResourceOption) { defaultGlobal := map[string]interface{}{ "clusterName": d.clusterName, - "kubelet": map[string]interface{}{ - "tlsVerify": d.opts.KubeletTLSVerify, - }, "credentials": map[string]interface{}{ "apiSecret": map[string]interface{}{ "secretName": baseName + "-datadog-credentials", diff --git a/components/datadog/operatorparams/params.go b/components/datadog/operatorparams/params.go index 4274a7389..24606eb2d 100644 --- a/components/datadog/operatorparams/params.go +++ b/components/datadog/operatorparams/params.go @@ -11,11 +11,11 @@ import ( ) type Params struct { - // OperatorFullImagePath is the full path of the docker agent image to use. + // OperatorFullImagePath is the full path of the operator image to use. OperatorFullImagePath string - // Namespace is the namespace to deploy the agent to. + // Namespace is the namespace to deploy the operator to. Namespace string - // HelmValues is the Helm values to use for the agent installation. + // HelmValues is the Helm values to use for the operator installation. HelmValues pulumi.AssetOrArchiveArray // PulumiResourceOptions is a list of resources to depend on. PulumiResourceOptions []pulumi.ResourceOption From c94aeef6ac8cc044f011e649d3cf65701eb1ba7f Mon Sep 17 00:00:00 2001 From: Fanny Jiang Date: Mon, 9 Dec 2024 14:00:16 -0500 Subject: [PATCH 07/11] more refactor --- .../datadog/agent/kubernetes_operator.go | 6 +- components/datadog/apps/dda/datadogagent.go | 150 +++++++----------- components/datadog/operator/component.go | 2 +- components/datadog/operator/helm.go | 2 +- components/datadog/operator/operator.go | 2 +- 5 files changed, 67 insertions(+), 95 deletions(-) diff --git a/components/datadog/agent/kubernetes_operator.go b/components/datadog/agent/kubernetes_operator.go index 63fd9cf89..71a0c13e6 100644 --- a/components/datadog/agent/kubernetes_operator.go +++ b/components/datadog/agent/kubernetes_operator.go @@ -27,14 +27,14 @@ func NewDDAWithOperator(e config.Env, resourceName string, kubeProvider *kuberne baseName := "dda-linux" - comp.LinuxNodeAgent, err = componentskube.NewKubernetesObjRef(e, baseName+"-nodeAgent", ddaParams.Namespace, "Pod", pulumi.String("").ToStringOutput(), pulumi.String("datadoghq/v2alpha1").ToStringOutput(), map[string]string{"app": baseName + "-datadog"}) + comp.LinuxNodeAgent, err = componentskube.NewKubernetesObjRef(e, baseName+"-nodeAgent", ddaParams.Namespace, "Pod", pulumi.String("").ToStringOutput(), pulumi.String("datadoghq/v2alpha1").ToStringOutput(), map[string]string{"app.kubernetes.io/instance": ddaParams.DDAConfig.Name + "-agent"}) if err != nil { return err } comp.LinuxClusterAgent, err = componentskube.NewKubernetesObjRef(e, baseName+"-clusterAgent", ddaParams.Namespace, "Pod", pulumi.String("").ToStringOutput(), pulumi.String("datadoghq/v2alpha1").ToStringOutput(), map[string]string{ - "app": baseName + "-datadog-cluster-agent", + "app.kubernetes.io/instance": ddaParams.DDAConfig.Name + "-cluster-agent", }) if err != nil { @@ -42,7 +42,7 @@ func NewDDAWithOperator(e config.Env, resourceName string, kubeProvider *kuberne } comp.LinuxClusterChecks, err = componentskube.NewKubernetesObjRef(e, baseName+"-clusterChecks", ddaParams.Namespace, "Pod", pulumi.String("").ToStringOutput(), pulumi.String("datadoghq/v2alpha1").ToStringOutput(), map[string]string{ - "app": baseName + "-datadog-clusterchecks", + "app.kubernetes.io/instance": baseName + "-cluster-checks-runner", }) if err != nil { diff --git a/components/datadog/apps/dda/datadogagent.go b/components/datadog/apps/dda/datadogagent.go index 6b7453d05..b9ec31de5 100644 --- a/components/datadog/apps/dda/datadogagent.go +++ b/components/datadog/apps/dda/datadogagent.go @@ -16,7 +16,7 @@ import ( ) const ( - baseName = "agent-with-operator" + baseName = "dda" ) type datadogAgentWorkload struct { @@ -139,19 +139,6 @@ func (d datadogAgentWorkload) defaultDDAConfig() map[string]interface{} { "namespace": d.opts.Namespace, }, "spec": map[string]interface{}{ - "global": map[string]interface{}{ - "clusterName": d.clusterName, - "credentials": map[string]interface{}{ - "apiSecret": map[string]interface{}{ - "secretName": baseName + "-datadog-credentials", - "keyName": "api-key", - }, - "appSecret": map[string]interface{}{ - "secretName": baseName + "-datadog-credentials", - "keyName": "app-key", - }, - }, - }, "features": map[string]interface{}{ "clusterChecks": map[string]interface{}{ "enabled": true, @@ -197,32 +184,21 @@ func (d datadogAgentWorkload) fakeIntakeEnvVars() []map[string]interface{} { func (d datadogAgentWorkload) defaultDDAYamlTransformations() []yaml.Transformation { return []yaml.Transformation{ - // Override custom DDAConfig with required defaults - func(state map[string]interface{}, opts ...pulumi.ResourceOption) { - defaultDDAConfig := d.defaultDDAConfig() - err := mergo.Merge(&state, defaultDDAConfig) - if err != nil { - d.ctx.Log.Debug(fmt.Sprintf("There was a problem merging the default DDA config: %v", err), nil) - } - }, // Configure metadata func(state map[string]interface{}, opts ...pulumi.ResourceOption) { + defaultMetadata := map[string]interface{}{ + "name": d.opts.DDAConfig.Name, + "namespace": d.opts.Namespace, + } if state["metadata"] == nil { - state["metadata"] = map[string]interface{}{ - "name": d.opts.DDAConfig.Name, - "namespace": d.opts.Namespace, + state["metadata"] = defaultMetadata + } else { + stateMetadata := state["metadata"].(map[string]interface{}) + err := mergo.Merge(&stateMetadata, defaultMetadata) + if err != nil { + d.ctx.Log.Debug(fmt.Sprintf("Error merging DDA metadata YAML: %v", err), nil) } - } - state["metadata"].(map[string]interface{})["namespace"] = d.opts.Namespace - state["metadata"].(map[string]interface{})["name"] = d.opts.DDAConfig.Name - - if state["spec"].(map[string]interface{})["global"] == nil { - state["spec"].(map[string]interface{})["global"] = map[string]interface{}{ - "clusterName": d.clusterName, - } - } else { - state["spec"].(map[string]interface{})["global"].(map[string]interface{})["clusterName"] = d.clusterName } }, // Configure global @@ -244,15 +220,9 @@ func (d datadogAgentWorkload) defaultDDAYamlTransformations() []yaml.Transformat state["spec"].(map[string]interface{})["global"] = defaultGlobal } else { stateGlobal := state["spec"].(map[string]interface{})["global"].(map[string]interface{}) - for k, v := range defaultGlobal { - if stateGlobal[k] == nil { - stateGlobal[k] = v - } else { - err := mergo.Map(stateGlobal[k], defaultGlobal[k]) - if err != nil { - d.ctx.Log.Debug(fmt.Sprintf("Error merging YAML maps: %v", err), nil) - } - } + err := mergo.Map(&stateGlobal, defaultGlobal) + if err != nil { + d.ctx.Log.Debug(fmt.Sprintf("Error merging DDA global YAML: %v", err), nil) } } }, @@ -261,25 +231,24 @@ func (d datadogAgentWorkload) defaultDDAYamlTransformations() []yaml.Transformat if d.opts.FakeIntake == nil { return } - for _, section := range []string{"nodeAgent", "clusterAgent", "clusterChecksRunner"} { - if state["spec"].(map[string]interface{})["override"] == nil { - state["spec"].(map[string]interface{})["override"] = map[string]interface{}{ - section: map[string]interface{}{ - "env": d.fakeIntakeEnvVars(), - }, - } - } - if state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section] == nil { - state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section] = map[string]interface{}{ - "env": d.fakeIntakeEnvVars(), - } - } - if state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["env"] == nil { - state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["env"] = d.fakeIntakeEnvVars() - } - if state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["env"].([]map[string]interface{}) != nil { - env := state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["env"].([]map[string]interface{}) - env = append(env, d.fakeIntakeEnvVars()...) + fakeIntakeOverride := map[string]interface{}{ + "nodeAgent": map[string]interface{}{ + "env": d.fakeIntakeEnvVars(), + }, + "clusterAgent": map[string]interface{}{ + "env": d.fakeIntakeEnvVars(), + }, + "clusterChecksRunner": map[string]interface{}{ + "env": d.fakeIntakeEnvVars(), + }, + } + if state["spec"].(map[string]interface{})["override"] == nil { + state["spec"].(map[string]interface{})["override"] = fakeIntakeOverride + } else { + stateOverride := state["spec"].(map[string]interface{})["override"].(map[string]interface{}) + err := mergo.Map(&stateOverride, fakeIntakeOverride) + if err != nil { + d.ctx.Log.Debug(fmt.Sprintf("Error merging fakeintake override YAML: %v", err), nil) } } }, @@ -288,35 +257,38 @@ func (d datadogAgentWorkload) defaultDDAYamlTransformations() []yaml.Transformat if d.imagePullSecret == nil { return } - for _, section := range []string{"nodeAgent", "clusterAgent", "clusterChecksRunner"} { - if _, found := state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section]; !found { - state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section] = map[string]interface{}{ - "image": map[string]interface{}{ - "pullSecrets": map[string]interface{}{ - "name": d.imagePullSecret.Metadata.Name(), - }, + + imgPullSecretOverride := map[string]interface{}{ + "nodeAgent": map[string]interface{}{ + "image": map[string]interface{}{ + "pullSecrets": map[string]interface{}{ + "name": d.imagePullSecret.Metadata.Name(), }, - } - } - if _, found := state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["image"]; !found { - state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["image"] = map[string]interface{}{ - "pullSecrets": []map[string]interface{}{{ + }, + }, + "clusterAgent": map[string]interface{}{ + "image": map[string]interface{}{ + "pullSecrets": map[string]interface{}{ "name": d.imagePullSecret.Metadata.Name(), - }}, - } - } - if _, found := state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["image"]; !found { - state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["image"] = map[string]interface{}{ - "pullSecrets": []map[string]interface{}{{ + }, + }, + }, + "clusterChecksRunner": map[string]interface{}{ + "image": map[string]interface{}{ + "pullSecrets": map[string]interface{}{ "name": d.imagePullSecret.Metadata.Name(), - }}, - } - } - if _, found := state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["image"].(map[string]interface{})["pullSecrets"]; found { - pullSecrets := state["spec"].(map[string]interface{})["override"].(map[string]interface{})[section].(map[string]interface{})["image"].(map[string]interface{})["pullSecrets"].([]map[string]interface{}) - pullSecrets = append(pullSecrets, map[string]interface{}{ - "name": d.imagePullSecret.Metadata.Name(), - }) + }, + }, + }, + } + + if state["spec"].(map[string]interface{})["override"] == nil { + state["spec"].(map[string]interface{})["override"] = imgPullSecretOverride + } else { + stateOverride := state["spec"].(map[string]interface{})["override"].(map[string]interface{}) + err := mergo.Map(&stateOverride, imgPullSecretOverride) + if err != nil { + d.ctx.Log.Debug(fmt.Sprintf("Error merging imagePullSecrets override YAML: %v", err), nil) } } }, diff --git a/components/datadog/operator/component.go b/components/datadog/operator/component.go index 93975be46..89e46b904 100644 --- a/components/datadog/operator/component.go +++ b/components/datadog/operator/component.go @@ -8,7 +8,7 @@ import ( ) // OperatorOutput is used to import the Operator component -type OperatorOutput struct { // nolint:revive, We want to keep the name as Output +type OperatorOutput struct { components.JSONImporter Operator compkubernetes.KubernetesObjRefOutput `pulumi:"operator"` diff --git a/components/datadog/operator/helm.go b/components/datadog/operator/helm.go index 15701ebe1..7bda78e3b 100644 --- a/components/datadog/operator/helm.go +++ b/components/datadog/operator/helm.go @@ -93,7 +93,7 @@ func NewHelmInstallation(e config.Env, args HelmInstallationArgs, opts ...pulumi operatorImagePath = args.OperatorFullImagePath } operatorImagePath, operatorImageTag := utils.ParseImageReference(operatorImagePath) - linuxInstallName := baseName + "-linux" + linuxInstallName := baseName + "-operator-linux" values := buildLinuxHelmValues(baseName, operatorImagePath, operatorImageTag) values.configureImagePullSecret(imgPullSecret) diff --git a/components/datadog/operator/operator.go b/components/datadog/operator/operator.go index 07d206acf..cf8325594 100644 --- a/components/datadog/operator/operator.go +++ b/components/datadog/operator/operator.go @@ -28,7 +28,7 @@ func NewOperator(e config.Env, resourceName string, kubeProvider *kubernetes.Pro return err } - comp.Operator, err = compkubernetes.NewKubernetesObjRef(e, "datadog-operator", params.Namespace, "Pod", release.LinuxHelmReleaseStatus.AppVersion().Elem(), release.LinuxHelmReleaseStatus.Version().Elem(), map[string]string{"app": "datadog-operator"}) + comp.Operator, err = compkubernetes.NewKubernetesObjRef(e, "datadog-operator", params.Namespace, "Pod", release.LinuxHelmReleaseStatus.AppVersion().Elem(), release.LinuxHelmReleaseStatus.Version().Elem(), map[string]string{"app.kubernetes.io/name": "datadog-operator"}) if err != nil { return err From 2dfb561f5149acbe199953aea56ddcccd2d63c28 Mon Sep 17 00:00:00 2001 From: Fanny Jiang Date: Mon, 9 Dec 2024 14:05:54 -0500 Subject: [PATCH 08/11] fix labelselector --- components/datadog/agent/kubernetes_operator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/datadog/agent/kubernetes_operator.go b/components/datadog/agent/kubernetes_operator.go index 71a0c13e6..c04b0b3ee 100644 --- a/components/datadog/agent/kubernetes_operator.go +++ b/components/datadog/agent/kubernetes_operator.go @@ -42,7 +42,7 @@ func NewDDAWithOperator(e config.Env, resourceName string, kubeProvider *kuberne } comp.LinuxClusterChecks, err = componentskube.NewKubernetesObjRef(e, baseName+"-clusterChecks", ddaParams.Namespace, "Pod", pulumi.String("").ToStringOutput(), pulumi.String("datadoghq/v2alpha1").ToStringOutput(), map[string]string{ - "app.kubernetes.io/instance": baseName + "-cluster-checks-runner", + "app.kubernetes.io/instance": ddaParams.DDAConfig.Name + "-cluster-checks-runner", }) if err != nil { From 1ab12b16151107cedbcaa54a10a1c7809cf12c65 Mon Sep 17 00:00:00 2001 From: Fanny Jiang Date: Mon, 9 Dec 2024 15:41:55 -0500 Subject: [PATCH 09/11] fix dda kindvm --- scenarios/aws/kindvm/run.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scenarios/aws/kindvm/run.go b/scenarios/aws/kindvm/run.go index 9fc8a3d84..483312926 100644 --- a/scenarios/aws/kindvm/run.go +++ b/scenarios/aws/kindvm/run.go @@ -136,7 +136,6 @@ agents: ddaOptions = append( ddaOptions, agentwithoperatorparams.WithNamespace("datadog"), - agentwithoperatorparams.WithTLSKubeletVerify(false), ) if fakeIntake != nil { @@ -146,7 +145,7 @@ agents: ) } - operatorAgentComponent, err := agent.NewDDAWithOperator(&awsEnv, awsEnv.CommonNamer().ResourceName("dd-operator-agent"), kindKubeProvider, operatorOpts, ddaOptions...) + operatorAgentComponent, err := agent.NewDDAWithOperator(&awsEnv, awsEnv.CommonNamer().ResourceName("dd-operator-agent"), kindKubeProvider, ddaOptions...) if err != nil { return err From c83c5b7d5919f726114d27346a59b05f814dd7a8 Mon Sep 17 00:00:00 2001 From: Fanny Jiang Date: Mon, 9 Dec 2024 18:32:02 -0500 Subject: [PATCH 10/11] fix default namespace --- .../datadog/agentwithoperatorparams/params.go | 7 ++++++- components/datadog/apps/dda/datadogagent.go | 15 ++++++++++----- components/datadog/operator/component.go | 2 +- components/datadog/operatorparams/params.go | 4 +++- scenarios/aws/kindvm/run.go | 10 ++++++++++ 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/components/datadog/agentwithoperatorparams/params.go b/components/datadog/agentwithoperatorparams/params.go index 73022bf45..4b71162d4 100644 --- a/components/datadog/agentwithoperatorparams/params.go +++ b/components/datadog/agentwithoperatorparams/params.go @@ -19,7 +19,12 @@ type Params struct { type Option = func(*Params) error func NewParams(options ...Option) (*Params, error) { - version := &Params{} + version := &Params{ + Namespace: "datadog", + DDAConfig: DDAConfig{ + Name: "dda", + }, + } return common.ApplyOption(version, options) } diff --git a/components/datadog/apps/dda/datadogagent.go b/components/datadog/apps/dda/datadogagent.go index b9ec31de5..926a53b6f 100644 --- a/components/datadog/apps/dda/datadogagent.go +++ b/components/datadog/apps/dda/datadogagent.go @@ -79,6 +79,7 @@ func K8sAppDefinition(e config.Env, kubeProvider *kubernetes.Provider, params *a } if err = ddaWorkload.buildDDAConfig(opts...); err != nil { + e.Ctx().Log.Debug(fmt.Sprintf("Error building DDA config: %v", err), nil) return nil, err } @@ -96,6 +97,7 @@ func (d datadogAgentWorkload) buildDDAConfig(opts ...pulumi.ResourceOption) erro }, opts...) if err != nil { + d.ctx.Log.Debug(fmt.Sprintf("Error transforming DDAConfig yaml file path: %v", err), nil) return err } } else if d.opts.DDAConfig.YamlConfig != "" { @@ -105,6 +107,7 @@ func (d datadogAgentWorkload) buildDDAConfig(opts ...pulumi.ResourceOption) erro }, opts...) if err != nil { + d.ctx.Log.Debug(fmt.Sprintf("Error transforming DDAConfig yaml: %v", err), nil) return err } } else if d.opts.DDAConfig.MapConfig != nil { @@ -114,15 +117,17 @@ func (d datadogAgentWorkload) buildDDAConfig(opts ...pulumi.ResourceOption) erro }, opts...) if err != nil { + d.ctx.Log.Debug(fmt.Sprintf("Error transforming DDAConfig map config: %v", err), nil) return err } } else { _, err := yaml.NewConfigGroup(ctx, d.name, &yaml.ConfigGroupArgs{ Objs: []map[string]interface{}{d.defaultDDAConfig()}, - Transformations: d.defaultDDAYamlTransformations(), + Transformations: defaultYamlTransformations, }, opts...) if err != nil { + d.ctx.Log.Debug(fmt.Sprintf("Error creating default DDA config: %v", err), nil) return err } @@ -185,7 +190,7 @@ func (d datadogAgentWorkload) fakeIntakeEnvVars() []map[string]interface{} { func (d datadogAgentWorkload) defaultDDAYamlTransformations() []yaml.Transformation { return []yaml.Transformation{ // Configure metadata - func(state map[string]interface{}, opts ...pulumi.ResourceOption) { + func(state map[string]interface{}, _ ...pulumi.ResourceOption) { defaultMetadata := map[string]interface{}{ "name": d.opts.DDAConfig.Name, "namespace": d.opts.Namespace, @@ -202,7 +207,7 @@ func (d datadogAgentWorkload) defaultDDAYamlTransformations() []yaml.Transformat } }, // Configure global - func(state map[string]interface{}, opts ...pulumi.ResourceOption) { + func(state map[string]interface{}, _ ...pulumi.ResourceOption) { defaultGlobal := map[string]interface{}{ "clusterName": d.clusterName, "credentials": map[string]interface{}{ @@ -227,7 +232,7 @@ func (d datadogAgentWorkload) defaultDDAYamlTransformations() []yaml.Transformat } }, // Configure Fake Intake - func(state map[string]interface{}, opts ...pulumi.ResourceOption) { + func(state map[string]interface{}, _ ...pulumi.ResourceOption) { if d.opts.FakeIntake == nil { return } @@ -253,7 +258,7 @@ func (d datadogAgentWorkload) defaultDDAYamlTransformations() []yaml.Transformat } }, // Configure Image pull secret - func(state map[string]interface{}, opts ...pulumi.ResourceOption) { + func(state map[string]interface{}, _ ...pulumi.ResourceOption) { if d.imagePullSecret == nil { return } diff --git a/components/datadog/operator/component.go b/components/datadog/operator/component.go index 89e46b904..f42aa196b 100644 --- a/components/datadog/operator/component.go +++ b/components/datadog/operator/component.go @@ -7,7 +7,7 @@ import ( "github.com/DataDog/test-infra-definitions/components" ) -// OperatorOutput is used to import the Operator component +// OperatorOutput is used to import the Operator component // nolint:revive, We want to keep the name as Output type OperatorOutput struct { components.JSONImporter diff --git a/components/datadog/operatorparams/params.go b/components/datadog/operatorparams/params.go index 24606eb2d..79cbf6c1c 100644 --- a/components/datadog/operatorparams/params.go +++ b/components/datadog/operatorparams/params.go @@ -24,7 +24,9 @@ type Params struct { type Option = func(*Params) error func NewParams(e config.Env, options ...Option) (*Params, error) { - version := &Params{} + version := &Params{ + Namespace: "datadog", + } if e.PipelineID() != "" && e.CommitSHA() != "" { options = append(options, WithOperatorFullImagePath(utils.BuildDockerImagePath(fmt.Sprintf("%s/operator", e.InternalRegistry()), fmt.Sprintf("%s-%s", e.PipelineID(), e.CommitSHA())))) diff --git a/scenarios/aws/kindvm/run.go b/scenarios/aws/kindvm/run.go index 483312926..af84dc8bb 100644 --- a/scenarios/aws/kindvm/run.go +++ b/scenarios/aws/kindvm/run.go @@ -15,6 +15,7 @@ import ( dogstatsdstandalone "github.com/DataDog/test-infra-definitions/components/datadog/dogstatsd-standalone" fakeintakeComp "github.com/DataDog/test-infra-definitions/components/datadog/fakeintake" "github.com/DataDog/test-infra-definitions/components/datadog/kubernetesagentparams" + "github.com/DataDog/test-infra-definitions/components/datadog/operator" "github.com/DataDog/test-infra-definitions/components/datadog/operatorparams" localKubernetes "github.com/DataDog/test-infra-definitions/components/kubernetes" @@ -132,6 +133,15 @@ agents: operatorparams.WithNamespace("datadog"), ) + operatorComp, err := operator.NewOperator(&awsEnv, awsEnv.CommonNamer().ResourceName("dd-operator"), kindKubeProvider, operatorOpts...) + if err != nil { + return err + } + + if err := operatorComp.Export(awsEnv.Ctx(), nil); err != nil { + return err + } + ddaOptions := make([]agentwithoperatorparams.Option, 0) ddaOptions = append( ddaOptions, From 156e590965074c2093b432600c3a7b6c00acba15 Mon Sep 17 00:00:00 2001 From: Fanny Jiang Date: Mon, 9 Dec 2024 18:45:07 -0500 Subject: [PATCH 11/11] fix linter --- components/datadog/operator/component.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/datadog/operator/component.go b/components/datadog/operator/component.go index f42aa196b..93975be46 100644 --- a/components/datadog/operator/component.go +++ b/components/datadog/operator/component.go @@ -7,8 +7,8 @@ import ( "github.com/DataDog/test-infra-definitions/components" ) -// OperatorOutput is used to import the Operator component // nolint:revive, We want to keep the name as Output -type OperatorOutput struct { +// OperatorOutput is used to import the Operator component +type OperatorOutput struct { // nolint:revive, We want to keep the name as Output components.JSONImporter Operator compkubernetes.KubernetesObjRefOutput `pulumi:"operator"`