mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
draft!
This commit is contained in:
@ -427,7 +427,7 @@ func (rc *RecordConfig) ToRR() dns.RR {
|
||||
rr.(*dns.SOA).Expire = rc.SoaExpire
|
||||
rr.(*dns.SOA).Minttl = rc.SoaMinttl
|
||||
case dns.TypeSPF:
|
||||
rr.(*dns.SPF).Txt = rc.TxtStrings
|
||||
rr.(*dns.SPF).Txt = []string{rc.target}
|
||||
case dns.TypeSRV:
|
||||
rr.(*dns.SRV).Priority = rc.SrvPriority
|
||||
rr.(*dns.SRV).Weight = rc.SrvWeight
|
||||
@ -443,7 +443,7 @@ func (rc *RecordConfig) ToRR() dns.RR {
|
||||
rr.(*dns.TLSA).Selector = rc.TlsaSelector
|
||||
rr.(*dns.TLSA).Certificate = rc.GetTargetField()
|
||||
case dns.TypeTXT:
|
||||
rr.(*dns.TXT).Txt = rc.TxtStrings
|
||||
rr.(*dns.TXT).Txt = []string{rc.target}
|
||||
default:
|
||||
panic(fmt.Sprintf("ToRR: Unimplemented rtype %v", rc.Type))
|
||||
// We panic so that we quickly find any switch statements
|
||||
|
@ -49,13 +49,13 @@ func (rc *RecordConfig) SetTargetTXT(s string) error {
|
||||
// SetTargetTXTs sets the TXT fields when there are many strings.
|
||||
// The individual strings are stored in .TxtStrings, and joined to make .Target.
|
||||
func (rc *RecordConfig) SetTargetTXTs(s []string) error {
|
||||
if rc.Type == "" {
|
||||
rc.Type = "TXT"
|
||||
} else if !rc.HasFormatIdenticalToTXT() {
|
||||
panic("assertion failed: SetTargetTXTs called when .Type is not TXT or compatible type")
|
||||
}
|
||||
// if rc.Type == "" {
|
||||
// rc.Type = "TXT"
|
||||
// } else if !rc.HasFormatIdenticalToTXT() {
|
||||
// panic("assertion failed: SetTargetTXTs called when .Type is not TXT or compatible type")
|
||||
// }
|
||||
|
||||
rc.SetTarget(strings.Join(s))
|
||||
rc.SetTargetTXT(strings.Join(s, ""))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -74,6 +74,7 @@ func (rc *RecordConfig) GetTargetTXTJoined() string {
|
||||
// "foo bar" << 1 string
|
||||
// "foo" "bar" << 2 strings
|
||||
// foo << error. No quotes! Did you intend to use SetTargetTXT?
|
||||
//
|
||||
// Deprecated: GetTargetTXTJoined is deprecated. ...or should be.
|
||||
func (rc *RecordConfig) SetTargetTXTfromRFC1035Quoted(s string) error {
|
||||
if s != "" && s[0] != '"' {
|
||||
|
@ -21,7 +21,7 @@ Not the best design, but we're stuck with it until we re-do RecordConfig, possib
|
||||
var debugWarnTxtField = false
|
||||
|
||||
// GetTargetField returns the target. There may be other fields (for example
|
||||
// an MX record also has a .MxPreference field.
|
||||
// an MX record also has a .MxPreference field; they are not included.
|
||||
func (rc *RecordConfig) GetTargetField() string {
|
||||
return rc.target
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ func flattenSPFs(cfg *models.DNSConfig) []error {
|
||||
// flatten all spf records that have the "flatten" metadata
|
||||
for _, txt := range txtRecords {
|
||||
var rec *spflib.SPFRecord
|
||||
txtTarget := strings.Join(txt.TxtStrings, "")
|
||||
txtTarget := txt.GetTargetField()
|
||||
if txt.Metadata["flatten"] != "" || txt.Metadata["split"] != "" {
|
||||
if cache == nil {
|
||||
cache, err = spflib.NewCache("spfcache.json")
|
||||
|
@ -11,30 +11,24 @@ import (
|
||||
|
||||
// TxtHasBackticks audits TXT records for strings that contain backticks.
|
||||
func TxtHasBackticks(rc *models.RecordConfig) error {
|
||||
for _, txt := range rc.TxtStrings {
|
||||
if strings.Contains(txt, "`") {
|
||||
return fmt.Errorf("txtstring contains backtick")
|
||||
}
|
||||
if strings.Contains(rc.GetTargetField(), "`") {
|
||||
return fmt.Errorf("txtstring contains backtick")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TxtHasSingleQuotes audits TXT records for strings that contain single-quotes.
|
||||
func TxtHasSingleQuotes(rc *models.RecordConfig) error {
|
||||
for _, txt := range rc.TxtStrings {
|
||||
if strings.Contains(txt, "'") {
|
||||
return fmt.Errorf("txtstring contains single-quotes")
|
||||
}
|
||||
if strings.Contains(rc.GetTargetField(), "'") {
|
||||
return fmt.Errorf("txtstring contains single-quotes")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TxtHasDoubleQuotes audits TXT records for strings that contain doublequotes.
|
||||
func TxtHasDoubleQuotes(rc *models.RecordConfig) error {
|
||||
for _, txt := range rc.TxtStrings {
|
||||
if strings.Contains(txt, `"`) {
|
||||
return fmt.Errorf("txtstring contains doublequotes")
|
||||
}
|
||||
if strings.Contains(rc.GetTargetField(), `"`) {
|
||||
return fmt.Errorf("txtstring contains doublequotes")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -42,27 +36,23 @@ func TxtHasDoubleQuotes(rc *models.RecordConfig) error {
|
||||
// TxtIsExactlyLen255 audits TXT records for strings exactly 255 octets long.
|
||||
// This is rare; you probably want to use TxtNoStringsLen256orLonger() instead.
|
||||
func TxtIsExactlyLen255(rc *models.RecordConfig) error {
|
||||
for _, txt := range rc.TxtStrings {
|
||||
if len(txt) == 255 {
|
||||
return fmt.Errorf("txtstring length is 255")
|
||||
}
|
||||
if len(rc.GetTargetField()) == 255 {
|
||||
return fmt.Errorf("txtstring length is 255")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TxtHasSegmentLen256orLonger audits TXT records for strings that are >255 octets.
|
||||
func TxtHasSegmentLen256orLonger(rc *models.RecordConfig) error {
|
||||
for _, txt := range rc.TxtStrings {
|
||||
if len(txt) > 255 {
|
||||
return fmt.Errorf("%q txtstring length > 255", rc.GetLabel())
|
||||
}
|
||||
if len(rc.GetTargetField()) > 255 {
|
||||
return fmt.Errorf("%q txtstring length > 255", rc.GetLabel())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TxtHasMultipleSegments audits TXT records for multiple strings
|
||||
func TxtHasMultipleSegments(rc *models.RecordConfig) error {
|
||||
if len(rc.TxtStrings) > 1 {
|
||||
if len(rc.GetTargetField()) > 255 {
|
||||
return fmt.Errorf("multiple strings in one txt")
|
||||
}
|
||||
return nil
|
||||
@ -70,35 +60,25 @@ func TxtHasMultipleSegments(rc *models.RecordConfig) error {
|
||||
|
||||
// TxtHasTrailingSpace audits TXT records for strings that end with space.
|
||||
func TxtHasTrailingSpace(rc *models.RecordConfig) error {
|
||||
for _, txt := range rc.TxtStrings {
|
||||
if txt != "" && txt[ultimate(txt)] == ' ' {
|
||||
return fmt.Errorf("txtstring ends with space")
|
||||
}
|
||||
txt := rc.GetTargetField()
|
||||
if txt != "" && txt[ultimate(txt)] == ' ' {
|
||||
return fmt.Errorf("txtstring ends with space")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TxtIsEmpty audits TXT records for empty strings.
|
||||
func TxtIsEmpty(rc *models.RecordConfig) error {
|
||||
// There must be strings.
|
||||
if len(rc.TxtStrings) == 0 {
|
||||
return fmt.Errorf("txt with no strings")
|
||||
}
|
||||
// Each string must be non-empty.
|
||||
for _, txt := range rc.TxtStrings {
|
||||
if len(txt) == 0 {
|
||||
return fmt.Errorf("txtstring is empty")
|
||||
}
|
||||
if len(rc.GetTargetField()) == 0 {
|
||||
return fmt.Errorf("txtstring is empty")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TxtHasUnpairedDoubleQuotes audits TXT records for strings that contain unpaired doublequotes.
|
||||
func TxtHasUnpairedDoubleQuotes(rc *models.RecordConfig) error {
|
||||
for _, txt := range rc.TxtStrings {
|
||||
if strings.Count(txt, `"`)%2 == 1 {
|
||||
return fmt.Errorf("txtstring contains unpaired doublequotes")
|
||||
}
|
||||
if strings.Count(rc.GetTargetField(), `"`)%2 == 1 {
|
||||
return fmt.Errorf("txtstring contains unpaired doublequotes")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -1,5 +1,23 @@
|
||||
package txtutil
|
||||
|
||||
import "github.com/StackExchange/dnscontrol/v4/models"
|
||||
|
||||
// SplitSingleLongTxt finds TXT records with a single long string and splits it
|
||||
// into 255-octet chunks. This is used by providers that, when a user specifies
|
||||
// one long TXT string, split it into smaller strings behind the scenes.
|
||||
// This should be called from GetZoneRecordsCorrections().
|
||||
// Deprecated: SplitSingleLongTxt() is deprecated. No longer needed.
|
||||
func SplitSingleLongTxt(records []*models.RecordConfig) {
|
||||
// for _, rc := range records {
|
||||
// if rc.HasFormatIdenticalToTXT() {
|
||||
// s := rc.TxtStrings[0]
|
||||
// if len(rc.TxtStrings) == 1 && len(s) > 255 {
|
||||
// rc.SetTargetTXTs(splitChunks(s, 255))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// ToChunks returns the string as chunks of 255-octet strings (the last string being the remainder).
|
||||
func ToChunks(s string) []string {
|
||||
return splitChunks(s, 255)
|
||||
|
@ -328,8 +328,7 @@ func (c *axfrddnsProvider) GetZoneRecords(domain string, meta map[string]string)
|
||||
last := foundRecords[len(foundRecords)-1]
|
||||
if last.Type == "TXT" &&
|
||||
last.Name == dnssecDummyLabel &&
|
||||
len(last.TxtStrings) == 1 &&
|
||||
last.TxtStrings[0] == dnssecDummyTxt {
|
||||
last.GetTargetField() == dnssecDummyTxt {
|
||||
c.hasDnssecRecords = true
|
||||
foundRecords = foundRecords[0:(len(foundRecords) - 1)]
|
||||
}
|
||||
|
@ -653,11 +653,9 @@ func (a *azurednsProvider) recordToNative(recordKey models.RecordKey, recordConf
|
||||
recordSet.Properties.TxtRecords = []*adns.TxtRecord{}
|
||||
}
|
||||
// Empty TXT record needs to have no value set in it's properties
|
||||
if !(len(rec.TxtStrings) == 1 && rec.TxtStrings[0] == "") {
|
||||
var txts []*string
|
||||
for _, txt := range rec.TxtStrings {
|
||||
txts = append(txts, to.StringPtr(txt))
|
||||
}
|
||||
tt := rec.GetTargetField()
|
||||
if tt != "" {
|
||||
txts := []*string{to.StringPtr(tt)}
|
||||
recordSet.Properties.TxtRecords = append(recordSet.Properties.TxtRecords, &adns.TxtRecord{Value: txts})
|
||||
}
|
||||
case "MX":
|
||||
@ -729,11 +727,9 @@ func (a *azurednsProvider) recordToNativeDiff2(recordKey models.RecordKey, recor
|
||||
recordSet.Properties.TxtRecords = []*adns.TxtRecord{}
|
||||
}
|
||||
// Empty TXT record needs to have no value set in it's properties
|
||||
if !(len(rec.TxtStrings) == 1 && rec.TxtStrings[0] == "") {
|
||||
var txts []*string
|
||||
for _, txt := range rec.TxtStrings {
|
||||
txts = append(txts, to.StringPtr(txt))
|
||||
}
|
||||
tt := rec.GetTargetField()
|
||||
if tt != "" {
|
||||
txts := []*string{to.StringPtr(tt)}
|
||||
recordSet.Properties.TxtRecords = append(recordSet.Properties.TxtRecords, &adns.TxtRecord{Value: txts})
|
||||
}
|
||||
case "MX":
|
||||
|
@ -135,14 +135,7 @@ func (client *providerClient) GetZoneRecordsCorrections(dc *models.DomainConfig,
|
||||
}
|
||||
|
||||
func makePurge(domainname string, cor diff.Correlation) zoneResourceRecordEdit {
|
||||
var existingTarget string
|
||||
|
||||
switch cor.Existing.Type {
|
||||
case "TXT":
|
||||
existingTarget = strings.Join(cor.Existing.TxtStrings, "")
|
||||
default:
|
||||
existingTarget = cor.Existing.GetTargetField()
|
||||
}
|
||||
existingTarget := cor.Existing.GetTargetField()
|
||||
|
||||
zer := zoneResourceRecordEdit{
|
||||
Action: "PURGE",
|
||||
@ -163,19 +156,11 @@ func makePurge(domainname string, cor diff.Correlation) zoneResourceRecordEdit {
|
||||
func makeAdd(domainname string, cre diff.Correlation) zoneResourceRecordEdit {
|
||||
rec := cre.Desired
|
||||
|
||||
var recTarget string
|
||||
switch rec.Type {
|
||||
case "TXT":
|
||||
recTarget = strings.Join(rec.TxtStrings, "")
|
||||
default:
|
||||
recTarget = rec.GetTargetField()
|
||||
}
|
||||
|
||||
zer := zoneResourceRecordEdit{
|
||||
Action: "ADD",
|
||||
RecordType: rec.Type,
|
||||
NewKey: rec.Name,
|
||||
NewValue: recTarget,
|
||||
NewValue: rec.GetTargetField(),
|
||||
NewTTL: rec.TTL,
|
||||
}
|
||||
|
||||
@ -192,7 +177,7 @@ func makeAdd(domainname string, cre diff.Correlation) zoneResourceRecordEdit {
|
||||
zer.NewWeight = rec.SrvWeight
|
||||
zer.NewPort = rec.SrvPort
|
||||
case "TXT":
|
||||
zer.NewValue = strings.Join(rec.TxtStrings, "")
|
||||
zer.NewValue = rec.GetTargetField()
|
||||
default: // "A", "CNAME", "NS"
|
||||
// Nothing to do.
|
||||
}
|
||||
@ -205,15 +190,8 @@ func makeEdit(domainname string, m diff.Correlation) zoneResourceRecordEdit {
|
||||
// TODO: Assert that old.Type == rec.Type
|
||||
// TODO: Assert that old.Name == rec.Name
|
||||
|
||||
var oldTarget, recTarget string
|
||||
switch old.Type {
|
||||
case "TXT":
|
||||
oldTarget = strings.Join(old.TxtStrings, "")
|
||||
recTarget = strings.Join(rec.TxtStrings, "")
|
||||
default:
|
||||
oldTarget = old.GetTargetField()
|
||||
recTarget = rec.GetTargetField()
|
||||
}
|
||||
oldTarget := old.GetTargetField()
|
||||
recTarget := rec.GetTargetField()
|
||||
|
||||
zer := zoneResourceRecordEdit{
|
||||
Action: "EDIT",
|
||||
|
@ -28,13 +28,6 @@ func (api *domainNameShopProvider) GetZoneRecords(domain string, meta map[string
|
||||
// GetZoneRecordsCorrections returns a list of corrections that will turn existing records into dc.Records.
|
||||
func (api *domainNameShopProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, existingRecords models.Records) ([]*models.Correction, error) {
|
||||
|
||||
// Merge TXT strings to one string
|
||||
for _, rc := range dc.Records {
|
||||
if rc.HasFormatIdenticalToTXT() {
|
||||
rc.SetTargetTXT(strings.Join(rc.TxtStrings, ""))
|
||||
}
|
||||
}
|
||||
|
||||
// Domainnameshop doesn't allow arbitrary TTLs they must be a multiple of 60.
|
||||
for _, record := range dc.Records {
|
||||
record.TTL = fixTTL(record.TTL)
|
||||
|
@ -63,7 +63,7 @@ func fromRecordConfig(in *models.RecordConfig, zone *zone) record {
|
||||
ZoneID: zone.ID,
|
||||
}
|
||||
|
||||
if r.Type == "TXT" && len(in.TxtStrings) == 1 {
|
||||
if r.Type == "TXT" {
|
||||
// HACK: HETZNER rejects values that fit into 255 bytes w/o quotes,
|
||||
// but do not fit w/ added quotes (via GetTargetCombined()).
|
||||
// Sending the raw, non-quoted value works for the comprehensive
|
||||
@ -71,7 +71,7 @@ func fromRecordConfig(in *models.RecordConfig, zone *zone) record {
|
||||
// The HETZNER validation does not provide helpful error messages.
|
||||
// {"error":{"message":"422 Unprocessable Entity: missing: ; ","code":422}}
|
||||
// Last checked: 2023-04-01
|
||||
valueNotQuoted := in.TxtStrings[0]
|
||||
valueNotQuoted := in.GetTargetField()
|
||||
if len(valueNotQuoted) == 254 || len(valueNotQuoted) == 255 {
|
||||
r.Value = valueNotQuoted
|
||||
}
|
||||
|
@ -256,7 +256,7 @@ func (n *HXClient) createRecordString(rc *models.RecordConfig, domain string) (s
|
||||
case "CAA":
|
||||
record.Answer = fmt.Sprintf(`%v %s "%s"`, rc.CaaFlag, rc.CaaTag, record.Answer)
|
||||
case "TXT":
|
||||
record.Answer = encodeTxt(rc.TxtStrings)
|
||||
record.Answer = encodeTxt([]string{rc.GetTargetField()})
|
||||
case "SRV":
|
||||
if rc.GetTargetField() == "." {
|
||||
return "", fmt.Errorf("SRV records with empty targets are not supported (as of 2020-02-27, the API returns 'Invalid attribute value syntax')")
|
||||
|
@ -356,7 +356,7 @@ func toVultrRecord(dc *models.DomainConfig, rc *models.RecordConfig, vultrID str
|
||||
// Vultr doesn't permit TXT strings to include double-quotes
|
||||
// therefore, we don't have to escape interior double-quotes.
|
||||
// Vultr's API requires the string to begin and end with double-quotes.
|
||||
r.Data = `"` + strings.Join(rc.TxtStrings, "") + `"`
|
||||
r.Data = `"` + rc.GetTargetField() + `"`
|
||||
default:
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user