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

Unmarshalling with nested fields overwritten in env config can miss those settings #649

Open
ajscholl opened this issue Dec 22, 2021 · 0 comments
Labels
bug Something isn't working

Comments

@ajscholl
Copy link
Contributor

If you want to overwrite the SQS endpoint for all services for all clients, you might specify the env variable CLOUD_AWS_SQS_CLIENTS_DEFAULT_ENDPOINT. This works fine for the default client. However, if you now have a client with a different name, it does not pick up the endpoint anymore and ends up with the default. This is caused by the following code in UnmarshalClientSettings in gosoline/pkg/cloud/aws/awsv2.go:

	config.UnmarshalKey(clientsKey, settings, []cfg.UnmarshalDefaults{
		cfg.UnmarshalWithDefaultsFromKey("cloud.aws.defaults.region", "region"),
		cfg.UnmarshalWithDefaultsFromKey("cloud.aws.defaults.endpoint", "endpoint"),
		cfg.UnmarshalWithDefaultsFromKey("cloud.aws.defaults.http_client", "http_client"),
		cfg.UnmarshalWithDefaultsFromKey(defaultClientKey, "."),
	}...)

For the default client, we have clientsKey == "cloud.aws.sqs.clients.default" (for SQS), thus using the normal unmarshal functionality and everything works. If we have a different client, though, we have clientsKey == "cloud.aws.sqs.clients.different" and only access the env variable via cfg.UnmarshalWithDefaultsFromKey(defaultClientKey, "."). This does not pick up the nested env variable and thus only provides the default value from the struct.

The following unit test triggers the same problem without any AWS related code:

func (s *ConfigTestSuite) TestConfig_FromEnvNested() {
	type configMap struct {
		Name        string `cfg:"name"`
		Endpoint    string `cfg:"endpoint" default:"https://example.com"`
		Credentials string `cfg:"credentials"`
	}

	expected := configMap{
		Name:        "custom",
		Endpoint:    "https://api.example.com",
		Credentials: "secret",
	}

	s.setupConfigValues(map[string]interface{}{
		"gosoline": map[string]interface{}{
			"example": map[string]interface{}{
				"config": map[string]interface{}{
					"credentials": "secret",
				},
			},
			// remove the following field for a different failure scenario (with s.config.IsSet("gosoline.default.config") no longer being true)
			"default": map[string]interface{}{
				"config": map[string]interface{}{
					"name": "default",
				},
			},
		},
	})

	err := s.envProvider.SetEnv("GOSOLINE_EXAMPLE_CONFIG_NAME", "custom")
	s.NoError(err)
	err = s.envProvider.SetEnv("GOSOLINE_DEFAULT_CONFIG_ENDPOINT", "https://api.example.com")
	s.NoError(err)

	s.True(s.config.IsSet("gosoline.default.config"))

	cm := configMap{}
	s.config.UnmarshalKey("gosoline.example.config", &cm,
		cfg.UnmarshalWithDefaultsFromKey("gosoline.default.config", "."),
	)

	s.Equal(expected, cm)
}
@ajscholl ajscholl added the bug Something isn't working label Dec 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant