133 lines
3.0 KiB
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
|
|
}
|