Browse Source

Add per-zone targeting configuration

Ask Bjørn Hansen 12 years ago
parent
commit
18f8f3b7b2
4 changed files with 106 additions and 4 deletions
  1. 60 0
      targeting.go
  2. 34 0
      targeting_test.go
  3. 6 4
      zone.go
  4. 6 0
      zones.go

+ 60 - 0
targeting.go

@@ -0,0 +1,60 @@
+package main
+
+import (
+	"fmt"
+	"strings"
+	// "github.com/abh/geodns/countries"
+)
+
+type TargetOptions int
+
+const (
+	TargetGlobal = 1 << iota
+	TargetContinent
+	TargetCountry
+	TargetRegionGroup
+	TargetRegion
+)
+
+func (t TargetOptions) String() string {
+	targets := make([]string, 0)
+	if t&TargetGlobal > 0 {
+		targets = append(targets, "@")
+	}
+	if t&TargetContinent > 0 {
+		targets = append(targets, "continent")
+	}
+	if t&TargetCountry > 0 {
+		targets = append(targets, "country")
+	}
+	if t&TargetRegionGroup > 0 {
+		targets = append(targets, "regiongroup")
+	}
+	if t&TargetRegion > 0 {
+		targets = append(targets, "region")
+	}
+	return strings.Join(targets, " ")
+}
+
+func parseTargets(v string) (tgt TargetOptions, err error) {
+	targets := strings.Split(v, " ")
+	for _, t := range targets {
+		var x TargetOptions
+		switch t {
+		case "@":
+			x = TargetGlobal
+		case "country":
+			x = TargetCountry
+		case "continent":
+			x = TargetContinent
+		case "regiongroup":
+			x = TargetRegionGroup
+		case "region":
+			x = TargetRegion
+		default:
+			err = fmt.Errorf("Unknown targeting option '%s'", t)
+		}
+		tgt = tgt | x
+	}
+	return
+}

+ 34 - 0
targeting_test.go

@@ -0,0 +1,34 @@
+package main
+
+import (
+	. "launchpad.net/gocheck"
+)
+
+type TargetingSuite struct {
+}
+
+var _ = Suite(&TargetingSuite{})
+
+func (s *TargetingSuite) SetUpSuite(c *C) {
+}
+
+func (s *TargetingSuite) TestTargetString(c *C) {
+	var tgt TargetOptions
+	tgt = TargetGlobal + TargetCountry + TargetContinent
+
+	str := tgt.String()
+	c.Check(str, Equals, "@ continent country")
+}
+
+func (s *TargetingSuite) TestTargetParse(c *C) {
+
+	tgt, err := parseTargets("@ foo country")
+	str := tgt.String()
+	c.Check(str, Equals, "@ country")
+	c.Check(err.Error(), Equals, "Unknown targeting option 'foo'")
+
+	tgt, err = parseTargets("@ continent country")
+	c.Assert(err, IsNil)
+	str = tgt.String()
+	c.Check(str, Equals, "@ continent country")
+}

+ 6 - 4
zone.go

@@ -8,10 +8,11 @@ import (
 )
 
 type ZoneOptions struct {
-	Serial   int
-	Ttl      int
-	MaxHosts int
-	Contact  string
+	Serial    int
+	Ttl       int
+	MaxHosts  int
+	Contact   string
+	Targeting TargetOptions
 }
 
 type ZoneLogging struct {
@@ -72,6 +73,7 @@ func NewZone(name string) *Zone {
 	zone.Options.Ttl = 120
 	zone.Options.MaxHosts = 2
 	zone.Options.Contact = "support.bitnames.com"
+	zone.Options.Targeting = TargetGlobal + TargetCountry + TargetContinent
 
 	return zone
 }

+ 6 - 0
zones.go

@@ -168,6 +168,12 @@ func readZoneFile(zoneName, fileName string) (zone *Zone, zerr error) {
 				zone.Options.Contact = v.(string)
 			case "max_hosts":
 				zone.Options.MaxHosts = valueToInt(v)
+			case "targeting":
+				zone.Options.Targeting, err = parseTargets(v.(string))
+				if err != nil {
+					log.Printf("Could not parse targeting '%s': %s", v, err)
+					return nil, err
+				}
 			}
 		case "logging":
 			{