1package handler
2
3import (
4 "fmt"
5 "log"
6 "net/http"
7
8 "github.com/bnema/gordon/internal/server"
9 "github.com/bnema/gordon/internal/templating/cmdparams"
10 "github.com/bnema/gordon/internal/templating/render"
11 "github.com/bnema/gordon/pkg/docker"
12 "github.com/bnema/gordon/pkg/sanitize"
13 "github.com/labstack/echo/v4"
14)
15
16// FromShortIDToImageID converts a short image ID to a full image ID
17func FromShortIDToImageID(ShortID string) (string, error) {
18 imageID, exists := safelyInteractWithIDMap(Fetch, ShortID)
19 if !exists {
20 log.Printf("No mapping found for short ID: %s", ShortID)
21 return "", fmt.Errorf("image ID not found")
22 }
23 return imageID, nil
24}
25
26// CreateContainerRoute is the route for creating a new container
27func CreateContainerGET(c echo.Context, a *server.App) error {
28 log.Printf("Full request URL: %s", c.Request().URL.String())
29 // Retrieve the ShortID of the image from the URL
30 shortID := c.Param("ID")
31 log.Printf("Received ShortID: %s", shortID)
32
33 fullID, exists := safelyInteractWithIDMap(Fetch, shortID)
34 if !exists {
35 log.Printf("No mapping found for short ID: %s", shortID)
36 return c.String(http.StatusNotFound, "Image ID not found")
37 }
38
39 log.Printf("Found mapping: %s -> %s", shortID, fullID)
40
41 // Get the image info
42 imageInfo, err := docker.GetImageInfo(fullID)
43 if err != nil {
44 return sendError(c, err)
45 }
46
47 // Extract image name
48 var imageName string
49 if len(imageInfo.RepoTags) > 0 {
50 imageName = imageInfo.RepoTags[0]
51 }
52
53 data := map[string]interface{}{
54 "Title": "Create a new container",
55 "ShortID": shortID,
56 "ImageID": fullID,
57 "ImageName": imageName,
58 }
59
60 rendererData, err := render.GetHTMLRenderer("html/fragments", "createcontainer.gohtml", a.TemplateFS, a)
61
62 if err != nil {
63 return sendError(c, err)
64 }
65
66 renderedHTML, err := rendererData.Render(data, a)
67
68 if err != nil {
69 return sendError(c, err)
70 }
71
72 return c.HTML(200, renderedHTML)
73
74}
75
76// CreateContainerFullGET handles the full HTML page for creating a new container
77func CreateContainerFullGET(c echo.Context, a *server.App) error {
78 // Retrieve the ShortID of the image from the URL
79 shortID := c.Param("ID")
80 log.Printf("Received ShortID: %s", shortID)
81
82 fullID, exists := safelyInteractWithIDMap(Fetch, shortID)
83 if !exists {
84 log.Printf("No mapping found for short ID: %s", shortID)
85 return c.String(http.StatusNotFound, "Image ID not found")
86 }
87
88 log.Printf("Found mapping: %s -> %s", shortID, fullID)
89
90 // Get the image info
91 imageInfo, err := docker.GetImageInfo(fullID)
92 if err != nil {
93 return sendError(c, err)
94 }
95
96 // Extract image name
97 var imageName string
98 if len(imageInfo.RepoTags) > 0 {
99 imageName = imageInfo.RepoTags[0]
100 }
101
102 data := map[string]interface{}{
103 "Title": "Create a new container",
104 "ShortID": shortID,
105 "ImageID": fullID,
106 "ImageName": imageName,
107 "AdminPath": a.Config.Admin.Path,
108 }
109
110 // Specify both admin and fragments directories
111 rendererData, err := render.GetHTMLRenderer("html/admin", "createcontainerfull.gohtml", a.TemplateFS, a, "html/fragments")
112 if err != nil {
113 return sendError(c, err)
114 }
115
116 renderedHTML, err := rendererData.Render(data, a)
117 if err != nil {
118 log.Printf("Error rendering template: %v", err)
119 return sendError(c, err)
120 }
121
122 return c.HTML(200, renderedHTML)
123}
124
125// CreateContainerPOST handles the create container form submission
126func CreateContainerPOST(c echo.Context, a *server.App) error {
127 // Retreive the ShortID of the image from the URL
128 ShortID := c.Param("ID")
129
130 // Convert the ShortID to a full image ID
131 imageID, err := FromShortIDToImageID(ShortID)
132 if err != nil {
133 return sendError(c, err)
134 }
135
136 // Get the image info
137 _, err = docker.GetImageInfo(imageID)
138 if err != nil {
139 return sendError(c, err)
140 }
141
142 // Retrieve all form parameters
143 formParams, err := c.FormParams()
144 if err != nil {
145 return sendError(c, err)
146 }
147
148 // Initialize a map to store sanitized values
149 sanitizedInputs := make(map[string]string)
150
151 // Iterate over all form parameters and sanitize them
152 for k, v := range formParams {
153 if len(v) > 0 {
154 sanitized, err := sanitize.SanitizeHTML(v[0])
155 if err != nil {
156 return sendError(c, err)
157 }
158 sanitizedInputs[k] = sanitized
159 }
160 }
161
162 cmdParams, err := cmdparams.FromInputsToCmdParams(sanitizedInputs, a)
163 if err != nil {
164 return sendError(c, err)
165 }
166
167 // Create the container
168 _, err = docker.CreateContainer(cmdParams)
169 if err != nil {
170 return sendError(c, err)
171 }
172
173 return c.HTML(http.StatusOK, ActionSuccess(a))
174}