194 lines
5.6 KiB
Go
194 lines
5.6 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
// Config 调度中心配置
|
|
type Config struct {
|
|
Server ServerConfig `mapstructure:"server"`
|
|
SOCKS5 SOCKS5Config `mapstructure:"socks5"`
|
|
Database DatabaseConfig `mapstructure:"database"`
|
|
Redis RedisConfig `mapstructure:"redis"`
|
|
Scheduler SchedulerConfig `mapstructure:"scheduler"`
|
|
Logging LoggingConfig `mapstructure:"logging"`
|
|
Install InstallConfig `mapstructure:"install"`
|
|
}
|
|
|
|
type ServerConfig struct {
|
|
Host string `mapstructure:"host"`
|
|
Port int `mapstructure:"port"`
|
|
Mode string `mapstructure:"mode"`
|
|
}
|
|
|
|
type SOCKS5Config struct {
|
|
Host string `mapstructure:"host"`
|
|
Port int `mapstructure:"port"`
|
|
MaxConnections int `mapstructure:"max_connections"`
|
|
Timeout int `mapstructure:"timeout"`
|
|
}
|
|
|
|
type DatabaseConfig struct {
|
|
Type string `mapstructure:"type"` // sqlite, postgres
|
|
Host string `mapstructure:"host"`
|
|
Port int `mapstructure:"port"`
|
|
User string `mapstructure:"user"`
|
|
Password string `mapstructure:"password"`
|
|
Database string `mapstructure:"database"`
|
|
SSLMode string `mapstructure:"sslmode"`
|
|
Path string `mapstructure:"path"` // SQLite 数据库文件路径
|
|
}
|
|
|
|
func (c DatabaseConfig) DSN() string {
|
|
if c.Type == "sqlite" {
|
|
return c.Path
|
|
}
|
|
return fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s",
|
|
c.Host, c.Port, c.User, c.Password, c.Database, c.SSLMode)
|
|
}
|
|
|
|
type RedisConfig struct {
|
|
Enabled bool `mapstructure:"enabled"`
|
|
Host string `mapstructure:"host"`
|
|
Port int `mapstructure:"port"`
|
|
Password string `mapstructure:"password"`
|
|
DB int `mapstructure:"db"`
|
|
}
|
|
|
|
func (c RedisConfig) Addr() string {
|
|
return fmt.Sprintf("%s:%d", c.Host, c.Port)
|
|
}
|
|
|
|
type SchedulerConfig struct {
|
|
Strategy string `mapstructure:"strategy"`
|
|
HealthCheckInterval int `mapstructure:"health_check_interval"`
|
|
UnlockCheckInterval int `mapstructure:"unlock_check_interval"`
|
|
NodeTimeout int `mapstructure:"node_timeout"`
|
|
}
|
|
|
|
type LoggingConfig struct {
|
|
Level string `mapstructure:"level"`
|
|
Output string `mapstructure:"output"`
|
|
File string `mapstructure:"file"`
|
|
}
|
|
|
|
type InstallConfig struct {
|
|
Installed bool `mapstructure:"installed"`
|
|
}
|
|
|
|
// Load 加载配置
|
|
func Load(configPath string) (*Config, error) {
|
|
viper.SetConfigFile(configPath)
|
|
viper.SetConfigType("yaml")
|
|
|
|
// 设置默认值
|
|
viper.SetDefault("server.host", "0.0.0.0")
|
|
viper.SetDefault("server.port", 8080)
|
|
viper.SetDefault("server.mode", "release")
|
|
viper.SetDefault("database.type", "sqlite")
|
|
viper.SetDefault("database.path", "data/proxy.db")
|
|
viper.SetDefault("redis.enabled", false)
|
|
viper.SetDefault("install.installed", false)
|
|
|
|
if err := viper.ReadInConfig(); err != nil {
|
|
return nil, fmt.Errorf("读取配置文件失败: %w", err)
|
|
}
|
|
|
|
var config Config
|
|
if err := viper.Unmarshal(&config); err != nil {
|
|
return nil, fmt.Errorf("解析配置失败: %w", err)
|
|
}
|
|
|
|
return &config, nil
|
|
}
|
|
|
|
// Save 保存配置
|
|
func Save(configPath string, cfg *Config) error {
|
|
viper.Set("server", cfg.Server)
|
|
viper.Set("socks5", cfg.SOCKS5)
|
|
viper.Set("database", cfg.Database)
|
|
viper.Set("redis", cfg.Redis)
|
|
viper.Set("scheduler", cfg.Scheduler)
|
|
viper.Set("logging", cfg.Logging)
|
|
viper.Set("install", cfg.Install)
|
|
|
|
if err := viper.WriteConfig(); err != nil {
|
|
return fmt.Errorf("写入配置文件失败: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// AgentConfig 节点 Agent 配置
|
|
type AgentConfig struct {
|
|
Agent AgentSettings `mapstructure:"agent"`
|
|
Scheduler SchedulerConn `mapstructure:"scheduler"`
|
|
WARP WARPConfig `mapstructure:"warp"`
|
|
SOCKS5 SOCKS5Config `mapstructure:"socks5"`
|
|
Unlock UnlockConfig `mapstructure:"unlock"`
|
|
Routing RoutingConfig `mapstructure:"routing"`
|
|
Logging LoggingConfig `mapstructure:"logging"`
|
|
}
|
|
|
|
type AgentSettings struct {
|
|
NodeID string `mapstructure:"node_id"`
|
|
Name string `mapstructure:"name"`
|
|
Region string `mapstructure:"region"`
|
|
}
|
|
|
|
type SchedulerConn struct {
|
|
Host string `mapstructure:"host"`
|
|
APIKey string `mapstructure:"api_key"`
|
|
HeartbeatInterval int `mapstructure:"heartbeat_interval"`
|
|
ReportInterval int `mapstructure:"report_interval"`
|
|
}
|
|
|
|
type WARPConfig struct {
|
|
Enabled bool `mapstructure:"enabled"`
|
|
SOCKS5Port int `mapstructure:"socks5_port"`
|
|
RefreshCooldown int `mapstructure:"refresh_cooldown"`
|
|
MaxRefreshRetries int `mapstructure:"max_refresh_retries"`
|
|
RefreshRetryDelayMin int `mapstructure:"refresh_retry_delay_min"`
|
|
RefreshRetryDelayMax int `mapstructure:"refresh_retry_delay_max"`
|
|
}
|
|
|
|
type UnlockConfig struct {
|
|
CheckInterval int `mapstructure:"check_interval"`
|
|
Services []ServiceConfig `mapstructure:"services"`
|
|
}
|
|
|
|
type ServiceConfig struct {
|
|
Name string `mapstructure:"name"`
|
|
URL string `mapstructure:"url"`
|
|
SuccessKeywords []string `mapstructure:"success_keywords"`
|
|
FailKeywords []string `mapstructure:"fail_keywords"`
|
|
}
|
|
|
|
type RoutingConfig struct {
|
|
WARPRoutes []RouteRule `mapstructure:"warp_routes"`
|
|
DirectRoutes []RouteRule `mapstructure:"direct_routes"`
|
|
}
|
|
|
|
type RouteRule struct {
|
|
Port int `mapstructure:"port"`
|
|
Domains []string `mapstructure:"domains"`
|
|
}
|
|
|
|
// LoadAgent 加载 Agent 配置
|
|
func LoadAgent(configPath string) (*AgentConfig, error) {
|
|
viper.SetConfigFile(configPath)
|
|
viper.SetConfigType("yaml")
|
|
|
|
if err := viper.ReadInConfig(); err != nil {
|
|
return nil, fmt.Errorf("读取配置文件失败: %w", err)
|
|
}
|
|
|
|
var config AgentConfig
|
|
if err := viper.Unmarshal(&config); err != nil {
|
|
return nil, fmt.Errorf("解析配置失败: %w", err)
|
|
}
|
|
|
|
return &config, nil
|
|
}
|