mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
Fixing OVH DKIM MODIFY (#1290)
* Treat DKIM as normal TXT record type * Empty FieldType before to prevent API error for DKIM * Unsplit DKIM TXT records before diffing the values
This commit is contained in:
@@ -130,6 +130,21 @@ func (c *ovhProvider) GetDomainCorrections(dc *models.DomainConfig) ([]*models.C
|
|||||||
models.PostProcessRecords(actual)
|
models.PostProcessRecords(actual)
|
||||||
txtutil.SplitSingleLongTxt(dc.Records) // Autosplit long TXT records
|
txtutil.SplitSingleLongTxt(dc.Records) // Autosplit long TXT records
|
||||||
|
|
||||||
|
// OVH handles DKIM keys differently, no matter if sent to API as TXT or DKIM record type. The OVH expects the DKIM
|
||||||
|
// string to be in one single string. That's why we'll need to un-split the DKIM TXT records. If not, dnscontrol
|
||||||
|
// will always detect a mismatch between the unsplitted string from API to the splitted one in dnscontrol.
|
||||||
|
for _, rc := range dc.Records {
|
||||||
|
if c.isDKIMRecord(rc) {
|
||||||
|
// When DKIM records are updated, OVH does special logic in their backend, most likely validating the string.
|
||||||
|
// Splitting the string causes the validation on the API backend to fail with error message:
|
||||||
|
// "FAILURE! Error 400: "Invalid subfield found in DKIM : \"v=DKIM1""
|
||||||
|
// Therefore, we merge the text string before we compare or send it to the API.
|
||||||
|
unsplittedTarget := strings.Join(rc.TxtStrings, "")
|
||||||
|
rc.SetTarget(unsplittedTarget)
|
||||||
|
rc.SetTargetTXTString(unsplittedTarget)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
differ := diff.New(dc)
|
differ := diff.New(dc)
|
||||||
_, create, delete, modify, err := differ.IncrementalDiff(actual)
|
_, create, delete, modify, err := differ.IncrementalDiff(actual)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -2,10 +2,9 @@ package ovh
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v3/models"
|
"github.com/StackExchange/dnscontrol/v3/models"
|
||||||
"github.com/miekg/dns/dnsutil"
|
"github.com/miekg/dns/dnsutil"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Void an empty structure.
|
// Void an empty structure.
|
||||||
@@ -111,9 +110,6 @@ func (c *ovhProvider) deleteRecordFunc(id int64, fqdn string) func() error {
|
|||||||
// Returns a function that can be invoked to create a record in a zone.
|
// Returns a function that can be invoked to create a record in a zone.
|
||||||
func (c *ovhProvider) createRecordFunc(rc *models.RecordConfig, fqdn string) func() error {
|
func (c *ovhProvider) createRecordFunc(rc *models.RecordConfig, fqdn string) func() error {
|
||||||
return func() error {
|
return func() error {
|
||||||
if c.isDKIMRecord(rc) {
|
|
||||||
rc.Type = "DKIM"
|
|
||||||
}
|
|
||||||
record := Record{
|
record := Record{
|
||||||
SubDomain: dnsutil.TrimDomainName(rc.GetLabelFQDN(), fqdn),
|
SubDomain: dnsutil.TrimDomainName(rc.GetLabelFQDN(), fqdn),
|
||||||
FieldType: rc.Type,
|
FieldType: rc.Type,
|
||||||
@@ -132,9 +128,6 @@ func (c *ovhProvider) createRecordFunc(rc *models.RecordConfig, fqdn string) fun
|
|||||||
// Returns a function that can be invoked to update a record in a zone.
|
// Returns a function that can be invoked to update a record in a zone.
|
||||||
func (c *ovhProvider) updateRecordFunc(old *Record, rc *models.RecordConfig, fqdn string) func() error {
|
func (c *ovhProvider) updateRecordFunc(old *Record, rc *models.RecordConfig, fqdn string) func() error {
|
||||||
return func() error {
|
return func() error {
|
||||||
if c.isDKIMRecord(rc) {
|
|
||||||
rc.Type = "DKIM"
|
|
||||||
}
|
|
||||||
record := Record{
|
record := Record{
|
||||||
SubDomain: rc.GetLabel(),
|
SubDomain: rc.GetLabel(),
|
||||||
FieldType: rc.Type,
|
FieldType: rc.Type,
|
||||||
@@ -147,10 +140,13 @@ func (c *ovhProvider) updateRecordFunc(old *Record, rc *models.RecordConfig, fqd
|
|||||||
record.SubDomain = ""
|
record.SubDomain = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
err := c.client.CallAPI("PUT", fmt.Sprintf("/domain/zone/%s/record/%d", fqdn, old.ID), &record, &Void{}, true)
|
// We do this last just right before the final API call
|
||||||
if err != nil && rc.Type == "DKIM" && strings.Contains(err.Error(), "alter read-only properties: fieldType") {
|
if c.isDKIMRecord(rc) {
|
||||||
err = fmt.Errorf("this usually occurs when DKIM value is longer than the TXT record limit what OVH allows. Delete the TXT record to get past this limitation. [Original error: %s]", err.Error())
|
// When DKIM value is longer than 255, the MODIFY fails with "Try to alter read-only properties: fieldType"
|
||||||
|
// Setting FieldType to empty string results in the property not being altered, hence error does not occur.
|
||||||
|
record.FieldType = ""
|
||||||
}
|
}
|
||||||
|
err := c.client.CallAPI("PUT", fmt.Sprintf("/domain/zone/%s/record/%d", fqdn, old.ID), &record, &Void{}, true)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -161,6 +157,7 @@ func (c *ovhProvider) isDKIMRecord(rc *models.RecordConfig) bool {
|
|||||||
return (rc != nil && rc.Type == "TXT" && strings.Contains(rc.GetLabel(), "._domainkey"))
|
return (rc != nil && rc.Type == "TXT" && strings.Contains(rc.GetLabel(), "._domainkey"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// refreshZone initiates a refresh task on OVHs backend
|
||||||
func (c *ovhProvider) refreshZone(fqdn string) error {
|
func (c *ovhProvider) refreshZone(fqdn string) error {
|
||||||
return c.client.CallAPI("POST", fmt.Sprintf("/domain/zone/%s/refresh", fqdn), nil, &Void{}, true)
|
return c.client.CallAPI("POST", fmt.Sprintf("/domain/zone/%s/refresh", fqdn), nil, &Void{}, true)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user