feat(provider): new deployment provider: yandexcloud certificatemanager

This commit is contained in:
Fu Diwei
2026-07-29 17:07:58 +08:00
committed by RHQYZ
parent cb7e388bd3
commit 277099507f
16 changed files with 491 additions and 8 deletions
+3 -2
View File
@@ -82,6 +82,9 @@ require (
github.com/volcengine/volcengine-go-sdk v1.2.42
github.com/wneessen/go-mail v0.8.1
github.com/xhit/go-str2duration/v2 v2.1.0
github.com/yandex-cloud/go-genproto v0.99.0
github.com/yandex-cloud/go-sdk/services/certificatemanager v0.0.81
github.com/yandex-cloud/go-sdk/v2 v2.142.0
github.com/yunify/qingcloud-sdk-go v2.0.0-alpha.38+incompatible
github.com/zenlayer/zenlayercloud-sdk-go v0.2.46
gitlab.ecloud.com/ecloud/ecloudsdkcloudcore v1.0.0
@@ -257,9 +260,7 @@ require (
github.com/spf13/cast v1.10.0 // indirect
github.com/tinylib/msgp v1.6.4 // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/yandex-cloud/go-genproto v0.84.0 // indirect
github.com/yandex-cloud/go-sdk/services/dns v0.0.65 // indirect
github.com/yandex-cloud/go-sdk/v2 v2.114.0 // indirect
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
github.com/zeebo/xxh3 v1.1.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
+6 -4
View File
@@ -953,12 +953,14 @@ github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
github.com/yandex-cloud/go-genproto v0.84.0 h1:lzptMyo1wleGBGNkkEb8bzpgbnW3xPlha0f94g4prBE=
github.com/yandex-cloud/go-genproto v0.84.0/go.mod h1:0LDD/IZLIUIV4iPH+YcF+jysO3jkSvADFGm4dCAuwQo=
github.com/yandex-cloud/go-genproto v0.99.0 h1:mRJPHWj186U0Ww1sE8E0U727MvWM2gv1MqUjBbiVgjE=
github.com/yandex-cloud/go-genproto v0.99.0/go.mod h1:0LDD/IZLIUIV4iPH+YcF+jysO3jkSvADFGm4dCAuwQo=
github.com/yandex-cloud/go-sdk/services/certificatemanager v0.0.81 h1:tMdRkO7LakoH2PsUixoGuCt5cdQDUdFo+7sxaItNUjA=
github.com/yandex-cloud/go-sdk/services/certificatemanager v0.0.81/go.mod h1:VKW98WxZFwD04FSgniL5uObKaguR9zBhvwv770Ot2SM=
github.com/yandex-cloud/go-sdk/services/dns v0.0.65 h1:7jhZMHsK1GThGzAKC7Mjq8wu/Xbr/TbhRUoNFzot4K4=
github.com/yandex-cloud/go-sdk/services/dns v0.0.65/go.mod h1:Qm5HbUbmFI2Y8eDv8tcwr7OHgNumHuN/RtK3icd3bYU=
github.com/yandex-cloud/go-sdk/v2 v2.114.0 h1:gx03giWYrzMhgpFK4NJNuOnASSgdCuv4nkLUFejnCSs=
github.com/yandex-cloud/go-sdk/v2 v2.114.0/go.mod h1:XrF79/a3olVf0YUUCMYePI8Ik0m4KDcQlTooHGGZJB0=
github.com/yandex-cloud/go-sdk/v2 v2.142.0 h1:4l02xAC/B0GNWLs+SAWiLNX2iah/DHb7t1k62mYl8tU=
github.com/yandex-cloud/go-sdk/v2 v2.142.0/go.mod h1:cvtog6S0f82ju6ZqzQ6eMYz96P4cflml6R+W4/wDFEE=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
@@ -0,0 +1,26 @@
package deployers
import (
"fmt"
"github.com/certimate-go/certimate/internal/domain"
"github.com/certimate-go/certimate/pkg/core"
dplyimpl "github.com/certimate-go/certimate/pkg/core/deployer/providers/yandexcloud-certificatemanager"
xmaps "github.com/certimate-go/certimate/pkg/utils/maps"
)
func init() {
Registries.MustRegister(domain.DeploymentProviderTypeYandexCloudCertificateManager, func(options *ProviderFactoryOptions) (core.Deployer, error) {
credentials := domain.AccessConfigForYandexCloud{}
if err := xmaps.Populate(options.ProviderAccessConfig, &credentials); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
provider, err := dplyimpl.NewDeployer(&dplyimpl.DeployerConfig{
FolderId: credentials.FolderId,
ServiceAccountKey: credentials.ServiceAccountKey,
CertificateId: xmaps.GetString(options.ProviderExtendedConfig, "certificateId"),
})
return provider, err
})
}
+1
View File
@@ -467,6 +467,7 @@ const (
DeploymentProviderTypeWangsuCDNPro = DeploymentProviderType(AccessProviderTypeWangsu + "-cdnpro")
DeploymentProviderTypeWangsuCertificate = DeploymentProviderType(AccessProviderTypeWangsu + "-certificate")
DeploymentProviderTypeWebhook = DeploymentProviderType(AccessProviderTypeWebhook)
DeploymentProviderTypeYandexCloudCertificateManager = DeploymentProviderType(AccessProviderTypeYandexCloud + "-certificatemanager")
DeploymentProviderTypeZenlayerCDN = DeploymentProviderType(AccessProviderTypeZenlayer + "-cdn")
DeploymentProviderTypeZenlayerGA = DeploymentProviderType(AccessProviderTypeZenlayer + "-ga")
)
@@ -1,6 +1,7 @@
package googlecloudcertificatemanager_test
import (
"os"
"testing"
impl "github.com/certimate-go/certimate/pkg/core/certmgr/providers/googlecloud-certificatemanager"
@@ -11,12 +12,14 @@ var (
fp = tester.Args("GOOGLECLOUDCERTIFICATEMANAGER_")
fTestCertPath string
fTestKeyPath string
fProjectId string
fServiceAccountKey string
)
func init() {
fp.DefineString(&fTestCertPath, "TESTCERTPATH")
fp.DefineString(&fTestKeyPath, "TESTKEYPATH")
fp.DefineString(&fProjectId, "PROJECTID")
fp.DefineString(&fServiceAccountKey, "SERVICEACCOUNTKEY")
}
@@ -26,13 +29,20 @@ Shell command to run this test:
go test -v ./googlecloud_certificatemanager_test.go -args \
--GOOGLECLOUDCERTIFICATEMANAGER_TESTCERTPATH="/path/to/your-test-cert.pem" \
--GOOGLECLOUDCERTIFICATEMANAGER_TESTKEYPATH="/path/to/your-test-key.pem" \
--GOOGLECLOUDCERTIFICATEMANAGER_PROJECTID="your-project-id" \
--GOOGLECLOUDCERTIFICATEMANAGER_SERVICEACCOUNTKEY="{...}"
*/
func TestProvider(t *testing.T) {
fp.Parse()
if fServiceAccountKeyStat, err := os.Stat(fServiceAccountKey); err == nil && !fServiceAccountKeyStat.IsDir() {
fServiceAccountKeyBytes, _ := os.ReadFile(fServiceAccountKey)
fServiceAccountKey = string(fServiceAccountKeyBytes)
}
t.Run("Upload", func(t *testing.T) {
provider, err := impl.NewCertmgr(&impl.CertmgrConfig{
ProjectId: fProjectId,
ServiceAccountKey: fServiceAccountKey,
})
if err != nil {
@@ -0,0 +1,227 @@
package yandexcloudcertificatemanager
import (
"context"
"encoding/json"
"fmt"
"log/slog"
"strings"
"time"
yccertificatemanagerproto "github.com/yandex-cloud/go-genproto/yandex/cloud/certificatemanager/v1"
yccertificatemanager "github.com/yandex-cloud/go-sdk/services/certificatemanager/v1"
ycsdk "github.com/yandex-cloud/go-sdk/v2"
yccreds "github.com/yandex-cloud/go-sdk/v2/credentials"
yciamkey "github.com/yandex-cloud/go-sdk/v2/pkg/iamkey"
ycoptions "github.com/yandex-cloud/go-sdk/v2/pkg/options"
"github.com/certimate-go/certimate/pkg/core"
xcert "github.com/certimate-go/certimate/pkg/utils/cert"
)
type (
Provider = core.Certmgr
UploadResult = core.CertmgrUploadResult
ReplaceResult = core.CertmgrReplaceResult
)
type CertmgrConfig struct {
// Yandex Cloud 文件夹 ID。
FolderId string `json:"folderId"`
// Yandex Cloud 服务账号授权密钥。
ServiceAccountKey string `json:"serviceAccountKey"`
}
type Certmgr struct {
config *CertmgrConfig
logger *slog.Logger
sdkClient yccertificatemanager.CertificateClient
}
var _ Provider = (*Certmgr)(nil)
func NewCertmgr(config *CertmgrConfig) (*Certmgr, error) {
if config == nil {
return nil, fmt.Errorf("the configuration of the certmgr provider is nil")
}
client, err := createSDKClient(config.ServiceAccountKey)
if err != nil {
return nil, fmt.Errorf("could not create client: %w", err)
}
return &Certmgr{
config: config,
logger: slog.Default(),
sdkClient: client,
}, nil
}
func (c *Certmgr) SetLogger(logger *slog.Logger) {
if logger == nil {
c.logger = slog.New(slog.DiscardHandler)
} else {
c.logger = logger
}
}
func (c *Certmgr) Upload(ctx context.Context, certPEM, privkeyPEM string) (*UploadResult, error) {
// 解析证书内容
certX509, err := xcert.ParseCertificateFromPEM(certPEM)
if err != nil {
return nil, err
}
// 提取服务器证书和中间证书
serverCertPEM, issuerCertPEM, err := xcert.ExtractCertificatesFromPEM(certPEM)
if err != nil {
return nil, fmt.Errorf("failed to extract certs: %w", err)
}
// 获取证书列表,避免重复上传
// REF: https://yandex.cloud/en/docs/certificate-manager/api-ref/Certificate/list
listCertificatesPageToken := ""
listCertificatesPageSize := 100
for {
select {
case <-ctx.Done():
return nil, ctx.Err()
default:
}
listCertificatesReq := &yccertificatemanagerproto.ListCertificatesRequest{
FolderId: c.config.FolderId,
PageSize: int64(listCertificatesPageSize),
PageToken: listCertificatesPageToken,
}
listCertificatesResp, err := c.sdkClient.List(ctx, listCertificatesReq)
c.logger.Debug("sdk request 'certificatemanager.certificate.list'", slog.Any("request", listCertificatesReq), slog.Any("response", listCertificatesResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'certificatemanager.certificate.list': %w", err)
}
for _, certItem := range listCertificatesResp.Certificates {
// 对比证书备用名称
if !strings.EqualFold(strings.Join(certX509.DNSNames, ","), strings.Join(certItem.Domains, ",")) {
continue
}
// 对比证书主题 DN
if certX509.Subject.String() != certItem.Subject {
continue
}
// 对比证书颁发者 DN
if certX509.Issuer.String() != certItem.Issuer {
continue
}
// 对比证书序列号
if !strings.EqualFold(certX509.SerialNumber.Text(16), certItem.Serial) {
continue
}
// 对比证书有效期
if certItem.NotBefore != nil && certX509.NotBefore.Unix() != certItem.NotBefore.AsTime().Unix() {
continue
} else if certItem.NotAfter != nil && certX509.NotAfter.Unix() != certItem.NotAfter.AsTime().Unix() {
continue
}
// 如果以上信息都一致,则视为已存在相同证书,直接返回
c.logger.Info("ssl certificate already exists")
return &UploadResult{
CertId: certItem.Id,
CertName: certItem.Name,
}, nil
}
if len(listCertificatesResp.Certificates) == 0 || listCertificatesResp.NextPageToken == "" {
break
}
listCertificatesPageToken = listCertificatesResp.NextPageToken
}
// 创建证书
// REF: https://yandex.cloud/en/docs/certificate-manager/api-ref/Certificate/create
createCertificateReq := &yccertificatemanagerproto.CreateCertificateRequest{
FolderId: c.config.FolderId,
Name: fmt.Sprintf("certimate-%d", time.Now().UnixMilli()),
Description: "upload from Certimate",
Certificate: serverCertPEM,
Chain: issuerCertPEM,
PrivateKey: privkeyPEM,
}
createCertificateResp, err := c.sdkClient.Create(ctx, createCertificateReq)
c.logger.Debug("sdk request 'certificatemanager.certificate.create'", slog.Any("request", createCertificateReq), slog.Any("response", createCertificateResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'certificatemanager.certificate.create': %w", err)
}
return &UploadResult{
CertId: createCertificateResp.Response().Id,
CertName: createCertificateResp.Response().Name,
}, nil
}
func (c *Certmgr) Replace(ctx context.Context, certIdOrName string, certPEM, privkeyPEM string) (*ReplaceResult, error) {
// 提取服务器证书和中间证书
serverCertPEM, issuerCertPEM, err := xcert.ExtractCertificatesFromPEM(certPEM)
if err != nil {
return nil, fmt.Errorf("failed to extract certs: %w", err)
}
// 获取证书
// REF: https://yandex.cloud/en/docs/certificate-manager/api-ref/Certificate/get
getCertificateReq := &yccertificatemanagerproto.GetCertificateRequest{
CertificateId: certIdOrName,
View: yccertificatemanagerproto.CertificateView_BASIC,
}
getCertificateResp, err := c.sdkClient.Get(ctx, getCertificateReq)
c.logger.Debug("sdk request 'certificatemanager.certificate.get'", slog.Any("request", getCertificateReq), slog.Any("response", getCertificateResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'certificatemanager.certificate.get': %w", err)
}
// 更新证书
// REF: https://yandex.cloud/en/docs/certificate-manager/api-ref/Certificate/update
updateCertificateReq := &yccertificatemanagerproto.UpdateCertificateRequest{
CertificateId: certIdOrName,
Name: getCertificateResp.Name,
Description: getCertificateResp.Description,
Labels: getCertificateResp.Labels,
Certificate: serverCertPEM,
Chain: issuerCertPEM,
PrivateKey: privkeyPEM,
DeletionProtection: getCertificateResp.DeletionProtection,
}
updateCertificateResp, err := c.sdkClient.Update(ctx, updateCertificateReq)
c.logger.Debug("sdk request 'certificatemanager.certificate.update'", slog.Any("request", updateCertificateReq), slog.Any("response", updateCertificateResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'certificatemanager.certificate.update': %w", err)
}
return &ReplaceResult{}, nil
}
func createSDKClient(serviceAccountKey string) (yccertificatemanager.CertificateClient, error) {
saKey := []byte(serviceAccountKey)
saConf := &yciamkey.Key{}
if err := json.Unmarshal(saKey, saConf); err != nil {
return nil, fmt.Errorf("unable to acquire service account config: %w", err)
}
creds, err := yccreds.ServiceAccountKey(saConf)
if err != nil {
return nil, err
}
sdk, err := ycsdk.Build(context.Background(), ycoptions.WithCredentials(creds))
if err != nil {
return nil, err
}
client := yccertificatemanager.NewCertificateClient(sdk)
return client, nil
}
@@ -0,0 +1,55 @@
package yandexcloudcertificatemanager_test
import (
"os"
"testing"
impl "github.com/certimate-go/certimate/pkg/core/certmgr/providers/yandexcloud-certificatemanager"
tester "github.com/certimate-go/certimate/pkg/core/certmgr/testing"
)
var (
fp = tester.Args("YANDEXCLOUDCERTIFICATEMANAGER_")
fTestCertPath string
fTestKeyPath string
fFolderId string
fServiceAccountKey string
)
func init() {
fp.DefineString(&fTestCertPath, "TESTCERTPATH")
fp.DefineString(&fTestKeyPath, "TESTKEYPATH")
fp.DefineString(&fFolderId, "FOLDERID")
fp.DefineString(&fServiceAccountKey, "SERVICEACCOUNTKEY")
}
/*
Shell command to run this test:
go test -v ./yandexcloud_certificatemanager_test.go -args \
--YANDEXCLOUDCERTIFICATEMANAGER_TESTCERTPATH="/path/to/your-test-cert.pem" \
--YANDEXCLOUDCERTIFICATEMANAGER_TESTKEYPATH="/path/to/your-test-key.pem" \
--YANDEXCLOUDCERTIFICATEMANAGER_FOLDERID="your-folder-id" \
--YANDEXCLOUDCERTIFICATEMANAGER_SERVICEACCOUNTKEY="{...}"
*/
func TestProvider(t *testing.T) {
fp.Parse()
if fServiceAccountKeyStat, err := os.Stat(fServiceAccountKey); err == nil && !fServiceAccountKeyStat.IsDir() {
fServiceAccountKeyBytes, _ := os.ReadFile(fServiceAccountKey)
fServiceAccountKey = string(fServiceAccountKeyBytes)
}
t.Run("Upload", func(t *testing.T) {
provider, err := impl.NewCertmgr(&impl.CertmgrConfig{
FolderId: fFolderId,
ServiceAccountKey: fServiceAccountKey,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
tester.TestUpload(t, provider, tester.TestUploadArgs{CertPath: fTestCertPath, KeyPath: fTestKeyPath})
})
}
@@ -1,6 +1,7 @@
package k8ssecret_test
import (
"os"
"testing"
impl "github.com/certimate-go/certimate/pkg/core/deployer/providers/k8s-secret"
@@ -11,6 +12,7 @@ var (
fp = tester.Args("K8SSECRET_")
fTestCertPath string
fTestKeyPath string
fKubeConfig string
fNamespace string
fSecretName string
fSecretDataKeyForCrt string
@@ -20,6 +22,7 @@ var (
func init() {
fp.DefineString(&fTestCertPath, "TESTCERTPATH")
fp.DefineString(&fTestKeyPath, "TESTKEYPATH")
fp.DefineString(&fKubeConfig, "KUBECONFIG")
fp.DefineString(&fNamespace, "NAMESPACE", "default")
fp.DefineString(&fSecretName, "SECRETNAME")
fp.DefineString(&fSecretDataKeyForCrt, "SECRETDATAKEYFORCRT", "tls.crt")
@@ -32,6 +35,7 @@ Shell command to run this test:
go test -v ./k8s_secret_test.go -args \
--K8SSECRET_TESTCERTPATH="/path/to/your-test-cert.pem" \
--K8SSECRET_TESTKEYPATH="/path/to/your-test-key.pem" \
--K8SSECRET_KUBECONFIG="..." \
--K8SSECRET_NAMESPACE="default" \
--K8SSECRET_SECRETNAME="secret" \
--K8SSECRET_SECRETDATAKEYFORCRT="tls.crt" \
@@ -40,8 +44,14 @@ Shell command to run this test:
func TestProvider(t *testing.T) {
fp.Parse()
if fKubeConfigStat, err := os.Stat(fKubeConfig); err == nil && !fKubeConfigStat.IsDir() {
fKubeConfigBytes, _ := os.ReadFile(fKubeConfig)
fKubeConfig = string(fKubeConfigBytes)
}
t.Run("Deploy", func(t *testing.T) {
provider, err := impl.NewDeployer(&impl.DeployerConfig{
KubeConfig: fKubeConfig,
Namespace: fNamespace,
SecretName: fSecretName,
SecretDataKeyForCrt: fSecretDataKeyForCrt,
@@ -0,0 +1,85 @@
package yandexcloudcertificatemanager
import (
"context"
"fmt"
"log/slog"
"github.com/certimate-go/certimate/pkg/core"
cmgrimpl "github.com/certimate-go/certimate/pkg/core/certmgr/providers/yandexcloud-certificatemanager"
)
type (
Provider = core.Deployer
DeployResult = core.DeployerDeployResult
)
type DeployerConfig struct {
// Yandex Cloud 文件夹 ID。
FolderId string `json:"folderId"`
// Yandex Cloud 服务账号授权密钥。
ServiceAccountKey string `json:"serviceAccountKey"`
// 证书管理器证书 ID。
// 选填。零值时表示新建证书;否则表示更新证书。
CertificateId string `json:"certificateId,omitempty"`
}
type Deployer struct {
config *DeployerConfig
logger *slog.Logger
sdkCertmgr core.Certmgr
}
var _ Provider = (*Deployer)(nil)
func NewDeployer(config *DeployerConfig) (*Deployer, error) {
if config == nil {
return nil, fmt.Errorf("the configuration of the deployer provider is nil")
}
pcertmgr, err := cmgrimpl.NewCertmgr(&cmgrimpl.CertmgrConfig{
FolderId: config.FolderId,
ServiceAccountKey: config.ServiceAccountKey,
})
if err != nil {
return nil, fmt.Errorf("could not create certmgr: %w", err)
}
return &Deployer{
config: config,
logger: slog.Default(),
sdkCertmgr: pcertmgr,
}, nil
}
func (d *Deployer) SetLogger(logger *slog.Logger) {
if logger == nil {
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
d.sdkCertmgr.SetLogger(logger)
}
func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*DeployResult, error) {
if d.config.CertificateId == "" {
// 上传证书
upres, err := d.sdkCertmgr.Upload(ctx, certPEM, privkeyPEM)
if err != nil {
return nil, fmt.Errorf("failed to upload certificate file: %w", err)
} else {
d.logger.Info("ssl certificate uploaded", slog.Any("result", upres))
}
} else {
// 替换证书
rplres, err := d.sdkCertmgr.Replace(ctx, d.config.CertificateId, certPEM, privkeyPEM)
if err != nil {
return nil, fmt.Errorf("failed to replace certificate file: %w", err)
} else {
d.logger.Info("ssl certificate replaced", slog.Any("result", rplres))
}
}
return &DeployResult{}, nil
}
@@ -144,6 +144,7 @@ import BizDeployNodeConfigFieldsProviderWangsuCDN from "./BizDeployNodeConfigFie
import BizDeployNodeConfigFieldsProviderWangsuCDNPro from "./BizDeployNodeConfigFieldsProviderWangsuCDNPro";
import BizDeployNodeConfigFieldsProviderWangsuCertificate from "./BizDeployNodeConfigFieldsProviderWangsuCertificate";
import BizDeployNodeConfigFieldsProviderWebhook from "./BizDeployNodeConfigFieldsProviderWebhook";
import BizDeployNodeConfigFieldsProviderYandexCloudCertificateManager from "./BizDeployNodeConfigFieldsProviderYandexCloudCertificateManager";
import BizDeployNodeConfigFieldsProviderZenlayerCDN from "./BizDeployNodeConfigFieldsProviderZenlayerCDN";
import BizDeployNodeConfigFieldsProviderZenlayerGA from "./BizDeployNodeConfigFieldsProviderZenlayerGA";
@@ -294,6 +295,7 @@ const providerComponentMap: Partial<Record<DeploymentProviderType, React.Compone
[DEPLOYMENT_PROVIDERS.WANGSU_CDNPRO]: BizDeployNodeConfigFieldsProviderWangsuCDNPro,
[DEPLOYMENT_PROVIDERS.WANGSU_CERTIFICATE]: BizDeployNodeConfigFieldsProviderWangsuCertificate,
[DEPLOYMENT_PROVIDERS.WEBHOOK]: BizDeployNodeConfigFieldsProviderWebhook,
[DEPLOYMENT_PROVIDERS.YANDEXCLOUD_CERTIFICATEMANAGER]: BizDeployNodeConfigFieldsProviderYandexCloudCertificateManager,
[DEPLOYMENT_PROVIDERS.ZENLAYER_CDN]: BizDeployNodeConfigFieldsProviderZenlayerCDN,
[DEPLOYMENT_PROVIDERS.ZENLAYER_GA]: BizDeployNodeConfigFieldsProviderZenlayerGA,
};
@@ -0,0 +1,50 @@
import { getI18n, useTranslation } from "react-i18next";
import { Form, Input } from "antd";
import { createSchemaFieldRule } from "antd-zod";
import { z } from "zod";
import { useFormNestedFieldsContext } from "./_context";
const BizDeployNodeConfigFieldsProviderYandexCloudCertificateManager = () => {
const { i18n, t } = useTranslation();
const { parentNamePath } = useFormNestedFieldsContext();
const formSchema = z.object({
[parentNamePath]: getSchema({ i18n }),
});
const formRule = createSchemaFieldRule(formSchema);
const initialValues = getInitialValues();
return (
<>
<Form.Item
name={[parentNamePath, "certificateId"]}
initialValue={initialValues.certificateId}
label={t("workflow_node.deploy.form.yandexcloud_certificatemanager_certificate_id.label")}
extra={t("workflow_node.deploy.form.yandexcloud_certificatemanager_certificate_id.help")}
rules={[formRule]}
>
<Input allowClear placeholder={t("workflow_node.deploy.form.yandexcloud_certificatemanager_certificate_id.placeholder")} />
</Form.Item>
</>
);
};
const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
return {};
};
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
const { t: _ } = i18n;
return z.object({
certificateId: z.string().nullish(),
});
};
const _default = Object.assign(BizDeployNodeConfigFieldsProviderYandexCloudCertificateManager, {
getInitialValues,
getSchema,
});
export default _default;
+3 -1
View File
@@ -184,6 +184,7 @@ export const accessProvidersMap: Map<AccessProvider["type"] | string, AccessProv
[ACCESS_PROVIDERS.DIGITALOCEAN, "provider.digitalocean", "/imgs/providers/digitalocean.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.GCORE, "provider.gcore", "/imgs/providers/gcore.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.LINODE, "provider.linode", "/imgs/providers/linode.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.YANDEXCLOUD, "provider.yandexcloud", "/imgs/providers/yandexcloud.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.BAIDUCLOUD, "provider.baiducloud", "/imgs/providers/baiducloud.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.CMCCCLOUD, "provider.cmcccloud", "/imgs/providers/cmcccloud.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.CTCCCLOUD, "provider.ctcccloud", "/imgs/providers/ctcccloud.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
@@ -258,7 +259,6 @@ export const accessProvidersMap: Map<AccessProvider["type"] | string, AccessProv
[ACCESS_PROVIDERS.SIMPLYCOM, "provider.simplycom", "/imgs/providers/simplycom.png", [ACCESS_USAGES.DNS]],
[ACCESS_PROVIDERS.SPACESHIP, "provider.spaceship", "/imgs/providers/spaceship.png", [ACCESS_USAGES.DNS]],
[ACCESS_PROVIDERS.VULTR, "provider.vultr", "/imgs/providers/vultr.svg", [ACCESS_USAGES.DNS]],
[ACCESS_PROVIDERS.YANDEXCLOUD, "provider.yandexcloud", "/imgs/providers/yandexcloud.svg", [ACCESS_USAGES.DNS]],
[ACCESS_PROVIDERS["35CN"], "provider.35cn", "/imgs/providers/35cn.png", [ACCESS_USAGES.DNS]],
[ACCESS_PROVIDERS["51DNSCOM"], "provider.51dnscom", "/imgs/providers/51dnscom.png", [ACCESS_USAGES.DNS]],
[ACCESS_PROVIDERS.DNSLA, "provider.dnsla", "/imgs/providers/dnsla.svg", [ACCESS_USAGES.DNS]],
@@ -756,6 +756,7 @@ export const DEPLOYMENT_PROVIDERS = Object.freeze({
WANGSU_CDNPRO: `${ACCESS_PROVIDERS.WANGSU}-cdnpro`,
WANGSU_CERTIFICATE: `${ACCESS_PROVIDERS.WANGSU}-certificate`,
WEBHOOK: `${ACCESS_PROVIDERS.WEBHOOK}`,
YANDEXCLOUD_CERTIFICATEMANAGER: `${ACCESS_PROVIDERS.YANDEXCLOUD}-certificatemanager`,
ZENLAYER_CDN: `${ACCESS_PROVIDERS.ZENLAYER}-cdn`,
ZENLAYER_GA: `${ACCESS_PROVIDERS.ZENLAYER}-ga`,
} as const);
@@ -876,6 +877,7 @@ export const deploymentProvidersMap: Map<DeploymentProvider["type"] | string, De
[DEPLOYMENT_PROVIDERS.FLYIO, "provider.flyio", DEPLOYMENT_CATEGORIES.WEBSITE],
[DEPLOYMENT_PROVIDERS.NETLIFY, "provider.netlify", DEPLOYMENT_CATEGORIES.WEBSITE],
[DEPLOYMENT_PROVIDERS.VERCEL, "provider.vercel", DEPLOYMENT_CATEGORIES.WEBSITE],
[DEPLOYMENT_PROVIDERS.YANDEXCLOUD_CERTIFICATEMANAGER, "provider.yandexcloud_certificatemanager", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.ZENLAYER_CDN, "provider.zenlayer_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.ZENLAYER_GA, "provider.zenlayer_ga", DEPLOYMENT_CATEGORIES.ACCELERATOR],
[DEPLOYMENT_PROVIDERS.BAIDUCLOUD_CDN, "provider.baiducloud_cdn", DEPLOYMENT_CATEGORIES.CDN],
@@ -299,6 +299,7 @@
"westcn": "West.cn",
"xinnet": "Xinnet.com",
"yandexcloud": "Yandex Cloud",
"yandexcloud_certificatemanager": "Yandex Cloud - Certificate Manager",
"yandexcloud_dns": "Yandex Cloud - DNS",
"zerossl": "ZeroSSL",
"zenlayer": "Zenlayer",
@@ -963,7 +963,7 @@
"aws_acm_certificate_arn": {
"label": "AWS ACM certificate ARN (Optional)",
"placeholder": "Please enter AWS ACM certificate ARN",
"help": "Notes: Leave it blank to import a new certificate."
"help": "Notes: Leave it blank to import a new certificate; otherwise, to replace the existing one."
},
"aws_alb_region": {
"label": "AWS Region",
@@ -2904,6 +2904,11 @@
"placeholder": "Please enter Webhook timeout",
"unit": "seconds"
},
"yandexcloud_certificatemanager_certificate_id": {
"label": "Yandex Cloud Certificate Manager certificate ID (Optional)",
"placeholder": "Please enter Yandex Cloud Certificate Manager certificate ID",
"help": "Notes: Leave it blank to import a new certificate; otherwise, to replace the existing one."
},
"zenlayer_cdn_deploy_target": {
"option": {
"domain": {
@@ -299,6 +299,7 @@
"westcn": "西部数码",
"xinnet": "新网数码",
"yandexcloud": "Yandex Cloud",
"yandexcloud_certificatemanager": "Yandex Cloud - 证书管理器",
"yandexcloud_dns": "Yandex Cloud - DNS",
"zerossl": "ZeroSSL",
"zenlayer": "Zenlayer",
@@ -2903,6 +2903,11 @@
"placeholder": "请输入 Webhook 超时时间",
"unit": "秒"
},
"yandexcloud_certificatemanager_certificate_id": {
"label": "Yandex Cloud 证书管理器证书 ID(可选)",
"placeholder": "请输入 Yandex Cloud 证书管理器证书 ID",
"help": "提示:不填写时,将上传新证书;否则,将替换原证书。"
},
"zenlayer_cdn_deploy_target": {
"option": {
"domain": {