package config import ( "flag" "fmt" "os" "time" "gopkg.in/yaml.v3" ) type Config struct { Version int `yaml:"version"` Env string `yaml:"env"` Project string `yaml:"project"` Region string `yaml:"region"` Platform PlatformConfig `yaml:"platform"` Database DatabaseConfig `yaml:"database"` Cache CacheConfig `yaml:"cache"` Queue QueueConfig `yaml:"queue"` Deploy DeployConfig `yaml:"deploy"` Build BuildConfig `yaml:"build"` TencentCloud TencentCloudConfig `yaml:"tencentcloud"` COS COSConfig `yaml:"cos"` TAT TATConfig `yaml:"tat"` Release ReleaseConfig `yaml:"release"` Services map[string]ServiceConfig `yaml:"services"` } type PlatformConfig struct { Name string `yaml:"name"` HTTPPort string `yaml:"http_port"` CORSOrigin string `yaml:"cors_origin"` } type DatabaseConfig struct { DSN string `yaml:"dsn"` } type CacheConfig struct { RedisAddr string `yaml:"redis_addr"` RedisPassword string `yaml:"redis_password"` } type QueueConfig struct { Driver string `yaml:"driver"` RocketMQNameserver string `yaml:"rocketmq_nameserver"` Topic string `yaml:"topic"` Group string `yaml:"group"` } type DeployConfig struct { HealthcheckInterval string `yaml:"healthcheck_interval"` ScriptWorkDir string `yaml:"script_work_dir"` OperatorScript string `yaml:"operator_script"` ConfigPath string `yaml:"config_path"` } type BuildConfig struct { ScriptWorkDir string `yaml:"script_work_dir"` OperatorScript string `yaml:"operator_script"` WorkspaceRoot string `yaml:"workspace_root"` RepoSearchRoots []string `yaml:"repo_search_roots"` GiteaClonePrefix string `yaml:"gitea_clone_prefix"` GitSSHCommand string `yaml:"git_ssh_command"` BuildHost string `yaml:"build_host"` } type TencentCloudConfig struct { SecretID string `yaml:"secret_id"` SecretKey string `yaml:"secret_key"` SessionToken string `yaml:"session_token"` } type COSConfig struct { Region string `yaml:"region"` Bucket string `yaml:"bucket"` ReleasesPrefix string `yaml:"releases_prefix"` StatePrefix string `yaml:"state_prefix"` OutputPrefix string `yaml:"output_prefix"` } type TATConfig struct { Region string `yaml:"region"` CommandName string `yaml:"command_name"` CommandType string `yaml:"command_type"` WorkingDirectory string `yaml:"working_directory"` ScriptPath string `yaml:"script_path"` TimeoutSeconds int `yaml:"timeout_seconds"` ExecutionUser string `yaml:"execution_user"` } type ReleaseConfig struct { Order []string `yaml:"order"` } type ServiceConfig struct { Repo string `yaml:"repo"` PackageName string `yaml:"package_name"` DeployRoot string `yaml:"deploy_root"` UnitName string `yaml:"unit_name"` HealthURL string `yaml:"health_url"` HTTPPort int `yaml:"http_port"` GRPCPort int `yaml:"grpc_port"` Rollout RolloutConfig `yaml:"rollout"` Build ServiceBuild `yaml:"build"` Instances []InstanceRef `yaml:"instances"` CLB CLBConfig `yaml:"clb"` } type ServiceBuild struct { RepoURL string `yaml:"repo_url"` RepoCandidates []string `yaml:"repo_candidates"` DefaultBranch string `yaml:"default_branch"` WorkDir string `yaml:"work_dir"` BinaryName string `yaml:"binary_name"` BuildTarget string `yaml:"build_target"` ConfigSource string `yaml:"config_source"` BuildCommand string `yaml:"build_command"` } type RolloutConfig struct { BatchSize int `yaml:"batch_size"` DrainSeconds int `yaml:"drain_seconds"` PauseSeconds int `yaml:"pause_seconds"` } type InstanceRef struct { InstanceID string `yaml:"instance_id"` Name string `yaml:"name"` PrivateIP string `yaml:"private_ip"` } type CLBConfig struct { LoadBalancerID string `yaml:"load_balancer_id"` ListenerID string `yaml:"listener_id"` LocationID string `yaml:"location_id"` Domain string `yaml:"domain"` URL string `yaml:"url"` BackendPort int `yaml:"backend_port"` OriginalWeight int `yaml:"original_weight"` Targets []CLBTarget `yaml:"targets"` } type CLBTarget struct { InstanceID string `yaml:"instance_id"` PrivateIP string `yaml:"private_ip"` Port int `yaml:"port"` Weight int `yaml:"weight"` } func Load() Config { configPath := "config/prod.yaml" flag.StringVar(&configPath, "config", configPath, "config yaml path") flag.Parse() data, err := os.ReadFile(configPath) if err != nil { panic(fmt.Errorf("read config: %w", err)) } var cfg Config if err := yaml.Unmarshal(data, &cfg); err != nil { panic(fmt.Errorf("parse config: %w", err)) } if cfg.Platform.Name == "" { cfg.Platform.Name = "app-deploy-platform" } if cfg.Platform.HTTPPort == "" { cfg.Platform.HTTPPort = "8080" } if cfg.Platform.CORSOrigin == "" { cfg.Platform.CORSOrigin = "*" } if cfg.Queue.Driver == "" { cfg.Queue.Driver = "rocketmq" } if cfg.Queue.Topic == "" { cfg.Queue.Topic = "app-deploy-platform.deployments" } if cfg.Queue.Group == "" { cfg.Queue.Group = "app-deploy-platform.backend" } if cfg.Deploy.ConfigPath == "" { cfg.Deploy.ConfigPath = configPath } if cfg.Build.ScriptWorkDir == "" { cfg.Build.ScriptWorkDir = cfg.Deploy.ScriptWorkDir } if cfg.Build.BuildHost == "" { cfg.Build.BuildHost = "build-node" } return cfg } func (c Config) HealthcheckIntervalDuration() time.Duration { if c.Deploy.HealthcheckInterval == "" { return 10 * time.Second } value, err := time.ParseDuration(c.Deploy.HealthcheckInterval) if err != nil { return 10 * time.Second } return value }