Files
portainer/api/stacks/stackbuilders/director.go
T

94 lines
2.9 KiB
Go

package stackbuilders
import (
"errors"
portainer "github.com/portainer/portainer/api"
httperror "github.com/portainer/portainer/pkg/libhttp/error"
"github.com/portainer/portainer/pkg/libhttp/request"
)
type StackBuilderDirector struct {
builder any
}
func NewStackBuilderDirector(b any) *StackBuilderDirector {
return &StackBuilderDirector{
builder: b,
}
}
// Build executes the stack build process based on the builder type. It returns the
// created stack and any error encountered during the process.
// The returned error is of type *httperror.HandlerError, which could be a BadRequest
// or InternalServerError depending on the error encountered during the stack build process.
func (d *StackBuilderDirector) Build(payload *StackPayload, endpoint *portainer.Endpoint) (*portainer.Stack, *httperror.HandlerError) {
var (
stack *portainer.Stack
err error
)
// To align with the flow of the actual service deployment tools, we save
// the stack before the deployment. This allows us to track the stack
// metadata and partially created resources.
switch builder := d.builder.(type) {
case GitMethodStackBuildProcess:
stack, err = builder.SetGeneralInfo(payload, endpoint).
SetUniqueInfo(payload).
SetGitRepository(payload).
SaveStack()
if err != nil {
return nil, httperror.InternalServerError("Failed to save stack via Git repository method", err)
}
// Since AutoUpdate job for stack is created after a successful
// deployment, we need to update the stack with the new generated job ID
stack, err = builder.Deploy(payload, endpoint).
SetAutoUpdate(payload).
UpdateStack(stack)
case FileUploadMethodStackBuildProcess:
stack, err = builder.SetGeneralInfo(payload, endpoint).
SetUniqueInfo(payload).
SetUploadedFile(payload).
SaveStack()
if err != nil {
return nil, httperror.InternalServerError("Failed to save stack via File Upload method", err)
}
builder.Deploy(payload, endpoint)
err = builder.Error()
case FileContentMethodStackBuildProcess:
stack, err = builder.SetGeneralInfo(payload, endpoint).
SetUniqueInfo(payload).
SetFileContent(payload).
SaveStack()
if err != nil {
return nil, httperror.InternalServerError("Failed to save stack via File Content method", err)
}
builder.Deploy(payload, endpoint)
err = builder.Error()
case UrlMethodStackBuildProcess:
stack, err = builder.SetGeneralInfo(payload, endpoint).
SetUniqueInfo(payload).
SetURL(payload).
SaveStack()
if err != nil {
return nil, httperror.InternalServerError("Failed to save stack via URL method", err)
}
builder.Deploy(payload, endpoint)
err = builder.Error()
default:
return nil, httperror.BadRequest("Invalid value for query parameter: method. Value must be one of: string or repository or url or file", errors.New(request.ErrInvalidQueryParameter))
}
if err != nil {
return nil, httperror.InternalServerError("Failed to deploy stack", err)
}
return stack, nil
}