diff --git a/CHANGELOG.md b/CHANGELOG.md index b8b9081129..1787a704de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Released TBD +### Changed + +- feat(opampextension): opamp effective configuration is only derived from the + remote_configuration_directory contents and the contents are managed by the + extension [#1274] + +[#1274]: https://github.com/SumoLogic/sumologic-otel-collector/pull/1274 [Unreleased]: https://github.com/SumoLogic/sumologic-otel-collector/compare/v0.87.0-sumo-0...main ## [v0.87.0-sumo-0] diff --git a/pkg/extension/opampextension/README.md b/pkg/extension/opampextension/README.md index bc4adb8122..2577b0c4a5 100644 --- a/pkg/extension/opampextension/README.md +++ b/pkg/extension/opampextension/README.md @@ -40,9 +40,8 @@ extensions: installation_token: api_base_url: opamp: - instance_uid: endpoint: - remote_configuration_directory: /etc/otelcol-sumo/conf.d + remote_configuration_directory: /etc/otelcol-sumo/opamp.d ``` ## API URLs @@ -68,7 +67,7 @@ option: Here is a list of valid values for the OpAMP `endpoint** configuration option: -**Note:** As of Jan 2023, these endpoints are not yet available. +**Note:** These endpoints are not yet available. | Deployment | API base URL | |:-------------:|---------------------------------------------| @@ -84,11 +83,8 @@ Here is a list of valid values for the OpAMP `endpoint** configuration option: ## Storing local configuration When the OpAMP extension receives a remote configuration from the OpAMP server, -it persists the YAML configuration to a local file. The path of this file is -determined by the `remote_configuration_directory` configuration option and the -file name is `opamp-remote-config.yaml`. For example, if -`remote_configuration_directory` is set to `/etc/otelcol-sumo/conf.d`, the -resulting local configuration file path would be -`/etc/otelcol-sumo/conf.d/opamp-remote-config.yaml`. A configuration provider -must be used in order to load the stored configuration, for example: `--config -"glob:/etc/otelcol-sumo/conf.d/*"`. +it persists each received YAML configuration to a local file in the +`remote_configuration_directory`. The existing contents of the +`remote_configuration_directory` are removed before doing so. A configuration +provider must be used in order to load the stored configuration, for example: +`--config "glob:/etc/otelcol-sumo/opamp.d/*"`. diff --git a/pkg/extension/opampextension/config.go b/pkg/extension/opampextension/config.go index 0057e53d48..2df8e652f2 100644 --- a/pkg/extension/opampextension/config.go +++ b/pkg/extension/opampextension/config.go @@ -16,6 +16,8 @@ package opampextension import ( "errors" + "fmt" + "os" "github.com/oklog/ulid/v2" "go.opentelemetry.io/collector/component" @@ -34,6 +36,9 @@ type Config struct { // RemoteConfigurationDirectory is where received OpAMP remote configuration // is stored. RemoteConfigurationDirectory string `mapstructure:"remote_configuration_directory"` + + // AcceptsRemoteConfiguration indicates if the OpAMP agent will accept remote configuration. + AcceptsRemoteConfiguration bool `mapstructure:"accepts_remote_configuration"` } // CreateDefaultHTTPClientSettings returns default http client settings @@ -58,5 +63,10 @@ func (cfg *Config) Validate() error { return errors.New("opamp remote_configuration_directory must be provided") } + d := cfg.RemoteConfigurationDirectory + if _, err := os.Stat(d); err != nil { + return fmt.Errorf("opamp remote_configuration_directory %s must be readable: %v", d, err) + } + return nil } diff --git a/pkg/extension/opampextension/config_test.go b/pkg/extension/opampextension/config_test.go index 4ef631e065..7d86aaf4b2 100644 --- a/pkg/extension/opampextension/config_test.go +++ b/pkg/extension/opampextension/config_test.go @@ -15,7 +15,9 @@ package opampextension import ( + "os" "path/filepath" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -50,7 +52,8 @@ func TestUnmarshalConfig(t *testing.T) { }, }, InstanceUID: "01BX5ZZKBKACTAV9WEVGEMMVRZ", - RemoteConfigurationDirectory: "/tmp/", + RemoteConfigurationDirectory: "/tmp/opamp.d", + AcceptsRemoteConfiguration: true, }, cfg) } @@ -59,9 +62,19 @@ func TestConfigValidate(t *testing.T) { err := cfg.Validate() require.Error(t, err) assert.Equal(t, "opamp remote_configuration_directory must be provided", err.Error()) - cfg.RemoteConfigurationDirectory = "/tmp/" + + cfg.RemoteConfigurationDirectory = "/tmp/opamp.d" err = cfg.Validate() - require.NoError(t, err) + assert.True(t, strings.HasPrefix(err.Error(), "opamp remote_configuration_directory /tmp/opamp.d must be readable:")) + + d, err := os.MkdirTemp("", "opamp.d") + assert.NoError(t, err) + defer os.RemoveAll(d) + + cfg.RemoteConfigurationDirectory = d + err = cfg.Validate() + assert.NoError(t, err) + cfg.InstanceUID = "01BX5ZZKBKACTAV9WEVGEMMVRZFAIL" err = cfg.Validate() require.Error(t, err) diff --git a/pkg/extension/opampextension/factory.go b/pkg/extension/opampextension/factory.go index 6e1c512771..25de552481 100644 --- a/pkg/extension/opampextension/factory.go +++ b/pkg/extension/opampextension/factory.go @@ -32,7 +32,8 @@ func NewFactory() extension.Factory { func createDefaultConfig() component.Config { return &Config{ - HTTPClientSettings: CreateDefaultHTTPClientSettings(), + HTTPClientSettings: CreateDefaultHTTPClientSettings(), + AcceptsRemoteConfiguration: true, } } diff --git a/pkg/extension/opampextension/factory_test.go b/pkg/extension/opampextension/factory_test.go index e01798d785..85a09b58f0 100644 --- a/pkg/extension/opampextension/factory_test.go +++ b/pkg/extension/opampextension/factory_test.go @@ -37,6 +37,7 @@ func TestFactory_CreateDefaultConfig(t *testing.T) { AuthenticatorID: component.NewID("sumologic"), }, }, + AcceptsRemoteConfiguration: true, }) assert.NoError(t, componenttest.CheckConfigStruct(cfg)) diff --git a/pkg/extension/opampextension/go.mod b/pkg/extension/opampextension/go.mod index 7fdd19503c..f536984ac2 100644 --- a/pkg/extension/opampextension/go.mod +++ b/pkg/extension/opampextension/go.mod @@ -4,6 +4,7 @@ go 1.20 require ( github.com/SumoLogic/sumologic-otel-collector/pkg/extension/sumologicextension v0.77.0-sumo-0 + github.com/google/uuid v1.3.0 github.com/knadh/koanf/parsers/yaml v0.1.0 github.com/knadh/koanf/providers/rawbytes v0.1.0 github.com/knadh/koanf/v2 v2.0.1 diff --git a/pkg/extension/opampextension/go.sum b/pkg/extension/opampextension/go.sum index 424dae2b3e..26e47d269c 100644 --- a/pkg/extension/opampextension/go.sum +++ b/pkg/extension/opampextension/go.sum @@ -27,6 +27,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= diff --git a/pkg/extension/opampextension/opamp_agent.go b/pkg/extension/opampextension/opamp_agent.go index 7cf2e0c13f..38a1c8640e 100644 --- a/pkg/extension/opampextension/opamp_agent.go +++ b/pkg/extension/opampextension/opamp_agent.go @@ -20,10 +20,11 @@ import ( "net/http" "os" "path/filepath" + "reflect" "runtime" - "sort" "syscall" + "github.com/google/uuid" "github.com/knadh/koanf/parsers/yaml" "github.com/knadh/koanf/providers/rawbytes" "github.com/knadh/koanf/v2" @@ -53,7 +54,7 @@ type opampAgent struct { instanceId ulid.ULID - effectiveConfig string + effectiveConfig map[string]*protobufs.AgentConfigFile agentDescription *protobufs.AgentDescription @@ -66,13 +67,8 @@ func (o *opampAgent) Start(ctx context.Context, host component.Host) error { o.host = host o.opampClient = client.NewWebSocket(o.logger.Sugar()) - path := filepath.Join(o.cfg.RemoteConfigurationDirectory, "opamp-remote-config.yaml") - if _, err := os.Stat(path); err == nil { - err := o.loadEffectiveConfig(path) - - if err != nil { - return err - } + if err := o.loadEffectiveConfig(o.cfg.RemoteConfigurationDirectory); err != nil { + return err } if err := o.createAgentDescription(); err != nil { @@ -156,9 +152,7 @@ func (o *opampAgent) startClient(ctx context.Context) error { OnMessageFunc: o.onMessage, }, RemoteConfigStatus: o.remoteConfigStatus, - Capabilities: protobufs.AgentCapabilities_AgentCapabilities_AcceptsRemoteConfig | - protobufs.AgentCapabilities_AgentCapabilities_ReportsRemoteConfig | - protobufs.AgentCapabilities_AgentCapabilities_ReportsEffectiveConfig, + Capabilities: o.getAgentCapabilities(), } o.logger.Debug("Starting OpAMP client...") @@ -246,21 +240,21 @@ func newOpampAgent(cfg *Config, logger *zap.Logger, build component.BuildInfo, r uid := ulid.Make() - sid, ok := res.Attributes().Get(semconv.AttributeServiceInstanceID) - if ok { - puid, err := ulid.Parse(sid.AsString()) - if err != nil { - return nil, err - } - uid = puid - } - if cfg.InstanceUID != "" { puid, err := ulid.Parse(cfg.InstanceUID) if err != nil { return nil, err } uid = puid + } else { + sid, ok := res.Attributes().Get(semconv.AttributeServiceInstanceID) + if ok { + uuid, err := uuid.Parse(sid.AsString()) + if err != nil { + return nil, err + } + uid = ulid.ULID(uuid) + } } agent := &opampAgent{ @@ -274,6 +268,18 @@ func newOpampAgent(cfg *Config, logger *zap.Logger, build component.BuildInfo, r return agent, nil } +func (o *opampAgent) getAgentCapabilities() protobufs.AgentCapabilities { + c := protobufs.AgentCapabilities_AgentCapabilities_ReportsEffectiveConfig + + if o.cfg.AcceptsRemoteConfiguration { + c = c | + protobufs.AgentCapabilities_AgentCapabilities_AcceptsRemoteConfig | + protobufs.AgentCapabilities_AgentCapabilities_ReportsRemoteConfig + } + + return c +} + func stringKeyValue(key, value string) *protobufs.KeyValue { return &protobufs.KeyValue{ Key: key, @@ -290,9 +296,9 @@ func (o *opampAgent) createAgentDescription() error { } ident := []*protobufs.KeyValue{ - stringKeyValue("service.instance.id", o.instanceId.String()), - stringKeyValue("service.name", o.agentType), - stringKeyValue("service.version", o.agentVersion), + stringKeyValue(semconv.AttributeServiceInstanceID, o.instanceId.String()), + stringKeyValue(semconv.AttributeServiceName, o.agentType), + stringKeyValue(semconv.AttributeServiceVersion, o.agentVersion), } nonIdent := []*protobufs.KeyValue{ @@ -309,41 +315,77 @@ func (o *opampAgent) createAgentDescription() error { return nil } -func (o *opampAgent) loadEffectiveConfig(path string) error { - var k = koanf.New(".") +func (o *opampAgent) loadEffectiveConfig(dir string) error { + if _, err := os.Stat(dir); err != nil { + return err + } - rb, err := os.ReadFile(path) + ec := map[string]*protobufs.AgentConfigFile{} + paths, err := filepath.Glob(filepath.Join(dir, "*.yaml")) if err != nil { return err } - if err := k.Load(rawbytes.Provider(rb), yaml.Parser()); err != nil { - return err - } + for _, p := range paths { + var k = koanf.New(".") - ecb, err := k.Marshal(yaml.Parser()) - if err != nil { - return err + rb, err := os.ReadFile(p) + + if err != nil { + return err + } + + if err := k.Load(rawbytes.Provider(rb), yaml.Parser()); err != nil { + return err + } + + fb, err := k.Marshal(yaml.Parser()) + if err != nil { + return err + } + + ec[filepath.Base(p)] = &protobufs.AgentConfigFile{Body: fb} } - o.effectiveConfig = string(ecb) + o.effectiveConfig = ec return nil } -func (o *opampAgent) saveEffectiveConfig(path string) error { - f, err := os.Create(path) +func (o *opampAgent) saveEffectiveConfig(dir string) error { + d, err := os.Open(dir) if err != nil { return err } - defer f.Close() - _, err = f.Write([]byte(o.effectiveConfig)) + files, err := d.Readdir(0) if err != nil { return err } + for _, f := range files { + err := os.Remove(filepath.Join(dir, f.Name())) + if err != nil { + return err + } + } + + for k, v := range o.effectiveConfig { + p := filepath.Join(dir, k) + + f, err := os.Create(p) + if err != nil { + return err + } + defer f.Close() + + _, err = f.Write(v.Body) + if err != nil { + return err + } + } + return nil } @@ -367,93 +409,45 @@ func (o *opampAgent) updateAgentIdentity(instanceId ulid.ULID) { func (o *opampAgent) composeEffectiveConfig() *protobufs.EffectiveConfig { return &protobufs.EffectiveConfig{ ConfigMap: &protobufs.AgentConfigMap{ - ConfigMap: map[string]*protobufs.AgentConfigFile{ - "": {Body: []byte(o.effectiveConfig)}, - }, + ConfigMap: o.effectiveConfig, }, } } -type agentConfigFileItem struct { - name string - file *protobufs.AgentConfigFile -} - -type agentConfigFileSlice []agentConfigFileItem - -func (a agentConfigFileSlice) Less(i, j int) bool { - return a[i].name < a[j].name -} - -func (a agentConfigFileSlice) Swap(i, j int) { - t := a[i] - a[i] = a[j] - a[j] = t -} - -func (a agentConfigFileSlice) Len() int { - return len(a) -} - func (o *opampAgent) applyRemoteConfig(config *protobufs.AgentRemoteConfig) (configChanged bool, err error) { o.logger.Debug("Received remote config from OpAMP server", zap.ByteString("hash", config.ConfigHash)) - var k = koanf.New(".") - - orderedConfigs := agentConfigFileSlice{} - for name, file := range config.Config.ConfigMap { - if name == "" { - // skip instance config - continue - } - orderedConfigs = append(orderedConfigs, agentConfigFileItem{ - name: name, - file: file, - }) + if !o.cfg.AcceptsRemoteConfiguration { + return false, fmt.Errorf("OpAMP agent does not accept remote configuration") } - // Sort to make sure the order of merging is stable. - sort.Sort(orderedConfigs) + nec := map[string]*protobufs.AgentConfigFile{} - // Append instance config as the last item. - instanceConfig := config.Config.ConfigMap[""] - if instanceConfig != nil { - orderedConfigs = append(orderedConfigs, agentConfigFileItem{ - name: "", - file: instanceConfig, - }) - } + for n, f := range config.Config.ConfigMap { + var k = koanf.New(".") - // Merge received configs. - for _, item := range orderedConfigs { - var k2 = koanf.New(".") - err := k2.Load(rawbytes.Provider(item.file.Body), yaml.Parser()) + err := k.Load(rawbytes.Provider(f.Body), yaml.Parser()) if err != nil { - return false, fmt.Errorf("cannot parse config named %s: %v", item.name, err) + return false, fmt.Errorf("cannot parse config named %s: %v", n, err) } - err = k.Merge(k2) + + fb, err := k.Marshal(yaml.Parser()) if err != nil { - return false, fmt.Errorf("cannot merge config named %s: %v", item.name, err) + return false, fmt.Errorf("cannot marshal config named %s: %v", n, err) } - } - // The merged final result is our effective config. - effectiveConfigBytes, err := k.Marshal(yaml.Parser()) - if err != nil { - return false, fmt.Errorf("cannot marshal the OpAMP effective config: %v", err) + nec[n] = &protobufs.AgentConfigFile{Body: fb} } - newEffectiveConfig := string(effectiveConfigBytes) configChanged = false - if o.effectiveConfig != newEffectiveConfig { - path := filepath.Join(o.cfg.RemoteConfigurationDirectory, "opamp-remote-config.yaml") - oldEffectiveConfig := o.effectiveConfig - o.effectiveConfig = newEffectiveConfig + if !reflect.DeepEqual(o.effectiveConfig, nec) { + oec := o.effectiveConfig + o.effectiveConfig = nec - err := o.saveEffectiveConfig(path) + err := o.saveEffectiveConfig(o.cfg.RemoteConfigurationDirectory) if err != nil { - o.effectiveConfig = oldEffectiveConfig - return false, fmt.Errorf("cannot save the OpAMP effective config to %s: %v", path, err) + o.effectiveConfig = oec + return false, fmt.Errorf("cannot save the OpAMP effective config to %s: %v", o.cfg.RemoteConfigurationDirectory, err) } configChanged = true diff --git a/pkg/extension/opampextension/opamp_agent_test.go b/pkg/extension/opampextension/opamp_agent_test.go index fcdeda06b2..4875e6092d 100644 --- a/pkg/extension/opampextension/opamp_agent_test.go +++ b/pkg/extension/opampextension/opamp_agent_test.go @@ -36,8 +36,8 @@ func TestNewOpampAgent(t *testing.T) { set.BuildInfo = component.BuildInfo{Version: "test version", Command: "otelcoltest"} o, err := newOpampAgent(cfg.(*Config), set.Logger, set.BuildInfo, set.Resource) assert.NoError(t, err) - assert.Equal(t, o.agentType, "otelcoltest") - assert.Equal(t, o.agentVersion, "test version") + assert.Equal(t, "otelcoltest", o.agentType) + assert.Equal(t, "test version", o.agentVersion) assert.NotEmpty(t, o.instanceId.String()) assert.Empty(t, o.effectiveConfig) assert.Nil(t, o.agentDescription) @@ -49,12 +49,24 @@ func TestNewOpampAgentAttributes(t *testing.T) { set.BuildInfo = component.BuildInfo{Version: "test version", Command: "otelcoltest"} set.Resource.Attributes().PutStr(semconv.AttributeServiceName, "otelcol-sumo") set.Resource.Attributes().PutStr(semconv.AttributeServiceVersion, "sumo.0") - set.Resource.Attributes().PutStr(semconv.AttributeServiceInstanceID, "01BX5ZZKBKACTAV9WEVGEMMVRZ") + set.Resource.Attributes().PutStr(semconv.AttributeServiceInstanceID, "f8999bc1-4c9b-4619-9bae-7f009d2411ec") o, err := newOpampAgent(cfg.(*Config), set.Logger, set.BuildInfo, set.Resource) assert.NoError(t, err) - assert.Equal(t, o.agentType, "otelcol-sumo") - assert.Equal(t, o.agentVersion, "sumo.0") - assert.Equal(t, o.instanceId.String(), "01BX5ZZKBKACTAV9WEVGEMMVRZ") + assert.Equal(t, "otelcol-sumo", o.agentType) + assert.Equal(t, "sumo.0", o.agentVersion) + assert.Equal(t, "7RK6DW2K4V8RCSQBKZ02EJ84FC", o.instanceId.String()) +} + +func TestGetAgentCapabilities(t *testing.T) { + cfg := createDefaultConfig().(*Config) + set := extensiontest.NewNopCreateSettings() + o, err := newOpampAgent(cfg, set.Logger, set.BuildInfo, set.Resource) + assert.NoError(t, err) + + assert.Equal(t, o.getAgentCapabilities(), protobufs.AgentCapabilities(4102)) + + cfg.AcceptsRemoteConfiguration = false + assert.Equal(t, o.getAgentCapabilities(), protobufs.AgentCapabilities(4)) } func TestCreateAgentDescription(t *testing.T) { @@ -74,11 +86,10 @@ func TestLoadEffectiveConfig(t *testing.T) { o, err := newOpampAgent(cfg.(*Config), set.Logger, set.BuildInfo, set.Resource) assert.NoError(t, err) - assert.Empty(t, o.effectiveConfig) + assert.Equal(t, len(o.effectiveConfig), 0) - path := filepath.Join("testdata", "opamp-remote-config.yaml") - assert.NoError(t, o.loadEffectiveConfig(path)) - assert.NotEmpty(t, o.effectiveConfig) + assert.NoError(t, o.loadEffectiveConfig("testdata")) + assert.NotEqual(t, len(o.effectiveConfig), 0) } func TestSaveEffectiveConfig(t *testing.T) { @@ -87,11 +98,11 @@ func TestSaveEffectiveConfig(t *testing.T) { o, err := newOpampAgent(cfg.(*Config), set.Logger, set.BuildInfo, set.Resource) assert.NoError(t, err) - f, err := os.CreateTemp("", "opamp-remote-config.yaml") + d, err := os.MkdirTemp("", "opamp.d") assert.NoError(t, err) - defer os.Remove(f.Name()) + defer os.RemoveAll(d) - assert.NoError(t, o.saveEffectiveConfig(f.Name())) + assert.NoError(t, o.saveEffectiveConfig(d)) } func TestUpdateAgentIdentity(t *testing.T) { @@ -121,14 +132,19 @@ func TestComposeEffectiveConfig(t *testing.T) { } func TestApplyRemoteConfig(t *testing.T) { - cfg := createDefaultConfig() + d, err := os.MkdirTemp("", "opamp.d") + assert.NoError(t, err) + defer os.RemoveAll(d) + + cfg := createDefaultConfig().(*Config) + cfg.RemoteConfigurationDirectory = d set := extensiontest.NewNopCreateSettings() - o, err := newOpampAgent(cfg.(*Config), set.Logger, set.BuildInfo, set.Resource) + o, err := newOpampAgent(cfg, set.Logger, set.BuildInfo, set.Resource) assert.NoError(t, err) - assert.Empty(t, o.effectiveConfig) + assert.Equal(t, len(o.effectiveConfig), 0) - path := filepath.Join("testdata", "opamp-remote-config.yaml") + path := filepath.Join("testdata", "opamp.d", "opamp-remote-config.yaml") rb, err := os.ReadFile(path) assert.NoError(t, err) @@ -144,9 +160,15 @@ func TestApplyRemoteConfig(t *testing.T) { } changed, err := o.applyRemoteConfig(rc) - assert.True(t, changed) assert.NoError(t, err) - assert.NotEmpty(t, o.effectiveConfig) + assert.True(t, changed) + assert.NotEqual(t, len(o.effectiveConfig), 0) + + cfg.AcceptsRemoteConfiguration = false + changed, err = o.applyRemoteConfig(rc) + assert.False(t, changed) + assert.Error(t, err) + assert.Equal(t, "OpAMP agent does not accept remote configuration", err.Error()) } func TestShutdown(t *testing.T) { @@ -161,8 +183,13 @@ func TestShutdown(t *testing.T) { } func TestStart(t *testing.T) { + d, err := os.MkdirTemp("", "opamp.d") + assert.NoError(t, err) + defer os.RemoveAll(d) + cfg := createDefaultConfig().(*Config) cfg.HTTPClientSettings.Auth = nil + cfg.RemoteConfigurationDirectory = d set := extensiontest.NewNopCreateSettings() o, err := newOpampAgent(cfg, set.Logger, set.BuildInfo, set.Resource) assert.NoError(t, err) @@ -171,8 +198,13 @@ func TestStart(t *testing.T) { } func TestReload(t *testing.T) { + d, err := os.MkdirTemp("", "opamp.d") + assert.NoError(t, err) + defer os.RemoveAll(d) + cfg := createDefaultConfig().(*Config) cfg.HTTPClientSettings.Auth = nil + cfg.RemoteConfigurationDirectory = d set := extensiontest.NewNopCreateSettings() o, err := newOpampAgent(cfg, set.Logger, set.BuildInfo, set.Resource) assert.NoError(t, err) diff --git a/pkg/extension/opampextension/testdata/config.yaml b/pkg/extension/opampextension/testdata/config.yaml index 338acbd1c6..13980f6fae 100644 --- a/pkg/extension/opampextension/testdata/config.yaml +++ b/pkg/extension/opampextension/testdata/config.yaml @@ -1,3 +1,3 @@ endpoint: wss://127.0.0.1:4320/v1/opamp instance_uid: 01BX5ZZKBKACTAV9WEVGEMMVRZ -remote_configuration_directory: /tmp/ +remote_configuration_directory: /tmp/opamp.d diff --git a/pkg/extension/opampextension/testdata/opamp-remote-config.yaml b/pkg/extension/opampextension/testdata/opamp.d/opamp-remote-config.yaml similarity index 100% rename from pkg/extension/opampextension/testdata/opamp-remote-config.yaml rename to pkg/extension/opampextension/testdata/opamp.d/opamp-remote-config.yaml