diff --git a/api/projects/templates.go b/api/projects/templates.go index 5378cfaa..8191c4e0 100644 --- a/api/projects/templates.go +++ b/api/projects/templates.go @@ -230,13 +230,68 @@ func RemoveTemplate(w http.ResponseWriter, r *http.Request) { } func SetTemplateInventory(w http.ResponseWriter, r *http.Request) { + tpl := context.Get(r, "template").(db.Template) + inv := context.Get(r, "inventory").(db.Inventory) + if !tpl.App.HasInventoryType(inv.Type) { + helpers.WriteErrorStatus(w, "Inventory type is not supported for this template", http.StatusBadRequest) + return + } + + if tpl.App.IsTerraform() && (inv.TemplateID == nil || *inv.TemplateID != tpl.ID) { + helpers.WriteErrorStatus(w, "Inventory is not attached to this template", http.StatusBadRequest) + return + } + + tpl.InventoryID = &inv.ID + err := helpers.Store(r).UpdateTemplate(tpl) + if err != nil { + helpers.WriteError(w, err) + return + } + + w.WriteHeader(http.StatusNoContent) } func AttachInventory(w http.ResponseWriter, r *http.Request) { + tpl := context.Get(r, "template").(db.Template) + inv := context.Get(r, "inventory").(db.Inventory) + if inv.TemplateID != nil { + helpers.WriteErrorStatus(w, "Inventory is already attached to another template", http.StatusBadRequest) + return + } + + if !tpl.App.HasInventoryType(inv.Type) { + helpers.WriteErrorStatus(w, "Inventory type is not supported for this template", http.StatusBadRequest) + return + } + + inv.TemplateID = &tpl.ID + err := helpers.Store(r).UpdateInventory(inv) + if err != nil { + helpers.WriteError(w, err) + return + } + + w.WriteHeader(http.StatusNoContent) } func DetachInventory(w http.ResponseWriter, r *http.Request) { + tpl := context.Get(r, "template").(db.Template) + inv := context.Get(r, "inventory").(db.Inventory) + if inv.TemplateID == nil || *inv.TemplateID != tpl.ID { + helpers.WriteErrorStatus(w, "Inventory is not attached to this template", http.StatusBadRequest) + return + } + + inv.TemplateID = nil + err := helpers.Store(r).UpdateInventory(inv) + if err != nil { + helpers.WriteError(w, err) + return + } + + w.WriteHeader(http.StatusNoContent) } diff --git a/api/router.go b/api/router.go index 73054cc0..c1dc49c3 100644 --- a/api/router.go +++ b/api/router.go @@ -320,9 +320,12 @@ func Route() *mux.Router { projectTmplManagement.HandleFunc("/{template_id}/tasks/last", projects.GetLastTasks).Methods("GET") projectTmplManagement.HandleFunc("/{template_id}/schedules", projects.GetTemplateSchedules).Methods("GET") projectTmplManagement.HandleFunc("/{template_id}/stats", projects.GetTaskStats).Methods("GET") - projectTmplManagement.HandleFunc("/{template_id}/inventory", projects.AttachInventory).Methods("POST") - projectTmplManagement.HandleFunc("/{template_id}/inventory/{inventory_id}", projects.DetachInventory).Methods("DELETE") - projectTmplManagement.HandleFunc("/{template_id}/default_inventory", projects.SetTemplateInventory).Methods("PUT") + + projectTmplInvManagement := projectTmplManagement.PathPrefix("/{template_id}/inventory").Subrouter() + projectTmplInvManagement.Use(projects.InventoryMiddleware) + projectTmplInvManagement.HandleFunc("/{inventory_id}/set_default", projects.SetTemplateInventory).Methods("POST") + projectTmplInvManagement.HandleFunc("/{inventory_id}/attach", projects.AttachInventory).Methods("POST") + projectTmplInvManagement.HandleFunc("/{inventory_id}/detach", projects.DetachInventory).Methods("POST") projectTaskManagement := projectUserAPI.PathPrefix("/tasks").Subrouter() projectTaskManagement.Use(projects.GetTaskMiddleware) diff --git a/db/Template.go b/db/Template.go index 23cdc2bf..b82eec57 100644 --- a/db/Template.go +++ b/db/Template.go @@ -37,6 +37,19 @@ func (t TemplateApp) InventoryTypes() ([]InventoryType, error) { } } +func (t TemplateApp) HasInventoryType(inventoryType InventoryType) bool { + types, err := t.InventoryTypes() + if err != nil { + return false + } + for _, typ := range types { + if typ == inventoryType { + return true + } + } + return false +} + func (t TemplateApp) IsTerraform() bool { return t == AppTerraform || t == AppTofu }