Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[USM] Add envoy configuration value #27216

Closed
wants to merge 36 commits into from
Closed
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
1 change: 1 addition & 0 deletions pkg/config/setup/system_probe.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ func InitSystemProbeConfig(cfg pkgconfigmodel.Config) {
cfg.BindEnvAndSetDefault(join(smNS, "enable_kafka_monitoring"), false)
cfg.BindEnv(join(smNS, "enable_postgres_monitoring"))
cfg.BindEnvAndSetDefault(join(smNS, "tls", "istio", "enabled"), false)
cfg.BindEnv(join(smNS, "tls", "istio", "envoy_path"))
cfg.BindEnv(join(smNS, "tls", "nodejs", "enabled"))
cfg.BindEnvAndSetDefault(join(smjtNS, "enabled"), false)
cfg.BindEnvAndSetDefault(join(smjtNS, "debug"), false)
Expand Down
4 changes: 4 additions & 0 deletions pkg/network/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ type Config struct {
// EnableIstioMonitoring specifies whether USM should monitor Istio traffic
EnableIstioMonitoring bool

// EnvoyPath specifies the envoy path to be used for Istio monitoring
EnvoyPath string

// EnableNodeJSMonitoring specifies whether USM should monitor NodeJS TLS traffic
EnableNodeJSMonitoring bool

Expand Down Expand Up @@ -356,6 +359,7 @@ func New() *Config {
EnablePostgresMonitoring: cfg.GetBool(join(smNS, "enable_postgres_monitoring")),
EnableNativeTLSMonitoring: cfg.GetBool(join(smNS, "tls", "native", "enabled")),
EnableIstioMonitoring: cfg.GetBool(join(smNS, "tls", "istio", "enabled")),
EnvoyPath: cfg.GetString(join(smNS, "tls", "istio", "envoy_path")),
EnableNodeJSMonitoring: cfg.GetBool(join(smNS, "tls", "nodejs", "enabled")),
MaxUSMConcurrentRequests: uint32(cfg.GetInt(join(smNS, "max_concurrent_requests"))),
MaxHTTPStatsBuffered: cfg.GetInt(join(smNS, "max_http_stats_buffered")),
Expand Down
27 changes: 27 additions & 0 deletions pkg/network/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1342,6 +1342,33 @@ service_monitoring_config:
})
}

func TestEnvoyPathConfig(t *testing.T) {
t.Run("default value", func(t *testing.T) {
aconfig.ResetSystemProbeConfig(t)
cfg := New()
assert.Empty(t, cfg.EnvoyPath)
})

t.Run("via yaml", func(t *testing.T) {
aconfig.ResetSystemProbeConfig(t)
cfg := configurationFromYAML(t, `
service_monitoring_config:
tls:
istio:
envoy_path: "/test/envoy"
`)
assert.EqualValues(t, "/test/envoy", cfg.EnvoyPath)
})

t.Run("value set through env var", func(t *testing.T) {
aconfig.ResetSystemProbeConfig(t)
t.Setenv("DD_SERVICE_MONITORING_CONFIG_TLS_ISTIO_ENVOY_PATH", "/test/envoy")

cfg := New()
assert.EqualValues(t, "/test/envoy", cfg.EnvoyPath)
})
}

func TestNodeJSMonitoring(t *testing.T) {
t.Run("default value", func(t *testing.T) {
aconfig.ResetSystemProbeConfig(t)
Expand Down
27 changes: 19 additions & 8 deletions pkg/network/usm/istio.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ import (
const (
istioSslReadRetprobe = "istio_uretprobe__SSL_read"
istioSslWriteRetprobe = "istio_uretprobe__SSL_write"
// envoyCmd represents the search term used for determining
// whether or not a given PID represents an Envoy process.
// The search is done over the /proc/<pid>/cmdline file.
envoyCmd = "/bin/envoy"
)

var istioProbes = []manager.ProbesSelector{
Expand Down Expand Up @@ -76,11 +80,6 @@ var istioProbes = []manager.ProbesSelector{
},
}

// envoyCmd represents the search term used for determining
// whether or not a given PID represents an Envoy process.
// The search is done over the /proc/<pid>/cmdline file.
var envoyCmd = []byte("/bin/envoy")

// readBufferPool is used for reading /proc/<pid>/cmdline files.
// We use a pointer to a slice to avoid allocations when casting
// values to the empty interface during Put() calls.
Expand All @@ -95,6 +94,7 @@ var readBufferPool = ddsync.NewSlicePool[byte](128, 128)
type istioMonitor struct {
registry *utils.FileRegistry
procRoot string
envoyCmd string

// `utils.FileRegistry` callbacks
registerCB func(utils.FilePath) error
Expand All @@ -114,9 +114,14 @@ func newIstioMonitor(c *config.Config, mgr *manager.Manager) *istioMonitor {
}

procRoot := kernel.ProcFSRoot()
envoyCommand := envoyCmd
if c.EnvoyPath != "" {
envoyCommand = c.EnvoyPath
}
return &istioMonitor{
registry: utils.NewFileRegistry("istio"),
procRoot: procRoot,
envoyCmd: envoyCommand,
done: make(chan struct{}),

// Callbacks
Expand Down Expand Up @@ -271,7 +276,7 @@ func (m *istioMonitor) getEnvoyPath(pid uint32) string {
}
defer f.Close()

// From here on we shouldn't allocate for the common case
// From here on we shouldn't allocate for the common case.
// (eg., a process is *not* envoy)
bufferPtr := readBufferPool.Get()
defer func() {
Expand All @@ -285,11 +290,17 @@ func (m *istioMonitor) getEnvoyPath(pid uint32) string {
}

buffer = buffer[:n]
i := bytes.Index(buffer, envoyCmd)
envoyPath, err := os.Readlink(m.envoyCmd)
// if there is no error, it means that we were able to find the correct envoy path.
if err == nil {
m.envoyCmd = envoyPath
}

i := bytes.Index(buffer, []byte(m.envoyCmd))
if i < 0 {
return ""
}

executable := buffer[:i+len(envoyCmd)]
executable := buffer[:i+len([]byte(m.envoyCmd))]
return string(executable)
}
32 changes: 32 additions & 0 deletions pkg/network/usm/istio_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ func TestGetEnvoyPath(t *testing.T) {
})
}

func TestGetEnvoyPathWithConfig(t *testing.T) {
t.Setenv("DD_SERVICE_MONITORING_CONFIG_TLS_ISTIO_ENVOY_PATH", "/envoy")

_ = createFakeProcFS(t)
monitor := newIstioTestMonitor(t)

t.Run("an actual envoy process", func(t *testing.T) {
path := monitor.getEnvoyPath(uint32(4))
assert.Equal(t, "/usr/local/envoy", path)
})
}

func TestIstioSync(t *testing.T) {
t.Run("calling sync for the first time", func(t *testing.T) {
procRoot := createFakeProcFS(t)
Expand Down Expand Up @@ -160,6 +172,16 @@ func createFakeProcFS(t *testing.T) (procRoot string) {
"--allow-unknown-static-fields" +
"--log-format"

const envoyTestCmdline = "/usr/local/envoy" +
"-cetc/istio/proxy/envoy-rev.json" +
"--drain-time-s45" +
"--drain-strategyimmediate" +
"--local-address-ip-versionv4" +
"--file-flush-interval-msec1000" +
"--disable-hot-restart" +
"--allow-unknown-static-fields" +
"--log-format"

// PID 1
createFile(t,
filepath.Join(procRoot, "1", "cmdline"),
Expand All @@ -186,6 +208,16 @@ func createFakeProcFS(t *testing.T) (procRoot string) {
"",
)

// PID 4
createFile(t,
filepath.Join(procRoot, "4", "cmdline"),
envoyTestCmdline,
)
createFile(t,
filepath.Join(procRoot, "4", "root/usr/local/envoy"),
"",
)

return
}

Expand Down
1 change: 1 addition & 0 deletions t.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
55
1 change: 1 addition & 0 deletions test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test2
Loading