Skip to content
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
7 changes: 7 additions & 0 deletions internal/controller/datadogagent/component_clusteragent.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ func (c *ClusterAgentComponent) Reconcile(ctx context.Context, params *Reconcile
deployment.Labels[constants.MD5AgentDeploymentProviderLabelKey] = params.Provider
}

// Apply MD5 hashes for ConfigMaps
cmAnnotations := params.ResourceManagers.Store().GetComponentAnnotations(c.Name())
for key, value := range cmAnnotations {
podManagers.Annotation().AddAnnotation(key, value)

}

return c.reconciler.createOrUpdateDeployment(params.Logger, params.DDA, deployment, params.Status, updateStatusV2WithClusterAgent)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ func (c *ClusterChecksRunnerComponent) Reconcile(ctx context.Context, params *Re
override.Deployment(deployment, componentOverride)
}

// Apply MD5 hashes for ConfigMaps
cmAnnotations := params.ResourceManagers.Store().GetComponentAnnotations(c.Name())
for key, value := range cmAnnotations {
podManagers.Annotation().AddAnnotation(key, value)
}

return c.reconciler.createOrUpdateDeployment(params.Logger, params.DDA, deployment, params.Status, updateStatusV2WithClusterChecksRunner)
}

Expand Down
12 changes: 12 additions & 0 deletions internal/controller/datadogagent/controller_reconcile_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ func (r *Reconciler) reconcileV2Agent(logger logr.Logger, requiredComponents fea
return reconcile.Result{}, nil
}

// Apply MD5 hashes for ConfigMaps
cmAnnotations := resourcesManager.Store().GetComponentAnnotations(datadoghqv2alpha1.NodeAgentComponentName)
for key, value := range cmAnnotations {
podManagers.Annotation().AddAnnotation(key, value)
}

return r.createOrUpdateExtendedDaemonset(daemonsetLogger, dda, eds, newStatus, updateEDSStatusV2WithAgent)
}

Expand Down Expand Up @@ -236,6 +242,12 @@ func (r *Reconciler) reconcileV2Agent(logger logr.Logger, requiredComponents fea
return reconcile.Result{}, nil
}

// Apply MD5 hashes for ConfigMaps
cmAnnotations := resourcesManager.Store().GetComponentAnnotations(datadoghqv2alpha1.NodeAgentComponentName)
for key, value := range cmAnnotations {
podManagers.Annotation().AddAnnotation(key, value)
}

return r.createOrUpdateDaemonset(daemonsetLogger, dda, daemonset, newStatus, updateDSStatusV2WithAgent, profile)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,32 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/DataDog/datadog-operator/api/datadoghq/v2alpha1"
"github.com/DataDog/datadog-operator/internal/controller/datadogagent/object/configmap"
"github.com/DataDog/datadog-operator/pkg/constants"
)

func (f *ksmFeature) buildKSMCoreConfigMap(collectorOpts collectorOptions) (*corev1.ConfigMap, error) {
if f.customConfig != nil && f.customConfig.ConfigMap != nil {
return nil, nil
}

var configMap *corev1.ConfigMap
if f.customConfig != nil && f.customConfig.ConfigData != nil {
return configmap.BuildConfigMapConfigData(f.owner.GetNamespace(), f.customConfig.ConfigData, f.configConfigMapName, ksmCoreCheckName)
var err error
configMap, err = configmap.BuildConfigMapConfigData(f.owner.GetNamespace(), f.customConfig.ConfigData, f.configConfigMapName, ksmCoreCheckName)
if err != nil {
return nil, err
}
} else {
configMap = buildDefaultConfigMap(f.owner.GetNamespace(), f.configConfigMapName, ksmCheckConfig(f.runInClusterChecksRunner, collectorOpts))
}

configMap.Labels = map[string]string{
constants.ConfigIDLabelKey: string(f.ID()),
constants.GetOperatorComponentLabelKey(v2alpha1.ClusterAgentComponentName): "true",
}

configMap := buildDefaultConfigMap(f.owner.GetNamespace(), f.configConfigMapName, ksmCheckConfig(f.runInClusterChecksRunner, collectorOpts))
return configMap, nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,35 @@ import (
"testing"

"github.com/DataDog/datadog-operator/api/datadoghq/v2alpha1"
"github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature"
"github.com/DataDog/datadog-operator/pkg/constants"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// buildExpectedConfigMap creates the expected ConfigMap for testing
func buildExpectedConfigMap(namespace, name string, opts collectorOptions, runInClusterChecksRunner bool, customContent string) *corev1.ConfigMap {
content := customContent
if content == "" {
content = ksmCheckConfig(runInClusterChecksRunner, opts)
}

return &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: map[string]string{
constants.ConfigIDLabelKey: string(feature.KubernetesStateCoreIDType),
constants.GetOperatorComponentLabelKey(v2alpha1.ClusterAgentComponentName): "true",
},
},
Data: map[string]string{
ksmCoreCheckName: content,
},
}
}

func Test_ksmFeature_buildKSMCoreConfigMap(t *testing.T) {
owner := &metav1.ObjectMeta{
Name: "test",
Expand Down Expand Up @@ -102,7 +126,7 @@ instances:
runInClusterChecksRunner: true,
configConfigMapName: defaultKubeStateMetricsCoreConf,
},
want: buildDefaultConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, ksmCheckConfig(true, defaultOptions)),
want: buildExpectedConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, defaultOptions, true, ""),
},
{
name: "override",
Expand All @@ -115,7 +139,7 @@ instances:
ConfigData: &overrideConf,
},
},
want: buildDefaultConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, overrideConf),
want: buildExpectedConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, collectorOptions{}, true, overrideConf),
},
{
name: "no cluster check runners",
Expand All @@ -125,7 +149,7 @@ instances:
runInClusterChecksRunner: false,
configConfigMapName: defaultKubeStateMetricsCoreConf,
},
want: buildDefaultConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, ksmCheckConfig(false, defaultOptions)),
want: buildExpectedConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, defaultOptions, false, ""),
},
{
name: "with vpa",
Expand All @@ -136,7 +160,7 @@ instances:
configConfigMapName: defaultKubeStateMetricsCoreConf,
collectorOpts: optionsWithVPA,
},
want: buildDefaultConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, ksmCheckConfig(true, optionsWithVPA)),
want: buildExpectedConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, optionsWithVPA, true, ""),
},
{
name: "with CRDs",
Expand All @@ -147,7 +171,7 @@ instances:
configConfigMapName: defaultKubeStateMetricsCoreConf,
collectorOpts: optionsWithCRD,
},
want: buildDefaultConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, ksmCheckConfig(true, optionsWithCRD)),
want: buildExpectedConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, optionsWithCRD, true, ""),
},
{
name: "with APIServices",
Expand All @@ -158,7 +182,7 @@ instances:
configConfigMapName: defaultKubeStateMetricsCoreConf,
collectorOpts: optionsWithAPIService,
},
want: buildDefaultConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, ksmCheckConfig(true, optionsWithAPIService)),
want: buildExpectedConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, optionsWithAPIService, true, ""),
},
{
name: "with ControllerRevisions",
Expand All @@ -169,7 +193,7 @@ instances:
configConfigMapName: defaultKubeStateMetricsCoreConf,
collectorOpts: optionsWithControllerRevisions,
},
want: buildDefaultConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, ksmCheckConfig(true, optionsWithControllerRevisions)),
want: buildExpectedConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, optionsWithControllerRevisions, true, ""),
},
{
name: "with custom resources",
Expand All @@ -180,7 +204,7 @@ instances:
configConfigMapName: defaultKubeStateMetricsCoreConf,
collectorOpts: optionsWithCustomResources,
},
want: buildDefaultConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, ksmCheckConfig(true, optionsWithCustomResources)),
want: buildExpectedConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, optionsWithCustomResources, true, ""),
},
{
name: "with multiple custom resources",
Expand All @@ -191,7 +215,7 @@ instances:
configConfigMapName: defaultKubeStateMetricsCoreConf,
collectorOpts: optionsWithMultipleCustomResources,
},
want: buildDefaultConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, ksmCheckConfig(true, optionsWithMultipleCustomResources)),
want: buildExpectedConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, optionsWithMultipleCustomResources, true, ""),
},
{
name: "with VPA and custom resources",
Expand All @@ -202,7 +226,7 @@ instances:
configConfigMapName: defaultKubeStateMetricsCoreConf,
collectorOpts: optionsWithVPAAndCustomResources,
},
want: buildDefaultConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, ksmCheckConfig(true, optionsWithVPAAndCustomResources)),
want: buildExpectedConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, optionsWithVPAAndCustomResources, true, ""),
},
{
name: "with custom resources and no cluster check",
Expand All @@ -213,7 +237,7 @@ instances:
configConfigMapName: defaultKubeStateMetricsCoreConf,
collectorOpts: optionsWithCustomResources,
},
want: buildDefaultConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, ksmCheckConfig(false, optionsWithCustomResources)),
want: buildExpectedConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, optionsWithCustomResources, false, ""),
},
}
for _, tt := range tests {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ import (
"github.com/DataDog/datadog-operator/internal/controller/datadogagent/common"
"github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature"
"github.com/DataDog/datadog-operator/internal/controller/datadogagent/merger"
"github.com/DataDog/datadog-operator/internal/controller/datadogagent/object"
"github.com/DataDog/datadog-operator/internal/controller/datadogagent/object/volume"
"github.com/DataDog/datadog-operator/pkg/constants"
"github.com/DataDog/datadog-operator/pkg/controller/utils/comparison"
"github.com/DataDog/datadog-operator/pkg/kubernetes"
"github.com/DataDog/datadog-operator/pkg/utils"
)
Expand Down Expand Up @@ -145,30 +143,6 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent

if ddaSpec.Features.KubeStateMetricsCore.Conf != nil {
f.customConfig = ddaSpec.Features.KubeStateMetricsCore.Conf
hash, err := comparison.GenerateMD5ForSpec(f.customConfig)
if err != nil {
f.logger.Error(err, "couldn't generate hash for ksm core custom config")
} else {
f.logger.V(2).Info("built ksm core from custom config", "hash", hash)
}
f.customConfigAnnotationValue = hash
f.customConfigAnnotationKey = object.GetChecksumAnnotationKey(feature.KubernetesStateCoreIDType)
} else {
// Generate dynamic checksum for default configuration (based on user provided collectCrMetrics field and whether or not APIServices/CRD metrics are collected)
defaultConfigData := map[string]any{
"collect_crds": f.collectCRDMetrics,
"collect_apiservices": f.collectAPIServiceMetrics,
"collect_cr_metrics": f.collectCrMetrics,
}

hash, err := comparison.GenerateMD5ForSpec(defaultConfigData)
if err != nil {
f.logger.Error(err, "couldn't generate hash for default ksm core config")
} else {
f.logger.V(2).Info("generated default ksm core config hash", "hash", hash, "config", defaultConfigData)
}
f.customConfigAnnotationValue = hash
f.customConfigAnnotationKey = object.GetChecksumAnnotationKey(feature.KubernetesStateCoreIDType)
}

f.configConfigMapName = constants.GetConfName(dda, f.customConfig, defaultKubeStateMetricsCoreConf)
Expand Down Expand Up @@ -203,11 +177,6 @@ func (f *ksmFeature) ManageDependencies(managers feature.ResourceManagers, provi
return err
}
if configCM != nil {
// Add md5 hash annotation for custom config
if f.customConfigAnnotationKey != "" && f.customConfigAnnotationValue != "" {
annotations := object.MergeAnnotationsLabels(f.logger, configCM.GetAnnotations(), map[string]string{f.customConfigAnnotationKey: f.customConfigAnnotationValue}, "*")
configCM.SetAnnotations(annotations)
}
if err := managers.Store().AddOrUpdate(kubernetes.ConfigMapKind, configCM); err != nil {
return err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,14 @@
package kubernetesstatecore

import (
"fmt"
"testing"

apicommon "github.com/DataDog/datadog-operator/api/datadoghq/common"
"github.com/DataDog/datadog-operator/api/datadoghq/v2alpha1"
apiutils "github.com/DataDog/datadog-operator/api/utils"
"github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature"
"github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/fake"
"github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/test"
mergerfake "github.com/DataDog/datadog-operator/internal/controller/datadogagent/merger/fake"
"github.com/DataDog/datadog-operator/pkg/constants"
"github.com/DataDog/datadog-operator/pkg/controller/utils/comparison"
"github.com/DataDog/datadog-operator/pkg/testutils"

"github.com/google/go-cmp/cmp"
Expand Down Expand Up @@ -139,7 +135,7 @@ func Test_ksmFeature_Configure(t *testing.T) {
tests.Run(t, buildKSMFeature)
}

func ksmClusterAgentWantFunc(hasCustomConfig bool) *test.ComponentTest {
func ksmClusterAgentWantFunc(useClusterChecksRunner bool) *test.ComponentTest {
return test.NewDefaultComponentTest().WithWantFunc(
func(t testing.TB, mgrInterface feature.PodTemplateManagers) {
mgr := mgrInterface.(*fake.PodTemplateManagers)
Expand All @@ -156,33 +152,6 @@ func ksmClusterAgentWantFunc(hasCustomConfig bool) *test.ComponentTest {
},
}
assert.True(t, apiutils.IsEqualStruct(dcaEnvVars, want), "DCA envvars \ndiff = %s", cmp.Diff(dcaEnvVars, want))

if hasCustomConfig {
customConfig := v2alpha1.CustomConfig{
ConfigData: apiutils.NewStringPointer(customData),
}
hash, err := comparison.GenerateMD5ForSpec(&customConfig)
assert.NoError(t, err)
wantAnnotations := map[string]string{
fmt.Sprintf(constants.MD5ChecksumAnnotationKey, feature.KubernetesStateCoreIDType): hash,
}
annotations := mgr.AnnotationMgr.Annotations
assert.True(t, apiutils.IsEqualStruct(annotations, wantAnnotations), "Annotations \ndiff = %s", cmp.Diff(annotations, wantAnnotations))
} else {
// Verify default config annotation - CRDs and APIServices collected, no custom resource metrics
defaultConfigData := map[string]any{
"collect_crds": true,
"collect_apiservices": true,
"collect_cr_metrics": nil,
}
hash, err := comparison.GenerateMD5ForSpec(defaultConfigData)
assert.NoError(t, err)
wantAnnotations := map[string]string{
fmt.Sprintf(constants.MD5ChecksumAnnotationKey, feature.KubernetesStateCoreIDType): hash,
}
annotations := mgr.AnnotationMgr.Annotations
assert.True(t, apiutils.IsEqualStruct(annotations, wantAnnotations), "Default config annotations \ndiff = %s", cmp.Diff(annotations, wantAnnotations))
}
},
)
}
Expand Down
Loading
Loading