diff --git a/options/env.go b/options/env.go index f80cbfc..a89a762 100644 --- a/options/env.go +++ b/options/env.go @@ -41,17 +41,24 @@ func getEnvVarFile(service string) *envVarOverrides { return &env } -func (e *envVarOverrides) setEnvVariable(setting string, value string) error { - result := strings.ToUpper(setting) - // replace - with _ for keys such as add-known-secrets and edgex-startup-duration - result = strings.ReplaceAll(result, "-", "_") - // replace . with _ for config file overrides such as service.port - result = strings.ReplaceAll(result, ".", "_") - log.Infof("Mapping %s to %s", setting, result) - _, err := fmt.Fprintf(e.buffer, "export %s=%s\n", result, value) +func (e *envVarOverrides) setEnvVariable(key string, value string) error { + envKey, err := configKeyToEnvVar(key) + if err != nil { + return fmt.Errorf("error converting config key to environment variable key: %s", err) + } + log.Infof("Mapping %s to %s", key, envKey) + _, err = fmt.Fprintf(e.buffer, "export %s=%s\n", envKey, value) return err } +// convert my-var to MY_VAR +func configKeyToEnvVar(configKey string) (string, error) { + if strings.Contains(configKey, ".") { + return "", fmt.Errorf("config key must not contain dots: %s", configKey) + } + return strings.ReplaceAll(strings.ToUpper(configKey), "-", "_"), nil +} + func (e *envVarOverrides) getEnvFilename() string { // The app-service-configurable snap is the one outlier snap that doesn't diff --git a/options/options.go b/options/options.go index eb71f81..9ae3141 100644 --- a/options/options.go +++ b/options/options.go @@ -72,7 +72,9 @@ func processGlobalConfigOptions(services []string) error { for _, service := range services { overrides := getEnvVarFile(service) for env, value := range configuration { - overrides.setEnvVariable(env, value) + if err := overrides.setEnvVariable(env, value); err != nil { + return err + } } overrides.writeEnvFile(false) } @@ -192,7 +194,9 @@ func processAppConfigOptions(services []string) error { for env, value := range configuration { log.Debugf("Processing overrides setEnvVariable: %v=%v", env, value) - overrides.setEnvVariable(env, value) + if err := overrides.setEnvVariable(env, value); err != nil { + return err + } } overrides.writeEnvFile(true) } diff --git a/options/options_test.go b/options/options_test.go index 8130ab0..7cc6d55 100644 --- a/options/options_test.go +++ b/options/options_test.go @@ -65,7 +65,7 @@ func TestProcessAppConfig(t *testing.T) { }) t.Run("global options", func(t *testing.T) { - const key, value = "config.x.y", "value" + const key, value = "config.x-y", "value" t.Cleanup(func() { assert.NoError(t, snapctl.Unset(key).Run()) @@ -80,7 +80,7 @@ func TestProcessAppConfig(t *testing.T) { require.Error(t, options.ProcessAppConfig(testService, testService2)) }) - t.Run("set/unset", func(t *testing.T) { + t.Run("set+unset", func(t *testing.T) { require.NoError(t, snapctl.Set(configEnabled, "true").Run()) t.Cleanup(func() { require.NoError(t, snapctl.Unset("config").Run()) @@ -113,14 +113,14 @@ func TestProcessAppConfig(t *testing.T) { }) t.Run("single app options", func(t *testing.T) { - const key, value = "apps." + testService + ".config.x.y", "value" + const key, value = "apps." + testService + ".config.x-y", "value" t.Cleanup(func() { assert.NoError(t, snapctl.Unset(key).Run()) assert.NoError(t, os.RemoveAll(envFile)) }) - t.Run("set/unset", func(t *testing.T) { + t.Run("set+unset", func(t *testing.T) { require.NoError(t, snapctl.Set(configEnabled, "true").Run()) t.Cleanup(func() { require.NoError(t, snapctl.Unset("apps").Run()) @@ -176,7 +176,7 @@ func TestProcessAppConfig(t *testing.T) { t.Run("reject mixed legacy options", func(t *testing.T) { const ( legacyKey, legacyValue = "env.core-data.service.host", "legacy" - key, value = "apps.core-data.config.x.y", "value" + key, value = "apps.core-data.config.x-y", "value" ) configCoreDataDir := fmt.Sprintf("%s/core-data/res/", env.SnapDataConf)