From d502386d7bda3c9fd36810ada0ae6da970dc8a76 Mon Sep 17 00:00:00 2001 From: Frank Spano Date: Fri, 17 Oct 2025 12:53:33 -0400 Subject: [PATCH 1/7] add controllerrevisions collection for agents > 7.72.x --- api/datadoghq/v2alpha1/datadogagent_types.go | 6 ++ .../v2alpha1/zz_generated.deepcopy.go | 5 ++ .../v2alpha1/zz_generated.openapi.go | 7 ++ .../datadoghq.com_datadogagentinternals.yaml | 12 +++ ...hq.com_datadogagentinternals_v1alpha1.json | 8 ++ .../datadoghq.com_datadogagentprofiles.yaml | 6 ++ ...ghq.com_datadogagentprofiles_v1alpha1.json | 4 + .../bases/v1/datadoghq.com_datadogagents.yaml | 12 +++ .../datadoghq.com_datadogagents_v2alpha1.json | 8 ++ config/rbac/role.yaml | 7 ++ docs/configuration.v2alpha1.md | 3 +- .../feature/kubernetesstatecore/configmap.go | 4 + .../kubernetesstatecore/configmap_test.go | 12 +++ .../feature/kubernetesstatecore/feature.go | 90 ++++++++++++++----- .../feature/kubernetesstatecore/rbac.go | 1 + .../feature/kubernetesstatecore/rbac_test.go | 1 - .../controller/datadogagent_controller.go | 1 + pkg/kubernetes/rbac/const.go | 1 + 18 files changed, 165 insertions(+), 23 deletions(-) diff --git a/api/datadoghq/v2alpha1/datadogagent_types.go b/api/datadoghq/v2alpha1/datadogagent_types.go index 47cf307f47..594ffe6a5b 100644 --- a/api/datadoghq/v2alpha1/datadogagent_types.go +++ b/api/datadoghq/v2alpha1/datadogagent_types.go @@ -833,6 +833,12 @@ type KubeStateMetricsCoreFeatureConfig struct { // +optional // +listType=atomic CollectCrMetrics []Resource `json:"collectCrMetrics,omitempty"` + + // CollectControllerRevisions enables collection of ControllerRevision metrics. + // This requires agent version 7.72.0 or later. + // Default: false + // +optional + CollectControllerRevisions *bool `json:"collectControllerRevisions,omitempty"` } // Resource configures a custom resource for metric generation. diff --git a/api/datadoghq/v2alpha1/zz_generated.deepcopy.go b/api/datadoghq/v2alpha1/zz_generated.deepcopy.go index cba8e60dcb..e4510f41eb 100644 --- a/api/datadoghq/v2alpha1/zz_generated.deepcopy.go +++ b/api/datadoghq/v2alpha1/zz_generated.deepcopy.go @@ -2009,6 +2009,11 @@ func (in *KubeStateMetricsCoreFeatureConfig) DeepCopyInto(out *KubeStateMetricsC (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.CollectControllerRevisions != nil { + in, out := &in.CollectControllerRevisions, &out.CollectControllerRevisions + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeStateMetricsCoreFeatureConfig. diff --git a/api/datadoghq/v2alpha1/zz_generated.openapi.go b/api/datadoghq/v2alpha1/zz_generated.openapi.go index 4183ebb5c1..9f00e6c8bd 100644 --- a/api/datadoghq/v2alpha1/zz_generated.openapi.go +++ b/api/datadoghq/v2alpha1/zz_generated.openapi.go @@ -1153,6 +1153,13 @@ func schema_datadog_operator_api_datadoghq_v2alpha1_KubeStateMetricsCoreFeatureC }, }, }, + "collectControllerRevisions": { + SchemaProps: spec.SchemaProps{ + Description: "CollectControllerRevisions enables collection of ControllerRevision metrics. This requires agent version 7.72.0 or later. Default: false", + Type: []string{"boolean"}, + Format: "", + }, + }, }, }, }, diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml b/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml index be8056e292..33074eecf2 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml @@ -1527,6 +1527,12 @@ spec: kubeStateMetricsCore: description: KubeStateMetricsCore check configuration. properties: + collectControllerRevisions: + description: |- + CollectControllerRevisions enables collection of ControllerRevision metrics. + This requires agent version 7.72.0 or later. + Default: false + type: boolean collectCrMetrics: description: |- `CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect. @@ -9311,6 +9317,12 @@ spec: kubeStateMetricsCore: description: KubeStateMetricsCore check configuration. properties: + collectControllerRevisions: + description: |- + CollectControllerRevisions enables collection of ControllerRevision metrics. + This requires agent version 7.72.0 or later. + Default: false + type: boolean collectCrMetrics: description: |- `CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect. diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json index 9174bef1a3..46be1c062c 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json @@ -1552,6 +1552,10 @@ "additionalProperties": false, "description": "KubeStateMetricsCore check configuration.", "properties": { + "collectControllerRevisions": { + "description": "CollectControllerRevisions enables collection of ControllerRevision metrics.\nThis requires agent version 7.72.0 or later.\nDefault: false", + "type": "boolean" + }, "collectCrMetrics": { "description": "`CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect.\n\nThe datadog agent uses the same logic as upstream `kube-state-metrics`. So is its configuration.\nThe exact structure and existing fields of each item in this list can be found in:\nhttps://github.com/kubernetes/kube-state-metrics/blob/main/docs/metrics/extend/customresourcestate-metrics.md", "items": { @@ -9157,6 +9161,10 @@ "additionalProperties": false, "description": "KubeStateMetricsCore check configuration.", "properties": { + "collectControllerRevisions": { + "description": "CollectControllerRevisions enables collection of ControllerRevision metrics.\nThis requires agent version 7.72.0 or later.\nDefault: false", + "type": "boolean" + }, "collectCrMetrics": { "description": "`CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect.\n\nThe datadog agent uses the same logic as upstream `kube-state-metrics`. So is its configuration.\nThe exact structure and existing fields of each item in this list can be found in:\nhttps://github.com/kubernetes/kube-state-metrics/blob/main/docs/metrics/extend/customresourcestate-metrics.md", "items": { diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml index 175ecec18c..483b9c8d33 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml @@ -1527,6 +1527,12 @@ spec: kubeStateMetricsCore: description: KubeStateMetricsCore check configuration. properties: + collectControllerRevisions: + description: |- + CollectControllerRevisions enables collection of ControllerRevision metrics. + This requires agent version 7.72.0 or later. + Default: false + type: boolean collectCrMetrics: description: |- `CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect. diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json index a073ef13dd..9656f7781b 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json @@ -1556,6 +1556,10 @@ "additionalProperties": false, "description": "KubeStateMetricsCore check configuration.", "properties": { + "collectControllerRevisions": { + "description": "CollectControllerRevisions enables collection of ControllerRevision metrics.\nThis requires agent version 7.72.0 or later.\nDefault: false", + "type": "boolean" + }, "collectCrMetrics": { "description": "`CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect.\n\nThe datadog agent uses the same logic as upstream `kube-state-metrics`. So is its configuration.\nThe exact structure and existing fields of each item in this list can be found in:\nhttps://github.com/kubernetes/kube-state-metrics/blob/main/docs/metrics/extend/customresourcestate-metrics.md", "items": { diff --git a/config/crd/bases/v1/datadoghq.com_datadogagents.yaml b/config/crd/bases/v1/datadoghq.com_datadogagents.yaml index 70bd152701..2162ab4709 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagents.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogagents.yaml @@ -1527,6 +1527,12 @@ spec: kubeStateMetricsCore: description: KubeStateMetricsCore check configuration. properties: + collectControllerRevisions: + description: |- + CollectControllerRevisions enables collection of ControllerRevision metrics. + This requires agent version 7.72.0 or later. + Default: false + type: boolean collectCrMetrics: description: |- `CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect. @@ -9361,6 +9367,12 @@ spec: kubeStateMetricsCore: description: KubeStateMetricsCore check configuration. properties: + collectControllerRevisions: + description: |- + CollectControllerRevisions enables collection of ControllerRevision metrics. + This requires agent version 7.72.0 or later. + Default: false + type: boolean collectCrMetrics: description: |- `CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect. diff --git a/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json index e768edabd3..989545ee56 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json @@ -1552,6 +1552,10 @@ "additionalProperties": false, "description": "KubeStateMetricsCore check configuration.", "properties": { + "collectControllerRevisions": { + "description": "CollectControllerRevisions enables collection of ControllerRevision metrics.\nThis requires agent version 7.72.0 or later.\nDefault: false", + "type": "boolean" + }, "collectCrMetrics": { "description": "`CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect.\n\nThe datadog agent uses the same logic as upstream `kube-state-metrics`. So is its configuration.\nThe exact structure and existing fields of each item in this list can be found in:\nhttps://github.com/kubernetes/kube-state-metrics/blob/main/docs/metrics/extend/customresourcestate-metrics.md", "items": { @@ -9222,6 +9226,10 @@ "additionalProperties": false, "description": "KubeStateMetricsCore check configuration.", "properties": { + "collectControllerRevisions": { + "description": "CollectControllerRevisions enables collection of ControllerRevision metrics.\nThis requires agent version 7.72.0 or later.\nDefault: false", + "type": "boolean" + }, "collectCrMetrics": { "description": "`CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect.\n\nThe datadog agent uses the same logic as upstream `kube-state-metrics`. So is its configuration.\nThe exact structure and existing fields of each item in this list can be found in:\nhttps://github.com/kubernetes/kube-state-metrics/blob/main/docs/metrics/extend/customresourcestate-metrics.md", "items": { diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 4cd488ee30..0a116a7193 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -100,6 +100,13 @@ rules: - deletecollection - list - watch +- apiGroups: + - apps + resources: + - controllerrevisions + verbs: + - list + - watch - apiGroups: - apps resources: diff --git a/docs/configuration.v2alpha1.md b/docs/configuration.v2alpha1.md index f337172ce3..2cc308d111 100644 --- a/docs/configuration.v2alpha1.md +++ b/docs/configuration.v2alpha1.md @@ -124,6 +124,7 @@ spec: | features.helmCheck.collectEvents | CollectEvents set to `true` enables event collection in the Helm check (Requires Agent 7.36.0+ and Cluster Agent 1.20.0+) Default: false | | features.helmCheck.enabled | Enables the Helm check. Default: false | | features.helmCheck.valuesAsTags | ValuesAsTags collects Helm values from a release and uses them as tags (Requires Agent and Cluster Agent 7.40.0+). Default: {} | +| features.kubeStateMetricsCore.collectControllerRevisions | CollectControllerRevisions enables collection of ControllerRevision metrics. (Requires Agent and Cluster Agent 7.72.0+) Default: false | | features.kubeStateMetricsCore.collectCrMetrics | `CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect. The datadog agent uses the same logic as upstream `kube-state-metrics`. So is its configuration. The exact structure and existing fields of each item in this list can be found in: https://github.com/kubernetes/kube-state-metrics/blob/main/docs/metrics/extend/customresourcestate-metrics.md | | features.kubeStateMetricsCore.conf.configData | ConfigData corresponds to the configuration file content. | | features.kubeStateMetricsCore.conf.configMap.items | Maps a ConfigMap data `key` to a file `path` mount. | @@ -274,7 +275,7 @@ spec: The table below lists parameters that can be used to override default or global settings. Maps and arrays have a type annotation in the table; properties that are configured as map values contain a `[key]` element which should be replaced by the actual map key. `override` itself is a map with the following possible keys: `nodeAgent`, `clusterAgent`, or `clusterChecksRunner`. Other keys can be added, but they do not have any effect. -For example, the manifest below can be used to override the node Agent image, tag, and the resource limits of the system probe container. +For example, the manifest below can be used to override the node Agent image, tag, and the resource limits of the system probe container. ```yaml apiVersion: datadoghq.com/v2alpha1 diff --git a/internal/controller/datadogagent/feature/kubernetesstatecore/configmap.go b/internal/controller/datadogagent/feature/kubernetesstatecore/configmap.go index 763d5cede0..13d9e5b2a5 100644 --- a/internal/controller/datadogagent/feature/kubernetesstatecore/configmap.go +++ b/internal/controller/datadogagent/feature/kubernetesstatecore/configmap.go @@ -92,6 +92,10 @@ instances: config.WriteString(" - apiservices\n") } + if collectorOpts.enableControllerRevisions { + config.WriteString(" - controllerrevisions\n") + } + if collectorOpts.enableCRD { config.WriteString(" - customresourcedefinitions\n") } diff --git a/internal/controller/datadogagent/feature/kubernetesstatecore/configmap_test.go b/internal/controller/datadogagent/feature/kubernetesstatecore/configmap_test.go index 6aaebcf594..244167aabe 100644 --- a/internal/controller/datadogagent/feature/kubernetesstatecore/configmap_test.go +++ b/internal/controller/datadogagent/feature/kubernetesstatecore/configmap_test.go @@ -30,6 +30,7 @@ instances: optionsWithVPA := collectorOptions{enableVPA: true} optionsWithCRD := collectorOptions{enableCRD: true} optionsWithAPIService := collectorOptions{enableAPIService: true} + optionsWithControllerRevisions := collectorOptions{enableControllerRevisions: true} // Test custom resources optionsWithCustomResources := collectorOptions{ @@ -159,6 +160,17 @@ instances: }, want: buildDefaultConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, ksmCheckConfig(true, optionsWithAPIService)), }, + { + name: "with ControllerRevisions", + fields: fields{ + owner: owner, + enable: true, + runInClusterChecksRunner: true, + configConfigMapName: defaultKubeStateMetricsCoreConf, + collectorOpts: optionsWithControllerRevisions, + }, + want: buildDefaultConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, ksmCheckConfig(true, optionsWithControllerRevisions)), + }, { name: "with custom resources", fields: fields{ diff --git a/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go b/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go index b7be93094b..314395bfeb 100644 --- a/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go +++ b/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go @@ -46,10 +46,11 @@ func buildKSMFeature(options *feature.Options) feature.Feature { } type ksmFeature struct { - runInClusterChecksRunner bool - collectCRDMetrics bool - collectCrMetrics []v2alpha1.Resource - collectAPIServiceMetrics bool + runInClusterChecksRunner bool + collectCRDMetrics bool + collectCrMetrics []v2alpha1.Resource + collectAPIServiceMetrics bool + collectControllerRevisions bool rbacSuffix string serviceAccountName string @@ -67,6 +68,9 @@ type ksmFeature struct { // Add "-0" so that prerelase versions are considered sufficient. https://github.com/Masterminds/semver#working-with-prerelease-versions const crdAPIServiceCollectionMinVersion = "7.46.0-0" +// Minimum agent version that supports collection of controllerrevisions +const controllerRevisionsCollectionMinVersion = "7.72.0-0" + // ID returns the ID of the Feature func (f *ksmFeature) ID() feature.IDType { return feature.KubernetesStateCoreIDType @@ -78,6 +82,7 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent var output feature.RequiredComponents if ddaSpec.Features != nil && ddaSpec.Features.KubeStateMetricsCore != nil && apiutils.BoolValue(ddaSpec.Features.KubeStateMetricsCore.Enabled) { + f.logger.Info("KubeStateMetricsCore feature enabled") output.ClusterAgent.IsRequired = apiutils.NewBoolPointer(true) output.ClusterAgent.Containers = []apicommon.AgentContainerName{apicommon.ClusterAgentContainerName} output.Agent.IsRequired = apiutils.NewBoolPointer(true) @@ -88,6 +93,14 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent f.collectCrMetrics = ddaSpec.Features.KubeStateMetricsCore.CollectCrMetrics f.serviceAccountName = constants.GetClusterAgentServiceAccount(dda.GetName(), ddaSpec) + // Get the CollectControllerRevisions value from spec (default to false if not set) + collectControllerRevisionsExplicitlySet := ddaSpec.Features.KubeStateMetricsCore.CollectControllerRevisions != nil + if collectControllerRevisionsExplicitlySet { + f.collectControllerRevisions = apiutils.BoolValue(ddaSpec.Features.KubeStateMetricsCore.CollectControllerRevisions) + } else { + f.collectControllerRevisions = false + } + // This check will only run in the Cluster Checks Runners or Cluster Agent (not the Node Agent) if ddaSpec.Features.ClusterChecks != nil && apiutils.BoolValue(ddaSpec.Features.ClusterChecks.Enabled) && apiutils.BoolValue(ddaSpec.Features.ClusterChecks.UseClusterChecksRunners) { f.runInClusterChecksRunner = true @@ -97,17 +110,43 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent output.ClusterChecksRunner.Containers = []apicommon.AgentContainerName{apicommon.CoreAgentContainerName} if ccrOverride, ok := ddaSpec.Override[v2alpha1.ClusterChecksRunnerComponentName]; ok { - if ccrOverride.Image != nil && !utils.IsAboveMinVersion(common.GetAgentVersionFromImage(*ccrOverride.Image), crdAPIServiceCollectionMinVersion) { - // Disable if image is overridden to an unsupported version - f.collectAPIServiceMetrics = false - f.collectCRDMetrics = false + if ccrOverride.Image != nil { + agentVersion := common.GetAgentVersionFromImage(*ccrOverride.Image) + + if !utils.IsAboveMinVersion(agentVersion, crdAPIServiceCollectionMinVersion) { + f.collectAPIServiceMetrics = false + f.collectCRDMetrics = false + } + + // Only apply version check if CollectControllerRevisions was not explicitly set + if !collectControllerRevisionsExplicitlySet { + if utils.IsAboveMinVersion(agentVersion, controllerRevisionsCollectionMinVersion) { + f.collectControllerRevisions = true + } else { + f.collectControllerRevisions = false + } + } } } - } else if clusterAgentOverride, ok := ddaSpec.Override[v2alpha1.ClusterAgentComponentName]; ok { - if clusterAgentOverride.Image != nil && !utils.IsAboveMinVersion(common.GetAgentVersionFromImage(*clusterAgentOverride.Image), crdAPIServiceCollectionMinVersion) { - // Disable if image is overridden to an unsupported version - f.collectAPIServiceMetrics = false - f.collectCRDMetrics = false + } else { + if clusterAgentOverride, ok := ddaSpec.Override[v2alpha1.ClusterAgentComponentName]; ok { + if clusterAgentOverride.Image != nil { + agentVersion := common.GetAgentVersionFromImage(*clusterAgentOverride.Image) + + if !utils.IsAboveMinVersion(agentVersion, crdAPIServiceCollectionMinVersion) { + f.collectAPIServiceMetrics = false + f.collectCRDMetrics = false + } + + // Only apply version check if CollectControllerRevisions was not explicitly set + if !collectControllerRevisionsExplicitlySet { + if utils.IsAboveMinVersion(agentVersion, controllerRevisionsCollectionMinVersion) { + f.collectControllerRevisions = true + } else { + f.collectControllerRevisions = false + } + } + } } } @@ -124,16 +163,24 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent } f.configConfigMapName = constants.GetConfName(dda, f.customConfig, defaultKubeStateMetricsCoreConf) + + // Log final configuration state + f.logger.Info("KubeStateMetricsCore configuration finalized", + "collectAPIServiceMetrics", f.collectAPIServiceMetrics, + "collectCRDMetrics", f.collectCRDMetrics, + "collectControllerRevisions", f.collectControllerRevisions, + "runInClusterChecksRunner", f.runInClusterChecksRunner) } return output } type collectorOptions struct { - enableVPA bool - enableAPIService bool - enableCRD bool - customResources []v2alpha1.Resource + enableVPA bool + enableAPIService bool + enableCRD bool + enableControllerRevisions bool + customResources []v2alpha1.Resource } // ManageDependencies allows a feature to manage its dependencies. @@ -143,10 +190,11 @@ func (f *ksmFeature) ManageDependencies(managers feature.ResourceManagers, provi // OR if the default configMap is needed. pInfo := managers.Store().GetPlatformInfo() collectorOpts := collectorOptions{ - enableVPA: pInfo.IsResourceSupported("VerticalPodAutoscaler"), - enableAPIService: f.collectAPIServiceMetrics, - enableCRD: f.collectCRDMetrics, - customResources: f.collectCrMetrics, + enableVPA: pInfo.IsResourceSupported("VerticalPodAutoscaler"), + enableAPIService: f.collectAPIServiceMetrics, + enableCRD: f.collectCRDMetrics, + enableControllerRevisions: f.collectControllerRevisions, + customResources: f.collectCrMetrics, } configCM, err := f.buildKSMCoreConfigMap(collectorOpts) if err != nil { diff --git a/internal/controller/datadogagent/feature/kubernetesstatecore/rbac.go b/internal/controller/datadogagent/feature/kubernetesstatecore/rbac.go index eb81da78ef..80547ac0ac 100644 --- a/internal/controller/datadogagent/feature/kubernetesstatecore/rbac.go +++ b/internal/controller/datadogagent/feature/kubernetesstatecore/rbac.go @@ -45,6 +45,7 @@ func getRBACPolicyRules(collectorOpts collectorOptions) []rbacv1.PolicyRule { rbac.DeploymentsResource, rbac.ReplicasetsResource, rbac.StatefulsetsResource, + rbac.ControllerRevisionsResource, }, }, { diff --git a/internal/controller/datadogagent/feature/kubernetesstatecore/rbac_test.go b/internal/controller/datadogagent/feature/kubernetesstatecore/rbac_test.go index de8fd38d8b..98793de031 100644 --- a/internal/controller/datadogagent/feature/kubernetesstatecore/rbac_test.go +++ b/internal/controller/datadogagent/feature/kubernetesstatecore/rbac_test.go @@ -288,4 +288,3 @@ func TestGetRBACPolicyRules(t *testing.T) { }) } } - diff --git a/internal/controller/datadogagent_controller.go b/internal/controller/datadogagent_controller.go index 4cb85a22f1..c3f5522ad7 100644 --- a/internal/controller/datadogagent_controller.go +++ b/internal/controller/datadogagent_controller.go @@ -176,6 +176,7 @@ type DatadogAgentReconciler struct { // +kubebuilder:rbac:groups=apps,resources=replicasets,verbs=list;watch // +kubebuilder:rbac:groups="",resources=replicationcontrollers,verbs=get;list;watch // +kubebuilder:rbac:groups=apps,resources=statefulsets,verbs=list;watch +// +kubebuilder:rbac:groups=apps,resources=controllerrevisions,verbs=list;watch // +kubebuilder:rbac:groups=autoscaling,resources=horizontalpodautoscalers,verbs=list;watch // +kubebuilder:rbac:groups=batch,resources=cronjobs,verbs=list;watch // +kubebuilder:rbac:groups=batch,resources=jobs,verbs=list;watch diff --git a/pkg/kubernetes/rbac/const.go b/pkg/kubernetes/rbac/const.go index 331260ff3c..72499632fa 100644 --- a/pkg/kubernetes/rbac/const.go +++ b/pkg/kubernetes/rbac/const.go @@ -45,6 +45,7 @@ const ( ClusterRoleBindingResource = "clusterrolebindings" ClusterRoleResource = "clusterroles" ComponentStatusesResource = "componentstatuses" + ControllerRevisionsResource = "controllerrevisions" ConfigMapsResource = "configmaps" CronjobsResource = "cronjobs" CustomResourceDefinitionsResource = "customresourcedefinitions" From a9c052872aea763bbb9d549bf2d4b490912e4631 Mon Sep 17 00:00:00 2001 From: Frank Spano Date: Fri, 17 Oct 2025 13:23:49 -0400 Subject: [PATCH 2/7] add test coverage for controller revisions --- docs/configuration.v2alpha1.md | 4 +- .../kubernetesstatecore/feature_test.go | 66 +++++++++++++++++++ pkg/testutils/builder.go | 43 ++++++++++++ 3 files changed, 111 insertions(+), 2 deletions(-) diff --git a/docs/configuration.v2alpha1.md b/docs/configuration.v2alpha1.md index 2cc308d111..5be2673fd7 100644 --- a/docs/configuration.v2alpha1.md +++ b/docs/configuration.v2alpha1.md @@ -124,7 +124,7 @@ spec: | features.helmCheck.collectEvents | CollectEvents set to `true` enables event collection in the Helm check (Requires Agent 7.36.0+ and Cluster Agent 1.20.0+) Default: false | | features.helmCheck.enabled | Enables the Helm check. Default: false | | features.helmCheck.valuesAsTags | ValuesAsTags collects Helm values from a release and uses them as tags (Requires Agent and Cluster Agent 7.40.0+). Default: {} | -| features.kubeStateMetricsCore.collectControllerRevisions | CollectControllerRevisions enables collection of ControllerRevision metrics. (Requires Agent and Cluster Agent 7.72.0+) Default: false | +| features.kubeStateMetricsCore.collectControllerRevisions | CollectControllerRevisions enables collection of ControllerRevision metrics. This requires agent version 7.72.0 or later. Default: false | | features.kubeStateMetricsCore.collectCrMetrics | `CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect. The datadog agent uses the same logic as upstream `kube-state-metrics`. So is its configuration. The exact structure and existing fields of each item in this list can be found in: https://github.com/kubernetes/kube-state-metrics/blob/main/docs/metrics/extend/customresourcestate-metrics.md | | features.kubeStateMetricsCore.conf.configData | ConfigData corresponds to the configuration file content. | | features.kubeStateMetricsCore.conf.configMap.items | Maps a ConfigMap data `key` to a file `path` mount. | @@ -275,7 +275,7 @@ spec: The table below lists parameters that can be used to override default or global settings. Maps and arrays have a type annotation in the table; properties that are configured as map values contain a `[key]` element which should be replaced by the actual map key. `override` itself is a map with the following possible keys: `nodeAgent`, `clusterAgent`, or `clusterChecksRunner`. Other keys can be added, but they do not have any effect. -For example, the manifest below can be used to override the node Agent image, tag, and the resource limits of the system probe container. +For example, the manifest below can be used to override the node Agent image, tag, and the resource limits of the system probe container. ```yaml apiVersion: datadoghq.com/v2alpha1 diff --git a/internal/controller/datadogagent/feature/kubernetesstatecore/feature_test.go b/internal/controller/datadogagent/feature/kubernetesstatecore/feature_test.go index c3a67e1b50..a8908697c0 100644 --- a/internal/controller/datadogagent/feature/kubernetesstatecore/feature_test.go +++ b/internal/controller/datadogagent/feature/kubernetesstatecore/feature_test.go @@ -90,6 +90,72 @@ func Test_ksmFeature_Configure(t *testing.T) { ClusterAgent: ksmClusterAgentWantFunc(true), Agent: test.NewDefaultComponentTest().WithWantFunc(ksmAgentSingleAgentWantFunc), }, + { + Name: "ksm-core enabled, cluster agent with image >= 7.72.0", + DDA: testutils.NewDatadogAgentBuilder(). + WithKSMEnabled(true). + WithClusterAgentImage("gcr.io/datadoghq/agent:7.72.0"). + Build(), + WantConfigure: true, + ClusterAgent: ksmClusterAgentWantFunc(false), + Agent: test.NewDefaultComponentTest().WithWantFunc(ksmAgentNodeWantFunc), + }, + { + Name: "ksm-core enabled, cluster agent with image < 7.72.0", + DDA: testutils.NewDatadogAgentBuilder(). + WithKSMEnabled(true). + WithClusterAgentImage("gcr.io/datadoghq/agent:7.71.0"). + Build(), + WantConfigure: true, + ClusterAgent: ksmClusterAgentWantFunc(false), + Agent: test.NewDefaultComponentTest().WithWantFunc(ksmAgentNodeWantFunc), + }, + { + Name: "ksm-core enabled, cluster checks runner with image >= 7.72.0", + DDA: testutils.NewDatadogAgentBuilder(). + WithKSMEnabled(true). + WithClusterChecks(true, true). + WithClusterChecksRunnerImage("gcr.io/datadoghq/agent:7.72.0"). + Build(), + WantConfigure: true, + Agent: test.NewDefaultComponentTest().WithWantFunc(ksmAgentNodeWantFunc), + ClusterAgent: test.NewDefaultComponentTest().WithWantFunc(func(t testing.TB, mgrInterface feature.PodTemplateManagers) {}), + ClusterChecksRunner: test.NewDefaultComponentTest().WithWantFunc(func(t testing.TB, mgrInterface feature.PodTemplateManagers) {}), + }, + { + Name: "ksm-core enabled, cluster checks runner with image < 7.72.0", + DDA: testutils.NewDatadogAgentBuilder(). + WithKSMEnabled(true). + WithClusterChecks(true, true). + WithClusterChecksRunnerImage("gcr.io/datadoghq/agent:7.71.0"). + Build(), + WantConfigure: true, + Agent: test.NewDefaultComponentTest().WithWantFunc(ksmAgentNodeWantFunc), + ClusterAgent: test.NewDefaultComponentTest().WithWantFunc(func(t testing.TB, mgrInterface feature.PodTemplateManagers) {}), + ClusterChecksRunner: test.NewDefaultComponentTest().WithWantFunc(func(t testing.TB, mgrInterface feature.PodTemplateManagers) {}), + }, + { + Name: "ksm-core enabled, explicit collectControllerRevisions=true", + DDA: testutils.NewDatadogAgentBuilder(). + WithKSMEnabled(true). + WithClusterAgentImage("gcr.io/datadoghq/agent:7.71.0"). + WithKSMCollectControllerRevisions(true). + Build(), + WantConfigure: true, + ClusterAgent: ksmClusterAgentWantFunc(false), + Agent: test.NewDefaultComponentTest().WithWantFunc(ksmAgentNodeWantFunc), + }, + { + Name: "ksm-core enabled, explicit collectControllerRevisions=false", + DDA: testutils.NewDatadogAgentBuilder(). + WithKSMEnabled(true). + WithClusterAgentImage("gcr.io/datadoghq/agent:7.72.0"). + WithKSMCollectControllerRevisions(false). + Build(), + WantConfigure: true, + ClusterAgent: ksmClusterAgentWantFunc(false), + Agent: test.NewDefaultComponentTest().WithWantFunc(ksmAgentNodeWantFunc), + }, } tests.Run(t, buildKSMFeature) diff --git a/pkg/testutils/builder.go b/pkg/testutils/builder.go index b94ef7368e..834583a1e2 100644 --- a/pkg/testutils/builder.go +++ b/pkg/testutils/builder.go @@ -580,6 +580,12 @@ func (builder *DatadogAgentBuilder) WithKSMCustomConf(customData string) *Datado return builder } +func (builder *DatadogAgentBuilder) WithKSMCollectControllerRevisions(enabled bool) *DatadogAgentBuilder { + builder.initKSM() + builder.datadogAgent.Spec.Features.KubeStateMetricsCore.CollectControllerRevisions = apiutils.NewBoolPointer(enabled) + return builder +} + // Orchestrator Explorer func (builder *DatadogAgentBuilder) initOE() { @@ -646,6 +652,13 @@ func (builder *DatadogAgentBuilder) WithClusterChecksUseCLCEnabled(enabled bool) return builder } +func (builder *DatadogAgentBuilder) WithClusterChecks(enabled bool, useRunners bool) *DatadogAgentBuilder { + builder.initCC() + builder.datadogAgent.Spec.Features.ClusterChecks.Enabled = apiutils.NewBoolPointer(enabled) + builder.datadogAgent.Spec.Features.ClusterChecks.UseClusterChecksRunners = apiutils.NewBoolPointer(useRunners) + return builder +} + // Prometheus Scrape func (builder *DatadogAgentBuilder) initPrometheusScrape() { @@ -1045,6 +1058,36 @@ func (builder *DatadogAgentBuilder) WithComponentOverride(componentName v2alpha1 return builder } +func (builder *DatadogAgentBuilder) WithClusterAgentImage(image string) *DatadogAgentBuilder { + if builder.datadogAgent.Spec.Override == nil { + builder.datadogAgent.Spec.Override = map[v2alpha1.ComponentName]*v2alpha1.DatadogAgentComponentOverride{} + } + + if builder.datadogAgent.Spec.Override[v2alpha1.ClusterAgentComponentName] == nil { + builder.datadogAgent.Spec.Override[v2alpha1.ClusterAgentComponentName] = &v2alpha1.DatadogAgentComponentOverride{} + } + + builder.datadogAgent.Spec.Override[v2alpha1.ClusterAgentComponentName].Image = &v2alpha1.AgentImageConfig{ + Name: image, + } + return builder +} + +func (builder *DatadogAgentBuilder) WithClusterChecksRunnerImage(image string) *DatadogAgentBuilder { + if builder.datadogAgent.Spec.Override == nil { + builder.datadogAgent.Spec.Override = map[v2alpha1.ComponentName]*v2alpha1.DatadogAgentComponentOverride{} + } + + if builder.datadogAgent.Spec.Override[v2alpha1.ClusterChecksRunnerComponentName] == nil { + builder.datadogAgent.Spec.Override[v2alpha1.ClusterChecksRunnerComponentName] = &v2alpha1.DatadogAgentComponentOverride{} + } + + builder.datadogAgent.Spec.Override[v2alpha1.ClusterChecksRunnerComponentName].Image = &v2alpha1.AgentImageConfig{ + Name: image, + } + return builder +} + // FIPS func (builder *DatadogAgentBuilder) WithUseFIPSAgent() *DatadogAgentBuilder { From 2a3c448f778b111550433beba6b7d33e73bf815b Mon Sep 17 00:00:00 2001 From: Frank Spano Date: Mon, 20 Oct 2025 12:28:19 -0400 Subject: [PATCH 3/7] fix version check, expected to fail e2e if no image override is available and agent is >7.72 --- .../feature/kubernetesstatecore/feature.go | 41 ++++++++++----- pkg/utils/version.go | 50 +++++++++++++++++++ 2 files changed, 78 insertions(+), 13 deletions(-) diff --git a/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go b/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go index 314395bfeb..0e5439ab46 100644 --- a/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go +++ b/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go @@ -93,12 +93,16 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent f.collectCrMetrics = ddaSpec.Features.KubeStateMetricsCore.CollectCrMetrics f.serviceAccountName = constants.GetClusterAgentServiceAccount(dda.GetName(), ddaSpec) - // Get the CollectControllerRevisions value from spec (default to false if not set) + // Get the CollectControllerRevisions value from spec + // Default to false (opt-in), but can be auto-enabled by version check if agent >= 7.72.0 collectControllerRevisionsExplicitlySet := ddaSpec.Features.KubeStateMetricsCore.CollectControllerRevisions != nil if collectControllerRevisionsExplicitlySet { f.collectControllerRevisions = apiutils.BoolValue(ddaSpec.Features.KubeStateMetricsCore.CollectControllerRevisions) + f.logger.Info("CollectControllerRevisions set from spec", "value", f.collectControllerRevisions) } else { + // Default to false (will be auto-enabled by version check if agent supports it) f.collectControllerRevisions = false + f.logger.Info("CollectControllerRevisions not set in spec, defaulting to false (may be auto-enabled by version check)") } // This check will only run in the Cluster Checks Runners or Cluster Agent (not the Node Agent) @@ -112,39 +116,50 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent if ccrOverride, ok := ddaSpec.Override[v2alpha1.ClusterChecksRunnerComponentName]; ok { if ccrOverride.Image != nil { agentVersion := common.GetAgentVersionFromImage(*ccrOverride.Image) + f.logger.Info("ClusterChecksRunner image override detected", "image", *ccrOverride.Image, "version", agentVersion) if !utils.IsAboveMinVersion(agentVersion, crdAPIServiceCollectionMinVersion) { + f.logger.Info("Disabling CRD and APIService collection due to agent version", "version", agentVersion, "minVersion", crdAPIServiceCollectionMinVersion) f.collectAPIServiceMetrics = false f.collectCRDMetrics = false } - // Only apply version check if CollectControllerRevisions was not explicitly set - if !collectControllerRevisionsExplicitlySet { - if utils.IsAboveMinVersion(agentVersion, controllerRevisionsCollectionMinVersion) { - f.collectControllerRevisions = true - } else { - f.collectControllerRevisions = false + // Always enforce version check for controllerrevisions (safety guard) + if !utils.IsAboveMinVersionWithFallback(agentVersion, controllerRevisionsCollectionMinVersion) { + if f.collectControllerRevisions { + f.logger.Info("Disabling ControllerRevisions collection due to agent version (was explicitly enabled but version too old)", "version", agentVersion, "minVersion", controllerRevisionsCollectionMinVersion) } + f.collectControllerRevisions = false + } else if !collectControllerRevisionsExplicitlySet { + // Auto-enable for supported versions if not explicitly set + f.logger.Info("Auto-enabling ControllerRevisions collection based on agent version", "version", agentVersion, "minVersion", controllerRevisionsCollectionMinVersion) + f.collectControllerRevisions = true } } } } else { + f.logger.Info("Running in ClusterAgent mode") if clusterAgentOverride, ok := ddaSpec.Override[v2alpha1.ClusterAgentComponentName]; ok { if clusterAgentOverride.Image != nil { agentVersion := common.GetAgentVersionFromImage(*clusterAgentOverride.Image) + f.logger.Info("ClusterAgent image override detected", "image", *clusterAgentOverride.Image, "version", agentVersion) if !utils.IsAboveMinVersion(agentVersion, crdAPIServiceCollectionMinVersion) { + f.logger.Info("Disabling CRD and APIService collection due to agent version", "version", agentVersion, "minVersion", crdAPIServiceCollectionMinVersion) f.collectAPIServiceMetrics = false f.collectCRDMetrics = false } - // Only apply version check if CollectControllerRevisions was not explicitly set - if !collectControllerRevisionsExplicitlySet { - if utils.IsAboveMinVersion(agentVersion, controllerRevisionsCollectionMinVersion) { - f.collectControllerRevisions = true - } else { - f.collectControllerRevisions = false + // Always enforce version check for controllerrevisions (safety guard) + if !utils.IsAboveMinVersionWithFallback(agentVersion, controllerRevisionsCollectionMinVersion) { + if f.collectControllerRevisions { + f.logger.Info("Disabling ControllerRevisions collection due to agent version (was explicitly enabled but version too old)", "version", agentVersion, "minVersion", controllerRevisionsCollectionMinVersion) } + f.collectControllerRevisions = false + } else if !collectControllerRevisionsExplicitlySet { + // Auto-enable for supported versions if not explicitly set + f.logger.Info("Auto-enabling ControllerRevisions collection based on agent version", "version", agentVersion, "minVersion", controllerRevisionsCollectionMinVersion) + f.collectControllerRevisions = true } } } diff --git a/pkg/utils/version.go b/pkg/utils/version.go index dc053eb334..9c1cc42f81 100644 --- a/pkg/utils/version.go +++ b/pkg/utils/version.go @@ -14,6 +14,7 @@ import ( var versionRx = regexp.MustCompile(`(\d+\.\d+\.\d+)(\-[^\+]+)*(\+.+)*`) var versionWithDashesRx = regexp.MustCompile(`(\d+\-\d+\-\d+)(\-[^\+]+)*(\+.+)*`) +var majorMinorRx = regexp.MustCompile(`(\d+)\.(\d+)`) // IsAboveMinVersion uses semver to check if `version` is >= minVersion. // For versions not containing a semver, it will consider them above minVersion. @@ -34,6 +35,55 @@ func IsAboveMinVersion(version, minVersion string) bool { return c.Check(v) } +// IsAboveMinVersionWithFallback uses semver to check if `version` is >= minVersion. +// If semver parsing fails, it falls back to parsing major.minor versions only. +// For versions that can't be parsed at all, it returns false (conservative approach). +func IsAboveMinVersionWithFallback(version, minVersion string) bool { + version = formatVersionTag(version) + + // First, try standard semver parsing + v, err := semver.NewVersion(version) + if err == nil { + c, constraintErr := semver.NewConstraint(">= " + minVersion) + if constraintErr != nil { + return false + } + return c.Check(v) + } + + // Semver failed, try parsing just major.minor + // Extract major.minor from version string + matches := majorMinorRx.FindStringSubmatch(version) + if len(matches) < 3 { + // Can't parse version, return false (conservative) + return false + } + + versionMajorMinor := matches[1] + "." + matches[2] + ".0" + + // Parse minVersion to get its major.minor + minMatches := majorMinorRx.FindStringSubmatch(minVersion) + if len(minMatches) < 3 { + // Can't parse minVersion, return false + return false + } + + minVersionMajorMinor := minMatches[1] + "." + minMatches[2] + ".0" + + // Now compare using semver with the constructed x.y.0 versions + v, err = semver.NewVersion(versionMajorMinor) + if err != nil { + return false + } + + c, constraintErr := semver.NewConstraint(">= " + minVersionMajorMinor) + if constraintErr != nil { + return false + } + + return c.Check(v) +} + // formatVersionTag checks if the version tag uses dashes in lieu of periods, and replaces the first two dashes if so. func formatVersionTag(versionTag string) string { if versionWithDashesRx.FindString(versionTag) != "" { From 400cfed37cef40aa0f70339fe1ee87d47f129da4 Mon Sep 17 00:00:00 2001 From: Frank Spano Date: Mon, 20 Oct 2025 13:21:25 -0400 Subject: [PATCH 4/7] use default agent images if override not present --- .../feature/kubernetesstatecore/feature.go | 55 +++++++++++++++---- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go b/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go index 0e5439ab46..7b074c52d8 100644 --- a/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go +++ b/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go @@ -22,6 +22,7 @@ import ( "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/images" "github.com/DataDog/datadog-operator/pkg/kubernetes" "github.com/DataDog/datadog-operator/pkg/utils" ) @@ -93,16 +94,19 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent f.collectCrMetrics = ddaSpec.Features.KubeStateMetricsCore.CollectCrMetrics f.serviceAccountName = constants.GetClusterAgentServiceAccount(dda.GetName(), ddaSpec) - // Get the CollectControllerRevisions value from spec - // Default to false (opt-in), but can be auto-enabled by version check if agent >= 7.72.0 + // Determine CollectControllerRevisions setting + // Priority: 1) Explicit spec setting, 2) Image override version check, 3) Default image version check collectControllerRevisionsExplicitlySet := ddaSpec.Features.KubeStateMetricsCore.CollectControllerRevisions != nil + controllerRevisionsSetByOverride := false // Track if we determined the value via override + if collectControllerRevisionsExplicitlySet { + // Explicit setting in spec - use it (will be validated against version later if override present) f.collectControllerRevisions = apiutils.BoolValue(ddaSpec.Features.KubeStateMetricsCore.CollectControllerRevisions) - f.logger.Info("CollectControllerRevisions set from spec", "value", f.collectControllerRevisions) + f.logger.Info("CollectControllerRevisions explicitly set in spec", "value", f.collectControllerRevisions) } else { - // Default to false (will be auto-enabled by version check if agent supports it) + // Not explicitly set - will be determined by version checks below f.collectControllerRevisions = false - f.logger.Info("CollectControllerRevisions not set in spec, defaulting to false (may be auto-enabled by version check)") + f.logger.Info("CollectControllerRevisions not set in spec, will auto-enable if agent version supports it") } // This check will only run in the Cluster Checks Runners or Cluster Agent (not the Node Agent) @@ -118,23 +122,26 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent agentVersion := common.GetAgentVersionFromImage(*ccrOverride.Image) f.logger.Info("ClusterChecksRunner image override detected", "image", *ccrOverride.Image, "version", agentVersion) + // CRD and APIService version checks (existing logic - unchanged) if !utils.IsAboveMinVersion(agentVersion, crdAPIServiceCollectionMinVersion) { f.logger.Info("Disabling CRD and APIService collection due to agent version", "version", agentVersion, "minVersion", crdAPIServiceCollectionMinVersion) f.collectAPIServiceMetrics = false f.collectCRDMetrics = false } - // Always enforce version check for controllerrevisions (safety guard) + // ControllerRevisions version check with fallback parsing if !utils.IsAboveMinVersionWithFallback(agentVersion, controllerRevisionsCollectionMinVersion) { + // Version too old - disable even if explicitly set if f.collectControllerRevisions { f.logger.Info("Disabling ControllerRevisions collection due to agent version (was explicitly enabled but version too old)", "version", agentVersion, "minVersion", controllerRevisionsCollectionMinVersion) } f.collectControllerRevisions = false } else if !collectControllerRevisionsExplicitlySet { - // Auto-enable for supported versions if not explicitly set - f.logger.Info("Auto-enabling ControllerRevisions collection based on agent version", "version", agentVersion, "minVersion", controllerRevisionsCollectionMinVersion) + // Version supports it and not explicitly set - auto-enable + f.logger.Info("Auto-enabling ControllerRevisions collection based on override agent version", "version", agentVersion, "minVersion", controllerRevisionsCollectionMinVersion) f.collectControllerRevisions = true } + controllerRevisionsSetByOverride = true } } } else { @@ -144,27 +151,51 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent agentVersion := common.GetAgentVersionFromImage(*clusterAgentOverride.Image) f.logger.Info("ClusterAgent image override detected", "image", *clusterAgentOverride.Image, "version", agentVersion) + // CRD and APIService version checks (existing logic - unchanged) if !utils.IsAboveMinVersion(agentVersion, crdAPIServiceCollectionMinVersion) { f.logger.Info("Disabling CRD and APIService collection due to agent version", "version", agentVersion, "minVersion", crdAPIServiceCollectionMinVersion) f.collectAPIServiceMetrics = false f.collectCRDMetrics = false } - // Always enforce version check for controllerrevisions (safety guard) + // ControllerRevisions version check with fallback parsing if !utils.IsAboveMinVersionWithFallback(agentVersion, controllerRevisionsCollectionMinVersion) { + // Version too old - disable even if explicitly set if f.collectControllerRevisions { - f.logger.Info("Disabling ControllerRevisions collection due to agent version (was explicitly enabled but version too old)", "version", agentVersion, "minVersion", controllerRevisionsCollectionMinVersion) + f.logger.Info("Disabling ControllerRevisions collection due to cluster agent version (was explicitly enabled but version too old)", "version", agentVersion, "minVersion", controllerRevisionsCollectionMinVersion) } f.collectControllerRevisions = false } else if !collectControllerRevisionsExplicitlySet { - // Auto-enable for supported versions if not explicitly set - f.logger.Info("Auto-enabling ControllerRevisions collection based on agent version", "version", agentVersion, "minVersion", controllerRevisionsCollectionMinVersion) + // Version supports it and not explicitly set - auto-enable + f.logger.Info("Auto-enabling ControllerRevisions collection based on override cluster agent version", "version", agentVersion, "minVersion", controllerRevisionsCollectionMinVersion) f.collectControllerRevisions = true } + controllerRevisionsSetByOverride = true } } } + // If not explicitly set and not determined by image override, check default versions + if !collectControllerRevisionsExplicitlySet && !controllerRevisionsSetByOverride { + // Determine which default version to check based on deployment mode + var defaultVersion string + if f.runInClusterChecksRunner { + defaultVersion = images.AgentLatestVersion + f.logger.Info("No image override present, checking default agent version for ControllerRevisions support", "version", defaultVersion) + } else { + defaultVersion = images.ClusterAgentLatestVersion + f.logger.Info("No image override present, checking default cluster agent version for ControllerRevisions support", "version", defaultVersion) + } + + // Check if default version supports controllerrevisions + if utils.IsAboveMinVersionWithFallback(defaultVersion, controllerRevisionsCollectionMinVersion) { + f.logger.Info("Auto-enabling ControllerRevisions collection based on default version", "version", defaultVersion, "minVersion", controllerRevisionsCollectionMinVersion) + f.collectControllerRevisions = true + } else { + f.logger.Info("Default version does not support ControllerRevisions collection, keeping disabled", "version", defaultVersion, "minVersion", controllerRevisionsCollectionMinVersion) + } + } + if ddaSpec.Features.KubeStateMetricsCore.Conf != nil { f.customConfig = ddaSpec.Features.KubeStateMetricsCore.Conf hash, err := comparison.GenerateMD5ForSpec(f.customConfig) From 1f0a58129340fc4f645e319eea6fa6f57c08d7c6 Mon Sep 17 00:00:00 2001 From: Frank Spano Date: Tue, 21 Oct 2025 12:00:11 -0400 Subject: [PATCH 5/7] removes logging --- .../feature/kubernetesstatecore/feature.go | 25 ++----------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go b/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go index 7b074c52d8..1995a2c7e5 100644 --- a/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go +++ b/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go @@ -83,7 +83,6 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent var output feature.RequiredComponents if ddaSpec.Features != nil && ddaSpec.Features.KubeStateMetricsCore != nil && apiutils.BoolValue(ddaSpec.Features.KubeStateMetricsCore.Enabled) { - f.logger.Info("KubeStateMetricsCore feature enabled") output.ClusterAgent.IsRequired = apiutils.NewBoolPointer(true) output.ClusterAgent.Containers = []apicommon.AgentContainerName{apicommon.ClusterAgentContainerName} output.Agent.IsRequired = apiutils.NewBoolPointer(true) @@ -102,11 +101,9 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent if collectControllerRevisionsExplicitlySet { // Explicit setting in spec - use it (will be validated against version later if override present) f.collectControllerRevisions = apiutils.BoolValue(ddaSpec.Features.KubeStateMetricsCore.CollectControllerRevisions) - f.logger.Info("CollectControllerRevisions explicitly set in spec", "value", f.collectControllerRevisions) } else { // Not explicitly set - will be determined by version checks below f.collectControllerRevisions = false - f.logger.Info("CollectControllerRevisions not set in spec, will auto-enable if agent version supports it") } // This check will only run in the Cluster Checks Runners or Cluster Agent (not the Node Agent) @@ -120,11 +117,9 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent if ccrOverride, ok := ddaSpec.Override[v2alpha1.ClusterChecksRunnerComponentName]; ok { if ccrOverride.Image != nil { agentVersion := common.GetAgentVersionFromImage(*ccrOverride.Image) - f.logger.Info("ClusterChecksRunner image override detected", "image", *ccrOverride.Image, "version", agentVersion) - // CRD and APIService version checks (existing logic - unchanged) + // CRD and APIService version checks if !utils.IsAboveMinVersion(agentVersion, crdAPIServiceCollectionMinVersion) { - f.logger.Info("Disabling CRD and APIService collection due to agent version", "version", agentVersion, "minVersion", crdAPIServiceCollectionMinVersion) f.collectAPIServiceMetrics = false f.collectCRDMetrics = false } @@ -132,28 +127,21 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent // ControllerRevisions version check with fallback parsing if !utils.IsAboveMinVersionWithFallback(agentVersion, controllerRevisionsCollectionMinVersion) { // Version too old - disable even if explicitly set - if f.collectControllerRevisions { - f.logger.Info("Disabling ControllerRevisions collection due to agent version (was explicitly enabled but version too old)", "version", agentVersion, "minVersion", controllerRevisionsCollectionMinVersion) - } f.collectControllerRevisions = false } else if !collectControllerRevisionsExplicitlySet { // Version supports it and not explicitly set - auto-enable - f.logger.Info("Auto-enabling ControllerRevisions collection based on override agent version", "version", agentVersion, "minVersion", controllerRevisionsCollectionMinVersion) f.collectControllerRevisions = true } controllerRevisionsSetByOverride = true } } } else { - f.logger.Info("Running in ClusterAgent mode") if clusterAgentOverride, ok := ddaSpec.Override[v2alpha1.ClusterAgentComponentName]; ok { if clusterAgentOverride.Image != nil { agentVersion := common.GetAgentVersionFromImage(*clusterAgentOverride.Image) - f.logger.Info("ClusterAgent image override detected", "image", *clusterAgentOverride.Image, "version", agentVersion) - // CRD and APIService version checks (existing logic - unchanged) + // CRD and APIService version checks if !utils.IsAboveMinVersion(agentVersion, crdAPIServiceCollectionMinVersion) { - f.logger.Info("Disabling CRD and APIService collection due to agent version", "version", agentVersion, "minVersion", crdAPIServiceCollectionMinVersion) f.collectAPIServiceMetrics = false f.collectCRDMetrics = false } @@ -161,13 +149,9 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent // ControllerRevisions version check with fallback parsing if !utils.IsAboveMinVersionWithFallback(agentVersion, controllerRevisionsCollectionMinVersion) { // Version too old - disable even if explicitly set - if f.collectControllerRevisions { - f.logger.Info("Disabling ControllerRevisions collection due to cluster agent version (was explicitly enabled but version too old)", "version", agentVersion, "minVersion", controllerRevisionsCollectionMinVersion) - } f.collectControllerRevisions = false } else if !collectControllerRevisionsExplicitlySet { // Version supports it and not explicitly set - auto-enable - f.logger.Info("Auto-enabling ControllerRevisions collection based on override cluster agent version", "version", agentVersion, "minVersion", controllerRevisionsCollectionMinVersion) f.collectControllerRevisions = true } controllerRevisionsSetByOverride = true @@ -181,18 +165,13 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent var defaultVersion string if f.runInClusterChecksRunner { defaultVersion = images.AgentLatestVersion - f.logger.Info("No image override present, checking default agent version for ControllerRevisions support", "version", defaultVersion) } else { defaultVersion = images.ClusterAgentLatestVersion - f.logger.Info("No image override present, checking default cluster agent version for ControllerRevisions support", "version", defaultVersion) } // Check if default version supports controllerrevisions if utils.IsAboveMinVersionWithFallback(defaultVersion, controllerRevisionsCollectionMinVersion) { - f.logger.Info("Auto-enabling ControllerRevisions collection based on default version", "version", defaultVersion, "minVersion", controllerRevisionsCollectionMinVersion) f.collectControllerRevisions = true - } else { - f.logger.Info("Default version does not support ControllerRevisions collection, keeping disabled", "version", defaultVersion, "minVersion", controllerRevisionsCollectionMinVersion) } } From ef5903319dbf00bbfb19c89afa18f234ad1acc49 Mon Sep 17 00:00:00 2001 From: Frank Spano Date: Wed, 29 Oct 2025 10:40:49 -0400 Subject: [PATCH 6/7] Remove explicit controllerrevisions setting --- api/datadoghq/v2alpha1/datadogagent_types.go | 6 --- .../v2alpha1/zz_generated.deepcopy.go | 5 -- .../v2alpha1/zz_generated.openapi.go | 7 --- .../datadoghq.com_datadogagentinternals.yaml | 12 ----- ...hq.com_datadogagentinternals_v1alpha1.json | 8 ---- .../datadoghq.com_datadogagentprofiles.yaml | 6 --- ...ghq.com_datadogagentprofiles_v1alpha1.json | 4 -- .../bases/v1/datadoghq.com_datadogagents.yaml | 12 ----- .../datadoghq.com_datadogagents_v2alpha1.json | 8 ---- docs/configuration.v2alpha1.md | 1 - .../feature/kubernetesstatecore/feature.go | 47 ++++++------------- .../kubernetesstatecore/feature_test.go | 22 --------- pkg/testutils/builder.go | 6 --- 13 files changed, 15 insertions(+), 129 deletions(-) diff --git a/api/datadoghq/v2alpha1/datadogagent_types.go b/api/datadoghq/v2alpha1/datadogagent_types.go index 594ffe6a5b..47cf307f47 100644 --- a/api/datadoghq/v2alpha1/datadogagent_types.go +++ b/api/datadoghq/v2alpha1/datadogagent_types.go @@ -833,12 +833,6 @@ type KubeStateMetricsCoreFeatureConfig struct { // +optional // +listType=atomic CollectCrMetrics []Resource `json:"collectCrMetrics,omitempty"` - - // CollectControllerRevisions enables collection of ControllerRevision metrics. - // This requires agent version 7.72.0 or later. - // Default: false - // +optional - CollectControllerRevisions *bool `json:"collectControllerRevisions,omitempty"` } // Resource configures a custom resource for metric generation. diff --git a/api/datadoghq/v2alpha1/zz_generated.deepcopy.go b/api/datadoghq/v2alpha1/zz_generated.deepcopy.go index e4510f41eb..cba8e60dcb 100644 --- a/api/datadoghq/v2alpha1/zz_generated.deepcopy.go +++ b/api/datadoghq/v2alpha1/zz_generated.deepcopy.go @@ -2009,11 +2009,6 @@ func (in *KubeStateMetricsCoreFeatureConfig) DeepCopyInto(out *KubeStateMetricsC (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.CollectControllerRevisions != nil { - in, out := &in.CollectControllerRevisions, &out.CollectControllerRevisions - *out = new(bool) - **out = **in - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeStateMetricsCoreFeatureConfig. diff --git a/api/datadoghq/v2alpha1/zz_generated.openapi.go b/api/datadoghq/v2alpha1/zz_generated.openapi.go index 9f00e6c8bd..4183ebb5c1 100644 --- a/api/datadoghq/v2alpha1/zz_generated.openapi.go +++ b/api/datadoghq/v2alpha1/zz_generated.openapi.go @@ -1153,13 +1153,6 @@ func schema_datadog_operator_api_datadoghq_v2alpha1_KubeStateMetricsCoreFeatureC }, }, }, - "collectControllerRevisions": { - SchemaProps: spec.SchemaProps{ - Description: "CollectControllerRevisions enables collection of ControllerRevision metrics. This requires agent version 7.72.0 or later. Default: false", - Type: []string{"boolean"}, - Format: "", - }, - }, }, }, }, diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml b/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml index 33074eecf2..be8056e292 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml @@ -1527,12 +1527,6 @@ spec: kubeStateMetricsCore: description: KubeStateMetricsCore check configuration. properties: - collectControllerRevisions: - description: |- - CollectControllerRevisions enables collection of ControllerRevision metrics. - This requires agent version 7.72.0 or later. - Default: false - type: boolean collectCrMetrics: description: |- `CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect. @@ -9317,12 +9311,6 @@ spec: kubeStateMetricsCore: description: KubeStateMetricsCore check configuration. properties: - collectControllerRevisions: - description: |- - CollectControllerRevisions enables collection of ControllerRevision metrics. - This requires agent version 7.72.0 or later. - Default: false - type: boolean collectCrMetrics: description: |- `CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect. diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json index 46be1c062c..9174bef1a3 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json @@ -1552,10 +1552,6 @@ "additionalProperties": false, "description": "KubeStateMetricsCore check configuration.", "properties": { - "collectControllerRevisions": { - "description": "CollectControllerRevisions enables collection of ControllerRevision metrics.\nThis requires agent version 7.72.0 or later.\nDefault: false", - "type": "boolean" - }, "collectCrMetrics": { "description": "`CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect.\n\nThe datadog agent uses the same logic as upstream `kube-state-metrics`. So is its configuration.\nThe exact structure and existing fields of each item in this list can be found in:\nhttps://github.com/kubernetes/kube-state-metrics/blob/main/docs/metrics/extend/customresourcestate-metrics.md", "items": { @@ -9161,10 +9157,6 @@ "additionalProperties": false, "description": "KubeStateMetricsCore check configuration.", "properties": { - "collectControllerRevisions": { - "description": "CollectControllerRevisions enables collection of ControllerRevision metrics.\nThis requires agent version 7.72.0 or later.\nDefault: false", - "type": "boolean" - }, "collectCrMetrics": { "description": "`CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect.\n\nThe datadog agent uses the same logic as upstream `kube-state-metrics`. So is its configuration.\nThe exact structure and existing fields of each item in this list can be found in:\nhttps://github.com/kubernetes/kube-state-metrics/blob/main/docs/metrics/extend/customresourcestate-metrics.md", "items": { diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml index 483b9c8d33..175ecec18c 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml @@ -1527,12 +1527,6 @@ spec: kubeStateMetricsCore: description: KubeStateMetricsCore check configuration. properties: - collectControllerRevisions: - description: |- - CollectControllerRevisions enables collection of ControllerRevision metrics. - This requires agent version 7.72.0 or later. - Default: false - type: boolean collectCrMetrics: description: |- `CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect. diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json index 9656f7781b..a073ef13dd 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json @@ -1556,10 +1556,6 @@ "additionalProperties": false, "description": "KubeStateMetricsCore check configuration.", "properties": { - "collectControllerRevisions": { - "description": "CollectControllerRevisions enables collection of ControllerRevision metrics.\nThis requires agent version 7.72.0 or later.\nDefault: false", - "type": "boolean" - }, "collectCrMetrics": { "description": "`CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect.\n\nThe datadog agent uses the same logic as upstream `kube-state-metrics`. So is its configuration.\nThe exact structure and existing fields of each item in this list can be found in:\nhttps://github.com/kubernetes/kube-state-metrics/blob/main/docs/metrics/extend/customresourcestate-metrics.md", "items": { diff --git a/config/crd/bases/v1/datadoghq.com_datadogagents.yaml b/config/crd/bases/v1/datadoghq.com_datadogagents.yaml index 2162ab4709..70bd152701 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagents.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogagents.yaml @@ -1527,12 +1527,6 @@ spec: kubeStateMetricsCore: description: KubeStateMetricsCore check configuration. properties: - collectControllerRevisions: - description: |- - CollectControllerRevisions enables collection of ControllerRevision metrics. - This requires agent version 7.72.0 or later. - Default: false - type: boolean collectCrMetrics: description: |- `CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect. @@ -9367,12 +9361,6 @@ spec: kubeStateMetricsCore: description: KubeStateMetricsCore check configuration. properties: - collectControllerRevisions: - description: |- - CollectControllerRevisions enables collection of ControllerRevision metrics. - This requires agent version 7.72.0 or later. - Default: false - type: boolean collectCrMetrics: description: |- `CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect. diff --git a/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json index 989545ee56..e768edabd3 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json @@ -1552,10 +1552,6 @@ "additionalProperties": false, "description": "KubeStateMetricsCore check configuration.", "properties": { - "collectControllerRevisions": { - "description": "CollectControllerRevisions enables collection of ControllerRevision metrics.\nThis requires agent version 7.72.0 or later.\nDefault: false", - "type": "boolean" - }, "collectCrMetrics": { "description": "`CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect.\n\nThe datadog agent uses the same logic as upstream `kube-state-metrics`. So is its configuration.\nThe exact structure and existing fields of each item in this list can be found in:\nhttps://github.com/kubernetes/kube-state-metrics/blob/main/docs/metrics/extend/customresourcestate-metrics.md", "items": { @@ -9226,10 +9222,6 @@ "additionalProperties": false, "description": "KubeStateMetricsCore check configuration.", "properties": { - "collectControllerRevisions": { - "description": "CollectControllerRevisions enables collection of ControllerRevision metrics.\nThis requires agent version 7.72.0 or later.\nDefault: false", - "type": "boolean" - }, "collectCrMetrics": { "description": "`CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect.\n\nThe datadog agent uses the same logic as upstream `kube-state-metrics`. So is its configuration.\nThe exact structure and existing fields of each item in this list can be found in:\nhttps://github.com/kubernetes/kube-state-metrics/blob/main/docs/metrics/extend/customresourcestate-metrics.md", "items": { diff --git a/docs/configuration.v2alpha1.md b/docs/configuration.v2alpha1.md index 5be2673fd7..f337172ce3 100644 --- a/docs/configuration.v2alpha1.md +++ b/docs/configuration.v2alpha1.md @@ -124,7 +124,6 @@ spec: | features.helmCheck.collectEvents | CollectEvents set to `true` enables event collection in the Helm check (Requires Agent 7.36.0+ and Cluster Agent 1.20.0+) Default: false | | features.helmCheck.enabled | Enables the Helm check. Default: false | | features.helmCheck.valuesAsTags | ValuesAsTags collects Helm values from a release and uses them as tags (Requires Agent and Cluster Agent 7.40.0+). Default: {} | -| features.kubeStateMetricsCore.collectControllerRevisions | CollectControllerRevisions enables collection of ControllerRevision metrics. This requires agent version 7.72.0 or later. Default: false | | features.kubeStateMetricsCore.collectCrMetrics | `CollectCrMetrics` defines custom resources for the kube-state-metrics core check to collect. The datadog agent uses the same logic as upstream `kube-state-metrics`. So is its configuration. The exact structure and existing fields of each item in this list can be found in: https://github.com/kubernetes/kube-state-metrics/blob/main/docs/metrics/extend/customresourcestate-metrics.md | | features.kubeStateMetricsCore.conf.configData | ConfigData corresponds to the configuration file content. | | features.kubeStateMetricsCore.conf.configMap.items | Maps a ConfigMap data `key` to a file `path` mount. | diff --git a/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go b/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go index 1995a2c7e5..5668d2c8cc 100644 --- a/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go +++ b/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go @@ -65,12 +65,14 @@ type ksmFeature struct { logger logr.Logger } -// Minimum agent version that supports collection of CRD and APIService data -// Add "-0" so that prerelase versions are considered sufficient. https://github.com/Masterminds/semver#working-with-prerelease-versions -const crdAPIServiceCollectionMinVersion = "7.46.0-0" +const ( + // Minimum agent version that supports collection of CRD and APIService data + // Add "-0" so that prerelase versions are considered sufficient. https://github.com/Masterminds/semver#working-with-prerelease-versions + crdAPIServiceCollectionMinVersion = "7.46.0-0" -// Minimum agent version that supports collection of controllerrevisions -const controllerRevisionsCollectionMinVersion = "7.72.0-0" + // Minimum agent version that supports collection of controllerrevisions + controllerRevisionsCollectionMinVersion = "7.72.0-0" +) // ID returns the ID of the Feature func (f *ksmFeature) ID() feature.IDType { @@ -94,17 +96,8 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent f.serviceAccountName = constants.GetClusterAgentServiceAccount(dda.GetName(), ddaSpec) // Determine CollectControllerRevisions setting - // Priority: 1) Explicit spec setting, 2) Image override version check, 3) Default image version check - collectControllerRevisionsExplicitlySet := ddaSpec.Features.KubeStateMetricsCore.CollectControllerRevisions != nil - controllerRevisionsSetByOverride := false // Track if we determined the value via override - - if collectControllerRevisionsExplicitlySet { - // Explicit setting in spec - use it (will be validated against version later if override present) - f.collectControllerRevisions = apiutils.BoolValue(ddaSpec.Features.KubeStateMetricsCore.CollectControllerRevisions) - } else { - // Not explicitly set - will be determined by version checks below - f.collectControllerRevisions = false - } + // Default to false, then check version requirements + f.collectControllerRevisions = false // This check will only run in the Cluster Checks Runners or Cluster Agent (not the Node Agent) if ddaSpec.Features.ClusterChecks != nil && apiutils.BoolValue(ddaSpec.Features.ClusterChecks.Enabled) && apiutils.BoolValue(ddaSpec.Features.ClusterChecks.UseClusterChecksRunners) { @@ -124,15 +117,10 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent f.collectCRDMetrics = false } - // ControllerRevisions version check with fallback parsing - if !utils.IsAboveMinVersionWithFallback(agentVersion, controllerRevisionsCollectionMinVersion) { - // Version too old - disable even if explicitly set - f.collectControllerRevisions = false - } else if !collectControllerRevisionsExplicitlySet { - // Version supports it and not explicitly set - auto-enable + // ControllerRevisions version check - enable if version supports it + if utils.IsAboveMinVersionWithFallback(agentVersion, controllerRevisionsCollectionMinVersion) { f.collectControllerRevisions = true } - controllerRevisionsSetByOverride = true } } } else { @@ -146,21 +134,16 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent f.collectCRDMetrics = false } - // ControllerRevisions version check with fallback parsing - if !utils.IsAboveMinVersionWithFallback(agentVersion, controllerRevisionsCollectionMinVersion) { - // Version too old - disable even if explicitly set - f.collectControllerRevisions = false - } else if !collectControllerRevisionsExplicitlySet { - // Version supports it and not explicitly set - auto-enable + // ControllerRevisions version check - enable if version supports it + if utils.IsAboveMinVersionWithFallback(agentVersion, controllerRevisionsCollectionMinVersion) { f.collectControllerRevisions = true } - controllerRevisionsSetByOverride = true } } } - // If not explicitly set and not determined by image override, check default versions - if !collectControllerRevisionsExplicitlySet && !controllerRevisionsSetByOverride { + // If no override was found, check default version based on deployment mode + if !f.collectControllerRevisions { // Determine which default version to check based on deployment mode var defaultVersion string if f.runInClusterChecksRunner { diff --git a/internal/controller/datadogagent/feature/kubernetesstatecore/feature_test.go b/internal/controller/datadogagent/feature/kubernetesstatecore/feature_test.go index a8908697c0..fb6f45b297 100644 --- a/internal/controller/datadogagent/feature/kubernetesstatecore/feature_test.go +++ b/internal/controller/datadogagent/feature/kubernetesstatecore/feature_test.go @@ -134,28 +134,6 @@ func Test_ksmFeature_Configure(t *testing.T) { ClusterAgent: test.NewDefaultComponentTest().WithWantFunc(func(t testing.TB, mgrInterface feature.PodTemplateManagers) {}), ClusterChecksRunner: test.NewDefaultComponentTest().WithWantFunc(func(t testing.TB, mgrInterface feature.PodTemplateManagers) {}), }, - { - Name: "ksm-core enabled, explicit collectControllerRevisions=true", - DDA: testutils.NewDatadogAgentBuilder(). - WithKSMEnabled(true). - WithClusterAgentImage("gcr.io/datadoghq/agent:7.71.0"). - WithKSMCollectControllerRevisions(true). - Build(), - WantConfigure: true, - ClusterAgent: ksmClusterAgentWantFunc(false), - Agent: test.NewDefaultComponentTest().WithWantFunc(ksmAgentNodeWantFunc), - }, - { - Name: "ksm-core enabled, explicit collectControllerRevisions=false", - DDA: testutils.NewDatadogAgentBuilder(). - WithKSMEnabled(true). - WithClusterAgentImage("gcr.io/datadoghq/agent:7.72.0"). - WithKSMCollectControllerRevisions(false). - Build(), - WantConfigure: true, - ClusterAgent: ksmClusterAgentWantFunc(false), - Agent: test.NewDefaultComponentTest().WithWantFunc(ksmAgentNodeWantFunc), - }, } tests.Run(t, buildKSMFeature) diff --git a/pkg/testutils/builder.go b/pkg/testutils/builder.go index 834583a1e2..11224c2269 100644 --- a/pkg/testutils/builder.go +++ b/pkg/testutils/builder.go @@ -580,12 +580,6 @@ func (builder *DatadogAgentBuilder) WithKSMCustomConf(customData string) *Datado return builder } -func (builder *DatadogAgentBuilder) WithKSMCollectControllerRevisions(enabled bool) *DatadogAgentBuilder { - builder.initKSM() - builder.datadogAgent.Spec.Features.KubeStateMetricsCore.CollectControllerRevisions = apiutils.NewBoolPointer(enabled) - return builder -} - // Orchestrator Explorer func (builder *DatadogAgentBuilder) initOE() { From 48342830a9c31d6d55794184cead18583e5e1cc5 Mon Sep 17 00:00:00 2001 From: Frank Spano Date: Wed, 29 Oct 2025 10:43:19 -0400 Subject: [PATCH 7/7] remove logging --- .../datadogagent/feature/kubernetesstatecore/feature.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go b/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go index 5668d2c8cc..09f5514c89 100644 --- a/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go +++ b/internal/controller/datadogagent/feature/kubernetesstatecore/feature.go @@ -172,12 +172,6 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent f.configConfigMapName = constants.GetConfName(dda, f.customConfig, defaultKubeStateMetricsCoreConf) - // Log final configuration state - f.logger.Info("KubeStateMetricsCore configuration finalized", - "collectAPIServiceMetrics", f.collectAPIServiceMetrics, - "collectCRDMetrics", f.collectCRDMetrics, - "collectControllerRevisions", f.collectControllerRevisions, - "runInClusterChecksRunner", f.runInClusterChecksRunner) } return output