Files
zeromesh/internal/config/config.go

143 lines
3.4 KiB
Go

package config
import (
"fmt"
"os"
"gopkg.in/yaml.v3"
)
type Config struct {
Server ServerConfig `yaml:"server"`
Database DatabaseConfig `yaml:"database"`
JWT JWTConfig `yaml:"jwt"`
Controller ControllerConfig `yaml:"controller"`
Agent AgentConfig `yaml:"agent"`
Relay RelayConfig `yaml:"relay"`
CORS CORSConfig `yaml:"cors"`
RateLimit RateLimitConfig `yaml:"rate_limit"`
Logging LoggingConfig `yaml:"logging"`
Env EnvConfig `yaml:"env"`
}
type ServerConfig struct {
Port int `yaml:"port"`
}
func (s *ServerConfig) Addr() string {
return fmt.Sprintf(":%d", s.Port)
}
type DatabaseConfig struct {
Driver string `yaml:"driver"`
AutoMigrate bool `yaml:"auto_migrate"`
InitData bool `yaml:"init_data"`
SQLite SQLiteConfig `yaml:"sqlite"`
MySQL MySQLConfig `yaml:"mysql"`
}
type SQLiteConfig struct {
Path string `yaml:"path"`
}
type MySQLConfig struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
Username string `yaml:"username"`
Password string `yaml:"password"`
Database string `yaml:"database"`
Charset string `yaml:"charset"`
MaxIdleConns int `yaml:"max_idle_conns"`
MaxOpenConns int `yaml:"max_open_conns"`
}
type JWTConfig struct {
Secret string `yaml:"secret"`
ExpireHours int `yaml:"expire_hours"`
}
type ControllerConfig struct {
ListenPort int `yaml:"listen_port"`
PublicEndpoint string `yaml:"public_endpoint"`
PlanetID string `yaml:"planet_id"`
}
type AgentConfig struct {
ControllerURL string `yaml:"controller_url"`
ListenPort int `yaml:"listen_port"`
TAPName string `yaml:"tap_name"`
TAPMTU int `yaml:"tap_mtu"`
NetworkID uint32 `yaml:"network_id"`
PSK string `yaml:"psk"`
StaticPeers []string `yaml:"static_peers"`
}
type RelayConfig struct {
ListenPort int `yaml:"listen_port"`
Realm string `yaml:"realm"`
}
type CORSConfig struct {
AllowedOrigins []string `yaml:"allowed_origins"`
}
type RateLimitConfig struct {
Enabled bool `yaml:"enabled"`
RequestsPerSecond int `yaml:"requests_per_second"`
BurstSize int `yaml:"burst_size"`
}
type LoggingConfig struct {
Level string `yaml:"level"`
Format string `yaml:"format"`
}
type EnvConfig struct {
Name string `yaml:"name"`
}
func Load(path string) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("read config: %w", err)
}
var cfg Config
if err := yaml.Unmarshal(data, &cfg); err != nil {
return nil, fmt.Errorf("parse config: %w", err)
}
setDefaults(&cfg)
return &cfg, nil
}
func setDefaults(cfg *Config) {
if cfg.Server.Port == 0 {
cfg.Server.Port = 10001
}
if cfg.Controller.ListenPort == 0 {
cfg.Controller.ListenPort = 9993
}
if cfg.Agent.TAPName == "" {
cfg.Agent.TAPName = "zeromesh0"
}
if cfg.Agent.TAPMTU == 0 {
cfg.Agent.TAPMTU = 2800
}
if cfg.JWT.ExpireHours == 0 {
cfg.JWT.ExpireHours = 720
}
if cfg.Logging.Level == "" {
cfg.Logging.Level = "info"
}
if cfg.Env.Name == "" {
cfg.Env.Name = "dev"
}
}
func (d *DatabaseConfig) BuildDSN() string {
if d.Driver == "mysql" {
return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=True&loc=Local",
d.MySQL.Username, d.MySQL.Password, d.MySQL.Host, d.MySQL.Port, d.MySQL.Database, d.MySQL.Charset)
}
return ""
}