Skip to content

Commit 906495a

Browse files
authored
REFACTOR: Rewrite DS to use RecordConfigV2 (#3996)
# Issue DS is the next rtype scheduled to be converted to RecordConfigv2 # Resolution * Convert DS to RecordConfigv2
1 parent 16ee9d1 commit 906495a

File tree

6 files changed

+128
-29
lines changed

6 files changed

+128
-29
lines changed

integrationTest/helpers_integration_test.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -406,9 +406,14 @@ func dname(name, target string) *models.RecordConfig {
406406
}
407407

408408
func ds(name string, keyTag uint16, algorithm, digestType uint8, digest string) *models.RecordConfig {
409-
r := makeRec(name, "", "DS")
410-
panicOnErr(r.SetTargetDS(keyTag, algorithm, digestType, digest))
411-
return r
409+
rec, err := rtypecontrol.NewRecordConfigFromRaw(rtypecontrol.FromRawOpts{
410+
Type: "DS",
411+
TTL: 300,
412+
Args: []any{name, keyTag, algorithm, digestType, digest},
413+
DCN: globalDCN,
414+
})
415+
panicOnErr(err)
416+
return rec
412417
}
413418

414419
func dnskey(name string, flags uint16, protocol, algorithm uint8, publicKey string) *models.RecordConfig {

models/record.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -404,10 +404,7 @@ func (rc *RecordConfig) ToRR() dns.RR {
404404
case dns.TypeDNAME:
405405
rr.(*dns.DNAME).Target = rc.GetTargetField()
406406
case dns.TypeDS:
407-
rr.(*dns.DS).Algorithm = rc.DsAlgorithm
408-
rr.(*dns.DS).DigestType = rc.DsDigestType
409-
rr.(*dns.DS).Digest = rc.DsDigest
410-
rr.(*dns.DS).KeyTag = rc.DsKeyTag
407+
panic("DS should have been handled as modern type")
411408
case dns.TypeDNSKEY:
412409
rr.(*dns.DNSKEY).Flags = rc.DnskeyFlags
413410
rr.(*dns.DNSKEY).Protocol = rc.DnskeyProtocol

pkg/dnsrr/dnsrr.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func helperRRtoRC(rr dns.RR, origin string, fixBug bool) (models.RecordConfig, e
5656
case *dns.DNAME:
5757
err = rc.SetTarget(v.Target)
5858
case *dns.DS:
59-
err = rc.SetTargetDS(v.KeyTag, v.Algorithm, v.DigestType, v.Digest)
59+
panic("DS should be handled as modern type")
6060
case *dns.DNSKEY:
6161
err = rc.SetTargetDNSKEY(v.Flags, v.Protocol, v.Algorithm, v.PublicKey)
6262
case *dns.HTTPS:

pkg/js/helpers.js

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -470,25 +470,6 @@ var CAA = recordBuilder('CAA', {
470470
// CNAME(name,target, recordModifiers...)
471471
var CNAME = recordBuilder('CNAME');
472472

473-
// DS(name, keytag, algorithm, digestype, digest)
474-
var DS = recordBuilder('DS', {
475-
args: [
476-
['name', _.isString],
477-
['keytag', _.isNumber],
478-
['algorithm', _.isNumber],
479-
['digesttype', _.isNumber],
480-
['digest', _.isString],
481-
],
482-
transform: function (record, args, modifiers) {
483-
record.name = args.name;
484-
record.dskeytag = args.keytag;
485-
record.dsalgorithm = args.algorithm;
486-
record.dsdigesttype = args.digesttype;
487-
record.dsdigest = args.digest;
488-
record.target = args.target;
489-
},
490-
});
491-
492473
// DHCID(name,target, recordModifiers...)
493474
var DHCID = recordBuilder('DHCID');
494475

@@ -2499,4 +2480,5 @@ function rawrecordBuilder(type) {
24992480
var CF_REDIRECT = rawrecordBuilder('CF_REDIRECT');
25002481
var CF_SINGLE_REDIRECT = rawrecordBuilder('CLOUDFLAREAPI_SINGLE_REDIRECT');
25012482
var CF_TEMP_REDIRECT = rawrecordBuilder('CF_TEMP_REDIRECT');
2483+
var DS = rawrecordBuilder('DS');
25022484
var RP = rawrecordBuilder('RP');

pkg/js/parse_tests/027-ds.json

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,60 @@
1111
"name": "foo.com",
1212
"records": [
1313
{
14+
"comparable": "1 1 1 FFFF",
1415
"dsalgorithm": 1,
1516
"dsdigest": "FFFF",
1617
"dsdigesttype": 1,
1718
"dskeytag": 1,
19+
"fields": {
20+
"Algorithm": 1,
21+
"Digest": "FFFF",
22+
"DigestType": 1,
23+
"Hdr": {
24+
"Class": 1,
25+
"Name": "foo.com.",
26+
"Rdlength": 0,
27+
"Rrtype": 43,
28+
"Ttl": 300
29+
},
30+
"KeyTag": 1
31+
},
1832
"filepos": "[line:3:5]",
1933
"name": "@",
34+
"name_raw": "@",
35+
"name_unicode": "@",
2036
"target": "",
2137
"ttl": 300,
22-
"type": "DS"
38+
"type": "DS",
39+
"zonfefilepartial": "1 1 1 FFFF"
2340
},
2441
{
42+
"comparable": "1000 13 2 AABBCCDDEEFF",
2543
"dsalgorithm": 13,
2644
"dsdigest": "AABBCCDDEEFF",
2745
"dsdigesttype": 2,
2846
"dskeytag": 1000,
47+
"fields": {
48+
"Algorithm": 13,
49+
"Digest": "AABBCCDDEEFF",
50+
"DigestType": 2,
51+
"Hdr": {
52+
"Class": 1,
53+
"Name": "foo.com.",
54+
"Rdlength": 0,
55+
"Rrtype": 43,
56+
"Ttl": 300
57+
},
58+
"KeyTag": 1000
59+
},
2960
"filepos": "[line:2:5]",
3061
"name": "@",
62+
"name_raw": "@",
63+
"name_unicode": "@",
3164
"target": "",
3265
"ttl": 300,
33-
"type": "DS"
66+
"type": "DS",
67+
"zonfefilepartial": "1000 13 2 AABBCCDDEEFF"
3468
}
3569
],
3670
"registrar": "none",

pkg/rtype/ds.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package rtype
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/StackExchange/dnscontrol/v4/models"
7+
"github.com/StackExchange/dnscontrol/v4/pkg/domaintags"
8+
"github.com/StackExchange/dnscontrol/v4/pkg/rtypecontrol"
9+
"github.com/miekg/dns"
10+
)
11+
12+
func init() {
13+
rtypecontrol.Register(&DS{})
14+
}
15+
16+
// DS RR.
17+
type DS struct {
18+
dns.DS
19+
}
20+
21+
// Name returns the DNS record type as a string.
22+
func (handle *DS) Name() string {
23+
return "DS"
24+
}
25+
26+
// FromArgs fills in the RecordConfig from []any, which is typically from a parsed config file.
27+
func (handle *DS) FromArgs(dcn *domaintags.DomainNameVarieties, rec *models.RecordConfig, args []any) error {
28+
if err := rtypecontrol.PaveArgs(args[1:], "wbbs"); err != nil {
29+
return fmt.Errorf("ERROR: (%s) [DS(%q, %v)]: %w",
30+
rec.FilePos,
31+
rec.Name, rtypecontrol.StringifyQuoted(args[1:]),
32+
err)
33+
}
34+
fields := &dns.DS{
35+
KeyTag: args[1].(uint16),
36+
Algorithm: args[2].(uint8),
37+
DigestType: args[3].(uint8),
38+
Digest: args[4].(string),
39+
}
40+
41+
return handle.FromStruct(dcn, rec, args[0].(string), fields)
42+
}
43+
44+
// FromStruct fills in the RecordConfig from a struct, typically from an API response.
45+
func (handle *DS) FromStruct(dcn *domaintags.DomainNameVarieties, rec *models.RecordConfig, name string, fields any) error {
46+
// Fields is of type "any" thus we must validate the type. It should be the "inner" type of .F, not the outer type, rtype.DS{}.
47+
ds, ok := fields.(*dns.DS)
48+
if !ok {
49+
return fmt.Errorf("fields is not *dns.DS, got %T", fields)
50+
}
51+
rec.F = &DS{*ds}
52+
53+
rec.ZonefilePartial = rec.GetTargetRFC1035Quoted()
54+
rec.Comparable = rec.ZonefilePartial
55+
56+
handle.CopyToLegacyFields(rec)
57+
return nil
58+
}
59+
60+
// CopyToLegacyFields populates the legacy fields of the RecordConfig using the fields in .F.
61+
func (handle *DS) CopyToLegacyFields(rec *models.RecordConfig) {
62+
ds := rec.F.(*DS)
63+
_ = rec.SetTargetDS(ds.KeyTag, ds.Algorithm, ds.DigestType, ds.Digest)
64+
}
65+
66+
// CopyFromLegacyFields uses the the legacy fields to populate .F
67+
func (handle *DS) CopyFromLegacyFields(rec *models.RecordConfig) {
68+
// Copy fields:
69+
rec.F = &DS{
70+
dns.DS{
71+
KeyTag: rec.DsKeyTag,
72+
Algorithm: rec.DsAlgorithm,
73+
DigestType: rec.DsDigestType,
74+
Digest: rec.DsDigest,
75+
},
76+
}
77+
78+
// Fix up ZonefilePartial and Comparable:
79+
rec.ZonefilePartial = rec.GetTargetRFC1035Quoted()
80+
rec.Comparable = rec.ZonefilePartial
81+
}

0 commit comments

Comments
 (0)