mirror of https://github.com/portainer/portainer
91 lines
3.1 KiB
Go
91 lines
3.1 KiB
Go
package gitops
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
gittypes "github.com/portainer/portainer/api/git/types"
|
|
httperror "github.com/portainer/portainer/pkg/libhttp/error"
|
|
"github.com/portainer/portainer/pkg/libhttp/request"
|
|
"github.com/portainer/portainer/pkg/libhttp/response"
|
|
|
|
"github.com/asaskevich/govalidator"
|
|
)
|
|
|
|
type fileResponse struct {
|
|
FileContent string
|
|
}
|
|
|
|
type repositoryFilePreviewPayload struct {
|
|
Repository string `json:"repository" example:"https://github.com/openfaas/faas" validate:"required"`
|
|
Reference string `json:"reference" example:"refs/heads/master"`
|
|
Username string `json:"username" example:"myGitUsername"`
|
|
Password string `json:"password" example:"myGitPassword"`
|
|
// Path to file whose content will be read
|
|
TargetFile string `json:"targetFile" example:"docker-compose.yml"`
|
|
// TLSSkipVerify skips SSL verification when cloning the Git repository
|
|
TLSSkipVerify bool `example:"false"`
|
|
}
|
|
|
|
func (payload *repositoryFilePreviewPayload) Validate(r *http.Request) error {
|
|
if govalidator.IsNull(payload.Repository) || !govalidator.IsURL(payload.Repository) {
|
|
return errors.New("invalid repository URL. Must correspond to a valid URL format")
|
|
}
|
|
|
|
if govalidator.IsNull(payload.Reference) {
|
|
payload.Reference = "refs/heads/main"
|
|
}
|
|
|
|
if govalidator.IsNull(payload.TargetFile) {
|
|
return errors.New("invalid target filename")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// @id GitOperationRepoFilePreview
|
|
// @summary preview the content of target file in the git repository
|
|
// @description Retrieve the compose file content based on git repository configuration
|
|
// @description **Access policy**: authenticated
|
|
// @tags gitops
|
|
// @security ApiKeyAuth
|
|
// @security jwt
|
|
// @produce json
|
|
// @param body body repositoryFilePreviewPayload true "Template details"
|
|
// @success 200 {object} fileResponse "Success"
|
|
// @failure 400 "Invalid request"
|
|
// @failure 500 "Server error"
|
|
// @router /gitops/repo/file/preview [post]
|
|
func (handler *Handler) gitOperationRepoFilePreview(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
|
var payload repositoryFilePreviewPayload
|
|
err := request.DecodeAndValidateJSONPayload(r, &payload)
|
|
if err != nil {
|
|
return httperror.BadRequest("Invalid request payload", err)
|
|
}
|
|
|
|
projectPath, err := handler.fileService.GetTemporaryPath()
|
|
if err != nil {
|
|
return httperror.InternalServerError("Unable to create temporary folder", err)
|
|
}
|
|
|
|
err = handler.gitService.CloneRepository(projectPath, payload.Repository, payload.Reference, payload.Username, payload.Password, payload.TLSSkipVerify)
|
|
if err != nil {
|
|
if errors.Is(err, gittypes.ErrAuthenticationFailure) {
|
|
return httperror.BadRequest("Invalid git credential", err)
|
|
}
|
|
|
|
newErr := fmt.Errorf("unable to clone git repository, error: %w", err)
|
|
return httperror.InternalServerError(newErr.Error(), newErr)
|
|
}
|
|
|
|
defer handler.fileService.RemoveDirectory(projectPath)
|
|
|
|
fileContent, err := handler.fileService.GetFileContent(projectPath, payload.TargetFile)
|
|
if err != nil {
|
|
return httperror.InternalServerError("Unable to retrieve custom template file from disk", err)
|
|
}
|
|
|
|
return response.JSON(w, &fileResponse{FileContent: string(fileContent)})
|
|
}
|