package deployer import ( "certimate/internal/applicant" "certimate/internal/domain" "certimate/internal/utils/app" "context" "encoding/json" "errors" "fmt" "strings" "github.com/pocketbase/pocketbase/models" ) const ( targetAliyunOss = "aliyun-oss" targetAliyunCdn = "aliyun-cdn" targetAliyunEsa = "aliyun-dcdn" targetSSH = "ssh" targetWebhook = "webhook" targetTencentCdn = "tencent-cdn" targetQiniuCdn = "qiniu-cdn" targetLocal = "local" ) type DeployerOption struct { DomainId string `json:"domainId"` Domain string `json:"domain"` Product string `json:"product"` Access string `json:"access"` AceessRecord *models.Record `json:"-"` DeployConfig domain.DeployConfig `json:"deployConfig"` Certificate applicant.Certificate `json:"certificate"` Variables map[string]string `json:"variables"` } type Deployer interface { Deploy(ctx context.Context) error GetInfo() []string GetID() string } func Gets(record *models.Record, cert *applicant.Certificate) ([]Deployer, error) { rs := make([]Deployer, 0) if record.GetString("deployConfig") == "" { return rs, nil } deployConfigs := make([]domain.DeployConfig, 0) err := record.UnmarshalJSONField("deployConfig", &deployConfigs) if err != nil { return nil, fmt.Errorf("解析部署配置失败: %w", err) } if len(deployConfigs) == 0 { return rs, nil } for _, deployConfig := range deployConfigs { deployer, err := getWithDeployConfig(record, cert, deployConfig) if err != nil { return nil, err } rs = append(rs, deployer) } return rs, nil } func getWithDeployConfig(record *models.Record, cert *applicant.Certificate, deployConfig domain.DeployConfig) (Deployer, error) { access, err := app.GetApp().Dao().FindRecordById("access", deployConfig.Access) if err != nil { return nil, fmt.Errorf("access record not found: %w", err) } option := &DeployerOption{ DomainId: record.Id, Domain: record.GetString("domain"), Product: getProduct(deployConfig.Type), Access: access.GetString("config"), AceessRecord: access, DeployConfig: deployConfig, } if cert != nil { option.Certificate = *cert } else { option.Certificate = applicant.Certificate{ Certificate: record.GetString("certificate"), PrivateKey: record.GetString("privateKey"), } } switch deployConfig.Type { case targetAliyunOss: return NewAliyun(option) case targetAliyunCdn: return NewAliyunCdn(option) case targetAliyunEsa: return NewAliyunEsa(option) case targetSSH: return NewSSH(option) case targetWebhook: return NewWebhook(option) case targetTencentCdn: return NewTencentCdn(option) case targetQiniuCdn: return NewQiNiu(option) case targetLocal: return NewLocal(option), nil } return nil, errors.New("not implemented") } func getProduct(t string) string { rs := strings.Split(t, "-") if len(rs) < 2 { return "" } return rs[1] } func toStr(tag string, data any) string { if data == nil { return tag } byts, _ := json.Marshal(data) return tag + ":" + string(byts) } func getDeployString(conf domain.DeployConfig, key string) string { if _, ok := conf.Config[key]; !ok { return "" } val, ok := conf.Config[key].(string) if !ok { return "" } return val } func getDeployVariables(conf domain.DeployConfig) map[string]string { rs := make(map[string]string) data, ok := conf.Config["variables"] if !ok { return rs } bts, _ := json.Marshal(data) kvData := make([]domain.KV, 0) if err := json.Unmarshal(bts, &kvData); err != nil { return rs } for _, kv := range kvData { rs[kv.Key] = kv.Value } return rs }