Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for autodns #957

Merged
merged 38 commits into from
Nov 1, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4b694ec
Started adding autodns support
Aug 30, 2019
7c8d591
Autodns support roughly working
Aug 30, 2019
1b8f676
Fixed clearing all records when adding/removing the challenge record
Aug 30, 2019
beedce7
Started adding tests
Aug 30, 2019
570fc61
Added more tests
Aug 30, 2019
83c3955
Implemented adding/removing of records using the stream api
Aug 30, 2019
f209a5f
Fixed lint
Aug 30, 2019
3d32893
Fixed lint
Aug 30, 2019
58b82de
Updated readme
Sep 2, 2019
38177e5
Updated tests
Sep 2, 2019
e126098
Added more config variables
Sep 2, 2019
b3d3840
make generate
Sep 2, 2019
ba90111
Fixed lint
Sep 2, 2019
fd8b474
Tidy go mod
Sep 2, 2019
91dbe58
Merge branch 'master' into feature/autodns
kolaente Sep 2, 2019
4492220
Added timeouts
Sep 3, 2019
c8d9af3
Added example
Sep 3, 2019
388d597
Moved more stuff to default config
Sep 3, 2019
b0058c4
Added http timeout setting
Sep 3, 2019
e2ece28
Moved getting new dns provider config to own function
Sep 3, 2019
5047429
Fixed tests
Sep 3, 2019
e44adc5
Added more tests
Sep 3, 2019
1e23110
Added more checks
Sep 6, 2019
a24ee75
Merge branch 'master' into feature/autodns
kolaente Sep 18, 2019
bb23549
Merge branch 'master' into feature/autodns
kolaente Sep 19, 2019
5fcf189
Merge branch 'master' into feature/autodns
kolaente Sep 23, 2019
a1904c7
Merge branch 'master' into feature/autodns
kolaente Oct 7, 2019
0a3a026
Merge branch 'master' into feature/autodns
kolaente Oct 9, 2019
e4060f7
Merge branch 'master' into feature/autodns
kolaente Oct 22, 2019
e1010a6
Merge branch 'master' into feature/autodns
kolaente Oct 25, 2019
3935ea4
Pass the value when deleting a challenge record
Oct 25, 2019
5c66aec
Fixed lint
Oct 25, 2019
dc91e3f
review quick review.
ldez Oct 30, 2019
77ebb41
Merge branch 'master' into feature/autodns
kolaente Oct 30, 2019
73276e5
review: add documentation.
ldez Oct 30, 2019
6653372
review: homogeneous unit tests with the other providers.
ldez Oct 30, 2019
9f5c102
Merge pull request #1 from ldez/review/957
kolaente Oct 31, 2019
d792fdc
Fixed lint
Nov 1, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 17 additions & 0 deletions cmd/zz_gen_cmd_dnshelp.go
Expand Up @@ -17,6 +17,7 @@ func allDNSCodes() string {
"acme-dns",
"alidns",
"auroradns",
"autodns",
"azure",
"bindman",
"bluecat",
Expand Down Expand Up @@ -142,6 +143,22 @@ func displayDNSHelp(name string) error {
ew.writeln()
ew.writeln(`More information: https://go-acme.github.io/lego/dns/auroradns`)

case "autodns":
// generated from: providers/dns/autodns/autodns.toml
ew.writeln(`Configuration for Autodns.`)
ew.writeln(`Code: 'autodns'`)
ew.writeln(`Since: 'v3.1.0'`)
ew.writeln()

ew.writeln(`Credentials:`)
ew.writeln(` - "AUTODNS_API_PASSWORD": User Password`)
ew.writeln(` - "AUTODNS_API_USER": User ID`)
ew.writeln(` - "AUTODNS_ENDPOINT": API endpoint URL`)
ew.writeln()

ew.writeln()
ew.writeln(`More information: https://go-acme.github.io/lego/dns/autodns`)
kolaente marked this conversation as resolved.
Show resolved Hide resolved

case "azure":
// generated from: providers/dns/azure/azure.toml
ew.writeln(`Configuration for Azure.`)
Expand Down
1 change: 1 addition & 0 deletions go.sum
Expand Up @@ -78,6 +78,7 @@ github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-acme/lego v2.7.2+incompatible h1:ThhpPBgf6oa9X/vRd0kEmWOsX7+vmYdckmGZSb+FEp0=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-ini/ini v1.44.0 h1:8+SRbfpRFlIunpSum4BEf1ClTtVjOgKzgBv9pHFkI6w=
Expand Down
106 changes: 106 additions & 0 deletions providers/dns/autodns/autodns.go
@@ -0,0 +1,106 @@
package autodns

import (
"fmt"
"net/http"
"net/url"

"github.com/go-acme/lego/v3/challenge/dns01"
"github.com/go-acme/lego/v3/platform/config/env"
)

const (
envAPIUser = `AUTODNS_API_USER`
envAPIPassword = `AUTODNS_API_PASSWORD`
envAPIEndpoint = `AUTODNS_ENDPOINT`

defaultEndpoint = `https://api.autodns.com/v1/`
demoEndpoint = `https://api.demo.autodns.com/v1/`

defaultEndpointContext int = 4
)

type Config struct {
Endpoint *url.URL
Username string `json:"username"`
Password string `json:"password"`
Context int `json:"-"`
HTTPClient *http.Client
}

func NewDefaultConfig() *Config {
endpoint, _ := url.Parse(defaultEndpoint)

return &Config{
Endpoint: endpoint,
Context: defaultEndpointContext,
HTTPClient: &http.Client{},
kolaente marked this conversation as resolved.
Show resolved Hide resolved
}
}

type DNSProvider struct {
config *Config
//zoneNameservers map[string]string
//currentRecords []*ResourceRecord
}

func NewDNSProvider() (*DNSProvider, error) {
values, err := env.Get(envAPIUser, envAPIPassword)
if err != nil {
return nil, fmt.Errorf("autodns: %v", err)
}

rawEndpoint := env.GetOrDefaultString(envAPIEndpoint, defaultEndpoint)
endpoint, err := url.Parse(rawEndpoint)
if err != nil {
return nil, fmt.Errorf("autodns: %v", err)
}

config := NewDefaultConfig()
config.Username = values[envAPIUser]
config.Password = values[envAPIPassword]
config.Endpoint = endpoint

provider := &DNSProvider{config: config}

// Because autodns needs the nameservers for each request, we query them all here and put them
kolaente marked this conversation as resolved.
Show resolved Hide resolved
// in our state to avoid making a lot of requests later.
// FIXME: This should become obsolete once I figure out how the _stream endpoint works.
kolaente marked this conversation as resolved.
Show resolved Hide resolved
/*req, err := provider.makeRequest(http.MethodPost, path.Join("zone", "_search"), nil)
if err != nil {
return nil, fmt.Errorf("autodns: %v", err)
}

var resp *DataZoneResponse
if err := provider.sendRequest(req, &resp); err != nil {
return nil, fmt.Errorf("autodns: %v", err)
}

provider.zoneNameservers = make(map[string]string, len(resp.Data))

for _, zone := range resp.Data {
provider.zoneNameservers[zone.Name] = zone.VirtualNameServer
}*/

return provider, nil
}

// Present creates a TXT record to fulfill the dns-01 challenge
func (d *DNSProvider) Present(domain, token, keyAuth string) (err error) {

fqdn, value := dns01.GetRecord(domain, keyAuth)
_, err = d.addTxtRecord(domain, fqdn, value)
if err != nil {
return fmt.Errorf("autodns: %v", err)
}
return nil
}

// CleanUp removes the TXT record previously created
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
if err := d.removeTXTRecord(domain, "_acme-challenge"); err != nil {
return fmt.Errorf("autodns: removeTXTRecord: %v", err)
}

return nil
}
16 changes: 16 additions & 0 deletions providers/dns/autodns/autodns.toml
@@ -0,0 +1,16 @@
Name = "Autodns"
Description = ''''''
URL = "https://www.internetx.com/domains/autodns/"
Code = "autodns"
Since = "v3.1.0"

Example = ''''''
kolaente marked this conversation as resolved.
Show resolved Hide resolved

[Configuration]
[Configuration.Credentials]
AUTODNS_API_USER = "User ID"
AUTODNS_API_PASSWORD = "User Password"
AUTODNS_ENDPOINT = "API endpoint URL"

[Links]
API = "https://help.internetx.com/display/APIJSONEN"
101 changes: 101 additions & 0 deletions providers/dns/autodns/autodns_test.go
@@ -0,0 +1,101 @@
package autodns

import (
"net/http"
"net/url"
"reflect"
"testing"

"github.com/go-acme/lego/v3/platform/tester"
"github.com/stretchr/testify/assert"
)

var envTest = tester.NewEnvTest(envAPIEndpoint, envAPIUser, envAPIPassword)

func TestNewDNSProvider(t *testing.T) {
defaultEndpointURL, _ := url.Parse(defaultEndpoint)
examplEndpointURL, _ := url.Parse(demoEndpoint)

tests := []struct {
name string
want *DNSProvider
wantErr bool
env map[string]string
}{
{
name: "complete, no errors",
want: &DNSProvider{
config: &Config{
Endpoint: defaultEndpointURL,
Username: "test",
Password: "1234",
Context: defaultEndpointContext,
HTTPClient: &http.Client{},
},
},
env: map[string]string{
envAPIUser: "test",
envAPIPassword: "1234",
},
},
{
name: "different endpoint url",
want: &DNSProvider{
config: &Config{
Endpoint: examplEndpointURL,
Username: "test",
Password: "1234",
Context: defaultEndpointContext,
HTTPClient: &http.Client{},
},
},
env: map[string]string{
envAPIUser: "test",
envAPIPassword: "1234",
envAPIEndpoint: demoEndpoint,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer envTest.RestoreEnv()
envTest.ClearEnv()
envTest.Apply(tt.env)

got, err := NewDNSProvider()
if (err != nil) != tt.wantErr {
t.Errorf("NewDNSProvider() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewDNSProvider() got = %v, want %v", got, tt.want)
}
})
}
}

func TestDNSProvider_Present(t *testing.T) {
if !envTest.IsLiveTest() {
t.Skip("skipping live test")
}

envTest.RestoreEnv()
provider, err := NewDNSProvider()
assert.NoError(t, err)

err = provider.Present(envTest.GetDomain(), "", "123d==")
assert.NoError(t, err)
}

func TestDNSProvider_CleanUp(t *testing.T) {
if !envTest.IsLiveTest() {
t.Skip("skipping live test")
}

envTest.RestoreEnv()
provider, err := NewDNSProvider()
assert.NoError(t, err)

err = provider.CleanUp(envTest.GetDomain(), "", "123d==")
assert.NoError(t, err)
}