Skip to content

Commit

Permalink
Add DNS provider for CIVO (#1707)
Browse files Browse the repository at this point in the history
  • Loading branch information
dirien authored Sep 9, 2022
1 parent 438c2f1 commit 62a0d11
Show file tree
Hide file tree
Showing 9 changed files with 443 additions and 25 deletions.
48 changes: 24 additions & 24 deletions README.md

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions cmd/zz_gen_cmd_dnshelp.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func allDNSCodes() string {
"bindman",
"bluecat",
"checkdomain",
"civo",
"clouddns",
"cloudflare",
"cloudns",
Expand Down Expand Up @@ -344,6 +345,25 @@ func displayDNSHelp(name string) error {
ew.writeln()
ew.writeln(`More information: https://go-acme.github.io/lego/dns/checkdomain`)

case "civo":
// generated from: providers/dns/civo/civo.toml
ew.writeln(`Configuration for Civo.`)
ew.writeln(`Code: 'civo'`)
ew.writeln(`Since: 'v4.9.0'`)
ew.writeln()

ew.writeln(`Credentials:`)
ew.writeln(` - "CIVO_TOKEN": Authentication token`)
ew.writeln()

ew.writeln(`Additional Configuration:`)
ew.writeln(` - "CIVO_POLLING_INTERVAL": Time between DNS propagation check`)
ew.writeln(` - "CIVO_PROPAGATION_TIMEOUT": Maximum waiting time for DNS propagation`)
ew.writeln(` - "CIVO_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/civo`)

case "clouddns":
// generated from: providers/dns/clouddns/clouddns.toml
ew.writeln(`Configuration for CloudDNS.`)
Expand Down
66 changes: 66 additions & 0 deletions docs/content/dns/zz_gen_civo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: "Civo"
date: 2019-03-03T16:39:46+01:00
draft: false
slug: civo
dnsprovider:
since: "v4.9.0"
code: "civo"
url: "https://civo.com"
---

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


Configuration for [Civo](https://civo.com).


<!--more-->

- Code: `civo`
- Since: v4.9.0


Here is an example bash command using the Civo provider:

```bash
CIVO_TOKEN=xxxxxx \
lego --email you@example.com --dns civo --domains my.example.org run
```




## Credentials

| Environment Variable Name | Description |
|-----------------------|-------------|
| `CIVO_TOKEN` | Authentication token |

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 |
|--------------------------------|-------------|
| `CIVO_POLLING_INTERVAL` | Time between DNS propagation check |
| `CIVO_PROPAGATION_TIMEOUT` | Maximum waiting time for DNS propagation |
| `CIVO_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]({{< ref "dns#configuration-and-credentials" >}}).




## More information

- [API documentation](https://www.civo.com/api/dns)

<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
<!-- providers/dns/civo/civo.toml -->
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1755
github.com/aws/aws-sdk-go v1.39.0
github.com/cenkalti/backoff/v4 v4.1.3
github.com/civo/civogo v0.3.11
github.com/cloudflare/cloudflare-go v0.49.0
github.com/cpu/goacmedns v0.1.1
github.com/dnsimple/dnsimple-go v0.71.1
Expand Down
7 changes: 6 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/civo/civogo v0.3.11 h1:mON/fyrV946Sbk6paRtOSGsN+asCgCmHCgArf5xmGxM=
github.com/civo/civogo v0.3.11/go.mod h1:7+GeeFwc4AYTULaEshpT2vIcl3Qq8HPoxA17viX3l6g=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cloudflare-go v0.49.0 h1:KqJYk/YQ5ZhmyYz1oa4kGDskfF1gVuZfqesaJ/XDLto=
github.com/cloudflare/cloudflare-go v0.49.0/go.mod h1:h0QgcIZ3qEXwFiwfBO8sQxjVdYsLX+PfD7NFEnANaKg=
Expand Down Expand Up @@ -427,8 +429,9 @@ github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
github.com/oracle/oci-go-sdk v24.3.0+incompatible h1:x4mcfb4agelf1O4/1/auGlZ1lr97jXRSSN5MxTgG/zU=
github.com/oracle/oci-go-sdk v24.3.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
github.com/ovh/go-ovh v1.1.0 h1:bHXZmw8nTgZin4Nv7JuaLs0KG5x54EQR7migYTd1zrk=
Expand Down Expand Up @@ -664,6 +667,7 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
Expand Down Expand Up @@ -738,6 +742,7 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
176 changes: 176 additions & 0 deletions providers/dns/civo/civo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
// Package civo implements a DNS provider for solving the DNS-01 challenge using CIVO.
package civo

import (
"errors"
"fmt"
"strings"
"time"

"github.com/civo/civogo"
"github.com/go-acme/lego/v4/challenge/dns01"
"github.com/go-acme/lego/v4/platform/config/env"
)

const (
minTTL = 600
defaultPollingInterval = 30 * time.Second
defaultPropagationTimeout = 300 * time.Second
)

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

EnvAPIToken = envNamespace + "TOKEN"

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

// Config is used to configure the creation of the DNSProvider.
type Config struct {
ProjectID string
Token string
PropagationTimeout time.Duration
PollingInterval time.Duration
TTL int
}

// NewDefaultConfig returns a default configuration for the DNSProvider.
func NewDefaultConfig() *Config {
return &Config{
TTL: env.GetOrDefaultInt(EnvTTL, minTTL),
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, defaultPropagationTimeout),
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, defaultPollingInterval),
}
}

// DNSProvider implements the challenge.Provider interface.
type DNSProvider struct {
config *Config
client *civogo.Client
}

// NewDNSProvider returns a DNSProvider instance configured for CIVO.
// Credentials must be passed in the environment variables: API_TOKEN.
func NewDNSProvider() (*DNSProvider, error) {
values, err := env.Get(EnvAPIToken)
if err != nil {
return nil, fmt.Errorf("civo: %w", err)
}

config := NewDefaultConfig()
config.Token = values[EnvAPIToken]

return NewDNSProviderConfig(config)
}

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

if config.Token == "" {
return nil, errors.New("civo: credentials missing")
}

if config.TTL < minTTL {
config.TTL = minTTL
}

// Create a Civo client - DNS is region independent, we can use any region
client, err := civogo.NewClient(config.Token, "LON1")
if err != nil {
return nil, fmt.Errorf("civo: %w", err)
}

return &DNSProvider{config: config, client: client}, nil
}

// Present creates a TXT record to fulfill the dns-01 challenge.
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
fqdn, value := dns01.GetRecord(domain, keyAuth)

zone, err := getZone(fqdn)
if err != nil {
return fmt.Errorf("civo: failed to find zone: fqdn=%s: %w", fqdn, err)
}

dnsDomain, err := d.client.GetDNSDomain(zone)
if err != nil {
return fmt.Errorf("civo: %w", err)
}

_, err = d.client.CreateDNSRecord(dnsDomain.ID, &civogo.DNSRecordConfig{
Name: extractRecordName(fqdn, zone),
Value: value,
Type: civogo.DNSRecordTypeTXT,
TTL: d.config.TTL,
})
if err != nil {
return fmt.Errorf("civo: %w", err)
}

return nil
}

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

zone, err := getZone(fqdn)
if err != nil {
return fmt.Errorf("civo: failed to find zone: fqdn=%s: %w", fqdn, err)
}

dnsDomain, err := d.client.GetDNSDomain(zone)
if err != nil {
return fmt.Errorf("civo: %w", err)
}

dnsRecords, err := d.client.ListDNSRecords(dnsDomain.ID)
if err != nil {
return fmt.Errorf("civo: %w", err)
}

var dnsRecord civogo.DNSRecord
for _, entry := range dnsRecords {
if entry.Name == extractRecordName(fqdn, zone) && entry.Value == value {
dnsRecord = entry
break
}
}

_, err = d.client.DeleteDNSRecord(&dnsRecord)
if err != nil {
return fmt.Errorf("civo: %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 getZone(fqdn string) (string, error) {
authZone, err := dns01.FindZoneByFqdn(fqdn)
if err != nil {
return "", err
}

return dns01.UnFqdn(authZone), nil
}

func extractRecordName(fqdn, zone string) string {
name := dns01.UnFqdn(fqdn)
if idx := strings.Index(name, "."+zone); idx != -1 {
return name[:idx]
}
return name
}
21 changes: 21 additions & 0 deletions providers/dns/civo/civo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Name = "Civo"
Description = ''''''
URL = "https://civo.com"
Code = "civo"
Since = "v4.9.0"

Example = '''
CIVO_TOKEN=xxxxxx \
lego --email you@example.com --dns civo --domains my.example.org run
'''

[Configuration]
[Configuration.Credentials]
CIVO_TOKEN = "Authentication token"
[Configuration.Additional]
CIVO_POLLING_INTERVAL = "Time between DNS propagation check"
CIVO_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation"
CIVO_TTL = "The TTL of the TXT record used for the DNS challenge"

[Links]
API = "https://www.civo.com/api/dns"
Loading

0 comments on commit 62a0d11

Please sign in to comment.