Skip to content

Commit

Permalink
[opampsupervisor] Add HealthCheckPort configuration parameter (open-t…
Browse files Browse the repository at this point in the history
…elemetry#34704)

**Description:** <Describe what has changed.>
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue.
Ex. Adding a feature - Explain what this achieves.-->
Add a new configuration parameter to `agent` called `health_check_port`.
If this is set, then the supervisor will configure the agent's
healthcheck extension to use the given port. If it is unset, then we
will grab a random port same as before.

**Link to tracking Issue:** open-telemetry#34643

**Testing:** <Describe what testing was performed and which tests were
added.>
- Updated config validation tests
- Verified that healthcheck extension is configured with the correct
port and works as expected
  • Loading branch information
dpaasman00 authored and f7o committed Sep 12, 2024
1 parent 7247c42 commit 659ba41
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 7 deletions.
27 changes: 27 additions & 0 deletions .chloggen/supervisor-healthcheck-port-configurable.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: opampsupervisor

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: "Add new config parameter `agent.health_check_port` to allow configuring the port used by the agent healthcheck extension."

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [34643]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:

# If your change doesn't affect end users or the exported elements of any package,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: []
9 changes: 5 additions & 4 deletions cmd/opampsupervisor/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,18 +337,19 @@ func TestSupervisorStartsWithNoOpAMPServer(t *testing.T) {

// The supervisor is started without a running OpAMP server.
// The supervisor should start successfully, even if the OpAMP server is stopped.
s := newSupervisor(t, "basic", map[string]string{
"url": server.addr,
s := newSupervisor(t, "healthcheck_port", map[string]string{
"url": server.addr,
"healthcheck_port": "12345",
})

require.Nil(t, s.Start())
defer s.Shutdown()

// Verify the collector is running by checking the metrics endpoint
require.Eventually(t, func() bool {
resp, err := http.DefaultClient.Get("http://localhost:8888/metrics")
resp, err := http.DefaultClient.Get("http://localhost:12345")
if err != nil {
t.Logf("Failed check for prometheus metrics: %s", err)
t.Logf("Failed agent healthcheck request: %s", err)
return false
}
require.NoError(t, resp.Body.Close())
Expand Down
5 changes: 5 additions & 0 deletions cmd/opampsupervisor/supervisor/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,18 @@ type Agent struct {
Executable string
OrphanDetectionInterval time.Duration `mapstructure:"orphan_detection_interval"`
Description AgentDescription `mapstructure:"description"`
HealthCheckPort int `mapstructure:"health_check_port"`
}

func (a Agent) Validate() error {
if a.OrphanDetectionInterval <= 0 {
return errors.New("agent::orphan_detection_interval must be positive")
}

if a.HealthCheckPort < 0 || a.HealthCheckPort > 65535 {
return errors.New("agent::health_check_port must be a valid port number")
}

if a.Executable == "" {
return errors.New("agent::executable must be specified")
}
Expand Down
76 changes: 76 additions & 0 deletions cmd/opampsupervisor/supervisor/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,82 @@ func TestValidate(t *testing.T) {
},
expectedError: "agent::orphan_detection_interval must be positive",
},
{
name: "Invalid port number",
config: Supervisor{
Server: OpAMPServer{
Endpoint: "wss://localhost:9090/opamp",
Headers: http.Header{
"Header1": []string{"HeaderValue"},
},
TLSSetting: configtls.ClientConfig{
Insecure: true,
},
},
Agent: Agent{
Executable: "${file_path}",
OrphanDetectionInterval: 5 * time.Second,
HealthCheckPort: 65536,
},
Capabilities: Capabilities{
AcceptsRemoteConfig: true,
},
Storage: Storage{
Directory: "/etc/opamp-supervisor/storage",
},
},
expectedError: "agent::health_check_port must be a valid port number",
},
{
name: "Zero value port number",
config: Supervisor{
Server: OpAMPServer{
Endpoint: "wss://localhost:9090/opamp",
Headers: http.Header{
"Header1": []string{"HeaderValue"},
},
TLSSetting: configtls.ClientConfig{
Insecure: true,
},
},
Agent: Agent{
Executable: "${file_path}",
OrphanDetectionInterval: 5 * time.Second,
HealthCheckPort: 0,
},
Capabilities: Capabilities{
AcceptsRemoteConfig: true,
},
Storage: Storage{
Directory: "/etc/opamp-supervisor/storage",
},
},
},
{
name: "Normal port number",
config: Supervisor{
Server: OpAMPServer{
Endpoint: "wss://localhost:9090/opamp",
Headers: http.Header{
"Header1": []string{"HeaderValue"},
},
TLSSetting: configtls.ClientConfig{
Insecure: true,
},
},
Agent: Agent{
Executable: "${file_path}",
OrphanDetectionInterval: 5 * time.Second,
HealthCheckPort: 29848,
},
Capabilities: Capabilities{
AcceptsRemoteConfig: true,
},
Storage: Storage{
Directory: "/etc/opamp-supervisor/storage",
},
},
},
}

// create some fake files for validating agent config
Expand Down
9 changes: 6 additions & 3 deletions cmd/opampsupervisor/supervisor/supervisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,13 @@ func (s *Supervisor) Start() error {
return fmt.Errorf("could not get bootstrap info from the Collector: %w", err)
}

healthCheckPort, err := s.findRandomPort()
healthCheckPort := s.config.Agent.HealthCheckPort
if healthCheckPort == 0 {
healthCheckPort, err = s.findRandomPort()

if err != nil {
return fmt.Errorf("could not find port for health check: %w", err)
if err != nil {
return fmt.Errorf("could not find port for health check: %w", err)
}
}

s.agentHealthCheckEndpoint = fmt.Sprintf("localhost:%d", healthCheckPort)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
server:
endpoint: ws://{{.url}}/v1/opamp
tls:
insecure: true

capabilities:
reports_effective_config: true
reports_own_metrics: true
reports_health: true
accepts_remote_config: true
reports_remote_config: true
accepts_restart_command: true

storage:
directory: "{{.storage_dir}}"

agent:
executable: ../../bin/otelcontribcol_{{.goos}}_{{.goarch}}{{.extension}}
health_check_port: "{{ .healthcheck_port }}"

0 comments on commit 659ba41

Please sign in to comment.