package domain import ( "time" "github.com/usual2970/certimate/internal/pkg/utils/maputil" ) const CollectionNameWorkflow = "workflow" type Workflow struct { Meta Name string `json:"name" db:"name"` Description string `json:"description" db:"description"` Trigger WorkflowTriggerType `json:"trigger" db:"trigger"` TriggerCron string `json:"triggerCron" db:"triggerCron"` Enabled bool `json:"enabled" db:"enabled"` Content *WorkflowNode `json:"content" db:"content"` Draft *WorkflowNode `json:"draft" db:"draft"` HasDraft bool `json:"hasDraft" db:"hasDraft"` LastRunId string `json:"lastRunId" db:"lastRunId"` LastRunStatus WorkflowRunStatusType `json:"lastRunStatus" db:"lastRunStatus"` LastRunTime time.Time `json:"lastRunTime" db:"lastRunTime"` } type WorkflowNodeType string const ( WorkflowNodeTypeStart = WorkflowNodeType("start") WorkflowNodeTypeEnd = WorkflowNodeType("end") WorkflowNodeTypeApply = WorkflowNodeType("apply") WorkflowNodeTypeUpload = WorkflowNodeType("upload") WorkflowNodeTypeDeploy = WorkflowNodeType("deploy") WorkflowNodeTypeNotify = WorkflowNodeType("notify") WorkflowNodeTypeBranch = WorkflowNodeType("branch") WorkflowNodeTypeCondition = WorkflowNodeType("condition") WorkflowNodeTypeExecuteResultBranch = WorkflowNodeType("execute_result_branch") WorkflowNodeTypeExecuteSuccess = WorkflowNodeType("execute_success") WorkflowNodeTypeExecuteFailure = WorkflowNodeType("execute_failure") ) type WorkflowTriggerType string const ( WorkflowTriggerTypeAuto = WorkflowTriggerType("auto") WorkflowTriggerTypeManual = WorkflowTriggerType("manual") ) type WorkflowNode struct { Id string `json:"id"` Type WorkflowNodeType `json:"type"` Name string `json:"name"` Config map[string]any `json:"config"` Inputs []WorkflowNodeIO `json:"inputs"` Outputs []WorkflowNodeIO `json:"outputs"` Next *WorkflowNode `json:"next,omitempty"` Branches []WorkflowNode `json:"branches,omitempty"` Validated bool `json:"validated"` } type WorkflowNodeConfigForApply struct { Domains string `json:"domains"` // 域名列表,以半角分号分隔 ContactEmail string `json:"contactEmail"` // 联系邮箱 ChallengeType string `json:"challengeType"` // TODO: 验证方式。目前仅支持 dns-01 Provider string `json:"provider"` // DNS 提供商 ProviderAccessId string `json:"providerAccessId"` // DNS 提供商授权记录 ID ProviderConfig map[string]any `json:"providerConfig"` // DNS 提供商额外配置 KeyAlgorithm string `json:"keyAlgorithm"` // 密钥算法 Nameservers string `json:"nameservers"` // DNS 服务器列表,以半角分号分隔 DnsPropagationTimeout int32 `json:"dnsPropagationTimeout"` // DNS 传播超时时间(零值取决于提供商的默认值) DnsTTL int32 `json:"dnsTTL"` // DNS TTL(零值取决于提供商的默认值) DisableFollowCNAME bool `json:"disableFollowCNAME"` // 是否关闭 CNAME 跟随 DisableARI bool `json:"disableARI"` // 是否关闭 ARI SkipBeforeExpiryDays int32 `json:"skipBeforeExpiryDays"` // 证书到期前多少天前跳过续期(零值将使用默认值 30) } type WorkflowNodeConfigForUpload struct { Certificate string `json:"certificate"` PrivateKey string `json:"privateKey"` Domains string `json:"domains"` } type WorkflowNodeConfigForDeploy struct { Certificate string `json:"certificate"` // 前序节点输出的证书,形如“${NodeId}#certificate” Provider string `json:"provider"` // 主机提供商 ProviderAccessId string `json:"providerAccessId"` // 主机提供商授权记录 ID ProviderConfig map[string]any `json:"providerConfig"` // 主机提供商额外配置 SkipOnLastSucceeded bool `json:"skipOnLastSucceeded"` // 上次部署成功时是否跳过 } type WorkflowNodeConfigForNotify struct { Channel string `json:"channel"` // 通知渠道 Subject string `json:"subject"` // 通知主题 Message string `json:"message"` // 通知内容 } func (n *WorkflowNode) getConfigString(key string) string { return maputil.GetString(n.Config, key) } func (n *WorkflowNode) getConfigBool(key string) bool { return maputil.GetBool(n.Config, key) } func (n *WorkflowNode) getConfigInt32(key string) int32 { return maputil.GetInt32(n.Config, key) } func (n *WorkflowNode) getConfigMap(key string) map[string]any { if val, ok := n.Config[key]; ok { if result, ok := val.(map[string]any); ok { return result } } return make(map[string]any) } func (n *WorkflowNode) GetConfigForApply() WorkflowNodeConfigForApply { skipBeforeExpiryDays := n.getConfigInt32("skipBeforeExpiryDays") if skipBeforeExpiryDays == 0 { skipBeforeExpiryDays = 30 } return WorkflowNodeConfigForApply{ Domains: n.getConfigString("domains"), ContactEmail: n.getConfigString("contactEmail"), Provider: n.getConfigString("provider"), ProviderAccessId: n.getConfigString("providerAccessId"), ProviderConfig: n.getConfigMap("providerConfig"), KeyAlgorithm: n.getConfigString("keyAlgorithm"), Nameservers: n.getConfigString("nameservers"), DnsPropagationTimeout: n.getConfigInt32("dnsPropagationTimeout"), DnsTTL: n.getConfigInt32("dnsTTL"), DisableFollowCNAME: n.getConfigBool("disableFollowCNAME"), DisableARI: n.getConfigBool("disableARI"), SkipBeforeExpiryDays: skipBeforeExpiryDays, } } func (n *WorkflowNode) GetConfigForUpload() WorkflowNodeConfigForUpload { return WorkflowNodeConfigForUpload{ Certificate: n.getConfigString("certificate"), PrivateKey: n.getConfigString("privateKey"), Domains: n.getConfigString("domains"), } } func (n *WorkflowNode) GetConfigForDeploy() WorkflowNodeConfigForDeploy { return WorkflowNodeConfigForDeploy{ Certificate: n.getConfigString("certificate"), Provider: n.getConfigString("provider"), ProviderAccessId: n.getConfigString("providerAccessId"), ProviderConfig: n.getConfigMap("providerConfig"), SkipOnLastSucceeded: n.getConfigBool("skipOnLastSucceeded"), } } func (n *WorkflowNode) GetConfigForNotify() WorkflowNodeConfigForNotify { return WorkflowNodeConfigForNotify{ Channel: n.getConfigString("channel"), Subject: n.getConfigString("subject"), Message: n.getConfigString("message"), } } type WorkflowNodeIO struct { Label string `json:"label"` Name string `json:"name"` Type string `json:"type"` Required bool `json:"required"` Value any `json:"value"` ValueSelector WorkflowNodeIOValueSelector `json:"valueSelector"` } type WorkflowNodeIOValueSelector struct { Id string `json:"id"` Name string `json:"name"` } const WorkflowNodeIONameCertificate string = "certificate"