ntfy-bridge/bridge/flux.go

88 lines
2.3 KiB
Go

package bridge
import (
"encoding/json"
"fmt"
"log/slog"
"net/http"
"strings"
"time"
)
type fluxInvolvedObject struct {
Kind string `json:"kind"`
Namespace string `json:"namespace"`
Name string `json:"name"`
UID string `json:"uid"`
APIVersion string `json:"apiVersion"`
ResourceVersion string `json:"resourceVersion"`
}
func (f fluxInvolvedObject) String() string {
return strings.ToLower(f.Kind) + "/" + f.Namespace + "." + f.Name
}
type FluxNotification struct {
InvolvedObject fluxInvolvedObject `json:"involvedObject"`
Severity string `json:"severity"`
Timestamp time.Time `json:"timestamp"`
Message string `json:"message"`
Reason string `json:"reason"`
Metadata struct {
CommitStatus string `json:"commit_status"`
Revision string `json:"revision"`
Summary string `json:"summary"`
} `json:"metadata"`
ReportingController string `json:"reportingController"`
ReportingInstance string `json:"reportingInstance"`
}
type FluxHandler struct {
// Register all modifications of reconciliations
reconciliations map[string]bool
}
func NewFluxHandler() FluxHandler {
return FluxHandler{
reconciliations: make(map[string]bool),
}
}
func (f FluxHandler) ProduceNotifications(r *http.Request) ([]Notification, error) {
l := slog.With(slog.String("handler", "flux"))
dec := json.NewDecoder(r.Body)
defer r.Body.Close()
var not FluxNotification
if err := dec.Decode(&not); err != nil {
l.Error("invalid message format", "error", err)
return nil, err
}
obj := not.InvolvedObject.String()
if not.Reason == "ReconciliationSucceeded" {
if ok := f.reconciliations[obj]; !ok {
// Filter out spammy ReconciliationSucceeded notification
return nil, nil
}
// we will print the object so skip it next time it spam
f.reconciliations[obj] = false
} else {
// object has been modified, we can print it next time
f.reconciliations[obj] = true
}
title := fmt.Sprintf("[%s] %s %s", not.Severity, not.Reason, obj)
body := not.Message + "\n\n**revision**\n" + not.Metadata.Revision
l.Debug("flux notification", slog.Group("notification",
slog.String("title", title),
slog.String("body", body)))
return []Notification{{
Title: title,
Body: body,
IsMarkdown: true,
}}, nil
}