feat: load backend config from yaml
This commit is contained in:
@@ -1,32 +1,44 @@
|
||||
package config
|
||||
|
||||
import "os"
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Env string
|
||||
Port string
|
||||
DatabaseURL string
|
||||
StorageDir string
|
||||
AuthSecret string
|
||||
SystemAIKey string
|
||||
AIKeyEncryptionSecret string
|
||||
Env string `yaml:"env"`
|
||||
Port string `yaml:"port"`
|
||||
DatabaseURL string `yaml:"database_url"`
|
||||
StorageDir string `yaml:"storage_dir"`
|
||||
AuthSecret string `yaml:"auth_secret"`
|
||||
SystemAIKey string `yaml:"system_ai_key"`
|
||||
AIKeyEncryptionSecret string `yaml:"ai_key_encryption_secret"`
|
||||
}
|
||||
|
||||
func Load() Config {
|
||||
return Config{
|
||||
Env: getenv("APP_ENV", "development"),
|
||||
Port: getenv("PORT", "8080"),
|
||||
DatabaseURL: getenv("DATABASE_URL", "postgres://agent:agent@localhost:5432/agent?sslmode=disable"),
|
||||
StorageDir: getenv("STORAGE_DIR", "./data/files"),
|
||||
AuthSecret: getenv("AUTH_SECRET", "development-auth-secret-change-me"),
|
||||
SystemAIKey: os.Getenv("SYSTEM_AI_KEY"),
|
||||
AIKeyEncryptionSecret: getenv("AI_KEY_ENCRYPTION_SECRET", "development-ai-key-secret-change-me"),
|
||||
cfg, err := LoadFromDir("etc")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
func getenv(key string, fallback string) string {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
return value
|
||||
func LoadFromDir(configDir string) (Config, error) {
|
||||
mode := strings.TrimSpace(os.Getenv("SENLIN_APP_MODE"))
|
||||
if mode == "" {
|
||||
mode = "dev"
|
||||
}
|
||||
return fallback
|
||||
path := filepath.Join(configDir, "agent."+strings.ToLower(mode)+".yaml")
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
var cfg Config
|
||||
if err := yaml.Unmarshal(data, &cfg); err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
57
backend/internal/config/config_test.go
Normal file
57
backend/internal/config/config_test.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestLoadFromDirDefaultsToDevYAML(t *testing.T) {
|
||||
configDir := t.TempDir()
|
||||
writeConfig(t, configDir, "agent.dev.yaml", "development", "18080", "postgres://dev", "./dev-files", "dev-auth", "dev-system", "dev-ai")
|
||||
t.Setenv("SENLIN_APP_MODE", "")
|
||||
t.Setenv("PORT", "9999")
|
||||
|
||||
cfg, err := LoadFromDir(configDir)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "development", cfg.Env)
|
||||
require.Equal(t, "18080", cfg.Port)
|
||||
require.Equal(t, "postgres://dev", cfg.DatabaseURL)
|
||||
require.Equal(t, "./dev-files", cfg.StorageDir)
|
||||
require.Equal(t, "dev-auth", cfg.AuthSecret)
|
||||
require.Equal(t, "dev-system", cfg.SystemAIKey)
|
||||
require.Equal(t, "dev-ai", cfg.AIKeyEncryptionSecret)
|
||||
}
|
||||
|
||||
func TestLoadFromDirUsesSENLINAppMode(t *testing.T) {
|
||||
configDir := t.TempDir()
|
||||
writeConfig(t, configDir, "agent.dev.yaml", "development", "18080", "postgres://dev", "./dev-files", "dev-auth", "", "dev-ai")
|
||||
writeConfig(t, configDir, "agent.prod.yaml", "production", "80", "postgres://prod", "/data/files", "prod-auth", "prod-system", "prod-ai")
|
||||
t.Setenv("SENLIN_APP_MODE", "prod")
|
||||
|
||||
cfg, err := LoadFromDir(configDir)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "production", cfg.Env)
|
||||
require.Equal(t, "80", cfg.Port)
|
||||
require.Equal(t, "postgres://prod", cfg.DatabaseURL)
|
||||
require.Equal(t, "/data/files", cfg.StorageDir)
|
||||
require.Equal(t, "prod-auth", cfg.AuthSecret)
|
||||
require.Equal(t, "prod-system", cfg.SystemAIKey)
|
||||
require.Equal(t, "prod-ai", cfg.AIKeyEncryptionSecret)
|
||||
}
|
||||
|
||||
func writeConfig(t *testing.T, dir string, name string, env string, port string, databaseURL string, storageDir string, authSecret string, systemAIKey string, aiKeySecret string) {
|
||||
t.Helper()
|
||||
content := []byte("env: " + env + "\n" +
|
||||
"port: \"" + port + "\"\n" +
|
||||
"database_url: \"" + databaseURL + "\"\n" +
|
||||
"storage_dir: \"" + storageDir + "\"\n" +
|
||||
"auth_secret: \"" + authSecret + "\"\n" +
|
||||
"system_ai_key: \"" + systemAIKey + "\"\n" +
|
||||
"ai_key_encryption_secret: \"" + aiKeySecret + "\"\n")
|
||||
require.NoError(t, os.WriteFile(filepath.Join(dir, name), content, 0o600))
|
||||
}
|
||||
Reference in New Issue
Block a user