Gotify rejects a Grafana payload with 400 "Field 'message' is required", so a translation step is mandatory. This adds a small standard-library Python service: it accepts Grafana's JSON, builds a Gotify message, and posts it with an app token. Mapping: firing -> priority 8, title "[FIRING] <alertname>" resolved -> priority 3, title "[RESOLVED] <alertname>" body -> the summary annotation plus severity, namespace, pod, instance, job A multi-alert notification names the alert count instead of dropping the rest. The script ships as a ConfigMap so no image build is needed. The app token comes from a SOPS secret and belongs to Gotify application `grafana`.
81 lines
2.2 KiB
YAML
81 lines
2.2 KiB
YAML
# Grafana sends its own JSON and Gotify rejects it, so this Deployment is the
|
|
# translation step between them. Grafana posts to the Service, the bridge posts
|
|
# to /message with the app token from a SOPS secret.
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: grafana-gotify-bridge
|
|
namespace: notifications
|
|
labels:
|
|
app: grafana-gotify-bridge
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: grafana-gotify-bridge
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: grafana-gotify-bridge
|
|
spec:
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 65534
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
containers:
|
|
- name: bridge
|
|
image: python:3.12-alpine
|
|
command: ["python3", "/app/grafana_gotify_bridge.py"]
|
|
env:
|
|
- name: GOTIFY_URL
|
|
value: "http://gotify.notifications.svc.cluster.local"
|
|
- name: PORT
|
|
value: "8080"
|
|
- name: GOTIFY_TOKEN
|
|
valueFrom:
|
|
secretKeyRef: {name: grafana-gotify-bridge, key: app-token}
|
|
ports:
|
|
- name: http
|
|
containerPort: 8080
|
|
readinessProbe:
|
|
httpGet: {path: /, port: http}
|
|
initialDelaySeconds: 3
|
|
periodSeconds: 10
|
|
livenessProbe:
|
|
httpGet: {path: /, port: http}
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 20
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: true
|
|
capabilities:
|
|
drop: ["ALL"]
|
|
volumeMounts:
|
|
- name: script
|
|
mountPath: /app
|
|
readOnly: true
|
|
resources:
|
|
requests: {cpu: 10m, memory: 32Mi}
|
|
limits: {cpu: 200m, memory: 96Mi}
|
|
volumes:
|
|
- name: script
|
|
configMap:
|
|
name: grafana-gotify-bridge
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: grafana-gotify-bridge
|
|
namespace: notifications
|
|
labels:
|
|
app: grafana-gotify-bridge
|
|
spec:
|
|
type: ClusterIP
|
|
selector:
|
|
app: grafana-gotify-bridge
|
|
ports:
|
|
- name: http
|
|
port: 8080
|
|
targetPort: http
|