|
20 | 20 | package config |
21 | 21 |
|
22 | 22 | import ( |
| 23 | + "bytes" |
23 | 24 | "fmt" |
24 | 25 | "os" |
25 | 26 | "path/filepath" |
@@ -81,13 +82,41 @@ func (l *Loader) Load(configFile string) (*Config, error) { |
81 | 82 | v.SetConfigFile(configFile) |
82 | 83 | } |
83 | 84 |
|
84 | | - // Read config file |
85 | | - if err := v.ReadInConfig(); err != nil { |
86 | | - if _, ok := err.(viper.ConfigFileNotFoundError); !ok { |
87 | | - return nil, fmt.Errorf("failed to read config file: %w", err) |
| 85 | + // Read config file with environment variable expansion. |
| 86 | + // This resolves ${VAR} placeholders in config values (e.g., ${NODE_IP} in cAdvisor endpoint). |
| 87 | + // Viper's ReadInConfig does NOT expand env vars in values — only AutomaticEnv overrides keys. |
| 88 | + configLoaded := false |
| 89 | + if configFile != "" { |
| 90 | + raw, err := os.ReadFile(configFile) |
| 91 | + if err != nil { |
| 92 | + return nil, fmt.Errorf("failed to read config file %s: %w", configFile, err) |
| 93 | + } |
| 94 | + expanded := os.ExpandEnv(string(raw)) |
| 95 | + if err := v.ReadConfig(bytes.NewBufferString(expanded)); err != nil { |
| 96 | + return nil, fmt.Errorf("failed to parse config file: %w", err) |
| 97 | + } |
| 98 | + configLoaded = true |
| 99 | + } else { |
| 100 | + // Let Viper find the config file via search paths |
| 101 | + if err := v.ReadInConfig(); err != nil { |
| 102 | + if _, ok := err.(viper.ConfigFileNotFoundError); !ok { |
| 103 | + return nil, fmt.Errorf("failed to read config file: %w", err) |
| 104 | + } |
| 105 | + // Config file not found is OK, we'll use defaults + env |
| 106 | + } else { |
| 107 | + // Re-read the found file with env expansion |
| 108 | + foundFile := v.ConfigFileUsed() |
| 109 | + if foundFile != "" { |
| 110 | + raw, err := os.ReadFile(foundFile) |
| 111 | + if err == nil { |
| 112 | + expanded := os.ExpandEnv(string(raw)) |
| 113 | + _ = v.ReadConfig(bytes.NewBufferString(expanded)) |
| 114 | + } |
| 115 | + } |
| 116 | + configLoaded = true |
88 | 117 | } |
89 | | - // Config file not found is OK, we'll use defaults + env |
90 | 118 | } |
| 119 | + _ = configLoaded // suppress unused warning |
91 | 120 |
|
92 | 121 | // Configure environment variables |
93 | 122 | v.SetEnvPrefix(l.envPrefix) |
|
0 commit comments