Переглянути джерело

Basic support of external health data

Ask Bjørn Hansen 8 роки тому
батько
коміт
48d6c3b058
8 змінених файлів з 39 додано та 7 видалено
  1. 3 0
      config.go
  2. 3 0
      dns/geodns.conf.sample
  3. 6 1
      geodns.go
  4. 3 4
      health/status_file.go
  5. 1 1
      health/status_test.go
  6. 1 1
      zones/picker.go
  7. 14 0
      zones/reader.go
  8. 8 0
      zones/zone_health_test.go

+ 3 - 0
config.go

@@ -30,6 +30,9 @@ type AppConfig struct {
 		MaxSize int
 		Keep    int
 	}
+	Health struct {
+		Directory string
+	}
 	Nodeping struct {
 		Token string
 	}

+ 3 - 0
dns/geodns.conf.sample

@@ -19,3 +19,6 @@ path = log/queries.log
 ; require basic HTTP authentication; not encrypted or safe over the public internet
 ; user = stats
 ; password = Aeteereun8eoth4
+
+[health]
+; directory = dns/health

+ 6 - 1
geodns.go

@@ -30,6 +30,7 @@ import (
 	"time"
 
 	"github.com/abh/geodns/applog"
+	"github.com/abh/geodns/health"
 	"github.com/abh/geodns/monitor"
 	"github.com/abh/geodns/querylog"
 	"github.com/abh/geodns/server"
@@ -38,7 +39,7 @@ import (
 )
 
 // VERSION is the current version of GeoDNS
-var VERSION string = "2.7.0"
+var VERSION string = "3.0.0"
 var buildTime string
 var gitVersion string
 
@@ -170,6 +171,10 @@ func main() {
 	// load geodns.conf config
 	configReader(configFileName)
 
+	if len(Config.Health.Directory) > 0 {
+		go health.DirectoryReader(Config.Health.Directory)
+	}
+
 	// load (and re-load) zone data
 	go configWatcher(configFileName)
 

+ 3 - 4
health/status_file.go

@@ -9,8 +9,6 @@ import (
 	"strings"
 	"sync"
 	"time"
-
-	"github.com/kr/pretty"
 )
 
 type StatusFile struct {
@@ -28,6 +26,9 @@ func NewStatusFile(filename string) *StatusFile {
 	}
 }
 
+// DirectoryReader loads (and regularly re-loads) health
+// .json files from the specified files into the default
+// health registry.
 func DirectoryReader(dir string) {
 	for {
 		err := reloadDirectory(dir)
@@ -129,8 +130,6 @@ func (s *StatusFile) GetStatus(check string) StatusType {
 		return StatusUnknown
 	}
 
-	pretty.Println(s)
-
 	st, ok := s.m[check]
 	if !ok {
 		log.Printf("Not found '%s'", check)

+ 1 - 1
health/status_test.go

@@ -3,7 +3,7 @@ package health
 import "testing"
 
 func TestStatusFile(t *testing.T) {
-	sf := NewStatusFile()
+	sf := NewStatusFile("test.json")
 	err := sf.Load("test.json")
 	if err != nil {
 		t.Fatalf("could not load test.json: %s", err)

+ 1 - 1
zones/picker.go

@@ -15,7 +15,7 @@ func (zone *Zone) filterHealth(servers Records) (Records, int) {
 
 	sum := 0
 	for i, s := range servers {
-		if len(servers[i].Test) == 0 || zone.HealthStatus.GetStatus(servers[i].Test) == health.StatusHealthy {
+		if len(servers[i].Test) == 0 || health.GetStatus(servers[i].Test) == health.StatusHealthy {
 			tmpServers = append(tmpServers, s)
 			sum += s.Weight
 		}

+ 14 - 0
zones/reader.go

@@ -317,6 +317,20 @@ func setupZoneData(data map[string]interface{}, zone *Zone) {
 						target = rec.(string)
 					case []interface{}:
 						target, weight = getStringWeight(rec.([]interface{}))
+					case map[string]interface{}:
+						r := rec.(map[string]interface{})
+
+						if t, ok := r["cname"]; ok {
+							target = typeutil.ToString(t)
+						}
+
+						if w, ok := r["weight"]; ok {
+							weight = typeutil.ToInt(w)
+						}
+
+						if h, ok := r["health"]; ok {
+							record.Test = typeutil.ToString(h)
+						}
 					}
 					if !dns.IsFqdn(target) {
 						target = target + "." + zone.Origin

+ 8 - 0
zones/zone_health_test.go

@@ -30,6 +30,14 @@ func (hs *HealthStatus) GetStatus(name string) health.StatusType {
 	return hs.status
 }
 
+func (hs *HealthStatus) Close() error {
+	return nil
+}
+
+func (hs *HealthStatus) Reload() error {
+	return nil
+}
+
 func TestHealth(t *testing.T) {
 	muxm := loadZones(t)
 	t.Log("setting up health status")