mirror of
https://github.com/woodchen-ink/certimate.git
synced 2025-07-18 09:21:56 +08:00
refactor: clean code
This commit is contained in:
parent
3b9a7fe805
commit
61843a4997
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
199
internal/applicant/providers.go
Normal file
199
internal/applicant/providers.go
Normal file
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
@ -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"`
|
||||
}
|
||||
|
@ -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"`
|
||||
|
@ -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 {
|
||||
|
66
internal/domain/provider.go
Normal file
66
internal/domain/provider.go
Normal file
@ -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")
|
||||
)
|
@ -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"
|
||||
|
@ -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"),
|
||||
})
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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"`
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
2
main.go
2
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)
|
||||
|
@ -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<ACMEHttpReqAccessConfig>;
|
||||
type AccessEditFormACMEHttpReqConfigFieldValues = Partial<AccessConfigForACMEHttpReq>;
|
||||
|
||||
export type AccessEditFormACMEHttpReqConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<AWSAccessConfig>;
|
||||
type AccessEditFormAWSConfigFieldValues = Partial<AccessConfigForAWS>;
|
||||
|
||||
export type AccessEditFormAWSConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<AliyunAccessConfig>;
|
||||
type AccessEditFormAliyunConfigFieldValues = Partial<AccessConfigForAliyun>;
|
||||
|
||||
export type AccessEditFormAliyunConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<BaiduCloudAccessConfig>;
|
||||
type AccessEditFormBaiduCloudConfigFieldValues = Partial<AccessConfigForBaiduCloud>;
|
||||
|
||||
export type AccessEditFormBaiduCloudConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<BytePlusAccessConfig>;
|
||||
type AccessEditFormBytePlusConfigFieldValues = Partial<AccessConfigForBytePlus>;
|
||||
|
||||
export type AccessEditFormBytePlusConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<CloudflareAccessConfig>;
|
||||
type AccessEditFormCloudflareConfigFieldValues = Partial<AccessConfigForCloudflare>;
|
||||
|
||||
export type AccessEditFormCloudflareConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<DogeCloudAccessConfig>;
|
||||
type AccessEditFormDogeCloudConfigFieldValues = Partial<AccessConfigForDogeCloud>;
|
||||
|
||||
export type AccessEditFormDogeCloudConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<GoDaddyAccessConfig>;
|
||||
type AccessEditFormGoDaddyConfigFieldValues = Partial<AccessConfigForGoDaddy>;
|
||||
|
||||
export type AccessEditFormGoDaddyConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<HuaweiCloudAccessConfig>;
|
||||
type AccessEditFormHuaweiCloudConfigFieldValues = Partial<AccessConfigForHuaweiCloud>;
|
||||
|
||||
export type AccessEditFormHuaweiCloudConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<KubernetesAccessConfig>;
|
||||
type AccessEditFormKubernetesConfigFieldValues = Partial<AccessConfigForKubernetes>;
|
||||
|
||||
export type AccessEditFormKubernetesConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<LocalAccessConfig>;
|
||||
type AccessEditFormLocalConfigFieldValues = Partial<AccessConfigForLocal>;
|
||||
|
||||
export type AccessEditFormLocalConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<NameDotComAccessConfig>;
|
||||
type AccessEditFormNameDotComConfigFieldValues = Partial<AccessConfigForNameDotCom>;
|
||||
|
||||
export type AccessEditFormNameDotComConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<NameSiloAccessConfig>;
|
||||
type AccessEditFormNameSiloConfigFieldValues = Partial<AccessConfigForNameSilo>;
|
||||
|
||||
export type AccessEditFormNameSiloConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<PowerDNSAccessConfig>;
|
||||
type AccessEditFormPowerDNSConfigFieldValues = Partial<AccessConfigForPowerDNS>;
|
||||
|
||||
export type AccessEditFormPowerDNSConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<QiniuAccessConfig>;
|
||||
type AccessEditFormQiniuConfigFieldValues = Partial<AccessConfigForQiniu>;
|
||||
|
||||
export type AccessEditFormQiniuConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<SSHAccessConfig>;
|
||||
type AccessEditFormSSHConfigFieldValues = Partial<AccessConfigForSSH>;
|
||||
|
||||
export type AccessEditFormSSHConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<TencentCloudAccessConfig>;
|
||||
type AccessEditFormTencentCloudConfigFieldValues = Partial<AccessConfigForTencentCloud>;
|
||||
|
||||
export type AccessEditFormTencentCloudConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<VolcEngineAccessConfig>;
|
||||
type AccessEditFormVolcEngineConfigFieldValues = Partial<AccessConfigForVolcEngine>;
|
||||
|
||||
export type AccessEditFormVolcEngineConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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<WebhookAccessConfig>;
|
||||
type AccessEditFormWebhookConfigFieldValues = Partial<AccessConfigForWebhook>;
|
||||
|
||||
export type AccessEditFormWebhookConfigProps = {
|
||||
form: FormInstance;
|
||||
|
@ -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 证书");
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -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 (
|
||||
<div className="flex items-center justify-between space-x-2">
|
||||
<Typography.Text className="truncate">
|
||||
@ -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 <Typography.Text className="truncate">{config.domains || " "}</Typography.Text>;
|
||||
}
|
||||
|
||||
case WorkflowNodeType.Deploy: {
|
||||
const config = (node.config as WorkflowNodeConfigAsDeploy) ?? {};
|
||||
const config = (node.config as WorkflowNodeConfigForDeploy) ?? {};
|
||||
const provider = deployProvidersMap.get(config.provider);
|
||||
return (
|
||||
<Space>
|
||||
@ -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 (
|
||||
<div className="flex items-center justify-between space-x-2">
|
||||
|
@ -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<WorkflowNodeConfigAsApply> => {
|
||||
const initFormModel = (): Partial<WorkflowNodeConfigForApply> => {
|
||||
return {
|
||||
keyAlgorithm: "RSA2048",
|
||||
propagationTimeout: 60,
|
||||
@ -76,7 +76,7 @@ const ApplyNodeForm = ({ node }: ApplyNodeFormProps) => {
|
||||
formPending,
|
||||
formProps,
|
||||
} = useAntdForm<z.infer<typeof formSchema>>({
|
||||
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;
|
||||
})
|
||||
);
|
||||
|
@ -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<WorkflowNodeConfigAsDeploy> => {
|
||||
const initFormModel = (): Partial<WorkflowNodeConfigForDeploy> => {
|
||||
return {};
|
||||
};
|
||||
|
||||
@ -67,7 +67,7 @@ const DeployNodeForm = ({ node }: DeployFormProps) => {
|
||||
formPending,
|
||||
formProps,
|
||||
} = useAntdForm<z.infer<typeof formSchema>>({
|
||||
initialValues: (node?.config as WorkflowNodeConfigAsDeploy) ?? initFormModel(),
|
||||
initialValues: (node?.config as WorkflowNodeConfigForDeploy) ?? initFormModel(),
|
||||
onSubmit: async (values) => {
|
||||
await formInst.validateFields();
|
||||
await updateNode(
|
||||
|
@ -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<WorkflowNodeConfigAsNotify> => {
|
||||
const initFormModel = (): Partial<WorkflowNodeConfigForNotify> => {
|
||||
return {
|
||||
subject: "Completed!",
|
||||
message: "Your workflow has been completed on Certimate.",
|
||||
@ -57,7 +57,7 @@ const NotifyNodeForm = ({ node }: NotifyNodeFormProps) => {
|
||||
formPending,
|
||||
formProps,
|
||||
} = useAntdForm<z.infer<typeof formSchema>>({
|
||||
initialValues: (node?.config as WorkflowNodeConfigAsNotify) ?? initFormModel(),
|
||||
initialValues: (node?.config as WorkflowNodeConfigForNotify) ?? initFormModel(),
|
||||
onSubmit: async (values) => {
|
||||
await formInst.validateFields();
|
||||
await updateNode(
|
||||
|
@ -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<z.infer<typeof formSchema>>({
|
||||
initialValues: (node?.config as WorkflowNodeConfigAsStart) ?? initFormModel(),
|
||||
initialValues: (node?.config as WorkflowNodeConfigForStart) ?? initFormModel(),
|
||||
onSubmit: async (values) => {
|
||||
await formInst.validateFields();
|
||||
await updateNode(
|
||||
|
@ -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<string, unknown> &
|
||||
(
|
||||
| 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<unknown>;
|
||||
export type AccessConfigForLocal = NonNullable<unknown>;
|
||||
|
||||
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
|
||||
|
@ -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 ?? "",
|
||||
|
Loading…
x
Reference in New Issue
Block a user