mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-07 21:19:51 +00:00
commit
7643975ef9
@ -962,8 +962,8 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
|
|||||||
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
|
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
jumpServers := make([]pSSH.JumpServerConfig, len(access.JumpServerConfig))
|
jumpServers := make([]pSSH.JumpServerConfig, len(access.JumpServers))
|
||||||
for i, jumpServer := range access.JumpServerConfig {
|
for i, jumpServer := range access.JumpServers {
|
||||||
jumpServers[i] = pSSH.JumpServerConfig{
|
jumpServers[i] = pSSH.JumpServerConfig{
|
||||||
SshHost: jumpServer.Host,
|
SshHost: jumpServer.Host,
|
||||||
SshPort: jumpServer.Port,
|
SshPort: jumpServer.Port,
|
||||||
@ -981,19 +981,19 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
|
|||||||
SshPassword: access.Password,
|
SshPassword: access.Password,
|
||||||
SshKey: access.Key,
|
SshKey: access.Key,
|
||||||
SshKeyPassphrase: access.KeyPassphrase,
|
SshKeyPassphrase: access.KeyPassphrase,
|
||||||
JumpServerConfig: jumpServers,
|
JumpServers: jumpServers,
|
||||||
UseSCP: maputil.GetBool(options.ProviderExtendedConfig, "useSCP"),
|
UseSCP: maputil.GetBool(options.ProviderServiceConfig, "useSCP"),
|
||||||
PreCommand: maputil.GetString(options.ProviderExtendedConfig, "preCommand"),
|
PreCommand: maputil.GetString(options.ProviderServiceConfig, "preCommand"),
|
||||||
PostCommand: maputil.GetString(options.ProviderExtendedConfig, "postCommand"),
|
PostCommand: maputil.GetString(options.ProviderServiceConfig, "postCommand"),
|
||||||
OutputFormat: pSSH.OutputFormatType(maputil.GetOrDefaultString(options.ProviderExtendedConfig, "format", string(pSSH.OUTPUT_FORMAT_PEM))),
|
OutputFormat: pSSH.OutputFormatType(maputil.GetOrDefaultString(options.ProviderServiceConfig, "format", string(pSSH.OUTPUT_FORMAT_PEM))),
|
||||||
OutputCertPath: maputil.GetString(options.ProviderExtendedConfig, "certPath"),
|
OutputCertPath: maputil.GetString(options.ProviderServiceConfig, "certPath"),
|
||||||
OutputServerCertPath: maputil.GetString(options.ProviderExtendedConfig, "certPathForServerOnly"),
|
OutputServerCertPath: maputil.GetString(options.ProviderServiceConfig, "certPathForServerOnly"),
|
||||||
OutputIntermediaCertPath: maputil.GetString(options.ProviderExtendedConfig, "certPathForIntermediaOnly"),
|
OutputIntermediaCertPath: maputil.GetString(options.ProviderServiceConfig, "certPathForIntermediaOnly"),
|
||||||
OutputKeyPath: maputil.GetString(options.ProviderExtendedConfig, "keyPath"),
|
OutputKeyPath: maputil.GetString(options.ProviderServiceConfig, "keyPath"),
|
||||||
PfxPassword: maputil.GetString(options.ProviderExtendedConfig, "pfxPassword"),
|
PfxPassword: maputil.GetString(options.ProviderServiceConfig, "pfxPassword"),
|
||||||
JksAlias: maputil.GetString(options.ProviderExtendedConfig, "jksAlias"),
|
JksAlias: maputil.GetString(options.ProviderServiceConfig, "jksAlias"),
|
||||||
JksKeypass: maputil.GetString(options.ProviderExtendedConfig, "jksKeypass"),
|
JksKeypass: maputil.GetString(options.ProviderServiceConfig, "jksKeypass"),
|
||||||
JksStorepass: maputil.GetString(options.ProviderExtendedConfig, "jksStorepass"),
|
JksStorepass: maputil.GetString(options.ProviderServiceConfig, "jksStorepass"),
|
||||||
})
|
})
|
||||||
return deployer, err
|
return deployer, err
|
||||||
}
|
}
|
||||||
|
@ -284,20 +284,20 @@ type AccessConfigForSafeLine struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AccessConfigForSSH struct {
|
type AccessConfigForSSH struct {
|
||||||
Host string `json:"host"`
|
Host string `json:"host"`
|
||||||
Port int32 `json:"port"`
|
Port int32 `json:"port"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Password string `json:"password,omitempty"`
|
Password string `json:"password,omitempty"`
|
||||||
Key string `json:"key,omitempty"`
|
Key string `json:"key,omitempty"`
|
||||||
KeyPassphrase string `json:"keyPassphrase,omitempty"`
|
KeyPassphrase string `json:"keyPassphrase,omitempty"`
|
||||||
JumpServerConfig []struct {
|
JumpServers []struct {
|
||||||
Host string `json:"host"`
|
Host string `json:"host"`
|
||||||
Port int32 `json:"port"`
|
Port int32 `json:"port"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Password string `json:"password,omitempty"`
|
Password string `json:"password,omitempty"`
|
||||||
Key string `json:"key,omitempty"`
|
Key string `json:"key,omitempty"`
|
||||||
KeyPassphrase string `json:"keyPassphrase,omitempty"`
|
KeyPassphrase string `json:"keyPassphrase,omitempty"`
|
||||||
} `json:"jumpServerConfig,omitempty"`
|
} `json:"jumpServers,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AccessConfigForSSLCom struct {
|
type AccessConfigForSSLCom struct {
|
||||||
|
@ -105,11 +105,6 @@ type WorkflowNodeConfigForNotify struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *WorkflowNode) GetConfigForApply() WorkflowNodeConfigForApply {
|
func (n *WorkflowNode) GetConfigForApply() WorkflowNodeConfigForApply {
|
||||||
skipBeforeExpiryDays := maputil.GetInt32(n.Config, "skipBeforeExpiryDays")
|
|
||||||
if skipBeforeExpiryDays == 0 {
|
|
||||||
skipBeforeExpiryDays = 30
|
|
||||||
}
|
|
||||||
|
|
||||||
return WorkflowNodeConfigForApply{
|
return WorkflowNodeConfigForApply{
|
||||||
Domains: maputil.GetString(n.Config, "domains"),
|
Domains: maputil.GetString(n.Config, "domains"),
|
||||||
ContactEmail: maputil.GetString(n.Config, "contactEmail"),
|
ContactEmail: maputil.GetString(n.Config, "contactEmail"),
|
||||||
@ -126,7 +121,7 @@ func (n *WorkflowNode) GetConfigForApply() WorkflowNodeConfigForApply {
|
|||||||
DnsTTL: maputil.GetInt32(n.Config, "dnsTTL"),
|
DnsTTL: maputil.GetInt32(n.Config, "dnsTTL"),
|
||||||
DisableFollowCNAME: maputil.GetBool(n.Config, "disableFollowCNAME"),
|
DisableFollowCNAME: maputil.GetBool(n.Config, "disableFollowCNAME"),
|
||||||
DisableARI: maputil.GetBool(n.Config, "disableARI"),
|
DisableARI: maputil.GetBool(n.Config, "disableARI"),
|
||||||
SkipBeforeExpiryDays: skipBeforeExpiryDays,
|
SkipBeforeExpiryDays: maputil.GetOrDefaultInt32(n.Config, "skipBeforeExpiryDays", 30),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider,
|
|||||||
providerConfig := internal.NewDefaultConfig()
|
providerConfig := internal.NewDefaultConfig()
|
||||||
providerConfig.SecretID = config.AccessKeyId
|
providerConfig.SecretID = config.AccessKeyId
|
||||||
providerConfig.SecretKey = config.AccessKeySecret
|
providerConfig.SecretKey = config.AccessKeySecret
|
||||||
|
providerConfig.RegionID = config.Region
|
||||||
if config.DnsPropagationTimeout != 0 {
|
if config.DnsPropagationTimeout != 0 {
|
||||||
providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second
|
providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,8 @@ type DeployerConfig struct {
|
|||||||
SshKey string `json:"sshKey,omitempty"`
|
SshKey string `json:"sshKey,omitempty"`
|
||||||
// SSH 登录私钥口令。
|
// SSH 登录私钥口令。
|
||||||
SshKeyPassphrase string `json:"sshKeyPassphrase,omitempty"`
|
SshKeyPassphrase string `json:"sshKeyPassphrase,omitempty"`
|
||||||
// 跳板机配置
|
// 跳板机配置数组。
|
||||||
JumpServerConfig []JumpServerConfig `json:"jumpServerConfig,omitempty"`
|
JumpServers []JumpServerConfig `json:"jumpServers,omitempty"`
|
||||||
// 是否回退使用 SCP。
|
// 是否回退使用 SCP。
|
||||||
UseSCP bool `json:"useSCP,omitempty"`
|
UseSCP bool `json:"useSCP,omitempty"`
|
||||||
// 前置命令。
|
// 前置命令。
|
||||||
@ -120,9 +120,9 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
|
|||||||
var targetConn net.Conn
|
var targetConn net.Conn
|
||||||
|
|
||||||
// 连接到跳板机
|
// 连接到跳板机
|
||||||
if len(d.config.JumpServerConfig) > 0 {
|
if len(d.config.JumpServers) > 0 {
|
||||||
var jumpClient *ssh.Client
|
var jumpClient *ssh.Client
|
||||||
for i, jumpServerConf := range d.config.JumpServerConfig {
|
for i, jumpServerConf := range d.config.JumpServers {
|
||||||
d.logger.Info(fmt.Sprintf("connecting to jump server [%d]", i+1), slog.String("host", jumpServerConf.SshHost))
|
d.logger.Info(fmt.Sprintf("connecting to jump server [%d]", i+1), slog.String("host", jumpServerConf.SshHost))
|
||||||
|
|
||||||
var jumpConn net.Conn
|
var jumpConn net.Conn
|
||||||
@ -154,13 +154,14 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
|
|||||||
jumpClient = newClient
|
jumpClient = newClient
|
||||||
d.logger.Info(fmt.Sprintf("jump server connected [%d]", i+1), slog.String("host", jumpServerConf.SshHost))
|
d.logger.Info(fmt.Sprintf("jump server connected [%d]", i+1), slog.String("host", jumpServerConf.SshHost))
|
||||||
}
|
}
|
||||||
// 通过跳板机发起到目标服务器的TCP连接
|
|
||||||
|
// 通过跳板机发起 TCP 连接到目标服务器
|
||||||
targetConn, err = jumpClient.DialContext(ctx, "tcp", fmt.Sprintf("%s:%d", d.config.SshHost, d.config.SshPort))
|
targetConn, err = jumpClient.DialContext(ctx, "tcp", fmt.Sprintf("%s:%d", d.config.SshHost, d.config.SshPort))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to connect to target server: %w", err)
|
return nil, fmt.Errorf("failed to connect to target server: %w", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 直接TCP连接到目标服务器
|
// 直接发起 TCP 连接到目标服务器
|
||||||
targetConn, err = net.Dial("tcp", fmt.Sprintf("%s:%d", d.config.SshHost, d.config.SshPort))
|
targetConn, err = net.Dial("tcp", fmt.Sprintf("%s:%d", d.config.SshHost, d.config.SshPort))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to connect to target server: %w", err)
|
return nil, fmt.Errorf("failed to connect to target server: %w", err)
|
||||||
@ -168,7 +169,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
|
|||||||
}
|
}
|
||||||
defer targetConn.Close()
|
defer targetConn.Close()
|
||||||
|
|
||||||
// 通过已有的连接创建目标服务器SSH客户端
|
// 通过已有的连接创建目标服务器 SSH 客户端
|
||||||
client, err := createSshClient(
|
client, err := createSshClient(
|
||||||
targetConn,
|
targetConn,
|
||||||
d.config.SshHost,
|
d.config.SshHost,
|
||||||
|
@ -2,9 +2,11 @@ package tencentcloudcdn
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
tccdn "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn/v20180606"
|
tccdn "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn/v20180606"
|
||||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
||||||
@ -132,6 +134,49 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to execute sdk request 'ssl.DeployCertificateInstance': %w", err)
|
return nil, fmt.Errorf("failed to execute sdk request 'ssl.DeployCertificateInstance': %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 循环获取部署任务详情,等待任务状态变更
|
||||||
|
// REF: https://cloud.tencent.com.cn/document/api/400/91658
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, ctx.Err()
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
describeHostDeployRecordDetailReq := tcssl.NewDescribeHostDeployRecordDetailRequest()
|
||||||
|
describeHostDeployRecordDetailReq.DeployRecordId = common.StringPtr(fmt.Sprintf("%d", *deployCertificateInstanceResp.Response.DeployRecordId))
|
||||||
|
describeHostDeployRecordDetailResp, err := d.sdkClients.SSL.DescribeHostDeployRecordDetail(describeHostDeployRecordDetailReq)
|
||||||
|
d.logger.Debug("sdk request 'ssl.DescribeHostDeployRecordDetail'", slog.Any("request", describeHostDeployRecordDetailReq), slog.Any("response", describeHostDeployRecordDetailResp))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostDeployRecordDetail': %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var runningCount, succeededCount, failedCount, totalCount int64
|
||||||
|
if describeHostDeployRecordDetailResp.Response.TotalCount == nil {
|
||||||
|
return nil, errors.New("unexpected deployment job status")
|
||||||
|
} else {
|
||||||
|
if describeHostDeployRecordDetailResp.Response.RunningTotalCount != nil {
|
||||||
|
runningCount = *describeHostDeployRecordDetailResp.Response.RunningTotalCount
|
||||||
|
}
|
||||||
|
if describeHostDeployRecordDetailResp.Response.SuccessTotalCount != nil {
|
||||||
|
succeededCount = *describeHostDeployRecordDetailResp.Response.SuccessTotalCount
|
||||||
|
}
|
||||||
|
if describeHostDeployRecordDetailResp.Response.FailedTotalCount != nil {
|
||||||
|
failedCount = *describeHostDeployRecordDetailResp.Response.FailedTotalCount
|
||||||
|
}
|
||||||
|
if describeHostDeployRecordDetailResp.Response.TotalCount != nil {
|
||||||
|
totalCount = *describeHostDeployRecordDetailResp.Response.TotalCount
|
||||||
|
}
|
||||||
|
|
||||||
|
if succeededCount+failedCount == totalCount {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.logger.Info(fmt.Sprintf("waiting for deployment job completion (running: %d, succeeded: %d, failed: %d, total: %d) ...", runningCount, succeededCount, failedCount, totalCount))
|
||||||
|
time.Sleep(time.Second * 5)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &deployer.DeployResult{}, nil
|
return &deployer.DeployResult{}, nil
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"time"
|
||||||
|
|
||||||
tcclb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317"
|
tcclb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317"
|
||||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
||||||
@ -151,6 +152,49 @@ func (d *DeployerProvider) deployViaSslService(ctx context.Context, cloudCertId
|
|||||||
return fmt.Errorf("failed to execute sdk request 'ssl.DeployCertificateInstance': %w", err)
|
return fmt.Errorf("failed to execute sdk request 'ssl.DeployCertificateInstance': %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 循环获取部署任务详情,等待任务状态变更
|
||||||
|
// REF: https://cloud.tencent.com.cn/document/api/400/91658
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
describeHostDeployRecordDetailReq := tcssl.NewDescribeHostDeployRecordDetailRequest()
|
||||||
|
describeHostDeployRecordDetailReq.DeployRecordId = common.StringPtr(fmt.Sprintf("%d", *deployCertificateInstanceResp.Response.DeployRecordId))
|
||||||
|
describeHostDeployRecordDetailResp, err := d.sdkClients.SSL.DescribeHostDeployRecordDetail(describeHostDeployRecordDetailReq)
|
||||||
|
d.logger.Debug("sdk request 'ssl.DescribeHostDeployRecordDetail'", slog.Any("request", describeHostDeployRecordDetailReq), slog.Any("response", describeHostDeployRecordDetailResp))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostDeployRecordDetail': %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var runningCount, succeededCount, failedCount, totalCount int64
|
||||||
|
if describeHostDeployRecordDetailResp.Response.TotalCount == nil {
|
||||||
|
return errors.New("unexpected deployment job status")
|
||||||
|
} else {
|
||||||
|
if describeHostDeployRecordDetailResp.Response.RunningTotalCount != nil {
|
||||||
|
runningCount = *describeHostDeployRecordDetailResp.Response.RunningTotalCount
|
||||||
|
}
|
||||||
|
if describeHostDeployRecordDetailResp.Response.SuccessTotalCount != nil {
|
||||||
|
succeededCount = *describeHostDeployRecordDetailResp.Response.SuccessTotalCount
|
||||||
|
}
|
||||||
|
if describeHostDeployRecordDetailResp.Response.FailedTotalCount != nil {
|
||||||
|
failedCount = *describeHostDeployRecordDetailResp.Response.FailedTotalCount
|
||||||
|
}
|
||||||
|
if describeHostDeployRecordDetailResp.Response.TotalCount != nil {
|
||||||
|
totalCount = *describeHostDeployRecordDetailResp.Response.TotalCount
|
||||||
|
}
|
||||||
|
|
||||||
|
if succeededCount+failedCount == totalCount {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.logger.Info(fmt.Sprintf("waiting for deployment job completion (running: %d, succeeded: %d, failed: %d, total: %d) ...", runningCount, succeededCount, failedCount, totalCount))
|
||||||
|
time.Sleep(time.Second * 5)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
||||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
|
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
|
||||||
@ -102,6 +103,49 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
|
|||||||
return nil, fmt.Errorf("failed to execute sdk request 'ssl.DeployCertificateInstance': %w", err)
|
return nil, fmt.Errorf("failed to execute sdk request 'ssl.DeployCertificateInstance': %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 循环获取部署任务详情,等待任务状态变更
|
||||||
|
// REF: https://cloud.tencent.com.cn/document/api/400/91658
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, ctx.Err()
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
describeHostDeployRecordDetailReq := tcssl.NewDescribeHostDeployRecordDetailRequest()
|
||||||
|
describeHostDeployRecordDetailReq.DeployRecordId = common.StringPtr(fmt.Sprintf("%d", *deployCertificateInstanceResp.Response.DeployRecordId))
|
||||||
|
describeHostDeployRecordDetailResp, err := d.sdkClient.DescribeHostDeployRecordDetail(describeHostDeployRecordDetailReq)
|
||||||
|
d.logger.Debug("sdk request 'ssl.DescribeHostDeployRecordDetail'", slog.Any("request", describeHostDeployRecordDetailReq), slog.Any("response", describeHostDeployRecordDetailResp))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostDeployRecordDetail': %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var runningCount, succeededCount, failedCount, totalCount int64
|
||||||
|
if describeHostDeployRecordDetailResp.Response.TotalCount == nil {
|
||||||
|
return nil, errors.New("unexpected deployment job status")
|
||||||
|
} else {
|
||||||
|
if describeHostDeployRecordDetailResp.Response.RunningTotalCount != nil {
|
||||||
|
runningCount = *describeHostDeployRecordDetailResp.Response.RunningTotalCount
|
||||||
|
}
|
||||||
|
if describeHostDeployRecordDetailResp.Response.SuccessTotalCount != nil {
|
||||||
|
succeededCount = *describeHostDeployRecordDetailResp.Response.SuccessTotalCount
|
||||||
|
}
|
||||||
|
if describeHostDeployRecordDetailResp.Response.FailedTotalCount != nil {
|
||||||
|
failedCount = *describeHostDeployRecordDetailResp.Response.FailedTotalCount
|
||||||
|
}
|
||||||
|
if describeHostDeployRecordDetailResp.Response.TotalCount != nil {
|
||||||
|
totalCount = *describeHostDeployRecordDetailResp.Response.TotalCount
|
||||||
|
}
|
||||||
|
|
||||||
|
if succeededCount+failedCount == totalCount {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.logger.Info(fmt.Sprintf("waiting for deployment job completion (running: %d, succeeded: %d, failed: %d, total: %d) ...", runningCount, succeededCount, failedCount, totalCount))
|
||||||
|
time.Sleep(time.Second * 5)
|
||||||
|
}
|
||||||
|
|
||||||
return &deployer.DeployResult{}, nil
|
return &deployer.DeployResult{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,9 +2,11 @@ package tencentcloudecdn
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
tccdn "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn/v20180606"
|
tccdn "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn/v20180606"
|
||||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
||||||
@ -103,7 +105,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
|
|||||||
} else {
|
} else {
|
||||||
d.logger.Info("found ecdn instances to deploy", slog.Any("instanceIds", instanceIds))
|
d.logger.Info("found ecdn instances to deploy", slog.Any("instanceIds", instanceIds))
|
||||||
|
|
||||||
// 证书部署到 ECDN 实例
|
// 证书部署到 CDN 实例
|
||||||
// REF: https://cloud.tencent.com/document/product/400/91667
|
// REF: https://cloud.tencent.com/document/product/400/91667
|
||||||
deployCertificateInstanceReq := tcssl.NewDeployCertificateInstanceRequest()
|
deployCertificateInstanceReq := tcssl.NewDeployCertificateInstanceRequest()
|
||||||
deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId)
|
deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId)
|
||||||
@ -115,6 +117,49 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to execute sdk request 'ssl.DeployCertificateInstance': %w", err)
|
return nil, fmt.Errorf("failed to execute sdk request 'ssl.DeployCertificateInstance': %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 循环获取部署任务详情,等待任务状态变更
|
||||||
|
// REF: https://cloud.tencent.com.cn/document/api/400/91658
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, ctx.Err()
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
describeHostDeployRecordDetailReq := tcssl.NewDescribeHostDeployRecordDetailRequest()
|
||||||
|
describeHostDeployRecordDetailReq.DeployRecordId = common.StringPtr(fmt.Sprintf("%d", *deployCertificateInstanceResp.Response.DeployRecordId))
|
||||||
|
describeHostDeployRecordDetailResp, err := d.sdkClients.SSL.DescribeHostDeployRecordDetail(describeHostDeployRecordDetailReq)
|
||||||
|
d.logger.Debug("sdk request 'ssl.DescribeHostDeployRecordDetail'", slog.Any("request", describeHostDeployRecordDetailReq), slog.Any("response", describeHostDeployRecordDetailResp))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostDeployRecordDetail': %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var runningCount, succeededCount, failedCount, totalCount int64
|
||||||
|
if describeHostDeployRecordDetailResp.Response.TotalCount == nil {
|
||||||
|
return nil, errors.New("unexpected deployment job status")
|
||||||
|
} else {
|
||||||
|
if describeHostDeployRecordDetailResp.Response.RunningTotalCount != nil {
|
||||||
|
runningCount = *describeHostDeployRecordDetailResp.Response.RunningTotalCount
|
||||||
|
}
|
||||||
|
if describeHostDeployRecordDetailResp.Response.SuccessTotalCount != nil {
|
||||||
|
succeededCount = *describeHostDeployRecordDetailResp.Response.SuccessTotalCount
|
||||||
|
}
|
||||||
|
if describeHostDeployRecordDetailResp.Response.FailedTotalCount != nil {
|
||||||
|
failedCount = *describeHostDeployRecordDetailResp.Response.FailedTotalCount
|
||||||
|
}
|
||||||
|
if describeHostDeployRecordDetailResp.Response.TotalCount != nil {
|
||||||
|
totalCount = *describeHostDeployRecordDetailResp.Response.TotalCount
|
||||||
|
}
|
||||||
|
|
||||||
|
if succeededCount+failedCount == totalCount {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.logger.Info(fmt.Sprintf("waiting for deployment job completion (running: %d, succeeded: %d, failed: %d, total: %d) ...", runningCount, succeededCount, failedCount, totalCount))
|
||||||
|
time.Sleep(time.Second * 5)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &deployer.DeployResult{}, nil
|
return &deployer.DeployResult{}, nil
|
||||||
|
@ -116,30 +116,35 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
|
|||||||
|
|
||||||
describeHostDeployRecordDetailReq := tcssl.NewDescribeHostDeployRecordDetailRequest()
|
describeHostDeployRecordDetailReq := tcssl.NewDescribeHostDeployRecordDetailRequest()
|
||||||
describeHostDeployRecordDetailReq.DeployRecordId = common.StringPtr(fmt.Sprintf("%d", *deployCertificateInstanceResp.Response.DeployRecordId))
|
describeHostDeployRecordDetailReq.DeployRecordId = common.StringPtr(fmt.Sprintf("%d", *deployCertificateInstanceResp.Response.DeployRecordId))
|
||||||
describeHostDeployRecordDetailReq.Limit = common.Uint64Ptr(100)
|
|
||||||
describeHostDeployRecordDetailResp, err := d.sdkClient.DescribeHostDeployRecordDetail(describeHostDeployRecordDetailReq)
|
describeHostDeployRecordDetailResp, err := d.sdkClient.DescribeHostDeployRecordDetail(describeHostDeployRecordDetailReq)
|
||||||
d.logger.Debug("sdk request 'ssl.DescribeHostDeployRecordDetail'", slog.Any("request", describeHostDeployRecordDetailReq), slog.Any("response", describeHostDeployRecordDetailResp))
|
d.logger.Debug("sdk request 'ssl.DescribeHostDeployRecordDetail'", slog.Any("request", describeHostDeployRecordDetailReq), slog.Any("response", describeHostDeployRecordDetailResp))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostDeployRecordDetail': %w", err)
|
return nil, fmt.Errorf("failed to execute sdk request 'ssl.DescribeHostDeployRecordDetail': %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var runningCount, succeededCount, failedCount, totalCount int64
|
||||||
if describeHostDeployRecordDetailResp.Response.TotalCount == nil {
|
if describeHostDeployRecordDetailResp.Response.TotalCount == nil {
|
||||||
return nil, errors.New("unexpected deployment job status")
|
return nil, errors.New("unexpected deployment job status")
|
||||||
} else {
|
} else {
|
||||||
acc := int64(0)
|
if describeHostDeployRecordDetailResp.Response.RunningTotalCount != nil {
|
||||||
|
runningCount = *describeHostDeployRecordDetailResp.Response.RunningTotalCount
|
||||||
|
}
|
||||||
if describeHostDeployRecordDetailResp.Response.SuccessTotalCount != nil {
|
if describeHostDeployRecordDetailResp.Response.SuccessTotalCount != nil {
|
||||||
acc += *describeHostDeployRecordDetailResp.Response.SuccessTotalCount
|
succeededCount = *describeHostDeployRecordDetailResp.Response.SuccessTotalCount
|
||||||
}
|
}
|
||||||
if describeHostDeployRecordDetailResp.Response.FailedTotalCount != nil {
|
if describeHostDeployRecordDetailResp.Response.FailedTotalCount != nil {
|
||||||
acc += *describeHostDeployRecordDetailResp.Response.FailedTotalCount
|
failedCount = *describeHostDeployRecordDetailResp.Response.FailedTotalCount
|
||||||
|
}
|
||||||
|
if describeHostDeployRecordDetailResp.Response.TotalCount != nil {
|
||||||
|
totalCount = *describeHostDeployRecordDetailResp.Response.TotalCount
|
||||||
}
|
}
|
||||||
|
|
||||||
if acc == *describeHostDeployRecordDetailResp.Response.TotalCount {
|
if succeededCount+failedCount == totalCount {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d.logger.Info("waiting for deployment job completion ...")
|
d.logger.Info(fmt.Sprintf("waiting for deployment job completion (running: %d, succeeded: %d, failed: %d, total: %d) ...", runningCount, succeededCount, failedCount, totalCount))
|
||||||
time.Sleep(time.Second * 5)
|
time.Sleep(time.Second * 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { ArrowDownOutlined, ArrowUpOutlined, CloseOutlined, PlusOutlined } from "@ant-design/icons";
|
||||||
import { Button, Collapse, Form, type FormInstance, Input, InputNumber, Space } from "antd";
|
import { Button, Collapse, Form, type FormInstance, Input, InputNumber, Space } from "antd";
|
||||||
import { createSchemaFieldRule } from "antd-zod";
|
import { createSchemaFieldRule } from "antd-zod";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@ -6,7 +7,6 @@ import { z } from "zod";
|
|||||||
import TextFileInput from "@/components/TextFileInput";
|
import TextFileInput from "@/components/TextFileInput";
|
||||||
import { type AccessConfigForSSH } from "@/domain/access";
|
import { type AccessConfigForSSH } from "@/domain/access";
|
||||||
import { validDomainName, validIPv4Address, validIPv6Address, validPortNumber } from "@/utils/validators";
|
import { validDomainName, validIPv4Address, validIPv6Address, validPortNumber } from "@/utils/validators";
|
||||||
import { ArrowDownOutlined, ArrowUpOutlined, CloseOutlined, PlusOutlined } from "@ant-design/icons";
|
|
||||||
|
|
||||||
type AccessFormSSHConfigFieldValues = Nullish<AccessConfigForSSH>;
|
type AccessFormSSHConfigFieldValues = Nullish<AccessConfigForSSH>;
|
||||||
|
|
||||||
@ -29,42 +29,6 @@ const initFormModel = (): AccessFormSSHConfigFieldValues => {
|
|||||||
const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormSSHConfigProps) => {
|
const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormSSHConfigProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const jumpServerConfigItemSchema = z
|
|
||||||
.object({
|
|
||||||
host: z.string().refine((v) => validDomainName(v) || validIPv4Address(v) || validIPv6Address(v), t("common.errmsg.host_invalid")),
|
|
||||||
port: z.preprocess(
|
|
||||||
(v) => Number(v),
|
|
||||||
z
|
|
||||||
.number()
|
|
||||||
.int(t("access.form.ssh_port.placeholder"))
|
|
||||||
.refine((v) => validPortNumber(v), t("common.errmsg.port_invalid"))
|
|
||||||
),
|
|
||||||
username: z
|
|
||||||
.string()
|
|
||||||
.min(1, t("access.form.ssh_username.placeholder"))
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
password: z
|
|
||||||
.string()
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 }))
|
|
||||||
.nullish(),
|
|
||||||
key: z
|
|
||||||
.string()
|
|
||||||
.max(20480, t("common.errmsg.string_max", { max: 20480 }))
|
|
||||||
.nullish(),
|
|
||||||
keyPassphrase: z
|
|
||||||
.string()
|
|
||||||
.max(20480, t("common.errmsg.string_max", { max: 20480 }))
|
|
||||||
.nullish(),
|
|
||||||
})
|
|
||||||
.superRefine((data, ctx) => {
|
|
||||||
if (data.keyPassphrase && !data.key) {
|
|
||||||
ctx.addIssue({
|
|
||||||
path: ["keyPassphrase"],
|
|
||||||
code: z.ZodIssueCode.custom,
|
|
||||||
message: t("access.form.ssh_key.placeholder"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const formSchema = z.object({
|
const formSchema = z.object({
|
||||||
host: z.string().refine((v) => validDomainName(v) || validIPv4Address(v) || validIPv6Address(v), t("common.errmsg.host_invalid")),
|
host: z.string().refine((v) => validDomainName(v) || validIPv4Address(v) || validIPv6Address(v), t("common.errmsg.host_invalid")),
|
||||||
port: z.preprocess(
|
port: z.preprocess(
|
||||||
@ -91,7 +55,46 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
|||||||
.max(20480, t("common.errmsg.string_max", { max: 20480 }))
|
.max(20480, t("common.errmsg.string_max", { max: 20480 }))
|
||||||
.nullish()
|
.nullish()
|
||||||
.refine((v) => !v || formInst.getFieldValue("key"), t("access.form.ssh_key.placeholder")),
|
.refine((v) => !v || formInst.getFieldValue("key"), t("access.form.ssh_key.placeholder")),
|
||||||
jumpServerConfig: jumpServerConfigItemSchema.array().nullish(),
|
jumpServers: z
|
||||||
|
.array(
|
||||||
|
z
|
||||||
|
.object({
|
||||||
|
host: z.string().refine((v) => validDomainName(v) || validIPv4Address(v) || validIPv6Address(v), t("common.errmsg.host_invalid")),
|
||||||
|
port: z.preprocess(
|
||||||
|
(v) => Number(v),
|
||||||
|
z
|
||||||
|
.number()
|
||||||
|
.int(t("access.form.ssh_port.placeholder"))
|
||||||
|
.refine((v) => validPortNumber(v), t("common.errmsg.port_invalid"))
|
||||||
|
),
|
||||||
|
username: z
|
||||||
|
.string()
|
||||||
|
.min(1, t("access.form.ssh_username.placeholder"))
|
||||||
|
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
||||||
|
password: z
|
||||||
|
.string()
|
||||||
|
.max(64, t("common.errmsg.string_max", { max: 64 }))
|
||||||
|
.nullish(),
|
||||||
|
key: z
|
||||||
|
.string()
|
||||||
|
.max(20480, t("common.errmsg.string_max", { max: 20480 }))
|
||||||
|
.nullish(),
|
||||||
|
keyPassphrase: z
|
||||||
|
.string()
|
||||||
|
.max(20480, t("common.errmsg.string_max", { max: 20480 }))
|
||||||
|
.nullish(),
|
||||||
|
})
|
||||||
|
.superRefine((data, ctx) => {
|
||||||
|
if (data.keyPassphrase && !data.key) {
|
||||||
|
ctx.addIssue({
|
||||||
|
path: ["keyPassphrase"],
|
||||||
|
code: z.ZodIssueCode.custom,
|
||||||
|
message: t("access.form.ssh_key.placeholder"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.nullish(),
|
||||||
});
|
});
|
||||||
const formRule = createSchemaFieldRule(formSchema);
|
const formRule = createSchemaFieldRule(formSchema);
|
||||||
|
|
||||||
@ -153,49 +156,63 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
|||||||
<Input.Password allowClear autoComplete="new-password" placeholder={t("access.form.ssh_key_passphrase.placeholder")} />
|
<Input.Password allowClear autoComplete="new-password" placeholder={t("access.form.ssh_key_passphrase.placeholder")} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item name="jumpServers" label={t("access.form.ssh_jump_servers.label")} rules={[formRule]}>
|
||||||
label={t("access.form.ssh_jump_server_config.label")}
|
<Form.List name="jumpServers">
|
||||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.ssh_jump_server_config.tooltip") }}></span>}
|
|
||||||
>
|
|
||||||
<Form.List name="jumpServerConfig">
|
|
||||||
{(fields, { add, remove, move }) => (
|
{(fields, { add, remove, move }) => (
|
||||||
<Space className="w-full" direction="vertical" size="small">
|
<Space className="w-full" direction="vertical" size="small">
|
||||||
{fields?.length > 0 ? (
|
{fields?.length > 0 ? (
|
||||||
<Collapse
|
<Collapse
|
||||||
items={fields.map((field, index) => {
|
items={fields.map((field, index) => {
|
||||||
const Label = () => {
|
const Label = () => {
|
||||||
const itemHost = Form.useWatch(["jumpServerConfig", field.name, "host"], formInst);
|
const host = Form.useWatch(["jumpServers", field.name, "host"], formInst);
|
||||||
|
const port = Form.useWatch(["jumpServers", field.name, "port"], formInst);
|
||||||
|
const addr = !!host && !!port ? `${host}:${port}` : host ? host : port ? `:${port}` : "unknown";
|
||||||
return (
|
return (
|
||||||
<span style={{ userSelect: "none" }}>
|
<span className="select-none">
|
||||||
[{t("access.form.ssh_jump_server_config.item.label")} {field.name + 1}] {itemHost ?? ""}
|
[{t("access.form.ssh_jump_servers.item.label")} {field.name + 1}] {addr}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
key: field.key,
|
key: field.key,
|
||||||
label: <Label />, // 这里用组件渲染
|
label: <Label />,
|
||||||
extra: (
|
extra: (
|
||||||
<Space>
|
<Space.Compact>
|
||||||
<ArrowUpOutlined
|
<Button
|
||||||
|
icon={<ArrowUpOutlined />}
|
||||||
|
color="default"
|
||||||
|
disabled={disabled || index === 0}
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
move(index, index - 1);
|
move(index, index - 1);
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<ArrowDownOutlined
|
<Button
|
||||||
|
icon={<ArrowDownOutlined />}
|
||||||
|
color="default"
|
||||||
|
disabled={disabled || index === fields.length - 1}
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
move(index, index + 1);
|
move(index, index + 1);
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<CloseOutlined
|
<Button
|
||||||
|
icon={<CloseOutlined />}
|
||||||
|
color="default"
|
||||||
|
disabled={disabled}
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
remove(field.name);
|
remove(field.name);
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Space>
|
</Space.Compact>
|
||||||
),
|
),
|
||||||
children: (
|
children: (
|
||||||
<>
|
<>
|
||||||
@ -211,9 +228,11 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Form.Item name={[field.name, "username"]} label={t("access.form.ssh_username.label")} rules={[formRule]}>
|
<Form.Item name={[field.name, "username"]} label={t("access.form.ssh_username.label")} rules={[formRule]}>
|
||||||
<Input autoComplete="new-password" placeholder={t("access.form.ssh_username.placeholder")} />
|
<Input autoComplete="new-password" placeholder={t("access.form.ssh_username.placeholder")} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={[field.name, "password"]}
|
name={[field.name, "password"]}
|
||||||
label={t("access.form.ssh_password.label")}
|
label={t("access.form.ssh_password.label")}
|
||||||
@ -222,6 +241,7 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
|||||||
>
|
>
|
||||||
<Input.Password allowClear autoComplete="new-password" placeholder={t("access.form.ssh_password.placeholder")} />
|
<Input.Password allowClear autoComplete="new-password" placeholder={t("access.form.ssh_password.placeholder")} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={[field.name, "key"]}
|
name={[field.name, "key"]}
|
||||||
label={t("access.form.ssh_key.label")}
|
label={t("access.form.ssh_key.label")}
|
||||||
@ -230,6 +250,7 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
|||||||
>
|
>
|
||||||
<TextFileInput allowClear autoSize={{ minRows: 1, maxRows: 5 }} placeholder={t("access.form.ssh_key.placeholder")} />
|
<TextFileInput allowClear autoSize={{ minRows: 1, maxRows: 5 }} placeholder={t("access.form.ssh_key.placeholder")} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={[field.name, "keyPassphrase"]}
|
name={[field.name, "keyPassphrase"]}
|
||||||
label={t("access.form.ssh_key_passphrase.label")}
|
label={t("access.form.ssh_key_passphrase.label")}
|
||||||
@ -245,7 +266,7 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
|||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<Button type="dashed" className="w-full" icon={<PlusOutlined />} onClick={() => add()}>
|
<Button type="dashed" className="w-full" icon={<PlusOutlined />} onClick={() => add()}>
|
||||||
{t("access.form.ssh_jump_server_config.add")}
|
{t("access.form.ssh_jump_servers.add")}
|
||||||
</Button>
|
</Button>
|
||||||
</Space>
|
</Space>
|
||||||
)}
|
)}
|
||||||
@ -256,4 +277,3 @@ const AccessFormSSHConfig = ({ form: formInst, formName, disabled, initialValues
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default AccessFormSSHConfig;
|
export default AccessFormSSHConfig;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ const AccessFormTelegramBotConfig = ({ form: formInst, formName, disabled, initi
|
|||||||
.nullish()
|
.nullish()
|
||||||
.refine((v) => {
|
.refine((v) => {
|
||||||
if (v == null || v + "" === "") return true;
|
if (v == null || v + "" === "") return true;
|
||||||
return /^\d+$/.test(v + "") && +v! > 0;
|
return !Number.isNaN(+v!) && +v! !== 0;
|
||||||
}, t("access.form.telegram_bot_default_chat_id.placeholder"))
|
}, t("access.form.telegram_bot_default_chat_id.placeholder"))
|
||||||
)
|
)
|
||||||
.nullish(),
|
.nullish(),
|
||||||
@ -72,7 +72,7 @@ const AccessFormTelegramBotConfig = ({ form: formInst, formName, disabled, initi
|
|||||||
rules={[formRule]}
|
rules={[formRule]}
|
||||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.telegram_bot_default_chat_id.tooltip") }}></span>}
|
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.telegram_bot_default_chat_id.tooltip") }}></span>}
|
||||||
>
|
>
|
||||||
<Input type="number" allowClear placeholder={t("access.form.telegram_bot_default_chat_id.placeholder")} />
|
<Input allowClear placeholder={t("access.form.telegram_bot_default_chat_id.placeholder")} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
@ -37,7 +37,7 @@ const NotifyNodeConfigFormTelegramBotConfig = ({
|
|||||||
.nullish()
|
.nullish()
|
||||||
.refine((v) => {
|
.refine((v) => {
|
||||||
if (v == null || v + "" === "") return true;
|
if (v == null || v + "" === "") return true;
|
||||||
return /^\d+$/.test(v + "") && +v! > 0;
|
return !Number.isNaN(+v!) && +v! !== 0;
|
||||||
}, t("workflow_node.notify.form.telegram_bot_chat_id.placeholder"))
|
}, t("workflow_node.notify.form.telegram_bot_chat_id.placeholder"))
|
||||||
)
|
)
|
||||||
.nullish(),
|
.nullish(),
|
||||||
@ -63,7 +63,7 @@ const NotifyNodeConfigFormTelegramBotConfig = ({
|
|||||||
rules={[formRule]}
|
rules={[formRule]}
|
||||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.notify.form.telegram_bot_chat_id.tooltip") }}></span>}
|
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.notify.form.telegram_bot_chat_id.tooltip") }}></span>}
|
||||||
>
|
>
|
||||||
<Input type="number" allowClear placeholder={t("workflow_node.notify.form.telegram_bot_chat_id.placeholder")} />
|
<Input allowClear placeholder={t("workflow_node.notify.form.telegram_bot_chat_id.placeholder")} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
@ -392,10 +392,9 @@
|
|||||||
"access.form.ssh_key_passphrase.label": "SSH key passphrase (Optional)",
|
"access.form.ssh_key_passphrase.label": "SSH key passphrase (Optional)",
|
||||||
"access.form.ssh_key_passphrase.placeholder": "Please enter SSH key passphrase",
|
"access.form.ssh_key_passphrase.placeholder": "Please enter SSH key passphrase",
|
||||||
"access.form.ssh_key_passphrase.tooltip": "Optional when using key to connect to SSH.",
|
"access.form.ssh_key_passphrase.tooltip": "Optional when using key to connect to SSH.",
|
||||||
"access.form.ssh_jump_server_config.label": "SSH jump server (Optional)",
|
"access.form.ssh_jump_servers.label": "SSH jump server (Optional)",
|
||||||
"access.form.ssh_jump_server_config.tooltip": "Optional when using a jump server to connect to the server.",
|
"access.form.ssh_jump_servers.item.label": "Jump server",
|
||||||
"access.form.ssh_jump_server_config.item.label": "Jump Server",
|
"access.form.ssh_jump_servers.add": "Add jump server",
|
||||||
"access.form.ssh_jump_server_config.add": "Add Jump Server",
|
|
||||||
"access.form.sslcom_eab_kid.label": "ACME EAB KID",
|
"access.form.sslcom_eab_kid.label": "ACME EAB KID",
|
||||||
"access.form.sslcom_eab_kid.placeholder": "Please enter ACME EAB KID",
|
"access.form.sslcom_eab_kid.placeholder": "Please enter ACME EAB KID",
|
||||||
"access.form.sslcom_eab_kid.tooltip": "For more information, see <a href=\"https://www.ssl.com/how-to/generate-acme-credentials-for-reseller-customers/#ftoc-heading-6\" target=\"_blank\">https://www.ssl.com/how-to/generate-acme-credentials-for-reseller-customers/</a>",
|
"access.form.sslcom_eab_kid.tooltip": "For more information, see <a href=\"https://www.ssl.com/how-to/generate-acme-credentials-for-reseller-customers/#ftoc-heading-6\" target=\"_blank\">https://www.ssl.com/how-to/generate-acme-credentials-for-reseller-customers/</a>",
|
||||||
|
@ -386,10 +386,9 @@
|
|||||||
"access.form.ssh_key_passphrase.label": "SSH 密钥口令(可选)",
|
"access.form.ssh_key_passphrase.label": "SSH 密钥口令(可选)",
|
||||||
"access.form.ssh_key_passphrase.placeholder": "请输入 SSH 密钥口令",
|
"access.form.ssh_key_passphrase.placeholder": "请输入 SSH 密钥口令",
|
||||||
"access.form.ssh_key_passphrase.tooltip": "使用 SSH 密钥连接到 SSH 时选填。",
|
"access.form.ssh_key_passphrase.tooltip": "使用 SSH 密钥连接到 SSH 时选填。",
|
||||||
"access.form.ssh_jump_server_config.label": "SSH 跳板机(可选)",
|
"access.form.ssh_jump_servers.label": "SSH 跳板机(可选)",
|
||||||
"access.form.ssh_jump_server_config.tooltip": "使用跳板机连接到服务器时选填。",
|
"access.form.ssh_jump_servers.item.label": "跳板机",
|
||||||
"access.form.ssh_jump_server_config.item.label": "跳板机",
|
"access.form.ssh_jump_servers.add": "添加跳板机",
|
||||||
"access.form.ssh_jump_server_config.add": "添加跳板机",
|
|
||||||
"access.form.sslcom_eab_kid.label": "ACME EAB KID",
|
"access.form.sslcom_eab_kid.label": "ACME EAB KID",
|
||||||
"access.form.sslcom_eab_kid.placeholder": "请输入 ACME EAB KID",
|
"access.form.sslcom_eab_kid.placeholder": "请输入 ACME EAB KID",
|
||||||
"access.form.sslcom_eab_kid.tooltip": "这是什么?请参阅 <a href=\"https://www.ssl.com/how-to/generate-acme-credentials-for-reseller-customers/#ftoc-heading-6\" target=\"_blank\">https://www.ssl.com/how-to/generate-acme-credentials-for-reseller-customers/</a>",
|
"access.form.sslcom_eab_kid.tooltip": "这是什么?请参阅 <a href=\"https://www.ssl.com/how-to/generate-acme-credentials-for-reseller-customers/#ftoc-heading-6\" target=\"_blank\">https://www.ssl.com/how-to/generate-acme-credentials-for-reseller-customers/</a>",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user