Skip to content

Commit

Permalink
Add DNS provider for g-core labs (#1456)
Browse files Browse the repository at this point in the history
Co-authored-by: Fernandez Ludovic <ldez@users.noreply.github.com>
  • Loading branch information
shubinmi and ldez committed Jul 22, 2021
1 parent 6e982d6 commit 71a3bbc
Show file tree
Hide file tree
Showing 10 changed files with 879 additions and 18 deletions.
32 changes: 16 additions & 16 deletions README.md
Expand Up @@ -54,22 +54,22 @@ Detailed documentation is available [here](https://go-acme.github.io/lego/dns).
| [Digital Ocean](https://go-acme.github.io/lego/dns/digitalocean/) | [DNS Made Easy](https://go-acme.github.io/lego/dns/dnsmadeeasy/) | [DNSimple](https://go-acme.github.io/lego/dns/dnsimple/) | [DNSPod](https://go-acme.github.io/lego/dns/dnspod/) |
| [Domain Offensive (do.de)](https://go-acme.github.io/lego/dns/dode/) | [Domeneshop](https://go-acme.github.io/lego/dns/domeneshop/) | [DreamHost](https://go-acme.github.io/lego/dns/dreamhost/) | [Duck DNS](https://go-acme.github.io/lego/dns/duckdns/) |
| [Dyn](https://go-acme.github.io/lego/dns/dyn/) | [Dynu](https://go-acme.github.io/lego/dns/dynu/) | [EasyDNS](https://go-acme.github.io/lego/dns/easydns/) | [Exoscale](https://go-acme.github.io/lego/dns/exoscale/) |
| [External program](https://go-acme.github.io/lego/dns/exec/) | [freemyip.com](https://go-acme.github.io/lego/dns/freemyip/) | [Gandi Live DNS (v5)](https://go-acme.github.io/lego/dns/gandiv5/) | [Gandi](https://go-acme.github.io/lego/dns/gandi/) |
| [Glesys](https://go-acme.github.io/lego/dns/glesys/) | [Go Daddy](https://go-acme.github.io/lego/dns/godaddy/) | [Google Cloud](https://go-acme.github.io/lego/dns/gcloud/) | [Hetzner](https://go-acme.github.io/lego/dns/hetzner/) |
| [Hosting.de](https://go-acme.github.io/lego/dns/hostingde/) | [Hosttech](https://go-acme.github.io/lego/dns/hosttech/) | [HTTP request](https://go-acme.github.io/lego/dns/httpreq/) | [Hurricane Electric DNS](https://go-acme.github.io/lego/dns/hurricane/) |
| [HyperOne](https://go-acme.github.io/lego/dns/hyperone/) | [Infoblox](https://go-acme.github.io/lego/dns/infoblox/) | [Infomaniak](https://go-acme.github.io/lego/dns/infomaniak/) | [Internet Initiative Japan](https://go-acme.github.io/lego/dns/iij/) |
| [Internet.bs](https://go-acme.github.io/lego/dns/internetbs/) | [INWX](https://go-acme.github.io/lego/dns/inwx/) | [Ionos](https://go-acme.github.io/lego/dns/ionos/) | [Joker](https://go-acme.github.io/lego/dns/joker/) |
| [Joohoi's ACME-DNS](https://go-acme.github.io/lego/dns/acme-dns/) | [Linode (v4)](https://go-acme.github.io/lego/dns/linode/) | [Liquid Web](https://go-acme.github.io/lego/dns/liquidweb/) | [Loopia](https://go-acme.github.io/lego/dns/loopia/) |
| [LuaDNS](https://go-acme.github.io/lego/dns/luadns/) | [Manual](https://go-acme.github.io/lego/dns/manual/) | [MyDNS.jp](https://go-acme.github.io/lego/dns/mydnsjp/) | [MythicBeasts](https://go-acme.github.io/lego/dns/mythicbeasts/) |
| [Name.com](https://go-acme.github.io/lego/dns/namedotcom/) | [Namecheap](https://go-acme.github.io/lego/dns/namecheap/) | [Namesilo](https://go-acme.github.io/lego/dns/namesilo/) | [Netcup](https://go-acme.github.io/lego/dns/netcup/) |
| [Netlify](https://go-acme.github.io/lego/dns/netlify/) | [NIFCloud](https://go-acme.github.io/lego/dns/nifcloud/) | [Njalla](https://go-acme.github.io/lego/dns/njalla/) | [NS1](https://go-acme.github.io/lego/dns/ns1/) |
| [Open Telekom Cloud](https://go-acme.github.io/lego/dns/otc/) | [Oracle Cloud](https://go-acme.github.io/lego/dns/oraclecloud/) | [OVH](https://go-acme.github.io/lego/dns/ovh/) | [Porkbun](https://go-acme.github.io/lego/dns/porkbun/) |
| [PowerDNS](https://go-acme.github.io/lego/dns/pdns/) | [Rackspace](https://go-acme.github.io/lego/dns/rackspace/) | [reg.ru](https://go-acme.github.io/lego/dns/regru/) | [RFC2136](https://go-acme.github.io/lego/dns/rfc2136/) |
| [RimuHosting](https://go-acme.github.io/lego/dns/rimuhosting/) | [Sakura Cloud](https://go-acme.github.io/lego/dns/sakuracloud/) | [Scaleway](https://go-acme.github.io/lego/dns/scaleway/) | [Selectel](https://go-acme.github.io/lego/dns/selectel/) |
| [Servercow](https://go-acme.github.io/lego/dns/servercow/) | [Simply.com](https://go-acme.github.io/lego/dns/simply/) | [Sonic](https://go-acme.github.io/lego/dns/sonic/) | [Stackpath](https://go-acme.github.io/lego/dns/stackpath/) |
| [TransIP](https://go-acme.github.io/lego/dns/transip/) | [VegaDNS](https://go-acme.github.io/lego/dns/vegadns/) | [Versio.[nl/eu/uk]](https://go-acme.github.io/lego/dns/versio/) | [VinylDNS](https://go-acme.github.io/lego/dns/vinyldns/) |
| [Vscale](https://go-acme.github.io/lego/dns/vscale/) | [Vultr](https://go-acme.github.io/lego/dns/vultr/) | [WEDOS](https://go-acme.github.io/lego/dns/wedos/) | [Yandex](https://go-acme.github.io/lego/dns/yandex/) |
| [Zone.ee](https://go-acme.github.io/lego/dns/zoneee/) | [Zonomi](https://go-acme.github.io/lego/dns/zonomi/) | | |
| [External program](https://go-acme.github.io/lego/dns/exec/) | [freemyip.com](https://go-acme.github.io/lego/dns/freemyip/) | [G-Core Labs](https://go-acme.github.io/lego/dns/gcore/) | [Gandi Live DNS (v5)](https://go-acme.github.io/lego/dns/gandiv5/) |
| [Gandi](https://go-acme.github.io/lego/dns/gandi/) | [Glesys](https://go-acme.github.io/lego/dns/glesys/) | [Go Daddy](https://go-acme.github.io/lego/dns/godaddy/) | [Google Cloud](https://go-acme.github.io/lego/dns/gcloud/) |
| [Hetzner](https://go-acme.github.io/lego/dns/hetzner/) | [Hosting.de](https://go-acme.github.io/lego/dns/hostingde/) | [Hosttech](https://go-acme.github.io/lego/dns/hosttech/) | [HTTP request](https://go-acme.github.io/lego/dns/httpreq/) |
| [Hurricane Electric DNS](https://go-acme.github.io/lego/dns/hurricane/) | [HyperOne](https://go-acme.github.io/lego/dns/hyperone/) | [Infoblox](https://go-acme.github.io/lego/dns/infoblox/) | [Infomaniak](https://go-acme.github.io/lego/dns/infomaniak/) |
| [Internet Initiative Japan](https://go-acme.github.io/lego/dns/iij/) | [Internet.bs](https://go-acme.github.io/lego/dns/internetbs/) | [INWX](https://go-acme.github.io/lego/dns/inwx/) | [Ionos](https://go-acme.github.io/lego/dns/ionos/) |
| [Joker](https://go-acme.github.io/lego/dns/joker/) | [Joohoi's ACME-DNS](https://go-acme.github.io/lego/dns/acme-dns/) | [Linode (v4)](https://go-acme.github.io/lego/dns/linode/) | [Liquid Web](https://go-acme.github.io/lego/dns/liquidweb/) |
| [Loopia](https://go-acme.github.io/lego/dns/loopia/) | [LuaDNS](https://go-acme.github.io/lego/dns/luadns/) | [Manual](https://go-acme.github.io/lego/dns/manual/) | [MyDNS.jp](https://go-acme.github.io/lego/dns/mydnsjp/) |
| [MythicBeasts](https://go-acme.github.io/lego/dns/mythicbeasts/) | [Name.com](https://go-acme.github.io/lego/dns/namedotcom/) | [Namecheap](https://go-acme.github.io/lego/dns/namecheap/) | [Namesilo](https://go-acme.github.io/lego/dns/namesilo/) |
| [Netcup](https://go-acme.github.io/lego/dns/netcup/) | [Netlify](https://go-acme.github.io/lego/dns/netlify/) | [NIFCloud](https://go-acme.github.io/lego/dns/nifcloud/) | [Njalla](https://go-acme.github.io/lego/dns/njalla/) |
| [NS1](https://go-acme.github.io/lego/dns/ns1/) | [Open Telekom Cloud](https://go-acme.github.io/lego/dns/otc/) | [Oracle Cloud](https://go-acme.github.io/lego/dns/oraclecloud/) | [OVH](https://go-acme.github.io/lego/dns/ovh/) |
| [Porkbun](https://go-acme.github.io/lego/dns/porkbun/) | [PowerDNS](https://go-acme.github.io/lego/dns/pdns/) | [Rackspace](https://go-acme.github.io/lego/dns/rackspace/) | [reg.ru](https://go-acme.github.io/lego/dns/regru/) |
| [RFC2136](https://go-acme.github.io/lego/dns/rfc2136/) | [RimuHosting](https://go-acme.github.io/lego/dns/rimuhosting/) | [Sakura Cloud](https://go-acme.github.io/lego/dns/sakuracloud/) | [Scaleway](https://go-acme.github.io/lego/dns/scaleway/) |
| [Selectel](https://go-acme.github.io/lego/dns/selectel/) | [Servercow](https://go-acme.github.io/lego/dns/servercow/) | [Simply.com](https://go-acme.github.io/lego/dns/simply/) | [Sonic](https://go-acme.github.io/lego/dns/sonic/) |
| [Stackpath](https://go-acme.github.io/lego/dns/stackpath/) | [TransIP](https://go-acme.github.io/lego/dns/transip/) | [VegaDNS](https://go-acme.github.io/lego/dns/vegadns/) | [Versio.[nl/eu/uk]](https://go-acme.github.io/lego/dns/versio/) |
| [VinylDNS](https://go-acme.github.io/lego/dns/vinyldns/) | [Vscale](https://go-acme.github.io/lego/dns/vscale/) | [Vultr](https://go-acme.github.io/lego/dns/vultr/) | [WEDOS](https://go-acme.github.io/lego/dns/wedos/) |
| [Yandex](https://go-acme.github.io/lego/dns/yandex/) | [Zone.ee](https://go-acme.github.io/lego/dns/zoneee/) | [Zonomi](https://go-acme.github.io/lego/dns/zonomi/) | |

<!-- END DNS PROVIDERS LIST -->

Expand Down
21 changes: 21 additions & 0 deletions cmd/zz_gen_cmd_dnshelp.go
Expand Up @@ -50,6 +50,7 @@ func allDNSCodes() string {
"gandi",
"gandiv5",
"gcloud",
"gcore",
"glesys",
"godaddy",
"hetzner",
Expand Down Expand Up @@ -881,6 +882,26 @@ func displayDNSHelp(name string) error {
ew.writeln()
ew.writeln(`More information: https://go-acme.github.io/lego/dns/gcloud`)

case "gcore":
// generated from: providers/dns/gcore/gcore.toml
ew.writeln(`Configuration for G-Core Labs.`)
ew.writeln(`Code: 'gcore'`)
ew.writeln(`Since: 'v4.5.0'`)
ew.writeln()

ew.writeln(`Credentials:`)
ew.writeln(` - "GCORE_PERMANENT_API_TOKEN": Permanent API tokene (https://gcorelabs.com/blog/permanent-api-token-explained/)`)
ew.writeln()

ew.writeln(`Additional Configuration:`)
ew.writeln(` - "GCORE_HTTP_TIMEOUT": API request timeout`)
ew.writeln(` - "GCORE_POLLING_INTERVAL": Time between DNS propagation check`)
ew.writeln(` - "GCORE_PROPAGATION_TIMEOUT": Maximum waiting time for DNS propagation`)
ew.writeln(` - "GCORE_TTL": The TTL of the TXT record used for the DNS challenge`)

ew.writeln()
ew.writeln(`More information: https://go-acme.github.io/lego/dns/gcore`)

case "glesys":
// generated from: providers/dns/glesys/glesys.toml
ew.writeln(`Configuration for Glesys.`)
Expand Down
62 changes: 62 additions & 0 deletions docs/content/dns/zz_gen_gcore.md
@@ -0,0 +1,62 @@
---
title: "G-Core Labs"
date: 2019-03-03T16:39:46+01:00
draft: false
slug: gcore
---

<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
<!-- providers/dns/gcore/gcore.toml -->
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->

Since: v4.5.0

Configuration for [G-Core Labs](https://gcorelabs.com/dns/).


<!--more-->

- Code: `gcore`

Here is an example bash command using the G-Core Labs provider:

```bash
GCORE_PERMANENT_API_TOKEN=xxxxx \
lego --email myemail@example.com --dns gcore --domains my.example.org run
```




## Credentials

| Environment Variable Name | Description |
|-----------------------|-------------|
| `GCORE_PERMANENT_API_TOKEN` | Permanent API tokene (https://gcorelabs.com/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](/lego/dns/#configuration-and-credentials).


## Additional Configuration

| Environment Variable Name | Description |
|--------------------------------|-------------|
| `GCORE_HTTP_TIMEOUT` | API request timeout |
| `GCORE_POLLING_INTERVAL` | Time between DNS propagation check |
| `GCORE_PROPAGATION_TIMEOUT` | Maximum waiting time for DNS propagation |
| `GCORE_TTL` | The TTL of the TXT record used for the DNS challenge |

The environment variable names can be suffixed by `_FILE` to reference a file instead of a value.
More information [here](/lego/dns/#configuration-and-credentials).




## More information

- [API documentation](https://dnsapi.gcorelabs.com/docs#tag/zonesV2)

<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
<!-- providers/dns/gcore/gcore.toml -->
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
7 changes: 5 additions & 2 deletions providers/dns/dns_providers.go
Expand Up @@ -41,6 +41,7 @@ import (
"github.com/go-acme/lego/v4/providers/dns/gandi"
"github.com/go-acme/lego/v4/providers/dns/gandiv5"
"github.com/go-acme/lego/v4/providers/dns/gcloud"
"github.com/go-acme/lego/v4/providers/dns/gcore"
"github.com/go-acme/lego/v4/providers/dns/glesys"
"github.com/go-acme/lego/v4/providers/dns/godaddy"
"github.com/go-acme/lego/v4/providers/dns/hetzner"
Expand Down Expand Up @@ -173,10 +174,12 @@ func NewDNSChallengeProviderByName(name string) (challenge.Provider, error) {
return gandi.NewDNSProvider()
case "gandiv5":
return gandiv5.NewDNSProvider()
case "glesys":
return glesys.NewDNSProvider()
case "gcloud":
return gcloud.NewDNSProvider()
case "gcore":
return gcore.NewDNSProvider()
case "glesys":
return glesys.NewDNSProvider()
case "godaddy":
return godaddy.NewDNSProvider()
case "hetzner":
Expand Down
166 changes: 166 additions & 0 deletions providers/dns/gcore/gcore.go
@@ -0,0 +1,166 @@
package gcore

import (
"context"
"errors"
"fmt"
"net/http"
"strings"
"time"

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

const (
defaultPropagationTimeout = 360 * time.Second
defaultPollingInterval = 20 * time.Second
)

// Environment variables names.
const (
envNamespace = "GCORE_"

EnvPermanentAPIToken = envNamespace + "PERMANENT_API_TOKEN"

EnvTTL = envNamespace + "TTL"
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
)

// 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 *internal.Client
}

// NewDNSProvider returns an instance of DNSProvider configured for G-Core Labs DNS API.
func NewDNSProvider() (*DNSProvider, error) {
values, err := env.Get(EnvPermanentAPIToken)
if err != nil {
return nil, fmt.Errorf("gcore: %w", err)
}

config := NewDefaultConfig()
config.APIToken = values[EnvPermanentAPIToken]

return NewDNSProviderConfig(config)
}

// NewDNSProviderConfig return a DNSProvider instance configured for G-Core Labs DNS API.
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
if config == nil {
return nil, errors.New("gcore: the configuration of the DNS provider is nil")
}

if config.APIToken == "" {
return nil, errors.New("gcore: incomplete credentials provided")
}

client := internal.NewClient(config.APIToken)

if config.HTTPClient != nil {
client.HTTPClient = config.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 {
fqdn, value := dns01.GetRecord(domain, keyAuth)

ctx := context.Background()

zone, err := d.guessZone(ctx, fqdn)
if err != nil {
return fmt.Errorf("gcore: %w", err)
}

err = d.client.AddRRSet(ctx, zone, dns01.UnFqdn(fqdn), value, d.config.TTL)
if err != nil {
return fmt.Errorf("gcore: add txt record: %w", err)
}

return nil
}

// CleanUp removes the record matching the specified parameters.
func (d *DNSProvider) CleanUp(domain, _, keyAuth string) error {
fqdn, _ := dns01.GetRecord(domain, keyAuth)

ctx := context.Background()

zone, err := d.guessZone(ctx, fqdn)
if err != nil {
return fmt.Errorf("gcore: %w", err)
}

err = d.client.DeleteRRSet(ctx, zone, dns01.UnFqdn(fqdn))
if err != nil {
return fmt.Errorf("gcore: 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 extractAllZones(fqdn) {
dnsZone, err := d.client.GetZone(ctx, zone)
if err == nil {
return dnsZone.Name, nil
}

lastErr = err
}

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
}

0 comments on commit 71a3bbc

Please sign in to comment.