2015-08-23 03:20:58 +00:00
|
|
|
package handlers
|
2015-08-21 17:27:26 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"../cloudflare"
|
2015-08-23 03:20:58 +00:00
|
|
|
"../core"
|
2015-08-21 17:27:26 +00:00
|
|
|
"log"
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
2015-08-23 03:20:58 +00:00
|
|
|
func NewCloudflareHandler(config core.ReactionConfig) *core.GenericHandler {
|
2015-08-23 00:35:33 +00:00
|
|
|
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))
|
|
|
|
}
|
|
|
|
|
2015-08-23 03:20:58 +00:00
|
|
|
return core.NewGenericHandler(make(chan core.Transition, 5), &cloudflareHandler{
|
2015-08-21 17:27:26 +00:00
|
|
|
config,
|
2015-08-23 00:35:33 +00:00
|
|
|
cloudflare.NewClient(config.Options["email"], config.Options["apiKey"]),
|
2015-08-21 17:27:26 +00:00
|
|
|
make(map[string]bool),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
type cloudflareHandler struct{
|
2015-08-23 03:20:58 +00:00
|
|
|
config core.ReactionConfig
|
2015-08-21 17:27:26 +00:00
|
|
|
client *cloudflare.Client
|
|
|
|
actuallyDownHosts map[string]bool
|
|
|
|
}
|
|
|
|
|
2015-08-23 03:20:58 +00:00
|
|
|
func (this *cloudflareHandler) Handle(transition core.Transition) {
|
2015-08-21 17:27:26 +00:00
|
|
|
switch transition.To {
|
2015-08-23 03:20:58 +00:00
|
|
|
case core.Down:
|
2015-08-21 17:27:26 +00:00
|
|
|
log.Print(fmt.Sprintf(
|
|
|
|
"Removed cloudflare record for `%s`: `%v`\n",
|
|
|
|
transition.RecordValue,
|
2015-08-23 00:35:33 +00:00
|
|
|
this.removeCloudflareRecord(transition.RecordValue)))
|
2015-08-21 17:27:26 +00:00
|
|
|
|
2015-08-23 03:20:58 +00:00
|
|
|
case core.Up:
|
2015-08-21 17:27:26 +00:00
|
|
|
log.Print(fmt.Sprintf(
|
|
|
|
"Added cloudflare record for `%s`: `%v`\n",
|
|
|
|
transition.RecordValue,
|
2015-08-23 00:35:33 +00:00
|
|
|
this.addCloudflareRecord(transition.RecordValue)))
|
2015-08-21 17:27:26 +00:00
|
|
|
|
2015-08-23 03:20:58 +00:00
|
|
|
case core.Unknown: //just leave it how it was, going up/down is idempotent anyways
|
2015-08-21 17:27:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-24 05:28:45 +00:00
|
|
|
func (this *cloudflareHandler) Stop() bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2015-08-23 00:35:33 +00:00
|
|
|
func (this *cloudflareHandler) removeCloudflareRecord(recordValue string) bool {
|
|
|
|
records, err := this.client.RetrieveRecordsByName(this.config.Options["Domain"], this.config.Options["Name"])
|
2015-08-21 17:27:26 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
exitStatus := true
|
|
|
|
for _, record := range records {
|
|
|
|
if record.Value != recordValue {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2015-08-23 00:35:33 +00:00
|
|
|
exitStatus = exitStatus && this.client.DestroyRecord(this.config.Options["domain"], record.Id) == nil
|
2015-08-21 17:27:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return exitStatus
|
|
|
|
}
|
|
|
|
|
2015-08-23 00:35:33 +00:00
|
|
|
func (this *cloudflareHandler) addCloudflareRecord(recordValue string) bool {
|
2015-08-21 17:27:26 +00:00
|
|
|
opts := cloudflare.CreateRecord{
|
|
|
|
"A",
|
2015-08-23 00:35:33 +00:00
|
|
|
this.config.Options["name"],
|
2015-08-21 17:27:26 +00:00
|
|
|
recordValue,
|
|
|
|
"1",
|
|
|
|
"0",
|
|
|
|
}
|
|
|
|
|
2015-08-23 00:35:33 +00:00
|
|
|
_, err := this.client.CreateRecord(this.config.Options["domain"], &opts)
|
2015-08-21 17:27:26 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Sprintf("%s", err) == "API Error: The record already exists."
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|