Merge pull request #515 from fudiwei/main

enhance & bugfix
This commit is contained in:
Yoan.liu 2025-03-12 21:44:12 +08:00 committed by GitHub
commit e888df2b9f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 126 additions and 45 deletions

View File

@ -226,6 +226,7 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) {
AccessKeySecret: access.AccessKeySecret, AccessKeySecret: access.AccessKeySecret,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
InstanceId: maps.GetValueAsString(options.ProviderDeployConfig, "instanceId"), InstanceId: maps.GetValueAsString(options.ProviderDeployConfig, "instanceId"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}) })
return deployer, err return deployer, err

View File

@ -297,7 +297,9 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
var errs []error var errs []error
for _, listenerCertificate := range listenerCertificates { for _, listenerCertificate := range listenerCertificates {
if *listenerCertificate.CertificateId == cloudCertId { // 监听证书 ID 格式:${证书 ID}-${地域}
certificateId := strings.Split(*listenerCertificate.CertificateId, "-")[0]
if certificateId == cloudCertId {
certificateIsAssociated = true certificateIsAssociated = true
continue continue
} }
@ -306,14 +308,14 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
continue continue
} }
listenerCertificateId, err := strconv.ParseInt(*listenerCertificate.CertificateId, 10, 64) certificateIdAsInt64, err := strconv.ParseInt(certificateId, 10, 64)
if err != nil { if err != nil {
errs = append(errs, err) errs = append(errs, err)
continue continue
} }
getUserCertificateDetailReq := &aliyunCas.GetUserCertificateDetailRequest{ getUserCertificateDetailReq := &aliyunCas.GetUserCertificateDetailRequest{
CertId: tea.Int64(listenerCertificateId), CertId: tea.Int64(certificateIdAsInt64),
} }
getUserCertificateDetailResp, err := d.sdkClients.cas.GetUserCertificateDetail(getUserCertificateDetailReq) getUserCertificateDetailResp, err := d.sdkClients.cas.GetUserCertificateDetail(getUserCertificateDetailReq)
if err != nil { if err != nil {
@ -332,7 +334,7 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
continue continue
} }
certificateIdsExpired = append(certificateIdsExpired, *listenerCertificate.CertificateId) certificateIdsExpired = append(certificateIdsExpired, certificateId)
} }
if len(errs) > 0 { if len(errs) > 0 {

View File

@ -24,8 +24,10 @@ type DeployerConfig struct {
AccessKeySecret string `json:"accessKeySecret"` AccessKeySecret string `json:"accessKeySecret"`
// 阿里云地域。 // 阿里云地域。
Region string `json:"region"` Region string `json:"region"`
// 阿里云 WAF 实例 ID。 // WAF 实例 ID。
InstanceId string `json:"instanceId"` InstanceId string `json:"instanceId"`
// 接入域名(支持泛域名)。
Domain string `json:"domain,omitempty"`
} }
type DeployerProvider struct { type DeployerProvider struct {
@ -74,38 +76,87 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem) upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil { if err != nil {
return nil, xerrors.Wrap(err, "failed to upload certificate file") return nil, xerrors.Wrap(err, "failed to upload certificate file")
} else {
d.logger.Logt("certificate file uploaded", upres)
} }
d.logger.Logt("certificate file uploaded", upres) if d.config.Domain == "" {
// 未指定接入域名,只需替换默认证书即可
// 查询默认 SSL/TLS 设置 // 查询默认 SSL/TLS 设置
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-describedefaulthttps // REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-describedefaulthttps
describeDefaultHttpsReq := &aliyunWaf.DescribeDefaultHttpsRequest{ describeDefaultHttpsReq := &aliyunWaf.DescribeDefaultHttpsRequest{
InstanceId: tea.String(d.config.InstanceId), InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region), RegionId: tea.String(d.config.Region),
} }
describeDefaultHttpsResp, err := d.sdkClient.DescribeDefaultHttps(describeDefaultHttpsReq) describeDefaultHttpsResp, err := d.sdkClient.DescribeDefaultHttps(describeDefaultHttpsReq)
if err != nil { if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'waf.DescribeDefaultHttps'") return nil, xerrors.Wrap(err, "failed to execute sdk request 'waf.DescribeDefaultHttps'")
} } else {
d.logger.Logt("已查询到默认 SSL/TLS 设置", describeDefaultHttpsResp)
}
d.logger.Logt("已查询到默认 SSL/TLS 设置", describeDefaultHttpsResp) // 修改默认 SSL/TLS 设置
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-modifydefaulthttps
modifyDefaultHttpsReq := &aliyunWaf.ModifyDefaultHttpsRequest{
InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region),
CertId: tea.String(upres.CertId),
TLSVersion: tea.String("tlsv1"),
EnableTLSv3: tea.Bool(false),
}
if describeDefaultHttpsResp.Body != nil && describeDefaultHttpsResp.Body.DefaultHttps != nil {
modifyDefaultHttpsReq.TLSVersion = describeDefaultHttpsResp.Body.DefaultHttps.TLSVersion
modifyDefaultHttpsReq.EnableTLSv3 = describeDefaultHttpsResp.Body.DefaultHttps.EnableTLSv3
}
modifyDefaultHttpsResp, err := d.sdkClient.ModifyDefaultHttps(modifyDefaultHttpsReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'waf.ModifyDefaultHttps'")
} else {
d.logger.Logt("已修改默认 SSL/TLS 设置", modifyDefaultHttpsResp)
}
} else {
// 指定接入域名
// 修改默认 SSL/TLS 设置 // 查询 CNAME 接入详情
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-modifydefaulthttps // REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-describedomaindetail
modifyDefaultHttpsReq := &aliyunWaf.ModifyDefaultHttpsRequest{ describeDomainDetailReq := &aliyunWaf.DescribeDomainDetailRequest{
InstanceId: tea.String(d.config.InstanceId), InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region), RegionId: tea.String(d.config.Region),
CertId: tea.String(upres.CertId), Domain: tea.String(d.config.Domain),
TLSVersion: describeDefaultHttpsResp.Body.DefaultHttps.TLSVersion, }
EnableTLSv3: describeDefaultHttpsResp.Body.DefaultHttps.EnableTLSv3, describeDomainDetailResp, err := d.sdkClient.DescribeDomainDetail(describeDomainDetailReq)
} if err != nil {
modifyDefaultHttpsResp, err := d.sdkClient.ModifyDefaultHttps(modifyDefaultHttpsReq) return nil, xerrors.Wrap(err, "failed to execute sdk request 'waf.DescribeDomainDetail'")
if err != nil { } else {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'waf.ModifyDefaultHttps'") d.logger.Logt("已查询到 CNAME 接入详情", describeDomainDetailResp)
} }
d.logger.Logt("已修改默认 SSL/TLS 设置", modifyDefaultHttpsResp) // 修改 CNAME 接入资源
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-modifydomain
modifyDomainReq := &aliyunWaf.ModifyDomainRequest{
InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region),
Domain: tea.String(d.config.Domain),
Listen: &aliyunWaf.ModifyDomainRequestListen{
CertId: tea.String(upres.CertId),
TLSVersion: tea.String("tlsv1"),
EnableTLSv3: tea.Bool(false),
},
Redirect: &aliyunWaf.ModifyDomainRequestRedirect{},
}
if describeDomainDetailResp.Body != nil && describeDomainDetailResp.Body.Listen != nil {
modifyDomainReq.Listen.TLSVersion = describeDomainDetailResp.Body.Listen.TLSVersion
modifyDomainReq.Listen.EnableTLSv3 = describeDomainDetailResp.Body.Listen.EnableTLSv3
modifyDomainReq.Listen.FocusHttps = describeDomainDetailResp.Body.Listen.FocusHttps
}
modifyDomainResp, err := d.sdkClient.ModifyDomain(modifyDomainReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'waf.ModifyDomain'")
} else {
d.logger.Logt("已修改 CNAME 接入资源", modifyDomainResp)
}
}
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }

View File

@ -104,19 +104,22 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
ServiceID: d.config.ServiceId, ServiceID: d.config.ServiceId,
}, },
UpdateHTTPSBody: &veImageX.UpdateHTTPSBody{ UpdateHTTPSBody: &veImageX.UpdateHTTPSBody{
Domain: getDomainConfigResp.Result.Domain, Domain: d.config.Domain,
HTTPS: &veImageX.UpdateHTTPSBodyHTTPS{ HTTPS: &veImageX.UpdateHTTPSBodyHTTPS{
CertID: upres.CertId, CertID: upres.CertId,
EnableHTTP2: getDomainConfigResp.Result.HTTPSConfig.EnableHTTP2, EnableHTTPS: true,
EnableHTTPS: getDomainConfigResp.Result.HTTPSConfig.EnableHTTPS,
EnableOcsp: getDomainConfigResp.Result.HTTPSConfig.EnableOcsp,
TLSVersions: getDomainConfigResp.Result.HTTPSConfig.TLSVersions,
EnableForceRedirect: getDomainConfigResp.Result.HTTPSConfig.EnableForceRedirect,
ForceRedirectType: getDomainConfigResp.Result.HTTPSConfig.ForceRedirectType,
ForceRedirectCode: getDomainConfigResp.Result.HTTPSConfig.ForceRedirectCode,
}, },
}, },
} }
if getDomainConfigResp.Result != nil && getDomainConfigResp.Result.HTTPSConfig != nil {
updateHttpsReq.UpdateHTTPSBody.HTTPS.EnableHTTPS = getDomainConfigResp.Result.HTTPSConfig.EnableHTTPS
updateHttpsReq.UpdateHTTPSBody.HTTPS.EnableHTTP2 = getDomainConfigResp.Result.HTTPSConfig.EnableHTTP2
updateHttpsReq.UpdateHTTPSBody.HTTPS.EnableOcsp = getDomainConfigResp.Result.HTTPSConfig.EnableOcsp
updateHttpsReq.UpdateHTTPSBody.HTTPS.TLSVersions = getDomainConfigResp.Result.HTTPSConfig.TLSVersions
updateHttpsReq.UpdateHTTPSBody.HTTPS.EnableForceRedirect = getDomainConfigResp.Result.HTTPSConfig.EnableForceRedirect
updateHttpsReq.UpdateHTTPSBody.HTTPS.ForceRedirectType = getDomainConfigResp.Result.HTTPSConfig.ForceRedirectType
updateHttpsReq.UpdateHTTPSBody.HTTPS.ForceRedirectCode = getDomainConfigResp.Result.HTTPSConfig.ForceRedirectCode
}
updateHttpsResp, err := d.sdkClient.UpdateHTTPS(context.TODO(), updateHttpsReq) updateHttpsResp, err := d.sdkClient.UpdateHTTPS(context.TODO(), updateHttpsReq)
if err != nil { if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'imagex.UpdateHttps'") return nil, xerrors.Wrap(err, "failed to execute sdk request 'imagex.UpdateHttps'")

View File

@ -3,9 +3,12 @@ import { Form, type FormInstance, Input } from "antd";
import { createSchemaFieldRule } from "antd-zod"; import { createSchemaFieldRule } from "antd-zod";
import { z } from "zod"; import { z } from "zod";
import { validDomainName } from "@/utils/validators";
type DeployNodeConfigFormAliyunWAFConfigFieldValues = Nullish<{ type DeployNodeConfigFormAliyunWAFConfigFieldValues = Nullish<{
region: string; region: string;
instanceId: string; instanceId: string;
domain?: string;
}>; }>;
export type DeployNodeConfigFormAliyunWAFConfigProps = { export type DeployNodeConfigFormAliyunWAFConfigProps = {
@ -39,6 +42,12 @@ const DeployNodeConfigFormAliyunWAFConfig = ({
.nonempty(t("workflow_node.deploy.form.aliyun_waf_instance_id.placeholder")) .nonempty(t("workflow_node.deploy.form.aliyun_waf_instance_id.placeholder"))
.max(64, t("common.errmsg.string_max", { max: 64 })) .max(64, t("common.errmsg.string_max", { max: 64 }))
.trim(), .trim(),
domain: z
.string()
.nullish()
.refine((v) => {
return !v || validDomainName(v!, { allowWildcard: true });
}, t("common.errmsg.domain_invalid")),
}); });
const formRule = createSchemaFieldRule(formSchema); const formRule = createSchemaFieldRule(formSchema);
@ -72,6 +81,15 @@ const DeployNodeConfigFormAliyunWAFConfig = ({
> >
<Input placeholder={t("workflow_node.deploy.form.aliyun_waf_instance_id.placeholder")} /> <Input placeholder={t("workflow_node.deploy.form.aliyun_waf_instance_id.placeholder")} />
</Form.Item> </Form.Item>
<Form.Item
name="domain"
label={t("workflow_node.deploy.form.aliyun_waf_domain.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.aliyun_waf_domain.tooltip") }}></span>}
>
<Input placeholder={t("workflow_node.deploy.form.aliyun_waf_domain.placeholder")} />
</Form.Item>
</Form> </Form>
); );
}; };

View File

@ -138,14 +138,14 @@ const DeployNodeConfigFormLocalConfig = ({ form: formInst, formName, disabled, i
switch (key) { switch (key) {
case "reload_nginx": case "reload_nginx":
{ {
formInst.setFieldValue("shellEnv", "sh"); formInst.setFieldValue("shellEnv", SHELLENV_SH);
formInst.setFieldValue("postCommand", "sudo service nginx reload"); formInst.setFieldValue("postCommand", "sudo service nginx reload");
} }
break; break;
case "binding_iis": case "binding_iis":
{ {
formInst.setFieldValue("shellEnv", "powershell"); formInst.setFieldValue("shellEnv", SHELLENV_POWERSHELL);
formInst.setFieldValue( formInst.setFieldValue(
"postCommand", "postCommand",
`# 请将以下变量替换为实际值 `# 请将以下变量替换为实际值
@ -182,7 +182,7 @@ Remove-Item -Path "$pfxPath" -Force
case "binding_netsh": case "binding_netsh":
{ {
formInst.setFieldValue("shellEnv", "powershell"); formInst.setFieldValue("shellEnv", SHELLENV_POWERSHELL);
formInst.setFieldValue( formInst.setFieldValue(
"postCommand", "postCommand",
`# 请将以下变量替换为实际值 `# 请将以下变量替换为实际值
@ -210,7 +210,7 @@ Remove-Item -Path "$pfxPath" -Force
break; break;
case "binding_rdp": case "binding_rdp":
{ {
formInst.setFieldValue("shellEnv", "powershell"); formInst.setFieldValue("shellEnv", SHELLENV_POWERSHELL);
formInst.setFieldValue( formInst.setFieldValue(
"postCommand", "postCommand",
`# 请将以下变量替换为实际值 `# 请将以下变量替换为实际值

View File

@ -202,6 +202,9 @@
"workflow_node.deploy.form.aliyun_waf_instance_id.label": "Alibaba Cloud WAF instance ID", "workflow_node.deploy.form.aliyun_waf_instance_id.label": "Alibaba Cloud WAF instance ID",
"workflow_node.deploy.form.aliyun_waf_instance_id.placeholder": "Please enter Alibaba Cloud WAF instance ID", "workflow_node.deploy.form.aliyun_waf_instance_id.placeholder": "Please enter Alibaba Cloud WAF instance ID",
"workflow_node.deploy.form.aliyun_waf_instance_id.tooltip": "For more information, see <a href=\"https://waf.console.aliyun.com\" target=\"_blank\">https://waf.console.aliyun.com</a>", "workflow_node.deploy.form.aliyun_waf_instance_id.tooltip": "For more information, see <a href=\"https://waf.console.aliyun.com\" target=\"_blank\">https://waf.console.aliyun.com</a>",
"workflow_node.deploy.form.aliyun_waf_domain.label": "Alibaba Cloud WAF domain (Optional)",
"workflow_node.deploy.form.aliyun_waf_domain.placeholder": "Please enter Alibaba Cloud WAF domain name",
"workflow_node.deploy.form.aliyun_waf_domain.tooltip": "For more information, see <a href=\"https://waf.console.aliyun.com\" target=\"_blank\">https://waf.console.aliyun.com</a>",
"workflow_node.deploy.form.aws_cloudfront_region.label": "AWS CloudFront Region", "workflow_node.deploy.form.aws_cloudfront_region.label": "AWS CloudFront Region",
"workflow_node.deploy.form.aws_cloudfront_region.placeholder": "Please enter AWS CloudFront region (e.g. us-east-1)", "workflow_node.deploy.form.aws_cloudfront_region.placeholder": "Please enter AWS CloudFront region (e.g. us-east-1)",
"workflow_node.deploy.form.aws_cloudfront_region.tooltip": "For more information, see <a href=\"https://docs.aws.amazon.com/en_us/general/latest/gr/rande.html#regional-endpoints\" target=\"_blank\">https://docs.aws.amazon.com/en_us/general/latest/gr/rande.html#regional-endpoints</a>", "workflow_node.deploy.form.aws_cloudfront_region.tooltip": "For more information, see <a href=\"https://docs.aws.amazon.com/en_us/general/latest/gr/rande.html#regional-endpoints\" target=\"_blank\">https://docs.aws.amazon.com/en_us/general/latest/gr/rande.html#regional-endpoints</a>",

View File

@ -201,7 +201,10 @@
"workflow_node.deploy.form.aliyun_waf_region.tooltip": "这是什么?请参阅 <a href=\"https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-endpoint\" target=\"_blank\">https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-endpoint</a>", "workflow_node.deploy.form.aliyun_waf_region.tooltip": "这是什么?请参阅 <a href=\"https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-endpoint\" target=\"_blank\">https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-endpoint</a>",
"workflow_node.deploy.form.aliyun_waf_instance_id.label": "阿里云 WAF 实例 ID", "workflow_node.deploy.form.aliyun_waf_instance_id.label": "阿里云 WAF 实例 ID",
"workflow_node.deploy.form.aliyun_waf_instance_id.placeholder": "请输入阿里云 WAF 实例 ID", "workflow_node.deploy.form.aliyun_waf_instance_id.placeholder": "请输入阿里云 WAF 实例 ID",
"workflow_node.deploy.form.aliyun_waf_instance_id.tooltip": "这是什么?请参阅 <a href=\"https://waf.console.aliyun.com\" target=\"_blank\">https://waf.console.aliyun.com</a>", "workflow_node.deploy.form.aliyun_waf_instance_id.tooltip": "这是什么?请参阅 <a href=\"https://waf.console.aliyun.com\" target=\"_blank\">https://waf.console.aliyun.com</a><br><br>仅支持 CNAME 接入。",
"workflow_node.deploy.form.aliyun_waf_domain.label": "阿里云 WAF 接入域名(可选)",
"workflow_node.deploy.form.aliyun_waf_domain.placeholder": "请输入阿里云 WAF 接入域名(支持泛域名)",
"workflow_node.deploy.form.aliyun_waf_domain.tooltip": "这是什么?请参阅 <a href=\"https://waf.console.aliyun.com\" target=\"_blank\">waf.console.aliyun.com</a><br><br>不填写时,将替换实例的默认证书。",
"workflow_node.deploy.form.aws_cloudfront_region.label": "AWS CloudFront 服务区域", "workflow_node.deploy.form.aws_cloudfront_region.label": "AWS CloudFront 服务区域",
"workflow_node.deploy.form.aws_cloudfront_region.placeholder": "请输入 AWS CloudFront 服务区域例如us-east-1", "workflow_node.deploy.form.aws_cloudfront_region.placeholder": "请输入 AWS CloudFront 服务区域例如us-east-1",
"workflow_node.deploy.form.aws_cloudfront_region.tooltip": "这是什么?请参阅 <a href=\"https://docs.aws.amazon.com/zh_cn/general/latest/gr/rande.html#regional-endpoints\" tworkflow_node.applyank\">https://docs.aws.amazon.com/zh_cn/general/latest/gr/rande.html#regional-endpoints</a>", "workflow_node.deploy.form.aws_cloudfront_region.tooltip": "这是什么?请参阅 <a href=\"https://docs.aws.amazon.com/zh_cn/general/latest/gr/rande.html#regional-endpoints\" tworkflow_node.applyank\">https://docs.aws.amazon.com/zh_cn/general/latest/gr/rande.html#regional-endpoints</a>",