feat: support configuring multiple domains deployment to tencentcloud edgeone

This commit is contained in:
吃瓜的星核精 2025-07-08 21:22:29 +08:00 committed by GitHub
parent b43fcc3b61
commit 1e4cd2b9d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 159 additions and 30 deletions

View File

@ -1202,7 +1202,7 @@ func createSSLDeployerProvider(options *deployerProviderOptions) (core.SSLDeploy
SecretKey: access.SecretKey,
Endpoint: xmaps.GetString(options.ProviderServiceConfig, "endpoint"),
ZoneId: xmaps.GetString(options.ProviderServiceConfig, "zoneId"),
Domain: xmaps.GetString(options.ProviderServiceConfig, "domain"),
Domains: xslices.Filter(strings.Split(xmaps.GetString(options.ProviderServiceConfig, "domains"), ";"), func(s string) bool { return s != "" }),
})
return deployer, err

View File

@ -270,12 +270,12 @@ func init() {
Id string `json:"id"`
Type string `json:"type"`
Name string `json:"name"`
Config map[string]any `json:"config"`
Inputs []map[string]any `json:"inputs"`
Outputs []map[string]any `json:"outputs"`
Config map[string]any `json:"config,omitempty"`
Inputs []map[string]any `json:"inputs,omitempty"`
Outputs []map[string]any `json:"outputs,omitempty"`
Next *dWorkflowNode `json:"next,omitempty"`
Branches []dWorkflowNode `json:"branches,omitempty"`
Validated bool `json:"validated"`
Branches []*dWorkflowNode `json:"branches,omitempty"`
Validated bool `json:"validated,omitempty"`
}
for _, workflowRun := range workflowRuns {

View File

@ -0,0 +1,112 @@
package migrations
import (
"github.com/pocketbase/pocketbase/core"
m "github.com/pocketbase/pocketbase/migrations"
)
func init() {
m.Register(func(app core.App) error {
tracer := NewTracer("(v0.3)1751961600")
tracer.Printf("go ...")
// migrate data
{
workflows, err := app.FindAllRecords("workflow")
if err != nil {
return err
}
type dWorkflowNode struct {
Id string `json:"id"`
Type string `json:"type"`
Name string `json:"name"`
Config map[string]any `json:"config,omitempty"`
Inputs []map[string]any `json:"inputs,omitempty"`
Outputs []map[string]any `json:"outputs,omitempty"`
Next *dWorkflowNode `json:"next,omitempty"`
Branches []*dWorkflowNode `json:"branches,omitempty"`
Validated bool `json:"validated,omitempty"`
}
deepChangeFn := func(node *dWorkflowNode) bool {
stack := []*dWorkflowNode{node}
for len(stack) > 0 {
current := stack[len(stack)-1]
stack = stack[:len(stack)-1]
if current.Type == "deploy" {
configMap := current.Config
if configMap != nil {
if provider, ok := configMap["provider"]; ok {
if provider.(string) == "tencentcloud-eo" {
if providerConfig, ok := configMap["providerConfig"]; ok {
if providerConfigMap, ok := providerConfig.(map[string]any); ok {
if _, ok := providerConfigMap["domain"]; ok {
providerConfigMap["domains"] = providerConfigMap["domain"]
delete(providerConfigMap, "domain")
configMap["providerConfig"] = providerConfigMap
return true
}
}
}
}
}
}
}
if current.Next != nil {
stack = append(stack, current.Next)
}
if current.Branches != nil {
for i := len(current.Branches) - 1; i >= 0; i-- {
stack = append(stack, current.Branches[i])
}
}
}
return false
}
for _, workflow := range workflows {
changed := false
rootNodeContent := &dWorkflowNode{}
if err := workflow.UnmarshalJSONField("content", rootNodeContent); err != nil {
return err
} else {
if deepChangeFn(rootNodeContent) {
workflow.Set("content", rootNodeContent)
changed = true
}
}
rootNodeDraft := &dWorkflowNode{}
if err := workflow.UnmarshalJSONField("draft", rootNodeDraft); err != nil {
return err
} else {
if deepChangeFn(rootNodeDraft) {
workflow.Set("draft", rootNodeDraft)
changed = true
}
}
if changed {
err = app.Save(workflow)
if err != nil {
return err
}
tracer.Printf("record #%s in collection '%s' updated", workflow.Id, workflow.Collection().Name)
}
}
}
tracer.Printf("done")
return nil
}, func(app core.App) error {
return nil
})
}

View File

@ -25,8 +25,8 @@ type SSLDeployerProviderConfig struct {
Endpoint string `json:"endpoint,omitempty"`
// 站点 ID。
ZoneId string `json:"zoneId"`
// 加速域名(支持泛域名)。
Domain string `json:"domain"`
// 加速域名列表(支持泛域名)。
Domains []string `json:"domains"`
}
type SSLDeployerProvider struct {
@ -82,8 +82,8 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke
if d.config.ZoneId == "" {
return nil, errors.New("config `zoneId` is required")
}
if d.config.Domain == "" {
return nil, errors.New("config `domain` is required")
if len(d.config.Domains) == 0 {
return nil, errors.New("config `domains` is required")
}
// 上传证书
@ -99,7 +99,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke
modifyHostsCertificateReq := tcteo.NewModifyHostsCertificateRequest()
modifyHostsCertificateReq.ZoneId = common.StringPtr(d.config.ZoneId)
modifyHostsCertificateReq.Mode = common.StringPtr("sslcert")
modifyHostsCertificateReq.Hosts = common.StringPtrs([]string{d.config.Domain})
modifyHostsCertificateReq.Hosts = common.StringPtrs(d.config.Domains)
modifyHostsCertificateReq.ServerCertInfo = []*tcteo.ServerCertInfo{{CertId: common.StringPtr(upres.CertId)}}
modifyHostsCertificateResp, err := d.sdkClient.ModifyHostsCertificate(modifyHostsCertificateReq)
d.logger.Debug("sdk request 'teo.ModifyHostsCertificate'", slog.Any("request", modifyHostsCertificateReq), slog.Any("response", modifyHostsCertificateResp))

View File

@ -17,7 +17,7 @@ var (
fSecretId string
fSecretKey string
fZoneId string
fDomain string
fDomains string
)
func init() {
@ -28,7 +28,7 @@ func init() {
flag.StringVar(&fSecretId, argsPrefix+"SECRETID", "", "")
flag.StringVar(&fSecretKey, argsPrefix+"SECRETKEY", "", "")
flag.StringVar(&fZoneId, argsPrefix+"ZONEID", "", "")
flag.StringVar(&fDomain, argsPrefix+"DOMAIN", "", "")
flag.StringVar(&fDomains, argsPrefix+"DOMAINS", "", "")
}
/*
@ -40,7 +40,7 @@ Shell command to run this test:
--CERTIMATE_SSLDEPLOYER_TENCENTCLOUDEO_SECRETID="your-secret-id" \
--CERTIMATE_SSLDEPLOYER_TENCENTCLOUDEO_SECRETKEY="your-secret-key" \
--CERTIMATE_SSLDEPLOYER_TENCENTCLOUDEO_ZONEID="your-zone-id" \
--CERTIMATE_SSLDEPLOYER_TENCENTCLOUDEO_DOMAIN="example.com"
--CERTIMATE_SSLDEPLOYER_TENCENTCLOUDEO_DOMAINS="example.com"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
@ -53,14 +53,14 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("SECRETID: %v", fSecretId),
fmt.Sprintf("SECRETKEY: %v", fSecretKey),
fmt.Sprintf("ZONEID: %v", fZoneId),
fmt.Sprintf("DOMAIN: %v", fDomain),
fmt.Sprintf("DOMAINS: %v", fDomains),
}, "\n"))
deployer, err := provider.NewSSLDeployerProvider(&provider.SSLDeployerProviderConfig{
SecretId: fSecretId,
SecretKey: fSecretKey,
ZoneId: fZoneId,
Domain: fDomain,
Domains: strings.Split(fDomains, ";"),
})
if err != nil {
t.Errorf("err: %+v", err)

View File

@ -4,11 +4,12 @@ import { createSchemaFieldRule } from "antd-zod";
import { z } from "zod/v4";
import { validDomainName } from "@/utils/validators";
import MultipleSplitValueInput from "@/components/MultipleSplitValueInput";
type DeployNodeConfigFormTencentCloudEOConfigFieldValues = Nullish<{
endpoint?: string;
zoneId: string;
domain: string;
domains: string;
}>;
export type DeployNodeConfigFormTencentCloudEOConfigProps = {
@ -23,6 +24,8 @@ const initFormModel = (): DeployNodeConfigFormTencentCloudEOConfigFieldValues =>
return {};
};
const MULTIPLE_INPUT_SEPARATOR = ";";
const DeployNodeConfigFormTencentCloudEOConfig = ({
form: formInst,
formName,
@ -37,9 +40,14 @@ const DeployNodeConfigFormTencentCloudEOConfig = ({
zoneId: z
.string(t("workflow_node.deploy.form.tencentcloud_eo_zone_id.placeholder"))
.nonempty(t("workflow_node.deploy.form.tencentcloud_eo_zone_id.placeholder")),
domain: z
.string(t("workflow_node.deploy.form.tencentcloud_eo_domain.placeholder"))
.refine((v) => validDomainName(v, { allowWildcard: true }), t("common.errmsg.domain_invalid")),
domains: z
.string(t("workflow_node.deploy.form.tencentcloud_eo_domains.placeholder"))
.refine((v) => {
if (!v) return false;
return String(v)
.split(MULTIPLE_INPUT_SEPARATOR)
.every((e) => validDomainName(e, { allowWildcard: true }));
}, t("common.errmsg.domain_invalid")),
});
const formRule = createSchemaFieldRule(formSchema);
@ -75,12 +83,17 @@ const DeployNodeConfigFormTencentCloudEOConfig = ({
</Form.Item>
<Form.Item
name="domain"
label={t("workflow_node.deploy.form.tencentcloud_eo_domain.label")}
name="domains"
label={t("workflow_node.deploy.form.tencentcloud_eo_domains.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.tencentcloud_eo_domain.tooltip") }}></span>}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.tencentcloud_eo_domains.tooltip") }}></span>}
>
<Input placeholder={t("workflow_node.deploy.form.tencentcloud_eo_domain.placeholder")} />
<MultipleSplitValueInput
modalTitle={t("workflow_node.deploy.form.tencentcloud_eo_domains.multiple_input_modal.title")}
placeholder={t("workflow_node.deploy.form.tencentcloud_eo_domains.placeholder")}
placeholderInModal={t("workflow_node.deploy.form.tencentcloud_eo_domains.multiple_input_modal.placeholder")}
splitOptions={{ trim: true, removeEmpty: true }}
/>
</Form.Item>
</Form>
);

View File

@ -727,9 +727,11 @@
"workflow_node.deploy.form.tencentcloud_eo_zone_id.label": "Tencent Cloud EdgeOne zone ID",
"workflow_node.deploy.form.tencentcloud_eo_zone_id.placeholder": "Please enter Tencent Cloud EdgeOne zone ID",
"workflow_node.deploy.form.tencentcloud_eo_zone_id.tooltip": "For more information, see <a href=\"https://console.tencentcloud.com/edgeone\" target=\"_blank\">https://console.tencentcloud.com/edgeone</a>",
"workflow_node.deploy.form.tencentcloud_eo_domain.label": "Tencent Cloud EdgeOne domain",
"workflow_node.deploy.form.tencentcloud_eo_domain.placeholder": "Please enter Tencent Cloud EdgeOne domain name",
"workflow_node.deploy.form.tencentcloud_eo_domain.tooltip": "For more information, see <a href=\"https://console.tencentcloud.com/edgeone\" target=\"_blank\">https://console.tencentcloud.com/edgeone</a>",
"workflow_node.deploy.form.tencentcloud_eo_domains.label": "Tencent Cloud EdgeOne domains",
"workflow_node.deploy.form.tencentcloud_eo_domains.placeholder": "Please enter Tencent Cloud EdgeOne domain names (separated by semicolons)",
"workflow_node.deploy.form.tencentcloud_eo_domains.tooltip": "For more information, see <a href=\"https://console.tencentcloud.com/edgeone\" target=\"_blank\">https://console.tencentcloud.com/edgeone</a>",
"workflow_node.deploy.form.tencentcloud_eo_domains.multiple_input_modal.title": "Change Tencent Cloud EdgeOne domain",
"workflow_node.deploy.form.tencentcloud_eo_domains.multiple_input_modal.placeholder": "Please enter Tencent Cloud EdgeOne domain name",
"workflow_node.deploy.form.tencentcloud_gaap_endpoint.label": "Tencent Cloud GAAP API endpoint (Optional)",
"workflow_node.deploy.form.tencentcloud_gaap_endpoint.placeholder": "Please enter Tencent Cloud GAAP API endpoint (e.g. gaap.intl.tencentcloudapi.com)",
"workflow_node.deploy.form.tencentcloud_gaap_endpoint.tooltip": "<ul style=\"margin-left: 1.25em; list-style: disc;\"><li><strong>gaap.intl.tencentcloudapi.com</strong> for Tencent Cloud International</li><li><strong>gaap.tencentcloudapi.com</strong> for Tencent Cloud in China</li></ul>",

View File

@ -725,9 +725,11 @@
"workflow_node.deploy.form.tencentcloud_eo_zone_id.label": "腾讯云 EdgeOne 站点 ID",
"workflow_node.deploy.form.tencentcloud_eo_zone_id.placeholder": "请输入腾讯云 EdgeOne 站点 ID",
"workflow_node.deploy.form.tencentcloud_eo_zone_id.tooltip": "这是什么?请参阅 <a href=\"https://console.cloud.tencent.com/edgeone\" target=\"_blank\">https://console.cloud.tencent.com/edgeone</a>",
"workflow_node.deploy.form.tencentcloud_eo_domain.label": "腾讯云 EdgeOne 加速域名",
"workflow_node.deploy.form.tencentcloud_eo_domain.placeholder": "请输入腾讯云 EdgeOne 加速域名(支持泛域名)",
"workflow_node.deploy.form.tencentcloud_eo_domain.tooltip": "这是什么?请参阅 <a href=\"https://console.cloud.tencent.com/edgeone\" target=\"_blank\">https://console.cloud.tencent.com/edgeone</a>",
"workflow_node.deploy.form.tencentcloud_eo_domains.label": "腾讯云 EdgeOne 加速域名",
"workflow_node.deploy.form.tencentcloud_eo_domains.placeholder": "请输入腾讯云 EdgeOne 加速域名(支持泛域名;多个值请用半角分号隔开)",
"workflow_node.deploy.form.tencentcloud_eo_domains.tooltip": "这是什么?请参阅 <a href=\"https://console.cloud.tencent.com/edgeone\" target=\"_blank\">https://console.cloud.tencent.com/edgeone</a>",
"workflow_node.deploy.form.tencentcloud_eo_domains.multiple_input_modal.title": "修改腾讯云 EdgeOne 加速域名",
"workflow_node.deploy.form.tencentcloud_eo_domains.multiple_input_modal.placeholder": "请输入腾讯云 EdgeOne 加速域名(支持泛域名)",
"workflow_node.deploy.form.tencentcloud_gaap_endpoint.label": "腾讯云 GAAP 接口端点(可选)",
"workflow_node.deploy.form.tencentcloud_gaap_endpoint.placeholder": "请输入腾讯云 GAAP 接口端点例如gaap.tencentcloudapi.com",
"workflow_node.deploy.form.tencentcloud_gaap_endpoint.tooltip": "这是什么?请参阅 <a href=\"https://cloud.tencent.com/document/product/608/36934\" target=\"_blank\">https://cloud.tencent.com/document/product/608/36934</a><br><br>国际站用户请填写 <em>gaap.intl.tencentcloudapi.com</em>。",