mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2026-01-07 00:34:46 +08:00
add stutter checking
This commit is contained in:
parent
c87451ccda
commit
cd73784860
4 changed files with 95 additions and 13 deletions
|
|
@ -118,7 +118,7 @@ func TestParsedFiles(t *testing.T) {
|
|||
} else {
|
||||
zoneFile = filepath.Join(testDir, testName, dc.Name+".zone")
|
||||
}
|
||||
fmt.Printf("DEBUG: zonefile = %q\n", zoneFile)
|
||||
//fmt.Printf("DEBUG: zonefile = %q\n", zoneFile)
|
||||
expectedZone, err := os.ReadFile(zoneFile)
|
||||
if err != nil {
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -18,16 +18,20 @@ func ImportRawRecords(domains []*models.DomainConfig) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO(tlim): Check if rec.Name might be a typo of dc.Name. But not if meta["skip_fqdn_check"]=="true"
|
||||
// See "validate.go"
|
||||
/*
|
||||
}
|
||||
if label == domain || strings.HasSuffix(label, "."+domain) {
|
||||
if m := meta["skip_fqdn_check"]; m != "true" {
|
||||
return errors.New(errorRepeat(label, domain))
|
||||
}
|
||||
|
||||
*/
|
||||
if rec.Metadata["skip_fqdn_check"] != "true" && stutters(rec.Name, dc.Name) {
|
||||
var shortname string
|
||||
if rec.Name == dc.Name {
|
||||
shortname = "@"
|
||||
} else {
|
||||
shortname = strings.TrimSuffix(rec.Name, "."+dc.Name)
|
||||
}
|
||||
return fmt.Errorf(
|
||||
"The name %q is an error (repeats the domain). Maybe instead of %q you intended %q? If not add DISABLE_REPEATED_DOMAIN_CHECK to this record to disable this check",
|
||||
rec.NameFQDNRaw,
|
||||
rec.NameRaw,
|
||||
shortname,
|
||||
)
|
||||
}
|
||||
|
||||
// Free memeory:
|
||||
clear(rawRec.Args)
|
||||
|
|
@ -41,6 +45,16 @@ func ImportRawRecords(domains []*models.DomainConfig) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func stutters(name, domain string) bool {
|
||||
if name == "@" {
|
||||
return false
|
||||
}
|
||||
if name == domain || strings.HasSuffix(name, "."+domain) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// NewRecordConfigFromRaw creates a new RecordConfig from the raw ([]any) args,
|
||||
// usually from the parsed dnsconfig.js file, but also useful when a provider
|
||||
// returns the fields of a record as individual values.
|
||||
|
|
|
|||
59
pkg/rtypecontrol/import_test.go
Normal file
59
pkg/rtypecontrol/import_test.go
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
package rtypecontrol
|
||||
|
||||
import "testing"
|
||||
|
||||
func Test_stutters(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
rName string
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "@ symbol should not stutter",
|
||||
rName: "@",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "exact domain match should stutter",
|
||||
rName: "example.com",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "subdomain with dot prefix should stutter",
|
||||
rName: "www.example.com",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "simple subdomain should not stutter",
|
||||
rName: "www",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "partial match without dot should not stutter",
|
||||
rName: "testexample.com",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "empty name should not stutter",
|
||||
rName: "",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "nested subdomain should stutter",
|
||||
rName: "api.staging.example.com",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "different domain should not stutter",
|
||||
rName: "example.org",
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := stutters(tt.rName, "example.com"); got != tt.want {
|
||||
t.Errorf("stutters(%q, %q) = %v, want %v", tt.rName, "example.com", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,11 @@ import (
|
|||
"github.com/StackExchange/dnscontrol/v4/pkg/domaintags"
|
||||
)
|
||||
|
||||
// This code defines many variables to make the logic easier to read. The Go optimizer
|
||||
// should eliminate any performance impact.
|
||||
// We could probably fold some of the logic together, but it would be harder to read.
|
||||
// It's difficult enough to understand it as-is, so clarity is preferred.
|
||||
|
||||
// setRecordNames uses n to update the .Name* fields. If the name is a FQDN
|
||||
// (ends with a "."), it will be handled accordingly. However if it does not
|
||||
// match the domain name, no error is returned but rec.Name* fields will end
|
||||
|
|
@ -100,8 +105,12 @@ func setRecordNamesNonExtend(rec *models.RecordConfig, dcn *domaintags.DomainNam
|
|||
}
|
||||
|
||||
func setRecordNamesExtend(rec *models.RecordConfig, dcn *domaintags.DomainNameVarieties, n string) error {
|
||||
// NB(tlim): What's important to remember is that the domain is the parent D(), not D_EXTEND().
|
||||
// That is... dcn.NameASCII, not rec.SubDomain+dcn.NameASCII.
|
||||
// NB(tlim): When a record has a subdomain "foo" and domain "example.com", a
|
||||
// record such as "www" is added as "www.foo" (short name) or
|
||||
// "www.foo.example.com" (FQDN name).
|
||||
// When generating the shortname, we are truncating the "D()" name, not the
|
||||
// D_EXTEND() name. That is... dcn.NameASCII, not
|
||||
// rec.SubDomain+dcn.NameASCII.
|
||||
|
||||
nRaw := n
|
||||
nASCII := domaintags.EfficientToASCII(n)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue