sensu-telegram-handler/main.go

133 lines
3.0 KiB
Go

package main
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"text/template"
"github.com/sensu/sensu-go/types"
"github.com/spf13/cobra"
"github.com/go-telegram-bot-api/telegram-bot-api"
)
var (
token string
channel int64
subject string
hookout bool
bodyTemplateFile string
stdin *os.File
emailSubjectTemplate = "Sensu Alert - {{.Entity.Name}}/{{.Check.Name}}: {{.Check.State}}"
emailBodyTemplate = "{{.Check.Output}}"
)
func main() {
cmd := &cobra.Command{
Use: "sensu-telegram-handler",
Short: "The Sensu Go Telegram handler for sending an email notification",
RunE: run,
}
cmd.Flags().StringVarP(&token, "token", "t", "", "the telegram bot token")
cmd.Flags().Int64VarP(&channel, "channel", "c", -1, "The channel")
cmd.Flags().BoolVarP(&hookout, "hookout", "H", false, "Include output from check hook(s)")
cmd.Flags().StringVarP(&bodyTemplateFile, "bodyTemplateFile", "T", "", "A template file to use for the body")
cmd.Execute()
}
func run(cmd *cobra.Command, args []string) error {
validationError := checkArgs()
if validationError != nil {
return validationError
}
if stdin == nil {
stdin = os.Stdin
}
eventJSON, err := ioutil.ReadAll(stdin)
if err != nil {
return fmt.Errorf("failed to read stdin: %s", err)
}
event := &types.Event{}
err = json.Unmarshal(eventJSON, event)
if err != nil {
return fmt.Errorf("failed to unmarshal stdin data: %s", err)
}
if err = event.Validate(); err != nil {
return fmt.Errorf("failed to validate event: %s", err)
}
if !event.HasCheck() {
return fmt.Errorf("event does not contain check")
}
sendMsg(event)
return nil
}
func checkArgs() error {
if hookout && len(bodyTemplateFile) > 0 {
return errors.New("--hookout (-H) and --bodyTemplateFile (-T) are mutually exclusive")
}
if hookout {
emailBodyTemplate = "{{.Check.Output}}\n{{range .Check.Hooks}}Hook Name: {{.Name}}\nHook Command: {{.Command}}\n\n{{.Output}}\n\n{{end}}"
} else if len(bodyTemplateFile) > 0 {
templateBytes, fileErr := ioutil.ReadFile(bodyTemplateFile)
if fileErr != nil {
return fmt.Errorf("failed to read specified template file %s", bodyTemplateFile)
}
emailBodyTemplate = string(templateBytes)
}
return nil
}
func sendMsg(event *types.Event) error {
var output string
bot, botErr := tgbotapi.NewBotAPI(token)
if botErr != nil {
return botErr
}
subject, subjectErr := resolveTemplate(emailSubjectTemplate, event)
if subjectErr != nil {
return subjectErr
}
body, bodyErr := resolveTemplate(emailBodyTemplate, event)
if bodyErr != nil {
return bodyErr
}
output = fmt.Sprintf("%s, %s",subject,body)
msg := tgbotapi.NewMessage(channel, output)
_, sendErr := bot.Send(msg)
return sendErr
}
func resolveTemplate(templateValue string, event *types.Event) (string, error) {
var resolved bytes.Buffer
tmpl, err := template.New("test").Parse(templateValue)
if err != nil {
panic(err)
}
err = tmpl.Execute(&resolved, *event)
if err != nil {
panic(err)
}
return resolved.String(), nil
}