Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions api/datadoghq/v2alpha1/datadogagent_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,12 @@ type CSPMFeatureConfig struct {
// HostBenchmarks contains configuration for host benchmarks.
// +optional
HostBenchmarks *CSPMHostBenchmarksConfig `json:"hostBenchmarks,omitempty"`

// RunInSystemProbe configures CSPM to send payloads directly from the system-probe, without using the security-agent.
// This is an experimental feature. Contact support before using.
// Default: false
// +optional
RunInSystemProbe *bool `json:"runInSystemProbe,omitempty"`
}

// CSPMHostBenchmarksConfig contains configuration for host benchmarks.
Expand Down
5 changes: 5 additions & 0 deletions api/datadoghq/v2alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions config/crd/bases/v1/datadoghq.com_datadogagentinternals.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,12 @@ spec:
Default: true
type: boolean
type: object
runInSystemProbe:
description: |-
RunInSystemProbe configures CSPM to send payloads directly from the system-probe, without using the security-agent.
This is an experimental feature. Contact support before using.
Default: false
type: boolean
type: object
cws:
description: CWS (Cloud Workload Security) configuration.
Expand Down Expand Up @@ -9142,6 +9148,12 @@ spec:
Default: true
type: boolean
type: object
runInSystemProbe:
description: |-
RunInSystemProbe configures CSPM to send payloads directly from the system-probe, without using the security-agent.
This is an experimental feature. Contact support before using.
Default: false
type: boolean
type: object
cws:
description: CWS (Cloud Workload Security) configuration.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1159,6 +1159,10 @@
}
},
"type": "object"
},
"runInSystemProbe": {
"description": "RunInSystemProbe configures CSPM to send payloads directly from the system-probe, without using the security-agent.\nThis is an experimental feature. Contact support before using.\nDefault: false",
"type": "boolean"
}
},
"type": "object"
Expand Down Expand Up @@ -9010,6 +9014,10 @@
}
},
"type": "object"
},
"runInSystemProbe": {
"description": "RunInSystemProbe configures CSPM to send payloads directly from the system-probe, without using the security-agent.\nThis is an experimental feature. Contact support before using.\nDefault: false",
"type": "boolean"
}
},
"type": "object"
Expand Down
6 changes: 6 additions & 0 deletions config/crd/bases/v1/datadoghq.com_datadogagentprofiles.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,12 @@ spec:
Default: true
type: boolean
type: object
runInSystemProbe:
description: |-
RunInSystemProbe configures CSPM to send payloads directly from the system-probe, without using the security-agent.
This is an experimental feature. Contact support before using.
Default: false
type: boolean
type: object
cws:
description: CWS (Cloud Workload Security) configuration.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,10 @@
}
},
"type": "object"
},
"runInSystemProbe": {
"description": "RunInSystemProbe configures CSPM to send payloads directly from the system-probe, without using the security-agent.\nThis is an experimental feature. Contact support before using.\nDefault: false",
"type": "boolean"
}
},
"type": "object"
Expand Down
12 changes: 12 additions & 0 deletions config/crd/bases/v1/datadoghq.com_datadogagents.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,12 @@ spec:
Default: true
type: boolean
type: object
runInSystemProbe:
description: |-
RunInSystemProbe configures CSPM to send payloads directly from the system-probe, without using the security-agent.
This is an experimental feature. Contact support before using.
Default: false
type: boolean
type: object
cws:
description: CWS (Cloud Workload Security) configuration.
Expand Down Expand Up @@ -9192,6 +9198,12 @@ spec:
Default: true
type: boolean
type: object
runInSystemProbe:
description: |-
RunInSystemProbe configures CSPM to send payloads directly from the system-probe, without using the security-agent.
This is an experimental feature. Contact support before using.
Default: false
type: boolean
type: object
cws:
description: CWS (Cloud Workload Security) configuration.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1159,6 +1159,10 @@
}
},
"type": "object"
},
"runInSystemProbe": {
"description": "RunInSystemProbe configures CSPM to send payloads directly from the system-probe, without using the security-agent.\nThis is an experimental feature. Contact support before using.\nDefault: false",
"type": "boolean"
}
},
"type": "object"
Expand Down Expand Up @@ -9075,6 +9079,10 @@
}
},
"type": "object"
},
"runInSystemProbe": {
"description": "RunInSystemProbe configures CSPM to send payloads directly from the system-probe, without using the security-agent.\nThis is an experimental feature. Contact support before using.\nDefault: false",
"type": "boolean"
}
},
"type": "object"
Expand Down
1 change: 1 addition & 0 deletions docs/configuration.v2alpha1.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ spec:
| features.cspm.customBenchmarks.configMap.name | Is the name of the ConfigMap. |
| features.cspm.enabled | Enables Cloud Security Posture Management. Default: false |
| features.cspm.hostBenchmarks.enabled | Enables host benchmarks. Default: true |
| features.cspm.runInSystemProbe | RunInSystemProbe configures CSPM to send payloads directly from the system-probe, without using the security-agent. This is an experimental feature. Contact support before using. Default: false |
| features.cws.customPolicies.configData | ConfigData corresponds to the configuration file content. |
| features.cws.customPolicies.configMap.items | Maps a ConfigMap data `key` to a file `path` mount. |
| features.cws.customPolicies.configMap.name | Is the name of the ConfigMap. |
Expand Down
3 changes: 3 additions & 0 deletions docs/configuration_public.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ spec:
`features.cspm.hostBenchmarks.enabled`
: Enables host benchmarks. Default: true

`features.cspm.runInSystemProbe`
: RunInSystemProbe configures CSPM to send payloads directly from the system-probe, without using the security-agent. This is an experimental feature. Contact support before using. Default: false

`features.cws.customPolicies.configData`
: ConfigData corresponds to the configuration file content.

Expand Down
43 changes: 30 additions & 13 deletions internal/controller/datadogagent/feature/cspm/feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type cspmFeature struct {
serviceAccountName string
checkInterval string
hostBenchmarksEnabled bool
runInSystemProbe bool

owner metav1.Object
logger logr.Logger
Expand Down Expand Up @@ -96,6 +97,16 @@ func (f *cspmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgen
f.hostBenchmarksEnabled = true
}

f.runInSystemProbe = apiutils.BoolValue(cspmConfig.RunInSystemProbe)

// Determine which container to use for CSPM on the node
var nodeContainer apicommon.AgentContainerName
if f.runInSystemProbe {
nodeContainer = apicommon.SystemProbeContainerName
} else {
nodeContainer = apicommon.SecurityAgentContainerName
}

reqComp = feature.RequiredComponents{
ClusterAgent: feature.RequiredComponent{
IsRequired: apiutils.NewBoolPointer(true),
Expand All @@ -104,7 +115,7 @@ func (f *cspmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgen
Agent: feature.RequiredComponent{
IsRequired: apiutils.NewBoolPointer(true),
Containers: []apicommon.AgentContainerName{
apicommon.SecurityAgentContainerName,
nodeContainer,
},
},
}
Expand Down Expand Up @@ -230,12 +241,18 @@ func (f *cspmFeature) ManageSingleContainerNodeAgent(managers feature.PodTemplat
// ManageNodeAgent allows a feature to configure the Node Agent's corev1.PodTemplateSpec
// It should do nothing if the feature doesn't need to configure it.
func (f *cspmFeature) ManageNodeAgent(managers feature.PodTemplateManagers, provider string) error {
// Determine which container to use based on runInSystemProbe
targetContainer := apicommon.SecurityAgentContainerName
if f.runInSystemProbe {
targetContainer = apicommon.SystemProbeContainerName
}

// security context capabilities
capabilities := []corev1.Capability{
"AUDIT_CONTROL",
"AUDIT_READ",
}
managers.SecurityContext().AddCapabilitiesToContainer(capabilities, apicommon.SecurityAgentContainerName)
managers.SecurityContext().AddCapabilitiesToContainer(capabilities, targetContainer)

volMountMgr := managers.VolumeMount()
VolMgr := managers.Volume()
Expand Down Expand Up @@ -281,10 +298,10 @@ func (f *cspmFeature) ManageNodeAgent(managers feature.PodTemplateManagers, prov
}
}

// Add empty volume to Security Agent
// Add empty volume to target container (Security Agent or System Probe)
benchmarksVol, benchmarksVolMount := volume.GetVolumesEmptyDir(securityAgentComplianceConfigDirVolumeName, securityAgentComplianceConfigDirVolumePath, true)
managers.Volume().AddVolume(&benchmarksVol)
managers.VolumeMount().AddVolumeMountToContainer(&benchmarksVolMount, apicommon.SecurityAgentContainerName)
managers.VolumeMount().AddVolumeMountToContainer(&benchmarksVolMount, targetContainer)

// Add compliance.d volume mount to init-volume container at different path
benchmarkVolMountInitVol := corev1.VolumeMount{
Expand All @@ -297,55 +314,55 @@ func (f *cspmFeature) ManageNodeAgent(managers feature.PodTemplateManagers, prov

// cgroups volume mount
cgroupsVol, cgroupsVolMount := volume.GetVolumes(common.CgroupsVolumeName, common.CgroupsHostPath, common.CgroupsMountPath, true)
volMountMgr.AddVolumeMountToContainer(&cgroupsVolMount, apicommon.SecurityAgentContainerName)
volMountMgr.AddVolumeMountToContainer(&cgroupsVolMount, targetContainer)
VolMgr.AddVolume(&cgroupsVol)

// passwd volume mount
passwdVol, passwdVolMount := volume.GetVolumes(common.PasswdVolumeName, common.PasswdHostPath, common.PasswdMountPath, true)
volMountMgr.AddVolumeMountToContainer(&passwdVolMount, apicommon.SecurityAgentContainerName)
volMountMgr.AddVolumeMountToContainer(&passwdVolMount, targetContainer)
VolMgr.AddVolume(&passwdVol)

// procdir volume mount
procdirVol, procdirVolMount := volume.GetVolumes(common.ProcdirVolumeName, common.ProcdirHostPath, common.ProcdirMountPath, true)
volMountMgr.AddVolumeMountToContainer(&procdirVolMount, apicommon.SecurityAgentContainerName)
volMountMgr.AddVolumeMountToContainer(&procdirVolMount, targetContainer)
VolMgr.AddVolume(&procdirVol)

// host root volume mount
hostRootVol, hostRootVolMount := volume.GetVolumes(common.HostRootVolumeName, common.HostRootHostPath, common.HostRootMountPath, true)
volMountMgr.AddVolumeMountToContainer(&hostRootVolMount, apicommon.SecurityAgentContainerName)
volMountMgr.AddVolumeMountToContainer(&hostRootVolMount, targetContainer)
VolMgr.AddVolume(&hostRootVol)

// group volume mount
groupVol, groupVolMount := volume.GetVolumes(common.GroupVolumeName, common.GroupHostPath, common.GroupMountPath, true)
volMountMgr.AddVolumeMountToContainer(&groupVolMount, apicommon.SecurityAgentContainerName)
volMountMgr.AddVolumeMountToContainer(&groupVolMount, targetContainer)
VolMgr.AddVolume(&groupVol)

// env vars
enabledEnvVar := &corev1.EnvVar{
Name: DDComplianceConfigEnabled,
Value: "true",
}
managers.EnvVar().AddEnvVarToContainers([]apicommon.AgentContainerName{apicommon.CoreAgentContainerName, apicommon.SecurityAgentContainerName}, enabledEnvVar)
managers.EnvVar().AddEnvVarToContainers([]apicommon.AgentContainerName{apicommon.CoreAgentContainerName, targetContainer}, enabledEnvVar)

hostRootEnvVar := &corev1.EnvVar{
Name: common.DDHostRootEnvVar,
Value: common.HostRootMountPath,
}
managers.EnvVar().AddEnvVarToContainer(apicommon.SecurityAgentContainerName, hostRootEnvVar)
managers.EnvVar().AddEnvVarToContainer(targetContainer, hostRootEnvVar)

if f.checkInterval != "" {
intervalEnvVar := &corev1.EnvVar{
Name: DDComplianceConfigCheckInterval,
Value: f.checkInterval,
}
managers.EnvVar().AddEnvVarToContainer(apicommon.SecurityAgentContainerName, intervalEnvVar)
managers.EnvVar().AddEnvVarToContainer(targetContainer, intervalEnvVar)
}

hostBenchmarksEnabledEnvVar := &corev1.EnvVar{
Name: DDComplianceHostBenchmarksEnabled,
Value: apiutils.BoolToString(&f.hostBenchmarksEnabled),
}
managers.EnvVar().AddEnvVarToContainer(apicommon.SecurityAgentContainerName, hostBenchmarksEnabledEnvVar)
managers.EnvVar().AddEnvVarToContainer(targetContainer, hostBenchmarksEnabledEnvVar)

return nil
}
Expand Down
44 changes: 38 additions & 6 deletions internal/controller/datadogagent/feature/cspm/feature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,25 @@ func Test_cspmFeature_Configure(t *testing.T) {
ddaCSPMEnabled.Spec.Features.CSPM.HostBenchmarks = &v2alpha1.CSPMHostBenchmarksConfig{Enabled: apiutils.NewBoolPointer(true)}
}

ddaCSPMDirectSendEnabled := ddaCSPMDisabled.DeepCopy()
{
ddaCSPMDirectSendEnabled.Spec.Features.CSPM.Enabled = apiutils.NewBoolPointer(true)
ddaCSPMDirectSendEnabled.Spec.Features.CSPM.CustomBenchmarks = &v2alpha1.CustomConfig{
ConfigMap: &v2alpha1.ConfigMapConfig{
Name: "custom_test",
Items: []corev1.KeyToPath{
{
Key: "key1",
Path: "some/path",
},
},
},
}
ddaCSPMDirectSendEnabled.Spec.Features.CSPM.CheckInterval = &metav1.Duration{Duration: 20 * time.Minute}
ddaCSPMDirectSendEnabled.Spec.Features.CSPM.HostBenchmarks = &v2alpha1.CSPMHostBenchmarksConfig{Enabled: apiutils.NewBoolPointer(true)}
ddaCSPMDirectSendEnabled.Spec.Features.CSPM.RunInSystemProbe = apiutils.NewBoolPointer(true)
}

tests := test.FeatureTestSuite{

{
Expand All @@ -79,7 +98,14 @@ func Test_cspmFeature_Configure(t *testing.T) {
DDA: ddaCSPMEnabled,
WantConfigure: true,
ClusterAgent: cspmClusterAgentWantFunc(),
Agent: cspmAgentNodeWantFunc(),
Agent: cspmAgentNodeWantFunc(false),
},
{
Name: "CSPM enabled with runInSystemProbe",
DDA: ddaCSPMDirectSendEnabled,
WantConfigure: true,
ClusterAgent: cspmClusterAgentWantFunc(),
Agent: cspmAgentNodeWantFunc(true),
},
}

Expand Down Expand Up @@ -145,11 +171,17 @@ func cspmClusterAgentWantFunc() *test.ComponentTest {
)
}

func cspmAgentNodeWantFunc() *test.ComponentTest {
func cspmAgentNodeWantFunc(runInSystemProbe bool) *test.ComponentTest {
return test.NewDefaultComponentTest().WithWantFunc(
func(t testing.TB, mgrInterface feature.PodTemplateManagers) {
mgr := mgrInterface.(*fake.PodTemplateManagers)

// Determine which container to check based on runInSystemProbe
targetContainer := apicommon.SecurityAgentContainerName
if runInSystemProbe {
targetContainer = apicommon.SystemProbeContainerName
}

want := []*corev1.EnvVar{
{
Name: DDComplianceConfigEnabled,
Expand All @@ -169,8 +201,8 @@ func cspmAgentNodeWantFunc() *test.ComponentTest {
},
}

securityAgentEnvVars := mgr.EnvVarMgr.EnvVarsByC[apicommon.SecurityAgentContainerName]
assert.True(t, apiutils.IsEqualStruct(securityAgentEnvVars, want), "Agent envvars \ndiff = %s", cmp.Diff(securityAgentEnvVars, want))
targetContainerEnvVars := mgr.EnvVarMgr.EnvVarsByC[targetContainer]
assert.True(t, apiutils.IsEqualStruct(targetContainerEnvVars, want), "Agent envvars \ndiff = %s", cmp.Diff(targetContainerEnvVars, want))

// check volume mounts
wantVolumeMounts := []corev1.VolumeMount{
Expand Down Expand Up @@ -206,8 +238,8 @@ func cspmAgentNodeWantFunc() *test.ComponentTest {
},
}

securityAgentVolumeMounts := mgr.VolumeMountMgr.VolumeMountsByC[apicommon.SecurityAgentContainerName]
assert.True(t, apiutils.IsEqualStruct(securityAgentVolumeMounts, wantVolumeMounts), "Security Agent volume mounts \ndiff = %s", cmp.Diff(securityAgentVolumeMounts, wantVolumeMounts))
targetContainerVolumeMounts := mgr.VolumeMountMgr.VolumeMountsByC[targetContainer]
assert.True(t, apiutils.IsEqualStruct(targetContainerVolumeMounts, wantVolumeMounts), "Target container volume mounts \ndiff = %s", cmp.Diff(targetContainerVolumeMounts, wantVolumeMounts))

// check volumes
wantVolumes := []corev1.Volume{
Expand Down
Loading