Files
p/main.go

159 lines
3.0 KiB
Go
Raw Normal View History

2024-11-21 14:59:10 -08:00
package main
import (
2024-11-21 21:42:03 -08:00
"bytes"
"encoding/json"
2024-11-21 14:59:10 -08:00
"fmt"
2024-11-22 15:01:49 -08:00
"html/template"
2024-11-21 21:42:03 -08:00
"io"
"log"
2024-11-21 14:59:10 -08:00
"net/http"
"os"
2024-11-22 15:01:49 -08:00
"strings"
2024-11-21 14:59:10 -08:00
)
2024-11-21 21:42:03 -08:00
type PDAlert struct {
RoutingKey string `json:"routing_key"`
EventAction string `json:"event_action"`
Payload PDPayload `json:"payload"`
}
type PDPayload struct {
Summary string `json:"summary"`
Source string `json:"source"`
Severity string `json:"severity"`
}
type PHandler struct {
2024-11-22 15:01:49 -08:00
tmpl *template.Template
2024-11-22 13:49:31 -08:00
routingKey string
2024-11-21 21:42:03 -08:00
}
2024-11-22 15:01:49 -08:00
func NewPHandler(routingKey string) (*PHandler, error) {
tmpl := template.New("index.html")
tmpl.Funcs(template.FuncMap{
"replaceAll": func(o, n, s string) string { return strings.ReplaceAll(s, o, n) },
})
tmpl, err := tmpl.ParseFiles("static/index.html")
if err != nil {
return nil, fmt.Errorf("static/index.html: %w", err)
}
2024-11-21 21:42:03 -08:00
return &PHandler{
2024-11-22 15:01:49 -08:00
tmpl: tmpl,
2024-11-22 13:49:31 -08:00
routingKey: routingKey,
2024-11-22 15:01:49 -08:00
}, nil
2024-11-21 21:42:03 -08:00
}
func (ph *PHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
http.Error(w, fmt.Sprintf("invalid form: %s\n", err), http.StatusBadRequest)
return
}
2024-11-22 13:49:31 -08:00
log.Printf("%s %s", r.RemoteAddr, r.Form.Encode())
2024-11-21 21:42:03 -08:00
msg := r.Form.Get("msg")
if msg == "" {
2024-11-22 15:01:49 -08:00
err = ph.tmpl.Execute(w, ph.envs())
if err != nil {
http.Error(w, fmt.Sprintf("execute %s: %s\n", ph.tmpl.Name(), err), http.StatusBadRequest)
return
}
2024-11-21 21:42:03 -08:00
return
}
2024-11-21 14:59:10 -08:00
2024-11-21 21:42:03 -08:00
buf := &bytes.Buffer{}
err = json.NewEncoder(buf).Encode(PDAlert{
2024-11-22 13:49:31 -08:00
RoutingKey: ph.routingKey,
2024-11-21 21:42:03 -08:00
EventAction: "trigger",
Payload: PDPayload{
Summary: msg,
2024-11-22 13:49:31 -08:00
Source: r.RemoteAddr,
2024-11-21 21:42:03 -08:00
Severity: "critical",
},
})
if err != nil {
http.Error(w, fmt.Sprintf("failed to create PD request: %s\n", err), http.StatusBadRequest)
return
}
req, err := http.NewRequest("POST", "https://events.pagerduty.com/v2/enqueue", buf)
if err != nil {
http.Error(w, fmt.Sprintf("failed to create HTTP request: %s\n", err), http.StatusBadRequest)
return
}
c := &http.Client{}
res, err := c.Do(req)
if err != nil {
http.Error(w, fmt.Sprintf("error from PD: %s\n", err), http.StatusBadRequest)
2024-11-22 15:01:49 -08:00
return
2024-11-21 21:42:03 -08:00
}
body, _ := io.ReadAll(res.Body)
res.Body.Close()
if res.StatusCode != 202 {
http.Error(w, fmt.Sprintf("error from PD: %s", string(body)), http.StatusBadRequest)
2024-11-22 15:01:49 -08:00
return
2024-11-21 21:42:03 -08:00
}
2024-11-22 15:01:49 -08:00
2024-11-21 21:42:03 -08:00
w.Write([]byte("page sent\n"))
}
2024-11-22 15:01:49 -08:00
var allowedEnvs = []string{
2024-11-22 22:09:29 -08:00
"SHORT_NAME",
"CONTACT_NAME",
2024-11-22 15:01:49 -08:00
"CONTACT_PHONE",
2024-11-22 21:14:28 -08:00
"CONTACT_SMS",
"CONTACT_IMESSAGE",
"CONTACT_WHATSAPP",
"CONTACT_PAGE_EMAIL",
2024-11-22 15:01:49 -08:00
}
func (ph *PHandler) envs() map[string]string {
envs := map[string]string{}
for _, k := range allowedEnvs {
v := os.Getenv(k)
if v != "" {
envs[k] = v
}
}
return envs
}
2024-11-21 21:42:03 -08:00
func main() {
2024-11-22 13:49:31 -08:00
routingKey := os.Getenv("PD_ROUTING_KEY")
if routingKey == "" {
log.Fatalf("please set PD_ROUTING_KEY")
}
2024-11-22 15:01:49 -08:00
ph, err := NewPHandler(routingKey)
if err != nil {
log.Fatalf("NewPHandler: %s", err)
}
http.Handle("/", ph)
2024-11-21 14:59:10 -08:00
port := os.Getenv("PORT")
if port == "" {
port = "80"
}
2024-11-21 21:42:03 -08:00
bind := fmt.Sprintf(":%s", port)
log.Printf("listening on %s", bind)
2024-11-21 14:59:10 -08:00
2024-11-21 21:42:03 -08:00
if err := http.ListenAndServe(bind, nil); err != nil {
2024-11-22 13:49:31 -08:00
log.Fatalf("listen: %s", err)
2024-11-21 14:59:10 -08:00
}
}