Skip to content

Commit

Permalink
Merge pull request d2iq-archive#123 from mesosphere/soa
Browse files Browse the repository at this point in the history
Improve customization of SOA records
  • Loading branch information
kozyraki committed Apr 10, 2015
2 parents 291e5e1 + c91c0a3 commit 47f0301
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 38 deletions.
8 changes: 7 additions & 1 deletion config.json.sample
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@
"refreshSeconds": 60,
"ttl": 60,
"domain": "mesos",
"ns": "ns1",
"port": 8053,
"resolvers": ["8.8.8.8"],
"timeout": 5,
"listener": "0.0.0.0",
"email": "root.mesos-dns.mesos",
"SOAMname": "root.ns1.mesos",
"SOARname": "ns1.mesos",
"SOARefresh": 60,
"SOARetry": 600,
"SOAExpire": 86400,
"SOAMinttl": 60,
"dnson": true,
"httpon": true,
"httpport": 8123,
Expand Down
23 changes: 20 additions & 3 deletions docs/docs/configuration-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,17 @@ The configuration file should include the following fields:
"port": 53,
"resolvers": ["169.254.169.254"],
"timeout": 5,
"httpon": true,
"dsnon": true,
"httpport": 8123,
"externalon": true
"listener": "10.101.160.16",
"email": "root.mesos-dns.mesos"
"SOAMname": "root.ns1.mesos",
"SOARname": "ns1.mesos",
"SOARefresh": 60,
"SOARetry": 600,
"SOAExpire": 86400,
"SOAMinttl": 60,
}
```

Expand All @@ -43,13 +52,21 @@ It is sufficient to specify just one of the `zk` or `masters` field. If both are

`listener` is the IP address of Mesos-DNS. In SOA replies, Mesos-DNS identifies hostname `mesos-dns.domain` as the primary nameserver for the domain. It uses this IP address in an A record for `mesos-dns.domain`. The default value is "0.0.0.0", which instructs Mesos-DNS to create an A record for every IP address associated with a network interface on the server that runs the Mesos-DNS process.

`email` is the email address of the Mesos domain name administrator. It is associated with the SOA record for the Mesos domain. The format is `mailbox-name.domain`, using a `.` instead of `@`. For example, if the email address is `root@mesos-dns.mesos`, the `email` field should be `root.mesos-dns.mesos`. The default value is `root.mesos-dns.mesos`.

`dnson` is a boolean field that controls whether Mesos-DNS listens for DNS requests or not. The default value is `true`.

`httpon` is a boolean field that controls whether Mesos-DNS listens for HTTP requests or not. The default value is `true`.

`httpport` is the port number that Mesos-DNS monitors for incoming HTTP requests. The default value is `8123`.

`externalon` is a boolean field that controls whether Mesos-DNS serves requests outside of the Mesos domain. The default value is `true`.

`SOAMname` is the MNAME field in the SOA record for the Mesos domain. The format is `mailbox.domain`, using a `.` instead of `@`. For example, if the email address is `root@ns1.mesos`, the `email` field should be `root.mesos-dns.mesos`. For details, see the [RFC-1035](http://tools.ietf.org/html/rfc1035#page-18). The default value is `root.ns1.mesos`.

`SOARefresh` is the REFRESH field in the SOA record for the Mesos domain. For details, see the [RFC-1035](http://tools.ietf.org/html/rfc1035#page-18). The default value is `60`.

`SOARetry` is the RETRY field in the SOA record for the Mesos domain. For details, see the [RFC-1035](http://tools.ietf.org/html/rfc1035#page-18). The default value is `600`.

`SOAExpire` is the EXPIRE field in the SOA record for the Mesos domain. For details, see the [RFC-1035](http://tools.ietf.org/html/rfc1035#page-18). The default value is `86400`.

`SOAMinttl` is the minimum TTL field in the SOA record for the Mesos domain. For details, see the [RFC-2308](https://tools.ietf.org/html/rfc2308). The default value is `60`.

7 changes: 7 additions & 0 deletions docs/docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ title: Mesos-DNS FAQ

You can check the Mesos-DNS version by executing `mesos-dns -version`.


---

#### SOA record customization

You can customize all fields in the SOA records for the Mesos domain. See the `SOA*` [configuration parameters](configuration-parameters.html).

---

#### Verbose and very verbose modes
Expand Down
48 changes: 33 additions & 15 deletions records/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os/user"
"path/filepath"
"strings"
"time"

"github.com/mesosphere/mesos-dns/logging"
"github.com/miekg/dns"
Expand All @@ -26,7 +27,7 @@ type Config struct {
RefreshSeconds int

// TTL: the TTL value used for SRV and A records (default 60)
TTL int
TTL int32

// Resolver port: port used to listen for slave requests (default 53)
Port int
Expand All @@ -44,11 +45,14 @@ type Config struct {
// File is the location of the config.json file
File string

// Email is the rname for a SOA
Email string

// Mname is the mname for a SOA
Mname string
// SOA record fields (see http://tools.ietf.org/html/rfc1035#page-18)
SOAMname string // primary name server
SOARname string // email of admin esponsible
SOASerial uint32 // initial version number (incremented on refresh)
SOARefresh uint32 // refresh interval
SOARetry uint32 // retry interval
SOAExpire uint32 // expiration time
SOAMinttl uint32 // minimum TTL

// ListenAddr is the server listener address
Listener string
Expand All @@ -73,7 +77,12 @@ func SetConfig(cjson string) (c Config) {
Domain: "mesos",
Port: 53,
Timeout: 5,
Email: "root.mesos-dns.mesos",
SOARname: "root.ns1.mesos",
SOAMname: "ns1.mesos",
SOARefresh: 60,
SOARetry: 600,
SOAExpire: 86400,
SOAMinttl: 60,
Resolvers: []string{"8.8.8.8"},
Listener: "0.0.0.0",
HttpPort: 8123,
Expand Down Expand Up @@ -119,14 +128,18 @@ func SetConfig(cjson string) (c Config) {
c.Resolvers = GetLocalDNS()
}

c.Email = strings.Replace(c.Email, "@", ".", -1)
if c.Email[len(c.Email)-1:] != "." {
c.Email = c.Email + "."
}

c.Domain = strings.ToLower(c.Domain)
c.Mname = "mesos-dns." + c.Domain + "."

// SOA record fields
c.SOARname = strings.Replace(c.SOARname, "@", ".", -1)
if c.SOARname[len(c.SOARname)-1:] != "." {
c.SOARname = c.SOARname + "."
}
if c.SOAMname[len(c.SOAMname)-1:] != "." {
c.SOAMname = c.SOAMname + "."
}
c.SOASerial = uint32(time.Now().Unix())

// print configuration file
logging.Verbose.Println("Mesos-DNS configuration:")
if len(c.Masters) != 0 {
Expand All @@ -144,8 +157,13 @@ func SetConfig(cjson string) (c Config) {
logging.Verbose.Println(" - Timeout: ", c.Timeout)
logging.Verbose.Println(" - Resolvers: " + strings.Join(c.Resolvers, ", "))
logging.Verbose.Println(" - ExternalOn: ", c.ExternalOn)
logging.Verbose.Println(" - Email: " + c.Email)
logging.Verbose.Println(" - Mname: " + c.Mname)
logging.Verbose.Println(" - SOAMname: " + c.SOAMname)
logging.Verbose.Println(" - SOARname: " + c.SOARname)
logging.Verbose.Println(" - SOASerial: ", c.SOASerial)
logging.Verbose.Println(" - SOARefresh: ", c.SOARefresh)
logging.Verbose.Println(" - SOARetry: ", c.SOARetry)
logging.Verbose.Println(" - SOAExpire: ", c.SOAExpire)
logging.Verbose.Println(" - SOAExpire: ", c.SOAMinttl)
logging.Verbose.Println(" - HttpPort: ", c.HttpPort)
logging.Verbose.Println(" - HttpOn: ", c.HttpOn)
logging.Verbose.Println(" - ConfigFile: ", c.File)
Expand Down
18 changes: 9 additions & 9 deletions records/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func (rg *RecordGenerator) ParseState(leader string, c Config) error {
}

// insert state
rg.InsertState(sj, c.Domain, c.Mname, c.Listener, c.Masters)
rg.InsertState(sj, c.Domain, c.SOAMname, c.Listener, c.Masters)
return nil
}

Expand Down Expand Up @@ -188,7 +188,7 @@ func (rg *RecordGenerator) loadWrap(ip string, port string) (StateJSON, error) {
}

// InsertState transforms a StateJSON into RecordGenerator RRs
func (rg *RecordGenerator) InsertState(sj StateJSON, domain string, mname string,
func (rg *RecordGenerator) InsertState(sj StateJSON, domain string, ns string,
listener string, masters []string) error {

// creates a map with slave IP addresses (IPv4)
Expand Down Expand Up @@ -244,7 +244,7 @@ func (rg *RecordGenerator) InsertState(sj StateJSON, domain string, mname string
}
}

rg.listenerRecord(listener, mname)
rg.listenerRecord(listener, ns)
rg.masterRecord(domain, masters, sj.Leader)
return nil
}
Expand Down Expand Up @@ -294,20 +294,20 @@ func (rg *RecordGenerator) masterRecord(domain string, masters []string, leader
}

// A record for mesos-dns (the name is listed in SOA replies)
func (rg *RecordGenerator) listenerRecord(listener string, mname string) {
func (rg *RecordGenerator) listenerRecord(listener string, ns string) {
if listener == "0.0.0.0" {
rg.setFromLocal(listener, mname)
rg.setFromLocal(listener, ns)
} else if listener == "127.0.0.1" {
rg.insertRR(mname, "127.0.0.1", "A")
rg.insertRR(ns, "127.0.0.1", "A")
} else {
rg.insertRR(mname, listener, "A")
rg.insertRR(ns, listener, "A")
}
}

// A records for each local interface
// If this causes problems you should explicitly set the
// listener address in config.json
func (rg *RecordGenerator) setFromLocal(host string, mname string) {
func (rg *RecordGenerator) setFromLocal(host string, ns string) {

ifaces, err := net.Interfaces()
if err != nil {
Expand Down Expand Up @@ -340,7 +340,7 @@ func (rg *RecordGenerator) setFromLocal(host string, mname string) {
continue
}

rg.insertRR(mname, ip.String(), "A")
rg.insertRR(ns, ip.String(), "A")
}
}
}
Expand Down
17 changes: 9 additions & 8 deletions resolver/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,11 @@ func (res *Resolver) Reload() {
err := t.ParseState(currentLeader, res.config)

if err == nil {
timestamp := uint32(time.Now().Unix())
// may need to refactor for fairness
res.rsLock.Lock()
defer res.rsLock.Unlock()
res.config.SOASerial = timestamp
res.rs = &t
} else {
logging.VeryVerbose.Println("Warning: master not found; keeping old DNS state")
Expand Down Expand Up @@ -225,12 +227,12 @@ func (res *Resolver) formatSOA(dom string) (*dns.SOA, error) {
Class: dns.ClassINET,
Ttl: ttl,
},
Ns: res.config.Mname,
Mbox: res.config.Email,
Serial: uint32(time.Now().Unix()),
Refresh: ttl,
Retry: 600,
Expire: 86400,
Ns: res.config.SOAMname,
Mbox: res.config.SOARname,
Serial: res.config.SOASerial,
Refresh: res.config.SOARefresh,
Retry: res.config.SOARetry,
Expire: res.config.SOAExpire,
Minttl: ttl,
}, nil
}
Expand Down Expand Up @@ -313,7 +315,7 @@ func (res *Resolver) HandleMesos(w dns.ResponseWriter, r *dns.Msg) {

m := new(dns.Msg)
m.Authoritative = true
m.RecursionAvailable = true
m.RecursionAvailable = false
m.SetReply(r)

rs := res.records()
Expand Down Expand Up @@ -385,7 +387,6 @@ func (res *Resolver) HandleMesos(w dns.ResponseWriter, r *dns.Msg) {
} else {
// no answers but not a {SOA,SRV} request
if len(m.Answer) == 0 && (qType != dns.TypeSOA) && (qType != dns.TypeSRV) {

m = new(dns.Msg)
// set NXDOMAIN
m.SetRcode(r, 3)
Expand Down
4 changes: 2 additions & 2 deletions resolver/resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ func fakeDNS(port int) (Resolver, error) {
Domain: "mesos",
Resolvers: records.GetLocalDNS(),
Listener: "127.0.0.1",
Email: "root.mesos-dns.mesos.",
Mname: "mesos-dns.mesos.",
SOARname: "root.ns1.mesos.",
SOAMname: "ns1.mesos.",
HttpPort: 8123,
ExternalOn: true,
}
Expand Down

0 comments on commit 47f0301

Please sign in to comment.