1package handler
2
3import (
4 "bytes"
5 "fmt"
6 "io"
7 "net/http"
8
9 "github.com/bnema/gordon/internal/common"
10 "github.com/bnema/gordon/internal/server"
11 "github.com/bnema/gordon/pkg/docker"
12 "github.com/bnema/gordon/pkg/store"
13 "github.com/labstack/echo/v4"
14)
15
16// Handle GET on /api/hello endpoint
17func GetHello(c echo.Context, a *server.App) error {
18 return c.JSON(http.StatusOK, "Hello, World!")
19}
20
21type InfoResponse struct {
22 Uptime string `json:"uptime"`
23 Version string `json:"version"`
24}
25
26func (info *InfoResponse) Populate(a *server.App) {
27 info.Uptime = a.GetUptime()
28 info.Version = a.GetVersionstring()
29}
30
31// Handle GET on /api/ping endpoint
32func GetInfos(c echo.Context, a *server.App) error {
33 body, _ := io.ReadAll(c.Request().Body)
34 c.Request().Body = io.NopCloser(bytes.NewBuffer(body)) // Reset the body
35
36 payload := new(common.RequestPayload)
37 if err := c.Bind(payload); err != nil {
38 fmt.Println("Bind Error:", err)
39 return c.JSON(http.StatusBadRequest, err.Error())
40 }
41
42 if payload.Type != "ping" {
43 return c.JSON(http.StatusBadRequest, "Invalid payload type")
44 }
45
46 pingPayload, ok := payload.Payload.(common.PingPayload)
47 if !ok {
48 return c.JSON(http.StatusBadRequest, "Invalid payload type")
49 }
50 if pingPayload.Message != "ping" {
51 return c.JSON(http.StatusBadRequest, "Invalid payload data")
52 }
53
54 // Prepare and populate the information
55 info := &InfoResponse{}
56 info.Populate(a)
57
58 return c.JSON(http.StatusOK, info)
59
60}
61
62func PostPush(c echo.Context, a *server.App) error {
63 body, _ := io.ReadAll(c.Request().Body)
64 c.Request().Body = io.NopCloser(bytes.NewBuffer(body)) // Reset the body
65
66 payload := new(common.RequestPayload)
67 if err := c.Bind(payload); err != nil {
68 fmt.Println("Bind Error:", err)
69 return c.JSON(http.StatusBadRequest, err.Error())
70 }
71
72 if payload.Type != "push" {
73 return c.JSON(http.StatusBadRequest, "Invalid payload type")
74 }
75
76 pushPayload, ok := payload.Payload.(common.PushPayload)
77 if !ok {
78 return c.JSON(http.StatusBadRequest, "Invalid payload type")
79 }
80
81 // Push payload contains Ports as a string, Image as string (image:tag), and the .tar image as a byte array
82 // Validate the ports
83 ports := pushPayload.Ports
84 if ports == "" {
85 return c.JSON(http.StatusBadRequest, "Ports cannot be empty")
86 }
87
88 // Validate the target domain
89 domain := pushPayload.TargetDomain
90 if domain == "" {
91 return c.JSON(http.StatusBadRequest, "Image cannot be empty")
92 }
93
94 // Validate the image tar
95 imageTar := pushPayload.Data
96 if imageTar == nil {
97 return c.JSON(http.StatusBadRequest, "Image tar cannot be empty")
98 }
99
100 imageName := pushPayload.ImageName
101 if imageName == "" {
102 return c.JSON(http.StatusBadRequest, "Image name cannot be empty")
103 }
104
105 // 1 - Save the image tar in the storage
106 imagePath, err := store.SaveImageToStorage(&a.Config, imageName, bytes.NewBuffer(imageTar))
107 if err != nil {
108 return c.JSON(http.StatusBadRequest, err.Error())
109 }
110 // 2 - Import the tar in docker
111 imageID, err := docker.ImportImageToEngine(imagePath)
112 if err != nil {
113 return c.JSON(http.StatusBadRequest, err.Error())
114 }
115
116 fmt.Println("Import successful, ImageID:", imageID)
117
118 // 3 - Create the container with traefik labels
119
120 // 4 - Start the container
121
122 return c.JSON(http.StatusOK, "OK")
123}