mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
@@ -65,6 +65,7 @@ func init() {
|
||||
providers.RegisterDomainServiceProviderType("BIND", initBind, features)
|
||||
}
|
||||
|
||||
// SoaInfo contains the parts of a SOA rtype.
|
||||
type SoaInfo struct {
|
||||
Ns string `json:"master"`
|
||||
Mbox string `json:"mbox"`
|
||||
@@ -79,6 +80,7 @@ func (s SoaInfo) String() string {
|
||||
return fmt.Sprintf("%s %s %d %d %d %d %d", s.Ns, s.Mbox, s.Serial, s.Refresh, s.Retry, s.Expire, s.Minttl)
|
||||
}
|
||||
|
||||
// Bind is the provider handle for the Bind driver.
|
||||
type Bind struct {
|
||||
DefaultNS []string `json:"default_ns"`
|
||||
DefaultSoa SoaInfo `json:"default_soa"`
|
||||
@@ -86,7 +88,7 @@ type Bind struct {
|
||||
directory string
|
||||
}
|
||||
|
||||
//var bindSkeletin = flag.String("bind_skeletin", "skeletin/master/var/named/chroot/var/named/master", "")
|
||||
// var bindSkeletin = flag.String("bind_skeletin", "skeletin/master/var/named/chroot/var/named/master", "")
|
||||
|
||||
func rrToRecord(rr dns.RR, origin string, replaceSerial uint32) (models.RecordConfig, uint32) {
|
||||
// Convert's dns.RR into our native data type (models.RecordConfig).
|
||||
@@ -95,7 +97,7 @@ func rrToRecord(rr dns.RR, origin string, replaceSerial uint32) (models.RecordCo
|
||||
// replaceSerial != 0, change the serial to replaceSerial.
|
||||
// WARNING(tlim): This assumes SOAs do not have serial=0.
|
||||
// If one is found, we replace it with serial=1.
|
||||
var old_serial, new_serial uint32
|
||||
var oldSerial, newSerial uint32
|
||||
header := rr.Header()
|
||||
rc := models.RecordConfig{}
|
||||
rc.Type = dns.TypeToString[header.Rrtype]
|
||||
@@ -121,17 +123,17 @@ func rrToRecord(rr dns.RR, origin string, replaceSerial uint32) (models.RecordCo
|
||||
case *dns.PTR:
|
||||
rc.Target = v.Ptr
|
||||
case *dns.SOA:
|
||||
old_serial = v.Serial
|
||||
if old_serial == 0 {
|
||||
oldSerial = v.Serial
|
||||
if oldSerial == 0 {
|
||||
// For SOA records, we never return a 0 serial number.
|
||||
old_serial = 1
|
||||
oldSerial = 1
|
||||
}
|
||||
new_serial = v.Serial
|
||||
newSerial = v.Serial
|
||||
if (dnsutil.TrimDomainName(rc.Name, origin+".") == "@") && replaceSerial != 0 {
|
||||
new_serial = replaceSerial
|
||||
newSerial = replaceSerial
|
||||
}
|
||||
rc.Target = fmt.Sprintf("%v %v %v %v %v %v %v",
|
||||
v.Ns, v.Mbox, new_serial, v.Refresh, v.Retry, v.Expire, v.Minttl)
|
||||
v.Ns, v.Mbox, newSerial, v.Refresh, v.Retry, v.Expire, v.Minttl)
|
||||
case *dns.SRV:
|
||||
rc.Target = v.Target
|
||||
rc.SrvPort = v.Port
|
||||
@@ -148,7 +150,7 @@ func rrToRecord(rr dns.RR, origin string, replaceSerial uint32) (models.RecordCo
|
||||
default:
|
||||
log.Fatalf("rrToRecord: Unimplemented zone record type=%s (%v)\n", rc.Type, rr)
|
||||
}
|
||||
return rc, old_serial
|
||||
return rc, oldSerial
|
||||
}
|
||||
|
||||
func makeDefaultSOA(info SoaInfo, origin string) *models.RecordConfig {
|
||||
@@ -184,10 +186,12 @@ func makeDefaultSOA(info SoaInfo, origin string) *models.RecordConfig {
|
||||
return &soaRec
|
||||
}
|
||||
|
||||
// GetNameservers returns the nameservers for a domain.
|
||||
func (c *Bind) GetNameservers(string) ([]*models.Nameserver, error) {
|
||||
return c.nameservers, nil
|
||||
}
|
||||
|
||||
// GetDomainCorrections returns a list of corrections to update a domain.
|
||||
func (c *Bind) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
|
||||
dc.Punycode()
|
||||
// Phase 1: Copy everything to []*models.RecordConfig:
|
||||
@@ -228,7 +232,7 @@ func (c *Bind) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correcti
|
||||
if serial != 0 {
|
||||
// This was an SOA record. Update the serial.
|
||||
oldSerial = serial
|
||||
newSerial = generate_serial(oldSerial)
|
||||
newSerial = generateSerial(oldSerial)
|
||||
// Regenerate with new serial:
|
||||
*soaRec, _ = rrToRecord(x.RR, dc.Name, newSerial)
|
||||
rec = *soaRec
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package bind
|
||||
|
||||
// Generate zonefiles.
|
||||
// This generates a zonefile that prioritizes beauty over efficiency.
|
||||
package bind
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -98,10 +99,10 @@ func (z *zoneGenData) Less(i, j int) bool {
|
||||
return a.String() < b.String()
|
||||
}
|
||||
|
||||
// mostCommonTtl returns the most common TTL in a set of records. If there is
|
||||
// mostCommonTTL returns the most common TTL in a set of records. If there is
|
||||
// a tie, the highest TTL is selected. This makes the results consistent.
|
||||
// NS records are not included in the analysis because Tom said so.
|
||||
func mostCommonTtl(records []dns.RR) uint32 {
|
||||
func mostCommonTTL(records []dns.RR) uint32 {
|
||||
// Index the TTLs in use:
|
||||
d := make(map[uint32]int)
|
||||
for _, r := range records {
|
||||
@@ -141,11 +142,11 @@ func WriteZoneFile(w io.Writer, records []dns.RR, origin string) error {
|
||||
// * $TTL is used to eliminate clutter. The most common TTL value is used.
|
||||
// * "@" is used instead of the apex domain name.
|
||||
|
||||
defaultTtl := mostCommonTtl(records)
|
||||
defaultTTL := mostCommonTTL(records)
|
||||
|
||||
z := &zoneGenData{
|
||||
Origin: dnsutil.AddOrigin(origin, "."),
|
||||
DefaultTtl: defaultTtl,
|
||||
DefaultTtl: defaultTTL,
|
||||
}
|
||||
z.Records = nil
|
||||
for _, r := range records {
|
||||
@@ -200,9 +201,6 @@ func (z *zoneGenData) generateZoneFileHelper(w io.Writer) error {
|
||||
|
||||
// items[4]: the remaining line
|
||||
target := items[4]
|
||||
//if typeStr == "TXT" {
|
||||
// fmt.Printf("generateZoneFileHelper.go: target=%#v\n", target)
|
||||
//}
|
||||
|
||||
fmt.Fprintln(w, formatLine([]int{10, 5, 2, 5, 0}, []string{name, ttl, "IN", typeStr, target}))
|
||||
}
|
||||
@@ -291,10 +289,9 @@ func zoneLabelLess(a, b string) bool {
|
||||
bu, berr := strconv.ParseUint(bs[j], 10, 64)
|
||||
if aerr == nil && berr == nil {
|
||||
return au < bu
|
||||
} else {
|
||||
// otherwise, compare as strings:
|
||||
return as[i] < bs[j]
|
||||
}
|
||||
// otherwise, compare as strings:
|
||||
return as[i] < bs[j]
|
||||
}
|
||||
}
|
||||
// The min top elements were equal, so the shorter name is less.
|
||||
|
||||
@@ -47,7 +47,7 @@ func TestMostCommonTtl(t *testing.T) {
|
||||
// All records are TTL=100
|
||||
records = nil
|
||||
records, e = append(records, r1, r1, r1), 100
|
||||
g = mostCommonTtl(records)
|
||||
g = mostCommonTTL(records)
|
||||
if e != g {
|
||||
t.Fatalf("expected %d; got %d\n", e, g)
|
||||
}
|
||||
@@ -55,7 +55,7 @@ func TestMostCommonTtl(t *testing.T) {
|
||||
// Mixture of TTLs with an obvious winner.
|
||||
records = nil
|
||||
records, e = append(records, r1, r2, r2), 200
|
||||
g = mostCommonTtl(records)
|
||||
g = mostCommonTTL(records)
|
||||
if e != g {
|
||||
t.Fatalf("expected %d; got %d\n", e, g)
|
||||
}
|
||||
@@ -63,7 +63,7 @@ func TestMostCommonTtl(t *testing.T) {
|
||||
// 3-way tie. Largest TTL should be used.
|
||||
records = nil
|
||||
records, e = append(records, r1, r2, r3), 300
|
||||
g = mostCommonTtl(records)
|
||||
g = mostCommonTTL(records)
|
||||
if e != g {
|
||||
t.Fatalf("expected %d; got %d\n", e, g)
|
||||
}
|
||||
@@ -71,7 +71,7 @@ func TestMostCommonTtl(t *testing.T) {
|
||||
// NS records are ignored.
|
||||
records = nil
|
||||
records, e = append(records, r1, r4, r5), 100
|
||||
g = mostCommonTtl(records)
|
||||
g = mostCommonTTL(records)
|
||||
if e != g {
|
||||
t.Fatalf("expected %d; got %d\n", e, g)
|
||||
}
|
||||
@@ -123,7 +123,7 @@ www 300 IN CNAME bosun.org.
|
||||
}
|
||||
|
||||
func TestWriteZoneFileMx(t *testing.T) {
|
||||
//exhibits explicit ttls and long name
|
||||
// exhibits explicit ttls and long name
|
||||
r1, _ := dns.NewRR(`bosun.org. 300 IN TXT "aaa"`)
|
||||
r2, _ := dns.NewRR(`bosun.org. 300 IN TXT "bbb"`)
|
||||
r2.(*dns.TXT).Txt[0] = `b"bb`
|
||||
@@ -157,7 +157,7 @@ google._domainkey IN TXT "\"foo\""
|
||||
`
|
||||
|
||||
func TestWriteZoneFileSrv(t *testing.T) {
|
||||
//exhibits explicit ttls and long name
|
||||
// exhibits explicit ttls and long name
|
||||
r1, _ := dns.NewRR(`bosun.org. 300 IN SRV 10 10 9999 foo.com.`)
|
||||
r2, _ := dns.NewRR(`bosun.org. 300 IN SRV 10 20 5050 foo.com.`)
|
||||
r3, _ := dns.NewRR(`bosun.org. 300 IN SRV 10 10 5050 foo.com.`)
|
||||
@@ -182,7 +182,7 @@ var testdataZFSRV = `$TTL 300
|
||||
`
|
||||
|
||||
func TestWriteZoneFilePtr(t *testing.T) {
|
||||
//exhibits explicit ttls and long name
|
||||
// exhibits explicit ttls and long name
|
||||
r1, _ := dns.NewRR(`bosun.org. 300 IN PTR chell.bosun.org`)
|
||||
r2, _ := dns.NewRR(`bosun.org. 300 IN PTR barney.bosun.org.`)
|
||||
r3, _ := dns.NewRR(`bosun.org. 300 IN PTR alex.bosun.org.`)
|
||||
@@ -203,7 +203,7 @@ var testdataZFPTR = `$TTL 300
|
||||
`
|
||||
|
||||
func TestWriteZoneFileCaa(t *testing.T) {
|
||||
//exhibits explicit ttls and long name
|
||||
// exhibits explicit ttls and long name
|
||||
r1, _ := dns.NewRR(`bosun.org. 300 IN CAA 0 issuewild ";"`)
|
||||
r2, _ := dns.NewRR(`bosun.org. 300 IN CAA 0 issue "letsencrypt.org"`)
|
||||
r3, _ := dns.NewRR(`bosun.org. 300 IN CAA 1 iodef "http://example.com"`)
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var nowFunc func() time.Time = time.Now
|
||||
var nowFunc = time.Now
|
||||
|
||||
// generate_serial takes an old SOA serial number and increments it.
|
||||
func generate_serial(old_serial uint32) uint32 {
|
||||
// generateSerial takes an old SOA serial number and increments it.
|
||||
func generateSerial(oldSerial uint32) uint32 {
|
||||
// Serial numbers are in the format yyyymmddvv
|
||||
// where vv is a version count that starts at 01 each day.
|
||||
// Multiple serial numbers generated on the same day increase vv.
|
||||
@@ -19,9 +19,9 @@ func generate_serial(old_serial uint32) uint32 {
|
||||
// that is smaller than the old one, we punt and increment the old number.
|
||||
// At no time will a serial number == 0 be returned.
|
||||
|
||||
original := old_serial
|
||||
old_serialStr := strconv.FormatUint(uint64(old_serial), 10)
|
||||
var new_serial uint32
|
||||
original := oldSerial
|
||||
oldSerialStr := strconv.FormatUint(uint64(oldSerial), 10)
|
||||
var newSerial uint32
|
||||
|
||||
// Make draft new serial number:
|
||||
today := nowFunc().UTC()
|
||||
@@ -34,38 +34,38 @@ func generate_serial(old_serial uint32) uint32 {
|
||||
draft := uint32(todayNum)*100 + version
|
||||
|
||||
method := "none" // Used only in debugging.
|
||||
if old_serial > draft {
|
||||
if oldSerial > draft {
|
||||
// If old_serial was really slow, upgrade to new yyyymmddvv standard:
|
||||
method = "o>d"
|
||||
new_serial = old_serial + 1
|
||||
new_serial = old_serial + 1
|
||||
} else if old_serial == draft {
|
||||
newSerial = oldSerial + 1
|
||||
newSerial = oldSerial + 1
|
||||
} else if oldSerial == draft {
|
||||
// Edge case: increment old serial:
|
||||
method = "o=d"
|
||||
new_serial = draft + 1
|
||||
} else if len(old_serialStr) != 10 {
|
||||
newSerial = draft + 1
|
||||
} else if len(oldSerialStr) != 10 {
|
||||
// If old_serial is wrong number of digits, upgrade to yyyymmddvv standard:
|
||||
method = "len!=10"
|
||||
new_serial = draft
|
||||
} else if strings.HasPrefix(old_serialStr, todayStr) {
|
||||
newSerial = draft
|
||||
} else if strings.HasPrefix(oldSerialStr, todayStr) {
|
||||
// If old_serial just needs to be incremented:
|
||||
method = "prefix"
|
||||
new_serial = old_serial + 1
|
||||
newSerial = oldSerial + 1
|
||||
} else {
|
||||
// First serial number to be requested today:
|
||||
method = "default"
|
||||
new_serial = draft
|
||||
newSerial = draft
|
||||
}
|
||||
|
||||
if new_serial == 0 {
|
||||
if newSerial == 0 {
|
||||
// We never return 0 as the serial number.
|
||||
new_serial = 1
|
||||
newSerial = 1
|
||||
}
|
||||
if old_serial == new_serial {
|
||||
log.Fatalf("%v: old_serial == new_serial (%v == %v) draft=%v method=%v", original, old_serial, new_serial, draft, method)
|
||||
if oldSerial == newSerial {
|
||||
log.Fatalf("%v: old_serial == new_serial (%v == %v) draft=%v method=%v", original, oldSerial, newSerial, draft, method)
|
||||
}
|
||||
if old_serial > new_serial {
|
||||
log.Fatalf("%v: old_serial > new_serial (%v > %v) draft=%v method=%v", original, old_serial, new_serial, draft, method)
|
||||
if oldSerial > newSerial {
|
||||
log.Fatalf("%v: old_serial > new_serial (%v > %v) draft=%v method=%v", original, oldSerial, newSerial, draft, method)
|
||||
}
|
||||
return new_serial
|
||||
return newSerial
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ func Test_generate_serial_1(t *testing.T) {
|
||||
nowFunc = func() time.Time {
|
||||
return tst.Today
|
||||
}
|
||||
found := generate_serial(tst.Given)
|
||||
found := generateSerial(tst.Given)
|
||||
if expected != found {
|
||||
t.Fatalf("Test:%d/%v: Expected (%d) got (%d)\n", i, tst.Given, expected, found)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user