From 77ac3e548d6f0832816e0a7b44a58cdafe89d867 Mon Sep 17 00:00:00 2001 From: niku Date: Sun, 11 Jun 2023 12:09:27 +0200 Subject: [PATCH] Added events feature + rewrote router.go api/v1 --- go.mod | 2 ++ go.sum | 4 +++ internal/app/api/v1/router.go | 36 +++++++++++-------- internal/events/events_controller.go | 26 ++++++++++++++ internal/events/services/events_service.go | 27 ++++++++++++++ .../{error_hander.go => error_handler.go} | 0 internal/middleware/websocket.go | 14 ++++++++ 7 files changed, 95 insertions(+), 14 deletions(-) create mode 100644 internal/events/events_controller.go create mode 100644 internal/events/services/events_service.go rename internal/middleware/{error_hander.go => error_handler.go} (100%) create mode 100644 internal/middleware/websocket.go diff --git a/go.mod b/go.mod index b285637..3015db9 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,7 @@ require ( github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11 // indirect github.com/docker/go-units v0.5.0 // indirect + github.com/fasthttp/websocket v1.5.3 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.3 // indirect @@ -55,6 +56,7 @@ require ( github.com/go-openapi/validate v0.22.1 // indirect github.com/godbus/dbus/v5 v5.1.1-0.20221029134443-4b691ce883d5 // indirect github.com/gofiber/contrib/jwt v1.0.1 // indirect + github.com/gofiber/contrib/websocket v1.0.0 // indirect github.com/gofiber/jwt/v2 v2.2.7 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect diff --git a/go.sum b/go.sum index 498810b..009ca7a 100644 --- a/go.sum +++ b/go.sum @@ -337,6 +337,8 @@ github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yih2JAcL6Ls/kVkSE8GFACTGVnMPruw= github.com/facebookgo/limitgroup v0.0.0-20150612190941-6abd8d71ec01 h1:IeaD1VDVBPlx3viJT9Md8if8IxxJnO+x0JCGb054heg= github.com/facebookgo/muster v0.0.0-20150708232844-fd3d7953fd52 h1:a4DFiKFJiDRGFD1qIcqGLX/WlUMD9dyLSLDt+9QZgt8= +github.com/fasthttp/websocket v1.5.3 h1:TPpQuLwJYfd4LJPXvHDYPMFWbLjsT91n3GpWtCQtdek= +github.com/fasthttp/websocket v1.5.3/go.mod h1:46gg/UBmTU1kUaTcwQXpUxtRwG2PvIZYeA8oL6vF3Fs= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= @@ -441,6 +443,8 @@ github.com/godbus/dbus/v5 v5.1.1-0.20221029134443-4b691ce883d5 h1:boOtwyhKoC3Aad github.com/godbus/dbus/v5 v5.1.1-0.20221029134443-4b691ce883d5/go.mod h1:fXoNnqaUvdKqjJmMGeiBgmRphUg+kO0MT4AhPOP6+Qg= github.com/gofiber/contrib/jwt v1.0.1 h1:JgVyPumOB9RoE/z+FXoIVulaLcgsrX/g+/HAlUw3y/8= github.com/gofiber/contrib/jwt v1.0.1/go.mod h1:UoenkOUg1MTcazOGrOwxoaIaQ0gcWvzq96ebzTS0R1A= +github.com/gofiber/contrib/websocket v1.0.0 h1:y9bbY5/KOvR84SrwPm/3+Q8/M4rxoJlz/eGQaezVrTk= +github.com/gofiber/contrib/websocket v1.0.0/go.mod h1:5TICl8C33weKzAcZjAQ0dYCIbG/5DfghiDs+qvTbIpw= github.com/gofiber/fiber/v2 v2.17.0/go.mod h1:iftruuHGkRYGEXVISmdD7HTYWyfS2Bh+Dkfq4n/1Owg= github.com/gofiber/fiber/v2 v2.46.0 h1:wkkWotblsGVlLjXj2dpgKQAYHtXumsK/HyFugQM68Ns= github.com/gofiber/fiber/v2 v2.46.0/go.mod h1:DNl0/c37WLe0g92U6lx1VMQuxGUQY5V7EIaVoEsUffc= diff --git a/internal/app/api/v1/router.go b/internal/app/api/v1/router.go index 28af1d9..45fd792 100644 --- a/internal/app/api/v1/router.go +++ b/internal/app/api/v1/router.go @@ -2,10 +2,13 @@ package v1 import ( "git.cesium.pw/niku/virteen/internal/auth" + "git.cesium.pw/niku/virteen/internal/events" + eventServices "git.cesium.pw/niku/virteen/internal/events/services" "git.cesium.pw/niku/virteen/internal/middleware" "git.cesium.pw/niku/virteen/internal/podman" - "git.cesium.pw/niku/virteen/internal/podman/models" - "git.cesium.pw/niku/virteen/internal/podman/services" + podmanModels "git.cesium.pw/niku/virteen/internal/podman/models" + podmanServices "git.cesium.pw/niku/virteen/internal/podman/services" + "github.com/gofiber/contrib/websocket" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/monitor" "github.com/pkg/errors" @@ -14,30 +17,35 @@ import ( func ConfigureRoutes(router fiber.Router) error { v1 := router.Group("/v1") - ac := auth.NewPamAuthController() - ag := v1.Group("/auth") - ag.Post("/token", ac.GetToken) + authController := auth.NewPamAuthController() + authGroup := v1.Group("/auth") + authGroup.Post("/token", authController.GetToken) v1.Get("/ping", Ping) v1.Get("/metrics", monitor.New()) v1.Use(middleware.Protected()) - var cs models.PodmanService - cs, err := services.NewPodmanContainerService() + eventsService := eventServices.NewEventsService() + eventsController := events.NewEventsController(eventsService) + eventsGroup := v1.Group("/events") + eventsGroup.Get("/ws", middleware.UpgradeSocket, websocket.New(eventsController.PollEvents)) + + var cs podmanModels.PodmanService + cs, err := podmanServices.NewPodmanContainerService() if err != nil { panic(errors.Wrapf(err, "failed to build podman container service")) } - cc := podman.NewPodmanController(&cs) + containerController := podman.NewPodmanController(&cs) - cg := v1.Group("/containers") - cg.Get("/", cc.ListContainers) - cg.Post("/", cc.CreateContainer) + containersGroup := v1.Group("/containers") + containersGroup.Get("/", containerController.ListContainers) + containersGroup.Post("/", containerController.CreateContainer) - ccg := cg.Group("/:name") - ccg.Put("/status", cc.UpdateContainerStatus) - ccg.Delete("/", cc.DeleteContainer) + containerGroup := containersGroup.Group("/:name") + containerGroup.Put("/status", containerController.UpdateContainerStatus) + containerGroup.Delete("/", containerController.DeleteContainer) return nil } diff --git a/internal/events/events_controller.go b/internal/events/events_controller.go new file mode 100644 index 0000000..5c843de --- /dev/null +++ b/internal/events/events_controller.go @@ -0,0 +1,26 @@ +package events + +import ( + "git.cesium.pw/niku/virteen/internal/events/services" + "github.com/gofiber/contrib/websocket" +) + +type EventsController struct { + events *services.EventsService +} + +func NewEventsController(events *services.EventsService) *EventsController { + return &EventsController{events} +} + +func (ec *EventsController) PollEvents(ws *websocket.Conn) { + (*ec.events).AddConnection(ws) + defer (*ec.events).RemoveConnection(ws) + + for { + _, _, err := ws.ReadMessage() + if err != nil { + return + } + } +} diff --git a/internal/events/services/events_service.go b/internal/events/services/events_service.go new file mode 100644 index 0000000..9c30dce --- /dev/null +++ b/internal/events/services/events_service.go @@ -0,0 +1,27 @@ +package services + +import "github.com/gofiber/contrib/websocket" + +type EventsService struct { + clients map[*websocket.Conn]interface{} +} + +func NewEventsService() *EventsService { + return &EventsService{ + clients: make(map[*websocket.Conn]interface{}), + } +} + +func (es *EventsService) AddConnection(ws *websocket.Conn) { + es.clients[ws] = nil +} + +func (es *EventsService) RemoveConnection(ws *websocket.Conn) { + delete(es.clients, ws) +} + +func (es *EventsService) Broadcast(msg interface{}) { + for connection := range es.clients { + go connection.WriteJSON(msg) + } +} diff --git a/internal/middleware/error_hander.go b/internal/middleware/error_handler.go similarity index 100% rename from internal/middleware/error_hander.go rename to internal/middleware/error_handler.go diff --git a/internal/middleware/websocket.go b/internal/middleware/websocket.go new file mode 100644 index 0000000..86bc023 --- /dev/null +++ b/internal/middleware/websocket.go @@ -0,0 +1,14 @@ +package middleware + +import ( + "github.com/gofiber/contrib/websocket" + "github.com/gofiber/fiber/v2" +) + +func UpgradeSocket(ctx *fiber.Ctx) error { + if websocket.IsWebSocketUpgrade(ctx) { + ctx.Locals("allowed", true) + return ctx.Next() + } + return fiber.ErrUpgradeRequired +}