Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions build/autotype/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ Remove `func cname()`

Remove the definition of the type:

Example:

```
var CNAME = recordBuilder('CNAME');
```


- Fix models/t_{type}.go

They should call RecordUpdateFields() (see t_mx.go for examples)
Expand All @@ -42,13 +43,13 @@ fgrep --include='*.go' -r 'SetTargetDSStrings('

-- fix models/t_parse.go

Add to PopulateFromStringFunc


-- fix record.go
Remove any mention of the type.

func (rc *RecordConfig) Copy()
-- fix models/record.go

Remove any mention of the type in:
func Downcase(recs []*RecordConfig) {
func CanonicalizeTargets(recs []*RecordConfig, origin string) {


-- fix pkg/js/parse_tests
Expand All @@ -60,4 +61,9 @@ update .targets to include the subdomain.

jstest.sh 014-caa.js

-- fix

Once all types are using RawRecords...

Update pkg/normalize/validate.go
func validateRecordTypes(rec *models.RecordConfig, domain string, pTypes []string) error {

2 changes: 1 addition & 1 deletion build/autotype/hints.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func GetHints() ([]string, TypeCatalog) {
//addType("SOA", "", nil)

// 12
//addType("PTR", "", nil)
addType("PTR", "", nil)

// 15
addType("MX", "", []Field{
Expand Down
21 changes: 21 additions & 0 deletions build/autotype/makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@ package models

import (
"fmt"
"net/netip"
"strconv"

"github.com/StackExchange/dnscontrol/v4/pkg/fieldtypes"
"github.com/StackExchange/dnscontrol/v4/pkg/transform"
"github.com/qdm12/reprint"
)

Expand Down Expand Up @@ -464,8 +466,27 @@ func PopulateFromRaw{{ .Name }}(rc *RecordConfig, rawfields []string, meta map[s
rc.TTL = 1
{{- end }}

{{ if eq .Name "PTR" }}
// First rawfield is the label.
label := rawfields[0]
// Activate PTR Magic! (if the label looks like an IP address, REV() it)
if _, err := netip.ParseAddr(label); err == nil {
// Label is an IP address.
var err error
label, err = transform.PtrNameMagic(label, origin)
if err != nil {
return err
}
subdomain = "" // subdomain is no longer relevant if we replace the label.
}
{{- end }}

{{- if eq .Name "PTR" }}
if err := rc.SetLabel3(label, subdomain, origin); err != nil {
{{- else }}
// First rawfield is the label.
if err := rc.SetLabel3(rawfields[0], subdomain, origin); err != nil {
{{- end }}
return err
}

Expand Down
9 changes: 9 additions & 0 deletions integrationTest/generated_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ func cname(name string, target string) *models.RecordConfig {
return models.MustCreateRecord(name, rdata, nil, 300, "**current-domain**")
}

func ptr(name string, ptr string) *models.RecordConfig {

rdata, err := models.ParsePTR([]string{ptr}, "", "**current-domain**")
if err != nil {
panic(err)
}
return models.MustCreateRecord(name, rdata, nil, 300, "**current-domain**")
}

func mx(name string, preference uint16, mx string) *models.RecordConfig {
spreference := strconv.Itoa(int(preference))

Expand Down
4 changes: 0 additions & 4 deletions integrationTest/helpers_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,10 +399,6 @@ func manyA(namePattern, target string, n int) []*models.RecordConfig {
return recs
}

func ptr(name, target string) *models.RecordConfig {
return makeRec(name, target, "PTR")
}

func r53alias(name, aliasType, target, evalTargetHealth string) *models.RecordConfig {
r := makeRec(name, target, "R53_ALIAS")
r.R53Alias = map[string]string{
Expand Down
2 changes: 0 additions & 2 deletions models/builder_caa.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ func BuilderCAA(rawfields []string, meta map[string]string, origin string) ([]st
return rawfields, meta, fmt.Errorf("CAA record must have at least 3 fields")
}

fmt.Printf("DEBUG: BuilderCAA: rawfields=%v meta=%+v\n", rawfields, meta)

flag := "0"
if meta["caa_critical"] != "" {
flag = "128"
Expand Down
101 changes: 100 additions & 1 deletion models/generated_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ package models

import (
"fmt"
"net/netip"
"strconv"

"github.com/StackExchange/dnscontrol/v4/pkg/fieldtypes"
"github.com/StackExchange/dnscontrol/v4/pkg/transform"
"github.com/qdm12/reprint"
)

func init() {
MustRegisterType("A", RegisterOpts{PopulateFromRaw: PopulateFromRawA})
MustRegisterType("NS", RegisterOpts{PopulateFromRaw: PopulateFromRawNS})
MustRegisterType("CNAME", RegisterOpts{PopulateFromRaw: PopulateFromRawCNAME})
MustRegisterType("PTR", RegisterOpts{PopulateFromRaw: PopulateFromRawPTR})
MustRegisterType("MX", RegisterOpts{PopulateFromRaw: PopulateFromRawMX})
MustRegisterType("AAAA", RegisterOpts{PopulateFromRaw: PopulateFromRawAAAA})
MustRegisterType("SRV", RegisterOpts{PopulateFromRaw: PopulateFromRawSRV})
Expand All @@ -24,7 +27,7 @@ func init() {

// RecordType is a constraint for DNS records.
type RecordType interface {
A | NS | CNAME | MX | AAAA | SRV | NAPTR | DS | DNSKEY | CAA | CFSINGLEREDIRECT
A | NS | CNAME | PTR | MX | AAAA | SRV | NAPTR | DS | DNSKEY | CAA | CFSINGLEREDIRECT
}

// ImportFromLegacy copies the legacy fields (MxPreference, SrvPort, etc.) to
Expand Down Expand Up @@ -53,6 +56,11 @@ func (rc *RecordConfig) ImportFromLegacy(origin string) error {
CNAME{Target: rc.target},
nil,
)
case "PTR":
return RecordUpdateFields(rc,
PTR{Ptr: rc.target},
nil,
)
case "MX":
return RecordUpdateFields(rc,
MX{Preference: rc.MxPreference, Mx: rc.target},
Expand Down Expand Up @@ -113,6 +121,11 @@ func (rc *RecordConfig) Seal() error {
rc.target = f.Target

rc.Comparable = f.Target
case "PTR":
f := rc.Fields.(*PTR)
rc.target = f.Ptr

rc.Comparable = f.Ptr
case "MX":
f := rc.Fields.(*MX)
rc.MxPreference = f.Preference
Expand Down Expand Up @@ -196,6 +209,9 @@ func (rc *RecordConfig) Copy() (*RecordConfig, error) {
case "CNAME":
newR.Fields = &CNAME{}
newR.Fields = rc.Fields.(*CNAME)
case "PTR":
newR.Fields = &PTR{}
newR.Fields = rc.Fields.(*PTR)
case "MX":
newR.Fields = &MX{}
newR.Fields = rc.Fields.(*MX)
Expand Down Expand Up @@ -239,6 +255,10 @@ func PopulateFromFields(rc *RecordConfig, rtype string, fields []string, origin
if rdata, err := ParseCNAME(fields, "", origin); err == nil {
return RecordUpdateFields(rc, rdata, nil)
}
case "PTR":
if rdata, err := ParsePTR(fields, "", origin); err == nil {
return RecordUpdateFields(rc, rdata, nil)
}
case "MX":
if rdata, err := ParseMX(fields, "", origin); err == nil {
return RecordUpdateFields(rc, rdata, nil)
Expand Down Expand Up @@ -285,6 +305,8 @@ func (rc *RecordConfig) GetTargetField() string {
return rc.AsNS().Ns
case "CNAME":
return rc.AsCNAME().Target
case "PTR":
return rc.AsPTR().Ptr
case "MX":
return rc.AsMX().Mx
case "AAAA":
Expand Down Expand Up @@ -507,6 +529,83 @@ func (rc *RecordConfig) SetTargetCNAME(target string) error {
return RecordUpdateFields(rc, CNAME{Target: target}, nil)
}

//// PTR

// PTR is the fields needed to store a DNS record of type PTR.
type PTR struct {
Ptr string `dns:"cdomain-name"`
}

// ParsePTR parses rawfields into an PTR struct.
// subdomain should be "" unless this function is being called by the process that turns dnsconfig.js into the "desired" list.
// Setting origin to "" activates a legacy mode that will go away when the SetTarget*() functions are removed.
func ParsePTR(rawfields []string, subdomain, origin string) (PTR, error) {

// Error checking
if errorCheckFieldCount(rawfields, 1) {
return PTR{}, fmt.Errorf("rtype PTR wants %d field(s), found %d: %+v", 1, len(rawfields)-1, rawfields[1:])
}
var ptr string
var err error
if ptr, err = fieldtypes.ParseHostnameDot(rawfields[0], subdomain, origin); err != nil {
return PTR{}, err
}

return PTR{Ptr: ptr}, nil
}

// PopulateFromRawPTR updates rc to be an PTR record with contents from rawfields, meta and origin.
func PopulateFromRawPTR(rc *RecordConfig, rawfields []string, meta map[string]string, subdomain, origin string) error {
rc.Type = "PTR"

// First rawfield is the label.
label := rawfields[0]
// Activate PTR Magic! (if the label looks like an IP address, REV() it)
if _, err := netip.ParseAddr(label); err == nil {
// Label is an IP address.
var err error
label, err = transform.PtrNameMagic(label, origin)
if err != nil {
return err
}
subdomain = "" // subdomain is no longer relevant if we replace the label.
}
if err := rc.SetLabel3(label, subdomain, origin); err != nil {
return err
}

// Parse the remaining fields.
rdata, err := ParsePTR(rawfields[1:], subdomain, origin)
if err != nil {
return err
}

return RecordUpdateFields(rc, rdata, meta)
}

// AsPTR returns rc.Fields as an PTR struct.
func (rc *RecordConfig) AsPTR() *PTR {
return rc.Fields.(*PTR)
}

// GetFieldsPTR returns rc.Fields as individual typed values.
func (rc *RecordConfig) GetFieldsPTR() string {
n := rc.AsPTR()
return n.Ptr
}

// GetFieldsAsStringsPTR returns rc.Fields as individual strings.
func (rc *RecordConfig) GetFieldsAsStringsPTR() [1]string {
n := rc.AsPTR()
return [1]string{n.Ptr}
}

// SetTargetPTR sets the PTR fields.
func (rc *RecordConfig) SetTargetPTR(ptr string) error {
rc.Type = "PTR"
return RecordUpdateFields(rc, PTR{Ptr: ptr}, nil)
}

//// MX

// MX is the fields needed to store a DNS record of type MX.
Expand Down
4 changes: 2 additions & 2 deletions models/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ func Downcase(recs []*RecordConfig) {
r.Name = strings.ToLower(r.Name)
r.NameFQDN = strings.ToLower(r.NameFQDN)
switch r.Type { // #rtype_variations
case "AKAMAICDN", "ALIAS", "AAAA", "ANAME", "CNAME", "DNAME", "DS", "DNSKEY", "MX", "NS", "NAPTR", "PTR", "SRV", "TLSA":
case "AKAMAICDN", "ALIAS", "AAAA", "ANAME", "CNAME", "DNAME", "DS", "DNSKEY", "MX", "NS", "NAPTR", "SRV", "TLSA":
// Target is case insensitive. Downcase it.
r.target = strings.ToLower(r.target)
// BUGFIX(tlim): isn't ALIAS in the wrong case statement?
Expand Down Expand Up @@ -649,7 +649,7 @@ func CanonicalizeTargets(recs []*RecordConfig, origin string) {

for _, r := range recs {
switch r.Type { // #rtype_variations
case "ALIAS", "ANAME", "CNAME", "DNAME", "DS", "DNSKEY", "MX", "NS", "NAPTR", "PTR", "SRV":
case "ALIAS", "ANAME", "CNAME", "DNAME", "DS", "DNSKEY", "MX", "NS", "NAPTR", "SRV":
// Target is a hostname that might be a shortname. Turn it into a FQDN.
r.target = dnsutil.AddOrigin(r.target, originFQDN)
case "A", "AKAMAICDN", "CAA", "DHCID", "CF_SINGLE_REDIRECT", "CF_REDIRECT", "CF_TEMP_REDIRECT", "CF_WORKER_ROUTE", "HTTPS", "IMPORT_TRANSFORM", "LOC", "SSHFP", "SVCB", "TLSA", "TXT":
Expand Down
45 changes: 1 addition & 44 deletions models/t_parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package models

import (
"fmt"
"net"
"strings"

"github.com/StackExchange/dnscontrol/v4/pkg/rfc1035"
Expand Down Expand Up @@ -86,57 +85,15 @@ func (rc *RecordConfig) PopulateFromStringFunc(rtype, contents, origin string, t
return PopulateFromFields(rc, rtype, fields, origin)
}

// switch rtype {

// case "A":
// if rdata, err := ParseA(fields, origin); err == nil {
// return RecordUpdateFields(rc, rdata, nil)
// }
// case "MX":
// if rdata, err := ParseMX(fields, origin); err == nil {
// return RecordUpdateFields(rc, rdata, nil)
// }
// case "CNAME":
// if rdata, err := ParseCNAME(fields, origin); err == nil {
// return RecordUpdateFields(rc, rdata, nil)
// }
// case "SRV":
// if rdata, err := ParseSRV(fields, origin); err == nil {
// return RecordUpdateFields(rc, rdata, nil)
// }
// case "CAA":
// if rdata, err := ParseCAA(fields, origin); err == nil {
// return RecordUpdateFields(rc, rdata, nil)
// }
// case "DS":
// if rdata, err := ParseDS(fields, origin); err == nil {
// return RecordUpdateFields(rc, rdata, nil)
// }
// case "DNSKEY":
// if rdata, err := ParseDNSKEY(fields, origin); err == nil {
// return RecordUpdateFields(rc, rdata, nil)
// }
// }
// return err
// }

switch rc.Type = rtype; rtype { // #rtype_variations
case "AAAA":
ip := net.ParseIP(contents)
if ip == nil || ip.To16() == nil {
return fmt.Errorf("invalid IP in AAAA record: %s", contents)
}
return rc.SetTargetIP(ip) // Reformat to canonical form.
case "AKAMAICDN", "ALIAS", "ANAME", "CNAME", "NS", "PTR":
case "AKAMAICDN", "ALIAS", "ANAME":
return rc.SetTarget(contents)
case "DHCID":
return rc.SetTarget(contents)
case "DNAME":
return rc.SetTarget(contents)
case "LOC":
return rc.SetTargetLOCString(origin, contents)
case "NAPTR":
return rc.SetTargetNAPTRString(contents)
case "SOA":
return rc.SetTargetSOAString(contents)
case "SPF", "TXT":
Expand Down
1 change: 1 addition & 0 deletions pkg/js/helpers-types.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
var A = rawrecordBuilder('A');
var NS = rawrecordBuilder('NS');
var CNAME = rawrecordBuilder('CNAME');
var PTR = rawrecordBuilder('PTR');
var MX = rawrecordBuilder('MX');
var AAAA = rawrecordBuilder('AAAA');
var SRV = rawrecordBuilder('SRV');
Expand Down
3 changes: 0 additions & 3 deletions pkg/js/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -403,9 +403,6 @@ var HTTPS = recordBuilder('HTTPS', {
},
});

// PTR(name,target, recordModifiers...)
var PTR = recordBuilder('PTR');

// SOA(name,ns,mbox,refresh,retry,expire,minimum, recordModifiers...)
var SOA = recordBuilder('SOA', {
args: [
Expand Down
Loading
Loading