mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-21 04:10:58 +00:00
Merge pull request #4930 from wucm667/fix/issue-4928-config-file-path
fix(config): honor explicit CONFIG_FILE path
This commit is contained in:
@@ -1640,20 +1640,7 @@ func LoadForBootstrap() (*Config, error) {
|
||||
func load(allowMissingJWTSecret bool) (*Config, error) {
|
||||
viper.SetConfigName("config")
|
||||
viper.SetConfigType("yaml")
|
||||
|
||||
// Add config paths in priority order
|
||||
// 1. DATA_DIR environment variable (highest priority)
|
||||
if dataDir := os.Getenv("DATA_DIR"); dataDir != "" {
|
||||
viper.AddConfigPath(dataDir)
|
||||
}
|
||||
// 2. Docker data directory
|
||||
viper.AddConfigPath("/app/data")
|
||||
// 3. Current directory
|
||||
viper.AddConfigPath(".")
|
||||
// 4. Config subdirectory
|
||||
viper.AddConfigPath("./config")
|
||||
// 5. System config directory
|
||||
viper.AddConfigPath("/etc/sub2api")
|
||||
configureConfigSource(viper.SetConfigFile, viper.AddConfigPath)
|
||||
|
||||
// 环境变量支持
|
||||
viper.AutomaticEnv()
|
||||
@@ -1828,6 +1815,22 @@ func load(allowMissingJWTSecret bool) (*Config, error) {
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
func configureConfigSource(setConfigFile, addConfigPath func(string)) {
|
||||
if configFile := strings.TrimSpace(os.Getenv("CONFIG_FILE")); configFile != "" {
|
||||
setConfigFile(configFile)
|
||||
return
|
||||
}
|
||||
|
||||
// Add config paths in priority order.
|
||||
if dataDir := strings.TrimSpace(os.Getenv("DATA_DIR")); dataDir != "" {
|
||||
addConfigPath(dataDir)
|
||||
}
|
||||
addConfigPath("/app/data")
|
||||
addConfigPath(".")
|
||||
addConfigPath("./config")
|
||||
addConfigPath("/etc/sub2api")
|
||||
}
|
||||
|
||||
func setDefaults() {
|
||||
viper.SetDefault("run_mode", RunModeStandard)
|
||||
|
||||
@@ -3488,14 +3491,12 @@ func generateJWTSecret(byteLength int) (string, error) {
|
||||
// GetServerAddress returns the server address (host:port) from config file or environment variable.
|
||||
// This is a lightweight function that can be used before full config validation,
|
||||
// such as during setup wizard startup.
|
||||
// Priority: config.yaml > environment variables > defaults
|
||||
// Priority: environment variables > config file > defaults.
|
||||
func GetServerAddress() string {
|
||||
v := viper.New()
|
||||
v.SetConfigName("config")
|
||||
v.SetConfigType("yaml")
|
||||
v.AddConfigPath(".")
|
||||
v.AddConfigPath("./config")
|
||||
v.AddConfigPath("/etc/sub2api")
|
||||
configureConfigSource(v.SetConfigFile, v.AddConfigPath)
|
||||
|
||||
// Support SERVER_HOST and SERVER_PORT environment variables
|
||||
v.AutomaticEnv()
|
||||
|
||||
@@ -17,6 +17,9 @@ import (
|
||||
func resetViperWithJWTSecret(t *testing.T) {
|
||||
t.Helper()
|
||||
viper.Reset()
|
||||
t.Cleanup(viper.Reset)
|
||||
t.Setenv("CONFIG_FILE", "")
|
||||
t.Setenv("DATA_DIR", "")
|
||||
t.Setenv("JWT_SECRET", strings.Repeat("x", 32))
|
||||
}
|
||||
|
||||
@@ -253,8 +256,53 @@ func TestLoadTrustedProxiesPresenceFromYAML(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadTrustedProxiesFromConfigFile(t *testing.T) {
|
||||
resetViperWithJWTSecret(t)
|
||||
configFile := filepath.Join(t.TempDir(), "reporter-config.yaml")
|
||||
require.NoError(t, os.WriteFile(configFile, []byte(`server:
|
||||
host: 192.0.2.10
|
||||
trusted_proxies:
|
||||
- 127.0.0.1/32
|
||||
- 10.0.0.0/8
|
||||
- 172.16.0.0/12
|
||||
- 192.168.0.0/16
|
||||
`), 0o600))
|
||||
t.Setenv("CONFIG_FILE", configFile)
|
||||
|
||||
cfg, err := Load()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "192.0.2.10", cfg.Server.Host)
|
||||
require.Equal(t, []string{"127.0.0.1/32", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}, cfg.Server.TrustedProxies)
|
||||
require.True(t, cfg.Server.TrustedProxiesConfigured)
|
||||
}
|
||||
|
||||
func TestConfigFileTakesPrecedenceOverDataDir(t *testing.T) {
|
||||
resetViperWithJWTSecret(t)
|
||||
dataDir := t.TempDir()
|
||||
require.NoError(t, os.WriteFile(filepath.Join(dataDir, "config.yaml"), []byte("server:\n host: 192.0.2.20\n"), 0o600))
|
||||
configFile := filepath.Join(t.TempDir(), "explicit.yaml")
|
||||
require.NoError(t, os.WriteFile(configFile, []byte("server:\n host: 192.0.2.30\n"), 0o600))
|
||||
t.Setenv("DATA_DIR", dataDir)
|
||||
t.Setenv("CONFIG_FILE", configFile)
|
||||
|
||||
cfg, err := Load()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "192.0.2.30", cfg.Server.Host)
|
||||
}
|
||||
|
||||
func TestLoadReturnsErrorForMissingConfigFile(t *testing.T) {
|
||||
resetViperWithJWTSecret(t)
|
||||
t.Setenv("CONFIG_FILE", filepath.Join(t.TempDir(), "missing.yaml"))
|
||||
|
||||
_, err := Load()
|
||||
require.ErrorContains(t, err, "read config error")
|
||||
}
|
||||
|
||||
func TestLoadForBootstrapAllowsMissingJWTSecret(t *testing.T) {
|
||||
viper.Reset()
|
||||
t.Cleanup(viper.Reset)
|
||||
t.Setenv("CONFIG_FILE", "")
|
||||
t.Setenv("DATA_DIR", "")
|
||||
t.Setenv("JWT_SECRET", "")
|
||||
|
||||
cfg, err := LoadForBootstrap()
|
||||
@@ -1155,6 +1203,8 @@ func TestNormalizeStringSlice(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetServerAddressFromEnv(t *testing.T) {
|
||||
t.Setenv("CONFIG_FILE", "")
|
||||
t.Setenv("DATA_DIR", "")
|
||||
t.Setenv("SERVER_HOST", "127.0.0.1")
|
||||
t.Setenv("SERVER_PORT", "9090")
|
||||
|
||||
@@ -1164,6 +1214,17 @@ func TestGetServerAddressFromEnv(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetServerAddressFromConfigFile(t *testing.T) {
|
||||
configFile := filepath.Join(t.TempDir(), "setup.yaml")
|
||||
require.NoError(t, os.WriteFile(configFile, []byte("server:\n host: 192.0.2.40\n port: 9191\n"), 0o600))
|
||||
t.Setenv("CONFIG_FILE", configFile)
|
||||
t.Setenv("DATA_DIR", "")
|
||||
t.Setenv("SERVER_HOST", "")
|
||||
t.Setenv("SERVER_PORT", "")
|
||||
|
||||
require.Equal(t, "192.0.2.40:9191", GetServerAddress())
|
||||
}
|
||||
|
||||
func TestValidateAbsoluteHTTPURL(t *testing.T) {
|
||||
if err := ValidateAbsoluteHTTPURL("https://example.com/path"); err != nil {
|
||||
t.Fatalf("ValidateAbsoluteHTTPURL valid url error: %v", err)
|
||||
|
||||
Reference in New Issue
Block a user