refactor: simplify config validation

This commit is contained in:
2026-08-30 19:54:34 +02:00
parent dd77a61b18
commit b364bee265
+37 -64
View File
@@ -3,97 +3,70 @@ package config
import ( import (
"fmt" "fmt"
"os" "os"
"strconv"
"gopkg.in/yaml.v3"
) )
// Config is the top-level server configuration. // Config is the top-level server configuration.
type Config struct { type Config struct {
Server ServerConfig `yaml:"server"` Server ServerConfig
Auth AuthConfig `yaml:"auth"` Auth AuthConfig
Storage StorageConfig `yaml:"storage"` Storage StorageConfig
TLS TLSConfig `yaml:"tls"` Logging LoggingConfig
Logging LoggingConfig `yaml:"logging"`
} }
type ServerConfig struct { type ServerConfig struct {
Host string `yaml:"host"` Host string
Port int `yaml:"port"` Port int
// Base URL used in DAV responses (e.g. https://dav.example.com) BaseURL string
BaseURL string `yaml:"base_url"`
} }
type AuthConfig struct { type AuthConfig struct {
// Realm shown in WWW-Authenticate header Realm string
Realm string `yaml:"realm"`
} }
type StorageConfig struct { type StorageConfig struct {
// Root directory for all data DataDir string
DataDir string `yaml:"data_dir"`
}
type TLSConfig struct {
Enabled bool `yaml:"enabled"`
CertFile string `yaml:"cert_file"`
KeyFile string `yaml:"key_file"`
} }
type LoggingConfig struct { type LoggingConfig struct {
Level string `yaml:"level"` // debug | info | warn | error Level string
Format string `yaml:"format"` // text | json Format string
} }
// Load reads and parses a YAML config file. // Load reads and parses environment variables to create the configuration.
func Load(path string) (*Config, error) { func Load() (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("reading config %q: %w", path, err)
}
cfg := &Config{} cfg := &Config{}
if err := yaml.Unmarshal(data, cfg); err != nil {
return nil, fmt.Errorf("parsing config %q: %w", path, err)
}
cfg.applyDefaults() cfg.applyDefaults()
return cfg, nil
return cfg, cfg.validate()
} }
func (c *Config) applyDefaults() { func (c *Config) applyDefaults() {
if c.Server.Host == "" { c.Server.Host = getEnv("NIDUS_HOST", "0.0.0.0")
c.Server.Host = "0.0.0.0" c.Server.Port = getEnvInt("NIDUS_PORT", 8080)
} c.Server.BaseURL = getEnv("NIDUS_BASE_URL", "")
if c.Server.Port == 0 {
c.Server.Port = 8080
}
if c.Server.BaseURL == "" { if c.Server.BaseURL == "" {
scheme := "http" c.Server.BaseURL = fmt.Sprintf("http://%s:%d", c.Server.Host, c.Server.Port)
if c.TLS.Enabled {
scheme = "https"
}
c.Server.BaseURL = fmt.Sprintf("%s://%s:%d", scheme, c.Server.Host, c.Server.Port)
}
if c.Auth.Realm == "" {
c.Auth.Realm = "DAV Server"
}
if c.Storage.DataDir == "" {
c.Storage.DataDir = "./data"
}
if c.Logging.Level == "" {
c.Logging.Level = "info"
}
if c.Logging.Format == "" {
c.Logging.Format = "text"
} }
c.Auth.Realm = getEnv("NIDUS_AUTH_REALM", "DAV Server")
c.Storage.DataDir = getEnv("NIDUS_DATA_DIR", "./data")
c.Logging.Level = getEnv("NIDUS_LOG_LEVEL", "info")
c.Logging.Format = getEnv("NIDUS_LOG_FORMAT", "text")
} }
func (c *Config) validate() error { func getEnv(key string, defaultValue string) string {
if c.TLS.Enabled { if val := os.Getenv(key); val != "" {
if c.TLS.CertFile == "" || c.TLS.KeyFile == "" { return val
return fmt.Errorf("tls.cert_file and tls.key_file are required when tls is enabled") }
return defaultValue
}
func getEnvInt(key string, defaultValue int) int {
if val := os.Getenv(key); val != "" {
if intVal, err := strconv.Atoi(val); err == nil {
return intVal
} }
} }
return nil return defaultValue
} }