diff --git a/providers/dns/transip/transip.go b/providers/dns/transip/transip.go index 062fc91a..ee88af28 100644 --- a/providers/dns/transip/transip.go +++ b/providers/dns/transip/transip.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "strings" + "sync" "time" "github.com/transip/gotransip" @@ -33,8 +34,9 @@ func NewDefaultConfig() *Config { // DNSProvider describes a provider for TransIP type DNSProvider struct { - config *Config - client gotransip.SOAPClient + config *Config + client gotransip.Client + dnsEntriesMu sync.Mutex } // NewDNSProvider returns a DNSProvider instance configured for TransIP. @@ -90,6 +92,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { // get the subDomain 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 info, err := transipdomain.GetInfo(d.client, domainName) if err != nil { @@ -126,6 +132,10 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { // get the subDomain 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 info, err := transipdomain.GetInfo(d.client, domainName) if err != nil { diff --git a/providers/dns/transip/transip_test.go b/providers/dns/transip/transip_test.go index 35c622ca..464b9424 100644 --- a/providers/dns/transip/transip_test.go +++ b/providers/dns/transip/transip_test.go @@ -1,13 +1,82 @@ package transip import ( + "encoding/xml" + "fmt" + "reflect" + "strings" + "sync" "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/transip/gotransip" + "github.com/transip/gotransip/domain" + "github.com/xenolf/lego/log" "github.com/xenolf/lego/platform/tester" ) +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, "