From 9ae5696aecf7ce757e7c060949c3f607c949e879 Mon Sep 17 00:00:00 2001 From: Schrody Date: Thu, 29 Jan 2026 17:55:14 +0100 Subject: [PATCH] Init commit, base struct and redis connection --- .devcontainer/devcontainer.json | 39 +++++++++++++++++++++++++++++++++ Dockerfile | 17 ++++++++++++++ README.md | 1 + cmd/main.go | 36 ++++++++++++++++++++++++++++++ docker-compose.yaml | 22 +++++++++++++++++++ go.mod | 10 +++++++++ go.sum | 10 +++++++++ handlers/worker.go | 28 +++++++++++++++++++++++ manager/redis.go | 35 +++++++++++++++++++++++++++++ structs/request.go | 8 +++++++ 10 files changed, 206 insertions(+) create mode 100644 .devcontainer/devcontainer.json create mode 100644 Dockerfile create mode 100644 cmd/main.go create mode 100644 docker-compose.yaml create mode 100644 go.mod create mode 100644 go.sum create mode 100644 handlers/worker.go create mode 100644 manager/redis.go create mode 100644 structs/request.go diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..26c8cf6 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,39 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/go +{ + "name": "Go", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/go:1-1.22-bookworm", + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Configure tool-specific properties. + "customizations": { + // Configure properties specific to VS Code. + "vscode": { + "settings": {}, + "extensions": [ + "streetsidesoftware.code-spell-checker" + ] + } + }, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [9000], + + // Use 'portsAttributes' to set default properties for specific forwarded ports. + // More info: https://containers.dev/implementors/json_reference/#port-attributes + "portsAttributes": { + "9000": { + "label": "Hello Remote World", + "onAutoForward": "notify" + } + } + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "go version", + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9459b7b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM golang:1.23.4-alpine AS builder + +WORKDIR /app + +COPY go.mod ./ + +RUN go mod download && go mod verify + +COPY . . + +RUN go build -o main cmd/main.go + +FROM scratch + +COPY --from=builder /app/main /main + +CMD ["./main"] \ No newline at end of file diff --git a/README.md b/README.md index 73cffd5..93dede3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # UeBucch +[Redis Viewer](https://github.com/ekvedaras/redis-gui) \ No newline at end of file diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 0000000..d7be57d --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "fmt" + "net/http" + "io" + "context" + "uebucch/manager" +) +func main() { + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "UeBucch!") + }) + http.HandleFunc("/webhook", func(w http.ResponseWriter, r *http.Request) { + webHookName := r.URL.Query().Get("name") + redisClient := manager.NewRedisClient() + body, _ := io.ReadAll(r.Body) + res := redisClient.LPush(context.Background(), webHookName, body) + if res.Err() != nil { + fmt.Fprintf(w, "Error: %s", res.Err()) + return + } + fmt.Fprintf(w, "Webhook created!") + }) + http.HandleFunc("/webhooks", func(w http.ResponseWriter, r *http.Request) { + webHooks, err := manager.GetWebhooks(context.Background(), manager.NewRedisClient()) + if err != nil { + fmt.Fprintf(w, "Error: %s", err) + return + } + for _, webHook := range webHooks { + fmt.Fprintf(w, "Webhook: %s", webHook) + } + }) + http.ListenAndServe(":8080", nil) +} \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..7403f0b --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,22 @@ +services: + app: + build: + context: . + dockerfile: Dockerfile + ports: + - 8080:8080 + depends_on: + - redis + environment: + - REDIS_ADDR=redis:6379 + + redis: + image: redis:7.4.1-alpine + ports: + - 6379:6379 + volumes: + - redis-data:/data + + +volumes: + redis-data: \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..f94ef73 --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module uebucch + +go 1.22.2 + +require github.com/redis/go-redis/v9 v9.17.3 + +require ( + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..d0bd1ab --- /dev/null +++ b/go.sum @@ -0,0 +1,10 @@ +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/redis/go-redis/v9 v9.17.3 h1:fN29NdNrE17KttK5Ndf20buqfDZwGNgoUr9qjl1DQx4= +github.com/redis/go-redis/v9 v9.17.3/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370= diff --git a/handlers/worker.go b/handlers/worker.go new file mode 100644 index 0000000..5e64c09 --- /dev/null +++ b/handlers/worker.go @@ -0,0 +1,28 @@ +package handlers + +import ( + "bytes" + "log" + "net/http" + "time" + + "uebucch/structs" +) +func worker(id int, jobs <-chan structs.WebhookJob) { + client := &http.Client{Timeout: 10 * time.Second} + + for job := range jobs { + req, _ := http.NewRequest(job.Method, job.TargetURL, bytes.NewBuffer(job.Payload)) + for k, v := range job.Headers { + req.Header[k] = v + } + + resp, err := client.Do(req) + if err != nil { + log.Printf("Worker %d: Errore nell'inoltro: %v", id, err) + continue + } + resp.Body.Close() + log.Printf("Worker %d: Inoltrato con successo a %s", id, job.TargetURL) + } +} \ No newline at end of file diff --git a/manager/redis.go b/manager/redis.go new file mode 100644 index 0000000..014b5a6 --- /dev/null +++ b/manager/redis.go @@ -0,0 +1,35 @@ +package manager + +import ( + "context" + "os" + + "github.com/redis/go-redis/v9" +) + +func NewRedisClient() *redis.Client { + addr := os.Getenv("REDIS_ADDR") + if addr == "" { + addr = "redis:6379" + } + + password := os.Getenv("REDIS_PASSWORD") + + return redis.NewClient(&redis.Options{ + Addr: addr, + Password: password, + DB: 0, + }) +} + +func GetWebhooks(ctx context.Context, client *redis.Client) ([]string, error) { + return client.LRange(ctx, "webhooks", 0, -1).Result() +} + +func CreateWebhook(ctx context.Context, client *redis.Client, webhook string) error { + return client.LPush(ctx, "webhooks", webhook).Err() +} + +func DeleteWebhook(ctx context.Context, client *redis.Client, webhook string) error { + return client.LRem(ctx, "webhooks", 0, webhook).Err() +} diff --git a/structs/request.go b/structs/request.go new file mode 100644 index 0000000..ec1c558 --- /dev/null +++ b/structs/request.go @@ -0,0 +1,8 @@ +package structs + +type WebhookJob struct { + TargetURL string + Method string + Headers map[string][]string + Payload []byte +} \ No newline at end of file