2019-09-21 22:03:26 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2019-10-01 15:26:07 +00:00
|
|
|
"bytes"
|
|
|
|
"log"
|
2019-09-21 22:03:26 +00:00
|
|
|
"os/exec"
|
|
|
|
"text/template"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2019-10-02 23:09:11 +00:00
|
|
|
// Alert is a config driven mechanism for sending a notice
|
2019-09-21 22:03:26 +00:00
|
|
|
type Alert struct {
|
|
|
|
Name string
|
|
|
|
Command []string
|
|
|
|
CommandShell string `yaml:"command_shell"`
|
2019-10-02 16:37:29 +00:00
|
|
|
commandTemplate []*template.Template
|
2019-10-01 15:26:07 +00:00
|
|
|
commandShellTemplate *template.Template
|
2019-09-21 22:03:26 +00:00
|
|
|
}
|
|
|
|
|
2019-10-02 23:09:11 +00:00
|
|
|
// AlertNotice captures the context for an alert to be sent
|
|
|
|
type AlertNotice struct {
|
|
|
|
MonitorName string
|
|
|
|
AlertCount int16
|
|
|
|
FailureCount int16
|
|
|
|
LastCheckOutput string
|
|
|
|
LastSuccess time.Time
|
|
|
|
IsUp bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsValid returns a boolean indicating if the Alert has been correctly
|
|
|
|
// configured
|
2019-09-21 22:03:26 +00:00
|
|
|
func (alert Alert) IsValid() bool {
|
|
|
|
atLeastOneCommand := (alert.CommandShell != "" || alert.Command != nil)
|
|
|
|
atMostOneCommand := (alert.CommandShell == "" || alert.Command == nil)
|
|
|
|
return atLeastOneCommand && atMostOneCommand
|
|
|
|
}
|
|
|
|
|
2019-10-02 23:09:11 +00:00
|
|
|
// BuildTemplates compiles command templates for the Alert
|
2019-09-21 22:03:26 +00:00
|
|
|
func (alert *Alert) BuildTemplates() {
|
|
|
|
if alert.commandTemplate == nil && alert.Command != nil {
|
|
|
|
// build template
|
2019-10-02 16:37:29 +00:00
|
|
|
log.Println("Building template for command...")
|
|
|
|
alert.commandTemplate = []*template.Template{}
|
|
|
|
for i, cmdPart := range alert.Command {
|
|
|
|
alert.commandTemplate = append(alert.commandTemplate, template.Must(
|
|
|
|
template.New(alert.Name+string(i)).Parse(cmdPart),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
log.Printf("Template built: %v", alert.commandTemplate)
|
2019-09-21 22:03:26 +00:00
|
|
|
} else if alert.commandShellTemplate == nil && alert.CommandShell != "" {
|
2019-10-02 16:37:29 +00:00
|
|
|
log.Println("Building template for shell command...")
|
2019-09-21 22:03:26 +00:00
|
|
|
alert.commandShellTemplate = template.Must(
|
|
|
|
template.New(alert.Name).Parse(alert.CommandShell),
|
|
|
|
)
|
2019-10-02 16:37:29 +00:00
|
|
|
log.Printf("Template built: %v", alert.commandShellTemplate)
|
2019-09-21 22:03:26 +00:00
|
|
|
} else {
|
2019-10-03 01:01:55 +00:00
|
|
|
log.Fatalf("No template provided for alert %s", alert.Name)
|
2019-09-21 22:03:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-02 23:09:11 +00:00
|
|
|
// Send will send an alert notice by executing the command template
|
|
|
|
func (alert Alert) Send(notice AlertNotice) {
|
2019-09-21 22:03:26 +00:00
|
|
|
var cmd *exec.Cmd
|
|
|
|
|
|
|
|
if alert.commandTemplate != nil {
|
|
|
|
// build template
|
2019-10-02 16:37:29 +00:00
|
|
|
log.Println("Send command thing...")
|
|
|
|
command := []string{}
|
|
|
|
for _, cmdTmp := range alert.commandTemplate {
|
|
|
|
var commandBuffer bytes.Buffer
|
|
|
|
err := cmdTmp.Execute(&commandBuffer, notice)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
command = append(command, commandBuffer.String())
|
|
|
|
}
|
|
|
|
cmd = exec.Command(command[0], command[1:]...)
|
2019-09-21 22:03:26 +00:00
|
|
|
} else if alert.commandShellTemplate != nil {
|
|
|
|
var commandBuffer bytes.Buffer
|
|
|
|
err := alert.commandShellTemplate.Execute(&commandBuffer, notice)
|
2019-10-01 15:26:07 +00:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2019-10-02 16:37:29 +00:00
|
|
|
shellCommand := commandBuffer.String()
|
2019-10-01 15:26:07 +00:00
|
|
|
|
2019-10-02 16:37:29 +00:00
|
|
|
log.Printf("About to run alert command: %s", shellCommand)
|
|
|
|
cmd = ShellCommand(shellCommand)
|
2019-09-21 22:03:26 +00:00
|
|
|
} else {
|
2019-10-02 16:37:29 +00:00
|
|
|
panic("No template compiled?")
|
|
|
|
}
|
|
|
|
|
|
|
|
output, err := cmd.CombinedOutput()
|
|
|
|
log.Printf("Check %s\n---\n%s\n---", alert.Name, string(output))
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
2019-09-21 22:03:26 +00:00
|
|
|
}
|
|
|
|
}
|