mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-12-09 13:46:07 +08:00
INWX: Fix INWX provider after their unexpected data-type breaking-change (#3855)
Fixes #3854 Unfortunately I couldn't run the integrationTests properly as INWX doesn't seem to have properly updated their sandbox environment (it still presents `int` instead of `string` like production). Hence, the tests do fail. I don't want to run this against my own production account, to be frank. See: ```shell $ curl -X POST https://api.ote.domrobot.com/xmlrpc/ -H "Content-Type: application/xml" -d '<?xml version="1.0" encoding="UTF-8"?> <methodCall> <methodName>nameserver.info</methodName> <params> <param> <value> <struct> <member> <name>user</name> <value> <string>[USER]</string> </value> </member> <member> <name>lang</name> <value> <string>en</string> </value> </member> <member> <name>pass</name> <value> <string>[PASS]</string> </value> </member> <member> <name>domain</name> <value> <string>[DOMAIN]</string> </value> </member> </struct> </value> </param> </params> </methodCall>' | xmllint --format - | grep -iE "id|roId" -C3 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 3968 0 2971 100 997 13375 4488 --:--:-- --:--:-- --:--:-- 17954 <value> <struct> <member> <name>roId</name> <value> <int>9677</int> </value> -- <value> <struct> <member> <name>id</name> <value> <int>118057</int> </value> -- <value> <struct> <member> <name>id</name> <value> <int>118060</int> </value> -- <value> <struct> <member> <name>id</name> <value> <int>79610</int> </value> -- <value> <struct> <member> <name>id</name> <value> <int>77243</int> </value> -- </value> </member> <member> <name>svTRID</name> <value> <string>20251127--ote</string> </value> ``` Hence, only done manualy tests via `dnscontrol push --domains <example.com>`: (tested create, delete and modify) ```text CONCURRENTLY checking for 0 zone(s) SERIALLY checking for 1 zone(s) Serially checking for zone: "example.tld" CONCURRENTLY gathering records of 0 zone(s) SERIALLY gathering records of 1 zone(s) Serially Gathering: "example.tld" ******************** Domain: example.tld 3 corrections (PK-INWX) #1: - DELETE _test1.example.tld TXT "123" ttl=43200 SUCCESS! #2: ± MODIFY _test2.example.tld TXT ("1234" ttl=43200) -> ("12345" ttl=43200) SUCCESS! #3: + CREATE _test4.example.tld TXT "123" ttl=43200 SUCCESS! Done. 3 corrections. ```
This commit is contained in:
parent
f306472d5a
commit
9aad2926fb
6 changed files with 28 additions and 34 deletions
2
go.mod
2
go.mod
|
|
@ -38,7 +38,7 @@ require (
|
|||
github.com/miekg/dns v1.1.68
|
||||
github.com/mittwald/go-powerdns v0.6.7
|
||||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04
|
||||
github.com/nrdcg/goinwx v0.11.0
|
||||
github.com/nrdcg/goinwx v0.12.0
|
||||
github.com/ovh/go-ovh v1.9.0
|
||||
github.com/philhug/opensrs-go v0.0.0-20171126225031-9dfa7433020d
|
||||
github.com/pkg/errors v0.9.1
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -307,8 +307,8 @@ github.com/nicholas-fedor/shoutrrr v0.12.0 h1:8mwJdfU+uBEybSymwQJMGl/grG7lvVUKbV
|
|||
github.com/nicholas-fedor/shoutrrr v0.12.0/go.mod h1:WYiRalR4C43Qmd2zhPWGIFIxu633NB1hDM6Ap/DQcsA=
|
||||
github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 h1:Up6+btDp321ZG5/zdSLo48H9Iaq0UQGthrhWC6pCxzE=
|
||||
github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481/go.mod h1:yKZQO8QE2bHlgozqWDiRVqTFlLQSj30K/6SAK8EeYFw=
|
||||
github.com/nrdcg/goinwx v0.11.0 h1:GER0SE3POub7rxARt3Y3jRy1OON1hwF1LRxHz5xsFBw=
|
||||
github.com/nrdcg/goinwx v0.11.0/go.mod h1:0BXSC0FxVtU4aTjX0Zw3x0DK32tjugLzeNIAGtwXvPQ=
|
||||
github.com/nrdcg/goinwx v0.12.0 h1:ujdUqDBnaRSFwzVnImvPHYw3w3m9XgmGImNUw1GyMb4=
|
||||
github.com/nrdcg/goinwx v0.12.0/go.mod h1:IrVKd3ZDbFiMjdPgML4CSxZAY9wOoqLvH44zv3NodJ0=
|
||||
github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=
|
||||
github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
|
||||
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ func CorrectZoneRecords(driver models.DNSProvider, dc *models.DomainConfig) ([]*
|
|||
models.CanonicalizeTargets(existingRecords, dc.Name)
|
||||
models.CanonicalizeTargets(dc.Records, dc.Name)
|
||||
|
||||
// Copy dc so that any corrections code that wants to
|
||||
// Copy dc so that any correction code that wants to
|
||||
// modify the records may. For example, if the provider only
|
||||
// supports certain TTL values, it will adjust the ones in
|
||||
// dc.Records.
|
||||
|
|
|
|||
|
|
@ -10,12 +10,8 @@ import (
|
|||
// supported, an empty list is returned.
|
||||
func AuditRecords(records []*models.RecordConfig) []error {
|
||||
a := rejectif.Auditor{}
|
||||
|
||||
a.Add("TXT", rejectif.TxtHasBackticks) // Last verified 2021-03-01
|
||||
|
||||
a.Add("TXT", rejectif.TxtHasTrailingSpace) // Last verified 2021-03-01
|
||||
|
||||
a.Add("TXT", rejectif.TxtIsEmpty) // Last verified 2021-03-01
|
||||
|
||||
return a.Audit(records)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,25 +10,22 @@ const (
|
|||
// testing shows 'AUTO' is what to expect if the domain has automatic
|
||||
// DNSSEC enabled.
|
||||
|
||||
// AutoDNSSEC is the status for DNSSEC enabled with automatic management
|
||||
// AutoDNSSECStatus is the status for DNSSEC enabled with automatic management
|
||||
AutoDNSSECStatus = "AUTO"
|
||||
// ManualDNSSEC is the status for DNSSEC enabled with manual management
|
||||
// ManualDNSSECStatus is the status for DNSSEC enabled with manual management
|
||||
ManualDNSSECStatus = "MANUAL"
|
||||
)
|
||||
|
||||
// DNSSecStatus returns domain dnssec status
|
||||
func (api *inwxAPI) DNSSecStatus(domain string) (string, error) {
|
||||
|
||||
resp, err := api.client.Dnssec.Info([]string{domain})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// domain has no DNSSEC configuration
|
||||
if len(resp.Data) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return resp.Data[0].DNSSecStatus, nil
|
||||
}
|
||||
|
||||
|
|
@ -40,16 +37,12 @@ func (api *inwxAPI) enableAutoDNSSEC(domain string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = api.client.Dnssec.Enable(domain)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// disableAutoDNSSEC disables automatic management of DNSSEC
|
||||
func (api *inwxAPI) disableAutoDNSSEC(domain string) error {
|
||||
|
||||
err := api.client.Dnssec.Disable(domain)
|
||||
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ import (
|
|||
/*
|
||||
INWX Registrar and DNS provider
|
||||
|
||||
Based on this great INWX API implementation:
|
||||
https://github.com/nrdcg/goinwx
|
||||
|
||||
Info required in `creds.json`:
|
||||
- username
|
||||
- password
|
||||
|
|
@ -34,7 +37,6 @@ Either of the following settings is required when two factor authentication is e
|
|||
|
||||
Additional settings available in `creds.json`:
|
||||
- sandbox (set to 1 to use the sandbox API from INWX)
|
||||
|
||||
*/
|
||||
|
||||
// InwxProductionDefaultNs contains the default INWX nameservers.
|
||||
|
|
@ -182,10 +184,10 @@ func makeNameserverRecordRequest(domain string, rec *models.RecordConfig) *goinw
|
|||
|
||||
switch rType := rec.Type; rType {
|
||||
/*
|
||||
INWX is a little bit special for CNAME,NS,MX and SRV records:
|
||||
INWX is a little bit special for CNAME, NS, MX and SRV records:
|
||||
The API will not accept any target with a final dot but will
|
||||
instead always add this final dot internally.
|
||||
Records with empty targets (i.e. records with target ".")
|
||||
Records with empty targets (i.e., records with target ".")
|
||||
are allowed.
|
||||
*/
|
||||
case "CNAME", "NS", "ALIAS":
|
||||
|
|
@ -219,14 +221,14 @@ func (api *inwxAPI) createRecord(domain string, rec *models.RecordConfig) error
|
|||
}
|
||||
|
||||
// updateRecord is used by GetDomainCorrections to update an existing record.
|
||||
func (api *inwxAPI) updateRecord(RecordID int, rec *models.RecordConfig) error {
|
||||
func (api *inwxAPI) updateRecord(RecordID string, rec *models.RecordConfig) error {
|
||||
req := makeNameserverRecordRequest("", rec)
|
||||
err := api.client.Nameservers.UpdateRecord(RecordID, req)
|
||||
return err
|
||||
}
|
||||
|
||||
// deleteRecord is used by GetDomainCorrections to delete a record.
|
||||
func (api *inwxAPI) deleteRecord(RecordID int) error {
|
||||
func (api *inwxAPI) deleteRecord(RecordID string) error {
|
||||
return api.client.Nameservers.DeleteRecord(RecordID)
|
||||
}
|
||||
|
||||
|
|
@ -244,7 +246,8 @@ func (api *inwxAPI) AutoDnssecToggle(dc *models.DomainConfig, corrections []*mod
|
|||
}
|
||||
|
||||
if dnssecStatus == ManualDNSSECStatus && dc.AutoDNSSEC != "" {
|
||||
return corrections, fmt.Errorf("INWX: Domain %s has manual DNSSEC enabled. Disable it before using AUTODNSSEC_ON/AUTODNSSEC_OFF", dc.Name)
|
||||
return corrections, fmt.Errorf("INWX: Domain %s has manual DNSSEC enabled. Disable it before using "+
|
||||
"AUTODNSSEC_ON/AUTODNSSEC_OFF", dc.Name)
|
||||
}
|
||||
|
||||
if dnssecStatus != AutoDNSSECStatus && dc.AutoDNSSEC == "on" {
|
||||
|
|
@ -289,23 +292,25 @@ func (api *inwxAPI) GetZoneRecordsCorrections(dc *models.DomainConfig, foundReco
|
|||
return nil, 0, err
|
||||
}
|
||||
for _, change := range changes {
|
||||
changeMsgs := change.MsgsJoined
|
||||
changeMessage := change.MsgsJoined
|
||||
switch change.Type {
|
||||
case diff2.REPORT:
|
||||
corrections = append(corrections, &models.Correction{Msg: changeMsgs})
|
||||
corrections = append(corrections, &models.Correction{Msg: changeMessage})
|
||||
case diff2.CHANGE:
|
||||
oldRec := change.Old[0]
|
||||
newRec := change.New[0]
|
||||
if isNullMX(newRec) || isNullMX(oldRec) {
|
||||
// changing to or from a Null MX has to be delete then create
|
||||
// changing to or from a Null MX has to be deleted then create
|
||||
deletes = append(deletes, &models.Correction{
|
||||
Msg: color.RedString("- DELETE %s %s %s ttl=%d", oldRec.GetLabelFQDN(), oldRec.Type, oldRec.ToComparableNoTTL(), oldRec.TTL),
|
||||
Msg: color.RedString("- DELETE %s %s %s ttl=%d", oldRec.GetLabelFQDN(), oldRec.Type,
|
||||
oldRec.ToComparableNoTTL(), oldRec.TTL),
|
||||
F: func() error {
|
||||
return api.deleteRecord(oldRec.Original.(goinwx.NameserverRecord).ID)
|
||||
},
|
||||
})
|
||||
deferred = append(deferred, &models.Correction{
|
||||
Msg: color.GreenString("+ CREATE %s %s %s ttl=%d", newRec.GetLabelFQDN(), newRec.Type, newRec.ToComparableNoTTL(), newRec.TTL),
|
||||
Msg: color.GreenString("+ CREATE %s %s %s ttl=%d", newRec.GetLabelFQDN(), newRec.Type,
|
||||
newRec.ToComparableNoTTL(), newRec.TTL),
|
||||
F: func() error {
|
||||
return api.createRecord(dc.Name, newRec)
|
||||
},
|
||||
|
|
@ -313,7 +318,7 @@ func (api *inwxAPI) GetZoneRecordsCorrections(dc *models.DomainConfig, foundReco
|
|||
} else {
|
||||
recID := oldRec.Original.(goinwx.NameserverRecord).ID
|
||||
corrections = append(corrections, &models.Correction{
|
||||
Msg: changeMsgs,
|
||||
Msg: changeMessage,
|
||||
F: func() error {
|
||||
return api.updateRecord(recID, newRec)
|
||||
},
|
||||
|
|
@ -322,7 +327,7 @@ func (api *inwxAPI) GetZoneRecordsCorrections(dc *models.DomainConfig, foundReco
|
|||
}
|
||||
case diff2.CREATE:
|
||||
creates = append(creates, &models.Correction{
|
||||
Msg: changeMsgs,
|
||||
Msg: changeMessage,
|
||||
F: func() error {
|
||||
return api.createRecord(dc.Name, change.New[0])
|
||||
},
|
||||
|
|
@ -330,7 +335,7 @@ func (api *inwxAPI) GetZoneRecordsCorrections(dc *models.DomainConfig, foundReco
|
|||
case diff2.DELETE:
|
||||
recID := change.Old[0].Original.(goinwx.NameserverRecord).ID
|
||||
deletes = append(deletes, &models.Correction{
|
||||
Msg: changeMsgs,
|
||||
Msg: changeMessage,
|
||||
F: func() error { return api.deleteRecord(recID) },
|
||||
})
|
||||
default:
|
||||
|
|
@ -343,7 +348,7 @@ func (api *inwxAPI) GetZoneRecordsCorrections(dc *models.DomainConfig, foundReco
|
|||
return corrections, actualChangeCount, nil
|
||||
}
|
||||
|
||||
// getDefaultNameservers returns string map with default nameservers based on e.g. sandbox mode.
|
||||
// getDefaultNameservers returns a string map with default nameservers based on e.g. sandbox mode.
|
||||
func (api *inwxAPI) getDefaultNameservers() []string {
|
||||
if api.sandbox {
|
||||
return InwxSandboxDefaultNs
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue