Skip to content

Commit 6c15654

Browse files
BinaryFissionGamesevan-bradleysrikanthccvtigrannajaryan
authored
[cmd/opampsupervisor] Receive and report effective config (#33462)
**Description:** Adds the ability to receive and run remote configurations from an OpAMP server, as well as to report the remote configuration status. This PR is just bringing #31641 up-to-date. **Link to tracking Issue:** Resolves #30622 **Testing:** <Describe what testing was performed and which tests were added.> Unit tests **Documentation:** <Describe the documentation added.> --------- Co-authored-by: Evan Bradley <[email protected]> Co-authored-by: Evan Bradley <[email protected]> Co-authored-by: Srikanth Chekuri <[email protected]> Co-authored-by: Tigran Najaryan <[email protected]>
1 parent f61e5c1 commit 6c15654

File tree

13 files changed

+452
-145
lines changed

13 files changed

+452
-145
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: cmd/opampsupervisor
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Receive and report effective config to the OpAMP server
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [30622]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: []

cmd/opampsupervisor/e2e_test.go

Lines changed: 85 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func (tl testLogger) Errorf(_ context.Context, format string, args ...any) {
5656
}
5757

5858
func defaultConnectingHandler(connectionCallbacks server.ConnectionCallbacksStruct) func(request *http.Request) types.ConnectionResponse {
59-
return func(request *http.Request) types.ConnectionResponse {
59+
return func(_ *http.Request) types.ConnectionResponse {
6060
return types.ConnectionResponse{
6161
Accept: true,
6262
ConnectionCallbacks: connectionCallbacks,
@@ -125,7 +125,8 @@ func newOpAMPServer(t *testing.T, connectingCallback onConnectingFuncFactory, ca
125125
require.Fail(t, "Agent connection has not been established")
126126
}
127127

128-
agentConn.Load().(types.Connection).Send(context.Background(), msg)
128+
err = agentConn.Load().(types.Connection).Send(context.Background(), msg)
129+
require.NoError(t, err)
129130
}
130131
t.Cleanup(func() {
131132
shutdown()
@@ -217,8 +218,9 @@ func TestSupervisorStartsCollectorWithRemoteConfig(t *testing.T) {
217218
cfg, ok := agentConfig.Load().(string)
218219
if ok {
219220
// The effective config may be structurally different compared to what was sent,
220-
// so just check that it includes some strings we know to be unique to the remote config.
221-
return strings.Contains(cfg, inputFile.Name()) && strings.Contains(cfg, outputFile.Name())
221+
// and will also have some data redacted,
222+
// so just check that it includes the filelog receiver
223+
return strings.Contains(cfg, "filelog")
222224
}
223225

224226
return false
@@ -340,9 +342,9 @@ func TestSupervisorConfiguresCapabilities(t *testing.T) {
340342
waitForSupervisorConnection(server.supervisorConnected, true)
341343

342344
require.Eventually(t, func() bool {
343-
cap := capabilities.Load()
345+
caps := capabilities.Load()
344346

345-
return cap == uint64(protobufs.AgentCapabilities_AgentCapabilities_ReportsStatus)
347+
return caps == uint64(protobufs.AgentCapabilities_AgentCapabilities_ReportsStatus)
346348
}, 5*time.Second, 250*time.Millisecond)
347349
}
348350

@@ -418,6 +420,82 @@ func TestSupervisorBootstrapsCollector(t *testing.T) {
418420
}, 5*time.Second, 250*time.Millisecond)
419421
}
420422

423+
func TestSupervisorReportsEffectiveConfig(t *testing.T) {
424+
var agentConfig atomic.Value
425+
server := newOpAMPServer(
426+
t,
427+
defaultConnectingHandler,
428+
server.ConnectionCallbacksStruct{
429+
OnMessageFunc: func(_ context.Context, _ types.Connection, message *protobufs.AgentToServer) *protobufs.ServerToAgent {
430+
if message.EffectiveConfig != nil {
431+
config := message.EffectiveConfig.ConfigMap.ConfigMap[""]
432+
if config != nil {
433+
agentConfig.Store(string(config.Body))
434+
}
435+
}
436+
437+
return &protobufs.ServerToAgent{}
438+
},
439+
})
440+
441+
s := newSupervisor(t, "basic", map[string]string{"url": server.addr})
442+
defer s.Shutdown()
443+
444+
waitForSupervisorConnection(server.supervisorConnected, true)
445+
446+
// Create input and output files so we can "communicate" with a Collector binary.
447+
// The testing package will automatically clean these up after each test.
448+
tempDir := t.TempDir()
449+
testKeyFile, err := os.CreateTemp(tempDir, "confKey")
450+
require.NoError(t, err)
451+
n, err := testKeyFile.Write([]byte(testKeyFile.Name()))
452+
require.NoError(t, err)
453+
require.NotZero(t, n)
454+
455+
colCfgTpl, err := os.ReadFile(path.Join("testdata", "collector", "split_config.yaml"))
456+
require.NoError(t, err)
457+
458+
templ, err := template.New("").Parse(string(colCfgTpl))
459+
require.NoError(t, err)
460+
461+
var cfg bytes.Buffer
462+
err = templ.Execute(
463+
&cfg,
464+
map[string]string{
465+
"TestKeyFile": testKeyFile.Name(),
466+
},
467+
)
468+
require.NoError(t, err)
469+
470+
h := sha256.New()
471+
if _, err := io.Copy(h, bytes.NewBuffer(cfg.Bytes())); err != nil {
472+
t.Fatal(err)
473+
}
474+
475+
server.sendToSupervisor(&protobufs.ServerToAgent{
476+
RemoteConfig: &protobufs.AgentRemoteConfig{
477+
Config: &protobufs.AgentConfigMap{
478+
ConfigMap: map[string]*protobufs.AgentConfigFile{
479+
"": {Body: cfg.Bytes()},
480+
},
481+
},
482+
ConfigHash: h.Sum(nil),
483+
},
484+
})
485+
486+
require.Eventually(t, func() bool {
487+
cfg, ok := agentConfig.Load().(string)
488+
if ok {
489+
// The effective config may be structurally different compared to what was sent,
490+
// and currently has most values redacted,
491+
// so just check that it includes some strings we know to be unique to the remote config.
492+
return strings.Contains(cfg, "test_key:")
493+
}
494+
495+
return false
496+
}, 5*time.Second, 500*time.Millisecond, "Collector never reported effective config")
497+
}
498+
421499
func TestSupervisorAgentDescriptionConfigApplies(t *testing.T) {
422500
// Load the Supervisor config so we can get the location of
423501
// the Collector that will be run.
@@ -673,7 +751,7 @@ func TestSupervisorOpAMPConnectionSettings(t *testing.T) {
673751
OnConnectedFunc: func(_ context.Context, _ types.Connection) {
674752
connectedToNewServer.Store(true)
675753
},
676-
OnMessageFunc: func(_ context.Context, _ types.Connection, message *protobufs.AgentToServer) *protobufs.ServerToAgent {
754+
OnMessageFunc: func(_ context.Context, _ types.Connection, _ *protobufs.AgentToServer) *protobufs.ServerToAgent {
677755
return &protobufs.ServerToAgent{}
678756
},
679757
})

cmd/opampsupervisor/examples/supervisor_darwin.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ server:
33
tls:
44
# Disable verification to test locally.
55
# Don't do this in production.
6-
insecure_skip_verify: true
6+
insecure_skip_verify: true
77
# For more TLS settings see config/configtls.ClientConfig
88

99
capabilities:
@@ -15,3 +15,6 @@ capabilities:
1515

1616
agent:
1717
executable: ../../bin/otelcontribcol_darwin_amd64
18+
19+
storage:
20+
directory: .

cmd/opampsupervisor/examples/supervisor_linux.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ server:
33
tls:
44
# Disable verification to test locally.
55
# Don't do this in production.
6-
insecure_skip_verify: true
6+
insecure_skip_verify: true
77
# For more TLS settings see config/configtls.ClientConfig
88

99
capabilities:
@@ -15,3 +15,6 @@ capabilities:
1515

1616
agent:
1717
executable: ../../bin/otelcontribcol_linux_amd64
18+
19+
storage:
20+
directory: .

cmd/opampsupervisor/examples/supervisor_windows.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ server:
33
tls:
44
# Disable verification to test locally.
55
# Don't do this in production.
6-
insecure_skip_verify: true
6+
insecure_skip_verify: true
77
# For more TLS settings see config/configtls.ClientConfig
88

99
capabilities:
@@ -15,3 +15,6 @@ capabilities:
1515

1616
agent:
1717
executable: ../../bin/otelcontribcol_windows_amd64.exe
18+
19+
storage:
20+
directory: .

cmd/opampsupervisor/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.21.0
55
require (
66
github.com/cenkalti/backoff/v4 v4.3.0
77
github.com/google/uuid v1.6.0
8+
github.com/knadh/koanf/maps v0.1.1
89
github.com/knadh/koanf/parsers/yaml v0.1.0
910
github.com/knadh/koanf/providers/file v0.1.0
1011
github.com/knadh/koanf/providers/rawbytes v0.1.0
@@ -26,7 +27,6 @@ require (
2627
github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 // indirect
2728
github.com/google/go-cmp v0.6.0 // indirect
2829
github.com/gorilla/websocket v1.5.1 // indirect
29-
github.com/knadh/koanf/maps v0.1.1 // indirect
3030
github.com/mitchellh/copystructure v1.2.0 // indirect
3131
github.com/mitchellh/reflectwalk v1.0.2 // indirect
3232
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package supervisor
5+
6+
import "os"
7+
8+
// pidProvider provides the PID of the current process
9+
type pidProvider interface {
10+
PID() int
11+
}
12+
13+
type defaultPIDProvider struct{}
14+
15+
func (defaultPIDProvider) PID() int {
16+
return os.Getpid()
17+
}

0 commit comments

Comments
 (0)