diff --git a/README.md b/README.md index 1a8480b24..59fb983eb 100644 --- a/README.md +++ b/README.md @@ -122,152 +122,152 @@ Detailed documentation is available [here](https://go-acme.github.io/lego/dns). DynDnsFree.de Dynu EasyDNS - Efficient IP + EdgeCenter + Efficient IP Epik Exoscale External program - F5 XC + F5 XC freemyip.com G-Core Gandi - Gandi Live DNS (v5) + Gandi Live DNS (v5) Glesys Go Daddy Google Cloud - Google Domains + Google Domains Hetzner Hosting.de Hostinger - Hosttech + Hosttech HTTP request http.net Huawei Cloud - Hurricane Electric DNS + Hurricane Electric DNS HyperOne IBM Cloud (SoftLayer) IIJ DNS Platform Service - Infoblox + Infoblox Infomaniak Internet Initiative Japan Internet.bs - INWX + INWX Ionos IPv64 iwantmyname (Deprecated) - Joker + Joker Joohoi's ACME-DNS KeyHelp Liara - Lima-City + Lima-City Linode (v4) Liquid Web Loopia - LuaDNS + LuaDNS Mail-in-a-Box ManageEngine CloudDNS Manual - Metaname + Metaname Metaregistrar mijn.host Mittwald - myaddr.{tools,dev,io} + myaddr.{tools,dev,io} MyDNS.jp MythicBeasts Name.com - Namecheap + Namecheap Namesilo NearlyFreeSpeech.NET Netcup - Netlify + Netlify Nicmanager NIFCloud Njalla - Nodion + Nodion NS1 Octenium Open Telekom Cloud - Oracle Cloud + Oracle Cloud OVH plesk.com Porkbun - PowerDNS + PowerDNS Rackspace Rain Yun/雨云 RcodeZero - reg.ru + reg.ru Regfish RFC2136 RimuHosting - RU CENTER + RU CENTER Sakura Cloud Scaleway Selectel - Selectel v2 + Selectel v2 SelfHost.(de|eu) Servercow Shellrent - Simply.com + Simply.com Sonic Spaceship Stackpath - Technitium + Technitium Tencent Cloud DNS Tencent EdgeOne Timeweb Cloud - TransIP + TransIP UKFast SafeDNS Ultradns Variomedia - VegaDNS + VegaDNS Vercel Versio.[nl|eu|uk] VinylDNS - VK Cloud + VK Cloud Volcano Engine/火山引擎 Vscale Vultr - webnames.ca + webnames.ca webnames.ru Websupport WEDOS - West.cn/西部数码 + West.cn/西部数码 Yandex 360 Yandex Cloud Yandex PDD - Zone.ee + Zone.ee ZoneEdit Zonomi - diff --git a/cmd/zz_gen_cmd_dnshelp.go b/cmd/zz_gen_cmd_dnshelp.go index e21f37e63..2859afd9b 100644 --- a/cmd/zz_gen_cmd_dnshelp.go +++ b/cmd/zz_gen_cmd_dnshelp.go @@ -62,6 +62,7 @@ func allDNSCodes() string { "dyndnsfree", "dynu", "easydns", + "edgecenter", "edgedns", "edgeone", "efficientip", @@ -1252,6 +1253,26 @@ func displayDNSHelp(w io.Writer, name string) error { ew.writeln() ew.writeln(`More information: https://go-acme.github.io/lego/dns/easydns`) + case "edgecenter": + // generated from: providers/dns/edgecenter/edgecenter.toml + ew.writeln(`Configuration for EdgeCenter.`) + ew.writeln(`Code: 'edgecenter'`) + ew.writeln(`Since: 'v4.29.0'`) + ew.writeln() + + ew.writeln(`Credentials:`) + ew.writeln(` - "EDGECENTER_PERMANENT_API_TOKEN": Permanent API token (https://edgecenter.ru/blog/permanent-api-token-explained/)`) + ew.writeln() + + ew.writeln(`Additional Configuration:`) + ew.writeln(` - "EDGECENTER_HTTP_TIMEOUT": API request timeout in seconds (Default: 10)`) + ew.writeln(` - "EDGECENTER_POLLING_INTERVAL": Time between DNS propagation check in seconds (Default: 20)`) + ew.writeln(` - "EDGECENTER_PROPAGATION_TIMEOUT": Maximum waiting time for DNS propagation in seconds (Default: 360)`) + ew.writeln(` - "EDGECENTER_TTL": The TTL of the TXT record used for the DNS challenge in seconds (Default: 120)`) + + ew.writeln() + ew.writeln(`More information: https://go-acme.github.io/lego/dns/edgecenter`) + case "edgedns": // generated from: providers/dns/edgedns/edgedns.toml ew.writeln(`Configuration for Akamai EdgeDNS.`) diff --git a/docs/content/dns/zz_gen_edgecenter.md b/docs/content/dns/zz_gen_edgecenter.md new file mode 100644 index 000000000..7c7dd9379 --- /dev/null +++ b/docs/content/dns/zz_gen_edgecenter.md @@ -0,0 +1,67 @@ +--- +title: "EdgeCenter" +date: 2019-03-03T16:39:46+01:00 +draft: false +slug: edgecenter +dnsprovider: + since: "v4.29.0" + code: "edgecenter" + url: "https://edgecenter.ru/dns" +--- + + + + + + +Configuration for [EdgeCenter](https://edgecenter.ru/dns). + + + + +- Code: `edgecenter` +- Since: v4.29.0 + + +Here is an example bash command using the EdgeCenter provider: + +```bash +EDGECENTER_PERMANENT_API_TOKEN=xxxxx \ +lego --email you@example.com --dns edgecenter -d '*.example.com' -d example.com run +``` + + + + +## Credentials + +| Environment Variable Name | Description | +|-----------------------|-------------| +| `EDGECENTER_PERMANENT_API_TOKEN` | Permanent API token (https://edgecenter.ru/blog/permanent-api-token-explained/) | + +The environment variable names can be suffixed by `_FILE` to reference a file instead of a value. +More information [here]({{% ref "dns#configuration-and-credentials" %}}). + + +## Additional Configuration + +| Environment Variable Name | Description | +|--------------------------------|-------------| +| `EDGECENTER_HTTP_TIMEOUT` | API request timeout in seconds (Default: 10) | +| `EDGECENTER_POLLING_INTERVAL` | Time between DNS propagation check in seconds (Default: 20) | +| `EDGECENTER_PROPAGATION_TIMEOUT` | Maximum waiting time for DNS propagation in seconds (Default: 360) | +| `EDGECENTER_TTL` | The TTL of the TXT record used for the DNS challenge in seconds (Default: 120) | + +The environment variable names can be suffixed by `_FILE` to reference a file instead of a value. +More information [here]({{% ref "dns#configuration-and-credentials" %}}). + + + + +## More information + +- [API documentation](https://apidocs.edgecenter.ru/dns) + + + + diff --git a/docs/data/zz_cli_help.toml b/docs/data/zz_cli_help.toml index 80cbcaac0..071c0f344 100644 --- a/docs/data/zz_cli_help.toml +++ b/docs/data/zz_cli_help.toml @@ -152,7 +152,7 @@ To display the documentation for a specific DNS provider, run: $ lego dnshelp -c code Supported DNS providers: - acme-dns, active24, alidns, allinkl, anexia, arvancloud, auroradns, autodns, axelname, azion, azure, azuredns, baiducloud, beget, binarylane, bindman, bluecat, bookmyname, brandit, bunny, checkdomain, civo, clouddns, cloudflare, cloudns, cloudru, cloudxns, conoha, conohav3, constellix, corenetworks, cpanel, derak, desec, designate, digitalocean, directadmin, dnshomede, dnsimple, dnsmadeeasy, dnspod, dode, domeneshop, dreamhost, duckdns, dyn, dyndnsfree, dynu, easydns, edgedns, edgeone, efficientip, epik, exec, exoscale, f5xc, freemyip, gandi, gandiv5, gcloud, gcore, glesys, godaddy, googledomains, hetzner, hostingde, hostinger, hosttech, httpnet, httpreq, huaweicloud, hurricane, hyperone, ibmcloud, iij, iijdpf, infoblox, infomaniak, internetbs, inwx, ionos, ipv64, iwantmyname, joker, keyhelp, liara, lightsail, limacity, linode, liquidweb, loopia, luadns, mailinabox, manageengine, manual, metaname, metaregistrar, mijnhost, mittwald, myaddr, mydnsjp, mythicbeasts, namecheap, namedotcom, namesilo, nearlyfreespeech, netcup, netlify, nicmanager, nicru, nifcloud, njalla, nodion, ns1, octenium, oraclecloud, otc, ovh, pdns, plesk, porkbun, rackspace, rainyun, rcodezero, regfish, regru, rfc2136, rimuhosting, route53, safedns, sakuracloud, scaleway, selectel, selectelv2, selfhostde, servercow, shellrent, simply, sonic, spaceship, stackpath, technitium, tencentcloud, timewebcloud, transip, ultradns, variomedia, vegadns, vercel, versio, vinyldns, vkcloud, volcengine, vscale, vultr, webnames, webnamesca, websupport, wedos, westcn, yandex, yandex360, yandexcloud, zoneedit, zoneee, zonomi + acme-dns, active24, alidns, allinkl, anexia, arvancloud, auroradns, autodns, axelname, azion, azure, azuredns, baiducloud, beget, binarylane, bindman, bluecat, bookmyname, brandit, bunny, checkdomain, civo, clouddns, cloudflare, cloudns, cloudru, cloudxns, conoha, conohav3, constellix, corenetworks, cpanel, derak, desec, designate, digitalocean, directadmin, dnshomede, dnsimple, dnsmadeeasy, dnspod, dode, domeneshop, dreamhost, duckdns, dyn, dyndnsfree, dynu, easydns, edgecenter, edgedns, edgeone, efficientip, epik, exec, exoscale, f5xc, freemyip, gandi, gandiv5, gcloud, gcore, glesys, godaddy, googledomains, hetzner, hostingde, hostinger, hosttech, httpnet, httpreq, huaweicloud, hurricane, hyperone, ibmcloud, iij, iijdpf, infoblox, infomaniak, internetbs, inwx, ionos, ipv64, iwantmyname, joker, keyhelp, liara, lightsail, limacity, linode, liquidweb, loopia, luadns, mailinabox, manageengine, manual, metaname, metaregistrar, mijnhost, mittwald, myaddr, mydnsjp, mythicbeasts, namecheap, namedotcom, namesilo, nearlyfreespeech, netcup, netlify, nicmanager, nicru, nifcloud, njalla, nodion, ns1, octenium, oraclecloud, otc, ovh, pdns, plesk, porkbun, rackspace, rainyun, rcodezero, regfish, regru, rfc2136, rimuhosting, route53, safedns, sakuracloud, scaleway, selectel, selectelv2, selfhostde, servercow, shellrent, simply, sonic, spaceship, stackpath, technitium, tencentcloud, timewebcloud, transip, ultradns, variomedia, vegadns, vercel, versio, vinyldns, vkcloud, volcengine, vscale, vultr, webnames, webnamesca, websupport, wedos, westcn, yandex, yandex360, yandexcloud, zoneedit, zoneee, zonomi More information: https://go-acme.github.io/lego/dns """ diff --git a/providers/dns/edgecenter/edgecenter.go b/providers/dns/edgecenter/edgecenter.go new file mode 100644 index 000000000..2040a304c --- /dev/null +++ b/providers/dns/edgecenter/edgecenter.go @@ -0,0 +1,160 @@ +package edgecenter + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/url" + "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" + "github.com/go-acme/lego/v4/providers/dns/internal/clientdebug" + "github.com/go-acme/lego/v4/providers/dns/internal/gcore" +) + +// Environment variables names. +const ( + envNamespace = "EDGECENTER_" + + EnvPermanentAPIToken = envNamespace + "PERMANENT_API_TOKEN" + + EnvTTL = envNamespace + "TTL" + EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT" + EnvPollingInterval = envNamespace + "POLLING_INTERVAL" + EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT" +) + +const ( + defaultPropagationTimeout = 360 * time.Second + defaultPollingInterval = 20 * time.Second +) + +var _ challenge.ProviderTimeout = (*DNSProvider)(nil) + +// Config for DNSProvider. +type Config struct { + APIToken string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider. +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt(EnvTTL, dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, defaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, defaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 10*time.Second), + }, + } +} + +// DNSProvider an implementation of challenge.Provider contract. +type DNSProvider struct { + config *Config + client *gcore.Client +} + +// NewDNSProvider returns an instance of DNSProvider configured for G-Core DNS API. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get(EnvPermanentAPIToken) + if err != nil { + return nil, fmt.Errorf("edgecenter: %w", err) + } + + config := NewDefaultConfig() + config.APIToken = values[EnvPermanentAPIToken] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for G-Core DNS API. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("edgecenter: the configuration of the DNS provider is nil") + } + + if config.APIToken == "" { + return nil, errors.New("edgecenter: incomplete credentials provided") + } + + client := gcore.NewClient(config.APIToken) + client.BaseURL, _ = url.Parse(gcore.DefaultEdgeCenterBaseURL) + + if config.HTTPClient != nil { + client.HTTPClient = config.HTTPClient + } + + client.HTTPClient = clientdebug.Wrap(client.HTTPClient) + + return &DNSProvider{ + config: config, + client: client, + }, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, _, keyAuth string) error { + info := dns01.GetChallengeInfo(domain, keyAuth) + + ctx := context.Background() + + zone, err := d.guessZone(ctx, info.EffectiveFQDN) + if err != nil { + return fmt.Errorf("edgecenter: %w", err) + } + + err = d.client.AddRRSet(ctx, zone, dns01.UnFqdn(info.EffectiveFQDN), info.Value, d.config.TTL) + if err != nil { + return fmt.Errorf("edgecenter: add txt record: %w", err) + } + + return nil +} + +// CleanUp removes the record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, _, keyAuth string) error { + info := dns01.GetChallengeInfo(domain, keyAuth) + + ctx := context.Background() + + zone, err := d.guessZone(ctx, info.EffectiveFQDN) + if err != nil { + return fmt.Errorf("edgecenter: %w", err) + } + + err = d.client.DeleteRRSet(ctx, zone, dns01.UnFqdn(info.EffectiveFQDN)) + if err != nil { + return fmt.Errorf("edgecenter: remove txt record: %w", err) + } + + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +func (d *DNSProvider) guessZone(ctx context.Context, fqdn string) (string, error) { + var lastErr error + + for zone := range dns01.UnFqdnDomainsSeq(fqdn) { + dnsZone, err := d.client.GetZone(ctx, zone) + if err != nil { + lastErr = err + continue + } + + return dnsZone.Name, nil + } + + return "", fmt.Errorf("zone %q not found: %w", fqdn, lastErr) +} diff --git a/providers/dns/edgecenter/edgecenter.toml b/providers/dns/edgecenter/edgecenter.toml new file mode 100644 index 000000000..0cd4b0cb6 --- /dev/null +++ b/providers/dns/edgecenter/edgecenter.toml @@ -0,0 +1,22 @@ +Name = "EdgeCenter" +Description = '''''' +URL = "https://edgecenter.ru/dns" +Code = "edgecenter" +Since = "v4.29.0" + +Example = ''' +EDGECENTER_PERMANENT_API_TOKEN=xxxxx \ +lego --email you@example.com --dns edgecenter -d '*.example.com' -d example.com run +''' + +[Configuration] + [Configuration.Credentials] + EDGECENTER_PERMANENT_API_TOKEN = "Permanent API token (https://edgecenter.ru/blog/permanent-api-token-explained/)" + [Configuration.Additional] + EDGECENTER_POLLING_INTERVAL = "Time between DNS propagation check in seconds (Default: 20)" + EDGECENTER_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation in seconds (Default: 360)" + EDGECENTER_TTL = "The TTL of the TXT record used for the DNS challenge in seconds (Default: 120)" + EDGECENTER_HTTP_TIMEOUT = "API request timeout in seconds (Default: 10)" + +[Links] + API = "https://apidocs.edgecenter.ru/dns" diff --git a/providers/dns/edgecenter/edgecenter_test.go b/providers/dns/edgecenter/edgecenter_test.go new file mode 100644 index 000000000..79814680d --- /dev/null +++ b/providers/dns/edgecenter/edgecenter_test.go @@ -0,0 +1,116 @@ +package edgecenter + +import ( + "testing" + + "github.com/go-acme/lego/v4/platform/tester" + "github.com/stretchr/testify/require" +) + +var envTest = tester.NewEnvTest(EnvPermanentAPIToken).WithDomain(envNamespace + "DOMAIN") + +func TestNewDNSProvider(t *testing.T) { + testCases := []struct { + desc string + envVars map[string]string + expected string + }{ + { + desc: "success", + envVars: map[string]string{ + EnvPermanentAPIToken: "A", + }, + }, + { + desc: "missing credentials", + envVars: map[string]string{ + EnvPermanentAPIToken: "", + }, + expected: "edgecenter: some credentials information are missing: EDGECENTER_PERMANENT_API_TOKEN", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + defer envTest.RestoreEnv() + + envTest.ClearEnv() + + envTest.Apply(test.envVars) + + p, err := NewDNSProvider() + + if test.expected == "" { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestNewDNSProviderConfig(t *testing.T) { + testCases := []struct { + desc string + apiToken string + expected string + }{ + { + desc: "success", + apiToken: "A", + }, + { + desc: "missing credentials", + expected: "edgecenter: incomplete credentials provided", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + config := NewDefaultConfig() + config.APIToken = test.apiToken + + p, err := NewDNSProviderConfig(config) + + if test.expected == "" { + require.NoError(t, err) + require.NotNil(t, p) + require.NotNil(t, p.config) + require.NotNil(t, p.client) + } else { + require.EqualError(t, err, test.expected) + } + }) + } +} + +func TestLivePresent(t *testing.T) { + if !envTest.IsLiveTest() { + t.Skip("skipping live test") + } + + envTest.RestoreEnv() + + provider, err := NewDNSProvider() + require.NoError(t, err) + + err = provider.Present(envTest.GetDomain(), "", "123d==") + require.NoError(t, err) +} + +func TestLiveCleanUp(t *testing.T) { + if !envTest.IsLiveTest() { + t.Skip("skipping live test") + } + + envTest.RestoreEnv() + + provider, err := NewDNSProvider() + require.NoError(t, err) + + err = provider.CleanUp(envTest.GetDomain(), "", "123d==") + require.NoError(t, err) +} diff --git a/providers/dns/gcore/gcore.go b/providers/dns/gcore/gcore.go index 19a548810..6400dc0b3 100644 --- a/providers/dns/gcore/gcore.go +++ b/providers/dns/gcore/gcore.go @@ -5,14 +5,13 @@ import ( "errors" "fmt" "net/http" - "strings" "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" - "github.com/go-acme/lego/v4/providers/dns/gcore/internal" "github.com/go-acme/lego/v4/providers/dns/internal/clientdebug" + "github.com/go-acme/lego/v4/providers/dns/internal/gcore" ) // Environment variables names. @@ -58,7 +57,7 @@ func NewDefaultConfig() *Config { // DNSProvider an implementation of challenge.Provider contract. type DNSProvider struct { config *Config - client *internal.Client + client *gcore.Client } // NewDNSProvider returns an instance of DNSProvider configured for G-Core DNS API. @@ -84,7 +83,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { return nil, errors.New("gcore: incomplete credentials provided") } - client := internal.NewClient(config.APIToken) + client := gcore.NewClient(config.APIToken) if config.HTTPClient != nil { client.HTTPClient = config.HTTPClient @@ -145,28 +144,15 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { func (d *DNSProvider) guessZone(ctx context.Context, fqdn string) (string, error) { var lastErr error - for _, zone := range extractAllZones(fqdn) { + for zone := range dns01.UnFqdnDomainsSeq(fqdn) { dnsZone, err := d.client.GetZone(ctx, zone) - if err == nil { - return dnsZone.Name, nil + if err != nil { + lastErr = err + continue } - lastErr = err + return dnsZone.Name, nil } return "", fmt.Errorf("zone %q not found: %w", fqdn, lastErr) } - -func extractAllZones(fqdn string) []string { - parts := strings.Split(dns01.UnFqdn(fqdn), ".") - if len(parts) < 3 { - return nil - } - - var zones []string - for i := 1; i < len(parts)-1; i++ { - zones = append(zones, strings.Join(parts[i:], ".")) - } - - return zones -} diff --git a/providers/dns/gcore/gcore_test.go b/providers/dns/gcore/gcore_test.go index 88769df21..88c1d02a5 100644 --- a/providers/dns/gcore/gcore_test.go +++ b/providers/dns/gcore/gcore_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/go-acme/lego/v4/platform/tester" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -115,30 +114,3 @@ func TestLiveCleanUp(t *testing.T) { err = provider.CleanUp(envTest.GetDomain(), "", "123d==") require.NoError(t, err) } - -func Test_extractAllZones(t *testing.T) { - testCases := []struct { - desc string - fqdn string - expected []string - }{ - { - desc: "success", - fqdn: "_acme-challenge.my.test.domain.com.", - expected: []string{"my.test.domain.com", "test.domain.com", "domain.com"}, - }, - { - desc: "empty", - fqdn: "_acme-challenge.com.", - }, - } - - for _, test := range testCases { - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - got := extractAllZones(test.fqdn) - assert.Equal(t, test.expected, got) - }) - } -} diff --git a/providers/dns/gcore/internal/client.go b/providers/dns/internal/gcore/client.go similarity index 89% rename from providers/dns/gcore/internal/client.go rename to providers/dns/internal/gcore/client.go index 638aaf0d7..93f17c0d2 100644 --- a/providers/dns/gcore/internal/client.go +++ b/providers/dns/internal/gcore/client.go @@ -1,4 +1,4 @@ -package internal +package gcore import ( "bytes" @@ -14,7 +14,10 @@ import ( "github.com/go-acme/lego/v4/providers/dns/internal/errutils" ) -const defaultBaseURL = "https://api.gcore.com/dns" +const ( + DefaultGCoreBaseURL = "https://api.gcore.com/dns" + DefaultEdgeCenterBaseURL = "https://api.edgecenter.ru/dns" +) const ( authorizationHeader = "Authorization" @@ -27,17 +30,17 @@ const txtRecordType = "TXT" type Client struct { token string - baseURL *url.URL + BaseURL *url.URL HTTPClient *http.Client } // NewClient constructor of Client. func NewClient(token string) *Client { - baseURL, _ := url.Parse(defaultBaseURL) + baseURL, _ := url.Parse(DefaultGCoreBaseURL) return &Client{ token: token, - baseURL: baseURL, + BaseURL: baseURL, HTTPClient: &http.Client{Timeout: 10 * time.Second}, } } @@ -45,7 +48,7 @@ func NewClient(token string) *Client { // GetZone gets zone information. // https://api.gcore.com/docs/dns#tag/zones/operation/Zone func (c *Client) GetZone(ctx context.Context, name string) (Zone, error) { - endpoint := c.baseURL.JoinPath("v2", "zones", name) + endpoint := c.BaseURL.JoinPath("v2", "zones", name) zone := Zone{} @@ -60,7 +63,7 @@ func (c *Client) GetZone(ctx context.Context, name string) (Zone, error) { // GetRRSet gets RRSet item. // https://api.gcore.com/docs/dns#tag/rrsets/operation/RRSet func (c *Client) GetRRSet(ctx context.Context, zone, name string) (RRSet, error) { - endpoint := c.baseURL.JoinPath("v2", "zones", zone, name, txtRecordType) + endpoint := c.BaseURL.JoinPath("v2", "zones", zone, name, txtRecordType) var result RRSet @@ -75,7 +78,7 @@ func (c *Client) GetRRSet(ctx context.Context, zone, name string) (RRSet, error) // DeleteRRSet removes RRSet record. // https://api.gcore.com/docs/dns#tag/rrsets/operation/DeleteRRSet func (c *Client) DeleteRRSet(ctx context.Context, zone, name string) error { - endpoint := c.baseURL.JoinPath("v2", "zones", zone, name, txtRecordType) + endpoint := c.BaseURL.JoinPath("v2", "zones", zone, name, txtRecordType) err := c.doRequest(ctx, http.MethodDelete, endpoint, nil, nil) if err != nil { @@ -106,14 +109,14 @@ func (c *Client) AddRRSet(ctx context.Context, zone, recordName, value string, t // https://api.gcore.com/docs/dns#tag/rrsets/operation/CreateRRSet func (c *Client) createRRSet(ctx context.Context, zone, name string, record RRSet) error { - endpoint := c.baseURL.JoinPath("v2", "zones", zone, name, txtRecordType) + endpoint := c.BaseURL.JoinPath("v2", "zones", zone, name, txtRecordType) return c.doRequest(ctx, http.MethodPost, endpoint, record, nil) } // https://api.gcore.com/docs/dns#tag/rrsets/operation/UpdateRRSet func (c *Client) updateRRSet(ctx context.Context, zone, name string, record RRSet) error { - endpoint := c.baseURL.JoinPath("v2", "zones", zone, name, txtRecordType) + endpoint := c.BaseURL.JoinPath("v2", "zones", zone, name, txtRecordType) return c.doRequest(ctx, http.MethodPut, endpoint, record, nil) } diff --git a/providers/dns/gcore/internal/client_test.go b/providers/dns/internal/gcore/client_test.go similarity index 98% rename from providers/dns/gcore/internal/client_test.go rename to providers/dns/internal/gcore/client_test.go index 4a0f83311..79289ef42 100644 --- a/providers/dns/gcore/internal/client_test.go +++ b/providers/dns/internal/gcore/client_test.go @@ -1,4 +1,4 @@ -package internal +package gcore import ( "net/http" @@ -21,7 +21,7 @@ func mockBuilder() *servermock.Builder[*Client] { return servermock.NewBuilder[*Client]( func(server *httptest.Server) (*Client, error) { client := NewClient(testToken) - client.baseURL, _ = url.Parse(server.URL) + client.BaseURL, _ = url.Parse(server.URL) client.HTTPClient = server.Client() return client, nil diff --git a/providers/dns/gcore/internal/types.go b/providers/dns/internal/gcore/types.go similarity index 96% rename from providers/dns/gcore/internal/types.go rename to providers/dns/internal/gcore/types.go index 4245f5ba8..1c4fbd502 100644 --- a/providers/dns/gcore/internal/types.go +++ b/providers/dns/internal/gcore/types.go @@ -1,4 +1,4 @@ -package internal +package gcore import "fmt" diff --git a/providers/dns/zz_gen_dns_providers.go b/providers/dns/zz_gen_dns_providers.go index 32de816a3..90bb2e13c 100644 --- a/providers/dns/zz_gen_dns_providers.go +++ b/providers/dns/zz_gen_dns_providers.go @@ -56,6 +56,7 @@ import ( "github.com/go-acme/lego/v4/providers/dns/dyndnsfree" "github.com/go-acme/lego/v4/providers/dns/dynu" "github.com/go-acme/lego/v4/providers/dns/easydns" + "github.com/go-acme/lego/v4/providers/dns/edgecenter" "github.com/go-acme/lego/v4/providers/dns/edgedns" "github.com/go-acme/lego/v4/providers/dns/edgeone" "github.com/go-acme/lego/v4/providers/dns/efficientip" @@ -277,6 +278,8 @@ func NewDNSChallengeProviderByName(name string) (challenge.Provider, error) { return dynu.NewDNSProvider() case "easydns": return easydns.NewDNSProvider() + case "edgecenter": + return edgecenter.NewDNSProvider() case "edgedns", "fastdns": return edgedns.NewDNSProvider() case "edgeone":