From 6b09d886119d856d3b2a70b47ff700437233138d Mon Sep 17 00:00:00 2001 From: kovags Date: Tue, 16 Jun 2026 17:35:34 +0200 Subject: [PATCH 1/2] generate and some changes --- api/datadoghq/v2alpha1/datadogagent_types.go | 5 +++++ api/datadoghq/v2alpha1/zz_generated.deepcopy.go | 5 +++++ .../bases/v1/datadoghq.com_datadogagentinternals.yaml | 10 ++++++++++ .../datadoghq.com_datadogagentinternals_v1alpha1.json | 8 ++++++++ .../bases/v1/datadoghq.com_datadogagentprofiles.yaml | 5 +++++ .../datadoghq.com_datadogagentprofiles_v1alpha1.json | 4 ++++ config/crd/bases/v1/datadoghq.com_datadogagents.yaml | 10 ++++++++++ .../bases/v1/datadoghq.com_datadogagents_v2alpha1.json | 8 ++++++++ docs/configuration.v2alpha1.md | 1 + docs/configuration_public.md | 3 +++ internal/controller/datadogagent/feature/cws/envvar.go | 1 + .../controller/datadogagent/feature/cws/feature.go | 5 +++++ 12 files changed, 65 insertions(+) diff --git a/api/datadoghq/v2alpha1/datadogagent_types.go b/api/datadoghq/v2alpha1/datadogagent_types.go index 9606de3b56..adc9a3652f 100644 --- a/api/datadoghq/v2alpha1/datadogagent_types.go +++ b/api/datadoghq/v2alpha1/datadogagent_types.go @@ -567,6 +567,11 @@ type CWSSecurityProfilesConfig struct { // Default: true // +optional Enabled *bool `json:"enabled,omitempty"` + + // Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. + // Default: true + // +optional + V2 *bool `json:"v2,omitempty"` } type CWSRemoteConfigurationConfig struct { diff --git a/api/datadoghq/v2alpha1/zz_generated.deepcopy.go b/api/datadoghq/v2alpha1/zz_generated.deepcopy.go index 3ce3956403..72686f0ae8 100644 --- a/api/datadoghq/v2alpha1/zz_generated.deepcopy.go +++ b/api/datadoghq/v2alpha1/zz_generated.deepcopy.go @@ -695,6 +695,11 @@ func (in *CWSSecurityProfilesConfig) DeepCopyInto(out *CWSSecurityProfilesConfig *out = new(bool) **out = **in } + if in.V2 != nil { + in, out := &in.V2, &out.V2 + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CWSSecurityProfilesConfig. diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml b/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml index 0fd41618bc..4e9db07732 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml @@ -1407,6 +1407,11 @@ spec: Enabled enables Security Profiles collection for Cloud Workload Security. Default: true type: boolean + v2: + description: |- + Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. + Default: true + type: boolean type: object syscallMonitorEnabled: description: |- @@ -10114,6 +10119,11 @@ spec: Enabled enables Security Profiles collection for Cloud Workload Security. Default: true type: boolean + v2: + description: |- + Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. + Default: true + type: boolean type: object syscallMonitorEnabled: description: |- diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json index 3c61a4a54a..580c5cada7 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json @@ -1397,6 +1397,10 @@ "enabled": { "description": "Enabled enables Security Profiles collection for Cloud Workload Security.\nDefault: true", "type": "boolean" + }, + "v2": { + "description": "Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nDefault: true", + "type": "boolean" } }, "type": "object" @@ -9823,6 +9827,10 @@ "enabled": { "description": "Enabled enables Security Profiles collection for Cloud Workload Security.\nDefault: true", "type": "boolean" + }, + "v2": { + "description": "Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nDefault: true", + "type": "boolean" } }, "type": "object" diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml index 5bc20fa1e9..989d49d408 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml @@ -1407,6 +1407,11 @@ spec: Enabled enables Security Profiles collection for Cloud Workload Security. Default: true type: boolean + v2: + description: |- + Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. + Default: true + type: boolean type: object syscallMonitorEnabled: description: |- diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json index a7488a18ca..811f282979 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json @@ -1401,6 +1401,10 @@ "enabled": { "description": "Enabled enables Security Profiles collection for Cloud Workload Security.\nDefault: true", "type": "boolean" + }, + "v2": { + "description": "Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nDefault: true", + "type": "boolean" } }, "type": "object" diff --git a/config/crd/bases/v1/datadoghq.com_datadogagents.yaml b/config/crd/bases/v1/datadoghq.com_datadogagents.yaml index 61b96259f8..e96fb09e60 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagents.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogagents.yaml @@ -1411,6 +1411,11 @@ spec: Enabled enables Security Profiles collection for Cloud Workload Security. Default: true type: boolean + v2: + description: |- + Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. + Default: true + type: boolean type: object syscallMonitorEnabled: description: |- @@ -10207,6 +10212,11 @@ spec: Enabled enables Security Profiles collection for Cloud Workload Security. Default: true type: boolean + v2: + description: |- + Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. + Default: true + type: boolean type: object syscallMonitorEnabled: description: |- diff --git a/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json index 0f72aabd93..a64549b855 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json @@ -1397,6 +1397,10 @@ "enabled": { "description": "Enabled enables Security Profiles collection for Cloud Workload Security.\nDefault: true", "type": "boolean" + }, + "v2": { + "description": "Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nDefault: true", + "type": "boolean" } }, "type": "object" @@ -9922,6 +9926,10 @@ "enabled": { "description": "Enabled enables Security Profiles collection for Cloud Workload Security.\nDefault: true", "type": "boolean" + }, + "v2": { + "description": "Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nDefault: true", + "type": "boolean" } }, "type": "object" diff --git a/docs/configuration.v2alpha1.md b/docs/configuration.v2alpha1.md index 2bc0e20346..81b2044ff4 100644 --- a/docs/configuration.v2alpha1.md +++ b/docs/configuration.v2alpha1.md @@ -101,6 +101,7 @@ spec: | features.cws.network.enabled | Enables Cloud Workload Security Network detections. Default: true | | features.cws.remoteConfiguration.enabled | Enables Remote Configuration for Cloud Workload Security. Default: true | | features.cws.securityProfiles.enabled | Enables Security Profiles collection for Cloud Workload Security. Default: true | +| features.cws.securityProfiles.v2 | Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. Default: true | | features.cws.syscallMonitorEnabled | SyscallMonitorEnabled enables Syscall Monitoring (recommended for troubleshooting only). Default: false | | features.dataPlane.dogstatsd.enabled | Configures the Data Plane to handle DogStatsD traffic. When set to false, DogStatsD is handled by the Core Agent instead. Default: true | | features.dataPlane.enabled | Enables the Data Plane. Default: false | diff --git a/docs/configuration_public.md b/docs/configuration_public.md index c141925584..f19cba3cd6 100644 --- a/docs/configuration_public.md +++ b/docs/configuration_public.md @@ -168,6 +168,9 @@ spec: `features.cws.securityProfiles.enabled` : Enables Security Profiles collection for Cloud Workload Security. Default: true +`features.cws.securityProfiles.v2` +: Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. Default: true + `features.cws.syscallMonitorEnabled` : SyscallMonitorEnabled enables Syscall Monitoring (recommended for troubleshooting only). Default: false diff --git a/internal/controller/datadogagent/feature/cws/envvar.go b/internal/controller/datadogagent/feature/cws/envvar.go index f2d1a2204d..09e865f0b9 100644 --- a/internal/controller/datadogagent/feature/cws/envvar.go +++ b/internal/controller/datadogagent/feature/cws/envvar.go @@ -16,4 +16,5 @@ const ( DDRuntimeSecurityConfigRemoteConfigurationEnabled = "DD_RUNTIME_SECURITY_CONFIG_REMOTE_CONFIGURATION_ENABLED" DDRuntimeSecurityConfigDirectSendFromSystemProbe = "DD_RUNTIME_SECURITY_CONFIG_DIRECT_SEND_FROM_SYSTEM_PROBE" DDRuntimeSecurityConfigEventGRPCServer = "DD_RUNTIME_SECURITY_CONFIG_EVENT_GRPC_SERVER" + DDRuntimeConfigActivityDumpV2 = "DD_RUNTIME_SECURITY_CONFIG_ACTIVITY_DUMP_V2" ) diff --git a/internal/controller/datadogagent/feature/cws/feature.go b/internal/controller/datadogagent/feature/cws/feature.go index be61445ab6..5213cabb0c 100644 --- a/internal/controller/datadogagent/feature/cws/feature.go +++ b/internal/controller/datadogagent/feature/cws/feature.go @@ -52,6 +52,7 @@ type cwsFeature struct { directSendFromSystemProbe bool enforcementEnabled bool useVSock bool + activityDumpV2 bool owner metav1.Object logger logr.Logger @@ -106,6 +107,10 @@ func (f *cwsFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent f.activityDumpEnabled = apiutils.BoolValue(cwsConfig.SecurityProfiles.Enabled) } + if ddaSpec.Features.CWS.SecurityProfiles.V2 != nil { + f.activityDumpV2 = apiutils.BoolValue(ddaSpec.Features.CWS.SecurityProfiles.V2) + } + if ddaSpec.Features != nil && ddaSpec.Features.RemoteConfiguration != nil { f.remoteConfigurationEnabled = apiutils.BoolValue(ddaSpec.Features.RemoteConfiguration.Enabled) if cwsConfig.RemoteConfiguration != nil { From a58f146074ccdb00288382112864739115586268 Mon Sep 17 00:00:00 2001 From: kovags Date: Tue, 16 Jun 2026 18:24:40 +0200 Subject: [PATCH 2/2] support v2 finished --- api/datadoghq/v2alpha1/datadogagent_types.go | 4 +- .../datadoghq.com_datadogagentinternals.yaml | 8 +- ...hq.com_datadogagentinternals_v1alpha1.json | 4 +- .../datadoghq.com_datadogagentprofiles.yaml | 4 +- ...ghq.com_datadogagentprofiles_v1alpha1.json | 2 +- .../bases/v1/datadoghq.com_datadogagents.yaml | 8 +- .../datadoghq.com_datadogagents_v2alpha1.json | 4 +- docs/configuration.v2alpha1.md | 2 +- docs/configuration_public.md | 2 +- .../datadogagent/feature/cws/feature.go | 32 ++++- .../datadogagent/feature/cws/feature_test.go | 121 ++++++++++++++++++ 11 files changed, 175 insertions(+), 16 deletions(-) diff --git a/api/datadoghq/v2alpha1/datadogagent_types.go b/api/datadoghq/v2alpha1/datadogagent_types.go index adc9a3652f..a7f2444d5c 100644 --- a/api/datadoghq/v2alpha1/datadogagent_types.go +++ b/api/datadoghq/v2alpha1/datadogagent_types.go @@ -568,7 +568,9 @@ type CWSSecurityProfilesConfig struct { // +optional Enabled *bool `json:"enabled,omitempty"` - // Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. + // V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security. + // Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned + // or custom tags) this is disabled to avoid unbounded memory usage. // Default: true // +optional V2 *bool `json:"v2,omitempty"` diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml b/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml index 4e9db07732..f776e61852 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml @@ -1409,7 +1409,9 @@ spec: type: boolean v2: description: |- - Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. + V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security. + Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned + or custom tags) this is disabled to avoid unbounded memory usage. Default: true type: boolean type: object @@ -10121,7 +10123,9 @@ spec: type: boolean v2: description: |- - Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. + V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security. + Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned + or custom tags) this is disabled to avoid unbounded memory usage. Default: true type: boolean type: object diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json index 580c5cada7..a6edaf80c8 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogagentinternals_v1alpha1.json @@ -1399,7 +1399,7 @@ "type": "boolean" }, "v2": { - "description": "Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nDefault: true", + "description": "V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nRequires Agent version \u003e= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned\nor custom tags) this is disabled to avoid unbounded memory usage.\nDefault: true", "type": "boolean" } }, @@ -9829,7 +9829,7 @@ "type": "boolean" }, "v2": { - "description": "Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nDefault: true", + "description": "V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nRequires Agent version \u003e= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned\nor custom tags) this is disabled to avoid unbounded memory usage.\nDefault: true", "type": "boolean" } }, diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml index 989d49d408..a34e0c0ca5 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml @@ -1409,7 +1409,9 @@ spec: type: boolean v2: description: |- - Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. + V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security. + Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned + or custom tags) this is disabled to avoid unbounded memory usage. Default: true type: boolean type: object diff --git a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json index 811f282979..26fa280c78 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogagentprofiles_v1alpha1.json @@ -1403,7 +1403,7 @@ "type": "boolean" }, "v2": { - "description": "Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nDefault: true", + "description": "V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nRequires Agent version \u003e= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned\nor custom tags) this is disabled to avoid unbounded memory usage.\nDefault: true", "type": "boolean" } }, diff --git a/config/crd/bases/v1/datadoghq.com_datadogagents.yaml b/config/crd/bases/v1/datadoghq.com_datadogagents.yaml index e96fb09e60..b50f1692bd 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagents.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogagents.yaml @@ -1413,7 +1413,9 @@ spec: type: boolean v2: description: |- - Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. + V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security. + Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned + or custom tags) this is disabled to avoid unbounded memory usage. Default: true type: boolean type: object @@ -10214,7 +10216,9 @@ spec: type: boolean v2: description: |- - Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. + V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security. + Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned + or custom tags) this is disabled to avoid unbounded memory usage. Default: true type: boolean type: object diff --git a/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json index a64549b855..ad9f0167b9 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogagents_v2alpha1.json @@ -1399,7 +1399,7 @@ "type": "boolean" }, "v2": { - "description": "Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nDefault: true", + "description": "V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nRequires Agent version \u003e= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned\nor custom tags) this is disabled to avoid unbounded memory usage.\nDefault: true", "type": "boolean" } }, @@ -9928,7 +9928,7 @@ "type": "boolean" }, "v2": { - "description": "Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nDefault: true", + "description": "V2 enables Activity Dump v2 Security Profiles collection for Cloud Workload Security.\nRequires Agent version \u003e= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned\nor custom tags) this is disabled to avoid unbounded memory usage.\nDefault: true", "type": "boolean" } }, diff --git a/docs/configuration.v2alpha1.md b/docs/configuration.v2alpha1.md index 81b2044ff4..99c727256c 100644 --- a/docs/configuration.v2alpha1.md +++ b/docs/configuration.v2alpha1.md @@ -101,7 +101,7 @@ spec: | features.cws.network.enabled | Enables Cloud Workload Security Network detections. Default: true | | features.cws.remoteConfiguration.enabled | Enables Remote Configuration for Cloud Workload Security. Default: true | | features.cws.securityProfiles.enabled | Enables Security Profiles collection for Cloud Workload Security. Default: true | -| features.cws.securityProfiles.v2 | Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. Default: true | +| features.cws.securityProfiles.v2 | Enables Activity Dump v2 Security Profiles collection for Cloud Workload Security. Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned or custom tags) this is disabled to avoid unbounded memory usage. Default: true | | features.cws.syscallMonitorEnabled | SyscallMonitorEnabled enables Syscall Monitoring (recommended for troubleshooting only). Default: false | | features.dataPlane.dogstatsd.enabled | Configures the Data Plane to handle DogStatsD traffic. When set to false, DogStatsD is handled by the Core Agent instead. Default: true | | features.dataPlane.enabled | Enables the Data Plane. Default: false | diff --git a/docs/configuration_public.md b/docs/configuration_public.md index f19cba3cd6..079ddd8346 100644 --- a/docs/configuration_public.md +++ b/docs/configuration_public.md @@ -169,7 +169,7 @@ spec: : Enables Security Profiles collection for Cloud Workload Security. Default: true `features.cws.securityProfiles.v2` -: Enabled Activity Dump v2 Security Profiles collection for Cloud Workload Security. Default: true +: Enables Activity Dump v2 Security Profiles collection for Cloud Workload Security. Requires Agent version >= 7.81.0. On older or unidentifiable Agent images (e.g. digest-pinned or custom tags) this is disabled to avoid unbounded memory usage. Default: true `features.cws.syscallMonitorEnabled` : SyscallMonitorEnabled enables Syscall Monitoring (recommended for troubleshooting only). Default: false diff --git a/internal/controller/datadogagent/feature/cws/feature.go b/internal/controller/datadogagent/feature/cws/feature.go index 5213cabb0c..2daca83077 100644 --- a/internal/controller/datadogagent/feature/cws/feature.go +++ b/internal/controller/datadogagent/feature/cws/feature.go @@ -24,9 +24,13 @@ 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" ) +const ActivityDumpV2MinVersion = "7.81.0-0" + func init() { err := feature.Register(feature.CWSIDType, buildCWSFeature) if err != nil { @@ -63,6 +67,19 @@ type cwsFeature struct { customConfigAnnotationValue string } +// activityDumpV2Supported reports whether the configured Agent image is known to be >= +// ActivityDumpV2MinVersion. The default value passed to IsAboveMinVersion is intentionally false: +// Activity Dump v2 lacks guards against unbounded memory allocation on older Agents, so when the +// version cannot be parsed (e.g. custom or digest-pinned tags) we must fail closed rather than risk +// an OOM. Do not flip this to true without adding such guards. +func activityDumpV2Supported(ddaSpec *v2alpha1.DatadogAgentSpec) bool { + defaultValue := false + if nodeAgent, ok := ddaSpec.Override[v2alpha1.NodeAgentComponentName]; ok && nodeAgent.Image != nil { + return utils.IsAboveMinVersion(common.GetAgentVersionFromImage(*nodeAgent.Image), ActivityDumpV2MinVersion, &defaultValue) + } + return utils.IsAboveMinVersion(images.AgentLatestVersion, ActivityDumpV2MinVersion, &defaultValue) +} + // ID returns the ID of the Feature func (f *cwsFeature) ID() feature.IDType { return feature.CWSIDType @@ -105,10 +122,19 @@ func (f *cwsFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent } if cwsConfig.SecurityProfiles != nil { f.activityDumpEnabled = apiutils.BoolValue(cwsConfig.SecurityProfiles.Enabled) - } - if ddaSpec.Features.CWS.SecurityProfiles.V2 != nil { - f.activityDumpV2 = apiutils.BoolValue(ddaSpec.Features.CWS.SecurityProfiles.V2) + if apiutils.BoolValue(cwsConfig.SecurityProfiles.V2) { + if activityDumpV2Supported(ddaSpec) { + f.activityDumpV2 = true + } else { + // Surface the silent gate: the user explicitly opted into v2 but we are disabling + // it because the Agent version can't be confirmed to support it. Logged at the + // default Info level so it is visible without raising log verbosity. + f.logger.Info("CWS Activity Dump v2 was requested but is disabled: the Agent image version could not be confirmed to be >= "+ + ActivityDumpV2MinVersion+" (custom or digest-pinned tags parse as unknown). Enabling it on older Agents risks unbounded memory usage.", + "minVersion", ActivityDumpV2MinVersion) + } + } } if ddaSpec.Features != nil && ddaSpec.Features.RemoteConfiguration != nil { diff --git a/internal/controller/datadogagent/feature/cws/feature_test.go b/internal/controller/datadogagent/feature/cws/feature_test.go index d42cbb7dcf..14567e2695 100644 --- a/internal/controller/datadogagent/feature/cws/feature_test.go +++ b/internal/controller/datadogagent/feature/cws/feature_test.go @@ -128,6 +128,127 @@ func Test_cwsFeature_Configure(t *testing.T) { tests.Run(t, buildCWSFeature) } +func Test_activityDumpV2Supported(t *testing.T) { + nodeAgentWithTag := func(tag string) map[v2alpha1.ComponentName]*v2alpha1.DatadogAgentComponentOverride { + return map[v2alpha1.ComponentName]*v2alpha1.DatadogAgentComponentOverride{ + v2alpha1.NodeAgentComponentName: { + Image: &v2alpha1.AgentImageConfig{Tag: tag}, + }, + } + } + + tests := []struct { + name string + override map[v2alpha1.ComponentName]*v2alpha1.DatadogAgentComponentOverride + want bool + }{ + { + name: "agent tag at minimum version", + override: nodeAgentWithTag("7.81.0"), + want: true, + }, + { + name: "agent tag above minimum version", + override: nodeAgentWithTag("7.82.0"), + want: true, + }, + { + name: "agent tag below minimum version", + override: nodeAgentWithTag("7.80.0"), + want: false, + }, + { + // Fails closed: an unparseable tag (custom build, digest-pinned, etc.) must not enable v2 + // because older Agents have no guard against unbounded memory allocation. + name: "unparseable custom tag fails closed", + override: nodeAgentWithTag("custom-internal-build"), + want: false, + }, + { + // No image override resolves to images.AgentLatestVersion, which is currently below the + // minimum, so v2 stays off until the operator default Agent version is bumped. + name: "no image override uses latest default", + override: nil, + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ddaSpec := &v2alpha1.DatadogAgentSpec{Override: tt.override} + assert.Equal(t, tt.want, activityDumpV2Supported(ddaSpec)) + }) + } +} + +func Test_cwsFeature_ConfigureActivityDumpV2(t *testing.T) { + newDDASpec := func(v2 *bool, tag string) *v2alpha1.DatadogAgentSpec { + spec := &v2alpha1.DatadogAgentSpec{ + Features: &v2alpha1.DatadogFeatures{ + CWS: &v2alpha1.CWSFeatureConfig{ + Enabled: ptr.To(true), + SecurityProfiles: &v2alpha1.CWSSecurityProfilesConfig{ + Enabled: ptr.To(true), + V2: v2, + }, + }, + }, + } + if tag != "" { + spec.Override = map[v2alpha1.ComponentName]*v2alpha1.DatadogAgentComponentOverride{ + v2alpha1.NodeAgentComponentName: {Image: &v2alpha1.AgentImageConfig{Tag: tag}}, + } + } + return spec + } + + tests := []struct { + name string + v2 *bool + tag string + want bool + }{ + { + name: "v2 requested on supported agent is enabled", + v2: ptr.To(true), + tag: "7.81.0", + want: true, + }, + { + name: "v2 requested on old agent is gated off", + v2: ptr.To(true), + tag: "7.80.0", + want: false, + }, + { + name: "v2 requested on unparseable tag is gated off", + v2: ptr.To(true), + tag: "custom-internal-build", + want: false, + }, + { + name: "v2 not requested stays off even on supported agent", + v2: ptr.To(false), + tag: "7.81.0", + want: false, + }, + { + name: "v2 unset stays off", + v2: nil, + tag: "7.81.0", + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f := &cwsFeature{} + f.Configure(&v2alpha1.DatadogAgent{}, newDDASpec(tt.v2, tt.tag), nil) + assert.Equal(t, tt.want, f.activityDumpV2) + }) + } +} + func cwsAgentNodeWantFunc(withSubFeatures bool, directSendFromSysProbe bool, enforcementEnabled bool) *test.ComponentTest { return test.NewDefaultComponentTest().WithWantFunc( func(t testing.TB, mgrInterface feature.PodTemplateManagers) {