Browse Source

Support TXT records

(issue #20)
Ask Bjørn Hansen 12 years ago
parent
commit
a84a6c9bc2
4 changed files with 68 additions and 13 deletions
  1. 23 10
      README.md
  2. 5 1
      dns/test.example.com.json
  3. 10 0
      zone_test.go
  4. 30 2
      zones.go

+ 23 - 10
README.md

@@ -145,7 +145,11 @@ A record for users in Europe than anywhere else, use:
     {
     {
         "serial": 1,
         "serial": 1,
         "data": {
         "data": {
-            "": { "mx": { "mx": "mail.example.com", "preference": 10 } },
+            "": {
+                "ns": [ "ns.example.net", "ns2.example.net" ],
+                "txt": "Example zone",
+                "mx": { "mx": "mail.example.com", "preference": 10 }
+            },
             "mail": { "a": [ ["192.168.0.1", 100], ["192.168.10.1", 50] ] },
             "mail": { "a": [ ["192.168.0.1", 100], ["192.168.10.1", 50] ] },
             "mail.europe": { "a": [ ["192.168.255.1", 0] ] },
             "mail.europe": { "a": [ ["192.168.255.1", 0] ] },
             "smtp": { "alias": "mail" }
             "smtp": { "alias": "mail" }
@@ -169,7 +173,7 @@ ticket in the issue tracker with what you are missing.
 Each record has the format of a short array with the first element being the
 Each record has the format of a short array with the first element being the
 IP address and the second the weight.
 IP address and the second the weight.
 
 
-    { "a": [ [ "192.168.0.1", 10], ["192.168.2.1", 5] ] }
+    [ [ "192.168.0.1", 10], ["192.168.2.1", 5] ]
 
 
 See above for how the weights work.
 See above for how the weights work.
 
 
@@ -181,12 +185,12 @@ Same format as A records (except the record type is "aaaa").
 
 
 Internally resolved cname, of sorts. Only works internally in a zone.
 Internally resolved cname, of sorts. Only works internally in a zone.
 
 
-    "alias": "foo"
+    "foo"
 
 
 ### CNAME
 ### CNAME
 
 
-    "cname": "target.example.com."
-    "cname": "www"
+    "target.example.com."
+    "www"
 
 
 The target will have the current zone name appended if it's not a FQDN (since v2.2.0).
 The target will have the current zone name appended if it's not a FQDN (since v2.2.0).
 
 
@@ -197,9 +201,9 @@ record should be returned.
 
 
 The `preference` is the MX record preference returned to the client.
 The `preference` is the MX record preference returned to the client.
 
 
-    "mx": { "mx": "foo.example.com" }
-    "mx": { "mx": "foo.example.com", "weight": 100 }
-    "mx": { "mx": "foo.example.com", "weight": 100, "preference": 10 }
+    { "mx": "foo.example.com" }
+    { "mx": "foo.example.com", "weight": 100 }
+    { "mx": "foo.example.com", "weight": 100, "preference": 10 }
 
 
 `weight` and `preference` are optional.
 `weight` and `preference` are optional.
 
 
@@ -208,14 +212,23 @@ The `preference` is the MX record preference returned to the client.
 NS records for the label, use it on the top level empty label (`""`) to specify
 NS records for the label, use it on the top level empty label (`""`) to specify
 the nameservers for the domain.
 the nameservers for the domain.
 
 
-    "ns": [ "ns1.example.com", "ns2.example.com" ]
+    [ "ns1.example.com", "ns2.example.com" ]
 
 
 There's an alternate legacy syntax that has space for glue records (IPv4 addresses),
 There's an alternate legacy syntax that has space for glue records (IPv4 addresses),
 but in GeoDNS the values in the object are ignored so the list syntax above is
 but in GeoDNS the values in the object are ignored so the list syntax above is
 recommended.
 recommended.
 
 
-    "ns": { "ns1.example.net.": null, "ns2.example.net.": null }
+    { "ns1.example.net.": null, "ns2.example.net.": null }
 
 
+### TXT
+
+Simple syntax
+
+    "Some text"
+
+Or with weights
+
+    { "txt": "Some text", "weight": 10 }
 
 
 ## License and Copyright
 ## License and Copyright
 
 

+ 5 - 1
dns/test.example.com.json

@@ -16,10 +16,14 @@
     "europe": { "mx": [ { "mx": "mx-eu.example.net" }]},
     "europe": { "mx": [ { "mx": "mx-eu.example.net" }]},
     "foo": {
     "foo": {
       "a": [ [ "192.168.1.2", 10 ], [ "192.168.1.3", 10 ], [ "192.168.1.4", 10 ] ],
       "a": [ [ "192.168.1.2", 10 ], [ "192.168.1.3", 10 ], [ "192.168.1.4", 10 ] ],
-      "aaaa": [ ["fd06:c1d3:e902::2", 10], ["fd06:c1d3:e902:202:a5ff:fecd:13a6:a", 10], ["fd06:c1d3:e902::4", 10] ]
+      "aaaa": [ ["fd06:c1d3:e902::2", 10], ["fd06:c1d3:e902:202:a5ff:fecd:13a6:a", 10], ["fd06:c1d3:e902::4", 10] ],
+      "txt": "this is foo"
     },
     },
     "weight": {
     "weight": {
       "a": [ [ "192.168.1.2", 100 ], [ "192.168.1.3", 50 ], [ "192.168.1.4", 25 ] ],
       "a": [ [ "192.168.1.2", 100 ], [ "192.168.1.3", 50 ], [ "192.168.1.4", 25 ] ],
+      "txt": [ { "txt": "w1000", "weight": 1000 },
+               { "txt": "w1",   "weight": 1 }
+             ],
       "max_hosts": "1"
       "max_hosts": "1"
     },
     },
     "bar": {
     "bar": {

+ 10 - 0
zone_test.go

@@ -45,6 +45,16 @@ func (s *ConfigSuite) TestExampleComZone(c *C) {
 	c.Check(Ns[0].RR.(*dns.NS).Ns, Equals, "ns1.example.net.")
 	c.Check(Ns[0].RR.(*dns.NS).Ns, Equals, "ns1.example.net.")
 	c.Check(Ns[1].RR.(*dns.NS).Ns, Equals, "ns2.example.net.")
 	c.Check(Ns[1].RR.(*dns.NS).Ns, Equals, "ns2.example.net.")
 
 
+	label, qtype = ex.findLabels("foo", "", qTypes{dns.TypeTXT})
+	Txt := label.Records[dns.TypeTXT]
+	c.Check(Txt, HasLen, 1)
+	c.Check(Txt[0].RR.(*dns.TXT).Txt[0], Equals, "this is foo")
+
+	label, qtype = ex.findLabels("weight", "", qTypes{dns.TypeTXT})
+	Txt = label.Records[dns.TypeTXT]
+	c.Check(Txt, HasLen, 2)
+	c.Check(Txt[0].RR.(*dns.TXT).Txt[0], Equals, "w1000")
+	c.Check(Txt[1].RR.(*dns.TXT).Txt[0], Equals, "w1")
 }
 }
 
 
 func (s *ConfigSuite) TestExampleOrgZone(c *C) {
 func (s *ConfigSuite) TestExampleOrgZone(c *C) {

+ 30 - 2
zones.go

@@ -206,10 +206,11 @@ func setupZoneData(data map[string]interface{}, Zone *Zone) {
 	recordTypes := map[string]uint16{
 	recordTypes := map[string]uint16{
 		"a":     dns.TypeA,
 		"a":     dns.TypeA,
 		"aaaa":  dns.TypeAAAA,
 		"aaaa":  dns.TypeAAAA,
-		"ns":    dns.TypeNS,
+		"alias": dns.TypeMF,
 		"cname": dns.TypeCNAME,
 		"cname": dns.TypeCNAME,
 		"mx":    dns.TypeMX,
 		"mx":    dns.TypeMX,
-		"alias": dns.TypeMF,
+		"ns":    dns.TypeNS,
+		"txt":   dns.TypeTXT,
 	}
 	}
 
 
 	for dk, dv_inter := range data {
 	for dk, dv_inter := range data {
@@ -372,6 +373,33 @@ func setupZoneData(data map[string]interface{}, Zone *Zone) {
 
 
 					record.RR = rr
 					record.RR = rr
 
 
+				case dns.TypeTXT:
+					rec := records[rType][i]
+
+					var txt string
+
+					switch rec.(type) {
+					case string:
+						txt = rec.(string)
+					case map[string]interface{}:
+
+						recmap := rec.(map[string]interface{})
+
+						if weight, ok := recmap["weight"]; ok {
+							record.Weight = valueToInt(weight)
+						}
+						if t, ok := recmap["txt"]; ok {
+							txt = t.(string)
+						}
+					}
+					if len(txt) > 0 {
+						rr := &dns.TXT{Hdr: h, Txt: []string{txt}}
+						record.RR = rr
+					} else {
+						log.Printf("Zero length txt record for '%s' in '%s'\n", label.Label, Zone.Origin)
+						continue
+					}
+
 				default:
 				default:
 					log.Println("type:", rType)
 					log.Println("type:", rType)
 					panic("Don't know how to handle this type")
 					panic("Don't know how to handle this type")