From 61843a4997eedad9135ea77cc501856e1b351b13 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Sun, 5 Jan 2025 00:08:12 +0800 Subject: [PATCH] refactor: clean code --- internal/applicant/acmehttpreq.go | 43 ---- internal/applicant/aliyun.go | 39 ---- internal/applicant/applicant.go | 127 ++++++----- internal/applicant/aws.go | 41 ---- internal/applicant/cloudflare.go | 38 ---- internal/applicant/godaddy.go | 39 ---- internal/applicant/huaweicloud.go | 46 ---- internal/applicant/namedotcom.go | 38 ---- internal/applicant/namesilo.go | 38 ---- internal/applicant/powerdns.go | 41 ---- internal/applicant/providers.go | 199 ++++++++++++++++++ internal/applicant/tencentcloud.go | 39 ---- internal/applicant/volcengine.go | 38 ---- internal/deployer/deployer.go | 49 +---- .../deployer/{factory.go => providers.go} | 90 ++++---- internal/domain/access.go | 68 ++---- internal/domain/certificate.go | 4 +- internal/domain/notify.go | 16 +- internal/domain/provider.go | 66 ++++++ internal/domain/workflow_output.go | 4 +- internal/notify/{factory.go => providers.go} | 16 +- .../lego-providers/acmehttpreq/acmehttpreq.go | 41 ++++ .../lego-providers/aliyun/aliyun.go | 35 +++ .../acme-dns-01/lego-providers/aws/aws.go | 39 ++++ .../lego-providers/cloudflare/cloudflare.go | 33 +++ .../lego-providers/godaddy/godaddy.go | 35 +++ .../lego-providers/huaweicloud/huaweicloud.go | 43 ++++ .../lego-providers/namedotcom/namedotcom.go | 35 +++ .../lego-providers/namesilo/namesilo.go | 33 +++ .../lego-providers/powerdns/powerdns.go | 37 ++++ .../tencentcloud/tencentcloud.go | 35 +++ .../lego-providers/volcengine/volcengine.go | 35 +++ internal/repository/certificate.go | 10 +- internal/repository/settings.go | 5 +- internal/repository/statistics.go | 1 + internal/repository/workflow.go | 2 +- internal/repository/workflow_output.go | 14 +- internal/workflow/event.go | 36 ++-- .../workflow/node-processor/apply_node.go | 16 +- .../workflow/node-processor/deploy_node.go | 10 +- internal/workflow/service.go | 19 +- main.go | 2 +- .../AccessEditFormACMEHttpReqConfig.tsx | 4 +- .../access/AccessEditFormAWSConfig.tsx | 4 +- .../access/AccessEditFormAliyunConfig.tsx | 4 +- .../access/AccessEditFormBaiduCloudConfig.tsx | 4 +- .../access/AccessEditFormBytePlusConfig.tsx | 4 +- .../access/AccessEditFormCloudflareConfig.tsx | 4 +- .../access/AccessEditFormDogeCloudConfig.tsx | 4 +- .../access/AccessEditFormGoDaddyConfig.tsx | 4 +- .../AccessEditFormHuaweiCloudConfig.tsx | 4 +- .../access/AccessEditFormKubernetesConfig.tsx | 4 +- .../access/AccessEditFormLocalConfig.tsx | 4 +- .../access/AccessEditFormNameDotComConfig.tsx | 4 +- .../access/AccessEditFormNameSiloConfig.tsx | 4 +- .../access/AccessEditFormPowerDNSConfig.tsx | 4 +- .../access/AccessEditFormQiniuConfig.tsx | 4 +- .../access/AccessEditFormSSHConfig.tsx | 4 +- .../AccessEditFormTencentCloudConfig.tsx | 4 +- .../access/AccessEditFormVolcEngineConfig.tsx | 4 +- .../access/AccessEditFormWebhookConfig.tsx | 4 +- .../certificate/CertificateDetail.tsx | 6 +- .../components/workflow/WorkflowElement.tsx | 16 +- .../workflow/node/ApplyNodeForm.tsx | 8 +- .../workflow/node/DeployNodeForm.tsx | 6 +- .../workflow/node/NotifyNodeForm.tsx | 6 +- .../workflow/node/StartNodeForm.tsx | 6 +- ui/src/domain/access.ts | 78 ++++--- ui/src/domain/workflow.ts | 14 +- 69 files changed, 972 insertions(+), 839 deletions(-) delete mode 100644 internal/applicant/acmehttpreq.go delete mode 100644 internal/applicant/aliyun.go delete mode 100644 internal/applicant/aws.go delete mode 100644 internal/applicant/cloudflare.go delete mode 100644 internal/applicant/godaddy.go delete mode 100644 internal/applicant/huaweicloud.go delete mode 100644 internal/applicant/namedotcom.go delete mode 100644 internal/applicant/namesilo.go delete mode 100644 internal/applicant/powerdns.go create mode 100644 internal/applicant/providers.go delete mode 100644 internal/applicant/tencentcloud.go delete mode 100644 internal/applicant/volcengine.go rename internal/deployer/{factory.go => providers.go} (85%) create mode 100644 internal/domain/provider.go rename internal/notify/{factory.go => providers.go} (90%) create mode 100644 internal/pkg/core/applicant/acme-dns-01/lego-providers/acmehttpreq/acmehttpreq.go create mode 100644 internal/pkg/core/applicant/acme-dns-01/lego-providers/aliyun/aliyun.go create mode 100644 internal/pkg/core/applicant/acme-dns-01/lego-providers/aws/aws.go create mode 100644 internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare/cloudflare.go create mode 100644 internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy/godaddy.go create mode 100644 internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud/huaweicloud.go create mode 100644 internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom/namedotcom.go create mode 100644 internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo/namesilo.go create mode 100644 internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns/powerdns.go create mode 100644 internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud/tencentcloud.go create mode 100644 internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine/volcengine.go diff --git a/internal/applicant/acmehttpreq.go b/internal/applicant/acmehttpreq.go deleted file mode 100644 index ca724482..00000000 --- a/internal/applicant/acmehttpreq.go +++ /dev/null @@ -1,43 +0,0 @@ -package applicant - -import ( - "encoding/json" - "net/url" - "time" - - "github.com/go-acme/lego/v4/providers/dns/httpreq" - - "github.com/usual2970/certimate/internal/domain" -) - -type acmeHttpReqApplicant struct { - option *ApplyOption -} - -func NewACMEHttpReqApplicant(option *ApplyOption) Applicant { - return &acmeHttpReqApplicant{ - option: option, - } -} - -func (a *acmeHttpReqApplicant) Apply() (*Certificate, error) { - access := &domain.ACMEHttpReqAccessConfig{} - json.Unmarshal([]byte(a.option.AccessConfig), access) - - config := httpreq.NewDefaultConfig() - endpoint, _ := url.Parse(access.Endpoint) - config.Endpoint = endpoint - config.Mode = access.Mode - config.Username = access.Username - config.Password = access.Password - if a.option.PropagationTimeout != 0 { - config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second - } - - provider, err := httpreq.NewDNSProviderConfig(config) - if err != nil { - return nil, err - } - - return apply(a.option, provider) -} diff --git a/internal/applicant/aliyun.go b/internal/applicant/aliyun.go deleted file mode 100644 index 386ea0c8..00000000 --- a/internal/applicant/aliyun.go +++ /dev/null @@ -1,39 +0,0 @@ -package applicant - -import ( - "encoding/json" - "time" - - "github.com/go-acme/lego/v4/providers/dns/alidns" - - "github.com/usual2970/certimate/internal/domain" -) - -type aliyunApplicant struct { - option *ApplyOption -} - -func NewAliyunApplicant(option *ApplyOption) Applicant { - return &aliyunApplicant{ - option: option, - } -} - -func (a *aliyunApplicant) Apply() (*Certificate, error) { - access := &domain.AliyunAccessConfig{} - json.Unmarshal([]byte(a.option.AccessConfig), access) - - config := alidns.NewDefaultConfig() - config.APIKey = access.AccessKeyId - config.SecretKey = access.AccessKeySecret - if a.option.PropagationTimeout != 0 { - config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second - } - - provider, err := alidns.NewDNSProviderConfig(config) - if err != nil { - return nil, err - } - - return apply(a.option, provider) -} diff --git a/internal/applicant/applicant.go b/internal/applicant/applicant.go index da3e36b6..171dfca0 100644 --- a/internal/applicant/applicant.go +++ b/internal/applicant/applicant.go @@ -50,10 +50,10 @@ type Certificate struct { PrivateKey string `json:"privateKey"` Certificate string `json:"certificate"` IssuerCertificate string `json:"issuerCertificate"` - Csr string `json:"csr"` + CSR string `json:"csr"` } -type ApplyOption struct { +type applyConfig struct { Domains string `json:"domains"` ContactEmail string `json:"contactEmail"` AccessConfig string `json:"accessConfig"` @@ -63,65 +63,79 @@ type ApplyOption struct { DisableFollowCNAME bool `json:"disableFollowCNAME"` } -type ApplyUser struct { - Ca string +type applyUser struct { + CA string Email string Registration *registration.Resource - key string + + privkey string } -func newApplyUser(ca, email string) (*ApplyUser, error) { +func newApplyUser(ca, email string) (*applyUser, error) { repo := getAcmeAccountRepository() - rs := &ApplyUser{ - Ca: ca, + + applyUser := &applyUser{ + CA: ca, Email: email, } - resp, err := repo.GetByCAAndEmail(ca, email) - if err != nil { - privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - if err != nil { - return nil, err - } - keyStr, err := x509.ConvertECPrivateKeyToPEM(privateKey) - if err != nil { - return nil, err - } - rs.key = keyStr - return rs, nil + acmeAccount, err := repo.GetByCAAndEmail(ca, email) + if err != nil { + key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return nil, err + } + + keyStr, err := x509.ConvertECPrivateKeyToPEM(key) + if err != nil { + return nil, err + } + + applyUser.privkey = keyStr + return applyUser, nil } - rs.Registration = resp.Resource - rs.key = resp.Key + applyUser.Registration = acmeAccount.Resource + applyUser.privkey = acmeAccount.Key - return rs, nil + return applyUser, nil } -func (u *ApplyUser) GetEmail() string { +func (u *applyUser) GetEmail() string { return u.Email } -func (u ApplyUser) GetRegistration() *registration.Resource { +func (u applyUser) GetRegistration() *registration.Resource { return u.Registration } -func (u *ApplyUser) GetPrivateKey() crypto.PrivateKey { - rs, _ := x509.ParseECPrivateKeyFromPEM(u.key) +func (u *applyUser) GetPrivateKey() crypto.PrivateKey { + rs, _ := x509.ParseECPrivateKeyFromPEM(u.privkey) return rs } -func (u *ApplyUser) hasRegistration() bool { +func (u *applyUser) hasRegistration() bool { return u.Registration != nil } -func (u *ApplyUser) getPrivateKeyString() string { - return u.key +func (u *applyUser) getPrivateKeyString() string { + return u.privkey } type Applicant interface { Apply() (*Certificate, error) } +// TODO: 暂时使用代理模式以兼容之前版本代码,后续重新实现此处逻辑 +type proxyApplicant struct { + applyConfig *applyConfig + applicant challenge.Provider +} + +func (d *proxyApplicant) Apply() (*Certificate, error) { + return apply(d.applyConfig, d.applicant) +} + func GetWithApplyNode(node *domain.WorkflowNode) (Applicant, error) { // 获取授权配置 accessRepo := repository.NewAccessRepository() @@ -131,7 +145,7 @@ func GetWithApplyNode(node *domain.WorkflowNode) (Applicant, error) { return nil, fmt.Errorf("access record not found: %w", err) } - applyConfig := &ApplyOption{ + applyConfig := &applyConfig{ Domains: node.GetConfigString("domains"), ContactEmail: node.GetConfigString("contactEmail"), AccessConfig: access.Config, @@ -141,40 +155,15 @@ func GetWithApplyNode(node *domain.WorkflowNode) (Applicant, error) { DisableFollowCNAME: node.GetConfigBool("disableFollowCNAME"), } - return GetWithTypeOption(domain.AccessProviderType(access.Provider), applyConfig) -} - -func GetWithTypeOption(provider domain.AccessProviderType, option *ApplyOption) (Applicant, error) { - /* - 注意:如果追加新的常量值,请保持以 ASCII 排序。 - NOTICE: If you add new constant, please keep ASCII order. - */ - switch provider { - case domain.ACCESS_PROVIDER_ACMEHTTPREQ: - return NewACMEHttpReqApplicant(option), nil - case domain.ACCESS_PROVIDER_ALIYUN: - return NewAliyunApplicant(option), nil - case domain.ACCESS_PROVIDER_AWS: - return NewAWSApplicant(option), nil - case domain.ACCESS_PROVIDER_CLOUDFLARE: - return NewCloudflareApplicant(option), nil - case domain.ACCESS_PROVIDER_GODADDY: - return NewGoDaddyApplicant(option), nil - case domain.ACCESS_PROVIDER_HUAWEICLOUD: - return NewHuaweiCloudApplicant(option), nil - case domain.ACCESS_PROVIDER_NAMEDOTCOM: - return NewNameDotComApplicant(option), nil - case domain.ACCESS_PROVIDER_NAMESILO: - return NewNamesiloApplicant(option), nil - case domain.ACCESS_PROVIDER_POWERDNS: - return NewPowerDNSApplicant(option), nil - case domain.ACCESS_PROVIDER_TENCENTCLOUD: - return NewTencentCloudApplicant(option), nil - case domain.ACCESS_PROVIDER_VOLCENGINE: - return NewVolcEngineApplicant(option), nil - default: - return nil, fmt.Errorf("unsupported applicant provider type: %s", provider) + challengeProvider, err := createChallengeProvider(domain.AccessProviderType(access.Provider), access.Config, applyConfig) + if err != nil { + return nil, err } + + return &proxyApplicant{ + applyConfig: applyConfig, + applicant: challengeProvider, + }, nil } type SSLProviderConfig struct { @@ -192,7 +181,7 @@ type SSLProviderEab struct { EabKid string `json:"eabKid"` } -func apply(option *ApplyOption, provider challenge.Provider) (*Certificate, error) { +func apply(option *applyConfig, provider challenge.Provider) (*Certificate, error) { record, _ := app.GetApp().Dao().FindFirstRecordByFilter("settings", "name='sslProvider'") sslProvider := &SSLProviderConfig{ @@ -259,7 +248,7 @@ func apply(option *ApplyOption, provider challenge.Provider) (*Certificate, erro PrivateKey: string(certificates.PrivateKey), Certificate: string(certificates.Certificate), IssuerCertificate: string(certificates.IssuerCertificate), - Csr: string(certificates.CSR), + CSR: string(certificates.CSR), }, nil } @@ -272,7 +261,9 @@ func getAcmeAccountRepository() AcmeAccountRepository { return repository.NewAcmeAccountRepository() } -func getReg(client *lego.Client, sslProvider *SSLProviderConfig, user *ApplyUser) (*registration.Resource, error) { +func getReg(client *lego.Client, sslProvider *SSLProviderConfig, user *applyUser) (*registration.Resource, error) { + // TODO: fix 潜在的并发问题 + var reg *registration.Resource var err error switch sslProvider.Provider { @@ -304,7 +295,7 @@ func getReg(client *lego.Client, sslProvider *SSLProviderConfig, user *ApplyUser resp, err := repo.GetByCAAndEmail(sslProvider.Provider, user.GetEmail()) if err == nil { - user.key = resp.Key + user.privkey = resp.Key return resp.Resource, nil } diff --git a/internal/applicant/aws.go b/internal/applicant/aws.go deleted file mode 100644 index 41c2ee94..00000000 --- a/internal/applicant/aws.go +++ /dev/null @@ -1,41 +0,0 @@ -package applicant - -import ( - "encoding/json" - "time" - - "github.com/go-acme/lego/v4/providers/dns/route53" - - "github.com/usual2970/certimate/internal/domain" -) - -type awsApplicant struct { - option *ApplyOption -} - -func NewAWSApplicant(option *ApplyOption) Applicant { - return &awsApplicant{ - option: option, - } -} - -func (a *awsApplicant) Apply() (*Certificate, error) { - access := &domain.AWSAccessConfig{} - json.Unmarshal([]byte(a.option.AccessConfig), access) - - config := route53.NewDefaultConfig() - config.AccessKeyID = access.AccessKeyId - config.SecretAccessKey = access.SecretAccessKey - config.Region = access.Region - config.HostedZoneID = access.HostedZoneId - if a.option.PropagationTimeout != 0 { - config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second - } - - provider, err := route53.NewDNSProviderConfig(config) - if err != nil { - return nil, err - } - - return apply(a.option, provider) -} diff --git a/internal/applicant/cloudflare.go b/internal/applicant/cloudflare.go deleted file mode 100644 index a7d6127d..00000000 --- a/internal/applicant/cloudflare.go +++ /dev/null @@ -1,38 +0,0 @@ -package applicant - -import ( - "encoding/json" - "time" - - "github.com/go-acme/lego/v4/providers/dns/cloudflare" - - "github.com/usual2970/certimate/internal/domain" -) - -type cloudflareApplicant struct { - option *ApplyOption -} - -func NewCloudflareApplicant(option *ApplyOption) Applicant { - return &cloudflareApplicant{ - option: option, - } -} - -func (a *cloudflareApplicant) Apply() (*Certificate, error) { - access := &domain.CloudflareAccessConfig{} - json.Unmarshal([]byte(a.option.AccessConfig), access) - - config := cloudflare.NewDefaultConfig() - config.AuthToken = access.DnsApiToken - if a.option.PropagationTimeout != 0 { - config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second - } - - provider, err := cloudflare.NewDNSProviderConfig(config) - if err != nil { - return nil, err - } - - return apply(a.option, provider) -} diff --git a/internal/applicant/godaddy.go b/internal/applicant/godaddy.go deleted file mode 100644 index 4fb5cd13..00000000 --- a/internal/applicant/godaddy.go +++ /dev/null @@ -1,39 +0,0 @@ -package applicant - -import ( - "encoding/json" - "time" - - "github.com/go-acme/lego/v4/providers/dns/godaddy" - - "github.com/usual2970/certimate/internal/domain" -) - -type godaddyApplicant struct { - option *ApplyOption -} - -func NewGoDaddyApplicant(option *ApplyOption) Applicant { - return &godaddyApplicant{ - option: option, - } -} - -func (a *godaddyApplicant) Apply() (*Certificate, error) { - access := &domain.GoDaddyAccessConfig{} - json.Unmarshal([]byte(a.option.AccessConfig), access) - - config := godaddy.NewDefaultConfig() - config.APIKey = access.ApiKey - config.APISecret = access.ApiSecret - if a.option.PropagationTimeout != 0 { - config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second - } - - provider, err := godaddy.NewDNSProviderConfig(config) - if err != nil { - return nil, err - } - - return apply(a.option, provider) -} diff --git a/internal/applicant/huaweicloud.go b/internal/applicant/huaweicloud.go deleted file mode 100644 index 05c48254..00000000 --- a/internal/applicant/huaweicloud.go +++ /dev/null @@ -1,46 +0,0 @@ -package applicant - -import ( - "encoding/json" - "time" - - huaweicloud "github.com/go-acme/lego/v4/providers/dns/huaweicloud" - - "github.com/usual2970/certimate/internal/domain" -) - -type huaweicloudApplicant struct { - option *ApplyOption -} - -func NewHuaweiCloudApplicant(option *ApplyOption) Applicant { - return &huaweicloudApplicant{ - option: option, - } -} - -func (a *huaweicloudApplicant) Apply() (*Certificate, error) { - access := &domain.HuaweiCloudAccessConfig{} - json.Unmarshal([]byte(a.option.AccessConfig), access) - - region := access.Region - if region == "" { - // 华为云的 SDK 要求必须传一个区域,实际上 DNS-01 流程里用不到,但不传会报错 - region = "cn-north-1" - } - - config := huaweicloud.NewDefaultConfig() - config.AccessKeyID = access.AccessKeyId - config.SecretAccessKey = access.SecretAccessKey - config.Region = region - if a.option.PropagationTimeout != 0 { - config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second - } - - provider, err := huaweicloud.NewDNSProviderConfig(config) - if err != nil { - return nil, err - } - - return apply(a.option, provider) -} diff --git a/internal/applicant/namedotcom.go b/internal/applicant/namedotcom.go deleted file mode 100644 index f3be2f71..00000000 --- a/internal/applicant/namedotcom.go +++ /dev/null @@ -1,38 +0,0 @@ -package applicant - -import ( - "encoding/json" - "time" - - "github.com/go-acme/lego/v4/providers/dns/namedotcom" - "github.com/usual2970/certimate/internal/domain" -) - -type nameDotComApplicant struct { - option *ApplyOption -} - -func NewNameDotComApplicant(option *ApplyOption) Applicant { - return &nameDotComApplicant{ - option: option, - } -} - -func (a *nameDotComApplicant) Apply() (*Certificate, error) { - access := &domain.NameDotComAccessConfig{} - json.Unmarshal([]byte(a.option.AccessConfig), access) - - config := namedotcom.NewDefaultConfig() - config.Username = access.Username - config.APIToken = access.ApiToken - if a.option.PropagationTimeout != 0 { - config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second - } - - provider, err := namedotcom.NewDNSProviderConfig(config) - if err != nil { - return nil, err - } - - return apply(a.option, provider) -} diff --git a/internal/applicant/namesilo.go b/internal/applicant/namesilo.go deleted file mode 100644 index 8d3ce88f..00000000 --- a/internal/applicant/namesilo.go +++ /dev/null @@ -1,38 +0,0 @@ -package applicant - -import ( - "encoding/json" - "time" - - namesilo "github.com/go-acme/lego/v4/providers/dns/namesilo" - - "github.com/usual2970/certimate/internal/domain" -) - -type namesiloApplicant struct { - option *ApplyOption -} - -func NewNamesiloApplicant(option *ApplyOption) Applicant { - return &namesiloApplicant{ - option: option, - } -} - -func (a *namesiloApplicant) Apply() (*Certificate, error) { - access := &domain.NameSiloAccessConfig{} - json.Unmarshal([]byte(a.option.AccessConfig), access) - - config := namesilo.NewDefaultConfig() - config.APIKey = access.ApiKey - if a.option.PropagationTimeout != 0 { - config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second - } - - provider, err := namesilo.NewDNSProviderConfig(config) - if err != nil { - return nil, err - } - - return apply(a.option, provider) -} diff --git a/internal/applicant/powerdns.go b/internal/applicant/powerdns.go deleted file mode 100644 index 36bce6f5..00000000 --- a/internal/applicant/powerdns.go +++ /dev/null @@ -1,41 +0,0 @@ -package applicant - -import ( - "encoding/json" - "net/url" - "time" - - "github.com/go-acme/lego/v4/providers/dns/pdns" - - "github.com/usual2970/certimate/internal/domain" -) - -type powerdnsApplicant struct { - option *ApplyOption -} - -func NewPowerDNSApplicant(option *ApplyOption) Applicant { - return &powerdnsApplicant{ - option: option, - } -} - -func (a *powerdnsApplicant) Apply() (*Certificate, error) { - access := &domain.PowerDNSAccessConfig{} - json.Unmarshal([]byte(a.option.AccessConfig), access) - - config := pdns.NewDefaultConfig() - host, _ := url.Parse(access.ApiUrl) - config.Host = host - config.APIKey = access.ApiKey - if a.option.PropagationTimeout != 0 { - config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second - } - - provider, err := pdns.NewDNSProviderConfig(config) - if err != nil { - return nil, err - } - - return apply(a.option, provider) -} diff --git a/internal/applicant/providers.go b/internal/applicant/providers.go new file mode 100644 index 00000000..c8800093 --- /dev/null +++ b/internal/applicant/providers.go @@ -0,0 +1,199 @@ +package applicant + +import ( + "encoding/json" + "fmt" + + "github.com/go-acme/lego/v4/challenge" + + "github.com/usual2970/certimate/internal/domain" + providerACMEHttpReq "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/acmehttpreq" + providerAliyun "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/aliyun" + providerAWS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/aws" + providerCloudflare "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare" + providerGoDaddy "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy" + providerHuaweiCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud" + providerNameDotCom "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom" + providerNameSilo "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo" + providerPowerDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns" + providerTencentCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud" + providerVolcEngine "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine" +) + +func createChallengeProvider(provider domain.AccessProviderType, accessConfig string, applyConfig *applyConfig) (challenge.Provider, error) { + /* + 注意:如果追加新的常量值,请保持以 ASCII 排序。 + NOTICE: If you add new constant, please keep ASCII order. + */ + switch provider { + case domain.AccessProviderTypeACMEHttpReq: + { + access := &domain.AccessConfigForACMEHttpReq{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerACMEHttpReq.NewChallengeProvider(&providerACMEHttpReq.ACMEHttpReqApplicantConfig{ + Endpoint: access.Endpoint, + Mode: access.Mode, + Username: access.Username, + Password: access.Password, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeAliyun: + { + access := &domain.AccessConfigForAliyun{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerAliyun.NewChallengeProvider(&providerAliyun.AliyunApplicantConfig{ + AccessKeyId: access.AccessKeyId, + AccessKeySecret: access.AccessKeySecret, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeAWS: + { + access := &domain.AccessConfigForAWS{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerAWS.NewChallengeProvider(&providerAWS.AWSApplicantConfig{ + AccessKeyId: access.AccessKeyId, + SecretAccessKey: access.SecretAccessKey, + Region: access.Region, + HostedZoneId: access.HostedZoneId, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeCloudflare: + { + access := &domain.AccessConfigForCloudflare{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerCloudflare.NewChallengeProvider(&providerCloudflare.CloudflareApplicantConfig{ + DnsApiToken: access.DnsApiToken, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeGoDaddy: + { + access := &domain.AccessConfigForGoDaddy{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerGoDaddy.NewChallengeProvider(&providerGoDaddy.GoDaddyApplicantConfig{ + ApiKey: access.ApiKey, + ApiSecret: access.ApiSecret, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeHuaweiCloud: + { + access := &domain.AccessConfigForHuaweiCloud{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerHuaweiCloud.NewChallengeProvider(&providerHuaweiCloud.HuaweiCloudApplicantConfig{ + AccessKeyId: access.AccessKeyId, + SecretAccessKey: access.SecretAccessKey, + Region: access.Region, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeNameDotCom: + { + access := &domain.AccessConfigForNameDotCom{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerNameDotCom.NewChallengeProvider(&providerNameDotCom.NameDotComApplicantConfig{ + Username: access.Username, + ApiToken: access.ApiToken, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeNameSilo: + { + access := &domain.AccessConfigForNameSilo{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerNameSilo.NewChallengeProvider(&providerNameSilo.NameSiloApplicantConfig{ + ApiKey: access.ApiKey, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypePowerDNS: + { + access := &domain.AccessConfigForPowerDNS{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerPowerDNS.NewChallengeProvider(&providerPowerDNS.PowerDNSApplicantConfig{ + ApiUrl: access.ApiUrl, + ApiKey: access.ApiKey, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeTencentCloud: + { + access := &domain.AccessConfigForTencentCloud{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerTencentCloud.NewChallengeProvider(&providerTencentCloud.TencentCloudApplicantConfig{ + SecretId: access.SecretId, + SecretKey: access.SecretKey, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + + case domain.AccessProviderTypeVolcEngine: + { + access := &domain.AccessConfigForVolcEngine{} + if err := json.Unmarshal([]byte(accessConfig), access); err != nil { + return nil, fmt.Errorf("failed to unmarshal access config: %w", err) + } + + applicant, err := providerVolcEngine.NewChallengeProvider(&providerVolcEngine.VolcEngineApplicantConfig{ + AccessKeyId: access.AccessKeyId, + SecretAccessKey: access.SecretAccessKey, + PropagationTimeout: applyConfig.PropagationTimeout, + }) + return applicant, err + } + } + + return nil, fmt.Errorf("unsupported applicant provider: %s", provider) +} diff --git a/internal/applicant/tencentcloud.go b/internal/applicant/tencentcloud.go deleted file mode 100644 index f273371d..00000000 --- a/internal/applicant/tencentcloud.go +++ /dev/null @@ -1,39 +0,0 @@ -package applicant - -import ( - "encoding/json" - "time" - - "github.com/go-acme/lego/v4/providers/dns/tencentcloud" - - "github.com/usual2970/certimate/internal/domain" -) - -type tencentcloudApplicant struct { - option *ApplyOption -} - -func NewTencentCloudApplicant(option *ApplyOption) Applicant { - return &tencentcloudApplicant{ - option: option, - } -} - -func (a *tencentcloudApplicant) Apply() (*Certificate, error) { - access := &domain.TencentCloudAccessConfig{} - json.Unmarshal([]byte(a.option.AccessConfig), access) - - config := tencentcloud.NewDefaultConfig() - config.SecretID = access.SecretId - config.SecretKey = access.SecretKey - if a.option.PropagationTimeout != 0 { - config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second - } - - provider, err := tencentcloud.NewDNSProviderConfig(config) - if err != nil { - return nil, err - } - - return apply(a.option, provider) -} diff --git a/internal/applicant/volcengine.go b/internal/applicant/volcengine.go deleted file mode 100644 index 9367f4bc..00000000 --- a/internal/applicant/volcengine.go +++ /dev/null @@ -1,38 +0,0 @@ -package applicant - -import ( - "encoding/json" - "time" - - "github.com/go-acme/lego/v4/providers/dns/volcengine" - "github.com/usual2970/certimate/internal/domain" -) - -type volcengineApplicant struct { - option *ApplyOption -} - -func NewVolcEngineApplicant(option *ApplyOption) Applicant { - return &volcengineApplicant{ - option: option, - } -} - -func (a *volcengineApplicant) Apply() (*Certificate, error) { - access := &domain.VolcEngineAccessConfig{} - json.Unmarshal([]byte(a.option.AccessConfig), access) - - config := volcengine.NewDefaultConfig() - config.AccessKey = access.AccessKeyId - config.SecretKey = access.SecretAccessKey - if a.option.PropagationTimeout != 0 { - config.PropagationTimeout = time.Duration(a.option.PropagationTimeout) * time.Second - } - - provider, err := volcengine.NewDNSProviderConfig(config) - if err != nil { - return nil, err - } - - return apply(a.option, provider) -} diff --git a/internal/deployer/deployer.go b/internal/deployer/deployer.go index 79b031aa..c62e892f 100644 --- a/internal/deployer/deployer.go +++ b/internal/deployer/deployer.go @@ -2,7 +2,6 @@ package deployer import ( "context" - "fmt" "github.com/usual2970/certimate/internal/applicant" "github.com/usual2970/certimate/internal/domain" @@ -10,39 +9,6 @@ import ( "github.com/usual2970/certimate/internal/pkg/core/logger" ) -/* -提供商部署目标常量值。 -短横线前的部分始终等于提供商类型。 - - 注意:如果追加新的常量值,请保持以 ASCII 排序。 - NOTICE: If you add new constant, please keep ASCII order. -*/ -const ( - targetAliyunALB = "aliyun-alb" - targetAliyunCDN = "aliyun-cdn" - targetAliyunCLB = "aliyun-clb" - targetAliyunDCDN = "aliyun-dcdn" - targetAliyunNLB = "aliyun-nlb" - targetAliyunOSS = "aliyun-oss" - targetBaiduCloudCDN = "baiducloud-cdn" - targetBytePlusCDN = "byteplus-cdn" - targetDogeCloudCDN = "dogecloud-cdn" - targetHuaweiCloudCDN = "huaweicloud-cdn" - targetHuaweiCloudELB = "huaweicloud-elb" - targetK8sSecret = "k8s-secret" - targetLocal = "local" - targetQiniuCDN = "qiniu-cdn" - targetSSH = "ssh" - targetTencentCloudCDN = "tencentcloud-cdn" - targetTencentCloudCLB = "tencentcloud-clb" - targetTencentCloudCOS = "tencentcloud-cos" - targetTencentCloudECDN = "tencentcloud-ecdn" - targetTencentCloudEO = "tencentcloud-eo" - targetVolcEngineCDN = "volcengine-cdn" - targetVolcEngineLive = "volcengine-live" - targetWebhook = "webhook" -) - type DeployerOption struct { NodeId string `json:"nodeId"` Domains string `json:"domains"` @@ -50,17 +16,14 @@ type DeployerOption struct { AccessRecord *domain.Access `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 - GetInfos() []string - GetID() string } -func GetWithTypeAndOption(deployType string, option *DeployerOption) (Deployer, error) { - deployer, logger, err := createDeployer(deployType, option.AccessRecord.Config, option.DeployConfig.NodeConfig) +func GetWithProviderAndOption(provider string, option *DeployerOption) (Deployer, error) { + deployer, logger, err := createDeployer(domain.DeployProviderType(provider), option.AccessRecord.Config, option.DeployConfig.NodeConfig) if err != nil { return nil, err } @@ -79,14 +42,6 @@ type proxyDeployer struct { deployer deployer.Deployer } -func (d *proxyDeployer) GetID() string { - return fmt.Sprintf("%s-%s", d.option.AccessRecord.Name, d.option.AccessRecord.Id) -} - -func (d *proxyDeployer) GetInfos() []string { - return d.logger.GetRecords() -} - func (d *proxyDeployer) Deploy(ctx context.Context) error { _, err := d.deployer.Deploy(ctx, d.option.Certificate.Certificate, d.option.Certificate.PrivateKey) return err diff --git a/internal/deployer/factory.go b/internal/deployer/providers.go similarity index 85% rename from internal/deployer/factory.go rename to internal/deployer/providers.go index 0338a0df..be2feb32 100644 --- a/internal/deployer/factory.go +++ b/internal/deployer/providers.go @@ -34,23 +34,23 @@ import ( "github.com/usual2970/certimate/internal/pkg/utils/maps" ) -func createDeployer(target string, accessConfig string, deployConfig map[string]any) (deployer.Deployer, logger.Logger, error) { +func createDeployer(provider domain.DeployProviderType, accessConfig string, deployConfig map[string]any) (deployer.Deployer, logger.Logger, error) { logger := logger.NewDefaultLogger() /* 注意:如果追加新的常量值,请保持以 ASCII 排序。 NOTICE: If you add new constant, please keep ASCII order. */ - switch target { - case targetAliyunALB, targetAliyunCDN, targetAliyunCLB, targetAliyunDCDN, targetAliyunNLB, targetAliyunOSS: + switch provider { + case domain.DeployProviderTypeAliyunALB, domain.DeployProviderTypeAliyunCDN, domain.DeployProviderTypeAliyunCLB, domain.DeployProviderTypeAliyunDCDN, domain.DeployProviderTypeAliyunNLB, domain.DeployProviderTypeAliyunOSS: { - access := &domain.AliyunAccessConfig{} + access := &domain.AccessConfigForAliyun{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } - switch target { - case targetAliyunALB: + switch provider { + case domain.DeployProviderTypeAliyunALB: deployer, err := providerAliyunALB.NewWithLogger(&providerAliyunALB.AliyunALBDeployerConfig{ AccessKeyId: access.AccessKeyId, AccessKeySecret: access.AccessKeySecret, @@ -61,7 +61,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetAliyunCDN: + case domain.DeployProviderTypeAliyunCDN: deployer, err := providerAliyunCDN.NewWithLogger(&providerAliyunCDN.AliyunCDNDeployerConfig{ AccessKeyId: access.AccessKeyId, AccessKeySecret: access.AccessKeySecret, @@ -69,7 +69,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetAliyunCLB: + case domain.DeployProviderTypeAliyunCLB: deployer, err := providerAliyunCLB.NewWithLogger(&providerAliyunCLB.AliyunCLBDeployerConfig{ AccessKeyId: access.AccessKeyId, AccessKeySecret: access.AccessKeySecret, @@ -80,7 +80,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetAliyunDCDN: + case domain.DeployProviderTypeAliyunDCDN: deployer, err := providerAliyunDCDN.NewWithLogger(&providerAliyunDCDN.AliyunDCDNDeployerConfig{ AccessKeyId: access.AccessKeyId, AccessKeySecret: access.AccessKeySecret, @@ -88,7 +88,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetAliyunNLB: + case domain.DeployProviderTypeAliyunNLB: deployer, err := providerAliyunNLB.NewWithLogger(&providerAliyunNLB.AliyunNLBDeployerConfig{ AccessKeyId: access.AccessKeyId, AccessKeySecret: access.AccessKeySecret, @@ -99,7 +99,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetAliyunOSS: + case domain.DeployProviderTypeAliyunOSS: deployer, err := providerAliyunOSS.NewWithLogger(&providerAliyunOSS.AliyunOSSDeployerConfig{ AccessKeyId: access.AccessKeyId, AccessKeySecret: access.AccessKeySecret, @@ -114,9 +114,9 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] } } - case targetBaiduCloudCDN: + case domain.DeployProviderTypeBaiduCloudCDN: { - access := &domain.BaiduCloudAccessConfig{} + access := &domain.AccessConfigForBaiduCloud{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } @@ -129,9 +129,9 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] return deployer, logger, err } - case targetBytePlusCDN: + case domain.DeployProviderTypeBytePlusCDN: { - access := &domain.BytePlusAccessConfig{} + access := &domain.AccessConfigForBytePlus{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } @@ -144,9 +144,9 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] return deployer, logger, err } - case targetDogeCloudCDN: + case domain.DeployProviderTypeDogeCloudCDN: { - access := &domain.DogeCloudAccessConfig{} + access := &domain.AccessConfigForDogeCloud{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } @@ -159,15 +159,15 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] return deployer, logger, err } - case targetHuaweiCloudCDN, targetHuaweiCloudELB: + case domain.DeployProviderTypeHuaweiCloudCDN, domain.DeployProviderTypeHuaweiCloudELB: { - access := &domain.HuaweiCloudAccessConfig{} + access := &domain.AccessConfigForHuaweiCloud{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } - switch target { - case targetHuaweiCloudCDN: + switch provider { + case domain.DeployProviderTypeHuaweiCloudCDN: deployer, err := providerHuaweiCloudCDN.NewWithLogger(&providerHuaweiCloudCDN.HuaweiCloudCDNDeployerConfig{ AccessKeyId: access.AccessKeyId, SecretAccessKey: access.SecretAccessKey, @@ -176,7 +176,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetHuaweiCloudELB: + case domain.DeployProviderTypeHuaweiCloudELB: deployer, err := providerHuaweiCloudELB.NewWithLogger(&providerHuaweiCloudELB.HuaweiCloudELBDeployerConfig{ AccessKeyId: access.AccessKeyId, SecretAccessKey: access.SecretAccessKey, @@ -193,7 +193,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] } } - case targetLocal: + case domain.DeployProviderTypeLocal: { deployer, err := providerLocal.NewWithLogger(&providerLocal.LocalDeployerConfig{ ShellEnv: providerLocal.ShellEnvType(maps.GetValueAsString(deployConfig, "shellEnv")), @@ -210,9 +210,9 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] return deployer, logger, err } - case targetK8sSecret: + case domain.DeployProviderTypeK8sSecret: { - access := &domain.KubernetesAccessConfig{} + access := &domain.AccessConfigForKubernetes{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } @@ -228,9 +228,9 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] return deployer, logger, err } - case targetQiniuCDN: + case domain.DeployProviderTypeQiniuCDN: { - access := &domain.QiniuAccessConfig{} + access := &domain.AccessConfigForQiniu{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } @@ -243,9 +243,9 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] return deployer, logger, err } - case targetSSH: + case domain.DeployProviderTypeSSH: { - access := &domain.SSHAccessConfig{} + access := &domain.AccessConfigForSSH{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } @@ -271,15 +271,15 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] return deployer, logger, err } - case targetTencentCloudCDN, targetTencentCloudCLB, targetTencentCloudCOS, targetTencentCloudECDN, targetTencentCloudEO: + case domain.DeployProviderTypeTencentCloudCDN, domain.DeployProviderTypeTencentCloudCLB, domain.DeployProviderTypeTencentCloudCOS, domain.DeployProviderTypeTencentCloudECDN, domain.DeployProviderTypeTencentCloudEO: { - access := &domain.TencentCloudAccessConfig{} + access := &domain.AccessConfigForTencentCloud{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } - switch target { - case targetTencentCloudCDN: + switch provider { + case domain.DeployProviderTypeTencentCloudCDN: deployer, err := providerTencentCloudCDN.NewWithLogger(&providerTencentCloudCDN.TencentCloudCDNDeployerConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, @@ -287,7 +287,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetTencentCloudCLB: + case domain.DeployProviderTypeTencentCloudCLB: deployer, err := providerTencentCloudCLB.NewWithLogger(&providerTencentCloudCLB.TencentCloudCLBDeployerConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, @@ -299,7 +299,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetTencentCloudCOS: + case domain.DeployProviderTypeTencentCloudCOS: deployer, err := providerTencentCloudCOD.NewWithLogger(&providerTencentCloudCOD.TencentCloudCOSDeployerConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, @@ -309,7 +309,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetTencentCloudECDN: + case domain.DeployProviderTypeTencentCloudECDN: deployer, err := providerTencentCloudECDN.NewWithLogger(&providerTencentCloudECDN.TencentCloudECDNDeployerConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, @@ -317,7 +317,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetTencentCloudEO: + case domain.DeployProviderTypeTencentCloudEO: deployer, err := providerTencentCloudEO.NewWithLogger(&providerTencentCloudEO.TencentCloudEODeployerConfig{ SecretId: access.SecretId, SecretKey: access.SecretKey, @@ -331,15 +331,15 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] } } - case targetVolcEngineCDN, targetVolcEngineLive: + case domain.DeployProviderTypeVolcEngineCDN, domain.DeployProviderTypeVolcEngineLive: { - access := &domain.VolcEngineAccessConfig{} + access := &domain.AccessConfigForVolcEngine{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } - switch target { - case targetVolcEngineCDN: + switch provider { + case domain.DeployProviderTypeVolcEngineCDN: deployer, err := providerVolcEngineCDN.NewWithLogger(&providerVolcEngineCDN.VolcEngineCDNDeployerConfig{ AccessKey: access.AccessKeyId, SecretKey: access.SecretAccessKey, @@ -347,7 +347,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] }, logger) return deployer, logger, err - case targetVolcEngineLive: + case domain.DeployProviderTypeVolcEngineLive: deployer, err := providerVolcEngineLive.NewWithLogger(&providerVolcEngineLive.VolcEngineLiveDeployerConfig{ AccessKey: access.AccessKeyId, SecretKey: access.SecretAccessKey, @@ -360,9 +360,9 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] } } - case targetWebhook: + case domain.DeployProviderTypeWebhook: { - access := &domain.WebhookAccessConfig{} + access := &domain.AccessConfigForWebhook{} if err := json.Unmarshal([]byte(accessConfig), access); err != nil { return nil, nil, fmt.Errorf("failed to unmarshal access config: %w", err) } @@ -375,5 +375,5 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] } } - return nil, nil, fmt.Errorf("unsupported deployer target: %s", target) + return nil, nil, fmt.Errorf("unsupported deployer provider: %s", provider) } diff --git a/internal/domain/access.go b/internal/domain/access.go index dfd8ba7d..9a2bcb7d 100644 --- a/internal/domain/access.go +++ b/internal/domain/access.go @@ -11,111 +11,81 @@ type Access struct { DeletedAt time.Time `json:"deleted" db:"deleted"` } -type AccessProviderType string - -/* -提供商类型常量值。 - - 注意:如果追加新的常量值,请保持以 ASCII 排序。 - NOTICE: If you add new constant, please keep ASCII order. -*/ -const ( - ACCESS_PROVIDER_ACMEHTTPREQ = AccessProviderType("acmehttpreq") - ACCESS_PROVIDER_ALIYUN = AccessProviderType("aliyun") - ACCESS_PROVIDER_AWS = AccessProviderType("aws") - ACCESS_PROVIDER_BAIDUCLOUD = AccessProviderType("baiducloud") - ACCESS_PROVIDER_BYTEPLUS = AccessProviderType("byteplus") - ACCESS_PROVIDER_CLOUDFLARE = AccessProviderType("cloudflare") - ACCESS_PROVIDER_DOGECLOUD = AccessProviderType("dogecloud") - ACCESS_PROVIDER_GODADDY = AccessProviderType("godaddy") - ACCESS_PROVIDER_HUAWEICLOUD = AccessProviderType("huaweicloud") - ACCESS_PROVIDER_KUBERNETES = AccessProviderType("k8s") - ACCESS_PROVIDER_LOCAL = AccessProviderType("local") - ACCESS_PROVIDER_NAMEDOTCOM = AccessProviderType("namedotcom") - ACCESS_PROVIDER_NAMESILO = AccessProviderType("namesilo") - ACCESS_PROVIDER_POWERDNS = AccessProviderType("powerdns") - ACCESS_PROVIDER_QINIU = AccessProviderType("qiniu") - ACCESS_PROVIDER_SSH = AccessProviderType("ssh") - ACCESS_PROVIDER_TENCENTCLOUD = AccessProviderType("tencentcloud") - ACCESS_PROVIDER_VOLCENGINE = AccessProviderType("volcengine") - ACCESS_PROVIDER_WEBHOOK = AccessProviderType("webhook") -) - -type ACMEHttpReqAccessConfig struct { +type AccessConfigForACMEHttpReq struct { Endpoint string `json:"endpoint"` Mode string `json:"mode"` Username string `json:"username"` Password string `json:"password"` } -type AliyunAccessConfig struct { +type AccessConfigForAliyun struct { AccessKeyId string `json:"accessKeyId"` AccessKeySecret string `json:"accessKeySecret"` } -type AWSAccessConfig struct { +type AccessConfigForAWS struct { AccessKeyId string `json:"accessKeyId"` SecretAccessKey string `json:"secretAccessKey"` Region string `json:"region"` HostedZoneId string `json:"hostedZoneId"` } -type BaiduCloudAccessConfig struct { +type AccessConfigForBaiduCloud struct { AccessKeyId string `json:"accessKeyId"` SecretAccessKey string `json:"secretAccessKey"` } -type BytePlusAccessConfig struct { +type AccessConfigForBytePlus struct { AccessKey string `json:"accessKey"` SecretKey string `json:"secretKey"` } -type CloudflareAccessConfig struct { +type AccessConfigForCloudflare struct { DnsApiToken string `json:"dnsApiToken"` } -type DogeCloudAccessConfig struct { +type AccessConfigForDogeCloud struct { AccessKey string `json:"accessKey"` SecretKey string `json:"secretKey"` } -type GoDaddyAccessConfig struct { +type AccessConfigForGoDaddy struct { ApiKey string `json:"apiKey"` ApiSecret string `json:"apiSecret"` } -type HuaweiCloudAccessConfig struct { +type AccessConfigForHuaweiCloud struct { AccessKeyId string `json:"accessKeyId"` SecretAccessKey string `json:"secretAccessKey"` Region string `json:"region"` } -type LocalAccessConfig struct{} +type AccessConfigForLocal struct{} -type KubernetesAccessConfig struct { +type AccessConfigForKubernetes struct { KubeConfig string `json:"kubeConfig"` } -type NameDotComAccessConfig struct { +type AccessConfigForNameDotCom struct { Username string `json:"username"` ApiToken string `json:"apiToken"` } -type NameSiloAccessConfig struct { +type AccessConfigForNameSilo struct { ApiKey string `json:"apiKey"` } -type PowerDNSAccessConfig struct { +type AccessConfigForPowerDNS struct { ApiUrl string `json:"apiUrl"` ApiKey string `json:"apiKey"` } -type QiniuAccessConfig struct { +type AccessConfigForQiniu struct { AccessKey string `json:"accessKey"` SecretKey string `json:"secretKey"` } -type SSHAccessConfig struct { +type AccessConfigForSSH struct { Host string `json:"host"` Port string `json:"port"` Username string `json:"username"` @@ -124,16 +94,16 @@ type SSHAccessConfig struct { KeyPassphrase string `json:"keyPassphrase"` } -type TencentCloudAccessConfig struct { +type AccessConfigForTencentCloud struct { SecretId string `json:"secretId"` SecretKey string `json:"secretKey"` } -type VolcEngineAccessConfig struct { +type AccessConfigForVolcEngine struct { AccessKeyId string `json:"accessKeyId"` SecretAccessKey string `json:"secretAccessKey"` } -type WebhookAccessConfig struct { +type AccessConfigForWebhook struct { Url string `json:"url"` } diff --git a/internal/domain/certificate.go b/internal/domain/certificate.go index 9797e602..2fe0c131 100644 --- a/internal/domain/certificate.go +++ b/internal/domain/certificate.go @@ -18,8 +18,8 @@ type Certificate struct { IssuerCertificate string `json:"issuerCertificate" db:"issuerCertificate"` EffectAt time.Time `json:"effectAt" db:"effectAt"` ExpireAt time.Time `json:"expireAt" db:"expireAt"` - AcmeCertUrl string `json:"acmeCertUrl" db:"acmeCertUrl"` - AcmeCertStableUrl string `json:"acmeCertStableUrl" db:"acmeCertStableUrl"` + ACMECertUrl string `json:"acmeCertUrl" db:"acmeCertUrl"` + ACMECertStableUrl string `json:"acmeCertStableUrl" db:"acmeCertStableUrl"` WorkflowId string `json:"workflowId" db:"workflowId"` WorkflowNodeId string `json:"workflowNodeId" db:"workflowNodeId"` WorkflowOutputId string `json:"workflowOutputId" db:"workflowOutputId"` diff --git a/internal/domain/notify.go b/internal/domain/notify.go index eb215939..7db79be6 100644 --- a/internal/domain/notify.go +++ b/internal/domain/notify.go @@ -9,14 +9,14 @@ type NotifyChannelType string NOTICE: If you add new constant, please keep ASCII order. */ const ( - NOTIFY_CHANNEL_BARK = NotifyChannelType("bark") - NOTIFY_CHANNEL_DINGTALK = NotifyChannelType("dingtalk") - NOTIFY_CHANNEL_EMAIL = NotifyChannelType("email") - NOTIFY_CHANNEL_LARK = NotifyChannelType("lark") - NOTIFY_CHANNEL_SERVERCHAN = NotifyChannelType("serverchan") - NOTIFY_CHANNEL_TELEGRAM = NotifyChannelType("telegram") - NOTIFY_CHANNEL_WEBHOOK = NotifyChannelType("webhook") - NOTIFY_CHANNEL_WECOM = NotifyChannelType("wecom") + NotifyChannelTypeBark = NotifyChannelType("bark") + NotifyChannelTypeDingTalk = NotifyChannelType("dingtalk") + NotifyChannelTypeEmail = NotifyChannelType("email") + NotifyChannelTypeLark = NotifyChannelType("lark") + NotifyChannelTypeServerChan = NotifyChannelType("serverchan") + NotifyChannelTypeTelegram = NotifyChannelType("telegram") + NotifyChannelTypeWebhook = NotifyChannelType("webhook") + NotifyChannelTypeWeCom = NotifyChannelType("wecom") ) type NotifyTestPushReq struct { diff --git a/internal/domain/provider.go b/internal/domain/provider.go new file mode 100644 index 00000000..a196d2c3 --- /dev/null +++ b/internal/domain/provider.go @@ -0,0 +1,66 @@ +package domain + +type AccessProviderType string + +/* +提供商类型常量值。 + + 注意:如果追加新的常量值,请保持以 ASCII 排序。 + NOTICE: If you add new constant, please keep ASCII order. +*/ +const ( + AccessProviderTypeACMEHttpReq = AccessProviderType("acmehttpreq") + AccessProviderTypeAliyun = AccessProviderType("aliyun") + AccessProviderTypeAWS = AccessProviderType("aws") + AccessProviderTypeBaiduCloud = AccessProviderType("baiducloud") + AccessProviderTypeBytePlus = AccessProviderType("byteplus") + AccessProviderTypeCloudflare = AccessProviderType("cloudflare") + AccessProviderTypeDogeCloud = AccessProviderType("dogecloud") + AccessProviderTypeGoDaddy = AccessProviderType("godaddy") + AccessProviderTypeHuaweiCloud = AccessProviderType("huaweicloud") + AccessProviderTypeKubernetes = AccessProviderType("k8s") + AccessProviderTypeLocal = AccessProviderType("local") + AccessProviderTypeNameDotCom = AccessProviderType("namedotcom") + AccessProviderTypeNameSilo = AccessProviderType("namesilo") + AccessProviderTypePowerDNS = AccessProviderType("powerdns") + AccessProviderTypeQiniu = AccessProviderType("qiniu") + AccessProviderTypeSSH = AccessProviderType("ssh") + AccessProviderTypeTencentCloud = AccessProviderType("tencentcloud") + AccessProviderTypeVolcEngine = AccessProviderType("volcengine") + AccessProviderTypeWebhook = AccessProviderType("webhook") +) + +type DeployProviderType string + +/* +提供商部署目标常量值。 +短横线前的部分始终等于提供商类型。 + + 注意:如果追加新的常量值,请保持以 ASCII 排序。 + NOTICE: If you add new constant, please keep ASCII order. +*/ +const ( + DeployProviderTypeAliyunALB = DeployProviderType("aliyun-alb") + DeployProviderTypeAliyunCDN = DeployProviderType("aliyun-cdn") + DeployProviderTypeAliyunCLB = DeployProviderType("aliyun-clb") + DeployProviderTypeAliyunDCDN = DeployProviderType("aliyun-dcdn") + DeployProviderTypeAliyunNLB = DeployProviderType("aliyun-nlb") + DeployProviderTypeAliyunOSS = DeployProviderType("aliyun-oss") + DeployProviderTypeBaiduCloudCDN = DeployProviderType("baiducloud-cdn") + DeployProviderTypeBytePlusCDN = DeployProviderType("byteplus-cdn") + DeployProviderTypeDogeCloudCDN = DeployProviderType("dogecloud-cdn") + DeployProviderTypeHuaweiCloudCDN = DeployProviderType("huaweicloud-cdn") + DeployProviderTypeHuaweiCloudELB = DeployProviderType("huaweicloud-elb") + DeployProviderTypeK8sSecret = DeployProviderType("k8s-secret") + DeployProviderTypeLocal = DeployProviderType("local") + DeployProviderTypeQiniuCDN = DeployProviderType("qiniu-cdn") + DeployProviderTypeSSH = DeployProviderType("ssh") + DeployProviderTypeTencentCloudCDN = DeployProviderType("tencentcloud-cdn") + DeployProviderTypeTencentCloudCLB = DeployProviderType("tencentcloud-clb") + DeployProviderTypeTencentCloudCOS = DeployProviderType("tencentcloud-cos") + DeployProviderTypeTencentCloudECDN = DeployProviderType("tencentcloud-ecdn") + DeployProviderTypeTencentCloudEO = DeployProviderType("tencentcloud-eo") + DeployProviderTypeVolcEngineCDN = DeployProviderType("volcengine-cdn") + DeployProviderTypeVolcEngineLive = DeployProviderType("volcengine-live") + DeployProviderTypeWebhook = DeployProviderType("webhook") +) diff --git a/internal/domain/workflow_output.go b/internal/domain/workflow_output.go index d0c5665c..abbddac1 100644 --- a/internal/domain/workflow_output.go +++ b/internal/domain/workflow_output.go @@ -1,7 +1,5 @@ package domain -const WorkflowOutputCertificate = "certificate" - type WorkflowOutput struct { Meta WorkflowId string `json:"workflowId" db:"workflow"` @@ -10,3 +8,5 @@ type WorkflowOutput struct { Outputs []WorkflowNodeIO `json:"outputs" db:"outputs"` Succeeded bool `json:"succeeded" db:"succeeded"` } + +const WORKFLOW_OUTPUT_CERTIFICATE = "certificate" diff --git a/internal/notify/factory.go b/internal/notify/providers.go similarity index 90% rename from internal/notify/factory.go rename to internal/notify/providers.go index ab613a17..6483a7a0 100644 --- a/internal/notify/factory.go +++ b/internal/notify/providers.go @@ -22,19 +22,19 @@ func createNotifier(channel domain.NotifyChannelType, channelConfig map[string]a NOTICE: If you add new constant, please keep ASCII order. */ switch channel { - case domain.NOTIFY_CHANNEL_BARK: + case domain.NotifyChannelTypeBark: return providerBark.New(&providerBark.BarkNotifierConfig{ DeviceKey: maps.GetValueAsString(channelConfig, "deviceKey"), ServerUrl: maps.GetValueAsString(channelConfig, "serverUrl"), }) - case domain.NOTIFY_CHANNEL_DINGTALK: + case domain.NotifyChannelTypeDingTalk: return providerDingTalk.New(&providerDingTalk.DingTalkNotifierConfig{ AccessToken: maps.GetValueAsString(channelConfig, "accessToken"), Secret: maps.GetValueAsString(channelConfig, "secret"), }) - case domain.NOTIFY_CHANNEL_EMAIL: + case domain.NotifyChannelTypeEmail: return providerEmail.New(&providerEmail.EmailNotifierConfig{ SmtpHost: maps.GetValueAsString(channelConfig, "smtpHost"), SmtpPort: maps.GetValueAsInt32(channelConfig, "smtpPort"), @@ -45,28 +45,28 @@ func createNotifier(channel domain.NotifyChannelType, channelConfig map[string]a ReceiverAddress: maps.GetValueAsString(channelConfig, "receiverAddress"), }) - case domain.NOTIFY_CHANNEL_LARK: + case domain.NotifyChannelTypeLark: return providerLark.New(&providerLark.LarkNotifierConfig{ WebhookUrl: maps.GetValueAsString(channelConfig, "webhookUrl"), }) - case domain.NOTIFY_CHANNEL_SERVERCHAN: + case domain.NotifyChannelTypeServerChan: return providerServerChan.New(&providerServerChan.ServerChanNotifierConfig{ Url: maps.GetValueAsString(channelConfig, "url"), }) - case domain.NOTIFY_CHANNEL_TELEGRAM: + case domain.NotifyChannelTypeTelegram: return providerTelegram.New(&providerTelegram.TelegramNotifierConfig{ ApiToken: maps.GetValueAsString(channelConfig, "apiToken"), ChatId: maps.GetValueAsInt64(channelConfig, "chatId"), }) - case domain.NOTIFY_CHANNEL_WEBHOOK: + case domain.NotifyChannelTypeWebhook: return providerWebhook.New(&providerWebhook.WebhookNotifierConfig{ Url: maps.GetValueAsString(channelConfig, "url"), }) - case domain.NOTIFY_CHANNEL_WECOM: + case domain.NotifyChannelTypeWeCom: return providerWeCom.New(&providerWeCom.WeComNotifierConfig{ WebhookUrl: maps.GetValueAsString(channelConfig, "webhookUrl"), }) diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/acmehttpreq/acmehttpreq.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/acmehttpreq/acmehttpreq.go new file mode 100644 index 00000000..4242809f --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/acmehttpreq/acmehttpreq.go @@ -0,0 +1,41 @@ +package acmehttpreq + +import ( + "errors" + "net/url" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/httpreq" +) + +type ACMEHttpReqApplicantConfig struct { + Endpoint string `json:"endpoint"` + Mode string `json:"mode"` + Username string `json:"username"` + Password string `json:"password"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *ACMEHttpReqApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + endpoint, _ := url.Parse(config.Endpoint) + providerConfig := httpreq.NewDefaultConfig() + providerConfig.Endpoint = endpoint + providerConfig.Mode = config.Mode + providerConfig.Username = config.Username + providerConfig.Password = config.Password + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := httpreq.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/aliyun/aliyun.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/aliyun/aliyun.go new file mode 100644 index 00000000..687cc0ff --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/aliyun/aliyun.go @@ -0,0 +1,35 @@ +package aliyun + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/alidns" +) + +type AliyunApplicantConfig struct { + AccessKeyId string `json:"accessKeyId"` + AccessKeySecret string `json:"accessKeySecret"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *AliyunApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := alidns.NewDefaultConfig() + providerConfig.APIKey = config.AccessKeyId + providerConfig.SecretKey = config.AccessKeySecret + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := alidns.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/aws/aws.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/aws/aws.go new file mode 100644 index 00000000..1a207eee --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/aws/aws.go @@ -0,0 +1,39 @@ +package aws + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/route53" +) + +type AWSApplicantConfig struct { + AccessKeyId string `json:"accessKeyId"` + SecretAccessKey string `json:"secretAccessKey"` + Region string `json:"region"` + HostedZoneId string `json:"hostedZoneId"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *AWSApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := route53.NewDefaultConfig() + providerConfig.AccessKeyID = config.AccessKeyId + providerConfig.SecretAccessKey = config.SecretAccessKey + providerConfig.Region = config.Region + providerConfig.HostedZoneID = config.HostedZoneId + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := route53.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare/cloudflare.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare/cloudflare.go new file mode 100644 index 00000000..0f1abc40 --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare/cloudflare.go @@ -0,0 +1,33 @@ +package cloudflare + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/cloudflare" +) + +type CloudflareApplicantConfig struct { + DnsApiToken string `json:"dnsApiToken"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *CloudflareApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := cloudflare.NewDefaultConfig() + providerConfig.AuthToken = config.DnsApiToken + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := cloudflare.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy/godaddy.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy/godaddy.go new file mode 100644 index 00000000..1a85a28d --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy/godaddy.go @@ -0,0 +1,35 @@ +package godaddy + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/godaddy" +) + +type GoDaddyApplicantConfig struct { + ApiKey string `json:"apiKey"` + ApiSecret string `json:"apiSecret"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *GoDaddyApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := godaddy.NewDefaultConfig() + providerConfig.APIKey = config.ApiKey + providerConfig.APISecret = config.ApiSecret + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := godaddy.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud/huaweicloud.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud/huaweicloud.go new file mode 100644 index 00000000..a271f99c --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud/huaweicloud.go @@ -0,0 +1,43 @@ +package huaweicloud + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + hwc "github.com/go-acme/lego/v4/providers/dns/huaweicloud" +) + +type HuaweiCloudApplicantConfig struct { + AccessKeyId string `json:"accessKeyId"` + SecretAccessKey string `json:"secretAccessKey"` + Region string `json:"region"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *HuaweiCloudApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + region := config.Region + if region == "" { + // 华为云的 SDK 要求必须传一个区域,实际上 DNS-01 流程里用不到,但不传会报错 + region = "cn-north-1" + } + + providerConfig := hwc.NewDefaultConfig() + providerConfig.AccessKeyID = config.AccessKeyId + providerConfig.SecretAccessKey = config.SecretAccessKey + providerConfig.Region = region + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := hwc.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom/namedotcom.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom/namedotcom.go new file mode 100644 index 00000000..b5c8d3cb --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom/namedotcom.go @@ -0,0 +1,35 @@ +package namedotcom + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/namedotcom" +) + +type NameDotComApplicantConfig struct { + Username string `json:"username"` + ApiToken string `json:"apiToken"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *NameDotComApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := namedotcom.NewDefaultConfig() + providerConfig.Username = config.Username + providerConfig.APIToken = config.ApiToken + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := namedotcom.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo/namesilo.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo/namesilo.go new file mode 100644 index 00000000..f62201d6 --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo/namesilo.go @@ -0,0 +1,33 @@ +package namesilo + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/namesilo" +) + +type NameSiloApplicantConfig struct { + ApiKey string `json:"apiKey"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *NameSiloApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := namesilo.NewDefaultConfig() + providerConfig.APIKey = config.ApiKey + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := namesilo.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns/powerdns.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns/powerdns.go new file mode 100644 index 00000000..b6512389 --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns/powerdns.go @@ -0,0 +1,37 @@ +package namesilo + +import ( + "errors" + "net/url" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/pdns" +) + +type PowerDNSApplicantConfig struct { + ApiUrl string `json:"apiUrl"` + ApiKey string `json:"apiKey"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *PowerDNSApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + host, _ := url.Parse(config.ApiUrl) + providerConfig := pdns.NewDefaultConfig() + providerConfig.Host = host + providerConfig.APIKey = config.ApiKey + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := pdns.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud/tencentcloud.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud/tencentcloud.go new file mode 100644 index 00000000..bd335fc4 --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud/tencentcloud.go @@ -0,0 +1,35 @@ +package tencentcloud + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/tencentcloud" +) + +type TencentCloudApplicantConfig struct { + SecretId string `json:"secretId"` + SecretKey string `json:"secretKey"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *TencentCloudApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := tencentcloud.NewDefaultConfig() + providerConfig.SecretID = config.SecretId + providerConfig.SecretKey = config.SecretKey + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := tencentcloud.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine/volcengine.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine/volcengine.go new file mode 100644 index 00000000..0c9ad3c5 --- /dev/null +++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine/volcengine.go @@ -0,0 +1,35 @@ +package volcengine + +import ( + "errors" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/providers/dns/volcengine" +) + +type VolcEngineApplicantConfig struct { + AccessKeyId string `json:"accessKeyId"` + SecretAccessKey string `json:"secretAccessKey"` + PropagationTimeout int32 `json:"propagationTimeout,omitempty"` +} + +func NewChallengeProvider(config *VolcEngineApplicantConfig) (challenge.Provider, error) { + if config == nil { + return nil, errors.New("config is nil") + } + + providerConfig := volcengine.NewDefaultConfig() + providerConfig.AccessKey = config.AccessKeyId + providerConfig.SecretKey = config.SecretAccessKey + if config.PropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.PropagationTimeout) * time.Second + } + + provider, err := volcengine.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/internal/repository/certificate.go b/internal/repository/certificate.go index ed348221..9bce7a9e 100644 --- a/internal/repository/certificate.go +++ b/internal/repository/certificate.go @@ -14,11 +14,13 @@ func NewCertificateRepository() *CertificateRepository { } func (c *CertificateRepository) ListExpireSoon(ctx context.Context) ([]domain.Certificate, error) { - rs := []domain.Certificate{} - if err := app.GetApp().Dao().DB(). + certificates := []domain.Certificate{} + err := app.GetApp().Dao().DB(). NewQuery("SELECT * FROM certificate WHERE expireAt > DATETIME('now') AND expireAt < DATETIME('now', '+20 days')"). - All(&rs); err != nil { + All(&certificates) + if err != nil { return nil, err } - return rs, nil + + return certificates, nil } diff --git a/internal/repository/settings.go b/internal/repository/settings.go index 2b15ffdb..bd13cc2e 100644 --- a/internal/repository/settings.go +++ b/internal/repository/settings.go @@ -20,7 +20,7 @@ func (s *SettingsRepository) GetByName(ctx context.Context, name string) (*domai return nil, err } - rs := &domain.Settings{ + settings := &domain.Settings{ Meta: domain.Meta{ Id: record.GetId(), CreatedAt: record.GetCreated().Time(), @@ -29,6 +29,5 @@ func (s *SettingsRepository) GetByName(ctx context.Context, name string) (*domai Name: record.GetString("name"), Content: record.GetString("content"), } - - return rs, nil + return settings, nil } diff --git a/internal/repository/statistics.go b/internal/repository/statistics.go index 967a2d0c..6cd19009 100644 --- a/internal/repository/statistics.go +++ b/internal/repository/statistics.go @@ -15,6 +15,7 @@ func NewStatisticsRepository() *StatisticsRepository { func (r *StatisticsRepository) Get(ctx context.Context) (*domain.Statistics, error) { rs := &domain.Statistics{} + // 所有证书 certTotal := struct { Total int `db:"total"` diff --git a/internal/repository/workflow.go b/internal/repository/workflow.go index 3f9bd8dd..31e1e606 100644 --- a/internal/repository/workflow.go +++ b/internal/repository/workflow.go @@ -82,7 +82,7 @@ func (w *WorkflowRepository) SaveRun(ctx context.Context, run *domain.WorkflowRu return nil } -func (w *WorkflowRepository) Get(ctx context.Context, id string) (*domain.Workflow, error) { +func (w *WorkflowRepository) GetById(ctx context.Context, id string) (*domain.Workflow, error) { record, err := app.GetApp().Dao().FindRecordById("workflow", id) if err != nil { if errors.Is(err, sql.ErrNoRows) { diff --git a/internal/repository/workflow_output.go b/internal/repository/workflow_output.go index 63ce443a..1e1cf7cf 100644 --- a/internal/repository/workflow_output.go +++ b/internal/repository/workflow_output.go @@ -17,7 +17,7 @@ func NewWorkflowOutputRepository() *WorkflowOutputRepository { return &WorkflowOutputRepository{} } -func (w *WorkflowOutputRepository) Get(ctx context.Context, nodeId string) (*domain.WorkflowOutput, error) { +func (w *WorkflowOutputRepository) GetByNodeId(ctx context.Context, nodeId string) (*domain.WorkflowOutput, error) { records, err := app.GetApp().Dao().FindRecordsByFilter("workflow_output", "nodeId={:nodeId}", "-created", 1, 0, dbx.Params{"nodeId": nodeId}) if err != nil { if errors.Is(err, sql.ErrNoRows) { @@ -56,7 +56,7 @@ func (w *WorkflowOutputRepository) Get(ctx context.Context, nodeId string) (*dom return rs, nil } -func (w *WorkflowOutputRepository) GetCertificate(ctx context.Context, nodeId string) (*domain.Certificate, error) { +func (w *WorkflowOutputRepository) GetCertificateByNodeId(ctx context.Context, nodeId string) (*domain.Certificate, error) { records, err := app.GetApp().Dao().FindRecordsByFilter("certificate", "workflowNodeId={:workflowNodeId}", "-created", 1, 0, dbx.Params{"workflowNodeId": nodeId}) if err != nil { if errors.Is(err, sql.ErrNoRows) { @@ -83,8 +83,8 @@ func (w *WorkflowOutputRepository) GetCertificate(ctx context.Context, nodeId st IssuerCertificate: record.GetString("issuerCertificate"), EffectAt: record.GetTime("effectAt"), ExpireAt: record.GetTime("expireAt"), - AcmeCertUrl: record.GetString("acmeCertUrl"), - AcmeCertStableUrl: record.GetString("acmeCertStableUrl"), + ACMECertUrl: record.GetString("acmeCertUrl"), + ACMECertStableUrl: record.GetString("acmeCertStableUrl"), WorkflowId: record.GetString("workflowId"), WorkflowNodeId: record.GetString("workflowNodeId"), WorkflowOutputId: record.GetString("workflowOutputId"), @@ -137,8 +137,8 @@ func (w *WorkflowOutputRepository) Save(ctx context.Context, output *domain.Work certRecord.Set("issuerCertificate", certificate.IssuerCertificate) certRecord.Set("effectAt", certificate.EffectAt) certRecord.Set("expireAt", certificate.ExpireAt) - certRecord.Set("acmeCertUrl", certificate.AcmeCertUrl) - certRecord.Set("acmeCertStableUrl", certificate.AcmeCertStableUrl) + certRecord.Set("acmeCertUrl", certificate.ACMECertUrl) + certRecord.Set("acmeCertStableUrl", certificate.ACMECertStableUrl) certRecord.Set("workflowId", certificate.WorkflowId) certRecord.Set("workflowNodeId", certificate.WorkflowNodeId) certRecord.Set("workflowOutputId", certificate.WorkflowOutputId) @@ -149,7 +149,7 @@ func (w *WorkflowOutputRepository) Save(ctx context.Context, output *domain.Work // 更新 certificate for i, item := range output.Outputs { - if item.Name == "certificate" { + if item.Name == domain.WORKFLOW_OUTPUT_CERTIFICATE { output.Outputs[i].Value = certRecord.GetId() break } diff --git a/internal/workflow/event.go b/internal/workflow/event.go index e302579d..2f209baa 100644 --- a/internal/workflow/event.go +++ b/internal/workflow/event.go @@ -14,7 +14,7 @@ import ( const tableName = "workflow" -func AddEvent() error { +func RegisterEvents() error { app := app.GetApp() app.OnRecordAfterCreateRequest(tableName).Add(func(e *core.RecordCreateEvent) error { @@ -32,30 +32,23 @@ func AddEvent() error { return nil } -func delete(_ context.Context, record *models.Record) error { - id := record.Id - scheduler := app.GetScheduler() - scheduler.Remove(id) - scheduler.Start() - return nil -} - func update(ctx context.Context, record *models.Record) error { - // 是不是自动 - // 是不是 enabled + scheduler := app.GetScheduler() - workflowId := record.Id + // 向数据库插入/更新时,同时更新定时任务 + workflowId := record.GetId() enabled := record.GetBool("enabled") trigger := record.GetString("trigger") - scheduler := app.GetScheduler() + // 如果是手动触发或未启用,移除定时任务 if !enabled || trigger == string(domain.WorkflowTriggerTypeManual) { - scheduler.Remove(workflowId) + scheduler.Remove(fmt.Sprintf("workflow#%s", workflowId)) scheduler.Start() return nil } - err := scheduler.Add(workflowId, record.GetString("triggerCron"), func() { + // 反之,重新添加定时任务 + err := scheduler.Add(fmt.Sprintf("workflow#%s", workflowId), record.GetString("triggerCron"), func() { NewWorkflowService(repository.NewWorkflowRepository()).Run(ctx, &domain.WorkflowRunReq{ WorkflowId: workflowId, Trigger: domain.WorkflowTriggerTypeAuto, @@ -65,8 +58,19 @@ func update(ctx context.Context, record *models.Record) error { app.GetLogger().Error("add cron job failed", "err", err) return fmt.Errorf("add cron job failed: %w", err) } - app.GetLogger().Error("add cron job failed", "subjectAltNames", record.GetString("subjectAltNames")) scheduler.Start() + + return nil +} + +func delete(_ context.Context, record *models.Record) error { + scheduler := app.GetScheduler() + + // 从数据库删除时,同时移除定时任务 + workflowId := record.GetId() + scheduler.Remove(fmt.Sprintf("workflow#%s", workflowId)) + scheduler.Start() + return nil } diff --git a/internal/workflow/node-processor/apply_node.go b/internal/workflow/node-processor/apply_node.go index 2dc6557c..15466c95 100644 --- a/internal/workflow/node-processor/apply_node.go +++ b/internal/workflow/node-processor/apply_node.go @@ -29,10 +29,10 @@ func NewApplyNode(node *domain.WorkflowNode) *applyNode { type WorkflowOutputRepository interface { // 查询节点输出 - Get(ctx context.Context, nodeId string) (*domain.WorkflowOutput, error) + GetByNodeId(ctx context.Context, nodeId string) (*domain.WorkflowOutput, error) // 查询申请节点的证书 - GetCertificate(ctx context.Context, nodeId string) (*domain.Certificate, error) + GetCertificateByNodeId(ctx context.Context, nodeId string) (*domain.Certificate, error) // 保存节点输出 Save(ctx context.Context, output *domain.WorkflowOutput, certificate *domain.Certificate, cb func(id string) error) error @@ -42,14 +42,14 @@ type WorkflowOutputRepository interface { func (a *applyNode) Run(ctx context.Context) error { a.AddOutput(ctx, a.node.Name, "开始执行") // 查询是否申请过,已申请过则直接返回(先保持和 v0.2 一致) - output, err := a.outputRepo.Get(ctx, a.node.Id) + output, err := a.outputRepo.GetByNodeId(ctx, a.node.Id) if err != nil && !domain.IsRecordNotFound(err) { a.AddOutput(ctx, a.node.Name, "查询申请记录失败", err.Error()) return err } if output != nil && output.Succeeded { - cert, err := a.outputRepo.GetCertificate(ctx, a.node.Id) + cert, err := a.outputRepo.GetCertificateByNodeId(ctx, a.node.Id) if err != nil { a.AddOutput(ctx, a.node.Name, "获取证书失败", err.Error()) return err @@ -62,14 +62,14 @@ func (a *applyNode) Run(ctx context.Context) error { } // 获取Applicant - apply, err := applicant.GetWithApplyNode(a.node) + applicant, err := applicant.GetWithApplyNode(a.node) if err != nil { a.AddOutput(ctx, a.node.Name, "获取申请对象失败", err.Error()) return err } // 申请 - certificate, err := apply.Apply() + certificate, err := applicant.Apply() if err != nil { a.AddOutput(ctx, a.node.Name, "申请失败", err.Error()) return err @@ -103,8 +103,8 @@ func (a *applyNode) Run(ctx context.Context) error { Certificate: certificate.Certificate, PrivateKey: certificate.PrivateKey, IssuerCertificate: certificate.IssuerCertificate, - AcmeCertUrl: certificate.CertUrl, - AcmeCertStableUrl: certificate.CertStableUrl, + ACMECertUrl: certificate.CertUrl, + ACMECertStableUrl: certificate.CertStableUrl, EffectAt: certX509.NotBefore, ExpireAt: certX509.NotAfter, WorkflowId: GetWorkflowId(ctx), diff --git a/internal/workflow/node-processor/deploy_node.go b/internal/workflow/node-processor/deploy_node.go index 965cc3f2..e43c767e 100644 --- a/internal/workflow/node-processor/deploy_node.go +++ b/internal/workflow/node-processor/deploy_node.go @@ -28,7 +28,7 @@ func NewDeployNode(node *domain.WorkflowNode) *deployNode { func (d *deployNode) Run(ctx context.Context) error { d.AddOutput(ctx, d.node.Name, "开始执行") // 检查是否部署过(部署过则直接返回,和 v0.2 暂时保持一致) - output, err := d.outputRepo.Get(ctx, d.node.Id) + output, err := d.outputRepo.GetByNodeId(ctx, d.node.Id) if err != nil && !domain.IsRecordNotFound(err) { d.AddOutput(ctx, d.node.Name, "查询部署记录失败", err.Error()) return err @@ -43,7 +43,7 @@ func (d *deployNode) Run(ctx context.Context) error { return fmt.Errorf("证书来源配置错误: %s", certSource) } - cert, err := d.outputRepo.GetCertificate(ctx, certSourceSlice[0]) + cert, err := d.outputRepo.GetCertificateByNodeId(ctx, certSourceSlice[0]) if err != nil { d.AddOutput(ctx, d.node.Name, "获取证书失败", err.Error()) return err @@ -71,8 +71,8 @@ func (d *deployNode) Run(ctx context.Context) error { AccessConfig: access.Config, AccessRecord: access, Certificate: applicant.Certificate{ - CertUrl: cert.AcmeCertUrl, - CertStableUrl: cert.AcmeCertStableUrl, + CertUrl: cert.ACMECertUrl, + CertStableUrl: cert.ACMECertStableUrl, PrivateKey: cert.PrivateKey, Certificate: cert.Certificate, IssuerCertificate: cert.IssuerCertificate, @@ -85,7 +85,7 @@ func (d *deployNode) Run(ctx context.Context) error { }, } - deploy, err := deployer.GetWithTypeAndOption(d.node.GetConfigString("provider"), option) + deploy, err := deployer.GetWithProviderAndOption(d.node.GetConfigString("provider"), option) if err != nil { d.AddOutput(ctx, d.node.Name, "获取部署对象失败", err.Error()) return err diff --git a/internal/workflow/service.go b/internal/workflow/service.go index 87a27b00..03bb8c80 100644 --- a/internal/workflow/service.go +++ b/internal/workflow/service.go @@ -11,7 +11,7 @@ import ( ) type WorkflowRepository interface { - Get(ctx context.Context, id string) (*domain.Workflow, error) + GetById(ctx context.Context, id string) (*domain.Workflow, error) SaveRun(ctx context.Context, run *domain.WorkflowRun) error ListEnabledAuto(ctx context.Context) ([]domain.Workflow, error) } @@ -27,7 +27,6 @@ func NewWorkflowService(repo WorkflowRepository) *WorkflowService { } func (s *WorkflowService) InitSchedule(ctx context.Context) error { - // 查询所有的 enabled auto workflow workflows, err := s.repo.ListEnabledAuto(ctx) if err != nil { return err @@ -35,7 +34,7 @@ func (s *WorkflowService) InitSchedule(ctx context.Context) error { scheduler := app.GetScheduler() for _, workflow := range workflows { - err := scheduler.Add(workflow.Id, workflow.TriggerCron, func() { + err := scheduler.Add(fmt.Sprintf("workflow#%s", workflow.Id), workflow.TriggerCron, func() { s.Run(ctx, &domain.WorkflowRunReq{ WorkflowId: workflow.Id, Trigger: domain.WorkflowTriggerTypeAuto, @@ -55,21 +54,12 @@ func (s *WorkflowService) InitSchedule(ctx context.Context) error { func (s *WorkflowService) Run(ctx context.Context, options *domain.WorkflowRunReq) error { // 查询 - if options.WorkflowId == "" { - return domain.ErrInvalidParams - } - - workflow, err := s.repo.Get(ctx, options.WorkflowId) + workflow, err := s.repo.GetById(ctx, options.WorkflowId) if err != nil { app.GetLogger().Error("failed to get workflow", "id", options.WorkflowId, "err", err) return err } - if !workflow.Enabled { - app.GetLogger().Error("workflow is disabled", "id", options.WorkflowId) - return fmt.Errorf("workflow is disabled") - } - // 执行 run := &domain.WorkflowRun{ WorkflowId: workflow.Id, @@ -78,7 +68,6 @@ func (s *WorkflowService) Run(ctx context.Context, options *domain.WorkflowRunRe StartedAt: time.Now(), EndedAt: time.Now(), } - processor := nodeprocessor.NewWorkflowProcessor(workflow) if err := processor.Run(ctx); err != nil { run.Status = domain.WorkflowRunStatusTypeFailed @@ -93,7 +82,7 @@ func (s *WorkflowService) Run(ctx context.Context, options *domain.WorkflowRunRe return fmt.Errorf("failed to run workflow: %w", err) } - // 保存执行日志 + // 保存日志 logs := processor.Log(ctx) runStatus := domain.WorkflowRunStatusTypeSucceeded runError := domain.WorkflowRunLogs(logs).FirstError() diff --git a/main.go b/main.go index cb800055..b7885e39 100644 --- a/main.go +++ b/main.go @@ -39,7 +39,7 @@ func main() { Automigrate: isGoRun, }) - workflow.AddEvent() + workflow.RegisterEvents() app.OnBeforeServe().Add(func(e *core.ServeEvent) error { routes.Register(e.Router) diff --git a/ui/src/components/access/AccessEditFormACMEHttpReqConfig.tsx b/ui/src/components/access/AccessEditFormACMEHttpReqConfig.tsx index b81f7fee..07eb1324 100644 --- a/ui/src/components/access/AccessEditFormACMEHttpReqConfig.tsx +++ b/ui/src/components/access/AccessEditFormACMEHttpReqConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type ACMEHttpReqAccessConfig } from "@/domain/access"; +import { type AccessConfigForACMEHttpReq } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormACMEHttpReqConfigFieldValues = Partial; +type AccessEditFormACMEHttpReqConfigFieldValues = Partial; export type AccessEditFormACMEHttpReqConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormAWSConfig.tsx b/ui/src/components/access/AccessEditFormAWSConfig.tsx index 8a7b5b89..382fbb7e 100644 --- a/ui/src/components/access/AccessEditFormAWSConfig.tsx +++ b/ui/src/components/access/AccessEditFormAWSConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AWSAccessConfig } from "@/domain/access"; +import { type AccessConfigForAWS } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormAWSConfigFieldValues = Partial; +type AccessEditFormAWSConfigFieldValues = Partial; export type AccessEditFormAWSConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormAliyunConfig.tsx b/ui/src/components/access/AccessEditFormAliyunConfig.tsx index b77aa9d3..108caac9 100644 --- a/ui/src/components/access/AccessEditFormAliyunConfig.tsx +++ b/ui/src/components/access/AccessEditFormAliyunConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type AliyunAccessConfig } from "@/domain/access"; +import { type AccessConfigForAliyun } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormAliyunConfigFieldValues = Partial; +type AccessEditFormAliyunConfigFieldValues = Partial; export type AccessEditFormAliyunConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormBaiduCloudConfig.tsx b/ui/src/components/access/AccessEditFormBaiduCloudConfig.tsx index 26f6523f..64a53016 100644 --- a/ui/src/components/access/AccessEditFormBaiduCloudConfig.tsx +++ b/ui/src/components/access/AccessEditFormBaiduCloudConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type BaiduCloudAccessConfig } from "@/domain/access"; +import { type AccessConfigForBaiduCloud } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormBaiduCloudConfigFieldValues = Partial; +type AccessEditFormBaiduCloudConfigFieldValues = Partial; export type AccessEditFormBaiduCloudConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormBytePlusConfig.tsx b/ui/src/components/access/AccessEditFormBytePlusConfig.tsx index fc3e3e11..43ad4993 100644 --- a/ui/src/components/access/AccessEditFormBytePlusConfig.tsx +++ b/ui/src/components/access/AccessEditFormBytePlusConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type BytePlusAccessConfig } from "@/domain/access"; +import { type AccessConfigForBytePlus } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormBytePlusConfigFieldValues = Partial; +type AccessEditFormBytePlusConfigFieldValues = Partial; export type AccessEditFormBytePlusConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormCloudflareConfig.tsx b/ui/src/components/access/AccessEditFormCloudflareConfig.tsx index 7c7ad2f1..ab242038 100644 --- a/ui/src/components/access/AccessEditFormCloudflareConfig.tsx +++ b/ui/src/components/access/AccessEditFormCloudflareConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type CloudflareAccessConfig } from "@/domain/access"; +import { type AccessConfigForCloudflare } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormCloudflareConfigFieldValues = Partial; +type AccessEditFormCloudflareConfigFieldValues = Partial; export type AccessEditFormCloudflareConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormDogeCloudConfig.tsx b/ui/src/components/access/AccessEditFormDogeCloudConfig.tsx index ffeae8b1..04b9e763 100644 --- a/ui/src/components/access/AccessEditFormDogeCloudConfig.tsx +++ b/ui/src/components/access/AccessEditFormDogeCloudConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type DogeCloudAccessConfig } from "@/domain/access"; +import { type AccessConfigForDogeCloud } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormDogeCloudConfigFieldValues = Partial; +type AccessEditFormDogeCloudConfigFieldValues = Partial; export type AccessEditFormDogeCloudConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormGoDaddyConfig.tsx b/ui/src/components/access/AccessEditFormGoDaddyConfig.tsx index 364369c7..d91820db 100644 --- a/ui/src/components/access/AccessEditFormGoDaddyConfig.tsx +++ b/ui/src/components/access/AccessEditFormGoDaddyConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type GoDaddyAccessConfig } from "@/domain/access"; +import { type AccessConfigForGoDaddy } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormGoDaddyConfigFieldValues = Partial; +type AccessEditFormGoDaddyConfigFieldValues = Partial; export type AccessEditFormGoDaddyConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormHuaweiCloudConfig.tsx b/ui/src/components/access/AccessEditFormHuaweiCloudConfig.tsx index a38e860e..0db63be1 100644 --- a/ui/src/components/access/AccessEditFormHuaweiCloudConfig.tsx +++ b/ui/src/components/access/AccessEditFormHuaweiCloudConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type HuaweiCloudAccessConfig } from "@/domain/access"; +import { type AccessConfigForHuaweiCloud } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormHuaweiCloudConfigFieldValues = Partial; +type AccessEditFormHuaweiCloudConfigFieldValues = Partial; export type AccessEditFormHuaweiCloudConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormKubernetesConfig.tsx b/ui/src/components/access/AccessEditFormKubernetesConfig.tsx index 4859f03a..ae24c440 100644 --- a/ui/src/components/access/AccessEditFormKubernetesConfig.tsx +++ b/ui/src/components/access/AccessEditFormKubernetesConfig.tsx @@ -7,11 +7,11 @@ import { Button, Form, type FormInstance, Input, Upload, type UploadFile, type U import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type KubernetesAccessConfig } from "@/domain/access"; +import { type AccessConfigForKubernetes } from "@/domain/access"; import { useAntdForm } from "@/hooks"; import { readFileContent } from "@/utils/file"; -type AccessEditFormKubernetesConfigFieldValues = Partial; +type AccessEditFormKubernetesConfigFieldValues = Partial; export type AccessEditFormKubernetesConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormLocalConfig.tsx b/ui/src/components/access/AccessEditFormLocalConfig.tsx index c25683f1..d0c20d58 100644 --- a/ui/src/components/access/AccessEditFormLocalConfig.tsx +++ b/ui/src/components/access/AccessEditFormLocalConfig.tsx @@ -1,9 +1,9 @@ import { Form, type FormInstance } from "antd"; -import { type LocalAccessConfig } from "@/domain/access"; +import { type AccessConfigForLocal } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormLocalConfigFieldValues = Partial; +type AccessEditFormLocalConfigFieldValues = Partial; export type AccessEditFormLocalConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormNameDotComConfig.tsx b/ui/src/components/access/AccessEditFormNameDotComConfig.tsx index a73a4e18..3e5ec9ca 100644 --- a/ui/src/components/access/AccessEditFormNameDotComConfig.tsx +++ b/ui/src/components/access/AccessEditFormNameDotComConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type NameDotComAccessConfig } from "@/domain/access"; +import { type AccessConfigForNameDotCom } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormNameDotComConfigFieldValues = Partial; +type AccessEditFormNameDotComConfigFieldValues = Partial; export type AccessEditFormNameDotComConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormNameSiloConfig.tsx b/ui/src/components/access/AccessEditFormNameSiloConfig.tsx index fc62a7ad..0228daf8 100644 --- a/ui/src/components/access/AccessEditFormNameSiloConfig.tsx +++ b/ui/src/components/access/AccessEditFormNameSiloConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type NameSiloAccessConfig } from "@/domain/access"; +import { type AccessConfigForNameSilo } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormNameSiloConfigFieldValues = Partial; +type AccessEditFormNameSiloConfigFieldValues = Partial; export type AccessEditFormNameSiloConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormPowerDNSConfig.tsx b/ui/src/components/access/AccessEditFormPowerDNSConfig.tsx index c0bdef90..bdcfed26 100644 --- a/ui/src/components/access/AccessEditFormPowerDNSConfig.tsx +++ b/ui/src/components/access/AccessEditFormPowerDNSConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type PowerDNSAccessConfig } from "@/domain/access"; +import { type AccessConfigForPowerDNS } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormPowerDNSConfigFieldValues = Partial; +type AccessEditFormPowerDNSConfigFieldValues = Partial; export type AccessEditFormPowerDNSConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormQiniuConfig.tsx b/ui/src/components/access/AccessEditFormQiniuConfig.tsx index 73d923ff..6e9f2941 100644 --- a/ui/src/components/access/AccessEditFormQiniuConfig.tsx +++ b/ui/src/components/access/AccessEditFormQiniuConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type QiniuAccessConfig } from "@/domain/access"; +import { type AccessConfigForQiniu } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormQiniuConfigFieldValues = Partial; +type AccessEditFormQiniuConfigFieldValues = Partial; export type AccessEditFormQiniuConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormSSHConfig.tsx b/ui/src/components/access/AccessEditFormSSHConfig.tsx index c4f858ee..bc98ad94 100644 --- a/ui/src/components/access/AccessEditFormSSHConfig.tsx +++ b/ui/src/components/access/AccessEditFormSSHConfig.tsx @@ -7,12 +7,12 @@ import { Button, Form, type FormInstance, Input, InputNumber, Upload, type Uploa import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type SSHAccessConfig } from "@/domain/access"; +import { type AccessConfigForSSH } from "@/domain/access"; import { useAntdForm } from "@/hooks"; import { readFileContent } from "@/utils/file"; import { validDomainName, validIPv4Address, validIPv6Address } from "@/utils/validators"; -type AccessEditFormSSHConfigFieldValues = Partial; +type AccessEditFormSSHConfigFieldValues = Partial; export type AccessEditFormSSHConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormTencentCloudConfig.tsx b/ui/src/components/access/AccessEditFormTencentCloudConfig.tsx index 1e8a1e25..7739d9bc 100644 --- a/ui/src/components/access/AccessEditFormTencentCloudConfig.tsx +++ b/ui/src/components/access/AccessEditFormTencentCloudConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type TencentCloudAccessConfig } from "@/domain/access"; +import { type AccessConfigForTencentCloud } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormTencentCloudConfigFieldValues = Partial; +type AccessEditFormTencentCloudConfigFieldValues = Partial; export type AccessEditFormTencentCloudConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormVolcEngineConfig.tsx b/ui/src/components/access/AccessEditFormVolcEngineConfig.tsx index 342d7b18..687e6d50 100644 --- a/ui/src/components/access/AccessEditFormVolcEngineConfig.tsx +++ b/ui/src/components/access/AccessEditFormVolcEngineConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type VolcEngineAccessConfig } from "@/domain/access"; +import { type AccessConfigForVolcEngine } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormVolcEngineConfigFieldValues = Partial; +type AccessEditFormVolcEngineConfigFieldValues = Partial; export type AccessEditFormVolcEngineConfigProps = { form: FormInstance; diff --git a/ui/src/components/access/AccessEditFormWebhookConfig.tsx b/ui/src/components/access/AccessEditFormWebhookConfig.tsx index fc451ba0..03192e27 100644 --- a/ui/src/components/access/AccessEditFormWebhookConfig.tsx +++ b/ui/src/components/access/AccessEditFormWebhookConfig.tsx @@ -3,10 +3,10 @@ import { Form, type FormInstance, Input } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type WebhookAccessConfig } from "@/domain/access"; +import { type AccessConfigForWebhook } from "@/domain/access"; import { useAntdForm } from "@/hooks"; -type AccessEditFormWebhookConfigFieldValues = Partial; +type AccessEditFormWebhookConfigFieldValues = Partial; export type AccessEditFormWebhookConfigProps = { form: FormInstance; diff --git a/ui/src/components/certificate/CertificateDetail.tsx b/ui/src/components/certificate/CertificateDetail.tsx index 6faff028..b82cb8db 100644 --- a/ui/src/components/certificate/CertificateDetail.tsx +++ b/ui/src/components/certificate/CertificateDetail.tsx @@ -96,16 +96,14 @@ const CertificateDetail = ({ data, ...props }: CertificateDetailProps) => { key: "PFX", label: "PFX", onClick: () => { - // TODO: 下载 PFX 格式证书 - alert("TODO"); + alert("TODO: 暂时不支持下载 PFX 证书"); }, }, { key: "JKS", label: "JKS", onClick: () => { - // TODO: 下载 JKS 格式证书 - alert("TODO"); + alert("TODO: 暂时不支持下载 JKS 证书"); }, }, ], diff --git a/ui/src/components/workflow/WorkflowElement.tsx b/ui/src/components/workflow/WorkflowElement.tsx index ad4a4fb1..fdb4b99c 100644 --- a/ui/src/components/workflow/WorkflowElement.tsx +++ b/ui/src/components/workflow/WorkflowElement.tsx @@ -9,10 +9,10 @@ import { notifyChannelsMap } from "@/domain/settings"; import { WORKFLOW_TRIGGERS, type WorkflowNode, - type WorkflowNodeConfigAsApply, - type WorkflowNodeConfigAsDeploy, - type WorkflowNodeConfigAsNotify, - type WorkflowNodeConfigAsStart, + type WorkflowNodeConfigForApply, + type WorkflowNodeConfigForDeploy, + type WorkflowNodeConfigForNotify, + type WorkflowNodeConfigForStart, WorkflowNodeType, } from "@/domain/workflow"; import { useZustandShallowSelector } from "@/hooks"; @@ -40,7 +40,7 @@ const WorkflowElement = ({ node, disabled }: NodeProps) => { switch (node.type) { case WorkflowNodeType.Start: { - const config = (node.config as WorkflowNodeConfigAsStart) ?? {}; + const config = (node.config as WorkflowNodeConfigForStart) ?? {}; return (
@@ -58,12 +58,12 @@ const WorkflowElement = ({ node, disabled }: NodeProps) => { } case WorkflowNodeType.Apply: { - const config = (node.config as WorkflowNodeConfigAsApply) ?? {}; + const config = (node.config as WorkflowNodeConfigForApply) ?? {}; return {config.domains || " "}; } case WorkflowNodeType.Deploy: { - const config = (node.config as WorkflowNodeConfigAsDeploy) ?? {}; + const config = (node.config as WorkflowNodeConfigForDeploy) ?? {}; const provider = deployProvidersMap.get(config.provider); return ( @@ -74,7 +74,7 @@ const WorkflowElement = ({ node, disabled }: NodeProps) => { } case WorkflowNodeType.Notify: { - const config = (node.config as WorkflowNodeConfigAsNotify) ?? {}; + const config = (node.config as WorkflowNodeConfigForNotify) ?? {}; const channel = notifyChannelsMap.get(config.channel as string); return (
diff --git a/ui/src/components/workflow/node/ApplyNodeForm.tsx b/ui/src/components/workflow/node/ApplyNodeForm.tsx index 8628b245..11a469bd 100644 --- a/ui/src/components/workflow/node/ApplyNodeForm.tsx +++ b/ui/src/components/workflow/node/ApplyNodeForm.tsx @@ -12,7 +12,7 @@ import MultipleInput from "@/components/MultipleInput"; import AccessEditModal from "@/components/access/AccessEditModal"; import AccessSelect from "@/components/access/AccessSelect"; import { ACCESS_USAGES, accessProvidersMap } from "@/domain/provider"; -import { type WorkflowNode, type WorkflowNodeConfigAsApply } from "@/domain/workflow"; +import { type WorkflowNode, type WorkflowNodeConfigForApply } from "@/domain/workflow"; import { useAntdForm, useZustandShallowSelector } from "@/hooks"; import { useAccessesStore } from "@/stores/access"; import { useContactEmailsStore } from "@/stores/contact"; @@ -26,7 +26,7 @@ export type ApplyNodeFormProps = { const MULTIPLE_INPUT_DELIMITER = ";"; -const initFormModel = (): Partial => { +const initFormModel = (): Partial => { return { keyAlgorithm: "RSA2048", propagationTimeout: 60, @@ -76,7 +76,7 @@ const ApplyNodeForm = ({ node }: ApplyNodeFormProps) => { formPending, formProps, } = useAntdForm>({ - initialValues: (node?.config as WorkflowNodeConfigAsApply) ?? initFormModel(), + initialValues: (node?.config as WorkflowNodeConfigForApply) ?? initFormModel(), onSubmit: async (values) => { await formInst.validateFields(); await addEmail(values.contactEmail); @@ -85,7 +85,7 @@ const ApplyNodeForm = ({ node }: ApplyNodeFormProps) => { draft.config = { provider: accesses.find((e) => e.id === values.providerAccessId)?.provider, ...values, - } as WorkflowNodeConfigAsApply; + } as WorkflowNodeConfigForApply; draft.validated = true; }) ); diff --git a/ui/src/components/workflow/node/DeployNodeForm.tsx b/ui/src/components/workflow/node/DeployNodeForm.tsx index e075a841..aab6628d 100644 --- a/ui/src/components/workflow/node/DeployNodeForm.tsx +++ b/ui/src/components/workflow/node/DeployNodeForm.tsx @@ -12,7 +12,7 @@ import AccessSelect from "@/components/access/AccessSelect"; import DeployProviderPicker from "@/components/provider/DeployProviderPicker"; import DeployProviderSelect from "@/components/provider/DeployProviderSelect"; import { ACCESS_USAGES, DEPLOY_PROVIDERS, accessProvidersMap, deployProvidersMap } from "@/domain/provider"; -import { type WorkflowNode, type WorkflowNodeConfigAsDeploy } from "@/domain/workflow"; +import { type WorkflowNode, type WorkflowNodeConfigForDeploy } from "@/domain/workflow"; import { useAntdForm, useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; import { usePanel } from "../PanelProvider"; @@ -44,7 +44,7 @@ export type DeployFormProps = { node: WorkflowNode; }; -const initFormModel = (): Partial => { +const initFormModel = (): Partial => { return {}; }; @@ -67,7 +67,7 @@ const DeployNodeForm = ({ node }: DeployFormProps) => { formPending, formProps, } = useAntdForm>({ - initialValues: (node?.config as WorkflowNodeConfigAsDeploy) ?? initFormModel(), + initialValues: (node?.config as WorkflowNodeConfigForDeploy) ?? initFormModel(), onSubmit: async (values) => { await formInst.validateFields(); await updateNode( diff --git a/ui/src/components/workflow/node/NotifyNodeForm.tsx b/ui/src/components/workflow/node/NotifyNodeForm.tsx index 539562b4..1b645a57 100644 --- a/ui/src/components/workflow/node/NotifyNodeForm.tsx +++ b/ui/src/components/workflow/node/NotifyNodeForm.tsx @@ -8,7 +8,7 @@ import { produce } from "immer"; import { z } from "zod"; import { notifyChannelsMap } from "@/domain/settings"; -import { type WorkflowNode, type WorkflowNodeConfigAsNotify } from "@/domain/workflow"; +import { type WorkflowNode, type WorkflowNodeConfigForNotify } from "@/domain/workflow"; import { useAntdForm, useZustandShallowSelector } from "@/hooks"; import { useNotifyChannelsStore } from "@/stores/notify"; import { useWorkflowStore } from "@/stores/workflow"; @@ -18,7 +18,7 @@ export type NotifyNodeFormProps = { node: WorkflowNode; }; -const initFormModel = (): Partial => { +const initFormModel = (): Partial => { return { subject: "Completed!", message: "Your workflow has been completed on Certimate.", @@ -57,7 +57,7 @@ const NotifyNodeForm = ({ node }: NotifyNodeFormProps) => { formPending, formProps, } = useAntdForm>({ - initialValues: (node?.config as WorkflowNodeConfigAsNotify) ?? initFormModel(), + initialValues: (node?.config as WorkflowNodeConfigForNotify) ?? initFormModel(), onSubmit: async (values) => { await formInst.validateFields(); await updateNode( diff --git a/ui/src/components/workflow/node/StartNodeForm.tsx b/ui/src/components/workflow/node/StartNodeForm.tsx index 326d7f32..92292266 100644 --- a/ui/src/components/workflow/node/StartNodeForm.tsx +++ b/ui/src/components/workflow/node/StartNodeForm.tsx @@ -7,7 +7,7 @@ import { produce } from "immer"; import { z } from "zod"; import Show from "@/components/Show"; -import { WORKFLOW_TRIGGERS, type WorkflowNode, type WorkflowNodeConfigAsStart } from "@/domain/workflow"; +import { WORKFLOW_TRIGGERS, type WorkflowNode, type WorkflowNodeConfigForStart } from "@/domain/workflow"; import { useAntdForm, useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; import { getNextCronExecutions, validCronExpression } from "@/utils/cron"; @@ -17,7 +17,7 @@ export type StartNodeFormProps = { node: WorkflowNode; }; -const initFormModel = (): WorkflowNodeConfigAsStart => { +const initFormModel = (): WorkflowNodeConfigForStart => { return { trigger: WORKFLOW_TRIGGERS.AUTO, triggerCron: "0 0 * * *", @@ -54,7 +54,7 @@ const StartNodeForm = ({ node }: StartNodeFormProps) => { formPending, formProps, } = useAntdForm>({ - initialValues: (node?.config as WorkflowNodeConfigAsStart) ?? initFormModel(), + initialValues: (node?.config as WorkflowNodeConfigForStart) ?? initFormModel(), onSubmit: async (values) => { await formInst.validateFields(); await updateNode( diff --git a/ui/src/domain/access.ts b/ui/src/domain/access.ts index 5fc6dde6..9cd7ad19 100644 --- a/ui/src/domain/access.ts +++ b/ui/src/domain/access.ts @@ -1,6 +1,5 @@ import { type AccessUsageType } from "./provider"; -// #region AccessModel export interface AccessModel extends BaseModel { name: string; provider: string; @@ -9,106 +8,105 @@ export interface AccessModel extends BaseModel { NOTICE: If you add new type, please keep ASCII order. */ Record & ( - | ACMEHttpReqAccessConfig - | AliyunAccessConfig - | AWSAccessConfig - | BaiduCloudAccessConfig - | BytePlusAccessConfig - | CloudflareAccessConfig - | DogeCloudAccessConfig - | GoDaddyAccessConfig - | HuaweiCloudAccessConfig - | KubernetesAccessConfig - | LocalAccessConfig - | NameDotComAccessConfig - | NameSiloAccessConfig - | PowerDNSAccessConfig - | QiniuAccessConfig - | SSHAccessConfig - | TencentCloudAccessConfig - | VolcEngineAccessConfig - | WebhookAccessConfig + | AccessConfigForACMEHttpReq + | AccessConfigForAliyun + | AccessConfigForAWS + | AccessConfigForBaiduCloud + | AccessConfigForBytePlus + | AccessConfigForCloudflare + | AccessConfigForDogeCloud + | AccessConfigForGoDaddy + | AccessConfigForHuaweiCloud + | AccessConfigForKubernetes + | AccessConfigForLocal + | AccessConfigForNameDotCom + | AccessConfigForNameSilo + | AccessConfigForPowerDNS + | AccessConfigForQiniu + | AccessConfigForSSH + | AccessConfigForTencentCloud + | AccessConfigForVolcEngine + | AccessConfigForWebhook ); usage: AccessUsageType; } -// #endregion // #region AccessConfig -export type ACMEHttpReqAccessConfig = { +export type AccessConfigForACMEHttpReq = { endpoint: string; mode?: string; username?: string; password?: string; }; -export type AliyunAccessConfig = { +export type AccessConfigForAliyun = { accessKeyId: string; accessKeySecret: string; }; -export type AWSAccessConfig = { +export type AccessConfigForAWS = { accessKeyId: string; secretAccessKey: string; region?: string; hostedZoneId?: string; }; -export type BaiduCloudAccessConfig = { +export type AccessConfigForBaiduCloud = { accessKeyId: string; secretAccessKey: string; }; -export type BytePlusAccessConfig = { +export type AccessConfigForBytePlus = { accessKey: string; secretKey: string; }; -export type CloudflareAccessConfig = { +export type AccessConfigForCloudflare = { dnsApiToken: string; }; -export type DogeCloudAccessConfig = { +export type AccessConfigForDogeCloud = { accessKey: string; secretKey: string; }; -export type GoDaddyAccessConfig = { +export type AccessConfigForGoDaddy = { apiKey: string; apiSecret: string; }; -export type HuaweiCloudAccessConfig = { +export type AccessConfigForHuaweiCloud = { accessKeyId: string; secretAccessKey: string; region?: string; }; -export type KubernetesAccessConfig = { +export type AccessConfigForKubernetes = { kubeConfig?: string; }; -export type LocalAccessConfig = NonNullable; +export type AccessConfigForLocal = NonNullable; -export type NameDotComAccessConfig = { +export type AccessConfigForNameDotCom = { username: string; apiToken: string; }; -export type NameSiloAccessConfig = { +export type AccessConfigForNameSilo = { apiKey: string; }; -export type PowerDNSAccessConfig = { +export type AccessConfigForPowerDNS = { apiUrl: string; apiKey: string; }; -export type QiniuAccessConfig = { +export type AccessConfigForQiniu = { accessKey: string; secretKey: string; }; -export type SSHAccessConfig = { +export type AccessConfigForSSH = { host: string; port: number; username: string; @@ -117,17 +115,17 @@ export type SSHAccessConfig = { keyPassphrase?: string; }; -export type TencentCloudAccessConfig = { +export type AccessConfigForTencentCloud = { secretId: string; secretKey: string; }; -export type VolcEngineAccessConfig = { +export type AccessConfigForVolcEngine = { accessKeyId: string; secretAccessKey: string; }; -export type WebhookAccessConfig = { +export type AccessConfigForWebhook = { url: string; }; // #endregion diff --git a/ui/src/domain/workflow.ts b/ui/src/domain/workflow.ts index 77c8f497..379d6c1b 100644 --- a/ui/src/domain/workflow.ts +++ b/ui/src/domain/workflow.ts @@ -95,12 +95,12 @@ export type WorkflowNode = { validated?: boolean; }; -export type WorkflowNodeConfigAsStart = { +export type WorkflowNodeConfigForStart = { trigger: string; triggerCron?: string; }; -export type WorkflowNodeConfigAsApply = { +export type WorkflowNodeConfigForApply = { domains: string; contactEmail: string; provider: string; @@ -111,22 +111,22 @@ export type WorkflowNodeConfigAsApply = { disableFollowCNAME?: boolean; }; -export type WorkflowNodeConfigAsDeploy = { +export type WorkflowNodeConfigForDeploy = { provider: string; providerAccessId: string; certificate: string; [key: string]: unknown; }; -export type WorkflowNodeConfigAsNotify = { +export type WorkflowNodeConfigForNotify = { channel: string; subject: string; message: string; }; -export type WorkflowNodeConfigAsBranch = never; +export type WorkflowNodeConfigForBranch = never; -export type WorkflowNodeConfigAsEnd = never; +export type WorkflowNodeConfigForEnd = never; export type WorkflowNodeIO = { name: string; @@ -403,7 +403,7 @@ export const isAllNodesValidated = (node: WorkflowNode): boolean => { */ export const getExecuteMethod = (node: WorkflowNode): { trigger: string; triggerCron: string } => { if (node.type === WorkflowNodeType.Start) { - const config = node.config as WorkflowNodeConfigAsStart; + const config = node.config as WorkflowNodeConfigForStart; return { trigger: config.trigger ?? "", triggerCron: config.triggerCron ?? "",