2022-10-09 14:19:48 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2022-10-09 19:50:46 +02:00
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2022-10-09 14:19:48 +02:00
|
|
|
"net/http"
|
|
|
|
"strings"
|
2022-10-09 19:50:46 +02:00
|
|
|
"time"
|
2022-10-09 14:19:48 +02:00
|
|
|
|
|
|
|
"git.xenrox.net/~xenrox/go-log"
|
2022-10-09 19:50:46 +02:00
|
|
|
"golang.org/x/text/cases"
|
|
|
|
"golang.org/x/text/language"
|
2022-10-09 14:19:48 +02:00
|
|
|
)
|
|
|
|
|
2022-10-09 19:50:46 +02:00
|
|
|
type receiver struct {
|
|
|
|
logger *log.Logger
|
|
|
|
}
|
|
|
|
|
|
|
|
type payload struct {
|
|
|
|
Status string `json:"status"`
|
|
|
|
Alerts []alert `json:"alerts"`
|
|
|
|
GroupLabels map[string]interface{} `json:"groupLabels"`
|
|
|
|
CommonLabels map[string]interface{} `json:"commonLabels"`
|
|
|
|
CommonAnnotations map[string]interface{} `json:"commonAnnotations"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type alert struct {
|
|
|
|
Status string `json:"status"`
|
|
|
|
Labels map[string]interface{} `json:"labels"`
|
|
|
|
Annotations map[string]interface{} `json:"annotations"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (rcv *receiver) handleWebhooks(w http.ResponseWriter, r *http.Request) {
|
|
|
|
defer r.Body.Close()
|
|
|
|
|
|
|
|
var event payload
|
|
|
|
if err := json.NewDecoder(r.Body).Decode(&event); err != nil {
|
|
|
|
rcv.logger.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
count := len(event.Alerts)
|
|
|
|
title := fmt.Sprintf("[%s", strings.ToUpper(event.Status))
|
|
|
|
if event.Status == "firing" {
|
|
|
|
title = fmt.Sprintf("%s:%d", title, count)
|
|
|
|
}
|
|
|
|
|
|
|
|
title += "]"
|
|
|
|
for _, value := range event.GroupLabels {
|
|
|
|
title = fmt.Sprintf("%s %s", title, value)
|
|
|
|
}
|
|
|
|
|
|
|
|
var body string
|
|
|
|
c := cases.Title(language.English)
|
|
|
|
|
|
|
|
for _, alert := range event.Alerts {
|
|
|
|
alertBody := fmt.Sprintf("%s\nLabels:\n", c.String(alert.Status))
|
|
|
|
for key, value := range alert.Labels {
|
|
|
|
alertBody = fmt.Sprintf("%s%s = %s\n", alertBody, key, value)
|
|
|
|
}
|
|
|
|
|
|
|
|
alertBody += "Annotations:\n"
|
|
|
|
for key, value := range alert.Annotations {
|
|
|
|
alertBody = fmt.Sprintf("%s%s = %s\n", alertBody, key, value)
|
|
|
|
}
|
|
|
|
|
|
|
|
alertBody += "\n"
|
|
|
|
|
|
|
|
body += alertBody
|
|
|
|
}
|
|
|
|
|
|
|
|
client := &http.Client{Timeout: time.Second * 3}
|
|
|
|
url := "https://ntfy.sh/alertmanager_test"
|
|
|
|
req, err := http.NewRequest(http.MethodPost, url, strings.NewReader(body))
|
|
|
|
if err != nil {
|
|
|
|
rcv.logger.Error(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
req.Header.Set("X-Title", title)
|
|
|
|
resp, err := client.Do(req)
|
|
|
|
if err != nil {
|
|
|
|
rcv.logger.Error(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
|
|
rcv.logger.Error("ntfy: received status code %d", resp.StatusCode)
|
|
|
|
}
|
2022-10-09 14:19:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
logger := log.NewDefaultLogger()
|
|
|
|
|
2022-10-09 19:50:46 +02:00
|
|
|
receiver := &receiver{logger: logger}
|
|
|
|
|
|
|
|
http.HandleFunc("/", receiver.handleWebhooks)
|
2022-10-09 14:19:48 +02:00
|
|
|
logger.Fatal(http.ListenAndServe("127.0.0.1:8080", nil))
|
|
|
|
}
|