diff --git a/internal/certapply/applicators/sp_bookmyname.go b/internal/certapply/applicators/sp_bookmyname.go
new file mode 100644
index 000000000..90c9c3a28
--- /dev/null
+++ b/internal/certapply/applicators/sp_bookmyname.go
@@ -0,0 +1,30 @@
+package applicators
+
+import (
+ "fmt"
+
+ "github.com/go-acme/lego/v4/challenge"
+
+ "github.com/certimate-go/certimate/internal/domain"
+ "github.com/certimate-go/certimate/pkg/core/ssl-applicator/acme-dns01/providers/bookmyname"
+ xmaps "github.com/certimate-go/certimate/pkg/utils/maps"
+)
+
+func init() {
+ if err := ACMEDns01Registries.Register(domain.ACMEDns01ProviderTypeBookMyName, func(options *ProviderFactoryOptions) (challenge.Provider, error) {
+ credentials := domain.AccessConfigForBookMyName{}
+ if err := xmaps.Populate(options.ProviderAccessConfig, &credentials); err != nil {
+ return nil, fmt.Errorf("failed to populate provider access config: %w", err)
+ }
+
+ provider, err := bookmyname.NewChallengeProvider(&bookmyname.ChallengeProviderConfig{
+ Username: credentials.Username,
+ Password: credentials.Password,
+ DnsPropagationTimeout: options.DnsPropagationTimeout,
+ DnsTTL: options.DnsTTL,
+ })
+ return provider, err
+ }); err != nil {
+ panic(err)
+ }
+}
diff --git a/internal/domain/access.go b/internal/domain/access.go
index 9b3f10bcb..dde8954cf 100644
--- a/internal/domain/access.go
+++ b/internal/domain/access.go
@@ -93,15 +93,20 @@ type AccessConfigForBaotaWAF struct {
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
}
-type AccessConfigForBytePlus struct {
- AccessKey string `json:"accessKey"`
- SecretKey string `json:"secretKey"`
+type AccessConfigForBookMyName struct {
+ Username string `json:"username"`
+ Password string `json:"password"`
}
type AccessConfigForBunny struct {
ApiKey string `json:"apiKey"`
}
+type AccessConfigForBytePlus struct {
+ AccessKey string `json:"accessKey"`
+ SecretKey string `json:"secretKey"`
+}
+
type AccessConfigForCacheFly struct {
ApiToken string `json:"apiToken"`
}
diff --git a/internal/domain/provider.go b/internal/domain/provider.go
index c51b9430c..bb970cd26 100644
--- a/internal/domain/provider.go
+++ b/internal/domain/provider.go
@@ -23,7 +23,7 @@ const (
AccessProviderTypeBaishan = AccessProviderType("baishan")
AccessProviderTypeBaotaPanel = AccessProviderType("baotapanel")
AccessProviderTypeBaotaWAF = AccessProviderType("baotawaf")
- AccessProviderTypeBookMyName = AccessProviderType("bookmyname") // BookMyName(预留)
+ AccessProviderTypeBookMyName = AccessProviderType("bookmyname")
AccessProviderTypeBunny = AccessProviderType("bunny")
AccessProviderTypeBytePlus = AccessProviderType("byteplus")
AccessProviderTypeCacheFly = AccessProviderType("cachefly")
@@ -144,6 +144,7 @@ const (
ACMEDns01ProviderTypeAzureDNS = ACMEDns01ProviderType(AccessProviderTypeAzure + "-dns")
ACMEDns01ProviderTypeBaiduCloud = ACMEDns01ProviderType(AccessProviderTypeBaiduCloud) // 兼容旧值,等同于 [ACMEDns01ProviderTypeBaiduCloudDNS]
ACMEDns01ProviderTypeBaiduCloudDNS = ACMEDns01ProviderType(AccessProviderTypeBaiduCloud + "-dns")
+ ACMEDns01ProviderTypeBookMyName = ACMEDns01ProviderType(AccessProviderTypeBookMyName)
ACMEDns01ProviderTypeBunny = ACMEDns01ProviderType(AccessProviderTypeBunny)
ACMEDns01ProviderTypeCloudflare = ACMEDns01ProviderType(AccessProviderTypeCloudflare)
ACMEDns01ProviderTypeClouDNS = ACMEDns01ProviderType(AccessProviderTypeClouDNS)
diff --git a/pkg/core/ssl-applicator/acme-dns01/providers/bookmyname/bookmyname.go b/pkg/core/ssl-applicator/acme-dns01/providers/bookmyname/bookmyname.go
new file mode 100644
index 000000000..748ada8df
--- /dev/null
+++ b/pkg/core/ssl-applicator/acme-dns01/providers/bookmyname/bookmyname.go
@@ -0,0 +1,40 @@
+package bookmyname
+
+import (
+ "errors"
+ "time"
+
+ "github.com/go-acme/lego/v4/providers/dns/bookmyname"
+
+ "github.com/certimate-go/certimate/pkg/core"
+)
+
+type ChallengeProviderConfig struct {
+ Username string `json:"username"`
+ Password string `json:"password"`
+ DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
+ DnsTTL int32 `json:"dnsTTL,omitempty"`
+}
+
+func NewChallengeProvider(config *ChallengeProviderConfig) (core.ACMEChallenger, error) {
+ if config == nil {
+ return nil, errors.New("the configuration of the acme challenge provider is nil")
+ }
+
+ providerConfig := bookmyname.NewDefaultConfig()
+ providerConfig.Username = config.Username
+ providerConfig.Password = config.Password
+ if config.DnsPropagationTimeout != 0 {
+ providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second
+ }
+ if config.DnsTTL != 0 {
+ providerConfig.TTL = int(config.DnsTTL)
+ }
+
+ provider, err := bookmyname.NewDNSProviderConfig(providerConfig)
+ if err != nil {
+ return nil, err
+ }
+
+ return provider, nil
+}
diff --git a/pkg/core/ssl-applicator/acme-dns01/providers/hetzner/hetzner.go b/pkg/core/ssl-applicator/acme-dns01/providers/hetzner/hetzner.go
index 8c270e6a2..e8c0ada43 100644
--- a/pkg/core/ssl-applicator/acme-dns01/providers/hetzner/hetzner.go
+++ b/pkg/core/ssl-applicator/acme-dns01/providers/hetzner/hetzner.go
@@ -1,4 +1,4 @@
-package namedotcom
+package hetzner
import (
"errors"
@@ -21,7 +21,7 @@ func NewChallengeProvider(config *ChallengeProviderConfig) (core.ACMEChallenger,
}
providerConfig := hetzner.NewDefaultConfig()
- providerConfig.APIKey = config.ApiToken
+ providerConfig.APIToken = config.ApiToken
if config.DnsPropagationTimeout != 0 {
providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second
}
diff --git a/ui/public/imgs/providers/bookmyname.png b/ui/public/imgs/providers/bookmyname.png
new file mode 100644
index 000000000..5f47787c6
Binary files /dev/null and b/ui/public/imgs/providers/bookmyname.png differ
diff --git a/ui/src/components/access/AccessForm.tsx b/ui/src/components/access/AccessForm.tsx
index 2430221b0..e0eab008b 100644
--- a/ui/src/components/access/AccessForm.tsx
+++ b/ui/src/components/access/AccessForm.tsx
@@ -24,6 +24,7 @@ import AccessConfigFieldsProviderBaiduCloud from "./forms/AccessConfigFieldsProv
import AccessConfigFieldsProviderBaishan from "./forms/AccessConfigFieldsProviderBaishan";
import AccessConfigFieldsProviderBaotaPanel from "./forms/AccessConfigFieldsProviderBaotaPanel";
import AccessConfigFieldsProviderBaotaWAF from "./forms/AccessConfigFieldsProviderBaotaWAF";
+import AccessConfigFieldsProviderBookMyName from "./forms/AccessConfigFieldsProviderBookMyName";
import AccessConfigFieldsProviderBunny from "./forms/AccessConfigFieldsProviderBunny";
import AccessConfigFieldsProviderBytePlus from "./forms/AccessConfigFieldsProviderBytePlus";
import AccessConfigFieldsProviderCacheFly from "./forms/AccessConfigFieldsProviderCacheFly";
@@ -174,6 +175,9 @@ const AccessForm = ({ className, style, disabled, initialValues, mode, usage, on
case ACCESS_PROVIDERS.BAOTAWAF: {
return