mirror of
https://github.com/grafana/grafana.git
synced 2024-12-29 10:21:41 -06:00
Settings: Env override support for dynamic settings (#21439)
* Settings: supports env overrrides for dynamic settings * Settings: makes it possible to explicitly get env override support for dynamic settings * Make linter happy
This commit is contained in:
parent
c5f906f472
commit
673ccdc448
35
pkg/setting/dynamic_settings_test.go
Normal file
35
pkg/setting/dynamic_settings_test.go
Normal file
@ -0,0 +1,35 @@
|
||||
package setting
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDynamicSettingsSupport_Override(t *testing.T) {
|
||||
cfg := NewCfg()
|
||||
|
||||
envKey := "GF_FOO_BAR"
|
||||
sectionName := "foo"
|
||||
keyName := "bar"
|
||||
expected := "dynamic value"
|
||||
|
||||
os.Setenv(envKey, expected)
|
||||
defer func() { os.Unsetenv(envKey) }()
|
||||
|
||||
value := cfg.SectionWithEnvOverrides(sectionName).Key(keyName).MustString("default value")
|
||||
require.Equal(t, expected, value)
|
||||
}
|
||||
|
||||
func TestDynamicSettingsSupport_NoOverride(t *testing.T) {
|
||||
cfg := NewCfg()
|
||||
sectionName := "foo"
|
||||
keyName := "bar"
|
||||
expected := "default value"
|
||||
|
||||
_, err := cfg.Raw.Section(sectionName).NewKey(keyName, expected)
|
||||
require.NoError(t, err)
|
||||
value := cfg.SectionWithEnvOverrides(sectionName).Key(keyName).String()
|
||||
require.Equal(t, expected, value)
|
||||
}
|
@ -32,6 +32,7 @@ const (
|
||||
HTTP2 Scheme = "h2"
|
||||
SOCKET Scheme = "socket"
|
||||
DEFAULT_HTTP_ADDR string = "0.0.0.0"
|
||||
REDACTED_PASSWORD string = "*********"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -327,15 +328,13 @@ func applyEnvVariableOverrides(file *ini.File) error {
|
||||
appliedEnvOverrides = make([]string, 0)
|
||||
for _, section := range file.Sections() {
|
||||
for _, key := range section.Keys() {
|
||||
sectionName := strings.ToUpper(strings.Replace(section.Name(), ".", "_", -1))
|
||||
keyName := strings.ToUpper(strings.Replace(key.Name(), ".", "_", -1))
|
||||
envKey := fmt.Sprintf("GF_%s_%s", sectionName, keyName)
|
||||
envKey := envKey(section.Name(), key.Name())
|
||||
envValue := os.Getenv(envKey)
|
||||
|
||||
if len(envValue) > 0 {
|
||||
key.SetValue(envValue)
|
||||
if shouldRedactKey(envKey) {
|
||||
envValue = "*********"
|
||||
envValue = REDACTED_PASSWORD
|
||||
}
|
||||
if shouldRedactURLKey(envKey) {
|
||||
u, err := url.Parse(envValue)
|
||||
@ -359,6 +358,13 @@ func applyEnvVariableOverrides(file *ini.File) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func envKey(sectionName string, keyName string) string {
|
||||
sN := strings.ToUpper(strings.Replace(sectionName, ".", "_", -1))
|
||||
kN := strings.ToUpper(strings.Replace(keyName, ".", "_", -1))
|
||||
envKey := fmt.Sprintf("GF_%s_%s", sN, kN)
|
||||
return envKey
|
||||
}
|
||||
|
||||
func applyCommandLineDefaultProperties(props map[string]string, file *ini.File) {
|
||||
appliedCommandLineProperties = make([]string, 0)
|
||||
for _, section := range file.Sections() {
|
||||
@ -368,7 +374,7 @@ func applyCommandLineDefaultProperties(props map[string]string, file *ini.File)
|
||||
if exists {
|
||||
key.SetValue(value)
|
||||
if shouldRedactKey(keyString) {
|
||||
value = "*********"
|
||||
value = REDACTED_PASSWORD
|
||||
}
|
||||
appliedCommandLineProperties = append(appliedCommandLineProperties, fmt.Sprintf("%s=%s", keyString, value))
|
||||
}
|
||||
@ -1114,6 +1120,37 @@ func (cfg *Cfg) LogConfigSources() {
|
||||
cfg.Logger.Info("App mode " + Env)
|
||||
}
|
||||
|
||||
type DynamicSection struct {
|
||||
section *ini.Section
|
||||
Logger log.Logger
|
||||
}
|
||||
|
||||
// Key dynamically overrides keys with environment variables.
|
||||
// As a side effect, the value of the setting key will be updated if an environment variable is present.
|
||||
func (s *DynamicSection) Key(k string) *ini.Key {
|
||||
envKey := envKey(s.section.Name(), k)
|
||||
envValue := os.Getenv(envKey)
|
||||
key := s.section.Key(k)
|
||||
|
||||
if len(envValue) == 0 {
|
||||
return key
|
||||
}
|
||||
|
||||
key.SetValue(envValue)
|
||||
if shouldRedactKey(envKey) {
|
||||
envValue = REDACTED_PASSWORD
|
||||
}
|
||||
s.Logger.Info("Config overridden from Environment variable", "var", fmt.Sprintf("%s=%s", envKey, envValue))
|
||||
|
||||
return key
|
||||
}
|
||||
|
||||
// SectionWithEnvOverrides dynamically overrides keys with environment variables.
|
||||
// As a side effect, the value of the setting key will be updated if an environment variable is present.
|
||||
func (cfg *Cfg) SectionWithEnvOverrides(s string) *DynamicSection {
|
||||
return &DynamicSection{cfg.Raw.Section(s), cfg.Logger}
|
||||
}
|
||||
|
||||
func IsExpressionsEnabled() bool {
|
||||
v, ok := FeatureToggles["expressions"]
|
||||
if !ok {
|
||||
|
Loading…
Reference in New Issue
Block a user