Skip to content

Commit

Permalink
[features] migrate USM feature (#482)
Browse files Browse the repository at this point in the history
* [features] migrate usm feature
  • Loading branch information
celenechang committed May 13, 2022
1 parent c07038f commit c32af59
Show file tree
Hide file tree
Showing 18 changed files with 714 additions and 57 deletions.
23 changes: 17 additions & 6 deletions apis/datadoghq/common/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ const (
DefaultMetricsProviderPort int32 = 8443
// DefaultKubeStateMetricsCoreConf default ksm core ConfigMap name
DefaultKubeStateMetricsCoreConf string = "kube-state-metrics-core-config"
// DefaultSysprobeSocketPath default system probe socket path
DefaultSysprobeSocketPath = "/var/run/sysprobe/sysprobe.sock"
// DefaultSystemProbeSocketPath default System Probe socket path
DefaultSystemProbeSocketPath string = "/var/run/sysprobe/sysprobe.sock"

// Liveness probe default config
DefaultLivenessProbeInitialDelaySeconds int32 = 15
Expand All @@ -69,6 +69,12 @@ const (
DefaultReadinessProbeHTTPPath = "/ready"
)

// Annotations
const (
SystemProbeAppArmorAnnotationKey = "container.apparmor.security.beta.kubernetes.io/system-probe"
SystemProbeAppArmorAnnotationValue = "unconfined"
)

// Datadog volume names and mount paths
const (
ConfdVolumeName = "confd"
Expand All @@ -77,6 +83,10 @@ const (
ConfigVolumePath = "/etc/datadog-agent"
KubeStateMetricCoreVolumeName = "ksm-core-config"

HostRootVolumeName = "hostroot"
HostRootHostPath = "/"
HostRootMountPath = "/host/root"

ProcdirVolumeName = "procdir"
ProcdirHostPath = "/proc"
ProcdirMountPath = "/host/proc"
Expand All @@ -85,11 +95,12 @@ const (
CgroupsHostPath = "/sys/fs/cgroup"
CgroupsMountPath = "/host/sys/fs/cgroup"

DebugfsVolumeName = "debugfs"
DebugfsVolumePath = "/sys/kernel/debug"
SystemProbeSocketVolumeName = "sysprobe-socket-dir"
SystemProbeSocketVolumePath = "/var/run/sysprobe"

SysprobeSocketVolumeName = "sysprobe-socket-dir"
SysprobeSocketVolumePath = "/var/run/sysprobe"
DebugfsVolumeName = "debugfs"
// same path on host and container
DebugfsPath = "/sys/kernel/debug"

ModulesVolumeName = "modules"
// same path on host and container
Expand Down
35 changes: 19 additions & 16 deletions apis/datadoghq/common/envvar.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,23 @@ package common

// Datadog env var names
const (
DDIgnoreAutoConf = "DD_IGNORE_AUTOCONF"
DDKubeStateMetricsCoreEnabled = "DD_KUBE_STATE_METRICS_CORE_ENABLED"
DDKubeStateMetricsCoreConfigMap = "DD_KUBE_STATE_METRICS_CORE_CONFIGMAP_NAME"
DDSystemProbeNPMEnabledEnvVar = "DD_SYSTEM_PROBE_NETWORK_ENABLED"
DDSystemProbeEnabledEnvVar = "DD_SYSTEM_PROBE_ENABLED"
DDProcessAgentEnabledEnvVar = "DD_PROCESS_AGENT_ENABLED"
DDSystemProbeSocketEnvVar = "DD_SYSPROBE_SOCKET"
DDEnableOOMKillEnvVar = "DD_SYSTEM_PROBE_CONFIG_ENABLE_OOM_KILL"
DDEnableTCPQueueLengthEnvVar = "DD_SYSTEM_PROBE_CONFIG_ENABLE_TCP_QUEUE_LENGTH"
DDLeaderElection = "DD_LEADER_ELECTION"
DDClusterAgentKubeServiceName = "DD_CLUSTER_AGENT_KUBERNETES_SERVICE_NAME"
DDHealthPort = "DD_HEALTH_PORT"
DDLogsEnabled = "DD_LOGS_ENABLED"
DDLogsConfigContainerCollectAll = "DD_LOGS_CONFIG_CONTAINER_COLLECT_ALL"
DDLogsContainerCollectUsingFiles = "DD_LOGS_CONFIG_K8S_CONTAINER_USE_FILE"
DDLogsConfigOpenFilesLimit = "DD_LOGS_CONFIG_OPEN_FILES_LIMIT"
DDIgnoreAutoConf = "DD_IGNORE_AUTOCONF"
DDKubeStateMetricsCoreEnabled = "DD_KUBE_STATE_METRICS_CORE_ENABLED"
DDKubeStateMetricsCoreConfigMap = "DD_KUBE_STATE_METRICS_CORE_CONFIGMAP_NAME"
DDHostRootEnvVar = "HOST_ROOT"
DDSystemProbeNPMEnabledEnvVar = "DD_SYSTEM_PROBE_NETWORK_ENABLED"
DDSystemProbeEnabledEnvVar = "DD_SYSTEM_PROBE_ENABLED"
DDProcessAgentEnabledEnvVar = "DD_PROCESS_AGENT_ENABLED"
DDSystemProbeExternal = "DD_SYSTEM_PROBE_EXTERNAL"
DDSystemProbeServiceMonitoringEnabled = "DD_SYSTEM_PROBE_SERVICE_MONITORING_ENABLED"
DDSystemProbeSocket = "DD_SYSPROBE_SOCKET"
DDEnableOOMKillEnvVar = "DD_SYSTEM_PROBE_CONFIG_ENABLE_OOM_KILL"
DDEnableTCPQueueLengthEnvVar = "DD_SYSTEM_PROBE_CONFIG_ENABLE_TCP_QUEUE_LENGTH"
DDLeaderElection = "DD_LEADER_ELECTION"
DDClusterAgentKubeServiceName = "DD_CLUSTER_AGENT_KUBERNETES_SERVICE_NAME"
DDHealthPort = "DD_HEALTH_PORT"
DDLogsEnabled = "DD_LOGS_ENABLED"
DDLogsConfigContainerCollectAll = "DD_LOGS_CONFIG_CONTAINER_COLLECT_ALL"
DDLogsContainerCollectUsingFiles = "DD_LOGS_CONFIG_K8S_CONTAINER_USE_FILE"
DDLogsConfigOpenFilesLimit = "DD_LOGS_CONFIG_OPEN_FILES_LIMIT"
)
2 changes: 1 addition & 1 deletion apis/datadoghq/v2alpha1/datadogagent_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ type NPMFeatureConfig struct {
}

// USMFeatureConfig contains USM (Universal Service Monitoring) feature configuration.
// Universal Service Monitoring runs in the System Probe.
// Universal Service Monitoring runs in the Process Agent and System Probe.
type USMFeatureConfig struct {
// Enabled enables Universal Service Monitoring.
// Default: false
Expand Down
24 changes: 19 additions & 5 deletions controllers/datadogagent/feature/fake/PodTemplateManagers.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import (

// PodTemplateManagers is an autogenerated mock type for the PodTemplateManagers type
type PodTemplateManagers struct {
Tpl v1.PodTemplateSpec
EnvVarMgr *mergerfake.EnvVarManager
VolumeMgr *mergerfake.VolumeManager
Tpl v1.PodTemplateSpec
EnvVarMgr *mergerfake.EnvVarManager
VolumeMgr *mergerfake.VolumeManager
SecurityContextMgr *mergerfake.SecurityContextManager
AnnotationMgr *mergerfake.AnnotationManager
}

// EnvVar provides a mock function with given fields:
Expand All @@ -31,10 +33,22 @@ func (_m *PodTemplateManagers) Volume() merger.VolumeManager {
return _m.VolumeMgr
}

// SecurityContext provides a mock function with given fields:
func (_m *PodTemplateManagers) SecurityContext() merger.SecurityContextManager {
return _m.SecurityContextMgr
}

// Annotation provides a mock function with given fields:
func (_m *PodTemplateManagers) Annotation() merger.AnnotationManager {
return _m.AnnotationMgr
}

// NewPodTemplateManagers creates a new instance of PodTemplateManagers. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations.
func NewPodTemplateManagers(t testing.TB) *PodTemplateManagers {
return &PodTemplateManagers{
EnvVarMgr: mergerfake.NewFakeEnvVarManager(t),
VolumeMgr: mergerfake.NewFakeVolumeManager(t),
EnvVarMgr: mergerfake.NewFakeEnvVarManager(t),
VolumeMgr: mergerfake.NewFakeVolumeManager(t),
SecurityContextMgr: mergerfake.NewFakeSecurityContextManager(t),
AnnotationMgr: mergerfake.NewFakeAnnotationManager(t),
}
}
2 changes: 2 additions & 0 deletions controllers/datadogagent/feature/ids.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const (
LogCollectionIDType
// NPMIDType NPM feature.
NPMIDType
// USMIDType USM feature.
USMIDType
// OOMKillIDType OOM Kill check feature
OOMKillIDType
// TCPQueueLengthIDType TCP Queue length check feature
Expand Down
40 changes: 35 additions & 5 deletions controllers/datadogagent/feature/npm/feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,22 @@ func (f *npmFeature) ManageClusterAgent(managers feature.PodTemplateManagers) er
// 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 *npmFeature) ManageNodeAgent(managers feature.PodTemplateManagers) error {
// annotations
managers.Annotation().AddAnnotation(apicommon.SystemProbeAppArmorAnnotationKey, apicommon.SystemProbeAppArmorAnnotationValue)

// security context capabilities
capabilities := []corev1.Capability{
"SYS_ADMIN",
"SYS_RESOURCE",
"SYS_PTRACE",
"NET_ADMIN",
"NET_BROADCAST",
"NET_RAW",
"IPC_LOCK",
"CHOWN",
}
managers.SecurityContext().AddCapabilitiesToContainer(capabilities, apicommonv1.SystemProbeContainerName)

// procdir volume mount
procdirVol, procdirVolMount := volume.GetVolumes(apicommon.ProcdirVolumeName, apicommon.ProcdirHostPath, apicommon.ProcdirMountPath, true)
managers.Volume().AddVolumeToContainers(&procdirVol, &procdirVolMount, []apicommonv1.AgentContainerName{apicommonv1.ProcessAgentContainerName, apicommonv1.SystemProbeContainerName})
Expand All @@ -97,12 +113,19 @@ func (f *npmFeature) ManageNodeAgent(managers feature.PodTemplateManagers) error
managers.Volume().AddVolumeToContainers(&cgroupsVol, &cgroupsVolMount, []apicommonv1.AgentContainerName{apicommonv1.ProcessAgentContainerName, apicommonv1.SystemProbeContainerName})

// debugfs volume mount
debugfsVol, debugfsVolMount := volume.GetVolumes(apicommon.DebugfsVolumeName, apicommon.DebugfsVolumePath, apicommon.DebugfsVolumePath, true)
debugfsVol, debugfsVolMount := volume.GetVolumes(apicommon.DebugfsVolumeName, apicommon.DebugfsPath, apicommon.DebugfsPath, true)
managers.Volume().AddVolumeToContainers(&debugfsVol, &debugfsVolMount, []apicommonv1.AgentContainerName{apicommonv1.ProcessAgentContainerName, apicommonv1.SystemProbeContainerName})

// socket volume mount
socketVol, socketVolMount := volume.GetVolumes(apicommon.SysprobeSocketVolumeName, apicommon.SysprobeSocketVolumePath, apicommon.SysprobeSocketVolumePath, true)
managers.Volume().AddVolumeToContainers(&socketVol, &socketVolMount, []apicommonv1.AgentContainerName{apicommonv1.ProcessAgentContainerName, apicommonv1.SystemProbeContainerName})
socketVol, socketVolMount := volume.GetVolumesEmptyDir(apicommon.SystemProbeSocketVolumeName, apicommon.SystemProbeSocketVolumePath)
managers.Volume().AddVolumeToContainers(
&socketVol,
&socketVolMount,
[]apicommonv1.AgentContainerName{
apicommonv1.CoreAgentContainerName,
apicommonv1.ProcessAgentContainerName,
apicommonv1.SystemProbeContainerName,
})

// env vars
enableEnvVar := &corev1.EnvVar{
Expand All @@ -120,8 +143,8 @@ func (f *npmFeature) ManageNodeAgent(managers feature.PodTemplateManagers) error
managers.EnvVar().AddEnvVarToContainer(apicommonv1.SystemProbeContainerName, sysProbeEnableEnvVar)

socketEnvVar := &corev1.EnvVar{
Name: apicommon.DDSystemProbeSocketEnvVar,
Value: apicommon.DefaultSysprobeSocketPath,
Name: apicommon.DDSystemProbeSocket,
Value: apicommon.DefaultSystemProbeSocketPath,
}

managers.EnvVar().AddEnvVarToContainer(apicommonv1.ProcessAgentContainerName, socketEnvVar)
Expand All @@ -135,6 +158,13 @@ func (f *npmFeature) ManageNodeAgent(managers feature.PodTemplateManagers) error
managers.EnvVar().AddEnvVarToContainer(apicommonv1.ProcessAgentContainerName, processEnvVar)
managers.EnvVar().AddEnvVarToContainer(apicommonv1.SystemProbeContainerName, processEnvVar)

// env vars for Process Agent only
sysProbeExternalEnvVar := &corev1.EnvVar{
Name: apicommon.DDSystemProbeExternal,
Value: "true",
}
managers.EnvVar().AddEnvVarToContainer(apicommonv1.ProcessAgentContainerName, sysProbeExternalEnvVar)

return nil
}

Expand Down
62 changes: 48 additions & 14 deletions controllers/datadogagent/feature/npm/feature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,26 @@ func Test_npmFeature_Configure(t *testing.T) {
npmAgentNodeWantFunc := func(t testing.TB, mgrInterface feature.PodTemplateManagers) {
mgr := mgrInterface.(*fake.PodTemplateManagers)

// check annotations
wantAnnotations := make(map[string]string)
wantAnnotations[apicommon.SystemProbeAppArmorAnnotationKey] = apicommon.SystemProbeAppArmorAnnotationValue
annotations := mgr.AnnotationMgr.Annotations
assert.True(t, apiutils.IsEqualStruct(annotations, wantAnnotations), "Annotations \ndiff = %s", cmp.Diff(annotations, wantAnnotations))

// check security context capabilities
wantCapabilities := []corev1.Capability{
"SYS_ADMIN",
"SYS_RESOURCE",
"SYS_PTRACE",
"NET_ADMIN",
"NET_BROADCAST",
"NET_RAW",
"IPC_LOCK",
"CHOWN",
}
sysProbeCapabilities := mgr.SecurityContextMgr.CapabilitiesByC[apicommonv1.SystemProbeContainerName]
assert.True(t, apiutils.IsEqualStruct(sysProbeCapabilities, wantCapabilities), "System Probe security context capabilities \ndiff = %s", cmp.Diff(sysProbeCapabilities, wantCapabilities))

// check volume mounts
wantVolumeMounts := []corev1.VolumeMount{
{
Expand All @@ -73,12 +93,12 @@ func Test_npmFeature_Configure(t *testing.T) {
},
{
Name: apicommon.DebugfsVolumeName,
MountPath: apicommon.DebugfsVolumePath,
MountPath: apicommon.DebugfsPath,
ReadOnly: true,
},
{
Name: apicommon.SysprobeSocketVolumeName,
MountPath: apicommon.SysprobeSocketVolumePath,
Name: apicommon.SystemProbeSocketVolumeName,
MountPath: apicommon.SystemProbeSocketVolumePath,
ReadOnly: true,
},
}
Expand All @@ -89,6 +109,16 @@ func Test_npmFeature_Configure(t *testing.T) {
sysProbeAgentMounts := mgr.VolumeMgr.VolumeMountByC[apicommonv1.SystemProbeContainerName]
assert.True(t, apiutils.IsEqualStruct(sysProbeAgentMounts, wantVolumeMounts), "System Probe volume mounts \ndiff = %s", cmp.Diff(sysProbeAgentMounts, wantVolumeMounts))

coreWantVolumeMounts := []corev1.VolumeMount{
{
Name: apicommon.SystemProbeSocketVolumeName,
MountPath: apicommon.SystemProbeSocketVolumePath,
ReadOnly: true,
},
}
coreAgentMounts := mgr.VolumeMgr.VolumeMountByC[apicommonv1.CoreAgentContainerName]
assert.True(t, apiutils.IsEqualStruct(coreAgentMounts, coreWantVolumeMounts), "Core Agent volume mounts \ndiff = %s", cmp.Diff(coreAgentMounts, coreWantVolumeMounts))

// check volumes
wantVolumes := []corev1.Volume{
{
Expand All @@ -111,16 +141,14 @@ func Test_npmFeature_Configure(t *testing.T) {
Name: apicommon.DebugfsVolumeName,
VolumeSource: corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: apicommon.DebugfsVolumePath,
Path: apicommon.DebugfsPath,
},
},
},
{
Name: apicommon.SysprobeSocketVolumeName,
Name: apicommon.SystemProbeSocketVolumeName,
VolumeSource: corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: apicommon.SysprobeSocketVolumePath,
},
EmptyDir: &corev1.EmptyDirVolumeSource{},
},
},
}
Expand All @@ -129,7 +157,7 @@ func Test_npmFeature_Configure(t *testing.T) {
assert.True(t, apiutils.IsEqualStruct(volumes, wantVolumes), "Volumes \ndiff = %s", cmp.Diff(volumes, wantVolumes))

// check env vars
wantEnvVars := []*corev1.EnvVar{
sysProbeWantEnvVars := []*corev1.EnvVar{
{
Name: apicommon.DDSystemProbeNPMEnabledEnvVar,
Value: "true",
Expand All @@ -139,19 +167,25 @@ func Test_npmFeature_Configure(t *testing.T) {
Value: "true",
},
{
Name: apicommon.DDSystemProbeSocketEnvVar,
Value: apicommon.DefaultSysprobeSocketPath,
Name: apicommon.DDSystemProbeSocket,
Value: apicommon.DefaultSystemProbeSocketPath,
},
{
Name: apicommon.DDProcessAgentEnabledEnvVar,
Value: "true",
},
}
systemProbeEnvVars := mgr.EnvVarMgr.EnvVarsByC[apicommonv1.SystemProbeContainerName]
assert.True(t, apiutils.IsEqualStruct(systemProbeEnvVars, sysProbeWantEnvVars), "System Probe envvars \ndiff = %s", cmp.Diff(systemProbeEnvVars, sysProbeWantEnvVars))

processWantEnvVars := append(sysProbeWantEnvVars, &corev1.EnvVar{
Name: apicommon.DDSystemProbeExternal,
Value: "true",
})

processAgentEnvVars := mgr.EnvVarMgr.EnvVarsByC[apicommonv1.ProcessAgentContainerName]
assert.True(t, apiutils.IsEqualStruct(processAgentEnvVars, wantEnvVars), "Process Agent envvars \ndiff = %s", cmp.Diff(processAgentEnvVars, wantEnvVars))
assert.True(t, apiutils.IsEqualStruct(processAgentEnvVars, processWantEnvVars), "Process Agent envvars \ndiff = %s", cmp.Diff(processAgentEnvVars, processWantEnvVars))

systemProbeEnvVars := mgr.EnvVarMgr.EnvVarsByC[apicommonv1.SystemProbeContainerName]
assert.True(t, apiutils.IsEqualStruct(systemProbeEnvVars, wantEnvVars), "System Probe envvars \ndiff = %s", cmp.Diff(systemProbeEnvVars, wantEnvVars))
}

tests := test.FeatureTestSuite{
Expand Down
2 changes: 1 addition & 1 deletion controllers/datadogagent/feature/test/testsuite.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func runTest(t *testing.T, tt FeatureTest, buildFunc feature.BuildFunc) {
}

if gotConfigure.IsEnabled() != tt.WantConfigure {
t.Errorf("ksmFeature.Configure() = %v, want %v", gotConfigure, tt.WantConfigure)
t.Errorf("feature.Configure() = %v, want %v", gotConfigure, tt.WantConfigure)
}

if !gotConfigure.IsEnabled() {
Expand Down

0 comments on commit c32af59

Please sign in to comment.