package api import ( "net/http" "strings" "provisioning/internal/image" ) type ImageAPI struct { Svc *image.Service } func (a *ImageAPI) List(w http.ResponseWriter, r *http.Request) { images, err := a.Svc.Store.List(r.Context()) if err != nil { writeJSONErr(w, http.StatusInternalServerError, "failed to list images") return } writeJSON(w, http.StatusOK, images) } func (a *ImageAPI) Get(w http.ResponseWriter, r *http.Request) { id, ok := idFromURL(w, r) if !ok { return } img, err := a.Svc.Store.Get(r.Context(), id) if err != nil { writeJSONErr(w, http.StatusNotFound, "image not found") return } writeJSON(w, http.StatusOK, img) } func (a *ImageAPI) Upload(w http.ResponseWriter, r *http.Request) { if err := r.ParseMultipartForm(0); err != nil { writeJSONErr(w, http.StatusBadRequest, "invalid multipart form") return } name := strings.TrimSpace(r.FormValue("name")) version := strings.TrimSpace(r.FormValue("version")) kind := strings.TrimSpace(r.FormValue("kind")) file, _, err := r.FormFile("iso") if err != nil { writeJSONErr(w, http.StatusBadRequest, "iso file is required") return } defer file.Close() img, err := a.Svc.Upload(r.Context(), image.UploadParams{ Name: name, Kind: kind, Version: version, ISO: file, }) if err != nil { status := http.StatusInternalServerError msg := err.Error() if strings.Contains(msg, "already exists") { status = http.StatusConflict } else if strings.Contains(msg, "invalid name") || strings.Contains(msg, "version is required") { status = http.StatusBadRequest } writeJSONErr(w, status, msg) return } writeJSON(w, http.StatusCreated, img) } func (a *ImageAPI) Delete(w http.ResponseWriter, r *http.Request) { id, ok := idFromURL(w, r) if !ok { return } if err := a.Svc.Delete(r.Context(), id); err != nil { writeJSONErr(w, http.StatusNotFound, "image not found") return } w.WriteHeader(http.StatusNoContent) } func (a *ImageAPI) SetDefault(w http.ResponseWriter, r *http.Request) { id, ok := idFromURL(w, r) if !ok { return } if err := a.Svc.Store.SetDefault(r.Context(), id); err != nil { writeJSONErr(w, http.StatusInternalServerError, "failed to set default") return } writeJSON(w, http.StatusOK, map[string]any{"ok": true}) }