From 7c8700a2f103c23a5179b736ecc575176496817a Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Fri, 26 Jun 2026 14:56:46 +0800 Subject: [PATCH] feat(provider): new acme dns-01 provider: oraclecloud --- go.mod | 6 + go.sum | 12 ++ .../certacme/certifiers/sp_oraclecloud_dns.go | 35 ++++ internal/domain/access.go | 9 + internal/domain/provider.go | 3 + .../challengers/dns01/oraclecloud/consts.go | 7 + .../dns01/oraclecloud/oraclecloud.go | 76 ++++++++ ui/public/imgs/providers/oraclecloud.svg | 1 + .../forms/AccessConfigFieldsProvider.tsx | 2 + .../AccessConfigFieldsProviderOracleCloud.tsx | 167 ++++++++++++++++++ .../BizApplyNodeConfigFieldsProvider.tsx | 3 + ...NodeConfigFieldsProviderOracleCloudDNS.tsx | 64 +++++++ ui/src/i18n/resources/en/nls.access.json | 48 ++++- ui/src/i18n/resources/en/nls.provider.json | 16 +- .../i18n/resources/en/nls.workflow.nodes.json | 10 ++ ui/src/i18n/resources/zh/nls.access.json | 48 ++++- ui/src/i18n/resources/zh/nls.provider.json | 16 +- .../i18n/resources/zh/nls.workflow.nodes.json | 10 ++ 18 files changed, 511 insertions(+), 22 deletions(-) create mode 100644 internal/certacme/certifiers/sp_oraclecloud_dns.go create mode 100644 pkg/core/certifier/challengers/dns01/oraclecloud/consts.go create mode 100644 pkg/core/certifier/challengers/dns01/oraclecloud/oraclecloud.go create mode 100644 ui/public/imgs/providers/oraclecloud.svg create mode 100644 ui/src/components/access/forms/AccessConfigFieldsProviderOracleCloud.tsx create mode 100644 ui/src/components/workflow/designer/forms/BizApplyNodeConfigFieldsProviderOracleCloudDNS.tsx diff --git a/go.mod b/go.mod index 233ebaaa..8345c2c1 100644 --- a/go.mod +++ b/go.mod @@ -52,6 +52,8 @@ require ( github.com/jlaffaye/ftp v0.2.0 github.com/microcosm-cc/bluemonday v1.0.27 github.com/minio/minio-go/v7 v7.2.0 + github.com/nrdcg/oci-go-sdk/certificatesmanagement/v1065 v1065.118.1 + github.com/nrdcg/oci-go-sdk/common/v1065 v1065.118.1 github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0 github.com/pkg/sftp v1.13.10 github.com/pocketbase/dbx v1.12.0 @@ -209,6 +211,7 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect github.com/go-test/deep v1.1.1 // indirect + github.com/gofrs/flock v0.13.0 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.16 // indirect @@ -241,14 +244,17 @@ require ( github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/ncruces/go-strftime v1.0.0 // indirect github.com/nrdcg/namesilo v0.5.0 // indirect + github.com/nrdcg/oci-go-sdk/dns/v1065 v1065.116.0 // indirect github.com/openshift/gssapi v0.0.0-20161010215902-5fb4217df13b // indirect github.com/philhofer/fwd v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/rs/xid v1.6.0 // indirect + github.com/sony/gobreaker/v2 v2.4.0 // indirect github.com/spf13/afero v1.15.0 // indirect github.com/spf13/cast v1.10.0 // indirect github.com/tinylib/msgp v1.6.4 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect diff --git a/go.sum b/go.sum index 8f9378ee..305657ac 100644 --- a/go.sum +++ b/go.sum @@ -437,6 +437,8 @@ github.com/goccy/go-yaml v1.9.8/go.mod h1:JubOolP3gh0HpiBc4BLRD4YmjEjHAmIIB2aaXK github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw= +github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -733,6 +735,12 @@ github.com/nrdcg/goacmedns v0.2.0 h1:ADMbThobzEMnr6kg2ohs4KGa3LFqmgiBA22/6jUWJR0 github.com/nrdcg/goacmedns v0.2.0/go.mod h1:T5o6+xvSLrQpugmwHvrSNkzWht0UGAwj2ACBMhh73Cg= github.com/nrdcg/namesilo v0.5.0 h1:6QNxT/XxE+f5B+7QlfWorthNzOzcGlBLRQxqi6YeBrE= github.com/nrdcg/namesilo v0.5.0/go.mod h1:4UkwlwQfDt74kSGmhLaDylnBrD94IfflnpoEaj6T2qw= +github.com/nrdcg/oci-go-sdk/certificatesmanagement/v1065 v1065.118.1 h1:wkYSV6QEHn3SvYBJCT0mxLxYOucrvyVLRI2E9XOoO10= +github.com/nrdcg/oci-go-sdk/certificatesmanagement/v1065 v1065.118.1/go.mod h1:6zkMV6Nw7Mqe6pFsohqmCqdwxT47U2i6ASkSxWZqFps= +github.com/nrdcg/oci-go-sdk/common/v1065 v1065.118.1 h1:nXs2HDhDO9Qfke/F0TIPr42aAeG+TRJGJD6w1jZj2gM= +github.com/nrdcg/oci-go-sdk/common/v1065 v1065.118.1/go.mod h1:8bOmK+tqjALlm0WH4PEp7kFflnnZaZQdIrhCWwV0mM8= +github.com/nrdcg/oci-go-sdk/dns/v1065 v1065.116.0 h1:j15rh7oUMvrqSwFVAavKC1haG+vP+IMH7SyFqVKFT+I= +github.com/nrdcg/oci-go-sdk/dns/v1065 v1065.116.0/go.mod h1:GMmUxJhLHleboAp7caAU3tDJ8yHs8dBpNmsp1CEtXsc= github.com/nrdcg/porkbun v0.4.0 h1:rWweKlwo1PToQ3H+tEO9gPRW0wzzgmI/Ob3n2Guticw= github.com/nrdcg/porkbun v0.4.0/go.mod h1:/QMskrHEIM0IhC/wY7iTCUgINsxdT2WcOphktJ9+Q54= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -841,6 +849,8 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/sony/gobreaker/v2 v2.4.0 h1:g2KJRW1Ubty3+ZOcSEUN7K+REQJdN6yo6XvaML+jptg= +github.com/sony/gobreaker/v2 v2.4.0/go.mod h1:pTyFJgcZ3h2tdQVLZZruK2C0eoFL1fb/G83wK1ZQl+s= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= @@ -937,6 +947,8 @@ github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gi github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/internal/certacme/certifiers/sp_oraclecloud_dns.go b/internal/certacme/certifiers/sp_oraclecloud_dns.go new file mode 100644 index 00000000..6b12f085 --- /dev/null +++ b/internal/certacme/certifiers/sp_oraclecloud_dns.go @@ -0,0 +1,35 @@ +package certifiers + +import ( + "fmt" + + "github.com/certimate-go/certimate/internal/domain" + "github.com/certimate-go/certimate/pkg/core" + chlgimpl "github.com/certimate-go/certimate/pkg/core/certifier/challengers/dns01/oraclecloud" + xmaps "github.com/certimate-go/certimate/pkg/utils/maps" +) + +func init() { + ACMEDns01Registries.MustRegister(domain.ACMEDns01ProviderTypeOracleCloudDNS, func(options *ProviderFactoryOptions) (core.ACMEChallenger, error) { + credentials := domain.AccessConfigForOracleCloud{} + if err := xmaps.Populate(options.ProviderAccessConfig, &credentials); err != nil { + return nil, fmt.Errorf("failed to populate provider access config: %w", err) + } + + provider, err := chlgimpl.NewChallenger(&chlgimpl.ChallengerConfig{ + AuthMethod: credentials.AuthMethod, + PrivateKey: credentials.PrivateKey, + PrivateKeyPassphrase: credentials.PrivateKeyPassphrase, + PublicKeyFingerprint: credentials.PublicKeyFingerprint, + TenancyOcid: credentials.TenancyOcid, + UserOcid: credentials.UserOcid, + Region: xmaps.GetString(options.ProviderExtendedConfig, "region"), + CompartmentOcid: xmaps.GetString(options.ProviderExtendedConfig, "compartmentOcid"), + DnsPropagationTimeout: options.DnsPropagationTimeout, + DnsTTL: options.DnsTTL, + }) + return provider, err + }) + + ACMEDns01Registries.MustRegisterAlias(domain.ACMEDns01ProviderTypeOracleCloud, domain.ACMEDns01ProviderTypeOracleCloudDNS) +} diff --git a/internal/domain/access.go b/internal/domain/access.go index 92eca945..eb088bcc 100644 --- a/internal/domain/access.go +++ b/internal/domain/access.go @@ -454,6 +454,15 @@ type AccessConfigForNS1 struct { ApiKey string `json:"apiKey"` } +type AccessConfigForOracleCloud struct { + AuthMethod string `json:"authMethod"` + PrivateKey string `json:"privateKey,omitempty"` + PrivateKeyPassphrase string `json:"privateKeyPassphrase,omitempty"` + PublicKeyFingerprint string `json:"publicKeyFingerprint,omitempty"` + TenancyOcid string `json:"tenancyOcid,omitempty"` + UserOcid string `json:"userOcid,omitempty"` +} + type AccessConfigForOVHcloud struct { Endpoint string `json:"endpoint"` AuthMethod string `json:"authMethod"` diff --git a/internal/domain/provider.go b/internal/domain/provider.go index df14a7db..c82c75d6 100644 --- a/internal/domain/provider.go +++ b/internal/domain/provider.go @@ -99,6 +99,7 @@ const ( AccessProviderTypeNetlify = AccessProviderType("netlify") AccessProviderTypeNginxProxyManager = AccessProviderType("nginxproxymanager") AccessProviderTypeNS1 = AccessProviderType("ns1") + AccessProviderTypeOracleCloud = AccessProviderType("oraclecloud") AccessProviderTypeOVHcloud = AccessProviderType("ovhcloud") AccessProviderTypePorkbun = AccessProviderType("porkbun") AccessProviderTypePowerDNS = AccessProviderType("powerdns") @@ -248,6 +249,8 @@ const ( ACMEDns01ProviderTypeNetcup = ACMEDns01ProviderType(AccessProviderTypeNetcup) ACMEDns01ProviderTypeNetlify = ACMEDns01ProviderType(AccessProviderTypeNetlify) ACMEDns01ProviderTypeNS1 = ACMEDns01ProviderType(AccessProviderTypeNS1) + ACMEDns01ProviderTypeOracleCloud = ACMEDns01ProviderType(AccessProviderTypeOracleCloud) // 兼容旧值,等同于 [ACMEDns01ProviderTypeOracleCloudDNS] + ACMEDns01ProviderTypeOracleCloudDNS = ACMEDns01ProviderType(AccessProviderTypeOracleCloud + "-dns") ACMEDns01ProviderTypeOVHcloud = ACMEDns01ProviderType(AccessProviderTypeOVHcloud) ACMEDns01ProviderTypePorkbun = ACMEDns01ProviderType(AccessProviderTypePorkbun) ACMEDns01ProviderTypePowerDNS = ACMEDns01ProviderType(AccessProviderTypePowerDNS) diff --git a/pkg/core/certifier/challengers/dns01/oraclecloud/consts.go b/pkg/core/certifier/challengers/dns01/oraclecloud/consts.go new file mode 100644 index 00000000..b4c835b3 --- /dev/null +++ b/pkg/core/certifier/challengers/dns01/oraclecloud/consts.go @@ -0,0 +1,7 @@ +package oraclecloud + +const ( + AUTH_METHOD_APIKEY = "apikey" + AUTH_METHOD_INSTANCEPRINCIPAL = "instanceprincipal" + AUTH_METHOD_RESOURCEPRINCIPAL = "resourceprincipal" +) diff --git a/pkg/core/certifier/challengers/dns01/oraclecloud/oraclecloud.go b/pkg/core/certifier/challengers/dns01/oraclecloud/oraclecloud.go new file mode 100644 index 00000000..e4ce9805 --- /dev/null +++ b/pkg/core/certifier/challengers/dns01/oraclecloud/oraclecloud.go @@ -0,0 +1,76 @@ +package oraclecloud + +import ( + "fmt" + "time" + + "github.com/go-acme/lego/v5/providers/dns/oraclecloud" + "github.com/nrdcg/oci-go-sdk/common/v1065" + "github.com/nrdcg/oci-go-sdk/common/v1065/auth" + + "github.com/certimate-go/certimate/pkg/core" +) + +type ChallengerConfig struct { + AuthMethod string `json:"authMethod"` + PrivateKey string `json:"privateKey,omitempty"` + PrivateKeyPassphrase string `json:"privateKeyPassphrase,omitempty"` + PublicKeyFingerprint string `json:"publicKeyFingerprint,omitempty"` + TenancyOcid string `json:"tenancyOcid,omitempty"` + UserOcid string `json:"userOcid,omitempty"` + Region string `json:"region"` + CompartmentOcid string `json:"compartmentOcid"` + DnsPropagationTimeout int `json:"dnsPropagationTimeout,omitempty"` + DnsTTL int `json:"dnsTTL,omitempty"` +} + +func NewChallenger(config *ChallengerConfig) (core.ACMEChallenger, error) { + if config == nil { + return nil, fmt.Errorf("the configuration of the acme challenge provider is nil") + } + + providerConfig := oraclecloud.NewDefaultConfig() + providerConfig.CompartmentID = config.CompartmentOcid + switch config.AuthMethod { + case AUTH_METHOD_APIKEY: + pkpwd := (*string)(nil) + if config.PrivateKeyPassphrase != "" { + pkpwd = &config.PrivateKeyPassphrase + } + providerConfig.OCIConfigProvider = common.NewRawConfigurationProvider( + config.TenancyOcid, + config.UserOcid, + config.Region, + config.PublicKeyFingerprint, + config.PrivateKey, + pkpwd, + ) + case AUTH_METHOD_INSTANCEPRINCIPAL: + configurationProvider, err := auth.InstancePrincipalConfigurationProviderForRegion(common.Region(config.Region)) + if err != nil { + return nil, fmt.Errorf("oraclecloud: %w", err) + } + providerConfig.OCIConfigProvider = configurationProvider + case AUTH_METHOD_RESOURCEPRINCIPAL: + configurationProvider, err := auth.ResourcePrincipalConfigurationProviderForRegion(common.Region(config.Region)) + if err != nil { + return nil, fmt.Errorf("oraclecloud: %w", err) + } + providerConfig.OCIConfigProvider = configurationProvider + default: + return nil, fmt.Errorf("unsupported auth method '%s'", config.AuthMethod) + } + if config.DnsPropagationTimeout != 0 { + providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second + } + if config.DnsTTL != 0 { + providerConfig.TTL = config.DnsTTL + } + + provider, err := oraclecloud.NewDNSProviderConfig(providerConfig) + if err != nil { + return nil, err + } + + return provider, nil +} diff --git a/ui/public/imgs/providers/oraclecloud.svg b/ui/public/imgs/providers/oraclecloud.svg new file mode 100644 index 00000000..95b97b9a --- /dev/null +++ b/ui/public/imgs/providers/oraclecloud.svg @@ -0,0 +1 @@ + diff --git a/ui/src/components/access/forms/AccessConfigFieldsProvider.tsx b/ui/src/components/access/forms/AccessConfigFieldsProvider.tsx index 38caff5f..8657c105 100644 --- a/ui/src/components/access/forms/AccessConfigFieldsProvider.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProvider.tsx @@ -83,6 +83,7 @@ import AccessConfigFieldsProviderNetcup from "./AccessConfigFieldsProviderNetcup import AccessConfigFieldsProviderNetlify from "./AccessConfigFieldsProviderNetlify"; import AccessConfigFieldsProviderNginxProxyManager from "./AccessConfigFieldsProviderNginxProxyManager"; import AccessConfigFieldsProviderNS1 from "./AccessConfigFieldsProviderNS1"; +import AccessConfigFieldsProviderOracleCloud from "./AccessConfigFieldsProviderOracleCloud"; import AccessConfigFieldsProviderOVHcloud from "./AccessConfigFieldsProviderOVHcloud"; import AccessConfigFieldsProviderPorkbun from "./AccessConfigFieldsProviderPorkbun"; import AccessConfigFieldsProviderPowerDNS from "./AccessConfigFieldsProviderPowerDNS"; @@ -208,6 +209,7 @@ const providerComponentMap: Partial { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const formInst = Form.useFormInstance>(); + const initialValues = getInitialValues(); + + const fieldAuthMethod = Form.useWatch([parentNamePath, "authMethod"], formInst); + + return ( + <> + + + {t("access.form.oraclecloud_auth_method.option.apikey.label")} + {t("access.form.oraclecloud_auth_method.option.instanceprincipal.label")} + {t("access.form.oraclecloud_auth_method.option.resourceprincipal.label")} + + + + + } + > + + + + + + + + + + + + + + + + + + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + authMethod: AUTH_METHOD_APIKEY, + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType }) => { + const { t: _ } = i18n; + + return z + .object({ + authMethod: z.enum([AUTH_METHOD_APIKEY, AUTH_METHOD_INSTANCEPRINCIPAL, AUTH_METHOD_RESOURCEPRINCIPAL]), + privateKey: z.string().nullish(), + privateKeyPassphrase: z.string().nullish(), + publicKeyFingerprint: z.string().nullish(), + tenancyOcid: z.string().nullish(), + userOcid: z.string().nullish(), + }) + .superRefine((values, ctx) => { + switch (values.authMethod) { + case AUTH_METHOD_APIKEY: + { + const scPrivateKey = z.string().refine((v) => validatePEMPrivateKey(v)); + const spPrivateKey = scPrivateKey.safeParse(values.privateKey); + if (!spPrivateKey.success) { + ctx.addIssue({ + code: "custom", + message: z.treeifyError(spPrivateKey.error).errors.join(), + path: ["privateKey"], + }); + } + + const scPublicKeyFingerprint = z.string().regex(/^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){15}$/); + const spPublicKeyFingerprint = scPublicKeyFingerprint.safeParse(values.publicKeyFingerprint); + if (!spPublicKeyFingerprint.success) { + ctx.addIssue({ + code: "custom", + message: z.treeifyError(spPublicKeyFingerprint.error).errors.join(), + path: ["publicKeyFingerprint"], + }); + } + + const scTenancyOcid = z.string().regex(/^ocid\d\..{1,}$/); + const spTenancyOcid = scTenancyOcid.safeParse(values.tenancyOcid); + if (!spTenancyOcid.success) { + ctx.addIssue({ + code: "custom", + message: z.treeifyError(spTenancyOcid.error).errors.join(), + path: ["tenancyOcid"], + }); + } + + const scUserOcid = z.string().regex(/^ocid\d\..{1,}$/); + const spUserOcid = scUserOcid.safeParse(values.userOcid); + if (!spUserOcid.success) { + ctx.addIssue({ + code: "custom", + message: z.treeifyError(spUserOcid.error).errors.join(), + path: ["userOcid"], + }); + } + } + break; + } + }); +}; + +const _default = Object.assign(AccessConfigFieldsProviderOracleCloud, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/components/workflow/designer/forms/BizApplyNodeConfigFieldsProvider.tsx b/ui/src/components/workflow/designer/forms/BizApplyNodeConfigFieldsProvider.tsx index aba5cc69..83636d30 100644 --- a/ui/src/components/workflow/designer/forms/BizApplyNodeConfigFieldsProvider.tsx +++ b/ui/src/components/workflow/designer/forms/BizApplyNodeConfigFieldsProvider.tsx @@ -9,6 +9,7 @@ import BizApplyNodeConfigFieldsProviderFTP from "./BizApplyNodeConfigFieldsProvi import BizApplyNodeConfigFieldsProviderHuaweiCloudDNS from "./BizApplyNodeConfigFieldsProviderHuaweiCloudDNS"; import BizApplyNodeConfigFieldsProviderJDCloudDNS from "./BizApplyNodeConfigFieldsProviderJDCloudDNS"; import BizApplyNodeConfigFieldsProviderLocal from "./BizApplyNodeConfigFieldsProviderLocal"; +import BizApplyNodeConfigFieldsProviderOracleCloudDNS from "./BizApplyNodeConfigFieldsProviderOracleCloudDNS"; import BizApplyNodeConfigFieldsProviderS3 from "./BizApplyNodeConfigFieldsProviderS3"; import BizApplyNodeConfigFieldsProviderSSH from "./BizApplyNodeConfigFieldsProviderSSH"; @@ -25,6 +26,8 @@ const acmeDns01ProviderComponentMap: Partial>> = { diff --git a/ui/src/components/workflow/designer/forms/BizApplyNodeConfigFieldsProviderOracleCloudDNS.tsx b/ui/src/components/workflow/designer/forms/BizApplyNodeConfigFieldsProviderOracleCloudDNS.tsx new file mode 100644 index 00000000..b739d340 --- /dev/null +++ b/ui/src/components/workflow/designer/forms/BizApplyNodeConfigFieldsProviderOracleCloudDNS.tsx @@ -0,0 +1,64 @@ +import { getI18n, useTranslation } from "react-i18next"; +import { Form, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { useFormNestedFieldsContext } from "./_context"; + +const BizApplyNodeConfigFieldsProviderOracleCloudDNS = () => { + 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 { + region: "us-phoenix-1", + compartmentOcid: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType }) => { + const { t: _ } = i18n; + + return z.object({ + region: z.string().nonempty(), + compartmentOcid: z.string().regex(/^ocid\d\..{1,}$/), + }); +}; + +const _default = Object.assign(BizApplyNodeConfigFieldsProviderOracleCloudDNS, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/i18n/resources/en/nls.access.json b/ui/src/i18n/resources/en/nls.access.json index 290d7cc0..77ab5c4d 100644 --- a/ui/src/i18n/resources/en/nls.access.json +++ b/ui/src/i18n/resources/en/nls.access.json @@ -736,13 +736,13 @@ "tooltip": "For more information, see https://goedge.cloud/docs/API/Auth.md" }, "googlecloud_project_id": { - "label": "Google Cloud project ID", - "placeholder": "Please enter Google Cloud project ID", + "label": "GCP project ID", + "placeholder": "Please enter GCP project ID", "tooltip": "For more information, see https://docs.cloud.google.com/resource-manager/docs/creating-managing-projects" }, "googlecloud_service_account_key": { - "label": "Google Cloud service account key", - "placeholder": "Please enter Google Cloud service account key", + "label": "GCP service account key", + "placeholder": "Please enter GCP service account key", "tooltip": "For more information, see https://docs.cloud.google.com/iam/docs/keys-create-delete" }, "googletrustservices_eab": { @@ -1004,6 +1004,46 @@ "placeholder": "Please enter NS1 API key", "tooltip": "For more information, see https://www.ibm.com/docs/en/ns1-connect?topic=introduction-using-api" }, + "oraclecloud_auth_method": { + "label": "OCI API authentication method", + "placeholder": "Please select OCI API authentication method", + "option": { + "apikey": { + "label": "API key" + }, + "instanceprincipal": { + "label": "Instance principal" + }, + "resourceprincipal": { + "label": "Resource principal" + } + } + }, + "oraclecloud_private_key": { + "label": "OCI API signing private key", + "placeholder": "Please enter OCI API signing private key", + "tooltip": "For more information, see https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm" + }, + "oraclecloud_private_key_passphrase": { + "label": "OCI API signing private key passphrase (Optional)", + "placeholder": "Please enter OCI API signing private key passphrase", + "tooltip": "For more information, see https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm" + }, + "oraclecloud_public_key_fingerprint": { + "label": "OCI API signing public key fingerprint", + "placeholder": "Please enter OCI API signing public key fingerprint", + "tooltip": "For more information, see https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm" + }, + "oraclecloud_tenancy_ocid": { + "label": "OCI tenancy OCID", + "placeholder": "Please enter OCI tenancy OCID", + "tooltip": "For more information, see https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm" + }, + "oraclecloud_user_ocid": { + "label": "OCI user OCID", + "placeholder": "Please enter OCI user OCID", + "tooltip": "For more information, see https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm" + }, "ovhcloud_endpoint": { "label": "OVHcloud API endpoint", "placeholder": "Please enter OVHcloud API endpoint" diff --git a/ui/src/i18n/resources/en/nls.provider.json b/ui/src/i18n/resources/en/nls.provider.json index 445499f3..aea96e8b 100644 --- a/ui/src/i18n/resources/en/nls.provider.json +++ b/ui/src/i18n/resources/en/nls.provider.json @@ -58,7 +58,7 @@ "aliyun_waf": "Alibaba Cloud - WAF (Web Application Firewall)", "apisix": "Apache APISIX", "arvancloud": "ArvanCloud", - "aws": "AWS", + "aws": "AWS (Amazon Web Services)", "aws_acm": "AWS - ACM (Amazon Certificate Manager)", "aws_alb": "AWS - ALB (Application Load Balancer)", "aws_apigateway": "AWS - API Gateway", @@ -69,7 +69,7 @@ "aws_lightsail": "AWS - Lightsail", "aws_nlb": "AWS - NLB (Network Load Balancer)", "aws_route53": "AWS - Route53", - "azure": "Azure", + "azure": "Azure (Microsoft Azure)", "azure_dns": "Azure - DNS", "azure_keyvault": "Azure - KeyVault", "baiducloud": "Baidu Cloud", @@ -80,13 +80,13 @@ "baiducloud_dns": "Baidu Cloud - DNS", "baishan": "Baishan", "baishan_cdn": "Baishan - CDN (Content Delivery Network)", - "baotapanel": "aaPanel (aka BaotaPanel)", + "baotapanel": "aaPanel / BaotaPanel", "baotapanel_common": "aaPanel", "baotapanel_console": "aaPanel - Console itself", - "baotapanelgo": "aaPanel WinGo (aka BaotaPanel WinGo)", + "baotapanelgo": "aaPanel WinGo / BaotaPanel WinGo", "baotapanelgo_common": "aaPanel WinGo", "baotapanelgo_console": "aaPanel WinGo - Console itself", - "baotawaf": "aaWAF (aka BaotaWAF)", + "baotawaf": "aaWAF / BaotaWAF", "baotawaf_common": "aaWAF", "baotawaf_console": "aaWAF - Console itself", "beget": "Бегет (Beget)", @@ -152,9 +152,9 @@ "gname": "GNAME", "godaddy": "GoDaddy", "goedge": "GoEdge", - "googlecloud": "Google Cloud", - "googlecloud_dns": "Google Cloud - DNS", + "googlecloud": "GCP (Google Cloud Platform)", "googlecloud_certificatemanager": "Google Cloud - Certificate Manager", + "googlecloud_dns": "Google Cloud - DNS", "googletrustservices": "Google Trust Services", "hetzner": "Hetzner", "hostingde": "hosting.de", @@ -205,6 +205,8 @@ "netlify": "Netlify", "nginxproxymanager": "Nginx Proxy Manager", "ns1": "NS1 (IBM NS1 Connect)", + "oraclecloud": "OCI (Oracle Cloud Infrastructure)", + "oraclecloud_dns": "Oracle Cloud - DNS", "ovhcloud": "OVHcloud", "porkbun": "Porkbun", "powerdns": "PowerDNS", diff --git a/ui/src/i18n/resources/en/nls.workflow.nodes.json b/ui/src/i18n/resources/en/nls.workflow.nodes.json index a9d7991d..0dcd606d 100644 --- a/ui/src/i18n/resources/en/nls.workflow.nodes.json +++ b/ui/src/i18n/resources/en/nls.workflow.nodes.json @@ -318,6 +318,16 @@ "placeholder": "Please enter web root path", "tooltip": "It's the main directory where the website's files are stored on the local device." }, + "oraclecloud_dns_region": { + "label": "OCI region", + "placeholder": "Please enter OCI DNS region (e.g. us-phoenix-1)", + "tooltip": "For more information, see https://docs.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm" + }, + "oraclecloud_dns_compartment_ocid": { + "label": "OCI compartment OCID", + "placeholder": "Please enter OCI compartment OCID", + "tooltip": "For more information, see https://docs.oracle.com/en-us/iaas/Content/Identity/compartments/managingcompartments.htm" + }, "s3_region": { "label": "Object storage (S3-compatible) region", "placeholder": "Please enter region" diff --git a/ui/src/i18n/resources/zh/nls.access.json b/ui/src/i18n/resources/zh/nls.access.json index 677bddc5..1fbf5cb4 100644 --- a/ui/src/i18n/resources/zh/nls.access.json +++ b/ui/src/i18n/resources/zh/nls.access.json @@ -736,13 +736,13 @@ "tooltip": "这是什么?请参阅 https://goedge.cloud/docs/API/Auth.md" }, "googlecloud_project_id": { - "label": "Google Cloud 项目 ID", - "placeholder": "请输入 Google Cloud 项目 ID", + "label": "GCP 项目 ID", + "placeholder": "请输入 GCP 项目 ID", "tooltip": "这是什么?请参阅 https://docs.cloud.google.com/resource-manager/docs/creating-managing-projects" }, "googlecloud_service_account_key": { - "label": "Google Cloud 服务账号密钥", - "placeholder": "请输入 Google Cloud 服务账号密钥", + "label": "GCP 服务账号密钥", + "placeholder": "请输入 GCP 服务账号密钥", "tooltip": "这是什么?请参阅 https://docs.cloud.google.com/iam/docs/keys-create-delete" }, "googletrustservices_eab": { @@ -999,6 +999,46 @@ "label": "NPM API Token", "placeholder": "请输入 NPM API Token" }, + "oraclecloud_auth_method": { + "label": "OCI API 认证方式", + "placeholder": "请选择 OCI API 认证方式", + "option": { + "apikey": { + "label": "API Key" + }, + "instanceprincipal": { + "label": "Instance Principal" + }, + "resourceprincipal": { + "label": "Resource Principal" + } + } + }, + "oraclecloud_private_key": { + "label": "OCI API 签名私钥", + "placeholder": "请输入 OCI API 签名私钥", + "tooltip": "这是什么?请参阅 https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm" + }, + "oraclecloud_private_key_passphrase": { + "label": "OCI API 签名私钥口令(可选)", + "placeholder": "请输入 OCI API 签名私钥口令", + "tooltip": "这是什么?请参阅 https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm" + }, + "oraclecloud_public_key_fingerprint": { + "label": "OCI API 签名公钥指纹", + "placeholder": "请输入 OCI API 签名公钥指纹", + "tooltip": "这是什么?请参阅 https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm" + }, + "oraclecloud_tenancy_ocid": { + "label": "OCI 租户 OCID", + "placeholder": "请输入 OCI 租户 OCID", + "tooltip": "这是什么?请参阅 https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm" + }, + "oraclecloud_user_ocid": { + "label": "OCI 用户 OCID", + "placeholder": "请输入 OCI 用户 OCID", + "tooltip": "这是什么?请参阅 https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm" + }, "ns1_api_key": { "label": "NS1 API Key", "placeholder": "请输入 NS1 API Key", diff --git a/ui/src/i18n/resources/zh/nls.provider.json b/ui/src/i18n/resources/zh/nls.provider.json index 96abf88b..cd6fd97e 100644 --- a/ui/src/i18n/resources/zh/nls.provider.json +++ b/ui/src/i18n/resources/zh/nls.provider.json @@ -58,7 +58,7 @@ "aliyun_waf": "阿里云 - Web 应用防火墙 WAF", "apisix": "Apache APISIX", "arvancloud": "ArvanCloud", - "aws": "AWS", + "aws": "AWS(Amazon Web Services)", "aws_acm": "AWS - 证书管理器 ACM", "aws_alb": "AWS - 应用程序负载均衡器 ALB", "aws_amplify": "AWS - Amplify 托管", @@ -69,7 +69,7 @@ "aws_lightsail": "AWS - Lightsail", "aws_nlb": "AWS - 网络负载均衡器 NLB", "aws_route53": "AWS - Route53", - "azure": "Azure", + "azure": "Azure(Microsoft Azure)", "azure_dns": "Azure - DNS", "azure_keyvault": "Azure - KeyVault", "baiducloud": "百度智能云", @@ -80,13 +80,13 @@ "baiducloud_dns": "百度智能云 - 智能云解析 DNS", "baishan": "白山云", "baishan_cdn": "白山云 - 内容分发网络 CDN", - "baotapanel": "宝塔面板(又名:aaPanel)", + "baotapanel": "宝塔面板 / aaPanel", "baotapanel_common": "宝塔面板", "baotapanel_console": "宝塔面板 - 面板自身", - "baotapanelgo": "宝塔面板极速版(又名:aaPanel WinGo)", + "baotapanelgo": "宝塔面板极速版 / aaPanel WinGo", "baotapanelgo_common": "宝塔面板极速版", "baotapanelgo_console": "宝塔面板极速版 - 面板自身", - "baotawaf": "堡塔云 WAF(又名:aaWAF)", + "baotawaf": "堡塔云 WAF / aaWAF", "baotawaf_common": "堡塔云 WAF", "baotawaf_console": "堡塔云 WAF - 面板自身", "beget": "Бегет(Beget)", @@ -152,9 +152,9 @@ "gname": "GNAME", "godaddy": "GoDaddy", "goedge": "GoEdge", - "googlecloud": "Google Cloud", + "googlecloud": "GCP(Google Cloud Platform)", + "googlecloud_certificatemanager": "Google Cloud - 证书管理器", "googlecloud_dns": "Google Cloud - DNS", - "googlecloud_certificatemanager": "Google Cloud - Certificate Manager", "googletrustservices": "Google Trust Services", "hetzner": "Hetzner", "hostingde": "hosting.de", @@ -205,6 +205,8 @@ "netlify": "Netlify", "nginxproxymanager": "Nginx Proxy Manager", "ns1": "NS1 (IBM NS1 Connect)", + "oraclecloud": "OCI(Oracle Cloud Infrastructure)", + "oraclecloud_dns": "Oracle Cloud - DNS", "ovhcloud": "OVHcloud", "porkbun": "Porkbun", "powerdns": "PowerDNS", diff --git a/ui/src/i18n/resources/zh/nls.workflow.nodes.json b/ui/src/i18n/resources/zh/nls.workflow.nodes.json index e0ce0f54..33fbaa87 100644 --- a/ui/src/i18n/resources/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/resources/zh/nls.workflow.nodes.json @@ -317,6 +317,16 @@ "placeholder": "请输入网站根目录", "tooltip": "即本机存储网站文件的主文件夹。" }, + "oraclecloud_dns_region": { + "label": "OCI 服务区域", + "placeholder": "请输入 OCI DNS 服务区域(例如:us-phoenix-1)", + "tooltip": "这是什么?请参阅 https://docs.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm" + }, + "oraclecloud_dns_compartment_ocid": { + "label": "OCI 资源区间 OCID", + "placeholder": "请输入 OCI 资源区间 OCID", + "tooltip": "这是什么?请参阅 https://docs.oracle.com/en-us/iaas/Content/Identity/compartments/managingcompartments.htm" + }, "s3_region": { "label": "对象存储区域", "placeholder": "请输入对象存储区域"