forked from TrueCloudLab/lego
transip: updated the client to v6 (#1104)
This commit is contained in:
parent
b58c9499ca
commit
b9f530e352
7 changed files with 218 additions and 152 deletions
|
@ -18,9 +18,13 @@ Configuration for [TransIP](https://www.transip.nl/).
|
||||||
|
|
||||||
- Code: `transip`
|
- Code: `transip`
|
||||||
|
|
||||||
{{% notice note %}}
|
Here is an example bash command using the TransIP provider:
|
||||||
_Please contribute by adding a CLI example._
|
|
||||||
{{% /notice %}}
|
```bash
|
||||||
|
TRANSIP_ACCOUNT_NAME = "Account name" \
|
||||||
|
TRANSIP_PRIVATE_KEY_PATH = "transip.key" \
|
||||||
|
lego --dns transip --domains my.domain.com --email my@email.com run
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,7 +56,7 @@ More information [here](/lego/dns/#configuration-and-credentials).
|
||||||
|
|
||||||
## More information
|
## More information
|
||||||
|
|
||||||
- [API documentation](https://api.transip.nl/docs/transip.nl/package-Transip.html)
|
- [API documentation](https://api.transip.eu/rest/docs.html)
|
||||||
- [Go client](https://github.com/transip/gotransip)
|
- [Go client](https://github.com/transip/gotransip)
|
||||||
|
|
||||||
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
|
<!-- THIS DOCUMENTATION IS AUTO-GENERATED. PLEASE DO NOT EDIT. -->
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -38,7 +38,7 @@ require (
|
||||||
github.com/sacloud/libsacloud v1.26.1
|
github.com/sacloud/libsacloud v1.26.1
|
||||||
github.com/stretchr/testify v1.5.1
|
github.com/stretchr/testify v1.5.1
|
||||||
github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7
|
github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7
|
||||||
github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f
|
github.com/transip/gotransip/v6 v6.0.2
|
||||||
github.com/urfave/cli v1.22.1
|
github.com/urfave/cli v1.22.1
|
||||||
github.com/vultr/govultr v0.1.4
|
github.com/vultr/govultr v0.1.4
|
||||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073
|
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -313,8 +313,8 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7 h1:CpHxIaZzVy26GqJn8ptRyto8fuoYOd1v0fXm9bG3wQ8=
|
github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7 h1:CpHxIaZzVy26GqJn8ptRyto8fuoYOd1v0fXm9bG3wQ8=
|
||||||
github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7/go.mod h1:imsgLplxEC/etjIhdr3dNzV3JeT27LbVu5pYWm0JCBY=
|
github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7/go.mod h1:imsgLplxEC/etjIhdr3dNzV3JeT27LbVu5pYWm0JCBY=
|
||||||
github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f h1:clyOmELPZd2LuFEyuo1mP6RXpbAW75PwD+RfDj4kBm0=
|
github.com/transip/gotransip/v6 v6.0.2 h1:rOCMY607PYF+YvMHHtJt7eZRd0mx/uhyz6dsXWPmn+4=
|
||||||
github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f/go.mod h1:i0f4R4o2HM0m3DZYQWsj6/MEowD57VzoH0v3d7igeFY=
|
github.com/transip/gotransip/v6 v6.0.2/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
|
||||||
github.com/uber-go/atomic v1.3.2 h1:Azu9lPBWRNKzYXSIwRfgRuDuS0YKsK4NFhiQv98gkxo=
|
github.com/uber-go/atomic v1.3.2 h1:Azu9lPBWRNKzYXSIwRfgRuDuS0YKsK4NFhiQv98gkxo=
|
||||||
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
|
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
|
||||||
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
|
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
|
||||||
|
@ -583,6 +583,8 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||||
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
|
123
providers/dns/transip/fakeclient_test.go
Normal file
123
providers/dns/transip/fakeclient_test.go
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
package transip
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/transip/gotransip/v6/domain"
|
||||||
|
"github.com/transip/gotransip/v6/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
type dnsEntryWrapper struct {
|
||||||
|
DNSEntry domain.DNSEntry `json:"dnsEntry"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type dnsEntriesWrapper struct {
|
||||||
|
DNSEntries []domain.DNSEntry `json:"dnsEntries"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type fakeClient struct {
|
||||||
|
dnsEntries []domain.DNSEntry
|
||||||
|
setDNSEntriesLatency time.Duration
|
||||||
|
getInfoLatency time.Duration
|
||||||
|
domainName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fakeClient) Get(request rest.Request, dest interface{}) error {
|
||||||
|
if f.getInfoLatency != 0 {
|
||||||
|
time.Sleep(f.getInfoLatency)
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.Endpoint != fmt.Sprintf("/domains/%s/dns", f.domainName) {
|
||||||
|
return fmt.Errorf("function GET for endpoint %s not implemented", request.Endpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
entries := dnsEntriesWrapper{DNSEntries: f.dnsEntries}
|
||||||
|
|
||||||
|
body, err := json.Marshal(entries)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("can't encode json: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(body, dest)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("can't decode json: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fakeClient) Put(request rest.Request) error {
|
||||||
|
if f.getInfoLatency != 0 {
|
||||||
|
time.Sleep(f.getInfoLatency)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("function PUT for endpoint %s not implemented", request.Endpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fakeClient) Post(request rest.Request) error {
|
||||||
|
if f.getInfoLatency != 0 {
|
||||||
|
time.Sleep(f.getInfoLatency)
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.Endpoint != fmt.Sprintf("/domains/%s/dns", f.domainName) {
|
||||||
|
return fmt.Errorf("function POST for endpoint %s not implemented", request.Endpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := request.GetJSONBody()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable get request body")
|
||||||
|
}
|
||||||
|
|
||||||
|
var entry dnsEntryWrapper
|
||||||
|
if err := json.Unmarshal(body, &entry); err != nil {
|
||||||
|
return fmt.Errorf("unable to decode request body")
|
||||||
|
}
|
||||||
|
|
||||||
|
f.dnsEntries = append(f.dnsEntries, entry.DNSEntry)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fakeClient) Delete(request rest.Request) error {
|
||||||
|
if f.getInfoLatency != 0 {
|
||||||
|
time.Sleep(f.getInfoLatency)
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.Endpoint != fmt.Sprintf("/domains/%s/dns", f.domainName) {
|
||||||
|
return fmt.Errorf("function DELETE for endpoint %s not implemented", request.Endpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := request.GetJSONBody()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable get request body")
|
||||||
|
}
|
||||||
|
|
||||||
|
var entry dnsEntryWrapper
|
||||||
|
if err := json.Unmarshal(body, &entry); err != nil {
|
||||||
|
return fmt.Errorf("unable to decode request body")
|
||||||
|
}
|
||||||
|
|
||||||
|
cp := make([]domain.DNSEntry, 0)
|
||||||
|
|
||||||
|
for _, e := range f.dnsEntries {
|
||||||
|
if e.Name == entry.DNSEntry.Name {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
cp = append(cp, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
f.dnsEntries = cp
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fakeClient) Patch(request rest.Request) error {
|
||||||
|
if f.getInfoLatency != 0 {
|
||||||
|
time.Sleep(f.getInfoLatency)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("function PATCH for endpoint %s not implemented", request.Endpoint)
|
||||||
|
}
|
|
@ -5,13 +5,12 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-acme/lego/v3/challenge/dns01"
|
"github.com/go-acme/lego/v3/challenge/dns01"
|
||||||
"github.com/go-acme/lego/v3/platform/config/env"
|
"github.com/go-acme/lego/v3/platform/config/env"
|
||||||
"github.com/transip/gotransip"
|
"github.com/transip/gotransip/v6"
|
||||||
transipdomain "github.com/transip/gotransip/domain"
|
transipdomain "github.com/transip/gotransip/v6/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Environment variables names.
|
// Environment variables names.
|
||||||
|
@ -47,8 +46,7 @@ func NewDefaultConfig() *Config {
|
||||||
// DNSProvider describes a provider for TransIP
|
// DNSProvider describes a provider for TransIP
|
||||||
type DNSProvider struct {
|
type DNSProvider struct {
|
||||||
config *Config
|
config *Config
|
||||||
client gotransip.Client
|
repository transipdomain.Repository
|
||||||
dnsEntriesMu sync.Mutex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDNSProvider returns a DNSProvider instance configured for TransIP.
|
// NewDNSProvider returns a DNSProvider instance configured for TransIP.
|
||||||
|
@ -73,7 +71,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
return nil, errors.New("transip: the configuration of the DNS provider is nil")
|
return nil, errors.New("transip: the configuration of the DNS provider is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := gotransip.NewSOAPClient(gotransip.ClientConfig{
|
client, err := gotransip.NewClient(gotransip.ClientConfiguration{
|
||||||
AccountName: config.AccountName,
|
AccountName: config.AccountName,
|
||||||
PrivateKeyPath: config.PrivateKeyPath,
|
PrivateKeyPath: config.PrivateKeyPath,
|
||||||
})
|
})
|
||||||
|
@ -81,7 +79,9 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
|
||||||
return nil, fmt.Errorf("transip: %w", err)
|
return nil, fmt.Errorf("transip: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &DNSProvider{client: client, config: config}, nil
|
repo := transipdomain.Repository{Client: client}
|
||||||
|
|
||||||
|
return &DNSProvider{repository: repo, config: config}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timeout returns the timeout and interval to use when checking for DNS propagation.
|
// Timeout returns the timeout and interval to use when checking for DNS propagation.
|
||||||
|
@ -104,35 +104,24 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
// get the subDomain
|
// get the subDomain
|
||||||
subDomain := strings.TrimSuffix(dns01.UnFqdn(fqdn), "."+domainName)
|
subDomain := strings.TrimSuffix(dns01.UnFqdn(fqdn), "."+domainName)
|
||||||
|
|
||||||
// use mutex to prevent race condition from GetInfo until SetDNSEntries
|
entry := transipdomain.DNSEntry{
|
||||||
d.dnsEntriesMu.Lock()
|
Name: subDomain,
|
||||||
defer d.dnsEntriesMu.Unlock()
|
Expire: int(d.config.TTL),
|
||||||
|
Type: "TXT",
|
||||||
// get all DNS entries
|
Content: value,
|
||||||
info, err := transipdomain.GetInfo(d.client, domainName)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("transip: error for %s in Present: %w", domain, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// include the new DNS entry
|
err = d.repository.AddDNSEntry(domainName, entry)
|
||||||
dnsEntries := append(info.DNSEntries, transipdomain.DNSEntry{
|
|
||||||
Name: subDomain,
|
|
||||||
TTL: d.config.TTL,
|
|
||||||
Type: transipdomain.DNSEntryTypeTXT,
|
|
||||||
Content: value,
|
|
||||||
})
|
|
||||||
|
|
||||||
// set the updated DNS entries
|
|
||||||
err = transipdomain.SetDNSEntries(d.client, domainName, dnsEntries)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("transip: %w", err)
|
return fmt.Errorf("transip: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CleanUp removes the TXT record matching the specified parameters
|
// CleanUp removes the TXT record matching the specified parameters
|
||||||
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
fqdn, _ := dns01.GetRecord(domain, keyAuth)
|
fqdn, value := dns01.GetRecord(domain, keyAuth)
|
||||||
|
|
||||||
authZone, err := dns01.FindZoneByFqdn(fqdn)
|
authZone, err := dns01.FindZoneByFqdn(fqdn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -144,29 +133,21 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
|
||||||
// get the subDomain
|
// get the subDomain
|
||||||
subDomain := strings.TrimSuffix(dns01.UnFqdn(fqdn), "."+domainName)
|
subDomain := strings.TrimSuffix(dns01.UnFqdn(fqdn), "."+domainName)
|
||||||
|
|
||||||
// use mutex to prevent race condition from GetInfo until SetDNSEntries
|
|
||||||
d.dnsEntriesMu.Lock()
|
|
||||||
defer d.dnsEntriesMu.Unlock()
|
|
||||||
|
|
||||||
// get all DNS entries
|
// get all DNS entries
|
||||||
info, err := transipdomain.GetInfo(d.client, domainName)
|
dnsEntries, err := d.repository.GetDNSEntries(domainName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("transip: error for %s in CleanUp: %w", fqdn, err)
|
return fmt.Errorf("transip: error for %s in CleanUp: %w", fqdn, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop through the existing entries and remove the specific record
|
// loop through the existing entries and remove the specific record
|
||||||
updatedEntries := info.DNSEntries[:0]
|
for _, entry := range dnsEntries {
|
||||||
for _, e := range info.DNSEntries {
|
if entry.Name == subDomain && entry.Content == value {
|
||||||
if e.Name != subDomain {
|
if err = d.repository.RemoveDNSEntry(domainName, entry); err != nil {
|
||||||
updatedEntries = append(updatedEntries, e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the updated DNS entries
|
|
||||||
err = transipdomain.SetDNSEntries(d.client, domainName, updatedEntries)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("transip: couldn't get Record ID in CleanUp: %w", err)
|
return fmt.Errorf("transip: couldn't get Record ID in CleanUp: %w", err)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,11 @@ URL = "https://www.transip.nl/"
|
||||||
Code = "transip"
|
Code = "transip"
|
||||||
Since = "v2.0.0"
|
Since = "v2.0.0"
|
||||||
|
|
||||||
Example = ''''''
|
Example = '''
|
||||||
|
TRANSIP_ACCOUNT_NAME = "Account name" \
|
||||||
|
TRANSIP_PRIVATE_KEY_PATH = "transip.key" \
|
||||||
|
lego --dns transip --domains my.domain.com --email my@email.com run
|
||||||
|
'''
|
||||||
|
|
||||||
[Configuration]
|
[Configuration]
|
||||||
[Configuration.Credentials]
|
[Configuration.Credentials]
|
||||||
|
@ -16,6 +20,6 @@ Example = ''''''
|
||||||
TRANSIP_TTL = "The TTL of the TXT record used for the DNS challenge"
|
TRANSIP_TTL = "The TTL of the TXT record used for the DNS challenge"
|
||||||
|
|
||||||
[Links]
|
[Links]
|
||||||
API = "https://api.transip.nl/docs/transip.nl/package-Transip.html"
|
API = "https://api.transip.eu/rest/docs.html"
|
||||||
GoClient = "https://github.com/transip/gotransip"
|
GoClient = "https://github.com/transip/gotransip"
|
||||||
|
|
||||||
|
|
|
@ -1,82 +1,20 @@
|
||||||
package transip
|
package transip
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-acme/lego/v3/log"
|
|
||||||
"github.com/go-acme/lego/v3/platform/tester"
|
"github.com/go-acme/lego/v3/platform/tester"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/transip/gotransip"
|
"github.com/transip/gotransip/v6/domain"
|
||||||
"github.com/transip/gotransip/domain"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type argDNSEntries struct {
|
|
||||||
Items domain.DNSEntries `xml:"item"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type argDomainName struct {
|
|
||||||
DomainName string `xml:",chardata"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type fakeClient struct {
|
|
||||||
dnsEntries []domain.DNSEntry
|
|
||||||
setDNSEntriesLatency time.Duration
|
|
||||||
getInfoLatency time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeClient) Call(r gotransip.SoapRequest, b interface{}) error {
|
|
||||||
switch r.Method {
|
|
||||||
case "getInfo":
|
|
||||||
d := b.(*domain.Domain)
|
|
||||||
cp := f.dnsEntries
|
|
||||||
|
|
||||||
if f.getInfoLatency != 0 {
|
|
||||||
time.Sleep(f.getInfoLatency)
|
|
||||||
}
|
|
||||||
d.DNSEntries = cp
|
|
||||||
|
|
||||||
log.Printf("getInfo: %+v\n", d.DNSEntries)
|
|
||||||
return nil
|
|
||||||
case "setDnsEntries":
|
|
||||||
var domainName argDomainName
|
|
||||||
var dnsEntries argDNSEntries
|
|
||||||
|
|
||||||
args := readArgs(r)
|
|
||||||
for _, arg := range args {
|
|
||||||
if strings.HasPrefix(arg, "<domainName") {
|
|
||||||
err := xml.Unmarshal([]byte(arg), &domainName)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
} else if strings.HasPrefix(arg, "<dnsEntries") {
|
|
||||||
err := xml.Unmarshal([]byte(arg), &dnsEntries)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("setDnsEntries domainName: %+v\n", domainName)
|
|
||||||
log.Printf("setDnsEntries dnsEntries: %+v\n", dnsEntries)
|
|
||||||
|
|
||||||
if f.setDNSEntriesLatency != 0 {
|
|
||||||
time.Sleep(f.setDNSEntriesLatency)
|
|
||||||
}
|
|
||||||
|
|
||||||
f.dnsEntries = dnsEntries.Items
|
|
||||||
return nil
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const envDomain = envNamespace + "DOMAIN"
|
const envDomain = envNamespace + "DOMAIN"
|
||||||
|
|
||||||
var envTest = tester.NewEnvTest(
|
var envTest = tester.NewEnvTest(
|
||||||
|
@ -121,14 +59,6 @@ func TestNewDNSProvider(t *testing.T) {
|
||||||
},
|
},
|
||||||
expected: "transip: some credentials information are missing: TRANSIP_PRIVATE_KEY_PATH",
|
expected: "transip: some credentials information are missing: TRANSIP_PRIVATE_KEY_PATH",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
desc: "could not open private key path",
|
|
||||||
envVars: map[string]string{
|
|
||||||
EnvAccountName: "johndoe",
|
|
||||||
EnvPrivateKeyPath: "./fixtures/non/existent/private.key",
|
|
||||||
},
|
|
||||||
expected: "transip: could not open private key: stat ./fixtures/non/existent/private.key: no such file or directory",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
|
@ -144,12 +74,29 @@ func TestNewDNSProvider(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, p)
|
require.NotNil(t, p)
|
||||||
require.NotNil(t, p.config)
|
require.NotNil(t, p.config)
|
||||||
require.NotNil(t, p.client)
|
require.NotNil(t, p.repository)
|
||||||
} else {
|
} else {
|
||||||
require.EqualError(t, err, test.expected)
|
require.EqualError(t, err, test.expected)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The error message for a file not existing is different on Windows and Linux.
|
||||||
|
// Therefore we test if the error type is the same.
|
||||||
|
t.Run("could not open private key path", func(t *testing.T) {
|
||||||
|
defer envTest.RestoreEnv()
|
||||||
|
envTest.ClearEnv()
|
||||||
|
|
||||||
|
envTest.Apply(map[string]string{
|
||||||
|
EnvAccountName: "johndoe",
|
||||||
|
EnvPrivateKeyPath: "./fixtures/non/existent/private.key",
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := NewDNSProvider()
|
||||||
|
if !errors.Is(err, os.ErrNotExist) {
|
||||||
|
t.Fatalf("Expected an os.ErrNotExists error, actual: %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSProviderConfig(t *testing.T) {
|
func TestNewDNSProviderConfig(t *testing.T) {
|
||||||
|
@ -176,13 +123,7 @@ func TestNewDNSProviderConfig(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "missing private key path",
|
desc: "missing private key path",
|
||||||
accountName: "johndoe",
|
accountName: "johndoe",
|
||||||
expected: "transip: PrivateKeyPath or PrivateKeyBody is required",
|
expected: "transip: PrivateKeyReader, token or PrivateKeyReader is required",
|
||||||
},
|
|
||||||
{
|
|
||||||
desc: "could not open private key path",
|
|
||||||
accountName: "johndoe",
|
|
||||||
privateKeyPath: "./fixtures/non/existent/private.key",
|
|
||||||
expected: "transip: could not open private key: stat ./fixtures/non/existent/private.key: no such file or directory",
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,23 +139,40 @@ func TestNewDNSProviderConfig(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, p)
|
require.NotNil(t, p)
|
||||||
require.NotNil(t, p.config)
|
require.NotNil(t, p.config)
|
||||||
require.NotNil(t, p.client)
|
require.NotNil(t, p.repository)
|
||||||
} else {
|
} else {
|
||||||
require.EqualError(t, err, test.expected)
|
require.EqualError(t, err, test.expected)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The error message for a file not existing is different on Windows and Linux.
|
||||||
|
// Therefore we test if the error type is the same.
|
||||||
|
t.Run("could not open private key path", func(t *testing.T) {
|
||||||
|
config := NewDefaultConfig()
|
||||||
|
config.AccountName = "johndoe"
|
||||||
|
config.PrivateKeyPath = "./fixtures/non/existent/private.key"
|
||||||
|
|
||||||
|
_, err := NewDNSProviderConfig(config)
|
||||||
|
|
||||||
|
if !errors.Is(err, os.ErrNotExist) {
|
||||||
|
t.Fatalf("Expected an os.ErrNotExists error, actual: %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDNSProvider_concurrentGetInfo(t *testing.T) {
|
func TestDNSProvider_concurrentGetDNSEntries(t *testing.T) {
|
||||||
client := &fakeClient{
|
client := &fakeClient{
|
||||||
getInfoLatency: 50 * time.Millisecond,
|
getInfoLatency: 50 * time.Millisecond,
|
||||||
setDNSEntriesLatency: 500 * time.Millisecond,
|
setDNSEntriesLatency: 500 * time.Millisecond,
|
||||||
|
domainName: "lego.wtf",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repo := domain.Repository{Client: client}
|
||||||
|
|
||||||
p := &DNSProvider{
|
p := &DNSProvider{
|
||||||
config: NewDefaultConfig(),
|
config: NewDefaultConfig(),
|
||||||
client: client,
|
repository: repo,
|
||||||
}
|
}
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
@ -222,12 +180,14 @@ func TestDNSProvider_concurrentGetInfo(t *testing.T) {
|
||||||
|
|
||||||
solve := func(domain1 string, suffix string, timeoutPresent time.Duration, timeoutSolve time.Duration, timeoutCleanup time.Duration) error {
|
solve := func(domain1 string, suffix string, timeoutPresent time.Duration, timeoutSolve time.Duration, timeoutCleanup time.Duration) error {
|
||||||
time.Sleep(timeoutPresent)
|
time.Sleep(timeoutPresent)
|
||||||
|
|
||||||
err := p.Present(domain1, "", "")
|
err := p.Present(domain1, "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(timeoutSolve)
|
time.Sleep(timeoutSolve)
|
||||||
|
|
||||||
var found bool
|
var found bool
|
||||||
for _, entry := range client.dnsEntries {
|
for _, entry := range client.dnsEntries {
|
||||||
if strings.HasSuffix(entry.Name, suffix) {
|
if strings.HasSuffix(entry.Name, suffix) {
|
||||||
|
@ -239,6 +199,7 @@ func TestDNSProvider_concurrentGetInfo(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(timeoutCleanup)
|
time.Sleep(timeoutCleanup)
|
||||||
|
|
||||||
return p.CleanUp(domain1, "", "")
|
return p.CleanUp(domain1, "", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,12 +220,15 @@ func TestDNSProvider_concurrentGetInfo(t *testing.T) {
|
||||||
assert.Empty(t, client.dnsEntries)
|
assert.Empty(t, client.dnsEntries)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDNSProvider_concurrentSetDNSEntries(t *testing.T) {
|
func TestDNSProvider_concurrentAddDNSEntry(t *testing.T) {
|
||||||
client := &fakeClient{}
|
client := &fakeClient{
|
||||||
|
domainName: "lego.wtf",
|
||||||
|
}
|
||||||
|
repo := domain.Repository{Client: client}
|
||||||
|
|
||||||
p := &DNSProvider{
|
p := &DNSProvider{
|
||||||
config: NewDefaultConfig(),
|
config: NewDefaultConfig(),
|
||||||
client: client,
|
repository: repo,
|
||||||
}
|
}
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
@ -298,18 +262,6 @@ func TestDNSProvider_concurrentSetDNSEntries(t *testing.T) {
|
||||||
assert.Empty(t, client.dnsEntries)
|
assert.Empty(t, client.dnsEntries)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readArgs(req gotransip.SoapRequest) []string {
|
|
||||||
v := reflect.ValueOf(req)
|
|
||||||
f := v.FieldByName("args")
|
|
||||||
|
|
||||||
var args []string
|
|
||||||
for i := 0; i < f.Len(); i++ {
|
|
||||||
args = append(args, f.Slice(0, f.Len()).Index(i).String())
|
|
||||||
}
|
|
||||||
|
|
||||||
return args
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLivePresent(t *testing.T) {
|
func TestLivePresent(t *testing.T) {
|
||||||
if !envTest.IsLiveTest() {
|
if !envTest.IsLiveTest() {
|
||||||
t.Skip("skipping live test")
|
t.Skip("skipping live test")
|
||||||
|
|
Loading…
Reference in a new issue