2026-04-07 11:48:19 +08:00

208 lines
5.9 KiB
Go

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
}