feat(provider): new deployment provider: linode object storage

This commit is contained in:
Fu Diwei
2026-06-12 12:44:35 +08:00
parent 8cea61eec5
commit 7528476b24
14 changed files with 457 additions and 49 deletions
@@ -0,0 +1,26 @@
package deployers
import (
"fmt"
"github.com/certimate-go/certimate/internal/domain"
"github.com/certimate-go/certimate/pkg/core"
dplyimpl "github.com/certimate-go/certimate/pkg/core/deployer/providers/linode-los"
xmaps "github.com/certimate-go/certimate/pkg/utils/maps"
)
func init() {
Registries.MustRegister(domain.DeploymentProviderTypeLinodeLOS, func(options *ProviderFactoryOptions) (core.Deployer, error) {
credentials := domain.AccessConfigForLinode{}
if err := xmaps.Populate(options.ProviderAccessConfig, &credentials); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
provider, err := dplyimpl.NewDeployer(&dplyimpl.DeployerConfig{
AccessToken: credentials.AccessToken,
RegionId: xmaps.GetString(options.ProviderExtendedConfig, "regionId"),
Bucket: xmaps.GetString(options.ProviderExtendedConfig, "bucket"),
})
return provider, err
})
}
+1
View File
@@ -391,6 +391,7 @@ const (
DeploymentProviderTypeKsyunCDN = DeploymentProviderType(AccessProviderTypeKsyun + "-cdn")
DeploymentProviderTypeKsyunSLB = DeploymentProviderType(AccessProviderTypeKsyun + "-slb")
DeploymentProviderTypeLeCDN = DeploymentProviderType(AccessProviderTypeLeCDN)
DeploymentProviderTypeLinodeLOS = DeploymentProviderType(AccessProviderTypeLinode + "-los")
DeploymentProviderTypeLocal = DeploymentProviderType(AccessProviderTypeLocal)
DeploymentProviderTypeMohuaMVH = DeploymentProviderType(AccessProviderTypeMohua + "-mvh")
DeploymentProviderTypeNetlify = DeploymentProviderType(AccessProviderTypeNetlify)
@@ -0,0 +1,109 @@
package linodelos
import (
"context"
"fmt"
"log/slog"
"github.com/certimate-go/certimate/pkg/core"
linodesdk "github.com/certimate-go/certimate/pkg/sdk3rd/linode"
)
type (
Provider = core.Deployer
DeployResult = core.DeployerDeployResult
)
type DeployerConfig struct {
// Linode AccessToken。
AccessToken string `json:"accessToken"`
// 对象存储区域 ID。
RegionId string `json:"regionId"`
// 对象存储桶名。
Bucket string `json:"bucket"`
}
type Deployer struct {
config *DeployerConfig
logger *slog.Logger
sdkClient *linodesdk.Client
}
var _ Provider = (*Deployer)(nil)
func NewDeployer(config *DeployerConfig) (*Deployer, error) {
if config == nil {
return nil, fmt.Errorf("the configuration of the deployer provider is nil")
}
client, err := createSDKClient(config.AccessToken)
if err != nil {
return nil, fmt.Errorf("could not create client: %w", err)
}
return &Deployer{
config: config,
logger: slog.Default(),
sdkClient: client,
}, nil
}
func (d *Deployer) SetLogger(logger *slog.Logger) {
if logger == nil {
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
}
func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*DeployResult, error) {
if d.config.RegionId == "" {
return nil, fmt.Errorf("config `regionId` is required")
}
if d.config.Bucket == "" {
return nil, fmt.Errorf("config `bucket` is required")
}
// Get an Object Storage TLS/SSL certificate
// REF: https://techdocs.akamai.com/linode-api/reference/get-object-storage-ssl
getObjectStorageSSLResp, err := d.sdkClient.GetObjectStorageSSLWithContext(ctx, d.config.RegionId, d.config.Bucket)
d.logger.Debug("sdk request 'objectstorage.GetSSL'", slog.String("params.regionId", d.config.RegionId), slog.String("params.bucket", d.config.Bucket), slog.Any("response", getObjectStorageSSLResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'objectstorage.GetSSL': %w", err)
}
// Delete an Object Storage TLS/SSL certificate
// REF: https://techdocs.akamai.com/linode-api/reference/delete-object-storage-ssl
if getObjectStorageSSLResp.SSL {
deleteObjectStorageSSLResp, err := d.sdkClient.DeleteObjectStorageSSLWithContext(ctx, d.config.RegionId, d.config.Bucket)
d.logger.Debug("sdk request 'objectstorage.DeleteSSL'", slog.String("params.regionId", d.config.RegionId), slog.String("params.bucket", d.config.Bucket), slog.Any("response", deleteObjectStorageSSLResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'objectstorage.DeleteSSL': %w", err)
}
}
// Upload an Object Storage TLS/SSL certificate
// REF: https://techdocs.akamai.com/linode-api/reference/post-object-storage-ssl
uploadObjectStorageSSLReq := &linodesdk.UploadObjectStorageSSLRequest{
Certificate: certPEM,
PrivateKey: privkeyPEM,
}
uploadObjectStorageSSLResp, err := d.sdkClient.UploadObjectStorageSSLWithContext(ctx, d.config.RegionId, d.config.Bucket, uploadObjectStorageSSLReq)
d.logger.Debug("sdk request 'objectstorage.UploadSSL'", slog.String("params.regionId", d.config.RegionId), slog.String("params.bucket", d.config.Bucket), slog.Any("request", uploadObjectStorageSSLReq), slog.Any("response", uploadObjectStorageSSLResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'objectstorage.UploadSSL': %w", err)
}
return &DeployResult{}, nil
}
func createSDKClient(accessToken string) (*linodesdk.Client, error) {
client, err := linodesdk.NewClient(
linodesdk.WithAccessToken(accessToken),
)
if err != nil {
return nil, err
}
return client, nil
}
@@ -0,0 +1,53 @@
package linodelos_test
import (
"testing"
"github.com/certimate-go/certimate/pkg/core/deployer/internal/tester"
impl "github.com/certimate-go/certimate/pkg/core/deployer/providers/linode-los"
)
var (
fp = tester.Args("LINODELOS_")
fTestCertPath string
fTestKeyPath string
fApiToken string
fAppName string
fDomain string
)
func init() {
fp.DefineString(&fTestCertPath, "TESTCERTPATH")
fp.DefineString(&fTestKeyPath, "TESTKEYPATH")
fp.DefineString(&fApiToken, "APITOKEN")
fp.DefineString(&fAppName, "APPNAME")
fp.DefineString(&fDomain, "DOMAIN")
}
/*
Shell command to run this test:
go test -v ./linode_los_test.go -args \
--LINODELOS_TESTCERTPATH="/path/to/your-test-cert.pem" \
--LINODELOS_TESTKEYPATH="/path/to/your-test-key.pem" \
--LINODELOS_APITOKEN="your-api-token" \
--LINODELOS_APPNAME="your-app-name" \
--LINODELOS_DOMAIN="example.com"
*/
func TestProvider(t *testing.T) {
fp.Parse()
t.Run("Deploy", func(t *testing.T) {
provider, err := impl.NewDeployer(&impl.DeployerConfig{
ApiToken: fApiToken,
AppName: fAppName,
Domain: fDomain,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
tester.TestDeploy(t, provider, tester.TestDeployArgs{CertPath: fTestCertPath, KeyPath: fTestKeyPath})
})
}
@@ -0,0 +1,40 @@
package linode
import (
"context"
"fmt"
"net/http"
"net/url"
)
type DeleteObjectStorageSSLResponse struct {
sdkResponseBase
}
func (c *Client) DeleteObjectStorageSSL(regionId string, bucket string) (*DeleteObjectStorageSSLResponse, error) {
return c.DeleteObjectStorageSSLWithContext(context.Background(), regionId, bucket)
}
func (c *Client) DeleteObjectStorageSSLWithContext(ctx context.Context, regionId string, bucket string) (*DeleteObjectStorageSSLResponse, error) {
if regionId == "" {
return nil, fmt.Errorf("sdkerr: bad request: unset regionId")
}
if bucket == "" {
return nil, fmt.Errorf("sdkerr: bad request: unset bucket")
}
path := fmt.Sprintf("/object-storage/buckets/%s/%s/ssl", url.PathEscape(regionId), url.PathEscape(bucket))
httpreq, err := c.newRequest(http.MethodDelete, path)
if err != nil {
return nil, err
} else {
httpreq.SetContext(ctx)
}
result := &DeleteObjectStorageSSLResponse{}
if _, err := c.doRequestWithResult(httpreq, result); err != nil {
return result, err
}
return result, nil
}
@@ -0,0 +1,42 @@
package linode
import (
"context"
"fmt"
"net/http"
"net/url"
)
type GetObjectStorageSSLResponse struct {
sdkResponseBase
SSL bool `json:"ssl"`
}
func (c *Client) GetObjectStorageSSL(regionId string, bucket string) (*GetObjectStorageSSLResponse, error) {
return c.GetObjectStorageSSLWithContext(context.Background(), regionId, bucket)
}
func (c *Client) GetObjectStorageSSLWithContext(ctx context.Context, regionId string, bucket string) (*GetObjectStorageSSLResponse, error) {
if regionId == "" {
return nil, fmt.Errorf("sdkerr: bad request: unset regionId")
}
if bucket == "" {
return nil, fmt.Errorf("sdkerr: bad request: unset bucket")
}
path := fmt.Sprintf("/object-storage/buckets/%s/%s/ssl", url.PathEscape(regionId), url.PathEscape(bucket))
httpreq, err := c.newRequest(http.MethodGet, path)
if err != nil {
return nil, err
} else {
httpreq.SetContext(ctx)
}
result := &GetObjectStorageSSLResponse{}
if _, err := c.doRequestWithResult(httpreq, result); err != nil {
return result, err
}
return result, nil
}
@@ -0,0 +1,50 @@
package linode
import (
"context"
"fmt"
"net/http"
"net/url"
)
type UploadObjectStorageSSLRequest struct {
sdkResponseBase
Certificate string `json:"certificate"`
PrivateKey string `json:"private_key"`
}
type UploadObjectStorageSSLResponse struct {
sdkResponseBase
SSL bool `json:"ssl"`
}
func (c *Client) UploadObjectStorageSSL(regionId string, bucket string, req *UploadObjectStorageSSLRequest) (*UploadObjectStorageSSLResponse, error) {
return c.UploadObjectStorageSSLWithContext(context.Background(), regionId, bucket, req)
}
func (c *Client) UploadObjectStorageSSLWithContext(ctx context.Context, regionId string, bucket string, req *UploadObjectStorageSSLRequest) (*UploadObjectStorageSSLResponse, error) {
if regionId == "" {
return nil, fmt.Errorf("sdkerr: bad request: unset regionId")
}
if bucket == "" {
return nil, fmt.Errorf("sdkerr: bad request: unset bucket")
}
path := fmt.Sprintf("/object-storage/buckets/%s/%s/ssl", url.PathEscape(regionId), url.PathEscape(bucket))
httpreq, err := c.newRequest(http.MethodPost, path)
if err != nil {
return nil, err
} else {
httpreq.SetBody(req)
httpreq.SetContext(ctx)
}
result := &UploadObjectStorageSSLResponse{}
if _, err := c.doRequestWithResult(httpreq, result); err != nil {
return result, err
}
return result, nil
}
@@ -81,6 +81,7 @@ import BizDeployNodeConfigFieldsProviderKsyunCDN from "./BizDeployNodeConfigFiel
import BizDeployNodeConfigFieldsProviderKsyunSLB from "./BizDeployNodeConfigFieldsProviderKsyunSLB";
import BizDeployNodeConfigFieldsProviderKubernetesSecret from "./BizDeployNodeConfigFieldsProviderKubernetesSecret";
import BizDeployNodeConfigFieldsProviderLeCDN from "./BizDeployNodeConfigFieldsProviderLeCDN";
import BizDeployNodeConfigFieldsProviderLinodeLOS from "./BizDeployNodeConfigFieldsProviderLinodeLOS";
import BizDeployNodeConfigFieldsProviderLocal from "./BizDeployNodeConfigFieldsProviderLocal";
import BizDeployNodeConfigFieldsProviderMohuaMVH from "./BizDeployNodeConfigFieldsProviderMohuaMVH";
import BizDeployNodeConfigFieldsProviderNetlify from "./BizDeployNodeConfigFieldsProviderNetlify";
@@ -223,6 +224,7 @@ const providerComponentMap: Partial<Record<DeploymentProviderType, React.Compone
[DEPLOYMENT_PROVIDERS.KSYUN_CDN]: BizDeployNodeConfigFieldsProviderKsyunCDN,
[DEPLOYMENT_PROVIDERS.KSYUN_SLB]: BizDeployNodeConfigFieldsProviderKsyunSLB,
[DEPLOYMENT_PROVIDERS.LECDN]: BizDeployNodeConfigFieldsProviderLeCDN,
[DEPLOYMENT_PROVIDERS.LINODE_LOS]: BizDeployNodeConfigFieldsProviderLinodeLOS,
[DEPLOYMENT_PROVIDERS.LOCAL]: BizDeployNodeConfigFieldsProviderLocal,
[DEPLOYMENT_PROVIDERS.MOHUA_MVH]: BizDeployNodeConfigFieldsProviderMohuaMVH,
[DEPLOYMENT_PROVIDERS.NETLIFY]: BizDeployNodeConfigFieldsProviderNetlify,
@@ -0,0 +1,63 @@
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 BizDeployNodeConfigFieldsProviderLinodeLOS = () => {
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, "regionId"]}
initialValue={initialValues.regionId}
label={t("workflow_node.deploy.form.linode_los_region_id.label")}
rules={[formRule]}
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.deploy.form.linode_los_region_id.tooltip") }}></span>}
>
<Input placeholder={t("workflow_node.deploy.form.linode_los_region_id.placeholder")} />
</Form.Item>
<Form.Item
name={[parentNamePath, "bucket"]}
initialValue={initialValues.bucket}
label={t("workflow_node.deploy.form.linode_los_bucket.label")}
rules={[formRule]}
>
<Input placeholder={t("workflow_node.deploy.form.linode_los_bucket.placeholder")} />
</Form.Item>
</>
);
};
const getInitialValues = (): Nullish<z.infer<ReturnType<typeof getSchema>>> => {
return {
regionId: "",
bucket: "",
};
};
const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType<typeof getI18n> }) => {
const { t: _ } = i18n;
return z.object({
regionId: z.string().nonempty(),
bucket: z.string().nonempty(),
});
};
const _default = Object.assign(BizDeployNodeConfigFieldsProviderLinodeLOS, {
getInitialValues,
getSchema,
});
export default _default;
+51 -49
View File
@@ -168,7 +168,6 @@ export const accessProvidersMap: Map<AccessProvider["type"] | string, AccessProv
[ACCESS_PROVIDERS.ALIYUN, "provider.aliyun", "/imgs/providers/aliyun.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.TENCENTCLOUD, "provider.tencentcloud", "/imgs/providers/tencentcloud.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.BAIDUCLOUD, "provider.baiducloud", "/imgs/providers/baiducloud.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.HUAWEICLOUD, "provider.huaweicloud", "/imgs/providers/huaweicloud.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.VOLCENGINE, "provider.volcengine", "/imgs/providers/volcengine.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.AWS, "provider.aws", "/imgs/providers/aws.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
@@ -178,23 +177,25 @@ export const accessProvidersMap: Map<AccessProvider["type"] | string, AccessProv
[ACCESS_PROVIDERS.CLOUDFLARE, "provider.cloudflare", "/imgs/providers/cloudflare.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.GCORE, "provider.gcore", "/imgs/providers/gcore.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.GOOGLECLOUD, "provider.googlecloud", "/imgs/providers/google.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.LINODE, "provider.linode", "/imgs/providers/linode.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.NETLIFY, "provider.netlify", "/imgs/providers/netlify.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.VERCEL, "provider.vercel", "/imgs/providers/vercel.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.BAIDUCLOUD, "provider.baiducloud", "/imgs/providers/baiducloud.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.CTCCCLOUD, "provider.ctcccloud", "/imgs/providers/ctcccloud.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.JDCLOUD, "provider.jdcloud", "/imgs/providers/jdcloud.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.RAINYUN, "provider.rainyun", "/imgs/providers/rainyun.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.UCLOUD, "provider.ucloud", "/imgs/providers/ucloud.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.CTCCCLOUD, "provider.ctcccloud", "/imgs/providers/ctcccloud.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.CPANEL, "provider.cpanel", "/imgs/providers/cpanel.svg", [ACCESS_USAGES.DNS, ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.QINIU, "provider.qiniu", "/imgs/providers/qiniu.svg", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.UPYUN, "provider.upyun", "/imgs/providers/upyun.svg", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.BAISHAN, "provider.baishan", "/imgs/providers/baishan.png", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.WANGSU, "provider.wangsu", "/imgs/providers/wangsu.svg", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.DOGECLOUD, "provider.dogecloud", "/imgs/providers/dogecloud.png", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.KSYUN, "provider.ksyun", "/imgs/providers/ksyun.svg", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.CACHEFLY, "provider.cachefly", "/imgs/providers/cachefly.png", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.QINIU, "provider.qiniu", "/imgs/providers/qiniu.svg", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.UPYUN, "provider.upyun", "/imgs/providers/upyun.svg", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.WANGSU, "provider.wangsu", "/imgs/providers/wangsu.svg", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.MOHUA, "provider.mohua", "/imgs/providers/mohua.png", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.UNICLOUD, "provider.unicloud", "/imgs/providers/unicloud.png", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.CACHEFLY, "provider.cachefly", "/imgs/providers/cachefly.png", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.ZENLAYER, "provider.zenlayer", "/imgs/providers/zenlayer.svg", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS["1PANEL"], "provider.1panel", "/imgs/providers/1panel.svg", [ACCESS_USAGES.HOSTING]],
[ACCESS_PROVIDERS.APISIX, "provider.apisix", "/imgs/providers/apisix.svg", [ACCESS_USAGES.HOSTING]],
@@ -238,7 +239,6 @@ export const accessProvidersMap: Map<AccessProvider["type"] | string, AccessProv
[ACCESS_PROVIDERS.HOSTINGER, "provider.hostinger", "/imgs/providers/hostinger.svg", [ACCESS_USAGES.DNS]],
[ACCESS_PROVIDERS.INFOMANIAK, "provider.infomaniak", "/imgs/providers/infomaniak.svg", [ACCESS_USAGES.DNS]],
[ACCESS_PROVIDERS.IONOS, "provider.ionos", "/imgs/providers/ionos.svg", [ACCESS_USAGES.DNS]],
[ACCESS_PROVIDERS.LINODE, "provider.linode", "/imgs/providers/linode.svg", [ACCESS_USAGES.DNS]],
[ACCESS_PROVIDERS.NAMECHEAP, "provider.namecheap", "/imgs/providers/namecheap.svg", [ACCESS_USAGES.DNS]],
[ACCESS_PROVIDERS.NAMEDOTCOM, "provider.namedotcom", "/imgs/providers/namedotcom.svg", [ACCESS_USAGES.DNS]],
[ACCESS_PROVIDERS.NAMESILO, "provider.namesilo", "/imgs/providers/namesilo.svg", [ACCESS_USAGES.DNS]],
@@ -464,10 +464,8 @@ export const acmeDns01ProvidersMap: Map<ACMEDns01Provider["type"] | string, ACME
[ACME_DNS01_PROVIDERS.ALIYUN_ESA, "provider.aliyun_esa"],
[ACME_DNS01_PROVIDERS.TENCENTCLOUD_DNS, "provider.tencentcloud_dns"],
[ACME_DNS01_PROVIDERS.TENCENTCLOUD_EO, "provider.tencentcloud_eo"],
[ACME_DNS01_PROVIDERS.BAIDUCLOUD_DNS, "provider.baiducloud_dns"],
[ACME_DNS01_PROVIDERS.HUAWEICLOUD_DNS, "provider.huaweicloud_dns"],
[ACME_DNS01_PROVIDERS.VOLCENGINE_DNS, "provider.volcengine_dns"],
[ACME_DNS01_PROVIDERS.JDCLOUD_DNS, "provider.jdcloud_dns"],
[ACME_DNS01_PROVIDERS.AWS_ROUTE53, "provider.aws_route53"],
[ACME_DNS01_PROVIDERS.AWS_LIGHTSAIL, "provider.aws_lightsail"],
[ACME_DNS01_PROVIDERS.AZURE_DNS, "provider.azure_dns"],
@@ -512,11 +510,13 @@ export const acmeDns01ProvidersMap: Map<ACMEDns01Provider["type"] | string, ACME
[ACME_DNS01_PROVIDERS.SPACESHIP, "provider.spaceship"],
[ACME_DNS01_PROVIDERS.VERCEL, "provider.vercel"],
[ACME_DNS01_PROVIDERS.VULTR, "provider.vultr"],
[ACME_DNS01_PROVIDERS.BAIDUCLOUD_DNS, "provider.baiducloud_dns"],
[ACME_DNS01_PROVIDERS.CMCCCLOUD_DNS, "provider.cmcccloud_dns"],
[ACME_DNS01_PROVIDERS.CTCCCLOUD_SMARTDNS, "provider.ctcccloud_smartdns"],
[ACME_DNS01_PROVIDERS.JDCLOUD_DNS, "provider.jdcloud_dns"],
[ACME_DNS01_PROVIDERS.RAINYUN, "provider.rainyun"],
[ACME_DNS01_PROVIDERS.UCLOUD_UDNR, "provider.ucloud_udnr"],
[ACME_DNS01_PROVIDERS.QINGCLOUD_DNS, "provider.qingcloud_dns"],
[ACME_DNS01_PROVIDERS.UCLOUD_UDNR, "provider.ucloud_udnr"],
[ACME_DNS01_PROVIDERS["35CN"], "provider.35cn"],
[ACME_DNS01_PROVIDERS["51DNSCOM"], "provider.51dnscom"],
[ACME_DNS01_PROVIDERS.DNSLA, "provider.dnsla"],
@@ -676,6 +676,7 @@ export const DEPLOYMENT_PROVIDERS = Object.freeze({
KSYUN_CDN: `${ACCESS_PROVIDERS.KSYUN}-cdn`,
KSYUN_SLB: `${ACCESS_PROVIDERS.KSYUN}-slb`,
LECDN: `${ACCESS_PROVIDERS.LECDN}`,
LINODE_LOS: `${ACCESS_PROVIDERS.LINODE}-los`,
LOCAL: `${ACCESS_PROVIDERS.LOCAL}`,
MOHUA_MVH: `${ACCESS_PROVIDERS.MOHUA}-mvh`,
NETLIFY: `${ACCESS_PROVIDERS.NETLIFY}`,
@@ -805,10 +806,6 @@ export const deploymentProvidersMap: Map<DeploymentProvider["type"] | string, De
[DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SSL, "provider.tencentcloud_ssl_upload", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SSL_DEPLOY, "provider.tencentcloud_ssl_deploy", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.TENCENTCLOUD_SSL_UPDATE, "provider.tencentcloud_ssl_update", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.BAIDUCLOUD_CDN, "provider.baiducloud_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.BAIDUCLOUD_BLB, "provider.baiducloud_blb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
[DEPLOYMENT_PROVIDERS.BAIDUCLOUD_APPBLB, "provider.baiducloud_appblb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
[DEPLOYMENT_PROVIDERS.BAIDUCLOUD_CERT, "provider.baiducloud_cert_upload", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.HUAWEICLOUD_CDN, "provider.huaweicloud_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.HUAWEICLOUD_OBS, "provider.huaweicloud_obs", DEPLOYMENT_CATEGORIES.STORAGE],
[DEPLOYMENT_PROVIDERS.HUAWEICLOUD_ELB, "provider.huaweicloud_elb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
@@ -828,40 +825,6 @@ export const deploymentProvidersMap: Map<DeploymentProvider["type"] | string, De
[DEPLOYMENT_PROVIDERS.VOLCENGINE_VOD, "provider.volcengine_vod", DEPLOYMENT_CATEGORIES.AV],
[DEPLOYMENT_PROVIDERS.VOLCENGINE_APIG, "provider.volcengine_apig", DEPLOYMENT_CATEGORIES.APIGATEWAY],
[DEPLOYMENT_PROVIDERS.VOLCENGINE_CERTCENTER, "provider.volcengine_certcenter_upload", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.JDCLOUD_ALB, "provider.jdcloud_alb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
[DEPLOYMENT_PROVIDERS.JDCLOUD_CDN, "provider.jdcloud_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.JDCLOUD_WAF, "provider.jdcloud_waf", DEPLOYMENT_CATEGORIES.FIREWALL],
[DEPLOYMENT_PROVIDERS.JDCLOUD_LIVE, "provider.jdcloud_live", DEPLOYMENT_CATEGORIES.AV],
[DEPLOYMENT_PROVIDERS.JDCLOUD_VOD, "provider.jdcloud_vod", DEPLOYMENT_CATEGORIES.AV],
[DEPLOYMENT_PROVIDERS.JDCLOUD_SSL, "provider.jdcloud_ssl_upload", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.QINIU_KODO, "provider.qiniu_kodo", DEPLOYMENT_CATEGORIES.STORAGE],
[DEPLOYMENT_PROVIDERS.QINIU_CDN, "provider.qiniu_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.QINIU_PILI, "provider.qiniu_pili", DEPLOYMENT_CATEGORIES.AV],
[DEPLOYMENT_PROVIDERS.UPYUN_FILE, "provider.upyun_file", DEPLOYMENT_CATEGORIES.STORAGE],
[DEPLOYMENT_PROVIDERS.UPYUN_CDN, "provider.upyun_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.BAISHAN_CDN, "provider.baishan_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.WANGSU_CDN, "provider.wangsu_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.WANGSU_CDNPRO, "provider.wangsu_cdnpro", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.WANGSU_CERTIFICATE, "provider.wangsu_certificate_upload", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.DOGECLOUD_CDN, "provider.dogecloud_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.KSYUN_CDN, "provider.ksyun_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.KSYUN_SLB, "provider.ksyun_slb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
[DEPLOYMENT_PROVIDERS.UCLOUD_US3, "provider.ucloud_us3", DEPLOYMENT_CATEGORIES.STORAGE],
[DEPLOYMENT_PROVIDERS.UCLOUD_UCDN, "provider.ucloud_ucdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.UCLOUD_UCLB, "provider.ucloud_uclb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
[DEPLOYMENT_PROVIDERS.UCLOUD_UALB, "provider.ucloud_ualb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
[DEPLOYMENT_PROVIDERS.UCLOUD_UEWAF, "provider.ucloud_uewaf", DEPLOYMENT_CATEGORIES.FIREWALL],
[DEPLOYMENT_PROVIDERS.UCLOUD_UPATHX, "provider.ucloud_upathx", DEPLOYMENT_CATEGORIES.ACCELERATOR],
[DEPLOYMENT_PROVIDERS.CTCCCLOUD_CDN, "provider.ctcccloud_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.CTCCCLOUD_ICDN, "provider.ctcccloud_icdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.CTCCCLOUD_AO, "provider.ctcccloud_ao", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.CTCCCLOUD_ELB, "provider.ctcccloud_elb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
[DEPLOYMENT_PROVIDERS.CTCCCLOUD_LVDN, "provider.ctcccloud_lvdn", DEPLOYMENT_CATEGORIES.AV],
[DEPLOYMENT_PROVIDERS.CTCCCLOUD_FAAS, "provider.ctcccloud_faas", DEPLOYMENT_CATEGORIES.SERVERLESS],
[DEPLOYMENT_PROVIDERS.CTCCCLOUD_CMS, "provider.ctcccloud_cms_upload", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.RAINYUN_RCDN, "provider.rainyun_rcdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.RAINYUN_SSLCENTER, "provider.rainyun_sslcenter_upload", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.UNICLOUD_WEBHOST, "provider.unicloud_webhost", DEPLOYMENT_CATEGORIES.WEBSITE],
[DEPLOYMENT_PROVIDERS.AWS_CLOUDFRONT, "provider.aws_cloudfront", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.AWS_CLB, "provider.aws_clb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
[DEPLOYMENT_PROVIDERS.AWS_ALB, "provider.aws_alb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
@@ -883,12 +846,51 @@ export const deploymentProvidersMap: Map<DeploymentProvider["type"] | string, De
[DEPLOYMENT_PROVIDERS.CACHEFLY, "provider.cachefly", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.CLOUDFLARE_SSL, "provider.cloudflare_ssl", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.GCORE_CDN, "provider.gcore_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.MOHUA_MVH, "provider.mohua_mvh", DEPLOYMENT_CATEGORIES.WEBSITE],
[DEPLOYMENT_PROVIDERS.LINODE_LOS, "provider.linode_los", DEPLOYMENT_CATEGORIES.STORAGE],
[DEPLOYMENT_PROVIDERS.FLYIO, "provider.flyio", DEPLOYMENT_CATEGORIES.WEBSITE],
[DEPLOYMENT_PROVIDERS.NETLIFY, "provider.netlify", DEPLOYMENT_CATEGORIES.WEBSITE],
[DEPLOYMENT_PROVIDERS.VERCEL, "provider.vercel", DEPLOYMENT_CATEGORIES.WEBSITE],
[DEPLOYMENT_PROVIDERS.ZENLAYER_CDN, "provider.zenlayer_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.ZENLAYER_GA, "provider.zenlayer_ga", DEPLOYMENT_CATEGORIES.ACCELERATOR],
[DEPLOYMENT_PROVIDERS.BAIDUCLOUD_CDN, "provider.baiducloud_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.BAIDUCLOUD_BLB, "provider.baiducloud_blb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
[DEPLOYMENT_PROVIDERS.BAIDUCLOUD_APPBLB, "provider.baiducloud_appblb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
[DEPLOYMENT_PROVIDERS.BAIDUCLOUD_CERT, "provider.baiducloud_cert_upload", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.CTCCCLOUD_CDN, "provider.ctcccloud_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.CTCCCLOUD_ICDN, "provider.ctcccloud_icdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.CTCCCLOUD_AO, "provider.ctcccloud_ao", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.CTCCCLOUD_ELB, "provider.ctcccloud_elb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
[DEPLOYMENT_PROVIDERS.CTCCCLOUD_LVDN, "provider.ctcccloud_lvdn", DEPLOYMENT_CATEGORIES.AV],
[DEPLOYMENT_PROVIDERS.CTCCCLOUD_FAAS, "provider.ctcccloud_faas", DEPLOYMENT_CATEGORIES.SERVERLESS],
[DEPLOYMENT_PROVIDERS.CTCCCLOUD_CMS, "provider.ctcccloud_cms_upload", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.JDCLOUD_ALB, "provider.jdcloud_alb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
[DEPLOYMENT_PROVIDERS.JDCLOUD_CDN, "provider.jdcloud_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.JDCLOUD_WAF, "provider.jdcloud_waf", DEPLOYMENT_CATEGORIES.FIREWALL],
[DEPLOYMENT_PROVIDERS.JDCLOUD_LIVE, "provider.jdcloud_live", DEPLOYMENT_CATEGORIES.AV],
[DEPLOYMENT_PROVIDERS.JDCLOUD_VOD, "provider.jdcloud_vod", DEPLOYMENT_CATEGORIES.AV],
[DEPLOYMENT_PROVIDERS.JDCLOUD_SSL, "provider.jdcloud_ssl_upload", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.KSYUN_CDN, "provider.ksyun_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.KSYUN_SLB, "provider.ksyun_slb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
[DEPLOYMENT_PROVIDERS.UCLOUD_US3, "provider.ucloud_us3", DEPLOYMENT_CATEGORIES.STORAGE],
[DEPLOYMENT_PROVIDERS.UCLOUD_UCDN, "provider.ucloud_ucdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.UCLOUD_UCLB, "provider.ucloud_uclb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
[DEPLOYMENT_PROVIDERS.UCLOUD_UALB, "provider.ucloud_ualb", DEPLOYMENT_CATEGORIES.LOADBALANCE],
[DEPLOYMENT_PROVIDERS.UCLOUD_UEWAF, "provider.ucloud_uewaf", DEPLOYMENT_CATEGORIES.FIREWALL],
[DEPLOYMENT_PROVIDERS.UCLOUD_UPATHX, "provider.ucloud_upathx", DEPLOYMENT_CATEGORIES.ACCELERATOR],
[DEPLOYMENT_PROVIDERS.BAISHAN_CDN, "provider.baishan_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.DOGECLOUD_CDN, "provider.dogecloud_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.QINIU_KODO, "provider.qiniu_kodo", DEPLOYMENT_CATEGORIES.STORAGE],
[DEPLOYMENT_PROVIDERS.QINIU_CDN, "provider.qiniu_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.QINIU_PILI, "provider.qiniu_pili", DEPLOYMENT_CATEGORIES.AV],
[DEPLOYMENT_PROVIDERS.WANGSU_CDN, "provider.wangsu_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.WANGSU_CDNPRO, "provider.wangsu_cdnpro", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.WANGSU_CERTIFICATE, "provider.wangsu_certificate_upload", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.UPYUN_FILE, "provider.upyun_file", DEPLOYMENT_CATEGORIES.STORAGE],
[DEPLOYMENT_PROVIDERS.UPYUN_CDN, "provider.upyun_cdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.RAINYUN_RCDN, "provider.rainyun_rcdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.RAINYUN_SSLCENTER, "provider.rainyun_sslcenter_upload", DEPLOYMENT_CATEGORIES.SSL],
[DEPLOYMENT_PROVIDERS.UNICLOUD_WEBHOST, "provider.unicloud_webhost", DEPLOYMENT_CATEGORIES.WEBSITE],
[DEPLOYMENT_PROVIDERS.MOHUA_MVH, "provider.mohua_mvh", DEPLOYMENT_CATEGORIES.WEBSITE],
[DEPLOYMENT_PROVIDERS.CDNFLY, "provider.cdnfly", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.FLEXCDN, "provider.flexcdn", DEPLOYMENT_CATEGORIES.CDN],
[DEPLOYMENT_PROVIDERS.GOEDGE, "provider.goedge", DEPLOYMENT_CATEGORIES.CDN],
@@ -187,6 +187,7 @@
"letsencrypt": "Let's Encrypt",
"letsencryptstaging": "Let's Encrypt Staging Environment",
"linode": "Linode",
"linode_los": "Linode - Object Storage",
"litessl": "LiteSSL",
"local": "Local host",
"mattermost": "Mattermost",
@@ -1834,6 +1834,15 @@
"placeholder": "Please enter LeCDN user ID",
"tooltip": "You can find it on LeCDN dashboard. <br>Required when using administrator's authorization. It Must be the same as the user to which the certificate belongs."
},
"linode_los_region_id": {
"label": "Linode region ID",
"placeholder": "Please enter Linode object storage region ID (e.g. us-east)",
"tooltip": "For more information, see <a href=\"https://techdocs.akamai.com/cloud-computing/docs/endpoint-types#supported-endpoint-types-by-region\" target=\"_blank\">https://techdocs.akamai.com/cloud-computing/docs/endpoint-types</a>"
},
"linode_los_bucket": {
"label": "Linode object storage bucket name",
"placeholder": "Please enter Linode object storage bucket name"
},
"local": {
"guide": "If you are running Certimate in Docker, the \"Local\" refers to the container rather than the host."
},
@@ -187,6 +187,7 @@
"letsencrypt": "Let's Encrypt",
"letsencryptstaging": "Let's Encrypt 测试环境",
"linode": "Linode",
"linode_los": "Linode - 对象存储",
"litessl": "LiteSSL",
"local": "本地主机",
"mattermost": "Mattermost",
@@ -1830,6 +1830,15 @@
"placeholder": "请输入 LeCDN 客户 ID",
"tooltip": "请登录 LeCDN 控制台查看。<br>使用的是系统管理员的授权信息时必填,需与证书所属客户相同。"
},
"linode_los_region_id": {
"label": "Linode 服务区域 ID",
"placeholder": "请输入 Linode 对象存储区域 ID(例如:us-east)",
"tooltip": "这是什么?请参阅 <a href=\"https://techdocs.akamai.com/cloud-computing/docs/endpoint-types#supported-endpoint-types-by-region\" target=\"_blank\">https://techdocs.akamai.com/cloud-computing/docs/endpoint-types</a>"
},
"linode_los_bucket": {
"label": "Linode 对象存储桶名",
"placeholder": "请输入 Linode 对象存储桶名"
},
"local": {
"guide": "如果你正在使用 Docker 运行 Certimate,「本地」指的是容器内而非宿主机。"
},