From 664d8b943495b3b6c7d95d04cba73687598f2278 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Fri, 14 Nov 2025 18:54:40 +0800 Subject: [PATCH 1/2] feat(provider): new acme dns-01 provider: 35cn --- internal/certapply/applicators/sp_35cn.go | 28 +++ internal/domain/access.go | 5 + internal/domain/provider.go | 2 + .../acme-dns01/providers/35cn/35cn.go | 39 +++ .../providers/35cn/internal/client.go | 230 ++++++++++++++++++ .../providers/35cn/internal/lego.go | 156 ++++++++++++ ui/public/imgs/providers/35cn.png | Bin 0 -> 9054 bytes .../forms/AccessConfigFieldsProvider.tsx | 2 + .../forms/AccessConfigFieldsProvider35cn.tsx | 64 +++++ ui/src/domain/provider.ts | 6 +- ui/src/i18n/locales/en/nls.access.json | 14 +- ui/src/i18n/locales/en/nls.provider.json | 1 + .../i18n/locales/en/nls.workflow.nodes.json | 106 ++++---- ui/src/i18n/locales/zh/nls.access.json | 14 +- ui/src/i18n/locales/zh/nls.provider.json | 1 + .../i18n/locales/zh/nls.workflow.nodes.json | 116 ++++----- 16 files changed, 664 insertions(+), 120 deletions(-) create mode 100644 internal/certapply/applicators/sp_35cn.go create mode 100644 pkg/core/ssl-applicator/acme-dns01/providers/35cn/35cn.go create mode 100644 pkg/core/ssl-applicator/acme-dns01/providers/35cn/internal/client.go create mode 100644 pkg/core/ssl-applicator/acme-dns01/providers/35cn/internal/lego.go create mode 100644 ui/public/imgs/providers/35cn.png create mode 100644 ui/src/components/access/forms/AccessConfigFieldsProvider35cn.tsx diff --git a/internal/certapply/applicators/sp_35cn.go b/internal/certapply/applicators/sp_35cn.go new file mode 100644 index 000000000..911eb4eb3 --- /dev/null +++ b/internal/certapply/applicators/sp_35cn.go @@ -0,0 +1,28 @@ +package applicators + +import ( + "fmt" + + "github.com/go-acme/lego/v4/challenge" + + "github.com/certimate-go/certimate/internal/domain" + west35cn "github.com/certimate-go/certimate/pkg/core/ssl-applicator/acme-dns01/providers/35cn" + xmaps "github.com/certimate-go/certimate/pkg/utils/maps" +) + +func init() { + ACMEDns01Registries.MustRegister(domain.ACMEDns01ProviderType35cn, func(options *ProviderFactoryOptions) (challenge.Provider, error) { + credentials := domain.AccessConfigFor35cn{} + if err := xmaps.Populate(options.ProviderAccessConfig, &credentials); err != nil { + return nil, fmt.Errorf("failed to populate provider access config: %w", err) + } + + provider, err := west35cn.NewChallengeProvider(&west35cn.ChallengeProviderConfig{ + Username: credentials.Username, + ApiPassword: credentials.ApiPassword, + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, + }) + return provider, err + }) +} diff --git a/internal/domain/access.go b/internal/domain/access.go index 14d95276c..f28c116de 100644 --- a/internal/domain/access.go +++ b/internal/domain/access.go @@ -22,6 +22,11 @@ type AccessConfigFor1Panel struct { AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"` } +type AccessConfigFor35cn struct { + Username string `json:"username"` + ApiPassword string `json:"apiPassword"` +} + type AccessConfigForACMEExternalAccountBinding struct { EabKid string `json:"eabKid,omitempty"` EabHmacKey string `json:"eabHmacKey,omitempty"` diff --git a/internal/domain/provider.go b/internal/domain/provider.go index 12fed51a2..81b641372 100644 --- a/internal/domain/provider.go +++ b/internal/domain/provider.go @@ -10,6 +10,7 @@ NOTICE: If you add new constant, please keep ASCII order. */ const ( AccessProviderType1Panel = AccessProviderType("1panel") + AccessProviderType35cn = AccessProviderType("35cn") AccessProviderTypeACMECA = AccessProviderType("acmeca") AccessProviderTypeACMEDNS = AccessProviderType("acmedns") AccessProviderTypeACMEHttpReq = AccessProviderType("acmehttpreq") @@ -141,6 +142,7 @@ ACME DNS-01 提供商常量值。 NOTICE: If you add new constant, please keep ASCII order. */ const ( + ACMEDns01ProviderType35cn = ACMEDns01ProviderType(AccessProviderType35cn) ACMEDns01ProviderTypeACMEDNS = ACMEDns01ProviderType(AccessProviderTypeACMEDNS) ACMEDns01ProviderTypeACMEHttpReq = ACMEDns01ProviderType(AccessProviderTypeACMEHttpReq) ACMEDns01ProviderTypeAkamai = ACMEDns01ProviderType(AccessProviderTypeAkamai) // 兼容旧值,等同于 [ACMEDns01ProviderTypeAkamaiEdgeDNS] diff --git a/pkg/core/ssl-applicator/acme-dns01/providers/35cn/35cn.go b/pkg/core/ssl-applicator/acme-dns01/providers/35cn/35cn.go new file mode 100644 index 000000000..1c7346448 --- /dev/null +++ b/pkg/core/ssl-applicator/acme-dns01/providers/35cn/35cn.go @@ -0,0 +1,39 @@ +package west35cn + +import ( + "errors" + "time" + + "github.com/certimate-go/certimate/pkg/core" + "github.com/certimate-go/certimate/pkg/core/ssl-applicator/acme-dns01/providers/35cn/internal" +) + +type ChallengeProviderConfig struct { + Username string `json:"username"` + ApiPassword string `json:"apiPassword"` + DnsPropagationTimeout int `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int `json:"dnsTTL,omitempty"` +} + +func NewChallengeProvider(config *ChallengeProviderConfig) (core.ACMEChallenger, error) { + if config == nil { + return nil, errors.New("the configuration of the acme challenge provider is nil") + } + + providerConfig := internal.NewDefaultConfig() + providerConfig.Username = config.Username + providerConfig.Password = config.ApiPassword + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = config.DnsTTL + } + + provider, err := internal.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/pkg/core/ssl-applicator/acme-dns01/providers/35cn/internal/client.go b/pkg/core/ssl-applicator/acme-dns01/providers/35cn/internal/client.go new file mode 100644 index 000000000..f6f29258a --- /dev/null +++ b/pkg/core/ssl-applicator/acme-dns01/providers/35cn/internal/client.go @@ -0,0 +1,230 @@ +package internal + +import ( + "bytes" + "context" + "crypto/md5" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strconv" + "strings" + "time" + + querystring "github.com/google/go-querystring/query" + "golang.org/x/text/encoding" + "golang.org/x/text/encoding/simplifiedchinese" + "golang.org/x/text/transform" +) + +// This is a modified fork of https://github.com/go-acme/lego/blob/master/providers/dns/westcn/internal/client.go +// It only changes the base URL. +type DnsClient struct { + username string + password string + + encoder *encoding.Encoder + + baseURL *url.URL + HTTPClient *http.Client +} + +func NewDnsClient(username, password string) (*DnsClient, error) { + if username == "" || password == "" { + return nil, errors.New("35cn: credentials missing") + } + + baseURL, _ := url.Parse("https://api.35.cn/api/v2") + + return &DnsClient{ + username: username, + password: password, + encoder: simplifiedchinese.GBK.NewEncoder(), + baseURL: baseURL, + HTTPClient: &http.Client{}, + }, nil +} + +type DnsAPIResponse[T any] struct { + Result int `json:"result,omitempty"` + ClientID string `json:"clientid,omitempty"` + Message string `json:"msg,omitempty"` + ErrorCode int `json:"errcode,omitempty"` + Data T `json:"data,omitempty"` +} + +func (a DnsAPIResponse[T]) Error() string { + return fmt.Sprintf("%d: %s (%d)", a.ErrorCode, a.Message, a.Result) +} + +type DnsRecord struct { + Domain string `url:"domain,omitempty"` + Host string `url:"host,omitempty"` + Type string `url:"type,omitempty"` + Value string `url:"value,omitempty"` + TTL int `url:"ttl,omitempty"` // 60~86400 seconds + Priority int `url:"level,omitempty"` +} + +type DnsRecordID struct { + ID int `json:"id,omitempty"` +} + +func (c *DnsClient) AddRecord(ctx context.Context, record DnsRecord) (int, error) { + values, err := querystring.Values(record) + if err != nil { + return 0, err + } + + req, err := c.newRequest(ctx, "domain", "adddnsrecord", values) + if err != nil { + return 0, err + } + + results := &DnsAPIResponse[DnsRecordID]{} + + err = c.doRequest(req, results) + if err != nil { + return 0, err + } + + if results.Result != http.StatusOK { + return 0, results + } + + return results.Data.ID, nil +} + +func (c *DnsClient) DeleteRecord(ctx context.Context, domain string, recordID int) error { + values := url.Values{} + values.Set("domain", domain) + values.Set("id", strconv.Itoa(recordID)) + + req, err := c.newRequest(ctx, "domain", "deldnsrecord", values) + if err != nil { + return err + } + + results := &DnsAPIResponse[any]{} + + err = c.doRequest(req, results) + if err != nil { + return err + } + + if results.Result != http.StatusOK { + return results + } + + return nil +} + +func (c *DnsClient) newRequest(ctx context.Context, p, act string, form url.Values) (*http.Request, error) { + if form == nil { + form = url.Values{} + } + + c.sign(form, time.Now()) + + values, err := c.convertURLValues(form) + if err != nil { + return nil, err + } + + endpoint := c.baseURL.JoinPath(p, "/") + + query := endpoint.Query() + query.Set("act", act) + endpoint.RawQuery = query.Encode() + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), strings.NewReader(values.Encode())) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + + return req, nil +} + +func (c *DnsClient) doRequest(req *http.Request, result any) error { + resp, err := c.HTTPClient.Do(req) + if err != nil { + return err + } + + defer func() { _ = resp.Body.Close() }() + + if resp.StatusCode != http.StatusOK { + return c.parseHttpError(req, resp) + } + + if result == nil { + return nil + } + + raw, err := io.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("35cn: %w", err) + } + + err = c.newGBKDecoder(raw).Decode(result) + if err != nil { + return fmt.Errorf("35cn: %w", err) + } + + return nil +} + +func (c *DnsClient) sign(form url.Values, now time.Time) { + timestamp := strconv.FormatInt(now.UnixMilli(), 10) + + sum := md5.Sum([]byte(c.username + c.password + timestamp)) + + form.Set("token", hex.EncodeToString(sum[:])) + form.Set("username", c.username) + form.Set("time", timestamp) +} + +func (c *DnsClient) convertURLValues(values url.Values) (url.Values, error) { + results := make(url.Values) + + for key, vs := range values { + encKey, err := c.encoder.String(key) + if err != nil { + return nil, err + } + + for _, value := range vs { + encValue, err := c.encoder.String(value) + if err != nil { + return nil, err + } + + results.Add(encKey, encValue) + } + } + + return results, nil +} + +func (c *DnsClient) parseHttpError(req *http.Request, resp *http.Response) error { + raw, _ := io.ReadAll(resp.Body) + + result := &DnsAPIResponse[any]{} + + err := c.newGBKDecoder(raw).Decode(result) + if err != nil { + return fmt.Errorf("35cn: %w", err) + } + + return result +} + +func (c *DnsClient) newGBKDecoder(raw []byte) *json.Decoder { + return json.NewDecoder(transform.NewReader(bytes.NewBuffer(raw), simplifiedchinese.GBK.NewDecoder())) +} diff --git a/pkg/core/ssl-applicator/acme-dns01/providers/35cn/internal/lego.go b/pkg/core/ssl-applicator/acme-dns01/providers/35cn/internal/lego.go new file mode 100644 index 000000000..c4f8a8071 --- /dev/null +++ b/pkg/core/ssl-applicator/acme-dns01/providers/35cn/internal/lego.go @@ -0,0 +1,156 @@ +package internal + +import ( + "context" + "errors" + "fmt" + "net/http" + "sync" + "time" + + "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v4/challenge/dns01" + "github.com/go-acme/lego/v4/platform/config/env" +) + +const ( + envNamespace = "35CN_" + + EnvUsername = envNamespace + "USERNAME" + EnvPassword = envNamespace + "PASSWORD" + + EnvTTL = envNamespace + "TTL" + EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT" + EnvPollingInterval = envNamespace + "POLLING_INTERVAL" + EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT" +) + +var _ challenge.ProviderTimeout = (*DNSProvider)(nil) + +type Config struct { + Username string + Password string + + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt(EnvTTL, 60), + PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute), + PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, 10*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second), + }, + } +} + +type DNSProvider struct { + config *Config + client *DnsClient + + recordIDs map[string]int + recordIDsMu sync.Mutex +} + +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get(EnvUsername, EnvPassword) + if err != nil { + return nil, fmt.Errorf("35cn: %w", err) + } + + config := NewDefaultConfig() + config.Username = values[EnvUsername] + config.Password = values[EnvPassword] + + return NewDNSProviderConfig(config) +} + +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("35cn: the configuration of the DNS provider is nil") + } + + client, err := NewDnsClient(config.Username, config.Password) + if err != nil { + return nil, fmt.Errorf("35cn: %w", err) + } + + if config.HTTPClient != nil { + client.HTTPClient = config.HTTPClient + } + + return &DNSProvider{ + config: config, + client: client, + recordIDs: make(map[string]int), + }, nil +} + +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + if err != nil { + return fmt.Errorf("35cn: could not find zone for domain %q: %w", domain, err) + } + + subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, authZone) + if err != nil { + return fmt.Errorf("35cn: %w", err) + } + + record := DnsRecord{ + Domain: dns01.UnFqdn(authZone), + Host: subDomain, + Type: "TXT", + Value: info.Value, + TTL: d.config.TTL, + } + + recordID, err := d.client.AddRecord(context.Background(), record) + if err != nil { + return fmt.Errorf("35cn: error when create record: %w", err) + } + + d.recordIDsMu.Lock() + d.recordIDs[token] = recordID + d.recordIDsMu.Unlock() + + return nil +} + +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + if err != nil { + return fmt.Errorf("35cn: could not find zone for domain %q: %w", domain, err) + } + + d.recordIDsMu.Lock() + recordID, ok := d.recordIDs[token] + d.recordIDsMu.Unlock() + + if !ok { + return fmt.Errorf("35cn: unknown record ID for '%s' '%s'", info.EffectiveFQDN, token) + } + + err = d.client.DeleteRecord(context.Background(), dns01.UnFqdn(authZone), recordID) + if err != nil { + return fmt.Errorf("35cn: error when delete record: %w", err) + } + + d.recordIDsMu.Lock() + delete(d.recordIDs, token) + d.recordIDsMu.Unlock() + + return nil +} + +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/ui/public/imgs/providers/35cn.png b/ui/public/imgs/providers/35cn.png new file mode 100644 index 0000000000000000000000000000000000000000..a9268dfe1b7e5e9351e3c63ac463ddca151c9fe9 GIT binary patch literal 9054 zcmb_?RaYEL(=7xDE&+lBcXtmif#B}0!GgO7*WeP|A-D|g4#C~sT?ZIum^sgTe#6(b zcI~RVsqS8VQERV`QB#q_MEimU2M32K|6NAoKOX-dP!Rs}*^wqS{}HjrH$4wcXB!W1 zb2n=^Nh@ayYfAZ_=0B`8tj(=_T_>zX;NTG8)ReTok?0@NnC$CCp7Plpd1jx{njeH$ zoL3J#UOz%;&9>csI#3&JEpETETJN8qp28ro(yk}}qU*f2C+Hg#0)r{~Zr%gmsfj-S zNI8qDd@zqY6|mieLf=RYxBmbxwN;crP>_h*5e)XM9eDBzf*xFf0aFi*#s{4XuTmZd zYb(q6XsEob%+=+kj21i9!`BcfWP0;$VISN%eGh^`o5ru7z>nk>n;ory=hyeghlj!C zr_Dpi#WiGV9|8is!CjKQ~u>brH-8_Cw zjE|A_J$Qq_pwRo|+D8cV1_T3My}S?3gMJlUpWMAuo1a79K_BHdKI?A_yKDkMuXW>( z{WDK@AZTLs6^+U1Ef92h|J*h8wtoqHgMr7FLDd7VKN4;f{m!M`&au=tX^d81U@&>l zLo%b)q1C&_;Ws>$Eim|PWCO_VuyuQR0fD~EPE9V&&u*MOQ=6}v>gkSdgPF~apJ6Yc zXQ0H-)4kI-NkM)lqf@8!Yf7yH6_3-~`*)M@tA^^T{G6k5@wd_2KCYrQSB7+M$B?6NA+nuIB3D!M?49*(><@1qLS5 zS_6T>^tS(P?B(y&gS?bP-Siu()^T4~=gT8>_x_#MXqJVF;`SbtKL8va=;O0I)(pJe z-P%Y?`b};)OJlwF&HEJe4tWJbq2PONiyh`4C#+^G6xtVMeXlJIb?syKFenW6-!=aa z?=aXq^uGoBF983SL!prWlK*e-(EnAybn2%9&KD(x1)O%P5h20cj`OEapc63c;_Yea z1T;K#`dM#T@z=F~!BJ!X$;QFM^TS(nbK?iO*}2t+n9`$r80_&DbbEXIU(1CJnkzUs ziYIv)NiCm^s~mJAJl)<`o^bdm9J%pm5!{FnS$xYm0FxMAnbfZo+?J0cXa=98B_r0p z6rj|uEb#N!qG@f^)pyz-7O%)%I(1!oHSz<{TQ`-s{}4YI*tfm-8FqEG^=v+h;{_BZ zwEM%hyI$PI9}kDDzSHxZ`p?|@&Pc*R6Qe_r_a%LB$ix3{3FI8sZWI>q9qNpD-!9F8 z|Ltp@2?vDFXPcR@NXO7N7KqDE`h!U!RM;8qH#kQ-ydt`M=)ot}jG;ZC=+PvF8ab$+ zESFqhS#j}674v|J`68I^-7m#j|NDUzU3=!U?_P&yItS**GL0?NGm-#Y5lA@?Y`?`?cNorx6tp~>@_z2=i)fOYTPzKn4ATP>j^l)!UEoCXpIIb`->b;aQ zWKGi{4*~3O3cUCkZw|C`%q9|1q@b60nS{_DjwMF>?zM;>&cd)HRA$8|*F=ki7vUpO z-`@Si)yfP|LPP9tmM?n{y%pM{b3SyGy8T7V$1(2-UzP5C*r!l2CW42TH4+a;#0~7= z@JMK`9Di4ZyLWjKi+!X8jAAt7!p+e~XZI-RUOH+-s&2B&o#G@b>hc zeW#+oBp6U$f9&^6^mf~Fhv6@yxoS~VggSQQQp1$rwqtcVC3QRG9n4uZs3}s>PZql zQhGd4^Os4k3Z2Wul|3kA=TwFGW5|Ws+9r0M%f$!4Z^PPK@#|pp>_DZdnHu#($PvGk z#+(!-awR#p-9zY*cCt3`zF@2lU>l~E$I7hZw-G{N;P-a11Qa+ruUM@w06r}NoAZ|< zJ3!BbzinKVd-*5{pC#Bxg3V_u^Gt8L=WahV?c{(|;ZTVyn?24T(c*zxC3q-^Bcr;R zJphivQwhj4NM=4qkpi8L{Kx6tk0C^u_UvtULMTail;s{t3BA&M80u+< zI&t4A@H+P|5x1K{(NTaDhHXMy@gPnLT38eYaa#4ko8jlr_(IY4jT)gV!V^EJhxyBv ztrh?PMzuzlM`ZB#4x}$alU1lESAeH4a>y21*;AFpLsSNGRABEemOr0*6Je@hPcMiQ?u&h=Kpz_d|?22kIf{r2{hTe;uwd{Zpl#O=GMLQk*% zh&ikY@vWpgI=%irlBJsza9x%WBkcxe=Djb(BSg9MX=z_$BTLPP|C^?lIptp_;wqCW zb){saPc>(vxy-1dLZ10GwN;?c$j!`!!Bs+J<1~Qt=>$iW4tZ3&AkO7Q1$23No6rR~ z^+KQh^4b0T7h!&ZOBzDBAMi~L4H@=4Fz__B(L`Rv+1%J;A7Ood=uCprV%o*oC?epz zIMTh}F_B7~8T*8x|9*C-+;QH~F%;DXUAe^^-(|NL`o#&)_oSmqLL!5<^efj6XL-r? zE56NitMMaic&67OzNA|9g{BpnVdB-LMVGP8;);%u(U#64r&mb*gO3q;=#8kG8$FNt zDH#?E{<>f^MkAyy(zovsqg?K4R3@24c!3^ zJ(1!gd<7w^eNVuNPf_9BCEnPg&Ih6)Gp+W?Xx6ew+Pt}S$FFj;BVnt!0+zBl6IEbK z|FVC`mMGs|$9L&BahAgK6(<8*8oRr@8@sEks{>w}kNT4?xP1cD0`vV}rLy1_oDc89 zL^~ zC|XPpMp~+(&J?S$7s@-LatrKKsZcXp8+C+xp7w8C+1iX)Ha!@R(if#7CpC zP|X+j+BroJ7NV!^3$VZbDPN*`?AC|yo3(>@^fnEhu&HUL53A7Y$W*y)l2>P{9G?nh zW&ZwC>_5M%az%u2c*nD*%`a(aCAEi2{_y>5Pq8X^765)g)+bhHwqvU}t?2<5N>3{ZslbY5AExDNTXGOSjVcy=}8Ut+EO3OmZfw9YcK|Qv+;6F zstUCLnj=Yz{Lj&xH8j`EspSvysuc;tcvoImM0 z2}AMryuQ+m>5{6KLw;<*K(CLhlT4&1J#Vr9801t9vlujqJWW}u6l?YN=@uhNVFB?FZMp2X0ITu->d)a*vz7K z)KSxZZc_b{i0C)Efgw(mMogZ3Zt1c;L&l^5XW6UQ?n5fj02%YLdTW)8_@3bT2T-JFd@v{CJS)Obmk+ND@ zN(X!9)?@lwQ?O0H9M*RdWAeLyQ5@YLOvc|njjIcIv}5OrizD@WbY@pN^Zfa&;Qli3 zjj}R|hTO1@t0lT-bowy_kCl;djg#i&tRWlm7|(spk`FCn-6nEIc0Q$-&_}-SlKn;( zEs);n&Sm{2_ubc4HA>IYQ5}s2owgMIB<@OB$v7YfBTP)$91k`co6T9WTyrHK7mzUr zHIl+<&+ISLz-A0BGoM#_PG1ea^0#!`3nM2D4q|la2t4|ia;ShPX`NRq_!3wJq&f2@f!nu~S(j}g5lC6RsoEwXxX zmd3<-xW(aA^{0qv{lDQ%pW@lVLVbD~Fr9+ydBqDRe9BwZDD9iqc~^R$t#`G@A2o9V z1@%(v77Ni{?+&Ec%W9ITVzDshKi|F;F3h^niD1=YYxrz^E3}=s-gklIM_GD_!ENnD zW!=;CW_=Jr^!Zv$v_B^yoePJynuKQdNt%G6+ZOuj9NBr~lzU@IUK@(>;%JlEBDkbw}xgP@Y;@^ek~upZ%`i=!(mN8P-Z zVGFbphOOy|t`i9GwNV!PwcFpwz32sfFR+pxZ$-s#kpFw$d#|FV5I8^72KsuOR^@Pd zofHh^{*5T3rRe_h5<_Y{IK*Ug#`qMr2B6pe8gmf}6x9>)#5XJ~32G8qB!nC0cMmWJ z%GX|Zsil5Yr!GJX)>rsjgclv8-7dX$*#2*M0k@0UV=!=@SD zfRCOixb#MOuDj#yM-Ds}GXz4!ZM2r#1KiDLP1^dYLL3N{4`uL)i=sTG`g`Vj+L$$N zV?Wq_6(mU@MVfpCk`_u)e!%t{@ii1H!bMY-bugEk?|Z=a|8iPW6x#MaK$9`pM*RMxeB;c`6_~zp4>77?)&k@a={obKwK~3Q1ZNJoiZqsj9yx2{-l~V@83ZYlU-Y4 zwa-9%o;X^xerC|?8j_1>bcdEqNP6wq2=x-xrBSLh5_5Zq;6v_sdHW|E5+u%N0$D4D zWwgRyB}9n6-uue`q_0f9!SOqHv)K~-Qeh6$C5wT`|2oL5*hvL|LWnnp?6&QkNX9MAA zDPC@pMt|b-HYFiTA~8~NGw2#ZyFAMPa0Q|2CNgp=yAGHB=tSdU|HGR-lB!e6C!`b` zxi1Yjqk%}~^)P_`>_ynR=84HbZ85O0>&yT!fU~&{{WNRNeX6`Xqd(tL_K~2S!R^N! zT;})gAk_0&m9`w5oTl4mKJ2IdGBam7+t1Lt zv+7#NcdUsp-5kO$ADU)-2P+j9Z>v6Tql5oe zSBfS2*n{o3p4@~iBP~z;zK*PHRS<;r*=+L*c~AQGc$HENt4{y?e1^kLXBVGsl++_$ zxAObXbmd>RAXBmFe!*fb>JeXecibGDW&};j)8d`{ttflWDF`O=f}+o0Xu~fsHu~(E znb_NWL2-WUb`N+&{xJoqL8PHbc@#6w4sB{Od{(=V+j4lkq9TF3N0?u%Shj+{s!NfUG96NFO-u%Tk`T9IpGO2@Do2_ncxDA>Zcj zD;5CYSxvnS@)3Z)bE{4QKf>4jPbF3Y*2+*58D8ejYK3e6)TfQ;F^(QXtIR%MzG6K@ zxtXG7Z9W5l**668ii)j2eyzG zg$Y%9?*U$%a*LeN8N^#-KWN8`S0r)DJ(n4HUa{e1F^rG`cgRi0Tw2+tD~}{6!^t7l z|H&C-QfGOlKpfMoq~5$jDuS>5CzOi0jeSGuKuoRD{&1V8%Y`;(?*jwqX( zeTX?7uE=-c`}6r2yHGa1=s);4%lW2gnRZ46)zvaQ{u}_uM5eWqa5vm_P zQovD|eBnF5DiIHUIztaxIh@q&squ3wZqTCyqu6Jt=x(i~{o&0lqJ0ZV%`WgAWalYh z41Ttxw#$)V*vM!t!g6F3UR<&gPZcJkzdSOQ2;c=`VT|d@kxwbJY!>lu%;j_MpU6?X zIdaU|zdIQeV-mTbDaEO70rVM1dB2=(XnGmP=X7Tkv&zhC=sj4oI^wSlACRlx95v77 z`Oii|4sR`Henil#wKo#aPV54X?Ke==aIi)6xdQkzeysQ>1; zm6b*MNw*=7HrHfzi~^4tcPi*;KwY1(PI0A@?r={Ofq?HuSKl_qNF|7mPwX!(7Z(bg!3Xt+w7N{_8; zMvB2UQcAeEtwxpw$l?lZe3lzxeglBwFaL2g&bqA>9MM$C* z2}6?Iw)hN$^+kl0LWR4?yMujiXw!-`MFdujkZAvaA^uxiu%Vb|LY*~Pyul}~7J0a=of9h zvs%}6mp3}=PJB*ED&E`sutX=1LcQW(K_82D$DXTo#3cn5ytyRGUpp%3c3W(c_ z#x*phecXXA+0`}X__$yietp7vq7m*(4|!jkps`0YFI*r((5k$nz~mQ~tzF^h*JXPh z@k_mW&*GcC z!{Xc9o4vP8w`+L9#)9`ZbG+O3ly!BVduF2Y#h(H3=K8I{6-E9H1W%nktjg6|M{Jf| zmbf{a>%&q6vE(xC%U-MhsW;qCWj(K#7Jq8m+Z!4_zv|<3$?LFIHeUMS2SWhm<>hJ_ ze=tLTRGe&l&gA3ci*7GD+!Dh7yvei6h%|2ByeG2TE<%>B6iW zvNvMBc}z>rImLC1m1N?7!vhZzy`sitXq997?6G1&10UB zaG>fmIACgjhAmNrl*ely%9XkbN$`q@KVMDQYd~z3O@(sZDYqb@F@qDmiZocSH_zVxGjFJ8*vx_xCtSc%MRrvGEXpQd z6uk!r!gANX#o}vyl5^YLC)Lh&arFyfb61E{mNM#*a)B;A;Y3X+NBE&jyMJ-d^9D6siL!+^G|hV z{&Zr5K;Jkn>nQ15^1k38t3NfKQ=y-bdHg)Fp7zwKwh8P7XD4B2_M`n&h*N zq&L_jY3zKOF#>38ZG3K)a@QNcq<>sk($Ursc!EiSIXMf1Mjk znPG?84SGsM-AE3282zTo9YbN?%h-W86T7l<&TBZL(X2i+o7Bh-k?0;aGPF`S?r~=V zyYbdW@Ws*kn;UH?)U4T+UmuGR`UD8;;R~J zq9n48j%pF-*SoDz%#g2?$>Y0!p0BpdrQF{dUuO<-}`wM^u)4PTIyc) zr$NyfS~lG!4s#p|b!Na?p_q4`LL*(!F`53I$1Bikibk;9fs+1DS>BaTuP9BswnQi4 zr-(XtDm{iDNVr$~(X+E|cs#6@?o(`jif6nDu2m%$xBEilerufky=wx$zR5yUX{o+} z4tC&c111G4Q4KsEA!}AZaLZ2hXm!}WdoAPwI^FB>s>DS*hl^@3Tc(MS8>&P8RMD%n z7Zht%Vm(6hBZZ<~#i4pIEPQ~1Gh{oNAxPWDVlv}rUsZBCnaPA8T@_r`hLx$P&~`V| z#cJx8>R9GcUf0pZT3pyB-R97NE(hJK;0Nte2)B`n_Syut=KFx_q8M zXQ{!Rxg}kxGuomiZf(P~RP}7Gzb%rlPY3boW8nvu#K=0tw8Rw@;+$_6H*EwxuLqst zZBFM#JaW5`hn4tSB>DtdtCkIZ2JtGqxa*wJjFi$M}kVZBOWDp@)Wz2)d%l%@f#&&%+w1tff2dfZPCv*t*NUudqEutX`upP?xz%nUXJTcZeaXCR=cGNxR9ZmJkHecUTX41PePvVu;l=CgD9% zVD&V&vwy3*Vg1Pqxim1Kv$P3R(atz8SEs;4B}6>YQJGyIo9skq5Y%Q}-S+{p%`*@6 z;B^m=g507y+eH(4XTrkktpZ(wB_cOtB`!{Ae|5_80tXn~T)Pc;?{hHzV^U^Je^T8z z6e5Q8KP`~KG{<2-7_kS#?kGi2{x4}9_A?2_&=2PZ8aheEoPquKVFphAn~F@Glv(Ki E0|ZzyWB>pF literal 0 HcmV?d00001 diff --git a/ui/src/components/access/forms/AccessConfigFieldsProvider.tsx b/ui/src/components/access/forms/AccessConfigFieldsProvider.tsx index 1b31c8f10..3b03967e2 100644 --- a/ui/src/components/access/forms/AccessConfigFieldsProvider.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProvider.tsx @@ -3,6 +3,7 @@ import { ACCESS_PROVIDERS, type AccessProviderType } from "@/domain/provider"; import AccessConfigFieldsProvider1Panel from "./AccessConfigFieldsProvider1Panel"; +import AccessConfigFieldsProvider35cn from "./AccessConfigFieldsProvider35cn"; import AccessConfigFieldsProviderACMECA from "./AccessConfigFieldsProviderACMECA"; import AccessConfigFieldsProviderACMEDNS from "./AccessConfigFieldsProviderACMEDNS"; import AccessConfigFieldsProviderACMEHttpReq from "./AccessConfigFieldsProviderACMEHttpReq"; @@ -102,6 +103,7 @@ const providerComponentMap: Partial { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + > + + + + } + > + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + username: "", + apiPassword: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t } = i18n; + + return z.object({ + username: z.string().nonempty(t("access.form.35cn_username.placeholder")), + apiPassword: z.string().nonempty(t("access.form.35cn_api_password.placeholder")), + }); +}; + +const _default = Object.assign(AccessConfigFormFieldsProvider35cn, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/domain/provider.ts b/ui/src/domain/provider.ts index 3468ad37b..4fa6afba2 100644 --- a/ui/src/domain/provider.ts +++ b/ui/src/domain/provider.ts @@ -16,6 +16,7 @@ interface BaseProviderWithAccess

extends BaseProvider

{ */ export const ACCESS_PROVIDERS = Object.freeze({ ["1PANEL"]: "1panel", + ["35CN"]: "35cn", ACMECA: "acmeca", ACMEDNS: "acmedns", ACMEHTTPREQ: "acmehttpreq", @@ -212,6 +213,7 @@ export const accessProvidersMap: Map = new NOTICE: If you add new constant, please keep ASCII order. */ export const ACME_DNS01_PROVIDERS = Object.freeze({ + ["35CN"]: `${ACCESS_PROVIDERS["35CN"]}`, ACMEDNS: `${ACCESS_PROVIDERS.ACMEDNS}`, ACMEHTTPREQ: `${ACCESS_PROVIDERS.ACMEHTTPREQ}`, - AKAMAI: `${ACCESS_PROVIDERS.AKAMAI}`, // 兼容旧值,等同于 `AKAMAI_EDGEDNS` + AKAMAI: `${ACCESS_PROVIDERS.AKAMAI}`, // 兼容旧值,等同于 `AKAMAI_EDGEDNS` AKAMAI_EDGEDNS: `${ACCESS_PROVIDERS.AKAMAI}-edgedns`, ALIYUN: `${ACCESS_PROVIDERS.ALIYUN}`, // 兼容旧值,等同于 `ALIYUN_DNS` ALIYUN_DNS: `${ACCESS_PROVIDERS.ALIYUN}-dns`, @@ -436,6 +439,7 @@ export const acmeDns01ProvidersMap: Maphttps://docs.1panel.pro/dev_manual/api_manual/", + "access.form.35cn_username.label": "35.cn agent username", + "access.form.35cn_username.placeholder": "Please enter West.cn agent username", + "access.form.35cn_username.tooltip": "For more information, see https://www.35.com/agent/mode-api.asp", + "access.form.35cn_api_password.label": "35.cn agent API password", + "access.form.35cn_api_password.placeholder": "Please enter West.cn agent API password", + "access.form.35cn_api_password.tooltip": "For more information, see https://www.35.com/agent/mode-api.asp", "access.form.acmeca_endpoint.label": "Endpoint", "access.form.acmeca_endpoint.placeholder": "Please enter endpoint", "access.form.acmeca_endpoint.tooltip": "For more information, see https://datatracker.ietf.org/doc/html/rfc8555#section-7.1.1", @@ -627,11 +633,11 @@ "access.form.wecombot_webhook_url.label": "WeCom bot Webhook URL", "access.form.wecombot_webhook_url.placeholder": "Please enter WeCom bot Webhook URL", "access.form.wecombot_webhook_url.tooltip": "For more information, see https://open.work.weixin.qq.com/help2/pc/18401", - "access.form.westcn_username.label": "West.cn username", - "access.form.westcn_username.placeholder": "Please enter West.cn username", + "access.form.westcn_username.label": "West.cn agent username", + "access.form.westcn_username.placeholder": "Please enter West.cn agent username", "access.form.westcn_username.tooltip": "For more information, see https://www.west.cn/CustomerCenter/doc/apiv2.html", - "access.form.westcn_api_password.label": "West.cn API password", - "access.form.westcn_api_password.placeholder": "Please enter West.cn API password", + "access.form.westcn_api_password.label": "West.cn agent API password", + "access.form.westcn_api_password.placeholder": "Please enter West.cn agent API password", "access.form.westcn_api_password.tooltip": "For more information, see https://www.west.cn/CustomerCenter/doc/apiv2.html", "access.form.zerossl_eab.guide": "Learn more about using EAB key in ZeroSSL:
https://zerossl.com/documentation/acme/" } diff --git a/ui/src/i18n/locales/en/nls.provider.json b/ui/src/i18n/locales/en/nls.provider.json index 352dbbf60..cd4677e64 100644 --- a/ui/src/i18n/locales/en/nls.provider.json +++ b/ui/src/i18n/locales/en/nls.provider.json @@ -2,6 +2,7 @@ "provider.1panel": "1Panel", "provider.1panel.console": "1Panel - Console itself", "provider.1panel.site": "1Panel - Website", + "provider.35cn": "35.cn", "provider.acmeca": "ACME Custom CA Endpoint", "provider.acmedns": "ACME-DNS", "provider.acmehttpreq": "ACME Custom HTTP Endpoint", diff --git a/ui/src/i18n/locales/en/nls.workflow.nodes.json b/ui/src/i18n/locales/en/nls.workflow.nodes.json index 38712266b..a2f61aac3 100644 --- a/ui/src/i18n/locales/en/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/en/nls.workflow.nodes.json @@ -54,19 +54,19 @@ "workflow_node.apply.form.provider_access_dns01.placeholder": "Please select an credential of DNS provider", "workflow_node.apply.form.provider_access_http01.label": "Hosting provider credential", "workflow_node.apply.form.provider_access_http01.placeholder": "Please select an credential of hosting provider", - "workflow_node.apply.form.aliyun_esa_region.label": "Alibaba Cloud ESA region", + "workflow_node.apply.form.aliyun_esa_region.label": "Alibaba Cloud region", "workflow_node.apply.form.aliyun_esa_region.placeholder": "Please enter Alibaba Cloud ESA region (e.g. cn-hangzhou)", "workflow_node.apply.form.aliyun_esa_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/edge-security-acceleration/esa/api-esa-2024-09-10-endpoint", - "workflow_node.apply.form.aws_route53_region.label": "AWS Route53 Region", + "workflow_node.apply.form.aws_route53_region.label": "AWS Region", "workflow_node.apply.form.aws_route53_region.placeholder": "Please enter AWS Route53 region (e.g. us-east-1)", "workflow_node.apply.form.aws_route53_region.tooltip": "For more information, see https://docs.aws.amazon.com/en_us/general/latest/gr/rande.html#regional-endpoints", "workflow_node.apply.form.aws_route53_hosted_zone_id.label": "AWS Route53 hosted zone ID", "workflow_node.apply.form.aws_route53_hosted_zone_id.placeholder": "Please enter AWS Route53 hosted zone ID", "workflow_node.apply.form.aws_route53_hosted_zone_id.tooltip": "For more information, see https://docs.aws.amazon.com/en_us/Route53/latest/DeveloperGuide/hosted-zones-working-with.html", - "workflow_node.apply.form.huaweicloud_dns_region.label": "Huawei Cloud DNS region", + "workflow_node.apply.form.huaweicloud_dns_region.label": "Huawei Cloud region", "workflow_node.apply.form.huaweicloud_dns_region.placeholder": "Please enter Huawei Cloud DNS region (e.g. cn-north-1)", "workflow_node.apply.form.huaweicloud_dns_region.tooltip": "For more information, see https://console-intl.huaweicloud.com/apiexplorer/#/endpoint", - "workflow_node.apply.form.jdcloud_dns_region_id.label": "JD Cloud DNS region ID", + "workflow_node.apply.form.jdcloud_dns_region_id.label": "JD Cloud region ID", "workflow_node.apply.form.jdcloud_dns_region_id.placeholder": "Please enter JD Cloud DNS region ID (e.g. cn-north-1)", "workflow_node.apply.form.jdcloud_dns_region_id.tooltip": "For more information, see https://docs.jdcloud.com/en/common-declaration/api/introduction", "workflow_node.apply.form.local_webroot_path.label": "Web root path", @@ -204,7 +204,7 @@ "workflow_node.deploy.form.1panel_site_node_name.placeholder": "Please enter 1Panel node name", "workflow_node.deploy.form.1panel_site_node_name.help": "Notes: It is only used for 1Panel v2+.", "workflow_node.deploy.form.1panel_site_node_name.tooltip": "You can find it on 1Panel dashboard.", - "workflow_node.deploy.form.aliyun_alb_region.label": "Alibaba Cloud ALB region", + "workflow_node.deploy.form.aliyun_alb_region.label": "Alibaba Cloud region", "workflow_node.deploy.form.1panel_site_resource_type.label": "Resource type", "workflow_node.deploy.form.1panel_site_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.1panel_site_resource_type.option.website.label": "Website", @@ -234,7 +234,7 @@ "workflow_node.deploy.form.aliyun_apigw_service_type.placeholder": "Please select Alibaba Cloud API gateway type", "workflow_node.deploy.form.aliyun_apigw_service_type.option.cloudnative.label": "Cloud-native API gateway", "workflow_node.deploy.form.aliyun_apigw_service_type.option.traditional.label": "Traditional API gateway", - "workflow_node.deploy.form.aliyun_apigw_region.label": "Alibaba Cloud API gateway region", + "workflow_node.deploy.form.aliyun_apigw_region.label": "Alibaba Cloud region", "workflow_node.deploy.form.aliyun_apigw_region.placeholder": "Please enter Alibaba Cloud API gateway region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_apigw_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/api-gateway/cloud-native-api-gateway/product-overview/regions", "workflow_node.deploy.form.aliyun_apigw_gateway_id.label": "Alibaba Cloud API gateway ID", @@ -245,11 +245,11 @@ "workflow_node.deploy.form.aliyun_apigw_group_id.tooltip": "For more information, see https://apigateway.console.aliyun.com", "workflow_node.deploy.form.aliyun_apigw_domain.label": "Alibaba Cloud API gateway domain", "workflow_node.deploy.form.aliyun_apigw_domain.placeholder": "Please enter Alibaba Cloud API gateway domain", - "workflow_node.deploy.form.aliyun_cas_region.label": "Alibaba Cloud CAS region", + "workflow_node.deploy.form.aliyun_cas_region.label": "Alibaba Cloud region", "workflow_node.deploy.form.aliyun_cas_region.placeholder": "Please enter Alibaba Cloud CAS region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_cas_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/ssl-certificate/developer-reference/endpoints", "workflow_node.deploy.form.aliyun_casdeploy.guide": "TIPS: This will invoke Alibaba Cloud OpenAPI CreateDeploymentJob to create an asynchronously deployment task. You need to go to the Alibaba Cloud console to check the actual deployment results by yourself.", - "workflow_node.deploy.form.aliyun_casdeploy_region.label": "Alibaba Cloud CAS region", + "workflow_node.deploy.form.aliyun_casdeploy_region.label": "Alibaba Cloud region", "workflow_node.deploy.form.aliyun_casdeploy_region.placeholder": "Please enter Alibaba Cloud CAS region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_casdeploy_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/ssl-certificate/developer-reference/endpoints", "workflow_node.deploy.form.aliyun_casdeploy_resource_ids.label": "Alibaba Cloud resource IDs", @@ -266,7 +266,7 @@ "workflow_node.deploy.form.aliyun_casdeploy_contact_ids.tooltip": "For more information, see https://www.alibabacloud.com/help/en/ssl-certificate/developer-reference/api-cas-2020-04-07-listcontact", "workflow_node.deploy.form.aliyun_casdeploy_contact_ids.multiple_input_modal.title": "Change Alibaba Cloud contact IDs", "workflow_node.deploy.form.aliyun_casdeploy_contact_ids.multiple_input_modal.placeholder": "Please enter Alibaba Cloud contact ID", - "workflow_node.deploy.form.aliyun_clb_region.label": "Alibaba Cloud CLB region", + "workflow_node.deploy.form.aliyun_clb_region.label": "Alibaba Cloud region", "workflow_node.deploy.form.aliyun_clb_region.placeholder": "Please enter Alibaba Cloud CLB region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_clb_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/slb/classic-load-balancer/product-overview/regions-that-support-clb", "workflow_node.deploy.form.aliyun_clb_resource_type.label": "Resource type", @@ -282,28 +282,28 @@ "workflow_node.deploy.form.aliyun_clb_snidomain.label": "Alibaba Cloud CLB SNI domain (Optional)", "workflow_node.deploy.form.aliyun_clb_snidomain.placeholder": "Please enter Alibaba Cloud CLB SNI domain name", "workflow_node.deploy.form.aliyun_clb_snidomain.help": "", - "workflow_node.deploy.form.aliyun_cdn_region.label": "Alibaba Cloud CDN region", + "workflow_node.deploy.form.aliyun_cdn_region.label": "Alibaba Cloud region", "workflow_node.deploy.form.aliyun_cdn_region.placeholder": "Please enter Alibaba Cloud CDN region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_cdn_region.tooltip": "

  • ap-southeast-1 for Alibaba Cloud International
  • cn-hangzhou for Alibaba Cloud in China
", "workflow_node.deploy.form.aliyun_cdn_domain.label": "Alibaba Cloud CDN domain", "workflow_node.deploy.form.aliyun_cdn_domain.placeholder": "Please enter Alibaba Cloud CDN domain name", - "workflow_node.deploy.form.aliyun_dcdn_region.label": "Alibaba Cloud DCDN region", + "workflow_node.deploy.form.aliyun_dcdn_region.label": "Alibaba Cloud region", "workflow_node.deploy.form.aliyun_dcdn_region.placeholder": "Please enter Alibaba Cloud DCDN region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_dcdn_region.tooltip": "
  • ap-southeast-1 for Alibaba Cloud International
  • cn-hangzhou for Alibaba Cloud in China
", "workflow_node.deploy.form.aliyun_dcdn_domain.label": "Alibaba Cloud DCDN domain", "workflow_node.deploy.form.aliyun_dcdn_domain.placeholder": "Please enter Alibaba Cloud DCDN domain name", - "workflow_node.deploy.form.aliyun_ddospro_region.label": "Alibaba Cloud Anti-DDoS region", + "workflow_node.deploy.form.aliyun_ddospro_region.label": "Alibaba Cloud region", "workflow_node.deploy.form.aliyun_ddospro_region.placeholder": "Please enter Alibaba Cloud Anti-DDoS region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_ddospro_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/anti-ddos/anti-ddos-pro-and-premium/developer-reference/api-ddoscoo-2020-01-01-endpoint", "workflow_node.deploy.form.aliyun_ddospro_domain.label": "Alibaba Cloud Anti-DDoS domain", "workflow_node.deploy.form.aliyun_ddospro_domain.placeholder": "Please enter Alibaba Cloud Anti-DDoS domain name", - "workflow_node.deploy.form.aliyun_esa_region.label": "Alibaba Cloud ESA region", + "workflow_node.deploy.form.aliyun_esa_region.label": "Alibaba Cloud region", "workflow_node.deploy.form.aliyun_esa_region.placeholder": "Please enter Alibaba Cloud ESA region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_esa_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/edge-security-acceleration/esa/api-esa-2024-09-10-endpoint", "workflow_node.deploy.form.aliyun_esa_site_id.label": "Alibaba Cloud ESA site ID", "workflow_node.deploy.form.aliyun_esa_site_id.placeholder": "Please enter Alibaba Cloud ESA site ID", "workflow_node.deploy.form.aliyun_esa_site_id.tooltip": "For more information, see https://esa.console.aliyun.com/siteManage/list", - "workflow_node.deploy.form.aliyun_fc_region.label": "Alibaba Cloud FC region", + "workflow_node.deploy.form.aliyun_fc_region.label": "Alibaba Cloud region", "workflow_node.deploy.form.aliyun_fc_region.placeholder": "Please enter Alibaba Cloud FC region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_fc_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/functioncompute/fc-3-0/product-overview/supported-regions", "workflow_node.deploy.form.aliyun_fc_service_version.label": "Alibaba Cloud FC version", @@ -323,12 +323,12 @@ "workflow_node.deploy.form.aliyun_ga_snidomain.label": "Alibaba Cloud GA SNI domain (Optional)", "workflow_node.deploy.form.aliyun_ga_snidomain.placeholder": "Please enter Alibaba Cloud GA SNI domain name", "workflow_node.deploy.form.aliyun_ga_snidomain.help": "", - "workflow_node.deploy.form.aliyun_live_region.label": "Alibaba Cloud Live region", + "workflow_node.deploy.form.aliyun_live_region.label": "Alibaba Cloud region", "workflow_node.deploy.form.aliyun_live_region.placeholder": "Please enter Alibaba Cloud Live region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_live_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/live/product-overview/supported-regions", "workflow_node.deploy.form.aliyun_live_domain.label": "Alibaba Cloud live streaming domain", "workflow_node.deploy.form.aliyun_live_domain.placeholder": "Please enter Alibaba Cloud live streaming domain name", - "workflow_node.deploy.form.aliyun_nlb_region.label": "Alibaba Cloud NLB region", + "workflow_node.deploy.form.aliyun_nlb_region.label": "Alibaba Cloud region", "workflow_node.deploy.form.aliyun_nlb_region.placeholder": "Please enter Alibaba Cloud NLB region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_nlb_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/slb/network-load-balancer/product-overview/regions-that-support-nlb", "workflow_node.deploy.form.aliyun_nlb_resource_type.label": "Resource type", @@ -341,19 +341,19 @@ "workflow_node.deploy.form.aliyun_nlb_listener_id.label": "Alibaba Cloud NLB listener ID", "workflow_node.deploy.form.aliyun_nlb_listener_id.placeholder": "Please enter Alibaba Cloud NLB listener ID", "workflow_node.deploy.form.aliyun_nlb_listener_id.tooltip": "For more information, see https://slb.console.aliyun.com/nlb", - "workflow_node.deploy.form.aliyun_oss_region.label": "Alibaba Cloud OSS region", + "workflow_node.deploy.form.aliyun_oss_region.label": "Alibaba Cloud region", "workflow_node.deploy.form.aliyun_oss_region.placeholder": "Please enter Alibaba Cloud OSS region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_oss_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/oss/user-guide/regions-and-endpoints", "workflow_node.deploy.form.aliyun_oss_bucket.label": "Alibaba Cloud OSS bucket", "workflow_node.deploy.form.aliyun_oss_bucket.placeholder": "Please enter Alibaba Cloud OSS bucket name", "workflow_node.deploy.form.aliyun_oss_domain.label": "Alibaba Cloud OSS custom domain", "workflow_node.deploy.form.aliyun_oss_domain.placeholder": "Please enter Alibaba Cloud OSS bucket custom domain name", - "workflow_node.deploy.form.aliyun_vod_region.label": "Alibaba Cloud VOD region", + "workflow_node.deploy.form.aliyun_vod_region.label": "Alibaba Cloud region", "workflow_node.deploy.form.aliyun_vod_region.placeholder": "Please enter Alibaba Cloud VOD region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_vod_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/vod/product-overview/regions", "workflow_node.deploy.form.aliyun_vod_domain.label": "Alibaba Cloud VOD domain", "workflow_node.deploy.form.aliyun_vod_domain.placeholder": "Please enter Alibaba Cloud VOD domain name", - "workflow_node.deploy.form.aliyun_waf_region.label": "Alibaba Cloud WAF region", + "workflow_node.deploy.form.aliyun_waf_region.label": "Alibaba Cloud region", "workflow_node.deploy.form.aliyun_waf_region.placeholder": "Please enter Alibaba Cloud WAF region (e.g. cn-hangzhou)", "workflow_node.deploy.form.aliyun_waf_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-endpoint", "workflow_node.deploy.form.aliyun_waf_service_version.label": "Alibaba Cloud WAF version", @@ -370,13 +370,13 @@ "workflow_node.deploy.form.apisix_certificate_id.label": "APISIX certificate ID", "workflow_node.deploy.form.apisix_certificate_id.placeholder": "Please enter APISIX certificate ID", "workflow_node.deploy.form.apisix_certificate_id.tooltip": "You can find it on APISIX dashboard.", - "workflow_node.deploy.form.aws_acm_region.label": "AWS ACM Region", + "workflow_node.deploy.form.aws_acm_region.label": "AWS Region", "workflow_node.deploy.form.aws_acm_region.placeholder": "Please enter AWS ACM region (e.g. us-east-1)", "workflow_node.deploy.form.aws_acm_region.tooltip": "For more information, see https://docs.aws.amazon.com/en_us/general/latest/gr/rande.html#regional-endpoints", "workflow_node.deploy.form.aws_acm_certificate_arn.label": "AWS ACM certificate ARN (Optional)", "workflow_node.deploy.form.aws_acm_certificate_arn.placeholder": "Please enter AWS ACM certificate ARN", "workflow_node.deploy.form.aws_acm_certificate_arn.help": "Notes: Leave it blank to import a new certificate.", - "workflow_node.deploy.form.aws_cloudfront_region.label": "AWS CloudFront Region", + "workflow_node.deploy.form.aws_cloudfront_region.label": "AWS 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.tooltip": "For more information, see https://docs.aws.amazon.com/en_us/general/latest/gr/rande.html#regional-endpoints", "workflow_node.deploy.form.aws_cloudfront_distribution_id.label": "AWS CloudFront distribution ID", @@ -384,7 +384,7 @@ "workflow_node.deploy.form.aws_cloudfront_distribution_id.tooltip": "For more information, see https://docs.aws.amazon.com/en_us/AmazonCloudFront/latest/DeveloperGuide/distribution-working-with.html", "workflow_node.deploy.form.aws_cloudfront_certificate_source.label": "AWS CloudFront certificate source", "workflow_node.deploy.form.aws_cloudfront_certificate_source.placeholder": "Please select AWS CloudFront certificate source", - "workflow_node.deploy.form.aws_iam_region.label": "AWS IAM Region", + "workflow_node.deploy.form.aws_iam_region.label": "AWS Region", "workflow_node.deploy.form.aws_iam_region.placeholder": "Please enter AWS IAM region (e.g. us-east-1)", "workflow_node.deploy.form.aws_iam_region.tooltip": "For more information, see https://docs.aws.amazon.com/en_us/general/latest/gr/rande.html#regional-endpoints", "workflow_node.deploy.form.aws_iam_certificate_path.label": "AWS IAM certificate path (Optional)", @@ -398,7 +398,7 @@ "workflow_node.deploy.form.azure_keyvault_certificate_name.placeholder": "Please enter Azure KeyVault certificate name", "workflow_node.deploy.form.azure_keyvault_certificate_name.errmsg.invalid": "Certificate name can only contain letters, numbers, and hyphens (-), with a length limit of 1 to 127 characters", "workflow_node.deploy.form.azure_keyvault_certificate_name.help": "Notes: Leave it blank to use a default name generated by Certimate.", - "workflow_node.deploy.form.baiducloud_appblb_region.label": "Baidu Cloud BLB region", + "workflow_node.deploy.form.baiducloud_appblb_region.label": "Baidu Cloud region", "workflow_node.deploy.form.baiducloud_appblb_region.placeholder": "Please enter Baidu Cloud BLB region (e.g. bj)", "workflow_node.deploy.form.baiducloud_appblb_region.tooltip": "For more information, see https://cloud.baidu.com/doc/BLB/s/cjwvxnzix", "workflow_node.deploy.form.baiducloud_appblb_resource_type.label": "Resource type", @@ -414,7 +414,7 @@ "workflow_node.deploy.form.baiducloud_appblb_snidomain.label": "Baidu Cloud BLB SNI domain (Optional)", "workflow_node.deploy.form.baiducloud_appblb_snidomain.placeholder": "Please enter Baidu Cloud BLB SNI domain name", "workflow_node.deploy.form.baiducloud_appblb_snidomain.help": "", - "workflow_node.deploy.form.baiducloud_blb_region.label": "Baidu Cloud BLB region", + "workflow_node.deploy.form.baiducloud_blb_region.label": "Baidu Cloud region", "workflow_node.deploy.form.baiducloud_blb_region.placeholder": "Please enter Baidu Cloud BLB region (e.g. bj)", "workflow_node.deploy.form.baiducloud_blb_region.tooltip": "For more information, see https://cloud.baidu.com/doc/BLB/s/cjwvxnzix", "workflow_node.deploy.form.baiducloud_blb_resource_type.label": "Resource type", @@ -485,7 +485,7 @@ "workflow_node.deploy.form.ctcccloud_ao_domain.placeholder": "Please enter CTCC StateCloud AccessOne domain name", "workflow_node.deploy.form.ctcccloud_cdn_domain.label": "CTCC StateCloud CDN domain", "workflow_node.deploy.form.ctcccloud_cdn_domain.placeholder": "Please enter CTCC StateCloud CDN domain name", - "workflow_node.deploy.form.ctcccloud_elb_region_id.label": "CTCC StateCloud ELB region ID", + "workflow_node.deploy.form.ctcccloud_elb_region_id.label": "CTCC StateCloud region ID", "workflow_node.deploy.form.ctcccloud_elb_region_id.placeholder": "Please enter CTCC StateCloud ELB region ID", "workflow_node.deploy.form.ctcccloud_elb_region_id.tooltip": "For more information, see https://www.ctyun.cn/document/10026755/10196575", "workflow_node.deploy.form.ctcccloud_elb_resource_type.label": "Resource type", @@ -524,19 +524,19 @@ "workflow_node.deploy.form.goedge_certificate_id.label": "GoEdge certificate ID", "workflow_node.deploy.form.goedge_certificate_id.placeholder": "Please enter GoEdge certificate ID", "workflow_node.deploy.form.goedge_certificate_id.tooltip": "You can find it on GoEdge dashboard.", - "workflow_node.deploy.form.huaweicloud_cdn_region.label": "Huawei Cloud CDN region", + "workflow_node.deploy.form.huaweicloud_cdn_region.label": "Huawei Cloud region", "workflow_node.deploy.form.huaweicloud_cdn_region.placeholder": "Please enter Huawei Cloud CDN region (e.g. cn-north-1)", "workflow_node.deploy.form.huaweicloud_cdn_region.tooltip": "For more information, see https://console-intl.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_cdn_domain.label": "Huawei Cloud CDN domain", "workflow_node.deploy.form.huaweicloud_cdn_domain.placeholder": "Please enter Huawei Cloud CDN domain name", - "workflow_node.deploy.form.huaweicloud_obs_region.label": "Huawei Cloud OBS region", + "workflow_node.deploy.form.huaweicloud_obs_region.label": "Huawei Cloud region", "workflow_node.deploy.form.huaweicloud_obs_region.placeholder": "Please enter the Huawei Cloud OBS region (e.g. cn-north-1)", "workflow_node.deploy.form.huaweicloud_obs_region.tooltip": "For more information, see https://console-intl.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_obs_bucket.label": "Huawei Cloud OBS bucket name", "workflow_node.deploy.form.huaweicloud_obs_bucket.placeholder": "Please enter the Huawei Cloud OBS bucket name", "workflow_node.deploy.form.huaweicloud_obs_domain.label": "Huawei Cloud OBS custom domain", "workflow_node.deploy.form.huaweicloud_obs_domain.placeholder": "Please enter the Huawei Cloud OBS custom domain name", - "workflow_node.deploy.form.huaweicloud_elb_region.label": "Huawei Cloud ELB region", + "workflow_node.deploy.form.huaweicloud_elb_region.label": "Huawei Cloud region", "workflow_node.deploy.form.huaweicloud_elb_region.placeholder": "Please enter Huawei Cloud ELB region (e.g. cn-north-1)", "workflow_node.deploy.form.huaweicloud_elb_region.tooltip": "For more information, see https://console-intl.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_elb_resource_type.label": "Resource type", @@ -553,7 +553,7 @@ "workflow_node.deploy.form.huaweicloud_elb_listener_id.label": "Huawei Cloud ELB listener ID", "workflow_node.deploy.form.huaweicloud_elb_listener_id.placeholder": "Please enter Huawei Cloud ELB listener ID", "workflow_node.deploy.form.huaweicloud_elb_listener_id.tooltip": "For more information, see https://console-intl.huaweicloud.com/vpc/#/elb/list/grid", - "workflow_node.deploy.form.huaweicloud_waf_region.label": "Huawei Cloud WAF region", + "workflow_node.deploy.form.huaweicloud_waf_region.label": "Huawei Cloud region", "workflow_node.deploy.form.huaweicloud_waf_region.placeholder": "Please enter Huawei Cloud WAF region (e.g. cn-north-1)", "workflow_node.deploy.form.huaweicloud_waf_region.tooltip": "For more information, see https://console-intl.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_waf_resource_type.label": "Resource type", @@ -566,7 +566,7 @@ "workflow_node.deploy.form.huaweicloud_waf_certificate_id.tooltip": "For more information, see https://console-intl.huaweicloud.com/console/#/waf/certificateManagement", "workflow_node.deploy.form.huaweicloud_waf_domain.label": "Huawei Cloud WAF domain", "workflow_node.deploy.form.huaweicloud_waf_domain.placeholder": "Please enter Huawei Cloud WAF domain name", - "workflow_node.deploy.form.jdcloud_alb_region_id.label": "JD Cloud ALB region ID", + "workflow_node.deploy.form.jdcloud_alb_region_id.label": "JD Cloud region ID", "workflow_node.deploy.form.jdcloud_alb_region_id.placeholder": "Please enter JD Cloud ALB region ID (e.g. cn-north-1)", "workflow_node.deploy.form.jdcloud_alb_region_id.tooltip": "For more information, see https://docs.jdcloud.com/en/common-declaration/api/introduction", "workflow_node.deploy.form.jdcloud_alb_resource_type.label": "Resource type", @@ -763,15 +763,15 @@ "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_rdp.label": "PowerShell - Binding RDP", "workflow_node.deploy.form.ssh_use_scp.label": "Fallback to use SCP", "workflow_node.deploy.form.ssh_use_scp.tooltip": "If the remote server does not support SFTP, please check this option to fallback to SCP.", - "workflow_node.deploy.form.tencentcloud_cdn_endpoint.label": "Tencent Cloud CDN API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_cdn_endpoint.label": "Tencent Cloud API endpoint (Optional)", "workflow_node.deploy.form.tencentcloud_cdn_endpoint.placeholder": "Please enter Tencent Cloud CDN API endpoint (e.g. cdn.intl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_cdn_endpoint.tooltip": "
  • cdn.intl.tencentcloudapi.com for Tencent Cloud International
  • cdn.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_cdn_domain.label": "Tencent Cloud CDN domain", "workflow_node.deploy.form.tencentcloud_cdn_domain.placeholder": "Please enter Tencent Cloud CDN domain name", - "workflow_node.deploy.form.tencentcloud_clb_endpoint.label": "Tencent Cloud CLB API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_clb_endpoint.label": "Tencent Cloud API endpoint (Optional)", "workflow_node.deploy.form.tencentcloud_clb_endpoint.placeholder": "Please enter Tencent Cloud CLB API endpoint (e.g. clb.intl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_clb_endpoint.tooltip": "
  • clb.intl.tencentcloudapi.com for Tencent Cloud International
  • clb.tencentcloudapi.com for Tencent Cloud in China
", - "workflow_node.deploy.form.tencentcloud_clb_region.label": "Tencent Cloud CLB region", + "workflow_node.deploy.form.tencentcloud_clb_region.label": "Tencent Cloud region", "workflow_node.deploy.form.tencentcloud_clb_region.placeholder": "Please enter Tencent Cloud CLB region (e.g. ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_clb_region.tooltip": "For more information, see https://www.tencentcloud.com/document/product/214/13629", "workflow_node.deploy.form.tencentcloud_clb_resource_type.label": "Resource type", @@ -787,24 +787,24 @@ "workflow_node.deploy.form.tencentcloud_clb_listener_id.tooltip": "For more information, see https://console.tencentcloud.com/clb", "workflow_node.deploy.form.tencentcloud_clb_ruledomain.label": "Tencent Cloud CLB domain", "workflow_node.deploy.form.tencentcloud_clb_ruledomain.placeholder": "Please enter Tencent Cloud CLB domain name", - "workflow_node.deploy.form.tencentcloud_cos_region.label": "Tencent Cloud COS region", + "workflow_node.deploy.form.tencentcloud_cos_region.label": "Tencent Cloud region", "workflow_node.deploy.form.tencentcloud_cos_region.placeholder": "Please enter Tencent Cloud COS region (e.g. ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_cos_region.tooltip": "For more information, see https://www.tencentcloud.com/document/product/436/6224", "workflow_node.deploy.form.tencentcloud_cos_bucket.label": "Tencent Cloud COS bucket", "workflow_node.deploy.form.tencentcloud_cos_bucket.placeholder": "Please enter Tencent Cloud COS bucket name", "workflow_node.deploy.form.tencentcloud_cos_domain.label": "Tencent Cloud COS custom domain", "workflow_node.deploy.form.tencentcloud_cos_domain.placeholder": "Please enter Tencent Cloud COS bucket custom domain name", - "workflow_node.deploy.form.tencentcloud_css_endpoint.label": "Tencent Cloud CSS API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_css_endpoint.label": "Tencent Cloud API endpoint (Optional)", "workflow_node.deploy.form.tencentcloud_css_endpoint.placeholder": "Please enter Tencent Cloud CSS API endpoint (e.g. live.intl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_css_endpoint.tooltip": "
  • live.intl.tencentcloudapi.com for Tencent Cloud International
  • live.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_css_domain.label": "Tencent Cloud CSS play domain", "workflow_node.deploy.form.tencentcloud_css_domain.placeholder": "Please enter Tencent Cloud CSS play domain name", - "workflow_node.deploy.form.tencentcloud_ecdn_endpoint.label": "Tencent Cloud ECDN API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_ecdn_endpoint.label": "Tencent Cloud API endpoint (Optional)", "workflow_node.deploy.form.tencentcloud_ecdn_endpoint.placeholder": "Please enter Tencent Cloud ECDN API endpoint (e.g. cdn.intl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_ecdn_endpoint.tooltip": "
  • cdn.intl.tencentcloudapi.com for Tencent Cloud International
  • cdn.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_ecdn_domain.label": "Tencent Cloud ECDN domain", "workflow_node.deploy.form.tencentcloud_ecdn_domain.placeholder": "Please enter Tencent Cloud ECDN domain name", - "workflow_node.deploy.form.tencentcloud_eo_endpoint.label": "Tencent Cloud EdgeOne API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_eo_endpoint.label": "Tencent Cloud API endpoint (Optional)", "workflow_node.deploy.form.tencentcloud_eo_endpoint.placeholder": "Please enter Tencent Cloud EdgeOne API endpoint (e.g. teo.intl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_eo_endpoint.tooltip": "
  • cdn.intl.tencentcloudapi.com for Tencent Cloud International
  • teo.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_eo_zone_id.label": "Tencent Cloud EdgeOne zone ID", @@ -815,7 +815,7 @@ "workflow_node.deploy.form.tencentcloud_eo_domains.help": "Notes: Multi-domains should be separated by semicolons.", "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.label": "Tencent Cloud 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": "
  • gaap.intl.tencentcloudapi.com for Tencent Cloud International
  • gaap.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_gaap_resource_type.label": "Resource type", @@ -827,22 +827,22 @@ "workflow_node.deploy.form.tencentcloud_gaap_listener_id.label": "Tencent Cloud GAAP listener ID", "workflow_node.deploy.form.tencentcloud_gaap_listener_id.placeholder": "Please enter Tencent Cloud GAAP listener ID", "workflow_node.deploy.form.tencentcloud_gaap_listener_id.tooltip": "For more information, see https://console.tencentcloud.com/gaap", - "workflow_node.deploy.form.tencentcloud_scf_endpoint.label": "Tencent Cloud SCF API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_scf_endpoint.label": "Tencent Cloud API endpoint (Optional)", "workflow_node.deploy.form.tencentcloud_scf_endpoint.placeholder": "Please enter Tencent Cloud SCF API endpoint (e.g. scf.intl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_scf_endpoint.tooltip": "
  • scf.intl.tencentcloudapi.com for Tencent Cloud International
  • scf.tencentcloudapi.com for Tencent Cloud in China
", - "workflow_node.deploy.form.tencentcloud_scf_region.label": "Tencent Cloud SCF region", + "workflow_node.deploy.form.tencentcloud_scf_region.label": "Tencent Cloud region", "workflow_node.deploy.form.tencentcloud_scf_region.placeholder": "Please enter Tencent Cloud SCF region (e.g. ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_scf_region.tooltip": "For more information, see https://www.tencentcloud.com/document/product/583/17299", "workflow_node.deploy.form.tencentcloud_scf_domain.label": "Tencent Cloud SCF domain", "workflow_node.deploy.form.tencentcloud_scf_domain.placeholder": "Please enter Tencent Cloud SCF domain name", - "workflow_node.deploy.form.tencentcloud_ssl_endpoint.label": "Tencent Cloud SSL API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_ssl_endpoint.label": "Tencent Cloud API endpoint (Optional)", "workflow_node.deploy.form.tencentcloud_ssl_endpoint.placeholder": "Please enter Tencent Cloud SSL API endpoint (e.g. ssl.intl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_ssl_endpoint.tooltip": "
  • ssl.intl.tencentcloudapi.com for Tencent Cloud International
  • ssl.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_ssldeploy.guide": "TIPS: This will invoke Tencent Cloud OpenAPI DeployCertificateInstance to create an asynchronously deployment task. You need to go to the Tencent Cloud console to check the actual deployment results by yourself.", - "workflow_node.deploy.form.tencentcloud_ssldeploy_endpoint.label": "Tencent Cloud SSL API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_ssldeploy_endpoint.label": "Tencent Cloud API endpoint (Optional)", "workflow_node.deploy.form.tencentcloud_ssldeploy_endpoint.placeholder": "Please enter Tencent Cloud SSL API endpoint (e.g. ssl.intl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_ssldeploy_endpoint.tooltip": "
  • ssl.intl.tencentcloudapi.com for Tencent Cloud International
  • ssl.tencentcloudapi.com for Tencent Cloud in China
", - "workflow_node.deploy.form.tencentcloud_ssldeploy_region.label": "Tencent Cloud service region", + "workflow_node.deploy.form.tencentcloud_ssldeploy_region.label": "Tencent Cloud region", "workflow_node.deploy.form.tencentcloud_ssldeploy_region.placeholder": "Please enter Tencent Cloud service region (e.g. ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_ssldeploy_region.tooltip": "For more information, see https://www.tencentcloud.com/document/product/1007/36573", "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_type.label": "Tencent Cloud resource type", @@ -856,7 +856,7 @@ "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_ids.multiple_input_modal.title": "Change Tencent Cloud resource IDs", "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_ids.multiple_input_modal.placeholder": "Please enter Tencent Cloud resouce ID", "workflow_node.deploy.form.tencentcloud_sslupdate.guide": "TIPS: This will invoke Tencent Cloud OpenAPI UpdateCertificateInstance or UploadUpdateCertificateInstance to create an asynchronously deployment task. You need to go to the Tencent Cloud console to check the actual deployment results by yourself.", - "workflow_node.deploy.form.tencentcloud_sslupdate_endpoint.label": "Tencent Cloud SSL API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_sslupdate_endpoint.label": "Tencent Cloud API endpoint (Optional)", "workflow_node.deploy.form.tencentcloud_sslupdate_endpoint.placeholder": "Please enter Tencent Cloud SSL API endpoint (e.g. ssl.intl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_sslupdate_endpoint.tooltip": "
  • ssl.intl.tencentcloudapi.com for Tencent Cloud International
  • ssl.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_sslupdate_certificate_id.label": "Tencent Cloud SSL certificate ID", @@ -876,7 +876,7 @@ "workflow_node.deploy.form.tencentcloud_sslupdate_resource_regions.multiple_input_modal.placeholder": "Please enter Tencent Cloud resource region", "workflow_node.deploy.form.tencentcloud_sslupdate_is_replaced.label": "Renewal certificate (certificate ID unchanged)", "workflow_node.deploy.form.tencentcloud_sslupdate_is_replaced.tooltip": "When unchecked, it will invoke UpdateCertificateInstance; otherwise, it will invoke UploadUpdateCertificateInstance.", - "workflow_node.deploy.form.tencentcloud_vod_endpoint.label": "Tencent Cloud VOD API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_vod_endpoint.label": "Tencent Cloud API endpoint (Optional)", "workflow_node.deploy.form.tencentcloud_vod_endpoint.placeholder": "Please enter Tencent Cloud VOD API endpoint (e.g. vod.intl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_vod_endpoint.tooltip": "
  • vod.intl.tencentcloudapi.com for Tencent Cloud International
  • vod.tencentcloudapi.com for Tencent Cloud in China
", "workflow_node.deploy.form.tencentcloud_vod_sub_app_id.label": "Tencent Cloud VOD App ID", @@ -884,10 +884,10 @@ "workflow_node.deploy.form.tencentcloud_vod_sub_app_id.tooltip": "For more information, see https://console.tencentcloud.com/vod", "workflow_node.deploy.form.tencentcloud_vod_domain.label": "Tencent Cloud VOD domain", "workflow_node.deploy.form.tencentcloud_vod_domain.placeholder": "Please enter Tencent Cloud VOD domain name", - "workflow_node.deploy.form.tencentcloud_waf_endpoint.label": "Tencent Cloud WAF API endpoint (Optional)", + "workflow_node.deploy.form.tencentcloud_waf_endpoint.label": "Tencent Cloud API endpoint (Optional)", "workflow_node.deploy.form.tencentcloud_waf_endpoint.placeholder": "Please enter Tencent Cloud WAF API endpoint (e.g. waf.intl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_waf_endpoint.tooltip": "
  • waf.intl.tencentcloudapi.com for Tencent Cloud International
  • waf.tencentcloudapi.com for Tencent Cloud in China
", - "workflow_node.deploy.form.tencentcloud_waf_region.label": "Tencent Cloud WAF region", + "workflow_node.deploy.form.tencentcloud_waf_region.label": "Tencent Cloud region", "workflow_node.deploy.form.tencentcloud_waf_region.placeholder": "Please enter Tencent Cloud WAF region (e.g. ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_waf_region.tooltip": "For more information, see https://www.tencentcloud.com/document/product/627/38085", "workflow_node.deploy.form.tencentcloud_waf_domain.label": "Tencent Cloud WAF domain", @@ -901,7 +901,7 @@ "workflow_node.deploy.form.ucloud_ucdn_domain_id.label": "UCloud UCDN domain ID", "workflow_node.deploy.form.ucloud_ucdn_domain_id.placeholder": "Please enter UCloud UCDN domain ID", "workflow_node.deploy.form.ucloud_ucdn_domain_id.tooltip": "For more information, see https://console.ucloud-global.com/ucdn", - "workflow_node.deploy.form.ucloud_us3_region.label": "UCloud US3 region", + "workflow_node.deploy.form.ucloud_us3_region.label": "UCloud region", "workflow_node.deploy.form.ucloud_us3_region.placeholder": "Please enter UCloud US3 region (e.g. cn-bj2)", "workflow_node.deploy.form.ucloud_us3_region.tooltip": "For more information, see https://www.ucloud-global.com/en/docs/api/summary/regionlist", "workflow_node.deploy.form.ucloud_us3_bucket.label": "UCloud US3 bucket", @@ -926,7 +926,7 @@ "workflow_node.deploy.form.upyun_file_bucket.placeholder": "Please enter UPYUN USS bucket name", "workflow_node.deploy.form.upyun_file_domain.label": "UPYUN USS custom domain", "workflow_node.deploy.form.upyun_file_domain.placeholder": "Please enter UPYUN USS bucket custom domain name", - "workflow_node.deploy.form.volcengine_alb_region.label": "VolcEngine ALB region", + "workflow_node.deploy.form.volcengine_alb_region.label": "VolcEngine region", "workflow_node.deploy.form.volcengine_alb_region.placeholder": "Please enter VolcEngine ALB region (e.g. cn-beijing)", "workflow_node.deploy.form.volcengine_alb_region.tooltip": "For more information, see https://www.volcengine.com/docs/6767/127501", "workflow_node.deploy.form.volcengine_alb_resource_type.label": "Resource type", @@ -944,9 +944,9 @@ "workflow_node.deploy.form.volcengine_alb_snidomain.help": "", "workflow_node.deploy.form.volcengine_cdn_domain.label": "VolcEngine CDN domain", "workflow_node.deploy.form.volcengine_cdn_domain.placeholder": "Please enter VolcEngine CDN domain name", - "workflow_node.deploy.form.volcengine_certcenter_region.label": "VolcEngine Certificate Center region", + "workflow_node.deploy.form.volcengine_certcenter_region.label": "VolcEngine region", "workflow_node.deploy.form.volcengine_certcenter_region.placeholder": "Please enter VolcEngine Certificate Center region (e.g. cn-beijing)", - "workflow_node.deploy.form.volcengine_clb_region.label": "VolcEngine CLB region", + "workflow_node.deploy.form.volcengine_clb_region.label": "VolcEngine region", "workflow_node.deploy.form.volcengine_clb_region.placeholder": "Please enter VolcEngine CLB region (e.g. cn-beijing)", "workflow_node.deploy.form.volcengine_clb_region.tooltip": "For more information, see https://www.volcengine.com/docs/6406/74892", "workflow_node.deploy.form.volcengine_clb_resource_type.label": "Resource type", @@ -961,7 +961,7 @@ "workflow_node.deploy.form.volcengine_clb_listener_id.tooltip": "For more information, see https://console.volcengine.com/clb/LoadBalancer", "workflow_node.deploy.form.volcengine_dcdn_domain.label": "VolcEngine DCDN domain", "workflow_node.deploy.form.volcengine_dcdn_domain.placeholder": "Please enter VolcEngine DCDN domain name", - "workflow_node.deploy.form.volcengine_imagex_region.label": "VolcEngine ImageX region", + "workflow_node.deploy.form.volcengine_imagex_region.label": "VolcEngine region", "workflow_node.deploy.form.volcengine_imagex_region.placeholder": "Please enter VolcEngine ImageX region (e.g. cn-north-1)", "workflow_node.deploy.form.volcengine_imagex_region.tooltip": "For more information, see https://www.volcengine.com/docs/508/23757", "workflow_node.deploy.form.volcengine_imagex_service_id.label": "VolcEngine ImageX service ID", @@ -971,7 +971,7 @@ "workflow_node.deploy.form.volcengine_imagex_domain.placeholder": "Please enter VolcEngine ImageX custom domain name", "workflow_node.deploy.form.volcengine_live_domain.label": "VolcEngine Live streaming domain", "workflow_node.deploy.form.volcengine_live_domain.placeholder": "Please enter VolcEngine Live streaming domain name", - "workflow_node.deploy.form.volcengine_tos_region.label": "VolcEngine TOS region", + "workflow_node.deploy.form.volcengine_tos_region.label": "VolcEngine region", "workflow_node.deploy.form.volcengine_tos_region.placeholder": "Please enter VolcEngine TOS region (e.g. cn-beijing)", "workflow_node.deploy.form.volcengine_tos_region.tooltip": "For more information, see https://www.volcengine.com/docs/6349/107356", "workflow_node.deploy.form.volcengine_tos_bucket.label": "VolcEngine TOS bucket", diff --git a/ui/src/i18n/locales/zh/nls.access.json b/ui/src/i18n/locales/zh/nls.access.json index 93abd91e4..bc641a4ff 100644 --- a/ui/src/i18n/locales/zh/nls.access.json +++ b/ui/src/i18n/locales/zh/nls.access.json @@ -57,6 +57,12 @@ "access.form.1panel_api_key.label": "1Panel 接口密钥", "access.form.1panel_api_key.placeholder": "请输入 1Panel 接口密钥", "access.form.1panel_api_key.tooltip": "这是什么?请参阅 https://1panel.cn/docs/dev_manual/api_manual/", + "access.form.35cn_username.label": "三五互联代理商用户名", + "access.form.35cn_username.placeholder": "请输入三五互联代理商用户名", + "access.form.35cn_username.tooltip": "这是什么?请参阅 https://www.35.com/agent/mode-api.asp", + "access.form.35cn_api_password.label": "三五互联代理商 API 密码", + "access.form.35cn_api_password.placeholder": "请输入三五互联代理商 API 密码", + "access.form.35cn_api_password.tooltip": "这是什么?请参阅 https://www.35.com/agent/mode-api.asp", "access.form.acmeca_endpoint.label": "服务端点", "access.form.acmeca_endpoint.placeholder": "请输入服务端点", "access.form.acmeca_endpoint.tooltip": "这是什么?请参阅 https://datatracker.ietf.org/doc/html/rfc8555#section-7.1.1", @@ -626,11 +632,11 @@ "access.form.wecombot_webhook_url.label": "企业微信群机器人 Webhook 地址", "access.form.wecombot_webhook_url.placeholder": "请输入企业微信群机器人 Webhook 地址", "access.form.wecombot_webhook_url.tooltip": "这是什么?请参阅 https://open.work.weixin.qq.com/help2/pc/18401", - "access.form.westcn_username.label": "西部数码用户名", - "access.form.westcn_username.placeholder": "请输入西部数码用户名", + "access.form.westcn_username.label": "西部数码代理商用户名", + "access.form.westcn_username.placeholder": "请输入西部数码代理商用户名", "access.form.westcn_username.tooltip": "这是什么?请参阅 https://www.west.cn/CustomerCenter/doc/apiv2.html", - "access.form.westcn_api_password.label": "西部数码 API 密码", - "access.form.westcn_api_password.placeholder": "请输入西部数码 API 密码", + "access.form.westcn_api_password.label": "西部数码代理商 API 密码", + "access.form.westcn_api_password.placeholder": "请输入西部数码代理商 API 密码", "access.form.westcn_api_password.tooltip": "这是什么?请参阅 https://www.west.cn/CustomerCenter/doc/apiv2.html", "access.form.zerossl_eab.guide": "点击下方链接了解如何获取 ZeroSSL EAB:
https://zerossl.com/documentation/acme/" } diff --git a/ui/src/i18n/locales/zh/nls.provider.json b/ui/src/i18n/locales/zh/nls.provider.json index 92e8561c8..8440253c3 100644 --- a/ui/src/i18n/locales/zh/nls.provider.json +++ b/ui/src/i18n/locales/zh/nls.provider.json @@ -2,6 +2,7 @@ "provider.1panel": "1Panel", "provider.1panel.console": "1Panel - 面板自身", "provider.1panel.site": "1Panel - 网站", + "provider.35cn": "三五互联", "provider.acmeca": "ACME 自定义 CA 端点", "provider.acmedns": "ACME-DNS", "provider.acmehttpreq": "ACME 自定义 HTTP 端点", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index 4b68a2063..1ebc1c07c 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -54,19 +54,19 @@ "workflow_node.apply.form.provider_access_dns01.placeholder": "请选择 DNS 提供商授权", "workflow_node.apply.form.provider_access_http01.label": "主机提供商授权", "workflow_node.apply.form.provider_access_http01.placeholder": "请选择主机提供商授权", - "workflow_node.apply.form.aliyun_esa_region.label": "阿里云 ESA 服务地域", + "workflow_node.apply.form.aliyun_esa_region.label": "阿里云服务地域", "workflow_node.apply.form.aliyun_esa_region.placeholder": "请输入阿里云 ESA 服务地域(例如:cn-hangzhou)", "workflow_node.apply.form.aliyun_esa_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/edge-security-acceleration/esa/api-esa-2024-09-10-endpoint", - "workflow_node.apply.form.aws_route53_region.label": "AWS Route53 服务区域", + "workflow_node.apply.form.aws_route53_region.label": "AWS 服务区域", "workflow_node.apply.form.aws_route53_region.placeholder": "请输入 AWS Route53 服务区域(例如:us-east-1)", "workflow_node.apply.form.aws_route53_region.tooltip": "这是什么?请参阅 https://docs.aws.amazon.com/zh_cn/general/latest/gr/rande.html#regional-endpoints", "workflow_node.apply.form.aws_route53_hosted_zone_id.label": "AWS Route53 托管区域 ID", "workflow_node.apply.form.aws_route53_hosted_zone_id.placeholder": "请输入 AWS Route53 托管区域 ID", "workflow_node.apply.form.aws_route53_hosted_zone_id.tooltip": "这是什么?请参阅 https://docs.aws.amazon.com/zh_cn/Route53/latest/DeveloperGuide/hosted-zones-working-with.html", - "workflow_node.apply.form.huaweicloud_dns_region.label": "华为云 DNS 服务区域", + "workflow_node.apply.form.huaweicloud_dns_region.label": "华为云服务区域", "workflow_node.apply.form.huaweicloud_dns_region.placeholder": "请输入华为云 DNS 服务区域(例如:cn-north-1)", "workflow_node.apply.form.huaweicloud_dns_region.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/apiexplorer/#/endpoint", - "workflow_node.apply.form.jdcloud_dns_region_id.label": "京东云 DNS 服务地域 ID", + "workflow_node.apply.form.jdcloud_dns_region_id.label": "京东云服务地域 ID", "workflow_node.apply.form.jdcloud_dns_region_id.placeholder": "请输入京东云 DNS 服务地域 ID(例如:cn-north-1)", "workflow_node.apply.form.jdcloud_dns_region_id.tooltip": "这是什么?请参阅 https://docs.jdcloud.com/cn/common-declaration/api/introduction", "workflow_node.apply.form.local_webroot_path.label": "网站根目录", @@ -193,7 +193,7 @@ "workflow_node.deploy.form.provider_access.placeholder": "请选择主机提供商授权", "workflow_node.deploy.form.provider_access.button": "新建", "workflow_node.deploy.form.shared_domain_match_pattern.label": "域名匹配模式", - "workflow_node.deploy.form.shared_domain_match_pattern.placeholder": "请选择域名匹配模式", + "workflow_node.deploy.form.shared_domain_match_pattern.placeholder": "请选择部署域名匹配模式", "workflow_node.deploy.form.shared_domain_match_pattern.option.exact.label": "精确匹配", "workflow_node.deploy.form.shared_domain_match_pattern.option.wildcard.label": "通配符匹配(泛域名)", "workflow_node.deploy.form.shared_domain_match_pattern.option.certsan.label": "根据证书自动匹配", @@ -213,7 +213,7 @@ "workflow_node.deploy.form.1panel_site_certificate_id.label": "1Panel 证书 ID", "workflow_node.deploy.form.1panel_site_certificate_id.placeholder": "请输入 1Panel 证书 ID", "workflow_node.deploy.form.1panel_site_certificate_id.tooltip": "请登录 1Panel 面板查看", - "workflow_node.deploy.form.aliyun_alb_region.label": "阿里云 ALB 服务地域", + "workflow_node.deploy.form.aliyun_alb_region.label": "阿里云服务地域", "workflow_node.deploy.form.aliyun_alb_region.placeholder": "请输入阿里云 ALB 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_alb_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/slb/application-load-balancer/product-overview/supported-regions-and-zones", "workflow_node.deploy.form.aliyun_alb_resource_type.label": "证书部署方式", @@ -233,7 +233,7 @@ "workflow_node.deploy.form.aliyun_apigw_service_type.placeholder": "请选择阿里云 API 网关服务类型", "workflow_node.deploy.form.aliyun_apigw_service_type.option.cloudnative.label": "云原生 API 网关", "workflow_node.deploy.form.aliyun_apigw_service_type.option.traditional.label": "原 API 网关", - "workflow_node.deploy.form.aliyun_apigw_region.label": "阿里云 API 网关服务地域", + "workflow_node.deploy.form.aliyun_apigw_region.label": "阿里云服务地域", "workflow_node.deploy.form.aliyun_apigw_region.placeholder": "请输入阿里云 API 网关地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_apigw_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/api-gateway/cloud-native-api-gateway/product-overview/regions", "workflow_node.deploy.form.aliyun_apigw_gateway_id.label": "阿里云 API 网关 ID", @@ -244,11 +244,11 @@ "workflow_node.deploy.form.aliyun_apigw_group_id.tooltip": "这是什么?请参阅 https://apigateway.console.aliyun.com", "workflow_node.deploy.form.aliyun_apigw_domain.label": "阿里云 API 网关自定义域名", "workflow_node.deploy.form.aliyun_apigw_domain.placeholder": "请输入阿里云 API 网关自定义域名", - "workflow_node.deploy.form.aliyun_cas_region.label": "阿里云 CAS 服务地域", + "workflow_node.deploy.form.aliyun_cas_region.label": "阿里云服务地域", "workflow_node.deploy.form.aliyun_cas_region.placeholder": "请输入阿里云 CAS 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_cas_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/ssl-certificate/developer-reference/endpoints", "workflow_node.deploy.form.aliyun_casdeploy.guide": "将通过阿里云 OpenAPI CreateDeploymentJob 接口创建异步部署任务。此部署目标若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往阿里云控制台查询。", - "workflow_node.deploy.form.aliyun_casdeploy_region.label": "阿里云 CAS 服务地域", + "workflow_node.deploy.form.aliyun_casdeploy_region.label": "阿里云服务地域", "workflow_node.deploy.form.aliyun_casdeploy_region.placeholder": "请输入阿里云 CAS 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_casdeploy_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/ssl-certificate/developer-reference/endpoints", "workflow_node.deploy.form.aliyun_casdeploy_resource_ids.label": "阿里云云产品资源 ID", @@ -265,7 +265,7 @@ "workflow_node.deploy.form.aliyun_casdeploy_contact_ids.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-listcontact", "workflow_node.deploy.form.aliyun_casdeploy_contact_ids.multiple_input_modal.title": "修改阿里云联系人 ID", "workflow_node.deploy.form.aliyun_casdeploy_contact_ids.multiple_input_modal.placeholder": "请输入阿里云联系人 ID", - "workflow_node.deploy.form.aliyun_clb_region.label": "阿里云 CLB 服务地域", + "workflow_node.deploy.form.aliyun_clb_region.label": "阿里云服务地域", "workflow_node.deploy.form.aliyun_clb_region.placeholder": "请输入阿里云 CLB 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_clb_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/slb/classic-load-balancer/product-overview/regions-that-support-clb", "workflow_node.deploy.form.aliyun_clb_resource_type.label": "证书部署方式", @@ -281,28 +281,28 @@ "workflow_node.deploy.form.aliyun_clb_snidomain.label": "阿里云 CLB 扩展域名(可选)", "workflow_node.deploy.form.aliyun_clb_snidomain.placeholder": "请输入阿里云 CLB 扩展域名", "workflow_node.deploy.form.aliyun_clb_snidomain.help": "提示:不填写时,将替换监听器的默认证书;否则,将替换扩展域名证书。", - "workflow_node.deploy.form.aliyun_cdn_region.label": "阿里云 CDN 服务地域", + "workflow_node.deploy.form.aliyun_cdn_region.label": "阿里云服务地域", "workflow_node.deploy.form.aliyun_cdn_region.placeholder": "请输入阿里云 CDN 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_cdn_region.tooltip": "中国站请填写 cn-hangzhou;
国际站请填写 ap-southeast-1。", "workflow_node.deploy.form.aliyun_cdn_domain.label": "阿里云 CDN 加速域名", "workflow_node.deploy.form.aliyun_cdn_domain.placeholder": "请输入阿里云 CDN 加速域名", - "workflow_node.deploy.form.aliyun_dcdn_region.label": "阿里云 DCDN 服务地域", + "workflow_node.deploy.form.aliyun_dcdn_region.label": "阿里云服务地域", "workflow_node.deploy.form.aliyun_dcdn_region.placeholder": "请输入阿里云 DCDN 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_dcdn_region.tooltip": "中国站请填写 cn-hangzhou;
国际站请填写 ap-southeast-1。", "workflow_node.deploy.form.aliyun_dcdn_domain.label": "阿里云 DCDN 加速域名", "workflow_node.deploy.form.aliyun_dcdn_domain.placeholder": "请输入阿里云 DCDN 加速域名", - "workflow_node.deploy.form.aliyun_ddospro_region.label": "阿里云 DDoS 高防服务地域", + "workflow_node.deploy.form.aliyun_ddospro_region.label": "阿里云服务地域", "workflow_node.deploy.form.aliyun_ddospro_region.placeholder": "请输入阿里云 DDoS 高防服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_ddospro_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/anti-ddos/anti-ddos-pro-and-premium/developer-reference/api-ddoscoo-2020-01-01-endpoint", "workflow_node.deploy.form.aliyun_ddospro_domain.label": "阿里云 DDoS 高防网站域名", "workflow_node.deploy.form.aliyun_ddospro_domain.placeholder": "请输入阿里云 DDoS 高防网站域名", - "workflow_node.deploy.form.aliyun_esa_region.label": "阿里云 ESA 服务地域", + "workflow_node.deploy.form.aliyun_esa_region.label": "阿里云服务地域", "workflow_node.deploy.form.aliyun_esa_region.placeholder": "请输入阿里云 ESA 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_esa_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/edge-security-acceleration/esa/api-esa-2024-09-10-endpoint", "workflow_node.deploy.form.aliyun_esa_site_id.label": "阿里云 ESA 站点 ID", "workflow_node.deploy.form.aliyun_esa_site_id.placeholder": "请输入阿里云 ESA 站点 ID", "workflow_node.deploy.form.aliyun_esa_site_id.tooltip": "这是什么?请参阅 https://esa.console.aliyun.com/siteManage/list", - "workflow_node.deploy.form.aliyun_fc_region.label": "阿里云 FC 服务地域", + "workflow_node.deploy.form.aliyun_fc_region.label": "阿里云服务地域", "workflow_node.deploy.form.aliyun_fc_region.placeholder": "请输入阿里云 FC 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_fc_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/functioncompute/fc-3-0/product-overview/supported-regions", "workflow_node.deploy.form.aliyun_fc_service_version.label": "阿里云 FC 服务版本", @@ -322,12 +322,12 @@ "workflow_node.deploy.form.aliyun_ga_snidomain.label": "阿里云全球加速扩展域名(可选)", "workflow_node.deploy.form.aliyun_ga_snidomain.placeholder": "请输入阿里云全球加速扩展域名", "workflow_node.deploy.form.aliyun_ga_snidomain.help": "提示:不填写时,将替换监听器的默认证书;否则,将替换扩展域名证书。", - "workflow_node.deploy.form.aliyun_live_region.label": "阿里云视频直播服务地域", + "workflow_node.deploy.form.aliyun_live_region.label": "阿里云服务地域", "workflow_node.deploy.form.aliyun_live_region.placeholder": "请输入阿里云视频直播服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_live_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/live/product-overview/supported-regions", "workflow_node.deploy.form.aliyun_live_domain.label": "阿里云视频直播流域名", "workflow_node.deploy.form.aliyun_live_domain.placeholder": "请输入阿里云视频直播流域名", - "workflow_node.deploy.form.aliyun_nlb_region.label": "阿里云 NLB 服务地域", + "workflow_node.deploy.form.aliyun_nlb_region.label": "阿里云服务地域", "workflow_node.deploy.form.aliyun_nlb_region.placeholder": "请输入阿里云 NLB 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_nlb_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/slb/network-load-balancer/product-overview/regions-that-support-nlb", "workflow_node.deploy.form.aliyun_nlb_resource_type.label": "证书部署方式", @@ -340,19 +340,19 @@ "workflow_node.deploy.form.aliyun_nlb_listener_id.label": "阿里云 NLB 监听器 ID", "workflow_node.deploy.form.aliyun_nlb_listener_id.placeholder": "请输入阿里云 NLB 监听器 ID", "workflow_node.deploy.form.aliyun_nlb_listener_id.tooltip": "这是什么?请参阅 https://slb.console.aliyun.com/nlb", - "workflow_node.deploy.form.aliyun_oss_region.label": "阿里云 OSS 服务地域", + "workflow_node.deploy.form.aliyun_oss_region.label": "阿里云服务地域", "workflow_node.deploy.form.aliyun_oss_region.placeholder": "请输入阿里云 OSS 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_oss_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/oss/user-guide/regions-and-endpoints", "workflow_node.deploy.form.aliyun_oss_bucket.label": "阿里云 OSS 存储桶名", "workflow_node.deploy.form.aliyun_oss_bucket.placeholder": "请输入阿里云 OSS 存储桶名", "workflow_node.deploy.form.aliyun_oss_domain.label": "阿里云 OSS 自定义域名", "workflow_node.deploy.form.aliyun_oss_domain.placeholder": "请输入阿里云 OSS 自定义域名", - "workflow_node.deploy.form.aliyun_vod_region.label": "阿里云视频点播服务地域", + "workflow_node.deploy.form.aliyun_vod_region.label": "阿里云服务地域", "workflow_node.deploy.form.aliyun_vod_region.placeholder": "请输入阿里云视频点播服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_vod_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/vod/product-overview/regions", "workflow_node.deploy.form.aliyun_vod_domain.label": "阿里云视频点播加速域名", "workflow_node.deploy.form.aliyun_vod_domain.placeholder": "请输入阿里云视频点播加速域名", - "workflow_node.deploy.form.aliyun_waf_region.label": "阿里云 WAF 服务地域", + "workflow_node.deploy.form.aliyun_waf_region.label": "阿里云服务地域", "workflow_node.deploy.form.aliyun_waf_region.placeholder": "请输入阿里云 WAF 服务地域(例如:cn-hangzhou)", "workflow_node.deploy.form.aliyun_waf_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-endpoint", "workflow_node.deploy.form.aliyun_waf_service_version.label": "阿里云 WAF 服务版本", @@ -369,13 +369,13 @@ "workflow_node.deploy.form.apisix_certificate_id.label": "APISIX 证书 ID", "workflow_node.deploy.form.apisix_certificate_id.placeholder": "请输入 APISIX 证书 ID", "workflow_node.deploy.form.apisix_certificate_id.tooltip": "请登录 APISIX 控制台查看", - "workflow_node.deploy.form.aws_acm_region.label": "AWS ACM 服务区域", + "workflow_node.deploy.form.aws_acm_region.label": "AWS 服务区域", "workflow_node.deploy.form.aws_acm_region.placeholder": "请输入 AWS ACM 服务区域(例如:us-east-1)", "workflow_node.deploy.form.aws_acm_region.tooltip": "这是什么?请参阅 https://docs.aws.amazon.com/zh_cn/general/latest/gr/rande.html#regional-endpoints", "workflow_node.deploy.form.aws_acm_certificate_arn.label": "AWS ACM 证书 ARN(可选)", "workflow_node.deploy.form.aws_acm_certificate_arn.placeholder": "请输入 AWS ACM 证书 ARN", "workflow_node.deploy.form.aws_acm_certificate_arn.help": "提示:不填写时,将导入为新证书;否则,将替换原证书。", - "workflow_node.deploy.form.aws_cloudfront_region.label": "AWS CloudFront 服务区域", + "workflow_node.deploy.form.aws_cloudfront_region.label": "AWS 服务区域", "workflow_node.deploy.form.aws_cloudfront_region.placeholder": "请输入 AWS CloudFront 服务区域(例如:us-east-1)", "workflow_node.deploy.form.aws_cloudfront_region.tooltip": "这是什么?请参阅 https://docs.aws.amazon.com/zh_cn/general/latest/gr/rande.html#regional-endpoints", "workflow_node.deploy.form.aws_cloudfront_distribution_id.label": "AWS CloudFront 分配 ID", @@ -383,7 +383,7 @@ "workflow_node.deploy.form.aws_cloudfront_distribution_id.tooltip": "这是什么?请参阅 https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/distribution-working-with.html", "workflow_node.deploy.form.aws_cloudfront_certificate_source.label": "AWS CloudFront 证书来源", "workflow_node.deploy.form.aws_cloudfront_certificate_source.placeholder": "请选择 AWS CloudFront 证书来源", - "workflow_node.deploy.form.aws_iam_region.label": "AWS IAM 服务区域", + "workflow_node.deploy.form.aws_iam_region.label": "AWS 服务区域", "workflow_node.deploy.form.aws_iam_region.placeholder": "请输入 AWS IAM 服务区域(例如:us-east-1)", "workflow_node.deploy.form.aws_iam_region.tooltip": "这是什么?请参阅 https://docs.aws.amazon.com/zh_cn/general/latest/gr/rande.html#regional-endpoints", "workflow_node.deploy.form.aws_iam_certificate_path.label": "AWS IAM 证书路径(可选)", @@ -397,7 +397,7 @@ "workflow_node.deploy.form.azure_keyvault_certificate_name.placeholder": "请输入 Azure KeyVault 证书名称", "workflow_node.deploy.form.azure_keyvault_certificate_name.errmsg.invalid": "证书名称只能包含字母、数字和连字符(-),长度限制为 1 到 127 个字符", "workflow_node.deploy.form.azure_keyvault_certificate_name.help": "提示:不填写时,将由 Certimate 自动生成证书名称。", - "workflow_node.deploy.form.baiducloud_appblb_region.label": "百度智能云 BLB 服务地域", + "workflow_node.deploy.form.baiducloud_appblb_region.label": "百度智能云服务地域", "workflow_node.deploy.form.baiducloud_appblb_region.placeholder": "请输入百度智能云 BLB 服务地域(例如:bj)", "workflow_node.deploy.form.baiducloud_appblb_region.tooltip": "这是什么?请参阅 https://cloud.baidu.com/doc/BLB/s/cjwvxnzix", "workflow_node.deploy.form.baiducloud_appblb_resource_type.label": "证书部署方式", @@ -413,7 +413,7 @@ "workflow_node.deploy.form.baiducloud_appblb_snidomain.label": "百度智能云 BLB 扩展域名(可选)", "workflow_node.deploy.form.baiducloud_appblb_snidomain.placeholder": "请输入百度智能云 BLB 扩展域名", "workflow_node.deploy.form.baiducloud_appblb_snidomain.help": "提示:不填写时,将替换监听器的默认证书;否则,将替换扩展域名证书。", - "workflow_node.deploy.form.baiducloud_blb_region.label": "百度智能云 BLB 服务地域", + "workflow_node.deploy.form.baiducloud_blb_region.label": "百度智能云服务地域", "workflow_node.deploy.form.baiducloud_blb_region.placeholder": "请输入百度智能云 BLB 服务地域(例如:bj)", "workflow_node.deploy.form.baiducloud_blb_region.tooltip": "这是什么?请参阅 https://cloud.baidu.com/doc/BLB/s/cjwvxnzix", "workflow_node.deploy.form.baiducloud_blb_resource_type.label": "证书部署方式", @@ -484,7 +484,7 @@ "workflow_node.deploy.form.ctcccloud_ao_domain.placeholder": "请输入天翼云 AccessOne 加速域名", "workflow_node.deploy.form.ctcccloud_cdn_domain.label": "天翼云 CDN 加速域名", "workflow_node.deploy.form.ctcccloud_cdn_domain.placeholder": "请输入天翼云 CDN 加速域名", - "workflow_node.deploy.form.ctcccloud_elb_region_id.label": "天翼云 ELB 资源池 ID", + "workflow_node.deploy.form.ctcccloud_elb_region_id.label": "天翼云资源池 ID", "workflow_node.deploy.form.ctcccloud_elb_region_id.placeholder": "请输入天翼云 ELB 资源池 ID", "workflow_node.deploy.form.ctcccloud_elb_region_id.tooltip": "这是什么?请参阅 https://www.ctyun.cn/document/10026755/10196575", "workflow_node.deploy.form.ctcccloud_elb_resource_type.label": "证书部署方式", @@ -522,19 +522,19 @@ "workflow_node.deploy.form.goedge_certificate_id.label": "GoEdge 证书 ID", "workflow_node.deploy.form.goedge_certificate_id.placeholder": "请输入 GoEdge 证书 ID", "workflow_node.deploy.form.goedge_certificate_id.tooltip": "请登录 GoEdge 控制台查看", - "workflow_node.deploy.form.huaweicloud_cdn_region.label": "华为云 CDN 服务区域", + "workflow_node.deploy.form.huaweicloud_cdn_region.label": "华为云服务区域", "workflow_node.deploy.form.huaweicloud_cdn_region.placeholder": "请输入华为云 CDN 服务区域(例如:cn-north-1)", "workflow_node.deploy.form.huaweicloud_cdn_region.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_cdn_domain.label": "华为云 CDN 加速域名", "workflow_node.deploy.form.huaweicloud_cdn_domain.placeholder": "请输入华为云 CDN 加速域名", - "workflow_node.deploy.form.huaweicloud_obs_region.label": "华为云 OBS 服务区域", + "workflow_node.deploy.form.huaweicloud_obs_region.label": "华为云服务区域", "workflow_node.deploy.form.huaweicloud_obs_region.placeholder": "请输入华为云 OBS 服务区域(例如:cn-north-1)", "workflow_node.deploy.form.huaweicloud_obs_region.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_obs_bucket.label": "华为云 OBS 存储桶名", "workflow_node.deploy.form.huaweicloud_obs_bucket.placeholder": "请输入华为云 OBS 存储桶名", "workflow_node.deploy.form.huaweicloud_obs_domain.label": "华为云 OBS 自定义域名", "workflow_node.deploy.form.huaweicloud_obs_domain.placeholder": "请输入华为云 OBS 自定义域名", - "workflow_node.deploy.form.huaweicloud_elb_region.label": "华为云 ELB 服务区域", + "workflow_node.deploy.form.huaweicloud_elb_region.label": "华为云服务区域", "workflow_node.deploy.form.huaweicloud_elb_region.placeholder": "请输入华为云 ELB 服务区域(例如:cn-north-1)", "workflow_node.deploy.form.huaweicloud_elb_region.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_elb_resource_type.label": "证书部署方式", @@ -551,7 +551,7 @@ "workflow_node.deploy.form.huaweicloud_elb_listener_id.label": "华为云 ELB 监听器 ID", "workflow_node.deploy.form.huaweicloud_elb_listener_id.placeholder": "请输入华为云 ELB 监听器 ID", "workflow_node.deploy.form.huaweicloud_elb_listener_id.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/vpc/#/elb/list/grid", - "workflow_node.deploy.form.huaweicloud_waf_region.label": "华为云 WAF 服务区域", + "workflow_node.deploy.form.huaweicloud_waf_region.label": "华为云服务区域", "workflow_node.deploy.form.huaweicloud_waf_region.placeholder": "请输入华为云 WAF 服务区域(例如:cn-north-1)", "workflow_node.deploy.form.huaweicloud_waf_region.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/apiexplorer/#/endpoint", "workflow_node.deploy.form.huaweicloud_waf_resource_type.label": "证书部署方式", @@ -564,7 +564,7 @@ "workflow_node.deploy.form.huaweicloud_waf_certificate_id.tooltip": "这是什么?请参阅 https://console.huaweicloud.com/console/#/waf/certificateManagement", "workflow_node.deploy.form.huaweicloud_waf_domain.label": "华为云 WAF 防护域名", "workflow_node.deploy.form.huaweicloud_waf_domain.placeholder": "请输入华为云 WAF 防护域名", - "workflow_node.deploy.form.jdcloud_alb_region_id.label": "京东云 ALB 服务地域 ID", + "workflow_node.deploy.form.jdcloud_alb_region_id.label": "京东云服务地域 ID", "workflow_node.deploy.form.jdcloud_alb_region_id.placeholder": "请输入京东云 ALB 服务地域 ID(例如:cn-north-1", "workflow_node.deploy.form.jdcloud_alb_region_id.tooltip": "这是什么?请参阅 https://docs.jdcloud.com/cn/common-declaration/api/introduction", "workflow_node.deploy.form.jdcloud_alb_resource_type.label": "证书部署方式", @@ -761,15 +761,15 @@ "workflow_node.deploy.form.ssh_preset_scripts.option.ps_binding_rdp.label": "PowerShell - 导入并绑定到 RDP", "workflow_node.deploy.form.ssh_use_scp.label": "回退使用 SCP", "workflow_node.deploy.form.ssh_use_scp.tooltip": "如果你的远程服务器不支持 SFTP,请开启此选项回退为 SCP。", - "workflow_node.deploy.form.tencentcloud_cdn_endpoint.label": "腾讯云 CDN 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_cdn_endpoint.label": "腾讯云接口端点(可选)", "workflow_node.deploy.form.tencentcloud_cdn_endpoint.placeholder": "请输入腾讯云 CDN 接口端点(例如:cdn.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_cdn_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/228/30976
国际站用户请填写 cdn.intl.tencentcloudapi.com。", "workflow_node.deploy.form.tencentcloud_cdn_domain.label": "腾讯云 CDN 加速域名", "workflow_node.deploy.form.tencentcloud_cdn_domain.placeholder": "请输入腾讯云 CDN 加速域名", - "workflow_node.deploy.form.tencentcloud_clb_endpoint.label": "腾讯云 CLB 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_clb_endpoint.label": "腾讯云接口端点(可选)", "workflow_node.deploy.form.tencentcloud_clb_endpoint.placeholder": "请输入腾讯云 CLB 接口端点(例如:clb.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_clb_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/214/30669
国际站用户请填写 clb.intl.tencentcloudapi.com。", - "workflow_node.deploy.form.tencentcloud_clb_region.label": "腾讯云 CLB 产品地域", + "workflow_node.deploy.form.tencentcloud_clb_region.label": "腾讯云服务地域", "workflow_node.deploy.form.tencentcloud_clb_region.placeholder": "请输入腾讯云 CLB 服务地域(例如:ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_clb_region.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/214/33415", "workflow_node.deploy.form.tencentcloud_clb_resource_type.label": "证书部署方式", @@ -785,24 +785,24 @@ "workflow_node.deploy.form.tencentcloud_clb_listener_id.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/clb", "workflow_node.deploy.form.tencentcloud_clb_ruledomain.label": "腾讯云 CLB 七层转发规则域名", "workflow_node.deploy.form.tencentcloud_clb_ruledomain.placeholder": "请输入腾讯云 CLB 七层转发规则域名", - "workflow_node.deploy.form.tencentcloud_cos_region.label": "腾讯云 COS 产品地域", - "workflow_node.deploy.form.tencentcloud_cos_region.placeholder": "请输入腾讯云 COS 产品地域(例如:ap-guangzhou)", + "workflow_node.deploy.form.tencentcloud_cos_region.label": "腾讯云服务地域", + "workflow_node.deploy.form.tencentcloud_cos_region.placeholder": "请输入腾讯云 COS 服务地域(例如:ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_cos_region.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/436/6224", "workflow_node.deploy.form.tencentcloud_cos_bucket.label": "腾讯云 COS 存储桶名", "workflow_node.deploy.form.tencentcloud_cos_bucket.placeholder": "请输入腾讯云 COS 存储桶名", "workflow_node.deploy.form.tencentcloud_cos_domain.label": "腾讯云 COS 自定义域名", "workflow_node.deploy.form.tencentcloud_cos_domain.placeholder": "请输入腾讯云 COS 自定义域名", - "workflow_node.deploy.form.tencentcloud_css_endpoint.label": "腾讯云云直播接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_css_endpoint.label": "腾讯云接口端点(可选)", "workflow_node.deploy.form.tencentcloud_css_endpoint.placeholder": "请输入腾讯云云直播接口端点(例如:live.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_css_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/267/20458
国际站用户请填写 live.intl.tencentcloudapi.com。", "workflow_node.deploy.form.tencentcloud_css_domain.label": "腾讯云云直播播放域名", "workflow_node.deploy.form.tencentcloud_css_domain.placeholder": "请输入腾讯云云直播播放域名", - "workflow_node.deploy.form.tencentcloud_ecdn_endpoint.label": "腾讯云 ECDN 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_ecdn_endpoint.label": "腾讯云接口端点(可选)", "workflow_node.deploy.form.tencentcloud_ecdn_endpoint.placeholder": "请输入腾讯云 ECDN 接口端点(例如:cdn.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_ecdn_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/214/30669
国际站用户请填写 cdn.intl.tencentcloudapi.com。", "workflow_node.deploy.form.tencentcloud_ecdn_domain.label": "腾讯云 ECDN 加速域名", "workflow_node.deploy.form.tencentcloud_ecdn_domain.placeholder": "请输入腾讯云 ECDN 加速域名", - "workflow_node.deploy.form.tencentcloud_eo_endpoint.label": "腾讯云 EdgeOne 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_eo_endpoint.label": "腾讯云接口端点(可选)", "workflow_node.deploy.form.tencentcloud_eo_endpoint.placeholder": "请输入腾讯云 EdgeOne 接口端点(例如:teo.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_eo_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/1552/80723
国际站用户请填写 teo.intl.tencentcloudapi.com。", "workflow_node.deploy.form.tencentcloud_eo_zone_id.label": "腾讯云 EdgeOne 站点 ID", @@ -813,7 +813,7 @@ "workflow_node.deploy.form.tencentcloud_eo_domains.help": "提示:多个域名请用半角分号隔开。", "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.label": "腾讯云接口端点(可选)", "workflow_node.deploy.form.tencentcloud_gaap_endpoint.placeholder": "请输入腾讯云 GAAP 接口端点(例如:gaap.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_gaap_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/608/36934
国际站用户请填写 gaap.intl.tencentcloudapi.com。", "workflow_node.deploy.form.tencentcloud_gaap_resource_type.label": "证书部署方式", @@ -825,23 +825,23 @@ "workflow_node.deploy.form.tencentcloud_gaap_listener_id.label": "腾讯云 GAAP 监听器 ID", "workflow_node.deploy.form.tencentcloud_gaap_listener_id.placeholder": "请输入腾讯云 GAAP 监听器 ID", "workflow_node.deploy.form.tencentcloud_gaap_listener_id.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/gaap", - "workflow_node.deploy.form.tencentcloud_scf_endpoint.label": "腾讯云 SCF 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_scf_endpoint.label": "腾讯云接口端点(可选)", "workflow_node.deploy.form.tencentcloud_scf_endpoint.placeholder": "请输入腾讯云 SCF 接口端点(例如:scf.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_scf_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/583/17237
国际站用户请填写 scf.intl.tencentcloudapi.com。", - "workflow_node.deploy.form.tencentcloud_scf_region.label": "腾讯云 SCF 产品地域", - "workflow_node.deploy.form.tencentcloud_scf_region.placeholder": "输入腾讯云 SCF 产品地域(例如:ap-guangzhou)", + "workflow_node.deploy.form.tencentcloud_scf_region.label": "腾讯云服务地域", + "workflow_node.deploy.form.tencentcloud_scf_region.placeholder": "输入腾讯云 SCF 服务地域(例如:ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_scf_region.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/583/17299", "workflow_node.deploy.form.tencentcloud_scf_domain.label": "腾讯云 SCF 自定义域名", "workflow_node.deploy.form.tencentcloud_scf_domain.placeholder": "输入腾讯云 SCF 自定义域名", - "workflow_node.deploy.form.tencentcloud_ssl_endpoint.label": "腾讯云 SSL 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_ssl_endpoint.label": "腾讯云接口端点(可选)", "workflow_node.deploy.form.tencentcloud_ssl_endpoint.placeholder": "请输入腾讯云 SSL 接口端点(例如:ssl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_ssl_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/41659
国际站用户请填写 ssl.intl.tencentcloudapi.com。", "workflow_node.deploy.form.tencentcloud_ssldeploy.guide": "将通过腾讯云 OpenAPI DeployCertificateInstance 接口创建异步部署任务。此部署目标若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往腾讯云控制台查询。", - "workflow_node.deploy.form.tencentcloud_ssldeploy_endpoint.label": "腾讯云 SSL 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_ssldeploy_endpoint.label": "腾讯云接口端点(可选)", "workflow_node.deploy.form.tencentcloud_ssldeploy_endpoint.placeholder": "请输入腾讯云 SSL 接口端点(例如:ssl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_ssldeploy_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/41659
国际站用户请填写 ssl.intl.tencentcloudapi.com。", - "workflow_node.deploy.form.tencentcloud_ssldeploy_region.label": "腾讯云云产品地域", - "workflow_node.deploy.form.tencentcloud_ssldeploy_region.placeholder": "请输入腾讯云云产品地域(例如:ap-guangzhou)", + "workflow_node.deploy.form.tencentcloud_ssldeploy_region.label": "腾讯云服务地域", + "workflow_node.deploy.form.tencentcloud_ssldeploy_region.placeholder": "请输入腾讯云云产品服务地域(例如:ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_ssldeploy_region.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/41659", "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_type.label": "腾讯云云产品资源类型", "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_type.placeholder": "请输入腾讯云产品资源类型", @@ -854,7 +854,7 @@ "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_ids.multiple_input_modal.title": "修改腾讯云云产品资源 ID", "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_ids.multiple_input_modal.placeholder": "请输入腾讯云云产品资源 ID", "workflow_node.deploy.form.tencentcloud_sslupdate.guide": "将通过腾讯云 OpenAPI UpdateCertificateInstance 或 UploadUpdateCertificateInstance 接口创建异步部署任务。此部署目标若执行成功仅代表已创建部署任务,实际部署结果需要你自行前往腾讯云控制台查询。", - "workflow_node.deploy.form.tencentcloud_sslupdate_endpoint.label": "腾讯云 SSL 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_sslupdate_endpoint.label": "腾讯云接口端点(可选)", "workflow_node.deploy.form.tencentcloud_sslupdate_endpoint.placeholder": "请输入腾讯云 SSL 接口端点(例如:ssl.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_sslupdate_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/41659
国际站用户请填写 ssl.intl.tencentcloudapi.com。", "workflow_node.deploy.form.tencentcloud_sslupdate_certificate_id.label": "腾讯云原证书 ID", @@ -874,7 +874,7 @@ "workflow_node.deploy.form.tencentcloud_sslupdate_resource_regions.multiple_input_modal.placeholder": "请输入腾讯云云产品部署地域", "workflow_node.deploy.form.tencentcloud_sslupdate_is_replaced.label": "是否更新原证书(即证书 ID 保持不变)", "workflow_node.deploy.form.tencentcloud_sslupdate_is_replaced.tooltip": "不勾选时,将调用腾讯云 OpenAPI UpdateCertificateInstance 接口;否则,将调用腾讯云 OpenAPI UploadUpdateCertificateInstance 接口。", - "workflow_node.deploy.form.tencentcloud_vod_endpoint.label": "腾讯云云点播接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_vod_endpoint.label": "腾讯云接口端点(可选)", "workflow_node.deploy.form.tencentcloud_vod_endpoint.placeholder": "请输入腾讯云云点播接口端点(例如:vod.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_vod_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/266/31755
国际站用户请填写 vod.intl.tencentcloudapi.com。", "workflow_node.deploy.form.tencentcloud_vod_sub_app_id.label": "腾讯云云点播应用 ID", @@ -882,11 +882,11 @@ "workflow_node.deploy.form.tencentcloud_vod_sub_app_id.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/vod", "workflow_node.deploy.form.tencentcloud_vod_domain.label": "腾讯云云点播加速域名", "workflow_node.deploy.form.tencentcloud_vod_domain.placeholder": "请输入腾讯云云点播加速域名", - "workflow_node.deploy.form.tencentcloud_waf_endpoint.label": "腾讯云 WAF 接口端点(可选)", + "workflow_node.deploy.form.tencentcloud_waf_endpoint.label": "腾讯云接口端点(可选)", "workflow_node.deploy.form.tencentcloud_waf_endpoint.placeholder": "请输入腾讯云 WAF 接口端点(例如:waf.tencentcloudapi.com)", "workflow_node.deploy.form.tencentcloud_waf_endpoint.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/627/53611
国际站用户请填写 waf.intl.tencentcloudapi.com。", - "workflow_node.deploy.form.tencentcloud_waf_region.label": "腾讯云 WAF 产品地域", - "workflow_node.deploy.form.tencentcloud_waf_region.placeholder": "请输入腾讯云 WAF 产品地域(例如:ap-guangzhou)", + "workflow_node.deploy.form.tencentcloud_waf_region.label": "腾讯云服务地域", + "workflow_node.deploy.form.tencentcloud_waf_region.placeholder": "请输入腾讯云 WAF 服务地域(例如:ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_waf_region.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/627/47525", "workflow_node.deploy.form.tencentcloud_waf_domain.label": "腾讯云 WAF 防护域名", "workflow_node.deploy.form.tencentcloud_waf_domain.placeholder": "请输入腾讯云 WAF 防护域名", @@ -899,7 +899,7 @@ "workflow_node.deploy.form.ucloud_ucdn_domain_id.label": "优刻得 UCDN 域名 ID", "workflow_node.deploy.form.ucloud_ucdn_domain_id.placeholder": "请输入优刻得 UCDN 域名 ID", "workflow_node.deploy.form.ucloud_ucdn_domain_id.tooltip": "这是什么?请参阅 https://console.ucloud.cn/ucdn", - "workflow_node.deploy.form.ucloud_us3_region.label": "优刻得 US3 服务地域", + "workflow_node.deploy.form.ucloud_us3_region.label": "优刻得服务地域", "workflow_node.deploy.form.ucloud_us3_region.placeholder": "优刻得 US3 服务地域(例如:cn-bj2)", "workflow_node.deploy.form.ucloud_us3_region.tooltip": "这是什么?请参阅 https://docs.ucloud.cn/api/summary/regionlist", "workflow_node.deploy.form.ucloud_us3_bucket.label": "优刻得 US3 存储桶名", @@ -928,7 +928,7 @@ "workflow_node.deploy.form.volcengine_alb_resource_type.placeholder": "请选择证书部署方式", "workflow_node.deploy.form.volcengine_alb_resource_type.option.loadbalancer.label": "替换指定负载均衡器下的全部 HTTPS 监听的证书", "workflow_node.deploy.form.volcengine_alb_resource_type.option.listener.label": "替换指定监听器的证书", - "workflow_node.deploy.form.volcengine_alb_region.label": "火山引擎 ALB 服务地域", + "workflow_node.deploy.form.volcengine_alb_region.label": "火山引擎服务地域", "workflow_node.deploy.form.volcengine_alb_region.placeholder": "请输入火山引擎 ALB 服务地域(例如:cn-beijing)", "workflow_node.deploy.form.volcengine_alb_region.tooltip": "这是什么?请参阅 https://www.volcengine.com/docs/6767/127501", "workflow_node.deploy.form.volcengine_alb_loadbalancer_id.label": "火山引擎 ALB 负载均衡器 ID", @@ -942,13 +942,13 @@ "workflow_node.deploy.form.volcengine_alb_snidomain.help": "提示:不填写时,将替换监听器的默认证书;否则,将替换扩展域名证书。", "workflow_node.deploy.form.volcengine_cdn_domain.label": "火山引擎 CDN 加速域名", "workflow_node.deploy.form.volcengine_cdn_domain.placeholder": "请输入火山引擎 CDN 加速域名", - "workflow_node.deploy.form.volcengine_certcenter_region.label": "火山引擎证书中心服务地域", + "workflow_node.deploy.form.volcengine_certcenter_region.label": "火山引擎服务地域", "workflow_node.deploy.form.volcengine_certcenter_region.placeholder": "请输入火山引擎证书中心服务地域(例如:cn-beijing)", "workflow_node.deploy.form.volcengine_clb_resource_type.label": "证书部署方式", "workflow_node.deploy.form.volcengine_clb_resource_type.placeholder": "请选择证书部署方式", "workflow_node.deploy.form.volcengine_clb_resource_type.option.loadbalancer.label": "替换指定负载均衡器下的全部 HTTPS 监听的证书", "workflow_node.deploy.form.volcengine_clb_resource_type.option.listener.label": "替换指定监听器的证书", - "workflow_node.deploy.form.volcengine_clb_region.label": "火山引擎 CLB 服务地域", + "workflow_node.deploy.form.volcengine_clb_region.label": "火山引擎服务地域", "workflow_node.deploy.form.volcengine_clb_region.placeholder": "请输入火山引擎 CLB 服务地域(例如:cn-beijing)", "workflow_node.deploy.form.volcengine_clb_region.tooltip": "这是什么?请参阅 https://www.volcengine.com/docs/6406/74892", "workflow_node.deploy.form.volcengine_clb_loadbalancer_id.label": "火山引擎 CLB 负载均衡器 ID", @@ -959,7 +959,7 @@ "workflow_node.deploy.form.volcengine_clb_listener_id.tooltip": "这是什么?请参阅 https://console.volcengine.com/clb/LoadBalancer", "workflow_node.deploy.form.volcengine_dcdn_domain.label": "火山引擎 DCDN 加速域名", "workflow_node.deploy.form.volcengine_dcdn_domain.placeholder": "请输入火山引擎 DCDN 加速域名", - "workflow_node.deploy.form.volcengine_imagex_region.label": "火山引擎 ImageX 服务地域", + "workflow_node.deploy.form.volcengine_imagex_region.label": "火山引擎服务地域", "workflow_node.deploy.form.volcengine_imagex_region.placeholder": "请输入火山引擎 ImageX 服务地域(例如:cn-north-1)", "workflow_node.deploy.form.volcengine_imagex_region.tooltip": "这是什么?请参阅 https://www.volcengine.com/docs/508/23757", "workflow_node.deploy.form.volcengine_imagex_service_id.label": "火山引擎 ImageX 服务 ID", @@ -969,7 +969,7 @@ "workflow_node.deploy.form.volcengine_imagex_domain.placeholder": "请输入火山引擎 ImageX 绑定域名", "workflow_node.deploy.form.volcengine_live_domain.label": "火山引擎视频直播流域名", "workflow_node.deploy.form.volcengine_live_domain.placeholder": "请输入火山引擎视频直播流域名", - "workflow_node.deploy.form.volcengine_tos_region.label": "火山引擎 TOS 服务地域", + "workflow_node.deploy.form.volcengine_tos_region.label": "火山引擎服务地域", "workflow_node.deploy.form.volcengine_tos_region.placeholder": "请输入火山引擎 TOS 服务地域(例如:cn-beijing)", "workflow_node.deploy.form.volcengine_tos_region.tooltip": "这是什么?请参阅 https://www.volcengine.com/docs/6349/107356", "workflow_node.deploy.form.volcengine_tos_bucket.label": "火山引擎 TOS 存储桶名", From ec91575fefe0b7adafabdf7fc6b58a8f952cd6c7 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Fri, 14 Nov 2025 18:54:40 +0800 Subject: [PATCH 2/2] feat(provider): supoprt cloud product access type in deployment to aliyun waf --- .../certdeploy/deployers/sp_aliyun_waf.go | 4 + .../deployers/sp_tencentcloud_ssldeploy.go | 12 +- .../deployers/sp_tencentcloud_sslupdate.go | 14 +- migrations/1762905600_m0.4.5.go | 37 --- migrations/1763092800_m0.4.5.go | 218 ++++++++++++++++++ .../aliyun-apigw/aliyun_apigw_test.go | 4 +- .../providers/aliyun-waf/aliyun_waf.go | 203 +++++++++++++++- .../providers/aliyun-waf/consts.go | 8 + .../providers/aliyun-waf/internal/client.go | 202 ++++++++++++++++ .../tencentcloud_ssl_deploy.go | 12 +- .../tencentcloud_ssl_update.go | 32 +-- ...loyNodeConfigFieldsProviderAliyunAPIGW.tsx | 20 +- ...eployNodeConfigFieldsProviderAliyunWAF.tsx | 121 ++++++++-- ...figFieldsProviderTencentCloudSSLDeploy.tsx | 14 +- ...figFieldsProviderTencentCloudSSLUpdate.tsx | 22 +- .../i18n/locales/en/nls.workflow.nodes.json | 38 +-- .../i18n/locales/zh/nls.workflow.nodes.json | 40 ++-- 17 files changed, 848 insertions(+), 153 deletions(-) delete mode 100644 migrations/1762905600_m0.4.5.go create mode 100644 migrations/1763092800_m0.4.5.go create mode 100644 pkg/core/ssl-deployer/providers/aliyun-waf/consts.go diff --git a/internal/certdeploy/deployers/sp_aliyun_waf.go b/internal/certdeploy/deployers/sp_aliyun_waf.go index 03a2074ea..247ecd07e 100644 --- a/internal/certdeploy/deployers/sp_aliyun_waf.go +++ b/internal/certdeploy/deployers/sp_aliyun_waf.go @@ -22,7 +22,11 @@ func init() { ResourceGroupId: credentials.ResourceGroupId, Region: xmaps.GetString(options.ProviderExtendedConfig, "region"), ServiceVersion: xmaps.GetOrDefaultString(options.ProviderExtendedConfig, "serviceVersion", "3.0"), + ServiceType: xmaps.GetString(options.ProviderExtendedConfig, "serviceType"), InstanceId: xmaps.GetString(options.ProviderExtendedConfig, "instanceId"), + ResourceProduct: xmaps.GetString(options.ProviderExtendedConfig, "resourceProduct"), + ResourceId: xmaps.GetString(options.ProviderExtendedConfig, "resourceId"), + ResourcePort: xmaps.GetOrDefaultInt32(options.ProviderExtendedConfig, "resourcePort", 443), Domain: xmaps.GetString(options.ProviderExtendedConfig, "domain"), }) return provider, err diff --git a/internal/certdeploy/deployers/sp_tencentcloud_ssldeploy.go b/internal/certdeploy/deployers/sp_tencentcloud_ssldeploy.go index dcb13e429..e8643c1c7 100644 --- a/internal/certdeploy/deployers/sp_tencentcloud_ssldeploy.go +++ b/internal/certdeploy/deployers/sp_tencentcloud_ssldeploy.go @@ -20,12 +20,12 @@ func init() { } provider, err := tencentcloudssldeploy.NewSSLDeployerProvider(&tencentcloudssldeploy.SSLDeployerProviderConfig{ - SecretId: credentials.SecretId, - SecretKey: credentials.SecretKey, - Endpoint: xmaps.GetString(options.ProviderExtendedConfig, "endpoint"), - Region: xmaps.GetString(options.ProviderExtendedConfig, "region"), - ResourceType: xmaps.GetString(options.ProviderExtendedConfig, "resourceType"), - ResourceIds: lo.Filter(strings.Split(xmaps.GetString(options.ProviderExtendedConfig, "resourceIds"), ";"), func(s string, _ int) bool { return s != "" }), + SecretId: credentials.SecretId, + SecretKey: credentials.SecretKey, + Endpoint: xmaps.GetString(options.ProviderExtendedConfig, "endpoint"), + Region: xmaps.GetString(options.ProviderExtendedConfig, "region"), + ResourceProduct: xmaps.GetString(options.ProviderExtendedConfig, "resourceProduct"), + ResourceIds: lo.Filter(strings.Split(xmaps.GetString(options.ProviderExtendedConfig, "resourceIds"), ";"), func(s string, _ int) bool { return s != "" }), }) return provider, err }) diff --git a/internal/certdeploy/deployers/sp_tencentcloud_sslupdate.go b/internal/certdeploy/deployers/sp_tencentcloud_sslupdate.go index 26430b14c..f472d6d19 100644 --- a/internal/certdeploy/deployers/sp_tencentcloud_sslupdate.go +++ b/internal/certdeploy/deployers/sp_tencentcloud_sslupdate.go @@ -20,13 +20,13 @@ func init() { } provider, err := tencentcloudsslupdate.NewSSLDeployerProvider(&tencentcloudsslupdate.SSLDeployerProviderConfig{ - SecretId: credentials.SecretId, - SecretKey: credentials.SecretKey, - Endpoint: xmaps.GetString(options.ProviderExtendedConfig, "endpoint"), - CertificateId: xmaps.GetString(options.ProviderExtendedConfig, "certificateId"), - IsReplaced: xmaps.GetBool(options.ProviderExtendedConfig, "isReplaced"), - ResourceTypes: lo.Filter(strings.Split(xmaps.GetString(options.ProviderExtendedConfig, "resourceTypes"), ";"), func(s string, _ int) bool { return s != "" }), - ResourceRegions: lo.Filter(strings.Split(xmaps.GetString(options.ProviderExtendedConfig, "resourceRegions"), ";"), func(s string, _ int) bool { return s != "" }), + SecretId: credentials.SecretId, + SecretKey: credentials.SecretKey, + Endpoint: xmaps.GetString(options.ProviderExtendedConfig, "endpoint"), + CertificateId: xmaps.GetString(options.ProviderExtendedConfig, "certificateId"), + IsReplaced: xmaps.GetBool(options.ProviderExtendedConfig, "isReplaced"), + ResourceProducts: lo.Filter(strings.Split(xmaps.GetString(options.ProviderExtendedConfig, "resourceProducts"), ";"), func(s string, _ int) bool { return s != "" }), + ResourceRegions: lo.Filter(strings.Split(xmaps.GetString(options.ProviderExtendedConfig, "resourceRegions"), ";"), func(s string, _ int) bool { return s != "" }), }) return provider, err }) diff --git a/migrations/1762905600_m0.4.5.go b/migrations/1762905600_m0.4.5.go deleted file mode 100644 index a6de954c3..000000000 --- a/migrations/1762905600_m0.4.5.go +++ /dev/null @@ -1,37 +0,0 @@ -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.4.5") - tracer.Printf("go ...") - - // adapt to new workflow data structure - { - if _, err := app.DB().NewQuery("UPDATE workflow SET graphDraft = REPLACE(graphDraft, '\"matchPattern\"', '\"domainMatchPattern\"')").Execute(); err != nil { - return err - } - - if _, err := app.DB().NewQuery("UPDATE workflow SET graphContent = REPLACE(graphContent, '\"matchPattern\"', '\"domainMatchPattern\"')").Execute(); err != nil { - return err - } - - if _, err := app.DB().NewQuery("UPDATE workflow_run SET graph = REPLACE(graph, '\"matchPattern\"', '\"domainMatchPattern\"')").Execute(); err != nil { - return err - } - - if _, err := app.DB().NewQuery("UPDATE workflow_output SET nodeConfig = REPLACE(nodeConfig, '\"matchPattern\"', '\"domainMatchPattern\"')").Execute(); err != nil { - return err - } - } - - tracer.Printf("done") - return nil - }, func(app core.App) error { - return nil - }) -} diff --git a/migrations/1763092800_m0.4.5.go b/migrations/1763092800_m0.4.5.go new file mode 100644 index 000000000..dd19ffd10 --- /dev/null +++ b/migrations/1763092800_m0.4.5.go @@ -0,0 +1,218 @@ +package migrations + +import ( + "github.com/go-viper/mapstructure/v2" + "github.com/pocketbase/pocketbase/core" + m "github.com/pocketbase/pocketbase/migrations" +) + +func init() { + m.Register(func(app core.App) error { + tracer := NewTracer("v0.4.5") + tracer.Printf("go ...") + + // adapt to new workflow data structure + { + type dWorkflowNode struct { + Id string `json:"id"` + Type string `json:"type"` + Data map[string]any `json:"data"` + Blocks []*dWorkflowNode `json:"blocks,omitempty,omitzero"` + } + + var deepMigrateNode func(node *dWorkflowNode) (_node *dWorkflowNode, _migrated bool) + var deepMigrateNodes func(nodes []*dWorkflowNode) (_nodes []*dWorkflowNode, _migrated bool) + deepMigrateNode = func(node *dWorkflowNode) (*dWorkflowNode, bool) { + migrated := false + + if node.Type == "bizDeploy" { + if node.Data != nil { + if _, ok := node.Data["config"]; ok { + nodeCfg := node.Data["config"].(map[string]any) + if nodeCfg["provider"] == "tencentcloud-ssldeploy" { + if nodeCfg["providerConfig"] != nil { + providerCfg := nodeCfg["providerConfig"].(map[string]any) + providerCfg["resourceProduct"] = providerCfg["resourceType"] + delete(providerCfg, "resourceType") + nodeCfg["providerConfig"] = providerCfg + + node.Data["config"] = nodeCfg + migrated = true + } + } else if nodeCfg["provider"] == "tencentcloud-sslupdate" { + if nodeCfg["providerConfig"] != nil { + providerCfg := nodeCfg["providerConfig"].(map[string]any) + providerCfg["resourceProducts"] = providerCfg["resourceTypes"] + delete(providerCfg, "resourceTypes") + nodeCfg["providerConfig"] = providerCfg + + node.Data["config"] = nodeCfg + migrated = true + } + } else if nodeCfg["provider"] == "aliyun-waf" { + if nodeCfg["providerConfig"] != nil { + providerCfg := nodeCfg["providerConfig"].(map[string]any) + providerCfg["serviceType"] = "cname" + nodeCfg["providerConfig"] = providerCfg + + node.Data["config"] = nodeCfg + migrated = true + } + } + } + } + } + + if len(node.Blocks) > 0 { + if newBlocks, changed := deepMigrateNodes(node.Blocks); changed { + node.Blocks = newBlocks + migrated = true + } + } + + return node, migrated + } + deepMigrateNodes = func(nodes []*dWorkflowNode) ([]*dWorkflowNode, bool) { + migrated := false + + for i, node := range nodes { + if newNode, changed := deepMigrateNode(node); changed { + nodes[i] = newNode + migrated = true + } + } + + return nodes, migrated + } + + // update collection `workflow` + // - migrate field `graphDraft` / `graphContent` + { + collection, err := app.FindCollectionByNameOrId("tovyif5ax6j62ur") + if err != nil { + return err + } + + records, err := app.FindAllRecords(collection) + if err != nil { + return err + } + + for _, record := range records { + changed := false + + graphDraft := make(map[string]any) + if err := record.UnmarshalJSONField("graphDraft", &graphDraft); err == nil { + if _, ok := graphDraft["nodes"]; ok { + nodes := make([]*dWorkflowNode, 0) + if err := mapstructure.Decode(graphDraft["nodes"], &nodes); err != nil { + return err + } + + if newNodes, migrated := deepMigrateNodes(nodes); migrated { + graphDraft["nodes"] = newNodes + record.Set("graphDraft", graphDraft) + changed = true + } + } + } + + graphContent := make(map[string]any) + if err := record.UnmarshalJSONField("graphContent", &graphContent); err == nil { + if _, ok := graphContent["nodes"]; ok { + nodes := make([]*dWorkflowNode, 0) + if err := mapstructure.Decode(graphContent["nodes"], &nodes); err != nil { + return err + } + + if newNodes, migrated := deepMigrateNodes(nodes); migrated { + graphContent["nodes"] = newNodes + record.Set("graphContent", graphContent) + changed = true + } + } + } + + if changed { + if err := app.Save(record); err != nil { + return err + } + + tracer.Printf("record #%s in collection '%s' updated", record.Id, collection.Name) + } + } + + if _, err := app.DB().NewQuery("UPDATE workflow SET graphDraft = REPLACE(graphDraft, '\"matchPattern\"', '\"domainMatchPattern\"')").Execute(); err != nil { + return err + } + + if _, err := app.DB().NewQuery("UPDATE workflow SET graphContent = REPLACE(graphContent, '\"matchPattern\"', '\"domainMatchPattern\"')").Execute(); err != nil { + return err + } + } + + // update collection `workflow_run` + // - migrate field `graph` + { + collection, err := app.FindCollectionByNameOrId("qjp8lygssgwyqyz") + if err != nil { + return err + } + + records, err := app.FindAllRecords(collection) + if err != nil { + return err + } + + for _, record := range records { + changed := false + + graph := make(map[string]any) + if err := record.UnmarshalJSONField("graph", &graph); err == nil { + if _, ok := graph["nodes"]; ok { + nodes := make([]*dWorkflowNode, 0) + if err := mapstructure.Decode(graph["nodes"], &nodes); err != nil { + return err + } + + if newNodes, migrated := deepMigrateNodes(nodes); migrated { + graph["nodes"] = newNodes + record.Set("graph", graph) + changed = true + } + } + } + + if changed { + if err := app.Save(record); err != nil { + return err + } + + tracer.Printf("record #%s in collection '%s' updated", record.Id, collection.Name) + } + } + + if _, err := app.DB().NewQuery("UPDATE workflow_run SET graph = REPLACE(graph, '\"matchPattern\"', '\"domainMatchPattern\"')").Execute(); err != nil { + return err + } + } + + // update collection `workflow_output` + // - migrate field `nodeConfig` + { + if _, err := app.DB().NewQuery("UPDATE workflow_output SET nodeConfig = REPLACE(nodeConfig, '\"matchPattern\"', '\"domainMatchPattern\"')").Execute(); err != nil { + return err + } + + if _, err := app.DB().NewQuery("UPDATE workflow_output SET nodeConfig = REPLACE(nodeConfig, '\"resourceType\"', '\"resourceProduct\"') WHERE nodeConfig LIKE '%\"provider\":\"tencentcloud-ssldeploy\"%' OR nodeConfig LIKE '%\"provider\":\"tencentcloud-sslupdate\"%'").Execute(); err != nil { + return err + } + } + } + + tracer.Printf("done") + return nil + }, func(app core.App) error { + return nil + }) +} diff --git a/pkg/core/ssl-deployer/providers/aliyun-apigw/aliyun_apigw_test.go b/pkg/core/ssl-deployer/providers/aliyun-apigw/aliyun_apigw_test.go index 2ed1b0527..00bd1b984 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-apigw/aliyun_apigw_test.go +++ b/pkg/core/ssl-deployer/providers/aliyun-apigw/aliyun_apigw_test.go @@ -46,9 +46,9 @@ Shell command to run this test: --CERTIMATE_SSLDEPLOYER_ALIYUNAPIGW_ACCESSKEYID="your-access-key-id" \ --CERTIMATE_SSLDEPLOYER_ALIYUNAPIGW_ACCESSKEYSECRET="your-access-key-secret" \ --CERTIMATE_SSLDEPLOYER_ALIYUNAPIGW_REGION="cn-hangzhou" \ + --CERTIMATE_SSLDEPLOYER_ALIYUNAPIGW_SERVICETYPE="cloudnative" \ --CERTIMATE_SSLDEPLOYER_ALIYUNAPIGW_GATEWAYID="your-api-gateway-id" \ --CERTIMATE_SSLDEPLOYER_ALIYUNAPIGW_GROUPID="your-api-group-id" \ - --CERTIMATE_SSLDEPLOYER_ALIYUNAPIGW_SERVICETYPE="cloudnative" \ --CERTIMATE_SSLDEPLOYER_ALIYUNAPIGW_DOMAIN="example.com" */ func TestDeploy(t *testing.T) { @@ -62,9 +62,9 @@ func TestDeploy(t *testing.T) { fmt.Sprintf("ACCESSKEYID: %v", fAccessKeyId), fmt.Sprintf("ACCESSKEYSECRET: %v", fAccessKeySecret), fmt.Sprintf("REGION: %v", fRegion), + fmt.Sprintf("SERVICETYPE: %v", fServiceType), fmt.Sprintf("GATEWAYID: %v", fGatewayId), fmt.Sprintf("GROUPID: %v", fGroupId), - fmt.Sprintf("SERVICETYPE: %v", fServiceType), fmt.Sprintf("DOMAIN: %v", fDomain), }, "\n")) diff --git a/pkg/core/ssl-deployer/providers/aliyun-waf/aliyun_waf.go b/pkg/core/ssl-deployer/providers/aliyun-waf/aliyun_waf.go index f12321f9f..dfe66d574 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-waf/aliyun_waf.go +++ b/pkg/core/ssl-deployer/providers/aliyun-waf/aliyun_waf.go @@ -6,6 +6,7 @@ import ( "fmt" "log/slog" "strings" + "time" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client" "github.com/alibabacloud-go/tea/dara" @@ -28,10 +29,22 @@ type SSLDeployerProviderConfig struct { // 阿里云地域。 Region string `json:"region"` // 服务版本。 + // 可取值 "3.0"。 ServiceVersion string `json:"serviceVersion"` + // 服务类型。 + ServiceType string `json:"serviceType"` // WAF 实例 ID。 InstanceId string `json:"instanceId"` - // 接入域名(支持泛域名)。 + // 云产品类型。 + // 服务类型为 [SERVICE_TYPE_CLOUDRESOURCE] 时必填。 + ResourceProduct string `json:"resourceProduct,omitempty"` + // 云产品资源 ID。 + // 服务类型为 [SERVICE_TYPE_CLOUDRESOURCE] 时必填。 + ResourceId string `json:"resourceId,omitempty"` + // 云产品资源端口。 + // 服务类型为 [SERVICE_TYPE_CLOUDRESOURCE] 时必填。 + ResourcePort int32 `json:"resourcePort,omitempty"` + // 扩展域名(支持泛域名)。 Domain string `json:"domain,omitempty"` } @@ -85,10 +98,6 @@ func (d *SSLDeployerProvider) SetLogger(logger *slog.Logger) { } func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*core.SSLDeployResult, error) { - if d.config.InstanceId == "" { - return nil, errors.New("config `instanceId` is required") - } - switch d.config.ServiceVersion { case "3", "3.0": if err := d.deployToWAF3(ctx, certPEM, privkeyPEM); err != nil { @@ -103,6 +112,10 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke } func (d *SSLDeployerProvider) deployToWAF3(ctx context.Context, certPEM string, privkeyPEM string) error { + if d.config.InstanceId == "" { + return errors.New("config `instanceId` is required") + } + // 上传证书 upres, err := d.sslManager.Upload(ctx, certPEM, privkeyPEM) if err != nil { @@ -111,8 +124,180 @@ func (d *SSLDeployerProvider) deployToWAF3(ctx context.Context, certPEM string, d.logger.Info("ssl certificate uploaded", slog.Any("result", upres)) } + // 根据接入方式决定部署方式 + switch d.config.ServiceType { + case SERVICE_TYPE_CLOUDRESOURCE: + certId := upres.ExtendedData["CertIdentifier"].(string) + if err := d.deployToWAF3WithCloudResource(ctx, certId); err != nil { + return err + } + + case SERVICE_TYPE_CNAME: + certId := upres.ExtendedData["CertIdentifier"].(string) + if err := d.deployToWAF3WithCNAME(ctx, certId); err != nil { + return err + } + + default: + return fmt.Errorf("unsupported service version '%s'", d.config.ServiceVersion) + } + + return nil +} + +func (d *SSLDeployerProvider) deployToWAF3WithCloudResource(ctx context.Context, cloudCertId string) error { + if d.config.ResourceProduct == "" { + return errors.New("config `resourceProduct` is required") + } + if d.config.ResourceId == "" { + return errors.New("config `resourceId` is required") + } + if d.config.ResourcePort == 0 { + d.config.ResourcePort = 443 + } + + // 查询已同步的云产品资产 + // REF: https://www.alibabacloud.com/help/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-describeproductinstances + var resourceInstance *aliwaf.DescribeProductInstancesResponseBodyProductInstances + var resourceInstancePort *aliwaf.DescribeProductInstancesResponseBodyProductInstancesResourcePorts + describeProductInstancesReq := &aliwaf.DescribeProductInstancesRequest{ + ResourceManagerResourceGroupId: lo.EmptyableToPtr(d.config.ResourceGroupId), + RegionId: tea.String(d.config.Region), + InstanceId: tea.String(d.config.InstanceId), + ResourceProduct: tea.String(d.config.ResourceProduct), + ResourceInstanceId: tea.String(d.config.ResourceId), + } + describeProductInstancesResp, err := d.sdkClient.DescribeProductInstancesWithContext(ctx, describeProductInstancesReq, &dara.RuntimeOptions{}) + d.logger.Debug("sdk request 'waf.DescribeProductInstances'", slog.Any("request", describeProductInstancesReq), slog.Any("response", describeProductInstancesResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request 'waf.DescribeProductInstances': %w", err) + } else if len(describeProductInstancesResp.Body.ProductInstances) == 0 { + return fmt.Errorf("cloud not find waf '%s' cloud resource '%s %s'", d.config.InstanceId, d.config.ResourceProduct, d.config.ResourceId) + } else { + resourceInstance = describeProductInstancesResp.Body.ProductInstances[0] + + resourceInstancePort, _ = lo.Find(resourceInstance.ResourcePorts, func(p *aliwaf.DescribeProductInstancesResponseBodyProductInstancesResourcePorts) bool { + return tea.Int32Value(p.Port) == d.config.ResourcePort + }) + if resourceInstancePort == nil { + return fmt.Errorf("could not find waf '%s' cloud resource '%s %s:%d'", d.config.InstanceId, d.config.ResourceProduct, d.config.ResourceId, d.config.ResourcePort) + } + } + + // 查询云产品实例的证书列表 + var resourceInstanceCertificates []*aliwaf.DescribeResourceInstanceCertsResponseBodyCerts = make([]*aliwaf.DescribeResourceInstanceCertsResponseBodyCerts, 0) + describeResourceInstanceCertsPageNumber := 1 + describeResourceInstanceCertsPageSize := 10 + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + describeResourceInstanceCertsReq := &aliwaf.DescribeResourceInstanceCertsRequest{ + ResourceManagerResourceGroupId: lo.EmptyableToPtr(d.config.ResourceGroupId), + InstanceId: tea.String(d.config.InstanceId), + ResourceInstanceId: tea.String(d.config.ResourceId), + PageNumber: tea.Int64(int64(describeResourceInstanceCertsPageNumber)), + PageSize: tea.Int64(int64(describeResourceInstanceCertsPageSize)), + } + describeResourceInstanceCertsResp, err := d.sdkClient.DescribeResourceInstanceCertsWithContext(ctx, describeResourceInstanceCertsReq, &dara.RuntimeOptions{}) + d.logger.Debug("sdk request 'waf.DescribeResourceInstanceCerts'", slog.Any("request", describeResourceInstanceCertsReq), slog.Any("response", describeResourceInstanceCertsResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request 'wafw.DescribeResourceInstanceCerts': %w", err) + } + + if describeResourceInstanceCertsResp.Body == nil { + break + } + + resourceInstanceCertificates = append(resourceInstanceCertificates, describeResourceInstanceCertsResp.Body.Certs...) + + if len(describeResourceInstanceCertsResp.Body.Certs) < describeResourceInstanceCertsPageSize { + break + } + + describeResourceInstanceCertsPageNumber++ + } + + // 生成请求参数 + modifyCloudResourceReq := &aliwaf.ModifyCloudResourceRequest{ + ResourceManagerResourceGroupId: lo.EmptyableToPtr(d.config.ResourceGroupId), + RegionId: tea.String(d.config.Region), + Listen: &aliwaf.ModifyCloudResourceRequestListen{ + ResourceProduct: resourceInstance.ResourceProduct, + ResourceInstanceId: resourceInstance.ResourceInstanceId, + Protocol: tea.String("https"), + Port: resourceInstancePort.Port, + Certificates: lo.Map(resourceInstancePort.Certificates, func(c *aliwaf.DescribeProductInstancesResponseBodyProductInstancesResourcePortsCertificates, _ int) *aliwaf.ModifyCloudResourceRequestListenCertificates { + return &aliwaf.ModifyCloudResourceRequestListenCertificates{ + CertificateId: c.CertificateId, + AppliedType: c.AppliedType, + } + }), + }, + } if d.config.Domain == "" { - // 未指定接入域名,只需替换默认证书即可 + // 未指定扩展域名,只需替换默认证书 + const certAppliedTypeDefault = "default" + for _, certItem := range modifyCloudResourceReq.Listen.Certificates { + if tea.StringValue(certItem.AppliedType) == certAppliedTypeDefault && + tea.StringValue(certItem.CertificateId) == cloudCertId { + return nil + } + } + + modifyCloudResourceReq.Listen.Certificates = lo.Filter(modifyCloudResourceReq.Listen.Certificates, func(c *aliwaf.ModifyCloudResourceRequestListenCertificates, _ int) bool { + return tea.StringValue(c.AppliedType) != certAppliedTypeDefault + }) + modifyCloudResourceReq.Listen.Certificates = append(modifyCloudResourceReq.Listen.Certificates, &aliwaf.ModifyCloudResourceRequestListenCertificates{ + CertificateId: tea.String(cloudCertId), + AppliedType: tea.String(certAppliedTypeDefault), + }) + } else { + // 指定扩展域名,需替换扩展证书 + const certAppliedTypeExtension = "extension" + + modifyCloudResourceReq.Listen.Certificates = append(modifyCloudResourceReq.Listen.Certificates, &aliwaf.ModifyCloudResourceRequestListenCertificates{ + CertificateId: tea.String(cloudCertId), + AppliedType: tea.String(certAppliedTypeExtension), + }) + } + + // 过滤掉不存在或已过期的证书,防止接口报错 + modifyCloudResourceReq.Listen.Certificates = lo.Filter(modifyCloudResourceReq.Listen.Certificates, func(c *aliwaf.ModifyCloudResourceRequestListenCertificates, _ int) bool { + if tea.StringValue(c.CertificateId) == cloudCertId { + return true + } + + resourceInstanceCert, _ := lo.Find(resourceInstanceCertificates, func(r *aliwaf.DescribeResourceInstanceCertsResponseBodyCerts) bool { + cId := tea.StringValue(c.CertificateId) + rId := tea.StringValue(r.CertIdentifier) + return cId == rId || strings.Split(cId, "-")[0] == strings.Split(rId, "-")[0] + }) + if resourceInstanceCert != nil { + certNotAfter := time.Unix(tea.Int64Value(resourceInstanceCert.AfterDate)/1000, 0) + return certNotAfter.After(time.Now()) + } + + return false + }) + + // 修改云产品接入的配置 + // REF: https://www.alibabacloud.com/help/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-modifycloudresource + modifyCloudResourceResp, err := d.sdkClient.ModifyCloudResourceWithContext(ctx, modifyCloudResourceReq, &dara.RuntimeOptions{}) + d.logger.Debug("sdk request 'waf.ModifyCloudResource'", slog.Any("request", modifyCloudResourceReq), slog.Any("response", modifyCloudResourceResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request 'waf.ModifyCloudResource': %w", err) + } + + return nil +} + +func (d *SSLDeployerProvider) deployToWAF3WithCNAME(ctx context.Context, cloudCertId string) error { + if d.config.Domain == "" { + // 未指定扩展域名,只需替换默认证书 // 查询默认 SSL/TLS 设置 // REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-describedefaulthttps @@ -133,7 +318,7 @@ func (d *SSLDeployerProvider) deployToWAF3(ctx context.Context, certPEM string, ResourceManagerResourceGroupId: lo.EmptyableToPtr(d.config.ResourceGroupId), RegionId: tea.String(d.config.Region), InstanceId: tea.String(d.config.InstanceId), - CertId: tea.String(upres.ExtendedData["CertIdentifier"].(string)), + CertId: tea.String(cloudCertId), TLSVersion: tea.String("tlsv1"), EnableTLSv3: tea.Bool(true), } @@ -151,7 +336,7 @@ func (d *SSLDeployerProvider) deployToWAF3(ctx context.Context, certPEM string, return fmt.Errorf("failed to execute sdk request 'waf.ModifyDefaultHttps': %w", err) } } else { - // 指定接入域名 + // 指定扩展域名,需替换扩展证书 // 查询 CNAME 接入详情 // REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-describedomaindetail @@ -172,7 +357,7 @@ func (d *SSLDeployerProvider) deployToWAF3(ctx context.Context, certPEM string, RegionId: tea.String(d.config.Region), InstanceId: tea.String(d.config.InstanceId), Domain: tea.String(d.config.Domain), - Listen: &aliwaf.ModifyDomainRequestListen{CertId: tea.String(upres.ExtendedData["CertIdentifier"].(string))}, + Listen: &aliwaf.ModifyDomainRequestListen{CertId: tea.String(cloudCertId)}, Redirect: &aliwaf.ModifyDomainRequestRedirect{Loadbalance: tea.String("iphash")}, } modifyDomainReq = _assign(modifyDomainReq, describeDomainDetailResp.Body) diff --git a/pkg/core/ssl-deployer/providers/aliyun-waf/consts.go b/pkg/core/ssl-deployer/providers/aliyun-waf/consts.go new file mode 100644 index 000000000..f565fb36f --- /dev/null +++ b/pkg/core/ssl-deployer/providers/aliyun-waf/consts.go @@ -0,0 +1,8 @@ +package aliyunwaf + +const ( + // 服务类型:云产品接入。 + SERVICE_TYPE_CLOUDRESOURCE = "cloudresource" + // 服务类型:CNAME 接入。 + SERVICE_TYPE_CNAME = "cname" +) diff --git a/pkg/core/ssl-deployer/providers/aliyun-waf/internal/client.go b/pkg/core/ssl-deployer/providers/aliyun-waf/internal/client.go index 7c056cd61..abdc117de 100644 --- a/pkg/core/ssl-deployer/providers/aliyun-waf/internal/client.go +++ b/pkg/core/ssl-deployer/providers/aliyun-waf/internal/client.go @@ -123,6 +123,208 @@ func (client *WafClient) DescribeDomainDetailWithContext(ctx context.Context, re return _result, _err } +func (client *WafClient) DescribeProductInstancesWithContext(ctx context.Context, request *aliwaf.DescribeProductInstancesRequest, runtime *dara.RuntimeOptions) (_result *aliwaf.DescribeProductInstancesResponse, _err error) { + _err = request.Validate() + if _err != nil { + return _result, _err + } + query := map[string]interface{}{} + + if !dara.IsNil(request.InstanceId) { + query["InstanceId"] = request.InstanceId + } + + if !dara.IsNil(request.OwnerUserId) { + query["OwnerUserId"] = request.OwnerUserId + } + + if !dara.IsNil(request.PageNumber) { + query["PageNumber"] = request.PageNumber + } + + if !dara.IsNil(request.PageSize) { + query["PageSize"] = request.PageSize + } + + if !dara.IsNil(request.RegionId) { + query["RegionId"] = request.RegionId + } + + if !dara.IsNil(request.ResourceInstanceAccessStatus) { + query["ResourceInstanceAccessStatus"] = request.ResourceInstanceAccessStatus + } + + if !dara.IsNil(request.ResourceInstanceId) { + query["ResourceInstanceId"] = request.ResourceInstanceId + } + + if !dara.IsNil(request.ResourceInstanceIp) { + query["ResourceInstanceIp"] = request.ResourceInstanceIp + } + + if !dara.IsNil(request.ResourceInstanceName) { + query["ResourceInstanceName"] = request.ResourceInstanceName + } + + if !dara.IsNil(request.ResourceIp) { + query["ResourceIp"] = request.ResourceIp + } + + if !dara.IsNil(request.ResourceManagerResourceGroupId) { + query["ResourceManagerResourceGroupId"] = request.ResourceManagerResourceGroupId + } + + if !dara.IsNil(request.ResourceName) { + query["ResourceName"] = request.ResourceName + } + + if !dara.IsNil(request.ResourceProduct) { + query["ResourceProduct"] = request.ResourceProduct + } + + if !dara.IsNil(request.ResourceRegionId) { + query["ResourceRegionId"] = request.ResourceRegionId + } + + req := &openapiutil.OpenApiRequest{ + Query: openapiutil.Query(query), + } + params := &openapiutil.Params{ + Action: dara.String("DescribeProductInstances"), + Version: dara.String("2021-10-01"), + Protocol: dara.String("HTTPS"), + Pathname: dara.String("/"), + Method: dara.String("POST"), + AuthType: dara.String("AK"), + Style: dara.String("RPC"), + ReqBodyType: dara.String("formData"), + BodyType: dara.String("json"), + } + _result = &aliwaf.DescribeProductInstancesResponse{} + _body, _err := client.CallApiWithCtx(ctx, params, req, runtime) + if _err != nil { + return _result, _err + } + _err = dara.Convert(_body, &_result) + return _result, _err +} + +func (client *WafClient) DescribeResourceInstanceCertsWithContext(ctx context.Context, request *aliwaf.DescribeResourceInstanceCertsRequest, runtime *dara.RuntimeOptions) (_result *aliwaf.DescribeResourceInstanceCertsResponse, _err error) { + _err = request.Validate() + if _err != nil { + return _result, _err + } + query := map[string]interface{}{} + + if !dara.IsNil(request.InstanceId) { + query["InstanceId"] = request.InstanceId + } + + if !dara.IsNil(request.PageNumber) { + query["PageNumber"] = request.PageNumber + } + + if !dara.IsNil(request.PageSize) { + query["PageSize"] = request.PageSize + } + + if !dara.IsNil(request.RegionId) { + query["RegionId"] = request.RegionId + } + + if !dara.IsNil(request.ResourceInstanceId) { + query["ResourceInstanceId"] = request.ResourceInstanceId + } + + if !dara.IsNil(request.ResourceManagerResourceGroupId) { + query["ResourceManagerResourceGroupId"] = request.ResourceManagerResourceGroupId + } + + req := &openapiutil.OpenApiRequest{ + Query: openapiutil.Query(query), + } + params := &openapiutil.Params{ + Action: dara.String("DescribeResourceInstanceCerts"), + Version: dara.String("2021-10-01"), + Protocol: dara.String("HTTPS"), + Pathname: dara.String("/"), + Method: dara.String("POST"), + AuthType: dara.String("AK"), + Style: dara.String("RPC"), + ReqBodyType: dara.String("formData"), + BodyType: dara.String("json"), + } + _result = &aliwaf.DescribeResourceInstanceCertsResponse{} + _body, _err := client.CallApiWithCtx(ctx, params, req, runtime) + if _err != nil { + return _result, _err + } + _err = dara.Convert(_body, &_result) + return _result, _err +} + +func (client *WafClient) ModifyCloudResourceWithContext(ctx context.Context, tmpReq *aliwaf.ModifyCloudResourceRequest, runtime *dara.RuntimeOptions) (_result *aliwaf.ModifyCloudResourceResponse, _err error) { + _err = tmpReq.Validate() + if _err != nil { + return _result, _err + } + + request := &aliwaf.ModifyCloudResourceShrinkRequest{} + openapiutil.Convert(tmpReq, request) + + if !dara.IsNil(tmpReq.Listen) { + request.ListenShrink = openapiutil.ArrayToStringWithSpecifiedStyle(tmpReq.Listen, dara.String("Listen"), dara.String("json")) + } + + if !dara.IsNil(tmpReq.Redirect) { + request.RedirectShrink = openapiutil.ArrayToStringWithSpecifiedStyle(tmpReq.Redirect, dara.String("Redirect"), dara.String("json")) + } + + query := map[string]interface{}{} + + if !dara.IsNil(request.InstanceId) { + query["InstanceId"] = request.InstanceId + } + + if !dara.IsNil(request.ListenShrink) { + query["Listen"] = request.ListenShrink + } + + if !dara.IsNil(request.RedirectShrink) { + query["Redirect"] = request.RedirectShrink + } + + if !dara.IsNil(request.RegionId) { + query["RegionId"] = request.RegionId + } + + if !dara.IsNil(request.ResourceManagerResourceGroupId) { + query["ResourceManagerResourceGroupId"] = request.ResourceManagerResourceGroupId + } + + req := &openapiutil.OpenApiRequest{ + Query: openapiutil.Query(query), + } + params := &openapiutil.Params{ + Action: dara.String("ModifyCloudResource"), + Version: dara.String("2021-10-01"), + Protocol: dara.String("HTTPS"), + Pathname: dara.String("/"), + Method: dara.String("POST"), + AuthType: dara.String("AK"), + Style: dara.String("RPC"), + ReqBodyType: dara.String("formData"), + BodyType: dara.String("json"), + } + _result = &aliwaf.ModifyCloudResourceResponse{} + _body, _err := client.CallApiWithCtx(ctx, params, req, runtime) + if _err != nil { + return _result, _err + } + _err = dara.Convert(_body, &_result) + return _result, _err +} + func (client *WafClient) ModifyDefaultHttpsWithContext(ctx context.Context, request *aliwaf.ModifyDefaultHttpsRequest, runtime *dara.RuntimeOptions) (_result *aliwaf.ModifyDefaultHttpsResponse, _err error) { _err = request.Validate() if _err != nil { diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go b/pkg/core/ssl-deployer/providers/tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go index b7fd0abde..d1d523652 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-ssl-deploy/tencentcloud_ssl_deploy.go @@ -26,9 +26,9 @@ type SSLDeployerProviderConfig struct { Endpoint string `json:"endpoint,omitempty"` // 腾讯云地域。 Region string `json:"region"` - // 云资源类型。 - ResourceType string `json:"resourceType"` - // 云资源 ID 数组。 + // 云产品类型。 + ResourceProduct string `json:"resourceProduct"` + // 云产品资源 ID 数组。 ResourceIds []string `json:"resourceIds,omitempty"` } @@ -79,8 +79,8 @@ func (d *SSLDeployerProvider) SetLogger(logger *slog.Logger) { } func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*core.SSLDeployResult, error) { - if d.config.ResourceType == "" { - return nil, errors.New("config `resourceType` is required") + if d.config.ResourceProduct == "" { + return nil, errors.New("config `resourceProduct` is required") } if len(d.config.ResourceIds) == 0 { return nil, errors.New("config `resourceIds` is required") @@ -98,7 +98,7 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke // REF: https://cloud.tencent.com/document/api/400/91667 deployCertificateInstanceReq := tcssl.NewDeployCertificateInstanceRequest() deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId) - deployCertificateInstanceReq.ResourceType = common.StringPtr(d.config.ResourceType) + deployCertificateInstanceReq.ResourceType = common.StringPtr(d.config.ResourceProduct) deployCertificateInstanceReq.InstanceIdList = common.StringPtrs(d.config.ResourceIds) deployCertificateInstanceReq.Status = common.Int64Ptr(1) deployCertificateInstanceResp, err := d.sdkClient.DeployCertificateInstance(deployCertificateInstanceReq) diff --git a/pkg/core/ssl-deployer/providers/tencentcloud-ssl-update/tencentcloud_ssl_update.go b/pkg/core/ssl-deployer/providers/tencentcloud-ssl-update/tencentcloud_ssl_update.go index 925ca2a47..bcc63b262 100644 --- a/pkg/core/ssl-deployer/providers/tencentcloud-ssl-update/tencentcloud_ssl_update.go +++ b/pkg/core/ssl-deployer/providers/tencentcloud-ssl-update/tencentcloud_ssl_update.go @@ -29,9 +29,9 @@ type SSLDeployerProviderConfig struct { CertificateId string `json:"certificateId"` // 是否替换原有证书(即保持原证书 ID 不变)。 IsReplaced bool `json:"isReplaced,omitempty"` - // 云资源类型数组。 - ResourceTypes []string `json:"resourceTypes"` - // 云资源地域数组。 + // 云产品类型数组。 + ResourceProducts []string `json:"resourceProducts"` + // 云产品地域数组。 ResourceRegions []string `json:"resourceRegions"` } @@ -85,8 +85,8 @@ func (d *SSLDeployerProvider) Deploy(ctx context.Context, certPEM string, privke if d.config.CertificateId == "" { return nil, errors.New("config `certificateId` is required") } - if len(d.config.ResourceTypes) == 0 { - return nil, errors.New("config `resourceTypes` is required") + if len(d.config.ResourceProducts) == 0 { + return nil, errors.New("config `resourceProducts` is required") } if d.config.IsReplaced { @@ -124,8 +124,8 @@ func (d *SSLDeployerProvider) executeUpdateCertificateInstance(ctx context.Conte updateCertificateInstanceReq := tcssl.NewUpdateCertificateInstanceRequest() updateCertificateInstanceReq.OldCertificateId = common.StringPtr(d.config.CertificateId) updateCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId) - updateCertificateInstanceReq.ResourceTypes = common.StringPtrs(d.config.ResourceTypes) - updateCertificateInstanceReq.ResourceTypesRegions = wrapResourceTypeRegions(d.config.ResourceTypes, d.config.ResourceRegions) + updateCertificateInstanceReq.ResourceTypes = common.StringPtrs(d.config.ResourceProducts) + updateCertificateInstanceReq.ResourceTypesRegions = wrapResourceProductRegions(d.config.ResourceProducts, d.config.ResourceRegions) updateCertificateInstanceResp, err := d.sdkClient.UpdateCertificateInstance(updateCertificateInstanceReq) d.logger.Debug("sdk request 'ssl.UpdateCertificateInstance'", slog.Any("request", updateCertificateInstanceReq), slog.Any("response", updateCertificateInstanceResp)) if err != nil { @@ -200,8 +200,8 @@ func (d *SSLDeployerProvider) executeUploadUpdateCertificateInstance(ctx context uploadUpdateCertificateInstanceReq.OldCertificateId = common.StringPtr(d.config.CertificateId) uploadUpdateCertificateInstanceReq.CertificatePublicKey = common.StringPtr(certPEM) uploadUpdateCertificateInstanceReq.CertificatePrivateKey = common.StringPtr(privkeyPEM) - uploadUpdateCertificateInstanceReq.ResourceTypes = common.StringPtrs(d.config.ResourceTypes) - uploadUpdateCertificateInstanceReq.ResourceTypesRegions = wrapResourceTypeRegions(d.config.ResourceTypes, d.config.ResourceRegions) + uploadUpdateCertificateInstanceReq.ResourceTypes = common.StringPtrs(d.config.ResourceProducts) + uploadUpdateCertificateInstanceReq.ResourceTypesRegions = wrapResourceProductRegions(d.config.ResourceProducts, d.config.ResourceRegions) uploadUpdateCertificateInstanceResp, err := d.sdkClient.UploadUpdateCertificateInstance(uploadUpdateCertificateInstanceReq) d.logger.Debug("sdk request 'ssl.UploadUpdateCertificateInstance'", slog.Any("request", uploadUpdateCertificateInstanceReq), slog.Any("response", uploadUpdateCertificateInstanceResp)) if err != nil { @@ -278,19 +278,19 @@ func createSDKClient(secretId, secretKey, endpoint string) (*internal.SslClient, return client, nil } -func wrapResourceTypeRegions(resourceTypes, resourceRegions []string) []*tcssl.ResourceTypeRegions { - if len(resourceTypes) == 0 || len(resourceRegions) == 0 { +func wrapResourceProductRegions(resourceProducts, resourceRegions []string) []*tcssl.ResourceTypeRegions { + if len(resourceProducts) == 0 || len(resourceRegions) == 0 { return nil } - // 仅以下云资源类型支持地域 - resourceTypesRequireRegion := []string{"apigateway", "clb", "cos", "tcb", "tke", "tse", "waf"} + // 仅以下云产品类型支持地域 + resourceProductsRequireRegion := []string{"apigateway", "clb", "cos", "tcb", "tke", "tse", "waf"} temp := make([]*tcssl.ResourceTypeRegions, 0) - for _, resourceType := range resourceTypes { - if slices.Contains(resourceTypesRequireRegion, resourceType) { + for _, resourceProduct := range resourceProducts { + if slices.Contains(resourceProductsRequireRegion, resourceProduct) { temp = append(temp, &tcssl.ResourceTypeRegions{ - ResourceType: common.StringPtr(resourceType), + ResourceType: common.StringPtr(resourceProduct), Regions: common.StringPtrs(resourceRegions), }) } diff --git a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderAliyunAPIGW.tsx b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderAliyunAPIGW.tsx index 78e63827a..3bd1a4734 100644 --- a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderAliyunAPIGW.tsx +++ b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderAliyunAPIGW.tsx @@ -31,6 +31,16 @@ const BizDeployNodeConfigFieldsProviderAliyunAPIGW = () => { return ( <> + } + > + + + { - } - > - - - { const { i18n, t } = useTranslation(); @@ -15,8 +19,11 @@ const BizDeployNodeConfigFieldsProviderAliyunWAF = () => { [parentNamePath]: getSchema({ i18n }), }); const formRule = createSchemaFieldRule(formSchema); + const formInst = Form.useFormInstance(); const initialValues = getInitialValues(); + const fieldServiceType = Form.useWatch([parentNamePath, "serviceType"], formInst); + return ( <> { + + + + { + + + ({ value }))} + placeholder={t("workflow_node.deploy.form.aliyun_waf_resource_product.placeholder")} + filterOption={(inputValue, option) => option!.value.toLowerCase().includes(inputValue.toLowerCase())} + /> + + + + + + + + + + + >> => { region: "", serviceVersion: "3.0", instanceId: "", + resourceProduct: "", + resourceId: "", + resourcePort: 443, }; }; const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType }) => { const { t } = i18n; - return z.object({ - region: z.string().nonempty(t("workflow_node.deploy.form.aliyun_waf_region.placeholder")), - serviceVersion: z.literal("3.0", t("workflow_node.deploy.form.aliyun_waf_service_version.placeholder")), - instanceId: z.string().nonempty(t("workflow_node.deploy.form.aliyun_waf_instance_id.placeholder")), - domain: z - .string() - .nullish() - .refine((v) => { - return !v || validDomainName(v!, { allowWildcard: true }); - }, t("common.errmsg.domain_invalid")), - }); + return z + .object({ + region: z.string().nonempty(t("workflow_node.deploy.form.aliyun_waf_region.placeholder")), + serviceVersion: z.literal("3.0", t("workflow_node.deploy.form.aliyun_waf_service_version.placeholder")), + serviceType: z.literal([SERVICE_TYPE_CLOUDRESOURCE, SERVICE_TYPE_CNAME], t("workflow_node.deploy.form.aliyun_waf_service_type.placeholder")), + instanceId: z.string().nonempty(t("workflow_node.deploy.form.aliyun_waf_instance_id.placeholder")), + resourceProduct: z.string().nullish(), + resourceId: z.string().nullish(), + resourcePort: z.preprocess((v) => (v == null || v === "" ? void 0 : Number(v)), z.number().nullish()), + domain: z + .string() + .nullish() + .refine((v) => { + return !v || validDomainName(v!, { allowWildcard: true }); + }, t("common.errmsg.domain_invalid")), + }) + .superRefine((values, ctx) => { + switch (values.serviceType) { + case SERVICE_TYPE_CLOUDRESOURCE: + { + if (!values.resourceProduct) { + ctx.addIssue({ + code: "custom", + message: t("workflow_node.deploy.form.aliyun_waf_resource_product.placeholder"), + path: ["resourceProduct"], + }); + } + + if (!values.resourceId) { + ctx.addIssue({ + code: "custom", + message: t("workflow_node.deploy.form.aliyun_waf_resource_id.placeholder"), + path: ["resourceId"], + }); + } + + if (!validPortNumber(values.resourcePort!)) { + ctx.addIssue({ + code: "custom", + message: t("workflow_node.deploy.form.aliyun_waf_resource_port.placeholder"), + path: ["resourcePort"], + }); + } + } + break; + } + }); }; const _default = Object.assign(BizDeployNodeConfigFieldsProviderAliyunWAF, { diff --git a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderTencentCloudSSLDeploy.tsx b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderTencentCloudSSLDeploy.tsx index e5c9a2d31..3e16b89bd 100644 --- a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderTencentCloudSSLDeploy.tsx +++ b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderTencentCloudSSLDeploy.tsx @@ -47,15 +47,15 @@ const BizDeployNodeConfigFieldsProviderTencentCloudSSLDeploy = () => { } + tooltip={} > ({ value }))} - placeholder={t("workflow_node.deploy.form.tencentcloud_ssldeploy_resource_type.placeholder")} + placeholder={t("workflow_node.deploy.form.tencentcloud_ssldeploy_resource_product.placeholder")} filterOption={(inputValue, option) => option!.value.toLowerCase().includes(inputValue.toLowerCase())} /> @@ -83,7 +83,7 @@ const BizDeployNodeConfigFieldsProviderTencentCloudSSLDeploy = () => { const getInitialValues = (): Nullish>> => { return { region: "", - resourceType: "", + resourceProduct: "", resourceIds: "", }; }; @@ -94,7 +94,7 @@ const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType }) return z.object({ endpoint: z.string().nullish(), region: z.string().nonempty(t("workflow_node.deploy.form.tencentcloud_ssldeploy_region.placeholder")), - resourceType: z.string().nonempty(t("workflow_node.deploy.form.tencentcloud_ssldeploy_resource_type.placeholder")), + resourceProduct: z.string().nonempty(t("workflow_node.deploy.form.tencentcloud_ssldeploy_resource_product.placeholder")), resourceIds: z.string().refine((v) => { if (!v) return false; return String(v) diff --git a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderTencentCloudSSLUpdate.tsx b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderTencentCloudSSLUpdate.tsx index b43e2b2a0..44eace7b0 100644 --- a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderTencentCloudSSLUpdate.tsx +++ b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderTencentCloudSSLUpdate.tsx @@ -47,17 +47,17 @@ const BizDeployNodeConfigFieldsProviderTencentCloudSSLUpdate = () => { } + tooltip={} > @@ -96,7 +96,7 @@ const BizDeployNodeConfigFieldsProviderTencentCloudSSLUpdate = () => { const getInitialValues = (): Nullish>> => { return { certificateId: "", - resourceTypes: "", + resourceProducts: "", }; }; @@ -106,12 +106,12 @@ const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType }) return z.object({ endpoint: z.string().nullish(), certificateId: z.string().nonempty(t("workflow_node.deploy.form.tencentcloud_sslupdate_certificate_id.placeholder")), - resourceTypes: z.string().refine((v) => { + resourceProducts: z.string().refine((v) => { if (!v) return false; return String(v) .split(MULTIPLE_INPUT_SEPARATOR) .every((e) => !!e.trim()); - }, t("workflow_node.deploy.form.tencentcloud_sslupdate_resource_types.placeholder")), + }, t("workflow_node.deploy.form.tencentcloud_sslupdate_resource_products.placeholder")), resourceRegions: z .string() .nullish() diff --git a/ui/src/i18n/locales/en/nls.workflow.nodes.json b/ui/src/i18n/locales/en/nls.workflow.nodes.json index a2f61aac3..56e9bed27 100644 --- a/ui/src/i18n/locales/en/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/en/nls.workflow.nodes.json @@ -230,13 +230,13 @@ "workflow_node.deploy.form.aliyun_alb_snidomain.label": "Alibaba Cloud ALB SNI domain (Optional)", "workflow_node.deploy.form.aliyun_alb_snidomain.placeholder": "Please enter Alibaba Cloud ALB SNI domain name", "workflow_node.deploy.form.aliyun_alb_snidomain.help": "", + "workflow_node.deploy.form.aliyun_apigw_region.label": "Alibaba Cloud region", + "workflow_node.deploy.form.aliyun_apigw_region.placeholder": "Please enter Alibaba Cloud API gateway region (e.g. cn-hangzhou)", + "workflow_node.deploy.form.aliyun_apigw_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/api-gateway/cloud-native-api-gateway/product-overview/regions", "workflow_node.deploy.form.aliyun_apigw_service_type.label": "Alibaba Cloud API gateway type", "workflow_node.deploy.form.aliyun_apigw_service_type.placeholder": "Please select Alibaba Cloud API gateway type", "workflow_node.deploy.form.aliyun_apigw_service_type.option.cloudnative.label": "Cloud-native API gateway", "workflow_node.deploy.form.aliyun_apigw_service_type.option.traditional.label": "Traditional API gateway", - "workflow_node.deploy.form.aliyun_apigw_region.label": "Alibaba Cloud region", - "workflow_node.deploy.form.aliyun_apigw_region.placeholder": "Please enter Alibaba Cloud API gateway region (e.g. cn-hangzhou)", - "workflow_node.deploy.form.aliyun_apigw_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/api-gateway/cloud-native-api-gateway/product-overview/regions", "workflow_node.deploy.form.aliyun_apigw_gateway_id.label": "Alibaba Cloud API gateway ID", "workflow_node.deploy.form.aliyun_apigw_gateway_id.placeholder": "Please enter Alibaba Cloud API gateway ID", "workflow_node.deploy.form.aliyun_apigw_gateway_id.tooltip": "For more information, see https://apigw.console.aliyun.com", @@ -358,11 +358,21 @@ "workflow_node.deploy.form.aliyun_waf_region.tooltip": "For more information, see https://www.alibabacloud.com/help/en/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-endpoint", "workflow_node.deploy.form.aliyun_waf_service_version.label": "Alibaba Cloud WAF version", "workflow_node.deploy.form.aliyun_waf_service_version.placeholder": "Please select Alibaba Cloud WAF version", + "workflow_node.deploy.form.aliyun_waf_service_type.label": "Alibaba Cloud WAF access type", + "workflow_node.deploy.form.aliyun_waf_service_type.placeholder": "Please select Alibaba Cloud WAF access type", + "workflow_node.deploy.form.aliyun_waf_service_type.option.cloudresource.label": "Cloud product access", + "workflow_node.deploy.form.aliyun_waf_service_type.option.cname.label": "CNAME access", "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.tooltip": "For more information, see https://waf.console.aliyun.com", - "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_resource_product.label": "Alibaba Cloud WAF accessed resource product", + "workflow_node.deploy.form.aliyun_waf_resource_product.placeholder": "Please enter Alibaba Cloud WAF accessed resource product", + "workflow_node.deploy.form.aliyun_waf_resource_id.label": "Alibaba Cloud WAF accessed resource ID", + "workflow_node.deploy.form.aliyun_waf_resource_id.placeholder": "Please enter Alibaba Cloud WAF accessed resource ID", + "workflow_node.deploy.form.aliyun_waf_resource_port.label": "Alibaba Cloud WAF accessed resource port", + "workflow_node.deploy.form.aliyun_waf_resource_port.placeholder": "Please enter Alibaba Cloud WAF accessed resource port", + "workflow_node.deploy.form.aliyun_waf_domain.label": "Alibaba Cloud WAF SNI domain (Optional)", + "workflow_node.deploy.form.aliyun_waf_domain.placeholder": "Please enter Alibaba Cloud WAF SNI domain name", "workflow_node.deploy.form.aliyun_waf_domain.help": "", "workflow_node.deploy.form.apisix_resource_type.label": "Resource type", "workflow_node.deploy.form.apisix_resource_type.placeholder": "Please select resource type", @@ -845,9 +855,9 @@ "workflow_node.deploy.form.tencentcloud_ssldeploy_region.label": "Tencent Cloud region", "workflow_node.deploy.form.tencentcloud_ssldeploy_region.placeholder": "Please enter Tencent Cloud service region (e.g. ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_ssldeploy_region.tooltip": "For more information, see https://www.tencentcloud.com/document/product/1007/36573", - "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_type.label": "Tencent Cloud resource type", - "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_type.placeholder": "Please enter Tencent Cloud resource type", - "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_type.tooltip": "For more information, see https://cloud.tencent.com/document/product/400/91667", + "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_product.label": "Tencent Cloud resource product", + "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_product.placeholder": "Please enter Tencent Cloud resource product", + "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_product.tooltip": "For more information, see https://cloud.tencent.com/document/product/400/91667", "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_ids.label": "Tencent Cloud resource IDs", "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_ids.placeholder": "Please enter Tencent Cloud resource IDs (separated by semicolons)", "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_ids.errmsg.invalid": "Please enter a valid Tencent Cloud resource ID", @@ -862,12 +872,12 @@ "workflow_node.deploy.form.tencentcloud_sslupdate_certificate_id.label": "Tencent Cloud SSL certificate ID", "workflow_node.deploy.form.tencentcloud_sslupdate_certificate_id.placeholder": "Please enter Tencent Cloud SSL certificate ID", "workflow_node.deploy.form.tencentcloud_sslupdate_certificate_id.tooltip": "For more information, see https://console.cloud.tencent.com/certoverview", - "workflow_node.deploy.form.tencentcloud_sslupdate_resource_types.label": "Tencent Cloud resource types", - "workflow_node.deploy.form.tencentcloud_sslupdate_resource_types.placeholder": "Please enter Tencent Cloud resource types (separated by semicolons)", - "workflow_node.deploy.form.tencentcloud_sslupdate_resource_types.help": "Notes: Multi-values should be separated by semicolons.", - "workflow_node.deploy.form.tencentcloud_sslupdate_resource_types.tooltip": "For more information, see https://www.tencentcloud.com/document/product/1007/57981 or https://www.tencentcloud.com/document/product/1007/70503", - "workflow_node.deploy.form.tencentcloud_sslupdate_resource_types.multiple_input_modal.title": "Change Tencent Cloud resource types", - "workflow_node.deploy.form.tencentcloud_sslupdate_resource_types.multiple_input_modal.placeholder": "Please enter Tencent Cloud resource type", + "workflow_node.deploy.form.tencentcloud_sslupdate_resource_products.label": "Tencent Cloud resource products", + "workflow_node.deploy.form.tencentcloud_sslupdate_resource_products.placeholder": "Please enter Tencent Cloud resource products (separated by semicolons)", + "workflow_node.deploy.form.tencentcloud_sslupdate_resource_products.help": "Notes: Multi-values should be separated by semicolons.", + "workflow_node.deploy.form.tencentcloud_sslupdate_resource_products.tooltip": "For more information, see https://www.tencentcloud.com/document/product/1007/57981 or https://www.tencentcloud.com/document/product/1007/70503", + "workflow_node.deploy.form.tencentcloud_sslupdate_resource_products.multiple_input_modal.title": "Change Tencent Cloud resource products", + "workflow_node.deploy.form.tencentcloud_sslupdate_resource_products.multiple_input_modal.placeholder": "Please enter Tencent Cloud resource product", "workflow_node.deploy.form.tencentcloud_sslupdate_resource_regions.label": "Tencent Cloud resource regions (Optional)", "workflow_node.deploy.form.tencentcloud_sslupdate_resource_regions.placeholder": "Please enter Tencent Cloud resource regions (separated by semicolons)", "workflow_node.deploy.form.tencentcloud_sslupdate_resource_regions.help": "Notes: Multi-values should be separated by semicolons.", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index 1ebc1c07c..00504453e 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -229,13 +229,13 @@ "workflow_node.deploy.form.aliyun_alb_snidomain.label": "阿里云 ALB 扩展域名(可选)", "workflow_node.deploy.form.aliyun_alb_snidomain.placeholder": "请输入阿里云 ALB 扩展域名", "workflow_node.deploy.form.aliyun_alb_snidomain.help": "提示:不填写时,将替换监听器的默认证书;否则,将替换扩展域名证书。", + "workflow_node.deploy.form.aliyun_apigw_region.label": "阿里云服务地域", + "workflow_node.deploy.form.aliyun_apigw_region.placeholder": "请输入阿里云 API 网关地域(例如:cn-hangzhou)", + "workflow_node.deploy.form.aliyun_apigw_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/api-gateway/cloud-native-api-gateway/product-overview/regions", "workflow_node.deploy.form.aliyun_apigw_service_type.label": "阿里云 API 网关服务类型", "workflow_node.deploy.form.aliyun_apigw_service_type.placeholder": "请选择阿里云 API 网关服务类型", "workflow_node.deploy.form.aliyun_apigw_service_type.option.cloudnative.label": "云原生 API 网关", "workflow_node.deploy.form.aliyun_apigw_service_type.option.traditional.label": "原 API 网关", - "workflow_node.deploy.form.aliyun_apigw_region.label": "阿里云服务地域", - "workflow_node.deploy.form.aliyun_apigw_region.placeholder": "请输入阿里云 API 网关地域(例如:cn-hangzhou)", - "workflow_node.deploy.form.aliyun_apigw_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/api-gateway/cloud-native-api-gateway/product-overview/regions", "workflow_node.deploy.form.aliyun_apigw_gateway_id.label": "阿里云 API 网关 ID", "workflow_node.deploy.form.aliyun_apigw_gateway_id.placeholder": "请输入阿里云 API 网关 ID", "workflow_node.deploy.form.aliyun_apigw_gateway_id.tooltip": "这是什么?请参阅 https://apigw.console.aliyun.com", @@ -357,11 +357,21 @@ "workflow_node.deploy.form.aliyun_waf_region.tooltip": "这是什么?请参阅 https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-endpoint", "workflow_node.deploy.form.aliyun_waf_service_version.label": "阿里云 WAF 服务版本", "workflow_node.deploy.form.aliyun_waf_service_version.placeholder": "请选择阿里云 WAF 服务版本", + "workflow_node.deploy.form.aliyun_waf_service_type.label": "阿里云 WAF 服务接入方式", + "workflow_node.deploy.form.aliyun_waf_service_type.placeholder": "请选择阿里云 WAF 服务接入方式", + "workflow_node.deploy.form.aliyun_waf_service_type.option.cloudresource.label": "云产品接入", + "workflow_node.deploy.form.aliyun_waf_service_type.option.cname.label": "CNAME 接入", "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.tooltip": "这是什么?请参阅 https://waf.console.aliyun.com
仅支持 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_instance_id.tooltip": "这是什么?请参阅 https://waf.console.aliyun.com", + "workflow_node.deploy.form.aliyun_waf_resource_product.label": "阿里云 WAF 云产品接入资源类型", + "workflow_node.deploy.form.aliyun_waf_resource_product.placeholder": "请选择 WAF 云产品接入资源类型", + "workflow_node.deploy.form.aliyun_waf_resource_id.label": "阿里云 WAF 云产品接入资源 ID", + "workflow_node.deploy.form.aliyun_waf_resource_id.placeholder": "请选择阿里云 WAF 云产品接入资源 ID", + "workflow_node.deploy.form.aliyun_waf_resource_port.label": "阿里云 WAF 云产品接入端口", + "workflow_node.deploy.form.aliyun_waf_resource_port.placeholder": "请选择阿里云 WAF 云产品接入端口", + "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.help": "提示:不填写时,将替换实例的默认证书;否则,将替换扩展域名证书。", "workflow_node.deploy.form.apisix_resource_type.label": "证书部署方式", "workflow_node.deploy.form.apisix_resource_type.placeholder": "请选择证书部署方式", @@ -843,9 +853,9 @@ "workflow_node.deploy.form.tencentcloud_ssldeploy_region.label": "腾讯云服务地域", "workflow_node.deploy.form.tencentcloud_ssldeploy_region.placeholder": "请输入腾讯云云产品服务地域(例如:ap-guangzhou)", "workflow_node.deploy.form.tencentcloud_ssldeploy_region.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/41659", - "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_type.label": "腾讯云云产品资源类型", - "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_type.placeholder": "请输入腾讯云产品资源类型", - "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_type.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/91667", + "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_product.label": "腾讯云云产品资源类型", + "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_product.placeholder": "请输入腾讯云产品资源类型", + "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_product.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/91667", "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_ids.label": "腾讯云云产品资源 ID", "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_ids.placeholder": "请输入腾讯云云产品资源 ID(多个值请用半角分号隔开)", "workflow_node.deploy.form.tencentcloud_ssldeploy_resource_ids.errmsg.invalid": "请输入正确的腾讯云云产品资源 ID", @@ -860,12 +870,12 @@ "workflow_node.deploy.form.tencentcloud_sslupdate_certificate_id.label": "腾讯云原证书 ID", "workflow_node.deploy.form.tencentcloud_sslupdate_certificate_id.placeholder": "请输入腾讯云原证书 ID", "workflow_node.deploy.form.tencentcloud_sslupdate_certificate_id.tooltip": "这是什么?请参阅 https://console.cloud.tencent.com/certoverview", - "workflow_node.deploy.form.tencentcloud_sslupdate_resource_types.label": "腾讯云云产品资源类型", - "workflow_node.deploy.form.tencentcloud_sslupdate_resource_types.placeholder": "请输入腾讯云云产品资源类型(多个值请用半角分号隔开)", - "workflow_node.deploy.form.tencentcloud_sslupdate_resource_types.help": "提示:多个类型请用半角分号隔开。", - "workflow_node.deploy.form.tencentcloud_sslupdate_resource_types.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/91649 或 https://cloud.tencent.com/document/product/400/119791
注意,这两个接口的所支持的云产品资源类型有所不同,具体请查看腾讯云官方文档。", - "workflow_node.deploy.form.tencentcloud_sslupdate_resource_types.multiple_input_modal.title": "修改腾讯云云产品资源类型", - "workflow_node.deploy.form.tencentcloud_sslupdate_resource_types.multiple_input_modal.placeholder": "请输入腾讯云云产品资源类型", + "workflow_node.deploy.form.tencentcloud_sslupdate_resource_products.label": "腾讯云云产品资源类型", + "workflow_node.deploy.form.tencentcloud_sslupdate_resource_products.placeholder": "请输入腾讯云云产品资源类型(多个值请用半角分号隔开)", + "workflow_node.deploy.form.tencentcloud_sslupdate_resource_products.help": "提示:多个类型请用半角分号隔开。", + "workflow_node.deploy.form.tencentcloud_sslupdate_resource_products.tooltip": "这是什么?请参阅 https://cloud.tencent.com/document/product/400/91649 或 https://cloud.tencent.com/document/product/400/119791
注意,这两个接口的所支持的云产品资源类型有所不同,具体请查看腾讯云官方文档。", + "workflow_node.deploy.form.tencentcloud_sslupdate_resource_products.multiple_input_modal.title": "修改腾讯云云产品资源类型", + "workflow_node.deploy.form.tencentcloud_sslupdate_resource_products.multiple_input_modal.placeholder": "请输入腾讯云云产品资源类型", "workflow_node.deploy.form.tencentcloud_sslupdate_resource_regions.label": "腾讯云云产品部署地域(可选)", "workflow_node.deploy.form.tencentcloud_sslupdate_resource_regions.placeholder": "请输入腾讯云云产品部署地域(多个值请用半角分号隔开)", "workflow_node.deploy.form.tencentcloud_sslupdate_resource_regions.help": "提示:多个地域请用半角分号隔开。",