diff --git a/cmd/system-probe/modules/eventmonitor.go b/cmd/system-probe/modules/eventmonitor.go index cec624ea3f746d..d94555cddd9397 100644 --- a/cmd/system-probe/modules/eventmonitor.go +++ b/cmd/system-probe/modules/eventmonitor.go @@ -48,7 +48,7 @@ func createEventMonitorModule(_ *sysconfigtypes.Config, deps module.FactoryDepen } if secconfig.RuntimeSecurity.IsRuntimeEnabled() { - cws, err := secmodule.NewCWSConsumer(evm, secconfig.RuntimeSecurity, secmoduleOpts) + cws, err := secmodule.NewCWSConsumer(evm, secconfig.RuntimeSecurity, deps.WMeta, secmoduleOpts) if err != nil { return nil, err } diff --git a/pkg/security/agent/agent.go b/pkg/security/agent/agent.go index 3d2fd1832d0b3c..60d71694f91880 100644 --- a/pkg/security/agent/agent.go +++ b/pkg/security/agent/agent.go @@ -37,7 +37,6 @@ type RuntimeSecurityAgent struct { connected *atomic.Bool eventReceived *atomic.Uint64 activityDumpReceived *atomic.Uint64 - telemetry *telemetry profContainersTelemetry *profContainersTelemetry endpoints *config.Endpoints cancel context.CancelFunc @@ -69,11 +68,6 @@ func (rsa *RuntimeSecurityAgent) Start(reporter common.RawReporter, endpoints *c go rsa.startActivityDumpStorageTelemetry(ctx) } - if rsa.telemetry != nil { - // Send Runtime Security Agent telemetry - go rsa.telemetry.run(ctx) - } - if rsa.profContainersTelemetry != nil { // Send Profiled Containers telemetry go rsa.profContainersTelemetry.run(ctx) diff --git a/pkg/security/agent/agent_nix.go b/pkg/security/agent/agent_nix.go index 5a051c9a125a1e..bc444d6f049fef 100644 --- a/pkg/security/agent/agent_nix.go +++ b/pkg/security/agent/agent_nix.go @@ -24,12 +24,6 @@ func NewRuntimeSecurityAgent(statsdClient statsd.ClientInterface, hostname strin return nil, err } - // on windows do no telemetry - telemetry, err := newTelemetry(statsdClient, wmeta) - if err != nil { - return nil, errors.New("failed to initialize the telemetry reporter") - } - profContainersTelemetry, err := newProfContainersTelemetry(statsdClient, wmeta, opts.LogProfiledWorkloads) if err != nil { return nil, errors.New("failed to initialize the profiled containers telemetry reporter") @@ -44,7 +38,6 @@ func NewRuntimeSecurityAgent(statsdClient statsd.ClientInterface, hostname strin return &RuntimeSecurityAgent{ client: client, hostname: hostname, - telemetry: telemetry, profContainersTelemetry: profContainersTelemetry, storage: storage, running: atomic.NewBool(false), diff --git a/pkg/security/agent/agent_windows.go b/pkg/security/agent/agent_windows.go index 54bd6862155e2f..3b1cad54f3e101 100644 --- a/pkg/security/agent/agent_windows.go +++ b/pkg/security/agent/agent_windows.go @@ -24,7 +24,6 @@ func NewRuntimeSecurityAgent(_ statsd.ClientInterface, hostname string, _ RSAOpt return &RuntimeSecurityAgent{ client: client, hostname: hostname, - telemetry: nil, storage: nil, running: atomic.NewBool(false), connected: atomic.NewBool(false), diff --git a/pkg/security/agent/status_provider_test.go b/pkg/security/agent/status_provider_test.go index 4c259193e5f67d..af26830e9f3dd0 100644 --- a/pkg/security/agent/status_provider_test.go +++ b/pkg/security/agent/status_provider_test.go @@ -18,7 +18,6 @@ func TestStatus(t *testing.T) { agent: &RuntimeSecurityAgent{ client: nil, hostname: "test", - telemetry: nil, storage: nil, running: atomic.NewBool(false), connected: atomic.NewBool(false), diff --git a/pkg/security/agent/telemetry_others.go b/pkg/security/agent/telemetry_others.go index d36f3e1aba54b2..10647951c734b2 100644 --- a/pkg/security/agent/telemetry_others.go +++ b/pkg/security/agent/telemetry_others.go @@ -10,10 +10,6 @@ package agent import "context" -type telemetry struct{} - -func (t *telemetry) run(_ context.Context) {} - type profContainersTelemetry struct{} func (t *profContainersTelemetry) registerProfiledContainer(_, _ string) {} diff --git a/pkg/security/module/cws.go b/pkg/security/module/cws.go index a5091b44ace950..4f2c298989e759 100644 --- a/pkg/security/module/cws.go +++ b/pkg/security/module/cws.go @@ -15,6 +15,7 @@ import ( "github.com/DataDog/datadog-go/v5/statsd" + workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" "github.com/DataDog/datadog-agent/pkg/eventmonitor" "github.com/DataDog/datadog-agent/pkg/security/config" "github.com/DataDog/datadog-agent/pkg/security/events" @@ -28,6 +29,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/security/secl/rules" "github.com/DataDog/datadog-agent/pkg/security/seclog" "github.com/DataDog/datadog-agent/pkg/security/serializers" + "github.com/DataDog/datadog-agent/pkg/security/telemetry" ) // CWSConsumer represents the system-probe module for the runtime security agent @@ -49,17 +51,19 @@ type CWSConsumer struct { ruleEngine *rulesmodule.RuleEngine selfTester *selftests.SelfTester reloader ReloaderInterface + crtelemetry *telemetry.ContainersRunningTelemetry } // NewCWSConsumer initializes the module with options -func NewCWSConsumer(evm *eventmonitor.EventMonitor, cfg *config.RuntimeSecurityConfig, opts Opts) (*CWSConsumer, error) { - ctx, cancelFnc := context.WithCancel(context.Background()) +func NewCWSConsumer(evm *eventmonitor.EventMonitor, cfg *config.RuntimeSecurityConfig, wmeta workloadmeta.Component, opts Opts) (*CWSConsumer, error) { + crtelemetry, err := telemetry.NewContainersRunningTelemetry(cfg, evm.StatsdClient, wmeta) + if err != nil { + return nil, err + } - var ( - selfTester *selftests.SelfTester - err error - ) + ctx, cancelFnc := context.WithCancel(context.Background()) + var selfTester *selftests.SelfTester if cfg.SelfTestEnabled { selfTester, err = selftests.NewSelfTester(cfg, evm.Probe) if err != nil { @@ -82,6 +86,7 @@ func NewCWSConsumer(evm *eventmonitor.EventMonitor, cfg *config.RuntimeSecurityC grpcServer: NewGRPCServer(family, address), selfTester: selfTester, reloader: NewReloader(), + crtelemetry: crtelemetry, } // set sender @@ -151,6 +156,11 @@ func (c *CWSConsumer) Start() error { c.wg.Add(1) go c.statsSender() + if c.crtelemetry != nil { + // Send containers running telemetry + go c.crtelemetry.Run(c.ctx) + } + seclog.Infof("runtime security started") // we can now wait for self test events diff --git a/pkg/security/module/opts.go b/pkg/security/module/opts.go index fd642eb438652d..984f0c3872142d 100644 --- a/pkg/security/module/opts.go +++ b/pkg/security/module/opts.go @@ -6,7 +6,9 @@ // Package module holds module related files package module -import "github.com/DataDog/datadog-agent/pkg/security/events" +import ( + "github.com/DataDog/datadog-agent/pkg/security/events" +) // Opts define module options type Opts struct { diff --git a/pkg/security/agent/telemetry_linux.go b/pkg/security/telemetry/containers_running_telemetry_linux.go similarity index 52% rename from pkg/security/agent/telemetry_linux.go rename to pkg/security/telemetry/containers_running_telemetry_linux.go index 71c5c41b864bde..3a325b7efa469a 100644 --- a/pkg/security/agent/telemetry_linux.go +++ b/pkg/security/telemetry/containers_running_telemetry_linux.go @@ -3,48 +3,42 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -// Package agent holds agent related files -package agent +package telemetry import ( "context" - "errors" "os" "time" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" + "github.com/DataDog/datadog-agent/pkg/security/config" "github.com/DataDog/datadog-agent/pkg/security/metrics" - "github.com/DataDog/datadog-agent/pkg/security/proto/api" - sectelemetry "github.com/DataDog/datadog-agent/pkg/security/telemetry" "github.com/DataDog/datadog-agent/pkg/util/log" "github.com/DataDog/datadog-go/v5/statsd" ) -// telemetry reports environment information (e.g containers running) when the runtime security component is running -type telemetry struct { - containers *sectelemetry.ContainersTelemetry - runtimeSecurityClient *RuntimeSecurityClient +// ContainersRunningTelemetry reports environment information (e.g containers running) when the runtime security component is running +type ContainersRunningTelemetry struct { + cfg *config.RuntimeSecurityConfig + containers *ContainersTelemetry } -func newTelemetry(statsdClient statsd.ClientInterface, wmeta workloadmeta.Component) (*telemetry, error) { - runtimeSecurityClient, err := NewRuntimeSecurityClient() +// NewContainersRunningTelemetry creates a new ContainersRunningTelemetry instance +func NewContainersRunningTelemetry(cfg *config.RuntimeSecurityConfig, statsdClient statsd.ClientInterface, wmeta workloadmeta.Component) (*ContainersRunningTelemetry, error) { + telemetrySender := NewSimpleTelemetrySenderFromStatsd(statsdClient) + containersTelemetry, err := NewContainersTelemetry(telemetrySender, wmeta) if err != nil { return nil, err } - telemetrySender := sectelemetry.NewSimpleTelemetrySenderFromStatsd(statsdClient) - containersTelemetry, err := sectelemetry.NewContainersTelemetry(telemetrySender, wmeta) - if err != nil { - return nil, err - } - - return &telemetry{ - containers: containersTelemetry, - runtimeSecurityClient: runtimeSecurityClient, + return &ContainersRunningTelemetry{ + cfg: cfg, + containers: containersTelemetry, }, nil } -func (t *telemetry) run(ctx context.Context) { +// Run starts the telemetry collection +func (t *ContainersRunningTelemetry) Run(ctx context.Context) { log.Info("started collecting Runtime Security Agent telemetry") defer log.Info("stopping Runtime Security Agent telemetry") @@ -63,33 +57,19 @@ func (t *telemetry) run(ctx context.Context) { } } -func (t *telemetry) fetchConfig() (*api.SecurityConfigMessage, error) { - cfg, err := t.runtimeSecurityClient.GetConfig() - if err != nil { - return cfg, errors.New("couldn't fetch config from runtime security module") - } - return cfg, nil -} - -func (t *telemetry) reportContainers() error { - // retrieve the runtime security module config - cfg, err := t.fetchConfig() - if err != nil { - return err - } - +func (t *ContainersRunningTelemetry) reportContainers() error { var fargate bool if os.Getenv("ECS_FARGATE") == "true" || os.Getenv("DD_ECS_FARGATE") == "true" || os.Getenv("DD_EKS_FARGATE") == "true" { fargate = true } var metricName string - if cfg.RuntimeEnabled { + if t.cfg.RuntimeEnabled { metricName = metrics.MetricSecurityAgentRuntimeContainersRunning if fargate { metricName = metrics.MetricSecurityAgentFargateRuntimeContainersRunning } - } else if cfg.FIMEnabled { + } else if t.cfg.FIMEnabled { metricName = metrics.MetricSecurityAgentFIMContainersRunning if fargate { metricName = metrics.MetricSecurityAgentFargateFIMContainersRunning diff --git a/pkg/security/telemetry/containers_running_telemetry_others.go b/pkg/security/telemetry/containers_running_telemetry_others.go new file mode 100644 index 00000000000000..3bb9658228d9a1 --- /dev/null +++ b/pkg/security/telemetry/containers_running_telemetry_others.go @@ -0,0 +1,27 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build !linux + +package telemetry + +import ( + "context" + + workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" + "github.com/DataDog/datadog-agent/pkg/security/config" + "github.com/DataDog/datadog-go/v5/statsd" +) + +// ContainersRunningTelemetry reports environment information (e.g containers running) when the runtime security component is running +type ContainersRunningTelemetry struct{} + +// NewContainersRunningTelemetry creates a new ContainersRunningTelemetry instance (not supported on non-linux platforms) +func NewContainersRunningTelemetry(_ *config.RuntimeSecurityConfig, _ statsd.ClientInterface, _ workloadmeta.Component) (*ContainersRunningTelemetry, error) { + return nil, nil +} + +// Run starts the telemetry collection +func (t *ContainersRunningTelemetry) Run(_ context.Context) {} diff --git a/pkg/security/tests/module_tester_linux.go b/pkg/security/tests/module_tester_linux.go index 07a3376d9398f4..da0946b338ce63 100644 --- a/pkg/security/tests/module_tester_linux.go +++ b/pkg/security/tests/module_tester_linux.go @@ -822,7 +822,7 @@ func newTestModuleWithOnDemandProbes(t testing.TB, onDemandHooks []rules.OnDeman if !opts.staticOpts.disableRuntimeSecurity { msgSender := newFakeMsgSender(testMod) - cws, err := module.NewCWSConsumer(testMod.eventMonitor, secconfig.RuntimeSecurity, module.Opts{EventSender: testMod, MsgSender: msgSender}) + cws, err := module.NewCWSConsumer(testMod.eventMonitor, secconfig.RuntimeSecurity, fxDeps.WMeta, module.Opts{EventSender: testMod, MsgSender: msgSender}) if err != nil { return nil, fmt.Errorf("failed to create module: %w", err) } diff --git a/pkg/security/tests/module_tester_windows.go b/pkg/security/tests/module_tester_windows.go index b2c6d20952a79a..972437a8ca4352 100644 --- a/pkg/security/tests/module_tester_windows.go +++ b/pkg/security/tests/module_tester_windows.go @@ -292,7 +292,7 @@ func newTestModule(t testing.TB, macroDefs []*rules.MacroDefinition, ruleDefs [] var ruleSetloadedErr *multierror.Error if !opts.staticOpts.disableRuntimeSecurity { - cws, err := module.NewCWSConsumer(testMod.eventMonitor, secconfig.RuntimeSecurity, module.Opts{EventSender: testMod}) + cws, err := module.NewCWSConsumer(testMod.eventMonitor, secconfig.RuntimeSecurity, fxDeps.WMeta, module.Opts{EventSender: testMod}) if err != nil { return nil, fmt.Errorf("failed to create module: %w", err) }