mirror of https://github.com/usual2970/certimate
				
				
				
			refactor: clean code
							parent
							
								
									ecde12ec23
								
							
						
					
					
						commit
						6adcc61447
					
				|  | @ -51,11 +51,12 @@ func NewWithApplyNode(node *domain.WorkflowNode) (Applicant, error) { | |||
| 		return nil, fmt.Errorf("node type is not apply") | ||||
| 	} | ||||
| 
 | ||||
| 	nodeConfig := node.GetConfigForApply() | ||||
| 
 | ||||
| 	accessRepo := repository.NewAccessRepository() | ||||
| 	accessId := node.GetConfigString("providerAccessId") | ||||
| 	access, err := accessRepo.GetById(context.Background(), accessId) | ||||
| 	access, err := accessRepo.GetById(context.Background(), nodeConfig.ProviderAccessId) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to get access #%s record: %w", accessId, err) | ||||
| 		return nil, fmt.Errorf("failed to get access #%s record: %w", nodeConfig.ProviderAccessId, err) | ||||
| 	} | ||||
| 
 | ||||
| 	accessConfig, err := access.UnmarshalConfigToMap() | ||||
|  | @ -64,15 +65,15 @@ func NewWithApplyNode(node *domain.WorkflowNode) (Applicant, error) { | |||
| 	} | ||||
| 
 | ||||
| 	options := &applicantOptions{ | ||||
| 		Domains:              slices.Filter(strings.Split(node.GetConfigString("domains"), ";"), func(s string) bool { return s != "" }), | ||||
| 		ContactEmail:         node.GetConfigString("contactEmail"), | ||||
| 		Provider:             domain.ApplyDNSProviderType(node.GetConfigString("provider")), | ||||
| 		Domains:              slices.Filter(strings.Split(nodeConfig.Domains, ";"), func(s string) bool { return s != "" }), | ||||
| 		ContactEmail:         nodeConfig.ContactEmail, | ||||
| 		Provider:             domain.ApplyDNSProviderType(nodeConfig.Provider), | ||||
| 		ProviderAccessConfig: accessConfig, | ||||
| 		ProviderApplyConfig:  node.GetConfigMap("providerConfig"), | ||||
| 		KeyAlgorithm:         node.GetConfigString("keyAlgorithm"), | ||||
| 		Nameservers:          slices.Filter(strings.Split(node.GetConfigString("nameservers"), ";"), func(s string) bool { return s != "" }), | ||||
| 		PropagationTimeout:   node.GetConfigInt32("propagationTimeout"), | ||||
| 		DisableFollowCNAME:   node.GetConfigBool("disableFollowCNAME"), | ||||
| 		ProviderApplyConfig:  nodeConfig.ProviderConfig, | ||||
| 		KeyAlgorithm:         nodeConfig.KeyAlgorithm, | ||||
| 		Nameservers:          slices.Filter(strings.Split(nodeConfig.Nameservers, ";"), func(s string) bool { return s != "" }), | ||||
| 		PropagationTimeout:   nodeConfig.PropagationTimeout, | ||||
| 		DisableFollowCNAME:   nodeConfig.DisableFollowCNAME, | ||||
| 	} | ||||
| 
 | ||||
| 	applicant, err := createApplicant(options) | ||||
|  |  | |||
|  | @ -29,11 +29,12 @@ func NewWithDeployNode(node *domain.WorkflowNode, certdata struct { | |||
| 		return nil, fmt.Errorf("node type is not deploy") | ||||
| 	} | ||||
| 
 | ||||
| 	nodeConfig := node.GetConfigForDeploy() | ||||
| 
 | ||||
| 	accessRepo := repository.NewAccessRepository() | ||||
| 	accessId := node.GetConfigString("providerAccessId") | ||||
| 	access, err := accessRepo.GetById(context.Background(), accessId) | ||||
| 	access, err := accessRepo.GetById(context.Background(), nodeConfig.ProviderAccessId) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to get access #%s record: %w", accessId, err) | ||||
| 		return nil, fmt.Errorf("failed to get access #%s record: %w", nodeConfig.ProviderAccessId, err) | ||||
| 	} | ||||
| 
 | ||||
| 	accessConfig, err := access.UnmarshalConfigToMap() | ||||
|  | @ -42,9 +43,9 @@ func NewWithDeployNode(node *domain.WorkflowNode, certdata struct { | |||
| 	} | ||||
| 
 | ||||
| 	deployer, logger, err := createDeployer(&deployerOptions{ | ||||
| 		Provider:             domain.DeployProviderType(node.GetConfigString("provider")), | ||||
| 		Provider:             domain.DeployProviderType(nodeConfig.Provider), | ||||
| 		ProviderAccessConfig: accessConfig, | ||||
| 		ProviderDeployConfig: node.GetConfigMap("providerConfig"), | ||||
| 		ProviderDeployConfig: nodeConfig.ProviderConfig, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
|  |  | |||
|  | @ -59,23 +59,44 @@ type WorkflowNode struct { | |||
| 	Validated bool `json:"validated"` | ||||
| } | ||||
| 
 | ||||
| func (n *WorkflowNode) GetConfigString(key string) string { | ||||
| type WorkflowNodeConfigForApply struct { | ||||
| 	Domains            string         `json:"domains"` | ||||
| 	ContactEmail       string         `json:"contactEmail"` | ||||
| 	Provider           string         `json:"provider"` | ||||
| 	ProviderAccessId   string         `json:"providerAccessId"` | ||||
| 	ProviderConfig     map[string]any `json:"providerConfig"` | ||||
| 	KeyAlgorithm       string         `json:"keyAlgorithm"` | ||||
| 	Nameservers        string         `json:"nameservers"` | ||||
| 	PropagationTimeout int32          `json:"propagationTimeout"` | ||||
| 	DisableFollowCNAME bool           `json:"disableFollowCNAME"` | ||||
| } | ||||
| 
 | ||||
| type WorkflowNodeConfigForDeploy struct { | ||||
| 	Certificate      string         `json:"certificate"` | ||||
| 	Provider         string         `json:"provider"` | ||||
| 	ProviderAccessId string         `json:"providerAccessId"` | ||||
| 	ProviderConfig   map[string]any `json:"providerConfig"` | ||||
| } | ||||
| 
 | ||||
| type WorkflowNodeConfigForNotify struct { | ||||
| 	Channel string `json:"channel"` | ||||
| 	Subject string `json:"subject"` | ||||
| 	Message string `json:"message"` | ||||
| } | ||||
| 
 | ||||
| func (n *WorkflowNode) getConfigValueAsString(key string) string { | ||||
| 	return maps.GetValueAsString(n.Config, key) | ||||
| } | ||||
| 
 | ||||
| func (n *WorkflowNode) GetConfigBool(key string) bool { | ||||
| func (n *WorkflowNode) getConfigValueAsBool(key string) bool { | ||||
| 	return maps.GetValueAsBool(n.Config, key) | ||||
| } | ||||
| 
 | ||||
| func (n *WorkflowNode) GetConfigInt32(key string) int32 { | ||||
| func (n *WorkflowNode) getConfigValueAsInt32(key string) int32 { | ||||
| 	return maps.GetValueAsInt32(n.Config, key) | ||||
| } | ||||
| 
 | ||||
| func (n *WorkflowNode) GetConfigInt64(key string) int64 { | ||||
| 	return maps.GetValueAsInt64(n.Config, key) | ||||
| } | ||||
| 
 | ||||
| func (n *WorkflowNode) GetConfigMap(key string) map[string]any { | ||||
| func (n *WorkflowNode) getConfigValueAsMap(key string) map[string]any { | ||||
| 	if val, ok := n.Config[key]; ok { | ||||
| 		if result, ok := val.(map[string]any); ok { | ||||
| 			return result | ||||
|  | @ -85,6 +106,37 @@ func (n *WorkflowNode) GetConfigMap(key string) map[string]any { | |||
| 	return make(map[string]any) | ||||
| } | ||||
| 
 | ||||
| func (n *WorkflowNode) GetConfigForApply() WorkflowNodeConfigForApply { | ||||
| 	return WorkflowNodeConfigForApply{ | ||||
| 		Domains:            n.getConfigValueAsString("domains"), | ||||
| 		ContactEmail:       n.getConfigValueAsString("contactEmail"), | ||||
| 		Provider:           n.getConfigValueAsString("provider"), | ||||
| 		ProviderAccessId:   n.getConfigValueAsString("providerAccessId"), | ||||
| 		ProviderConfig:     n.getConfigValueAsMap("providerConfig"), | ||||
| 		KeyAlgorithm:       n.getConfigValueAsString("keyAlgorithm"), | ||||
| 		Nameservers:        n.getConfigValueAsString("nameservers"), | ||||
| 		PropagationTimeout: n.getConfigValueAsInt32("propagationTimeout"), | ||||
| 		DisableFollowCNAME: n.getConfigValueAsBool("disableFollowCNAME"), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *WorkflowNode) GetConfigForDeploy() WorkflowNodeConfigForDeploy { | ||||
| 	return WorkflowNodeConfigForDeploy{ | ||||
| 		Certificate:      n.getConfigValueAsString("certificate"), | ||||
| 		Provider:         n.getConfigValueAsString("provider"), | ||||
| 		ProviderAccessId: n.getConfigValueAsString("providerAccessId"), | ||||
| 		ProviderConfig:   n.getConfigValueAsMap("providerConfig"), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *WorkflowNode) GetConfigForNotify() WorkflowNodeConfigForNotify { | ||||
| 	return WorkflowNodeConfigForNotify{ | ||||
| 		Channel: n.getConfigValueAsString("channel"), | ||||
| 		Subject: n.getConfigValueAsString("subject"), | ||||
| 		Message: n.getConfigValueAsString("message"), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| type WorkflowNodeIO struct { | ||||
| 	Label         string                      `json:"label"` | ||||
| 	Name          string                      `json:"name"` | ||||
|  |  | |||
|  | @ -114,19 +114,21 @@ func (a *applyNode) checkCanSkip(ctx context.Context, lastOutput *domain.Workflo | |||
| 	// TODO: 可控制是否强制申请
 | ||||
| 	if lastOutput != nil && lastOutput.Succeeded { | ||||
| 		// 比较和上次申请时的关键配置(即影响证书签发的)参数是否一致
 | ||||
| 		if lastOutput.Node.GetConfigString("domains") != a.node.GetConfigString("domains") { | ||||
| 		currentNodeConfig := a.node.GetConfigForApply() | ||||
| 		lastNodeConfig := lastOutput.Node.GetConfigForApply() | ||||
| 		if currentNodeConfig.Domains != lastNodeConfig.Domains { | ||||
| 			return false, "配置项变化:域名" | ||||
| 		} | ||||
| 		if lastOutput.Node.GetConfigString("contactEmail") != a.node.GetConfigString("contactEmail") { | ||||
| 		if currentNodeConfig.ContactEmail != lastNodeConfig.ContactEmail { | ||||
| 			return false, "配置项变化:联系邮箱" | ||||
| 		} | ||||
| 		if lastOutput.Node.GetConfigString("provider") != a.node.GetConfigString("provider") { | ||||
| 		if currentNodeConfig.ProviderAccessId != lastNodeConfig.ProviderAccessId { | ||||
| 			return false, "配置项变化:DNS 提供商授权" | ||||
| 		} | ||||
| 		if !maps.Equal(lastOutput.Node.GetConfigMap("providerConfig"), a.node.GetConfigMap("providerConfig")) { | ||||
| 		if !maps.Equal(currentNodeConfig.ProviderConfig, lastNodeConfig.ProviderConfig) { | ||||
| 			return false, "配置项变化:DNS 提供商参数" | ||||
| 		} | ||||
| 		if lastOutput.Node.GetConfigString("keyAlgorithm") != a.node.GetConfigString("keyAlgorithm") { | ||||
| 		if currentNodeConfig.KeyAlgorithm != lastNodeConfig.KeyAlgorithm { | ||||
| 			return false, "配置项变化:数字签名算法" | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
|  | @ -38,13 +38,13 @@ func (d *deployNode) Run(ctx context.Context) error { | |||
| 	} | ||||
| 
 | ||||
| 	// 获取前序节点输出证书
 | ||||
| 	certSource := d.node.GetConfigString("certificate") | ||||
| 	certSourceSlice := strings.Split(certSource, "#") | ||||
| 	if len(certSourceSlice) != 2 { | ||||
| 		d.AddOutput(ctx, d.node.Name, "证书来源配置错误", certSource) | ||||
| 		return fmt.Errorf("证书来源配置错误: %s", certSource) | ||||
| 	previousNodeOutputCertificateSource := d.node.GetConfigForDeploy().Certificate | ||||
| 	previousNodeOutputCertificateSourceSlice := strings.Split(previousNodeOutputCertificateSource, "#") | ||||
| 	if len(previousNodeOutputCertificateSourceSlice) != 2 { | ||||
| 		d.AddOutput(ctx, d.node.Name, "证书来源配置错误", previousNodeOutputCertificateSource) | ||||
| 		return fmt.Errorf("证书来源配置错误: %s", previousNodeOutputCertificateSource) | ||||
| 	} | ||||
| 	certificate, err := d.certRepo.GetByWorkflowNodeId(ctx, certSourceSlice[0]) | ||||
| 	certificate, err := d.certRepo.GetByWorkflowNodeId(ctx, previousNodeOutputCertificateSourceSlice[0]) | ||||
| 	if err != nil { | ||||
| 		d.AddOutput(ctx, d.node.Name, "获取证书失败", err.Error()) | ||||
| 		return err | ||||
|  | @ -102,10 +102,12 @@ func (d *deployNode) checkCanSkip(ctx context.Context, lastOutput *domain.Workfl | |||
| 	// TODO: 可控制是否强制部署
 | ||||
| 	if lastOutput != nil && lastOutput.Succeeded { | ||||
| 		// 比较和上次部署时的关键配置(即影响证书部署的)参数是否一致
 | ||||
| 		if lastOutput.Node.GetConfigString("provider") != d.node.GetConfigString("provider") { | ||||
| 		currentNodeConfig := d.node.GetConfigForDeploy() | ||||
| 		lastNodeConfig := lastOutput.Node.GetConfigForDeploy() | ||||
| 		if currentNodeConfig.ProviderAccessId != lastNodeConfig.ProviderAccessId { | ||||
| 			return false, "配置项变化:主机提供商授权" | ||||
| 		} | ||||
| 		if !maps.Equal(lastOutput.Node.GetConfigMap("providerConfig"), d.node.GetConfigMap("providerConfig")) { | ||||
| 		if !maps.Equal(currentNodeConfig.ProviderConfig, lastNodeConfig.ProviderConfig) { | ||||
| 			return false, "配置项变化:主机提供商参数" | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
|  | @ -25,6 +25,8 @@ func NewNotifyNode(node *domain.WorkflowNode) *notifyNode { | |||
| func (n *notifyNode) Run(ctx context.Context) error { | ||||
| 	n.AddOutput(ctx, n.node.Name, "开始执行") | ||||
| 
 | ||||
| 	nodeConfig := n.node.GetConfigForNotify() | ||||
| 
 | ||||
| 	// 获取通知配置
 | ||||
| 	settings, err := n.settingsRepo.GetByName(ctx, "notifyChannels") | ||||
| 	if err != nil { | ||||
|  | @ -33,18 +35,14 @@ func (n *notifyNode) Run(ctx context.Context) error { | |||
| 	} | ||||
| 
 | ||||
| 	// 获取通知渠道
 | ||||
| 	channelConfig, err := settings.GetNotifyChannelConfig(n.node.GetConfigString("channel")) | ||||
| 	channelConfig, err := settings.GetNotifyChannelConfig(nodeConfig.Channel) | ||||
| 	if err != nil { | ||||
| 		n.AddOutput(ctx, n.node.Name, "获取通知渠道配置失败", err.Error()) | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	// 发送通知
 | ||||
| 	if err := notify.SendToChannel(n.node.GetConfigString("subject"), | ||||
| 		n.node.GetConfigString("message"), | ||||
| 		n.node.GetConfigString("channel"), | ||||
| 		channelConfig, | ||||
| 	); err != nil { | ||||
| 	if err := notify.SendToChannel(nodeConfig.Subject, nodeConfig.Message, nodeConfig.Channel, channelConfig); err != nil { | ||||
| 		n.AddOutput(ctx, n.node.Name, "发送通知失败", err.Error()) | ||||
| 		return err | ||||
| 	} | ||||
|  |  | |||
|  | @ -49,7 +49,7 @@ const WorkflowRunDetailDrawer = ({ data, loading, trigger, ...props }: WorkflowR | |||
|                     <div className="flex flex-col space-y-1"> | ||||
|                       {item.outputs.map((output, j) => { | ||||
|                         return ( | ||||
|                           <div key={j} className="flex space-x-2 text-sm"> | ||||
|                           <div key={j} className="flex space-x-2 text-sm" style={{ wordBreak: "break-word" }}> | ||||
|                             <div className="whitespace-nowrap">[{dayjs(output.time).format("YYYY-MM-DD HH:mm:ss")}]</div> | ||||
|                             {output.error ? <div className="text-red-500">{output.error}</div> : <div>{output.content}</div>} | ||||
|                           </div> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Fu Diwei
						Fu Diwei