mirror of https://github.com/portainer/portainer
94 lines
2.7 KiB
Go
94 lines
2.7 KiB
Go
package templates
|
|
|
|
import (
|
|
"net/http"
|
|
"slices"
|
|
|
|
portainer "github.com/portainer/portainer/api"
|
|
httperror "github.com/portainer/portainer/pkg/libhttp/error"
|
|
"github.com/portainer/portainer/pkg/libhttp/request"
|
|
"github.com/portainer/portainer/pkg/libhttp/response"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
type fileResponse struct {
|
|
// The requested file content
|
|
FileContent string `example:"version:2"`
|
|
}
|
|
|
|
// @id TemplateFile
|
|
// @summary Get a template's file
|
|
// @description Get a template's file
|
|
// @description **Access policy**: authenticated
|
|
// @tags templates
|
|
// @security ApiKeyAuth
|
|
// @security jwt
|
|
// @accept json
|
|
// @produce json
|
|
// @param id path int true "Template identifier"
|
|
// @success 200 {object} fileResponse "Success"
|
|
// @failure 400 "Invalid request"
|
|
// @failure 500 "Server error"
|
|
// @router /templates/{id}/file [post]
|
|
func (handler *Handler) templateFile(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
|
id, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
|
if err != nil {
|
|
return httperror.BadRequest("Invalid template identifier", err)
|
|
}
|
|
|
|
templatesResponse, httpErr := handler.fetchTemplates()
|
|
if httpErr != nil {
|
|
return httpErr
|
|
}
|
|
|
|
templateIdx := slices.IndexFunc(templatesResponse.Templates, func(template portainer.Template) bool {
|
|
return template.ID == portainer.TemplateID(id)
|
|
})
|
|
|
|
if templateIdx == -1 {
|
|
return httperror.NotFound("Unable to find a template with the specified identifier", nil)
|
|
}
|
|
|
|
template := templatesResponse.Templates[templateIdx]
|
|
|
|
if template.Type == portainer.ContainerTemplate {
|
|
return httperror.BadRequest("Invalid template type", nil)
|
|
}
|
|
|
|
if template.StackFile != "" {
|
|
return response.JSON(w, fileResponse{FileContent: template.StackFile})
|
|
}
|
|
|
|
if template.Repository.StackFile == "" || template.Repository.URL == "" {
|
|
return httperror.BadRequest("Invalid template configuration", nil)
|
|
}
|
|
|
|
projectPath, err := handler.FileService.GetTemporaryPath()
|
|
if err != nil {
|
|
return httperror.InternalServerError("Unable to create temporary folder", err)
|
|
}
|
|
|
|
defer handler.cleanUp(projectPath)
|
|
|
|
err = handler.GitService.CloneRepository(projectPath, template.Repository.URL, "", "", "", false)
|
|
if err != nil {
|
|
return httperror.InternalServerError("Unable to clone git repository", err)
|
|
}
|
|
|
|
fileContent, err := handler.FileService.GetFileContent(projectPath, template.Repository.StackFile)
|
|
if err != nil {
|
|
return httperror.InternalServerError("Failed loading file content", err)
|
|
}
|
|
|
|
return response.JSON(w, fileResponse{FileContent: string(fileContent)})
|
|
|
|
}
|
|
|
|
func (handler *Handler) cleanUp(projectPath string) {
|
|
err := handler.FileService.RemoveDirectory(projectPath)
|
|
if err != nil {
|
|
log.Debug().Err(err).Msg("HTTP error: unable to cleanup stack creation")
|
|
}
|
|
}
|