From 72ec3e2477a5890e61366f6f76440459e7831aaf Mon Sep 17 00:00:00 2001 From: Jose Henrique Date: Sat, 16 Aug 2025 21:53:37 -0300 Subject: [PATCH] haven notify :) --- .gitea/workflows/haven-notify.yaml | 82 +++++++++++++++++++++++++++ haven-notify/Dockerfile | 12 ++++ haven-notify/deploy/haven-notify.yaml | 54 ++++++++++++++++++ haven-notify/main.go | 76 +++++++++++++++++++++++++ 4 files changed, 224 insertions(+) create mode 100644 .gitea/workflows/haven-notify.yaml create mode 100644 haven-notify/Dockerfile create mode 100644 haven-notify/deploy/haven-notify.yaml create mode 100644 haven-notify/main.go diff --git a/.gitea/workflows/haven-notify.yaml b/.gitea/workflows/haven-notify.yaml new file mode 100644 index 0000000..4483b49 --- /dev/null +++ b/.gitea/workflows/haven-notify.yaml @@ -0,0 +1,82 @@ +name: Haven Notify Build and Deploy + +on: + push: + branches: + - main + paths: + - 'haven-notify/**' + workflow_dispatch: {} + +env: + REGISTRY_HOST: git.ivanch.me + REGISTRY_USERNAME: ivanch + IMAGE_NOTIFY: ${{ env.REGISTRY_HOST }}/ivanch/haven-notify + KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }} + +jobs: + build_haven_notify: + runs-on: ubuntu-arm64 + + steps: + - name: Check out repository + uses: actions/checkout@v2 + + - name: Log in to Container Registry + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" \ + | docker login "${{ env.REGISTRY_HOST }}" \ + -u "${{ env.REGISTRY_USERNAME }}" \ + --password-stdin + + - name: Build and Push Image + run: | + TAG=latest + + cd haven-notify + + docker build \ + -t "${{ env.IMAGE_NOTIFY }}:${TAG}" \ + -f haven-notify/Dockerfile \ + haven-notify + + docker push "${{ env.IMAGE_NOTIFY }}:${TAG}" + + deploy_haven_notify: + runs-on: ubuntu-arm64 + needs: build_haven_notify + steps: + - name: Check KUBE_CONFIG validity + run: | + if [ -z "${KUBE_CONFIG}" ] || [ "${KUBE_CONFIG}" = "" ] || [ "${KUBE_CONFIG// }" = "" ]; then + echo "KUBE_CONFIG is not set or is empty." + exit 1 + fi + + - name: Check out repository + uses: actions/checkout@v2 + + - name: Download and install kubectl + run: | + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" + install -m 0755 kubectl /usr/local/bin/kubectl + kubectl version --client + + - name: Set up kubeconfig + run: | + cd haven-notify/deploy + echo "$KUBE_CONFIG" > kubeconfig.yaml + env: + KUBE_CONFIG: ${{ env.KUBE_CONFIG }} + + - name: Test connection to cluster + run: | + kubectl --kubeconfig=kubeconfig.yaml cluster-info + + - name: Apply haven-notify deployment + run: | + kubectl --kubeconfig=kubeconfig.yaml apply -f haven-notify.yaml + + - name: Rollout restart haven-notify + run: | + kubectl --kubeconfig=kubeconfig.yaml rollout restart deployment/haven-notify diff --git a/haven-notify/Dockerfile b/haven-notify/Dockerfile new file mode 100644 index 0000000..2b565b0 --- /dev/null +++ b/haven-notify/Dockerfile @@ -0,0 +1,12 @@ +# Start from the official Golang image for building +FROM golang:1.25 AS builder +WORKDIR /app +COPY . . +RUN go build -o haven-notify main.go + +# Use a minimal image for running +FROM busybox:latest +WORKDIR /app +COPY --from=builder /app/haven-notify . +EXPOSE 8080 +ENTRYPOINT ["/app/haven-notify"] diff --git a/haven-notify/deploy/haven-notify.yaml b/haven-notify/deploy/haven-notify.yaml new file mode 100644 index 0000000..5828190 --- /dev/null +++ b/haven-notify/deploy/haven-notify.yaml @@ -0,0 +1,54 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: haven-notify + labels: + app: haven-notify +spec: + replicas: 1 + selector: + matchLabels: + app: haven-notify + template: + metadata: + labels: + app: haven-notify + spec: + containers: + - name: haven-notify + image: git.ivanch.me/ivanch/haven-notify:latest + imagePullPolicy: Always + ports: + - containerPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: haven-notify +spec: + selector: + app: haven-notify + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: haven-notify + namespace: default + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: web +spec: + rules: + - host: notify.haven + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: haven-notify + port: + number: 8080 \ No newline at end of file diff --git a/haven-notify/main.go b/haven-notify/main.go new file mode 100644 index 0000000..ad72533 --- /dev/null +++ b/haven-notify/main.go @@ -0,0 +1,76 @@ + +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "log" + "net/http" +) + +// Notification payload +type Notification struct { + Title string `json:"title"` + Message string `json:"message"` +} + +func main() { + http.HandleFunc("/notify", notifyHandler) + log.Println("Starting server on :8080...") + log.Fatal(http.ListenAndServe(":8080", nil)) +} + +func notifyHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + w.WriteHeader(http.StatusMethodNotAllowed) + w.Write([]byte("Method not allowed")) + return + } + + var notif Notification + if err := json.NewDecoder(r.Body).Decode(¬if); err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte("Invalid payload")) + return + } + + // Call Discord notification function + if err := sendDiscordNotification(notif.Title, notif.Message); err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte("Failed to send Discord notification")) + return + } + + w.WriteHeader(http.StatusOK) + w.Write([]byte("Notification sent")) +} + +func sendDiscordNotification(title, message string) error { + const webhookURL = "" + + // Discord webhook payload + type discordPayload struct { + Content string `json:"content"` + } + + content := "**" + title + "**\n" + message + payload := discordPayload{Content: content} + + jsonData, err := json.Marshal(payload) + if err != nil { + return err + } + + resp, err := http.Post(webhookURL, "application/json", bytes.NewBuffer(jsonData)) + if err != nil { + return err + } + defer resp.Body.Close() + + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + return fmt.Errorf("Discord webhook returned status: %s", resp.Status) + } + + return nil +}