diff --git a/README.md b/README.md
index 97e851ea..b7cfc56e 100644
--- a/README.md
+++ b/README.md
@@ -96,6 +96,7 @@ make local.run
| [Azure](https://azure.microsoft.com/) | |
| [CloudFlare](https://www.cloudflare.com/) | |
| [ClouDNS](https://www.cloudns.net//) | |
+| [GNAME](https://www.gname.com/) | |
| [GoDaddy](https://www.godaddy.com/) | |
| [Name.com](https://www.name.com/) | |
| [NameSilo](https://www.namesilo.com/) | |
diff --git a/README_EN.md b/README_EN.md
index b5c71b3d..c2174fad 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -95,6 +95,7 @@ The following DNS providers are supported:
| [Azure DNS](https://azure.microsoft.com/) | |
| [CloudFlare](https://www.cloudflare.com/) | |
| [ClouDNS](https://www.cloudns.net//) | |
+| [GNAME](https://www.gname.com/) | |
| [GoDaddy](https://www.godaddy.com/) | |
| [Name.com](https://www.name.com/) | |
| [NameSilo](https://www.namesilo.com/) | |
diff --git a/internal/applicant/providers.go b/internal/applicant/providers.go
index 8329ff54..f53c7287 100644
--- a/internal/applicant/providers.go
+++ b/internal/applicant/providers.go
@@ -12,6 +12,7 @@ import (
providerAzureDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/azure-dns"
providerCloudflare "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare"
providerClouDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudns"
+ providerGname "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/gname"
providerGoDaddy "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy"
providerHuaweiCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud"
providerNameDotCom "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom"
@@ -131,6 +132,22 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return applicant, err
}
+ case domain.ApplyDNSProviderTypeGname:
+ {
+ access := domain.AccessConfigForGname{}
+ if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil {
+ return nil, fmt.Errorf("failed to decode provider access config: %w", err)
+ }
+
+ applicant, err := providerGname.NewChallengeProvider(&providerGname.GnameApplicantConfig{
+ AppId: access.AppId,
+ AppKey: access.AppKey,
+ DnsPropagationTimeout: options.DnsPropagationTimeout,
+ DnsTTL: options.DnsTTL,
+ })
+ return applicant, err
+ }
+
case domain.ApplyDNSProviderTypeGoDaddy:
{
access := domain.AccessConfigForGoDaddy{}
diff --git a/internal/domain/access.go b/internal/domain/access.go
index 70128622..c8448c21 100644
--- a/internal/domain/access.go
+++ b/internal/domain/access.go
@@ -78,6 +78,11 @@ type AccessConfigForEdgio struct {
ClientSecret string `json:"clientSecret"`
}
+type AccessConfigForGname struct {
+ AppId string `json:"appId"`
+ AppKey string `json:"appKey"`
+}
+
type AccessConfigForGoDaddy struct {
ApiKey string `json:"apiKey"`
ApiSecret string `json:"apiSecret"`
diff --git a/internal/domain/provider.go b/internal/domain/provider.go
index 374fab2c..894f8007 100644
--- a/internal/domain/provider.go
+++ b/internal/domain/provider.go
@@ -19,6 +19,7 @@ const (
AccessProviderTypeClouDNS = AccessProviderType("cloudns")
AccessProviderTypeDogeCloud = AccessProviderType("dogecloud")
AccessProviderTypeEdgio = AccessProviderType("edgio")
+ AccessProviderTypeGname = AccessProviderType("gname")
AccessProviderTypeGoDaddy = AccessProviderType("godaddy")
AccessProviderTypeHuaweiCloud = AccessProviderType("huaweicloud")
AccessProviderTypeKubernetes = AccessProviderType("k8s")
@@ -55,6 +56,7 @@ const (
ApplyDNSProviderTypeAzureDNS = ApplyDNSProviderType("azure-dns")
ApplyDNSProviderTypeCloudflare = ApplyDNSProviderType("cloudflare")
ApplyDNSProviderTypeClouDNS = ApplyDNSProviderType("cloudns")
+ ApplyDNSProviderTypeGname = ApplyDNSProviderType("gname")
ApplyDNSProviderTypeGoDaddy = ApplyDNSProviderType("godaddy")
ApplyDNSProviderTypeHuaweiCloud = ApplyDNSProviderType("huaweicloud") // 兼容旧值,等同于 [ApplyDNSProviderTypeHuaweiCloudDNS]
ApplyDNSProviderTypeHuaweiCloudDNS = ApplyDNSProviderType("huaweicloud-dns")
diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/gname/gname.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/gname/gname.go
new file mode 100644
index 00000000..90cec017
--- /dev/null
+++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/gname/gname.go
@@ -0,0 +1,40 @@
+package gname
+
+import (
+ "errors"
+ "time"
+
+ "github.com/go-acme/lego/v4/challenge"
+
+ internal "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/gname/internal"
+)
+
+type GnameApplicantConfig struct {
+ AppId string `json:"appId"`
+ AppKey string `json:"appKey"`
+ DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
+ DnsTTL int32 `json:"dnsTTL,omitempty"`
+}
+
+func NewChallengeProvider(config *GnameApplicantConfig) (challenge.Provider, error) {
+ if config == nil {
+ return nil, errors.New("config is nil")
+ }
+
+ providerConfig := internal.NewDefaultConfig()
+ providerConfig.AppID = config.AppId
+ providerConfig.AppKey = config.AppKey
+ if config.DnsPropagationTimeout != 0 {
+ providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second
+ }
+ if config.DnsTTL != 0 {
+ providerConfig.TTL = int(config.DnsTTL)
+ }
+
+ provider, err := internal.NewDNSProviderConfig(providerConfig)
+ if err != nil {
+ return nil, err
+ }
+
+ return provider, nil
+}
diff --git a/internal/pkg/core/applicant/acme-dns-01/lego-providers/gname/internal/lego.go b/internal/pkg/core/applicant/acme-dns-01/lego-providers/gname/internal/lego.go
new file mode 100644
index 00000000..979a803b
--- /dev/null
+++ b/internal/pkg/core/applicant/acme-dns-01/lego-providers/gname/internal/lego.go
@@ -0,0 +1,196 @@
+package lego_gname
+
+import (
+ "errors"
+ "fmt"
+ "time"
+
+ "github.com/go-acme/lego/v4/challenge"
+ "github.com/go-acme/lego/v4/challenge/dns01"
+ "github.com/go-acme/lego/v4/platform/config/env"
+
+ gnamesdk "github.com/usual2970/certimate/internal/pkg/vendors/gname-sdk"
+)
+
+const (
+ envNamespace = "GNAME_"
+
+ EnvAppID = envNamespace + "APP_ID"
+ EnvAppKey = envNamespace + "APP_KEY"
+
+ EnvTTL = envNamespace + "TTL"
+ EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
+ EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
+ EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
+)
+
+var _ challenge.ProviderTimeout = (*DNSProvider)(nil)
+
+type Config struct {
+ AppID string
+ AppKey string
+
+ PropagationTimeout time.Duration
+ PollingInterval time.Duration
+ TTL int
+ HTTPTimeout time.Duration
+}
+
+type DNSProvider struct {
+ client *gnamesdk.GnameClient
+ config *Config
+}
+
+func NewDefaultConfig() *Config {
+ return &Config{
+ TTL: env.GetOrDefaultInt(EnvTTL, dns01.DefaultTTL),
+ PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute),
+ PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval),
+ HTTPTimeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second),
+ }
+}
+
+func NewDNSProvider() (*DNSProvider, error) {
+ values, err := env.Get(EnvAppID, EnvAppKey)
+ if err != nil {
+ return nil, fmt.Errorf("gname: %w", err)
+ }
+
+ config := NewDefaultConfig()
+ config.AppID = values[EnvAppID]
+ config.AppKey = values[EnvAppKey]
+
+ return NewDNSProviderConfig(config)
+}
+
+func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
+ if config == nil {
+ return nil, errors.New("gname: the configuration of the DNS provider is nil")
+ }
+
+ client := gnamesdk.NewGnameClient(config.AppID, config.AppKey).
+ WithTimeout(config.HTTPTimeout)
+
+ return &DNSProvider{
+ client: client,
+ config: config,
+ }, nil
+}
+
+func (d *DNSProvider) Present(domain, token, keyAuth string) error {
+ info := dns01.GetChallengeInfo(domain, keyAuth)
+
+ zoneName, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
+ if err != nil {
+ return fmt.Errorf("gname: %w", err)
+ }
+
+ subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, zoneName)
+ if err != nil {
+ return fmt.Errorf("gname: %w", err)
+ }
+
+ if err := d.addOrUpdateDNSRecord(domain, subDomain, info.Value); err != nil {
+ return fmt.Errorf("gname: %w", err)
+ }
+
+ return nil
+}
+
+func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
+ fqdn, value := dns01.GetRecord(domain, keyAuth)
+ subDomain := dns01.UnFqdn(fqdn)
+
+ if err := d.removeDNSRecord(domain, subDomain, value); err != nil {
+ return fmt.Errorf("gname: %w", err)
+ }
+
+ return nil
+}
+
+func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
+ return d.config.PropagationTimeout, d.config.PollingInterval
+}
+
+func (d *DNSProvider) getDNSRecord(domain, subDomain string) (*gnamesdk.ResolutionRecord, error) {
+ page := 1
+ pageSize := 20
+ for {
+ request := &gnamesdk.ListDomainResolutionRequest{}
+ request.ZoneName = domain
+ request.Page = &page
+ request.PageSize = &pageSize
+
+ response, err := d.client.ListDomainResolution(request)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, record := range response.Data {
+ if record.RecordType == "TXT" && record.RecordName == subDomain {
+ return record, nil
+ }
+ }
+
+ if len(response.Data) == 0 {
+ break
+ }
+ if response.Page*response.PageSize >= response.Count {
+ break
+ }
+
+ page++
+ }
+
+ return nil, nil
+}
+
+func (d *DNSProvider) addOrUpdateDNSRecord(domain, subDomain, value string) error {
+ record, err := d.getDNSRecord(domain, subDomain)
+ if err != nil {
+ return err
+ }
+
+ if record == nil {
+ request := &gnamesdk.AddDomainResolutionRequest{
+ ZoneName: domain,
+ RecordType: "TXT",
+ RecordName: subDomain,
+ RecordValue: value,
+ TTL: d.config.TTL,
+ }
+ _, err := d.client.AddDomainResolution(request)
+ return err
+ } else {
+ request := &gnamesdk.ModifyDomainResolutionRequest{
+ ID: record.ID,
+ ZoneName: domain,
+ RecordType: "TXT",
+ RecordName: subDomain,
+ RecordValue: value,
+ TTL: d.config.TTL,
+ }
+ _, err := d.client.ModifyDomainResolution(request)
+ return err
+ }
+
+ return nil
+}
+
+func (d *DNSProvider) removeDNSRecord(domain, subDomain, value string) error {
+ record, err := d.getDNSRecord(domain, subDomain)
+ if err != nil {
+ return err
+ }
+
+ if record == nil {
+ return nil
+ }
+
+ request := &gnamesdk.DeleteDomainResolutionRequest{
+ ZoneName: domain,
+ RecordID: record.ID,
+ }
+ _, err = d.client.DeleteDomainResolution(request)
+ return err
+}
diff --git a/internal/pkg/vendors/gname-sdk/api.go b/internal/pkg/vendors/gname-sdk/api.go
index bb35f2e5..33972adc 100644
--- a/internal/pkg/vendors/gname-sdk/api.go
+++ b/internal/pkg/vendors/gname-sdk/api.go
@@ -5,7 +5,7 @@ type BaseResponse interface {
GetMsg() string
}
-type AddDNSRecordRequest struct {
+type AddDomainResolutionRequest struct {
ZoneName string `json:"ym"`
RecordType string `json:"lx"`
RecordName string `json:"zj"`
@@ -14,21 +14,21 @@ type AddDNSRecordRequest struct {
TTL int `json:"ttl"`
}
-type AddDNSRecordResponse struct {
+type AddDomainResolutionResponse struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data int `json:"data"`
}
-func (r *AddDNSRecordResponse) GetCode() int {
+func (r *AddDomainResolutionResponse) GetCode() int {
return r.Code
}
-func (r *AddDNSRecordResponse) GetMsg() string {
+func (r *AddDomainResolutionResponse) GetMsg() string {
return r.Msg
}
-type EditDNSRecordRequest struct {
+type ModifyDomainResolutionRequest struct {
ID string `json:"jxid"`
ZoneName string `json:"ym"`
RecordType string `json:"lx"`
@@ -38,53 +38,53 @@ type EditDNSRecordRequest struct {
TTL int `json:"ttl"`
}
-type EditDNSRecordResponse struct {
+type ModifyDomainResolutionResponse struct {
Code int `json:"code"`
Msg string `json:"msg"`
}
-func (r *EditDNSRecordResponse) GetCode() int {
+func (r *ModifyDomainResolutionResponse) GetCode() int {
return r.Code
}
-func (r *EditDNSRecordResponse) GetMsg() string {
+func (r *ModifyDomainResolutionResponse) GetMsg() string {
return r.Msg
}
-type DeleteDNSRecordRequest struct {
+type DeleteDomainResolutionRequest struct {
ZoneName string `json:"ym"`
- RecordId int `json:"jxid"`
+ RecordID string `json:"jxid"`
}
-type DeleteDNSRecordResponse struct {
+type DeleteDomainResolutionResponse struct {
Code int `json:"code"`
Msg string `json:"msg"`
}
-func (r *DeleteDNSRecordResponse) GetCode() int {
+func (r *DeleteDomainResolutionResponse) GetCode() int {
return r.Code
}
-func (r *DeleteDNSRecordResponse) GetMsg() string {
+func (r *DeleteDomainResolutionResponse) GetMsg() string {
return r.Msg
}
-type ListDNSRecordRequest struct {
+type ListDomainResolutionRequest struct {
ZoneName string `json:"ym"`
Page *int `json:"page,omitempty"`
PageSize *int `json:"limit,omitempty"`
}
-type ListDNSRecordResponse struct {
- Code int `json:"code"`
- Msg string `json:"msg"`
- Count int `json:"count"`
- Data []*DNSRecord `json:"data"`
- Page int `json:"page"`
- PageSize int `json:"pagesize"`
+type ListDomainResolutionResponse struct {
+ Code int `json:"code"`
+ Msg string `json:"msg"`
+ Count int `json:"count"`
+ Data []*ResolutionRecord `json:"data"`
+ Page int `json:"page"`
+ PageSize int `json:"pagesize"`
}
-type DNSRecord struct {
+type ResolutionRecord struct {
ID string `json:"id"`
ZoneName string `json:"ym"`
RecordType string `json:"lx"`
@@ -93,10 +93,10 @@ type DNSRecord struct {
MX int `json:"mx"`
}
-func (r *ListDNSRecordResponse) GetCode() int {
+func (r *ListDomainResolutionResponse) GetCode() int {
return r.Code
}
-func (r *ListDNSRecordResponse) GetMsg() string {
+func (r *ListDomainResolutionResponse) GetMsg() string {
return r.Msg
}
diff --git a/internal/pkg/vendors/gname-sdk/client.go b/internal/pkg/vendors/gname-sdk/client.go
index 81812682..d034cfeb 100644
--- a/internal/pkg/vendors/gname-sdk/client.go
+++ b/internal/pkg/vendors/gname-sdk/client.go
@@ -35,12 +35,12 @@ func (c *GnameClient) WithTimeout(timeout time.Duration) *GnameClient {
return c
}
-func (c *GnameClient) AddDNSRecord(req *AddDNSRecordRequest) (*AddDNSRecordResponse, error) {
+func (c *GnameClient) AddDomainResolution(req *AddDomainResolutionRequest) (*AddDomainResolutionResponse, error) {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, ¶ms)
- result := AddDNSRecordResponse{}
+ result := AddDomainResolutionResponse{}
err := c.sendRequestWithResult("/api/resolution/add", params, &result)
if err != nil {
return nil, err
@@ -48,12 +48,12 @@ func (c *GnameClient) AddDNSRecord(req *AddDNSRecordRequest) (*AddDNSRecordRespo
return &result, nil
}
-func (c *GnameClient) EditDNSRecord(req *EditDNSRecordRequest) (*EditDNSRecordResponse, error) {
+func (c *GnameClient) ModifyDomainResolution(req *ModifyDomainResolutionRequest) (*ModifyDomainResolutionResponse, error) {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, ¶ms)
- result := EditDNSRecordResponse{}
+ result := ModifyDomainResolutionResponse{}
err := c.sendRequestWithResult("/api/resolution/edit", params, &result)
if err != nil {
return nil, err
@@ -61,12 +61,12 @@ func (c *GnameClient) EditDNSRecord(req *EditDNSRecordRequest) (*EditDNSRecordRe
return &result, nil
}
-func (c *GnameClient) DeleteDNSRecord(req *DeleteDNSRecordRequest) (*DeleteDNSRecordResponse, error) {
+func (c *GnameClient) DeleteDomainResolution(req *DeleteDomainResolutionRequest) (*DeleteDomainResolutionResponse, error) {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, ¶ms)
- result := DeleteDNSRecordResponse{}
+ result := DeleteDomainResolutionResponse{}
err := c.sendRequestWithResult("/api/resolution/delete", params, &result)
if err != nil {
return nil, err
@@ -74,12 +74,12 @@ func (c *GnameClient) DeleteDNSRecord(req *DeleteDNSRecordRequest) (*DeleteDNSRe
return &result, nil
}
-func (c *GnameClient) ListDNSRecord(req *ListDNSRecordRequest) (*ListDNSRecordResponse, error) {
+func (c *GnameClient) ListDomainResolution(req *ListDomainResolutionRequest) (*ListDomainResolutionResponse, error) {
params := make(map[string]any)
jsonData, _ := json.Marshal(req)
json.Unmarshal(jsonData, ¶ms)
- result := ListDNSRecordResponse{}
+ result := ListDomainResolutionResponse{}
err := c.sendRequestWithResult("/api/resolution/list", params, &result)
if err != nil {
return nil, err
@@ -124,7 +124,7 @@ func (c *GnameClient) sendRequest(path string, params map[string]any) (*resty.Re
data["gntime"] = fmt.Sprintf("%d", time.Now().Unix())
data["gntoken"] = c.generateSignature(data)
- url := "https://api.gname.com" + path
+ url := "http://api.gname.com" + path
req := c.client.R().
SetHeader("Content-Type", "application/x-www-form-urlencoded").
SetFormData(data)
diff --git a/ui/public/imgs/providers/gname.svg b/ui/public/imgs/providers/gname.svg
new file mode 100644
index 00000000..ec409ca5
--- /dev/null
+++ b/ui/public/imgs/providers/gname.svg
@@ -0,0 +1 @@
+
diff --git a/ui/public/imgs/providers/rainyun.svg b/ui/public/imgs/providers/rainyun.svg
index 18413e16..1076cb76 100644
--- a/ui/public/imgs/providers/rainyun.svg
+++ b/ui/public/imgs/providers/rainyun.svg
@@ -1,10 +1 @@
-
+
diff --git a/ui/src/components/access/AccessForm.tsx b/ui/src/components/access/AccessForm.tsx
index e007eb89..c6c44d2d 100644
--- a/ui/src/components/access/AccessForm.tsx
+++ b/ui/src/components/access/AccessForm.tsx
@@ -19,6 +19,7 @@ import AccessFormCloudflareConfig from "./AccessFormCloudflareConfig";
import AccessFormClouDNSConfig from "./AccessFormClouDNSConfig";
import AccessFormDogeCloudConfig from "./AccessFormDogeCloudConfig";
import AccessFormEdgioConfig from "./AccessFormEdgioConfig";
+import AccessFormGnameConfig from "./AccessFormGnameConfig";
import AccessFormGoDaddyConfig from "./AccessFormGoDaddyConfig";
import AccessFormHuaweiCloudConfig from "./AccessFormHuaweiCloudConfig";
import AccessFormKubernetesConfig from "./AccessFormKubernetesConfig";
@@ -106,6 +107,8 @@ const AccessForm = forwardRef(({ className,
return ;
case ACCESS_PROVIDERS.DOGECLOUD:
return ;
+ case ACCESS_PROVIDERS.GNAME:
+ return ;
case ACCESS_PROVIDERS.GODADDY:
return ;
case ACCESS_PROVIDERS.EDGIO:
diff --git a/ui/src/components/access/AccessFormGnameConfig.tsx b/ui/src/components/access/AccessFormGnameConfig.tsx
new file mode 100644
index 00000000..f0c8f072
--- /dev/null
+++ b/ui/src/components/access/AccessFormGnameConfig.tsx
@@ -0,0 +1,76 @@
+import { useTranslation } from "react-i18next";
+import { Form, type FormInstance, Input } from "antd";
+import { createSchemaFieldRule } from "antd-zod";
+import { z } from "zod";
+
+import { type AccessConfigForGname } from "@/domain/access";
+
+type AccessFormGnameConfigFieldValues = Nullish;
+
+export type AccessFormGnameConfigProps = {
+ form: FormInstance;
+ formName: string;
+ disabled?: boolean;
+ initialValues?: AccessFormGnameConfigFieldValues;
+ onValuesChange?: (values: AccessFormGnameConfigFieldValues) => void;
+};
+
+const initFormModel = (): AccessFormGnameConfigFieldValues => {
+ return {
+ appId: "",
+ appKey: "",
+ };
+};
+
+const AccessFormGnameConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormGnameConfigProps) => {
+ const { t } = useTranslation();
+
+ const formSchema = z.object({
+ appId: z
+ .string()
+ .min(1, t("access.form.gname_app_id.placeholder"))
+ .max(64, t("common.errmsg.string_max", { max: 64 }))
+ .trim(),
+ appKey: z
+ .string()
+ .min(1, t("access.form.gname_app_key.placeholder"))
+ .max(64, t("common.errmsg.string_max", { max: 64 }))
+ .trim(),
+ });
+ const formRule = createSchemaFieldRule(formSchema);
+
+ const handleFormChange = (_: unknown, values: z.infer) => {
+ onValuesChange?.(values);
+ };
+
+ return (
+ }
+ >
+
+
+
+ }
+ >
+
+
+
+ );
+};
+
+export default AccessFormGnameConfig;
diff --git a/ui/src/domain/access.ts b/ui/src/domain/access.ts
index 14b31be6..1e229751 100644
--- a/ui/src/domain/access.ts
+++ b/ui/src/domain/access.ts
@@ -18,6 +18,7 @@ export interface AccessModel extends BaseModel {
| AccessConfigForClouDNS
| AccessConfigForDogeCloud
| AccessConfigForEdgio
+ | AccessConfigForGname
| AccessConfigForGoDaddy
| AccessConfigForHuaweiCloud
| AccessConfigForKubernetes
@@ -91,6 +92,11 @@ export type AccessConfigForEdgio = {
clientSecret: string;
};
+export type AccessConfigForGname = {
+ appId: string;
+ appKey: string;
+};
+
export type AccessConfigForGoDaddy = {
apiKey: string;
apiSecret: string;
diff --git a/ui/src/domain/provider.ts b/ui/src/domain/provider.ts
index 16fe5da6..652f4332 100644
--- a/ui/src/domain/provider.ts
+++ b/ui/src/domain/provider.ts
@@ -13,6 +13,7 @@ export const ACCESS_PROVIDERS = Object.freeze({
CLOUDFLARE: "cloudflare",
CLOUDNS: "cloudns",
DOGECLOUD: "dogecloud",
+ GNAME: "gname",
GODADDY: "godaddy",
EDGIO: "edgio",
HUAWEICLOUD: "huaweicloud",
@@ -73,6 +74,7 @@ export const accessProvidersMap: Maphttps://docs.edg.io/applications/v7/rest_api/authentication#administering-api-clients",
+ "access.form.gname_app_id.label": "GNAME AppId",
+ "access.form.gname_app_id.placeholder": "Please enter GNAME AppId",
+ "access.form.gname_app_id.tooltip": "For more information, see https://www.gname.com/user#/dealer_api",
+ "access.form.gname_app_key.label": "GNAME AppKey",
+ "access.form.gname_app_key.placeholder": "Please enter GNAME AppKey",
+ "access.form.gname_app_key.tooltip": "For more information, see https://www.gname.com/user#/dealer_api",
"access.form.godaddy_api_key.label": "GoDaddy API key",
"access.form.godaddy_api_key.placeholder": "Please enter GoDaddy API key",
"access.form.godaddy_api_key.tooltip": "For more information, see https://developer.godaddy.com/",
diff --git a/ui/src/i18n/locales/en/nls.common.json b/ui/src/i18n/locales/en/nls.common.json
index 4fb7e387..cb5c2d41 100644
--- a/ui/src/i18n/locales/en/nls.common.json
+++ b/ui/src/i18n/locales/en/nls.common.json
@@ -61,6 +61,7 @@
"common.provider.dogecloud.cdn": "Doge Cloud - CDN (Content Delivery Network)",
"common.provider.edgio": "Edgio",
"common.provider.edgio.applications": "Edgio - Applications",
+ "common.provider.gname": "GNAME",
"common.provider.godaddy": "GoDaddy",
"common.provider.huaweicloud": "Huawei Cloud",
"common.provider.huaweicloud.cdn": "Huawei Cloud - CDN (Content Delivery Network)",
diff --git a/ui/src/i18n/locales/zh/nls.access.json b/ui/src/i18n/locales/zh/nls.access.json
index 6fce9673..d0c9037d 100644
--- a/ui/src/i18n/locales/zh/nls.access.json
+++ b/ui/src/i18n/locales/zh/nls.access.json
@@ -90,6 +90,12 @@
"access.form.edgio_client_secret.label": "Edgio 客户端密码",
"access.form.edgio_client_secret.placeholder": "请输入 Edgio 客户端密码",
"access.form.edgio_client_secret.tooltip": "这是什么?请参阅 https://docs.edg.io/applications/v7/rest_api/authentication#administering-api-clients",
+ "access.form.gname_app_id.label": "GNAME AppId",
+ "access.form.gname_app_id.placeholder": "请输入 GNAME AppId",
+ "access.form.gname_app_id.tooltip": "这是什么?请参阅 https://www.gname.com/user#/dealer_api",
+ "access.form.gname_app_key.label": "GNAME AppKey",
+ "access.form.gname_app_key.placeholder": "请输入 GNAME AppKey",
+ "access.form.gname_app_key.tooltip": "这是什么?请参阅 https://www.gname.com/user#/dealer_api",
"access.form.godaddy_api_key.label": "GoDaddy API Key",
"access.form.godaddy_api_key.placeholder": "请输入 GoDaddy API Key",
"access.form.godaddy_api_key.tooltip": "这是什么?请参阅 https://developer.godaddy.com/",
diff --git a/ui/src/i18n/locales/zh/nls.common.json b/ui/src/i18n/locales/zh/nls.common.json
index 3035e533..b8b97842 100644
--- a/ui/src/i18n/locales/zh/nls.common.json
+++ b/ui/src/i18n/locales/zh/nls.common.json
@@ -61,6 +61,7 @@
"common.provider.dogecloud.cdn": "多吉云 - 内容分发网络 CDN",
"common.provider.edgio": "Edgio",
"common.provider.edgio.applications": "Edgio - Applications",
+ "common.provider.gname": "GNAME",
"common.provider.godaddy": "GoDaddy",
"common.provider.huaweicloud": "华为云",
"common.provider.huaweicloud.cdn": "华为云 - 内容分发网络 CDN",