Skip to content

Commit 5e57ad1

Browse files
authored
feat(config): add infrastructure mode overrides for EUDM (#43059)
### What does this PR do? Adds a new configuration override for **End User Device Mode (EUDM)** in the Agent setup. When the infrastructure mode is set to `end_user_device`, the following features are automatically enabled by default: - **Live Processes** - **Software Inventory** - **Notable Events** ### Motivation EUDM requires key observability features to be active by default to provide complete visibility into end-user devices. This change ensures a consistent configuration experience without additional manual setup. #### How did you validate this change? - Verified that setting `infrastructure_mode: end_user_device` enables the expected runtime configurations: - `process_config.process_collection.enabled = true` - `software_inventory.enabled = true` - `notable_events.enabled = true` - Confirmed that other infrastructure modes (`full`, `basic`) remain unaffected. #### Additional Notes - Default behavior for existing modes is unchanged. - This addition ensures feature parity and ease of use for EUDM environments. Co-authored-by: louis.coquerelle <[email protected]>
1 parent 87b1d73 commit 5e57ad1

File tree

7 files changed

+66
-24
lines changed

7 files changed

+66
-24
lines changed

comp/core/settings/settingsimpl/settingsimpl_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ func TestRuntimeSettings(t *testing.T) {
311311
// simply compare strings.
312312
expected := map[string]interface{}{}
313313
actual := map[string]interface{}{}
314-
json.Unmarshal([]byte("{\"value\":{\"Value\":\"\",\"Source\":\"\"},\"sources_value\":[{\"Source\":\"default\",\"Value\":null},{\"Source\":\"unknown\",\"Value\":null},{\"Source\":\"file\",\"Value\":null},{\"Source\":\"environment-variable\",\"Value\":null},{\"Source\":\"fleet-policies\",\"Value\":null},{\"Source\":\"agent-runtime\",\"Value\":null},{\"Source\":\"local-config-process\",\"Value\":null},{\"Source\":\"remote-config\",\"Value\":null},{\"Source\":\"cli\",\"Value\":null}]}"), &expected)
314+
json.Unmarshal([]byte("{\"value\":{\"Value\":\"\",\"Source\":\"\"},\"sources_value\":[{\"Source\":\"default\",\"Value\":null},{\"Source\":\"unknown\",\"Value\":null},{\"Source\":\"infra-mode\",\"Value\":null},{\"Source\":\"file\",\"Value\":null},{\"Source\":\"environment-variable\",\"Value\":null},{\"Source\":\"fleet-policies\",\"Value\":null},{\"Source\":\"agent-runtime\",\"Value\":null},{\"Source\":\"local-config-process\",\"Value\":null},{\"Source\":\"remote-config\",\"Value\":null},{\"Source\":\"cli\",\"Value\":null}]}"), &expected)
315315
err = json.Unmarshal(body, &actual)
316316

317317
require.NoError(t, err, fmt.Sprintf("error loading JSON body: %s", err))

pkg/config/model/types.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ const (
3333
// SourceUnknown are the values from unknown source. This should only be used in tests when calling
3434
// SetWithoutSource.
3535
SourceUnknown Source = "unknown"
36+
// SourceInfraMode are the values set by infrastructure mode configurations. These values have higher
37+
// priority than defaults but lower priority than user configuration (file, env vars, etc.).
38+
SourceInfraMode Source = "infra-mode"
3639
// SourceFile are the values loaded from configuration file.
3740
SourceFile Source = "file"
3841
// SourceEnvVar are the values loaded from the environment variables.
@@ -58,6 +61,7 @@ const (
5861
var Sources = []Source{
5962
SourceDefault,
6063
SourceUnknown,
64+
SourceInfraMode,
6165
SourceFile,
6266
SourceEnvVar,
6367
SourceFleetPolicies,
@@ -73,13 +77,14 @@ var sourcesPriority = map[Source]int{
7377
SourceSchema: -1,
7478
SourceDefault: 0,
7579
SourceUnknown: 1,
76-
SourceFile: 2,
77-
SourceEnvVar: 3,
78-
SourceFleetPolicies: 4,
79-
SourceAgentRuntime: 5,
80-
SourceLocalConfigProcess: 6,
81-
SourceRC: 7,
82-
SourceCLI: 8,
80+
SourceInfraMode: 2,
81+
SourceFile: 3,
82+
SourceEnvVar: 4,
83+
SourceFleetPolicies: 5,
84+
SourceAgentRuntime: 6,
85+
SourceLocalConfigProcess: 7,
86+
SourceRC: 8,
87+
SourceCLI: 9,
8388
}
8489

8590
// ValueWithSource is a tuple for a source and a value, not necessarily the applied value in the main config

pkg/config/nodetreemodel/config.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
var sources = []model.Source{
3131
model.SourceDefault,
3232
model.SourceUnknown,
33+
model.SourceInfraMode,
3334
model.SourceFile,
3435
model.SourceEnvVar,
3536
model.SourceFleetPolicies,
@@ -82,6 +83,8 @@ type ntmConfig struct {
8283
defaults *nodeImpl
8384
// unknown contains the settings set at runtime from unknown source. This should only evey be used by tests.
8485
unknown *nodeImpl
86+
// infraMode contains the settings set by infrastructure mode configurations
87+
infraMode *nodeImpl
8588
// file contains the settings pulled from YAML files
8689
file *nodeImpl
8790
// envs contains config settings created by environment variables
@@ -167,6 +170,8 @@ func (c *ntmConfig) getTreeBySource(source model.Source) (*nodeImpl, error) {
167170
return c.defaults, nil
168171
case model.SourceUnknown:
169172
return c.unknown, nil
173+
case model.SourceInfraMode:
174+
return c.infraMode, nil
170175
case model.SourceFile:
171176
return c.file, nil
172177
case model.SourceEnvVar:
@@ -935,6 +940,7 @@ func (c *ntmConfig) AllSettingsBySource() map[model.Source]interface{} {
935940
return map[model.Source]interface{}{
936941
model.SourceDefault: c.defaults.DumpSettings(func(model.Source) bool { return true }),
937942
model.SourceUnknown: c.unknown.DumpSettings(func(model.Source) bool { return true }),
943+
model.SourceInfraMode: c.infraMode.DumpSettings(func(model.Source) bool { return true }),
938944
model.SourceFile: c.file.DumpSettings(func(model.Source) bool { return true }),
939945
model.SourceEnvVar: c.envs.DumpSettings(func(model.Source) bool { return true }),
940946
model.SourceFleetPolicies: c.fleetPolicies.DumpSettings(func(model.Source) bool { return true }),
@@ -1075,6 +1081,7 @@ func NewNodeTreeConfig(name string, envPrefix string, envKeyReplacer *strings.Re
10751081
defaults: newInnerNode(nil),
10761082
file: newInnerNode(nil),
10771083
unknown: newInnerNode(nil),
1084+
infraMode: newInnerNode(nil),
10781085
envs: newInnerNode(nil),
10791086
runtime: newInnerNode(nil),
10801087
localConfigProcess: newInnerNode(nil),

pkg/config/nodetreemodel/config_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,8 @@ func TestAllSettingsBySource(t *testing.T) {
333333
},
334334
"x": 123,
335335
},
336-
model.SourceUnknown: map[string]interface{}{},
336+
model.SourceUnknown: map[string]interface{}{},
337+
model.SourceInfraMode: map[string]interface{}{},
337338
model.SourceFile: map[string]interface{}{
338339
"a": 987,
339340
},

pkg/config/nodetreemodel/getter_test.go

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -306,32 +306,34 @@ func TestGetFloat64SliceStringFromEnv(t *testing.T) {
306306
}
307307

308308
func TestGetAllSources(t *testing.T) {
309-
t.Setenv("TEST_A", "3")
309+
t.Setenv("TEST_A", "4")
310310

311311
cfg := NewNodeTreeConfig("test", "TEST", nil)
312312
cfg.BindEnvAndSetDefault("a", 0)
313313
cfg.BuildSchema()
314314

315315
cfg.Set("a", 1, model.SourceUnknown)
316-
cfg.Set("a", 2, model.SourceFile)
317-
cfg.Set("a", 4, model.SourceFleetPolicies)
318-
cfg.Set("a", 5, model.SourceAgentRuntime)
319-
cfg.Set("a", 6, model.SourceLocalConfigProcess)
320-
cfg.Set("a", 7, model.SourceRC)
321-
cfg.Set("a", 8, model.SourceCLI)
316+
cfg.Set("a", 2, model.SourceInfraMode)
317+
cfg.Set("a", 3, model.SourceFile)
318+
cfg.Set("a", 5, model.SourceFleetPolicies)
319+
cfg.Set("a", 6, model.SourceAgentRuntime)
320+
cfg.Set("a", 7, model.SourceLocalConfigProcess)
321+
cfg.Set("a", 8, model.SourceRC)
322+
cfg.Set("a", 9, model.SourceCLI)
322323

323324
res := cfg.GetAllSources("a")
324325
assert.Equal(t,
325326
[]model.ValueWithSource{
326327
{Source: model.SourceDefault, Value: 0},
327328
{Source: model.SourceUnknown, Value: 1},
328-
{Source: model.SourceFile, Value: 2},
329-
{Source: model.SourceEnvVar, Value: "3"},
330-
{Source: model.SourceFleetPolicies, Value: 4},
331-
{Source: model.SourceAgentRuntime, Value: 5},
332-
{Source: model.SourceLocalConfigProcess, Value: 6},
333-
{Source: model.SourceRC, Value: 7},
334-
{Source: model.SourceCLI, Value: 8},
329+
{Source: model.SourceInfraMode, Value: 2},
330+
{Source: model.SourceFile, Value: 3},
331+
{Source: model.SourceEnvVar, Value: "4"},
332+
{Source: model.SourceFleetPolicies, Value: 5},
333+
{Source: model.SourceAgentRuntime, Value: 6},
334+
{Source: model.SourceLocalConfigProcess, Value: 7},
335+
{Source: model.SourceRC, Value: 8},
336+
{Source: model.SourceCLI, Value: 9},
335337
},
336338
res,
337339
)

pkg/config/setup/config.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1317,7 +1317,7 @@ func agent(config pkgconfigmodel.Setup) {
13171317

13181318
// Infrastructure mode
13191319
// The infrastructure mode is used to determine the features that are available to the agent.
1320-
// The possible values are: full, basic.
1320+
// The possible values are: full, basic, end_user_device.
13211321
config.BindEnvAndSetDefault("infrastructure_mode", "full")
13221322

13231323
// Infrastructure basic mode - allowed checks (UNDOCUMENTED)
@@ -1392,6 +1392,7 @@ func agent(config pkgconfigmodel.Setup) {
13921392
bindEnvAndSetLogsConfigKeys(config, "event_management.forwarder.")
13931393

13941394
pkgconfigmodel.AddOverrideFunc(toggleDefaultPayloads)
1395+
pkgconfigmodel.AddOverrideFunc(applyInfrastructureModeOverrides)
13951396
}
13961397

13971398
func fleet(config pkgconfigmodel.Setup) {
@@ -2767,6 +2768,17 @@ func toggleDefaultPayloads(config pkgconfigmodel.Config) {
27672768
}
27682769
}
27692770

2771+
func applyInfrastructureModeOverrides(config pkgconfigmodel.Config) {
2772+
infraMode := config.GetString("infrastructure_mode")
2773+
2774+
if infraMode == "end_user_device" {
2775+
// Enable features for end_user_device mode
2776+
config.Set("process_config.process_collection.enabled", true, pkgconfigmodel.SourceInfraMode)
2777+
config.Set("software_inventory.enabled", true, pkgconfigmodel.SourceInfraMode)
2778+
config.Set("notable_events.enabled", true, pkgconfigmodel.SourceInfraMode)
2779+
}
2780+
}
2781+
27702782
func bindEnvAndSetLogsConfigKeys(config pkgconfigmodel.Setup, prefix string) {
27712783
config.BindEnv(prefix + "logs_dd_url") //nolint:forbidigo // TODO: replace by 'SetDefaultAndBindEnv' // Send the logs to a proxy. Must respect format '<HOST>:<PORT>' and '<PORT>' to be an integer
27722784
config.BindEnv(prefix + "dd_url") //nolint:forbidigo // TODO: replace by 'SetDefaultAndBindEnv'
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Each section from every release note are combined when the
2+
# CHANGELOG.rst is rendered. So the text needs to be worded so that
3+
# it does not depend on any information only available in another
4+
# section. This may mean repeating some details, but each section
5+
# must be readable independently of the other.
6+
#
7+
# Each section note must be formatted as reStructuredText.
8+
---
9+
features:
10+
- |
11+
Added support for ``infrastructure_mode: end_user_device`` configuration option.
12+
When enabled, this mode automatically activates key monitoring features tailored for
13+
end-user devices including process collection, software inventory tracking, and
14+
notable events monitoring. These settings can still be individually overridden in
15+
the configuration file if needed.

0 commit comments

Comments
 (0)