feat(provider): new acme dns-01 provider: oraclecloud

This commit is contained in:
Fu Diwei 2026-06-26 14:56:46 +08:00
parent a648631448
commit 7c8700a2f1
18 changed files with 511 additions and 22 deletions

6
go.mod
View File

@ -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

12
go.sum
View File

@ -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=

View File

@ -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)
}

View File

@ -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"`

View File

@ -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)

View File

@ -0,0 +1,7 @@
package oraclecloud
const (
AUTH_METHOD_APIKEY = "apikey"
AUTH_METHOD_INSTANCEPRINCIPAL = "instanceprincipal"
AUTH_METHOD_RESOURCEPRINCIPAL = "resourceprincipal"
)

View File

@ -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
}

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 393.815 203.828"><defs><clipPath clipPathUnits="userSpaceOnUse"><path d="M0 841.89h595.276V0H0Z"/></clipPath></defs><g transform="matrix(1.33333 0 0 -1.33333 -200.852 661.492)"><g><g><path d="M215.481 375.647c-17.881 0-32.981 15.534-32.981 33.909 0 18.451 14.796 33.446 32.981 33.446 18.184 0 32.983-14.995 32.983-33.446 0-18.375-15.107-33.909-32.983-33.909m0 98.596c-35.744 0-64.842-29.225-64.842-65.155 0-35.648 29.098-64.695 64.842-64.695 35.761 0 64.841 29.047 64.841 64.695 0 35.93-29.08 65.155-64.841 65.155" style="fill:#e31e30;fill-opacity:1;fill-rule:nonzero;stroke:none"/><path d="M381.963 394.02c-5.57-10.809-16.703-18.373-29.172-18.373-17.881 0-32.978 15.534-32.978 33.909 0 18.451 14.791 33.446 32.978 33.446 12.811 0 23.949-7.449 29.409-18.312l24.929 19.931c-11.584 17.825-31.613 29.622-54.338 29.622-35.744 0-64.843-29.225-64.843-65.155 0-35.648 29.099-64.695 64.843-64.695 22.783 0 42.849 11.786 54.408 29.558z" style="fill:#e31e30;fill-opacity:1;fill-rule:nonzero;stroke:none"/><path d="M413.976 368.717v70.226L446 464.499V343.248Z" style="fill:#e31e30;fill-opacity:1;fill-rule:nonzero;stroke:none"/><path d="M413.976 471.035v-21.054L446 475.658v20.461z" style="fill:#e31e30;fill-opacity:1;fill-rule:nonzero;stroke:none"/></g></g></g><script/></svg>

View File

@ -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<Record<AccessProviderType, React.ComponentTy
[ACCESS_PROVIDERS.NETLIFY]: AccessConfigFieldsProviderNetlify,
[ACCESS_PROVIDERS.NGINXPROXYMANAGER]: AccessConfigFieldsProviderNginxProxyManager,
[ACCESS_PROVIDERS.NS1]: AccessConfigFieldsProviderNS1,
[ACCESS_PROVIDERS.ORACLECLOUD]: AccessConfigFieldsProviderOracleCloud,
[ACCESS_PROVIDERS.OVHCLOUD]: AccessConfigFieldsProviderOVHcloud,
[ACCESS_PROVIDERS.PORKBUN]: AccessConfigFieldsProviderPorkbun,
[ACCESS_PROVIDERS.POWERDNS]: AccessConfigFieldsProviderPowerDNS,

View File

@ -0,0 +1,167 @@
import { getI18n, useTranslation } from "react-i18next";
import { Form, Input, Radio } from "antd";
import { createSchemaFieldRule } from "antd-zod";
import { z } from "zod";
import FileTextInput from "@/components/FileTextInput";
import Show from "@/components/Show";
import { validatePEMPrivateKey } from "@/utils/x509";
import { useFormNestedFieldsContext } from "./_context";
const AUTH_METHOD_APIKEY = "apikey" as const;
const AUTH_METHOD_INSTANCEPRINCIPAL = "instanceprincipal" as const;
const AUTH_METHOD_RESOURCEPRINCIPAL = "resourceprincipal" as const;
const AccessConfigFieldsProviderOracleCloud = () => {
const { i18n, t } = useTranslation();
const { parentNamePath } = useFormNestedFieldsContext();
const formSchema = z.object({
[parentNamePath]: getSchema({ i18n }),
});
const formRule = createSchemaFieldRule(formSchema);
const formInst = Form.useFormInstance<z.infer<typeof formSchema>>();
const initialValues = getInitialValues();
const fieldAuthMethod = Form.useWatch<string>([parentNamePath, "authMethod"], formInst);
return (
<>
<Form.Item
name={[parentNamePath, "authMethod"]}
initialValue={initialValues.authMethod}
label={t("access.form.oraclecloud_auth_method.label")}
rules={[formRule]}
>
<Radio.Group block>
<Radio.Button value={AUTH_METHOD_APIKEY}>{t("access.form.oraclecloud_auth_method.option.apikey.label")}</Radio.Button>
<Radio.Button value={AUTH_METHOD_INSTANCEPRINCIPAL}>{t("access.form.oraclecloud_auth_method.option.instanceprincipal.label")}</Radio.Button>
<Radio.Button value={AUTH_METHOD_RESOURCEPRINCIPAL}>{t("access.form.oraclecloud_auth_method.option.resourceprincipal.label")}</Radio.Button>
</Radio.Group>
</Form.Item>
<Show when={fieldAuthMethod === AUTH_METHOD_APIKEY}>
<Form.Item
name={[parentNamePath, "privateKey"]}
initialValue={initialValues.privateKey}
label={t("access.form.oraclecloud_private_key.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.oraclecloud_private_key.tooltip") }}></span>}
>
<FileTextInput autoSize={{ minRows: 3, maxRows: 10 }} placeholder={t("access.form.oraclecloud_private_key.placeholder")} />
</Form.Item>
<Form.Item
name={[parentNamePath, "privateKeyPassphrase"]}
initialValue={initialValues.privateKeyPassphrase}
label={t("access.form.oraclecloud_private_key_passphrase.label")}
rules={[formRule]}
>
<Input.Password autoComplete="new-password" placeholder={t("access.form.oraclecloud_private_key_passphrase.placeholder")} />
</Form.Item>
<Form.Item
name={[parentNamePath, "publicKeyFingerprint"]}
initialValue={initialValues.publicKeyFingerprint}
label={t("access.form.oraclecloud_public_key_fingerprint.label")}
rules={[formRule]}
>
<Input placeholder={t("access.form.oraclecloud_public_key_fingerprint.placeholder")} />
</Form.Item>
<Form.Item
name={[parentNamePath, "tenancyOcid"]}
initialValue={initialValues.tenancyOcid}
label={t("access.form.oraclecloud_tenancy_ocid.label")}
rules={[formRule]}
>
<Input placeholder={t("access.form.oraclecloud_tenancy_ocid.placeholder")} />
</Form.Item>
<Form.Item
name={[parentNamePath, "userOcid"]}
initialValue={initialValues.userOcid}
label={t("access.form.oraclecloud_user_ocid.label")}
rules={[formRule]}
>
<Input placeholder={t("access.form.oraclecloud_user_ocid.placeholder")} />
</Form.Item>
</Show>
</>
);
};
const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
return {
authMethod: AUTH_METHOD_APIKEY,
};
};
const getSchema = ({ i18n = getI18n() }: { i18n: ReturnType<typeof getI18n> }) => {
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;

View File

@ -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<Record<ACMEDns01ProviderType, React
[ACME_DNS01_PROVIDERS.HUAWEICLOUD_DNS]: BizApplyNodeConfigFieldsProviderHuaweiCloudDNS,
[ACME_DNS01_PROVIDERS.JDCLOUD]: BizApplyNodeConfigFieldsProviderJDCloudDNS,
[ACME_DNS01_PROVIDERS.JDCLOUD_DNS]: BizApplyNodeConfigFieldsProviderJDCloudDNS,
[ACME_DNS01_PROVIDERS.ORACLECLOUD]: BizApplyNodeConfigFieldsProviderOracleCloudDNS,
[ACME_DNS01_PROVIDERS.ORACLECLOUD_DNS]: BizApplyNodeConfigFieldsProviderOracleCloudDNS,
};
const acmeHttp01ProviderComponentMap: Partial<Record<ACMEHttp01ProviderType, React.ComponentType<any>>> = {

View File

@ -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 (
<>
<Form.Item
name={[parentNamePath, "region"]}
initialValue={initialValues.region}
label={t("workflow_node.apply.form.oraclecloud_dns_region.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.apply.form.oraclecloud_dns_region.tooltip") }}></span>}
>
<Input placeholder={t("workflow_node.apply.form.oraclecloud_dns_region.placeholder")} />
</Form.Item>
<Form.Item
name={[parentNamePath, "compartmentOcid"]}
initialValue={initialValues.compartmentOcid}
label={t("workflow_node.apply.form.oraclecloud_dns_compartment_ocid.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.apply.form.oraclecloud_dns_compartment_ocid.tooltip") }}></span>}
>
<Input placeholder={t("workflow_node.apply.form.oraclecloud_dns_compartment_ocid.placeholder")} />
</Form.Item>
</>
);
};
const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
return {
region: "us-phoenix-1",
compartmentOcid: "",
};
};
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
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;

View File

@ -736,13 +736,13 @@
"tooltip": "For more information, see <a href=\"https://goedge.cloud/docs/API/Auth.md\" target=\"_blank\">https://goedge.cloud/docs/API/Auth.md</a>"
},
"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 <a href=\"https://docs.cloud.google.com/resource-manager/docs/creating-managing-projects\" target=\"_blank\">https://docs.cloud.google.com/resource-manager/docs/creating-managing-projects</a>"
},
"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 <a href=\"https://docs.cloud.google.com/iam/docs/keys-create-delete\" target=\"_blank\">https://docs.cloud.google.com/iam/docs/keys-create-delete</a>"
},
"googletrustservices_eab": {
@ -1004,6 +1004,46 @@
"placeholder": "Please enter NS1 API key",
"tooltip": "For more information, see <a href=\"https://www.ibm.com/docs/en/ns1-connect?topic=introduction-using-api\" target=\"_blank\">https://www.ibm.com/docs/en/ns1-connect?topic=introduction-using-api</a>"
},
"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 <a href=\"https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm\" target=\"_blank\">https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm</a>"
},
"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 <a href=\"https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm\" target=\"_blank\">https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm</a>"
},
"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 <a href=\"https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm\" target=\"_blank\">https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm</a>"
},
"oraclecloud_tenancy_ocid": {
"label": "OCI tenancy OCID",
"placeholder": "Please enter OCI tenancy OCID",
"tooltip": "For more information, see <a href=\"https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm\" target=\"_blank\">https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm</a>"
},
"oraclecloud_user_ocid": {
"label": "OCI user OCID",
"placeholder": "Please enter OCI user OCID",
"tooltip": "For more information, see <a href=\"https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm\" target=\"_blank\">https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm</a>"
},
"ovhcloud_endpoint": {
"label": "OVHcloud API endpoint",
"placeholder": "Please enter OVHcloud API endpoint"

View File

@ -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",

View File

@ -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 <a href=\"https://docs.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm\" target=\"_blank\">https://docs.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm</a>"
},
"oraclecloud_dns_compartment_ocid": {
"label": "OCI compartment OCID",
"placeholder": "Please enter OCI compartment OCID",
"tooltip": "For more information, see <a href=\"https://docs.oracle.com/en-us/iaas/Content/Identity/compartments/managingcompartments.htm\" target=\"_blank\">https://docs.oracle.com/en-us/iaas/Content/Identity/compartments/managingcompartments.htm</a>"
},
"s3_region": {
"label": "Object storage (S3-compatible) region",
"placeholder": "Please enter region"

View File

@ -736,13 +736,13 @@
"tooltip": "这是什么?请参阅 <a href=\"https://goedge.cloud/docs/API/Auth.md\" target=\"_blank\">https://goedge.cloud/docs/API/Auth.md</a>"
},
"googlecloud_project_id": {
"label": "Google Cloud 项目 ID",
"placeholder": "请输入 Google Cloud 项目 ID",
"label": "GCP 项目 ID",
"placeholder": "请输入 GCP 项目 ID",
"tooltip": "这是什么?请参阅 <a href=\"https://docs.cloud.google.com/resource-manager/docs/creating-managing-projects?hl=zh-cn\" target=\"_blank\">https://docs.cloud.google.com/resource-manager/docs/creating-managing-projects</a>"
},
"googlecloud_service_account_key": {
"label": "Google Cloud 服务账号密钥",
"placeholder": "请输入 Google Cloud 服务账号密钥",
"label": "GCP 服务账号密钥",
"placeholder": "请输入 GCP 服务账号密钥",
"tooltip": "这是什么?请参阅 <a href=\"https://docs.cloud.google.com/iam/docs/keys-create-delete?hl=zh-cn\" target=\"_blank\">https://docs.cloud.google.com/iam/docs/keys-create-delete</a>"
},
"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": "这是什么?请参阅 <a href=\"https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm\" target=\"_blank\">https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm</a>"
},
"oraclecloud_private_key_passphrase": {
"label": "OCI API 签名私钥口令(可选)",
"placeholder": "请输入 OCI API 签名私钥口令",
"tooltip": "这是什么?请参阅 <a href=\"https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm\" target=\"_blank\">https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm</a>"
},
"oraclecloud_public_key_fingerprint": {
"label": "OCI API 签名公钥指纹",
"placeholder": "请输入 OCI API 签名公钥指纹",
"tooltip": "这是什么?请参阅 <a href=\"https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm\" target=\"_blank\">https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm</a>"
},
"oraclecloud_tenancy_ocid": {
"label": "OCI 租户 OCID",
"placeholder": "请输入 OCI 租户 OCID",
"tooltip": "这是什么?请参阅 <a href=\"https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm\" target=\"_blank\">https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm</a>"
},
"oraclecloud_user_ocid": {
"label": "OCI 用户 OCID",
"placeholder": "请输入 OCI 用户 OCID",
"tooltip": "这是什么?请参阅 <a href=\"https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm\" target=\"_blank\">https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm</a>"
},
"ns1_api_key": {
"label": "NS1 API Key",
"placeholder": "请输入 NS1 API Key",

View File

@ -58,7 +58,7 @@
"aliyun_waf": "阿里云 - Web 应用防火墙 WAF",
"apisix": "Apache APISIX",
"arvancloud": "ArvanCloud",
"aws": "AWS",
"aws": "AWSAmazon 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": "AzureMicrosoft 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": "GCPGoogle 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": "OCIOracle Cloud Infrastructure",
"oraclecloud_dns": "Oracle Cloud - DNS",
"ovhcloud": "OVHcloud",
"porkbun": "Porkbun",
"powerdns": "PowerDNS",

View File

@ -317,6 +317,16 @@
"placeholder": "请输入网站根目录",
"tooltip": "即本机存储网站文件的主文件夹。"
},
"oraclecloud_dns_region": {
"label": "OCI 服务区域",
"placeholder": "请输入 OCI DNS 服务区域例如us-phoenix-1",
"tooltip": "这是什么?请参阅 <a href=\"https://docs.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm\" target=\"_blank\">https://docs.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm</a>"
},
"oraclecloud_dns_compartment_ocid": {
"label": "OCI 资源区间 OCID",
"placeholder": "请输入 OCI 资源区间 OCID",
"tooltip": "这是什么?请参阅 <a href=\"https://docs.oracle.com/en-us/iaas/Content/Identity/compartments/managingcompartments.htm\" target=\"_blank\">https://docs.oracle.com/en-us/iaas/Content/Identity/compartments/managingcompartments.htm</a>"
},
"s3_region": {
"label": "对象存储区域",
"placeholder": "请输入对象存储区域"