refactor configuration format to allow multiple checks

This commit is contained in:
Kegan Myers 2015-08-22 19:35:33 -05:00
parent 619bb2e023
commit b7609e24da
7 changed files with 60 additions and 41 deletions

19
main.go
View file

@ -17,14 +17,21 @@ func main() {
c := monitor.Config{}
json.Unmarshal(file, &c)
handlers := make([]monitor.GenericHandler, 2)
handlers[0] = monitor.NewLogHandler()
handlers[1] = monitor.NewCloudflareHandler(c.Cloudflare)
for _, check := range c.Checks {
handlers := make([]*monitor.GenericHandler, 0)
engine := monitor.CreateEngine(handlers)
for _, reaction := range check.Reactions {
handler := monitor.CreateHandler(reaction)
for _, endpoint := range c.Hosts {
monitor.CreateCheck(c.Interval, engine, endpoint)
if handler == nil {
continue
}
handlers = append(handlers, handler)
}
engine := monitor.CreateEngine(handlers)
monitor.CreateCheck(check.Interval, engine, check.Target)
}
select{}

View file

@ -6,16 +6,20 @@ import (
"fmt"
)
func NewCloudflareHandler(config CloudflareConfig) GenericHandler {
func newCloudflareHandler(config ReactionConfig) *GenericHandler {
if config.Options["email"] == "" || config.Options["apiKey"] == "" || config.Options["domain"] == "" || config.Options["name"] == "" || config.Options["ttl"] == "" {
log.Fatal(fmt.Sprintf("Misconfigured cloudflare handler: %#v", config))
}
return runHandler(make(chan Transition, 5), &cloudflareHandler{
config,
cloudflare.NewClient(config.Email, config.ApiKey),
cloudflare.NewClient(config.Options["email"], config.Options["apiKey"]),
make(map[string]bool),
})
}
type cloudflareHandler struct{
config CloudflareConfig
config ReactionConfig
client *cloudflare.Client
actuallyDownHosts map[string]bool
}
@ -26,20 +30,20 @@ func (this *cloudflareHandler) handle(transition Transition) {
log.Print(fmt.Sprintf(
"Removed cloudflare record for `%s`: `%v`\n",
transition.RecordValue,
removeCloudflareRecord(this.client, this.config, transition.RecordValue)))
this.removeCloudflareRecord(transition.RecordValue)))
case Up:
log.Print(fmt.Sprintf(
"Added cloudflare record for `%s`: `%v`\n",
transition.RecordValue,
addCloudflareRecord(this.client, this.config, transition.RecordValue)))
this.addCloudflareRecord(transition.RecordValue)))
case Unknown: //just leave it how it was, going up/down is idempotent anyways
}
}
func removeCloudflareRecord(client *cloudflare.Client, config CloudflareConfig, recordValue string) bool {
records, err := client.RetrieveRecordsByName(config.Domain, config.Name)
func (this *cloudflareHandler) removeCloudflareRecord(recordValue string) bool {
records, err := this.client.RetrieveRecordsByName(this.config.Options["Domain"], this.config.Options["Name"])
if err != nil {
return false
@ -51,22 +55,22 @@ func removeCloudflareRecord(client *cloudflare.Client, config CloudflareConfig,
continue
}
exitStatus = exitStatus && client.DestroyRecord(config.Domain, record.Id) == nil
exitStatus = exitStatus && this.client.DestroyRecord(this.config.Options["domain"], record.Id) == nil
}
return exitStatus
}
func addCloudflareRecord(client *cloudflare.Client, config CloudflareConfig, recordValue string) bool {
func (this *cloudflareHandler) addCloudflareRecord(recordValue string) bool {
opts := cloudflare.CreateRecord{
"A",
config.Name,
this.config.Options["name"],
recordValue,
"1",
"0",
}
_, err := client.CreateRecord(config.Domain, &opts)
_, err := this.client.CreateRecord(this.config.Options["domain"], &opts)
if err != nil {
return fmt.Sprintf("%s", err) == "API Error: The record already exists."

View file

@ -1,21 +1,22 @@
package monitor
type HostConfig struct {
Host string
type Config struct {
Checks []CheckConfig
}
type CheckConfig struct {
Interval uint16
Target TargetConfig
Reactions []ReactionConfig
}
type TargetConfig struct {
Type string
Host string
Options map[string]string
}
type CloudflareConfig struct {
Email string
ApiKey string
Domain string
Name string
Ttl string
}
type Config struct {
Cloudflare CloudflareConfig
Hosts []HostConfig
Interval uint16
type ReactionConfig struct {
Type string
Options map[string]string
}

View file

@ -10,7 +10,7 @@ import (
type checkConfig struct {
engine *Engine
interval time.Duration
host HostConfig
host TargetConfig
}
type httpChecker struct {
@ -57,7 +57,7 @@ func newHttpChecker(config checkConfig) *httpChecker {
return &checker
}
func CreateCheck(interval uint16, engine *Engine, host HostConfig) {
func CreateCheck(interval uint16, engine *Engine, host TargetConfig) {
config := checkConfig{
engine,
time.Duration(int64(interval)) * time.Second,

View file

@ -1,14 +1,11 @@
package monitor
import (
)
type Engine struct {
Input chan Result
output []GenericHandler
output []*GenericHandler
}
func CreateEngine(handlers []GenericHandler) *Engine {
func CreateEngine(handlers []*GenericHandler) *Engine {
input := make(chan Result)
engine := Engine{

View file

@ -8,13 +8,23 @@ type GenericHandler struct {
channel chan Transition
}
func runHandler(input chan Transition, handler handler) GenericHandler {
func runHandler(input chan Transition, handler handler) *GenericHandler {
go func() {
for true {
handler.handle(<-input)
}
}()
return GenericHandler{
return &GenericHandler{
input,
}
}
func CreateHandler(handler ReactionConfig) *GenericHandler {
switch handler.Type {
case "cloudflare":
return newCloudflareHandler(handler)
case "log":
return newLogHandler(handler)
}
return nil
}

View file

@ -5,7 +5,7 @@ import (
"log"
)
func NewLogHandler() GenericHandler {
func newLogHandler(config ReactionConfig) *GenericHandler {
return runHandler(make(chan Transition), &logHandler{})
}