package config import ( "fmt" "time" "github.com/spf13/viper" ) type Config struct { Env string `mapstructure:"env"` Server ServerConfig `mapstructure:"server"` Databases map[string]DatabaseConf `mapstructure:"databases"` Docker DockerConfig `mapstructure:"docker"` Auth AuthConfig `mapstructure:"auth"` RateLimit RateLimitConfig `mapstructure:"rate_limit"` } type ServerConfig struct { Transport string `mapstructure:"transport"` // stdio | sse Addr string `mapstructure:"addr"` // :8080 for SSE mode } type DatabaseConf struct { Driver string `mapstructure:"driver"` // postgres | mysql DSN string `mapstructure:"dsn"` } type DockerConfig struct { Enabled bool `mapstructure:"enabled"` Host string `mapstructure:"host"` // unix:///var/run/docker.sock ContainerPattern string `mapstructure:"container_pattern"` MaxLogBytes int64 `mapstructure:"max_log_bytes"` MaxLogLines int `mapstructure:"max_log_lines"` MaxLogSince time.Duration `mapstructure:"max_log_since"` } type AuthConfig struct { Enabled bool `mapstructure:"enabled"` APIKeys map[string]string `mapstructure:"api_keys"` // key → description JWTSecret string `mapstructure:"jwt_secret"` } type RateLimitConfig struct { Enabled bool `mapstructure:"enabled"` Rate float64 `mapstructure:"rate"` // 每秒允许的请求数 Burst int `mapstructure:"burst"` // 突发允许数 } func Load(env string) (*Config, error) { v := viper.New() v.SetConfigName(env) // dev.yaml / staging.yaml / prod.yaml v.SetConfigType("yaml") v.AddConfigPath("./config") v.AddConfigPath(".") v.AddConfigPath("/config") v.SetEnvPrefix("OPS_MCP") v.AutomaticEnv() if err := v.ReadInConfig(); err != nil { return nil, fmt.Errorf("read config: %w", err) } // 设置默认值 v.SetDefault("server.transport", "stdio") v.SetDefault("server.addr", ":8080") v.SetDefault("docker.max_log_bytes", 1024*1024) v.SetDefault("docker.max_log_lines", 500) v.SetDefault("docker.max_log_since", "1h") v.SetDefault("rate_limit.rate", 10.0) v.SetDefault("rate_limit.burst", 20) var cfg Config if err := v.Unmarshal(&cfg); err != nil { return nil, fmt.Errorf("unmarshal config: %w", err) } return &cfg, nil }