2020-05-14 05:14:28 +03:00
package edgestacks
import (
2021-09-09 11:38:34 +03:00
"fmt"
2020-05-14 05:14:28 +03:00
"net/http"
2022-12-01 08:40:52 +02:00
"github.com/asaskevich/govalidator"
"github.com/pkg/errors"
2020-05-14 05:14:28 +03:00
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
2021-02-23 05:21:39 +02:00
portainer "github.com/portainer/portainer/api"
2020-05-14 05:14:28 +03:00
"github.com/portainer/portainer/api/filesystem"
2022-12-01 08:40:52 +02:00
gittypes "github.com/portainer/portainer/api/git/types"
"github.com/portainer/portainer/api/http/security"
2023-05-04 10:01:33 +12:00
edgestackservice "github.com/portainer/portainer/api/internal/edge/edgestacks"
2020-05-14 05:14:28 +03:00
)
func ( handler * Handler ) edgeStackCreate ( w http . ResponseWriter , r * http . Request ) * httperror . HandlerError {
2023-04-27 11:03:55 +07:00
method , err := request . RetrieveRouteVariableValue ( r , "method" )
2020-05-14 05:14:28 +03:00
if err != nil {
2022-09-14 20:42:39 -03:00
return httperror . BadRequest ( "Invalid query parameter: method" , err )
2020-05-14 05:14:28 +03:00
}
2022-12-01 08:40:52 +02:00
dryrun , _ := request . RetrieveBooleanQueryParameter ( r , "dryrun" , true )
tokenData , err := security . RetrieveTokenData ( r )
if err != nil {
return httperror . InternalServerError ( "Unable to retrieve user details from authentication token" , err )
}
2020-05-14 05:14:28 +03:00
2022-12-01 08:40:52 +02:00
edgeStack , err := handler . createSwarmStack ( method , dryrun , tokenData . ID , r )
2020-05-14 05:14:28 +03:00
if err != nil {
2023-05-04 10:01:33 +12:00
var payloadError * edgestackservice . InvalidPayloadError
2022-11-15 17:40:56 -03:00
switch {
case errors . As ( err , & payloadError ) :
return httperror . BadRequest ( "Invalid payload" , err )
default :
return httperror . InternalServerError ( "Unable to create Edge stack" , err )
}
2020-05-14 05:14:28 +03:00
}
return response . JSON ( w , edgeStack )
}
2022-12-01 08:40:52 +02:00
func ( handler * Handler ) createSwarmStack ( method string , dryrun bool , userID portainer . UserID , r * http . Request ) ( * portainer . EdgeStack , error ) {
2020-05-14 05:14:28 +03:00
switch method {
case "string" :
2022-12-01 08:40:52 +02:00
return handler . createSwarmStackFromFileContent ( r , dryrun )
2020-05-14 05:14:28 +03:00
case "repository" :
2022-12-01 08:40:52 +02:00
return handler . createSwarmStackFromGitRepository ( r , dryrun , userID )
2020-05-14 05:14:28 +03:00
case "file" :
2022-12-01 08:40:52 +02:00
return handler . createSwarmStackFromFileUpload ( r , dryrun )
2020-05-14 05:14:28 +03:00
}
2023-05-04 10:01:33 +12:00
return nil , edgestackservice . NewInvalidPayloadError ( "Invalid value for query parameter: method. Value must be one of: string, repository or file" )
2020-05-14 05:14:28 +03:00
}
type swarmStackFromFileContentPayload struct {
2021-02-23 05:21:39 +02:00
// Name of the stack
Name string ` example:"myStack" validate:"required" `
// Content of the Stack file
StackFileContent string ` example:"version: 3\n services:\n web:\n image:nginx" validate:"required" `
// List of identifiers of EdgeGroups
EdgeGroups [ ] portainer . EdgeGroupID ` example:"1" `
2021-09-09 11:38:34 +03:00
// Deployment type to deploy this stack
2022-12-01 08:40:52 +02:00
// Valid values are: 0 - 'compose', 1 - 'kubernetes', 2 - 'nomad'
2021-09-20 12:14:22 +12:00
// for compose stacks will use kompose to convert to kubernetes manifest for kubernetes environments(endpoints)
2022-12-01 08:40:52 +02:00
// kubernetes deploy type is enabled only for kubernetes environments(endpoints)
// nomad deploy type is enabled only for nomad environments(endpoints)
DeploymentType portainer . EdgeStackDeploymentType ` example:"0" enums:"0,1,2" `
// List of Registries to use for this stack
Registries [ ] portainer . RegistryID
2022-12-13 22:56:47 +02:00
// Uses the manifest's namespaces instead of the default one
UseManifestNamespaces bool
2020-05-14 05:14:28 +03:00
}
func ( payload * swarmStackFromFileContentPayload ) Validate ( r * http . Request ) error {
if govalidator . IsNull ( payload . Name ) {
2023-05-04 10:01:33 +12:00
return edgestackservice . NewInvalidPayloadError ( "Invalid stack name" )
2020-05-14 05:14:28 +03:00
}
if govalidator . IsNull ( payload . StackFileContent ) {
2023-05-04 10:01:33 +12:00
return edgestackservice . NewInvalidPayloadError ( "Invalid stack file content" )
2020-05-14 05:14:28 +03:00
}
2022-12-30 15:26:46 -03:00
if len ( payload . EdgeGroups ) == 0 {
2023-05-04 10:01:33 +12:00
return edgestackservice . NewInvalidPayloadError ( "Edge Groups are mandatory for an Edge stack" )
2020-05-14 05:14:28 +03:00
}
return nil
}
2023-04-27 11:03:55 +07:00
// @id EdgeStackCreateString
// @summary Create an EdgeStack from a text
// @description **Access policy**: administrator
// @tags edge_stacks
// @security ApiKeyAuth
// @security jwt
// @produce json
// @param body body swarmStackFromFileContentPayload true "stack config"
// @param dryrun query string false "if true, will not create an edge stack, but just will check the settings and return a non-persisted edge stack object"
// @success 200 {object} portainer.EdgeStack
2023-05-04 10:01:33 +12:00
// @failure 400 "Bad request"
// @failure 500 "Internal server error"
2023-04-27 11:03:55 +07:00
// @failure 503 "Edge compute features are disabled"
// @router /edge_stacks/create/string [post]
2022-12-01 08:40:52 +02:00
func ( handler * Handler ) createSwarmStackFromFileContent ( r * http . Request , dryrun bool ) ( * portainer . EdgeStack , error ) {
2020-05-14 05:14:28 +03:00
var payload swarmStackFromFileContentPayload
err := request . DecodeAndValidateJSONPayload ( r , & payload )
if err != nil {
return nil , err
}
2022-12-13 22:56:47 +02:00
stack , err := handler . edgeStacksService . BuildEdgeStack ( payload . Name , payload . DeploymentType , payload . EdgeGroups , payload . Registries , payload . UseManifestNamespaces )
2020-05-14 05:14:28 +03:00
if err != nil {
2022-12-01 08:40:52 +02:00
return nil , errors . Wrap ( err , "failed to create Edge stack object" )
2020-05-14 05:14:28 +03:00
}
2022-12-01 08:40:52 +02:00
if dryrun {
return stack , nil
2021-09-09 11:38:34 +03:00
}
2022-12-01 08:40:52 +02:00
return handler . edgeStacksService . PersistEdgeStack ( stack , func ( stackFolder string , relatedEndpointIds [ ] portainer . EndpointID ) ( composePath string , manifestPath string , projectPath string , err error ) {
return handler . storeFileContent ( stackFolder , payload . DeploymentType , relatedEndpointIds , [ ] byte ( payload . StackFileContent ) )
} )
2021-09-09 11:38:34 +03:00
2022-12-01 08:40:52 +02:00
}
2020-05-14 05:14:28 +03:00
2022-12-01 08:40:52 +02:00
func ( handler * Handler ) storeFileContent ( stackFolder string , deploymentType portainer . EdgeStackDeploymentType , relatedEndpointIds [ ] portainer . EndpointID , fileContent [ ] byte ) ( composePath , manifestPath , projectPath string , err error ) {
if deploymentType == portainer . EdgeStackDeploymentCompose {
composePath = filesystem . ComposeFileDefaultName
2021-09-09 11:38:34 +03:00
2022-12-01 08:40:52 +02:00
projectPath , err := handler . FileService . StoreEdgeStackFileFromBytes ( stackFolder , composePath , fileContent )
2021-09-09 11:38:34 +03:00
if err != nil {
2022-12-01 08:40:52 +02:00
return "" , "" , "" , err
2021-09-09 11:38:34 +03:00
}
2022-12-01 08:40:52 +02:00
manifestPath , err = handler . convertAndStoreKubeManifestIfNeeded ( stackFolder , projectPath , composePath , relatedEndpointIds )
2021-09-09 11:38:34 +03:00
if err != nil {
2022-12-01 08:40:52 +02:00
return "" , "" , "" , fmt . Errorf ( "Failed creating and storing kube manifest: %w" , err )
2021-09-09 11:38:34 +03:00
}
2022-12-01 08:40:52 +02:00
return composePath , manifestPath , projectPath , nil
2021-09-09 11:38:34 +03:00
2022-12-01 08:40:52 +02:00
}
hasDockerEndpoint , err := hasDockerEndpoint ( handler . DataStore . Endpoint ( ) , relatedEndpointIds )
if err != nil {
return "" , "" , "" , fmt . Errorf ( "unable to check for existence of docker environment: %w" , err )
}
2021-09-09 11:38:34 +03:00
2022-12-01 08:40:52 +02:00
if hasDockerEndpoint {
2023-05-04 10:01:33 +12:00
return "" , "" , "" , errors . New ( "edge stack with docker environment cannot be deployed with kubernetes or nomad config" )
2022-12-01 08:40:52 +02:00
}
2021-09-09 11:38:34 +03:00
2022-12-01 08:40:52 +02:00
if deploymentType == portainer . EdgeStackDeploymentKubernetes {
manifestPath = filesystem . ManifestFileDefaultName
projectPath , err := handler . FileService . StoreEdgeStackFileFromBytes ( stackFolder , manifestPath , fileContent )
2021-09-09 11:38:34 +03:00
if err != nil {
2022-12-01 08:40:52 +02:00
return "" , "" , "" , err
2021-09-09 11:38:34 +03:00
}
2022-12-01 08:40:52 +02:00
return "" , manifestPath , projectPath , nil
2020-05-14 05:14:28 +03:00
}
2023-05-04 10:01:33 +12:00
errMessage := fmt . Sprintf ( "invalid deployment type: %d" , deploymentType )
return "" , "" , "" , edgestackservice . NewInvalidPayloadError ( errMessage )
2020-05-14 05:14:28 +03:00
}
type swarmStackFromGitRepositoryPayload struct {
2021-02-23 05:21:39 +02:00
// Name of the stack
Name string ` example:"myStack" validate:"required" `
// URL of a Git repository hosting the Stack file
RepositoryURL string ` example:"https://github.com/openfaas/faas" validate:"required" `
// Reference name of a Git repository hosting the Stack file
RepositoryReferenceName string ` example:"refs/heads/master" `
// Use basic authentication to clone the Git repository
RepositoryAuthentication bool ` example:"true" `
// Username used in basic authentication. Required when RepositoryAuthentication is true.
RepositoryUsername string ` example:"myGitUsername" `
// Password used in basic authentication. Required when RepositoryAuthentication is true.
RepositoryPassword string ` example:"myGitPassword" `
// Path to the Stack file inside the Git repository
2021-09-09 11:38:34 +03:00
FilePathInRepository string ` example:"docker-compose.yml" default:"docker-compose.yml" `
2021-02-23 05:21:39 +02:00
// List of identifiers of EdgeGroups
EdgeGroups [ ] portainer . EdgeGroupID ` example:"1" `
2021-09-09 11:38:34 +03:00
// Deployment type to deploy this stack
2022-12-01 08:40:52 +02:00
// Valid values are: 0 - 'compose', 1 - 'kubernetes', 2 - 'nomad'
2021-09-20 12:14:22 +12:00
// for compose stacks will use kompose to convert to kubernetes manifest for kubernetes environments(endpoints)
2022-12-01 08:40:52 +02:00
// kubernetes deploy type is enabled only for kubernetes environments(endpoints)
// nomad deploy type is enabled only for nomad environments(endpoints)
DeploymentType portainer . EdgeStackDeploymentType ` example:"0" enums:"0,1,2" `
// List of Registries to use for this stack
Registries [ ] portainer . RegistryID
2022-12-13 22:56:47 +02:00
// Uses the manifest's namespaces instead of the default one
UseManifestNamespaces bool
2023-04-03 09:19:17 +03:00
// TLSSkipVerify skips SSL verification when cloning the Git repository
TLSSkipVerify bool ` example:"false" `
2020-05-14 05:14:28 +03:00
}
func ( payload * swarmStackFromGitRepositoryPayload ) Validate ( r * http . Request ) error {
if govalidator . IsNull ( payload . Name ) {
2023-05-04 10:01:33 +12:00
return edgestackservice . NewInvalidPayloadError ( "Invalid stack name" )
2020-05-14 05:14:28 +03:00
}
if govalidator . IsNull ( payload . RepositoryURL ) || ! govalidator . IsURL ( payload . RepositoryURL ) {
2023-05-04 10:01:33 +12:00
return edgestackservice . NewInvalidPayloadError ( "Invalid repository URL. Must correspond to a valid URL format" )
2020-05-14 05:14:28 +03:00
}
if payload . RepositoryAuthentication && ( govalidator . IsNull ( payload . RepositoryUsername ) || govalidator . IsNull ( payload . RepositoryPassword ) ) {
2023-05-04 10:01:33 +12:00
return edgestackservice . NewInvalidPayloadError ( "Invalid repository credentials. Username and password must be specified when authentication is enabled" )
2020-05-14 05:14:28 +03:00
}
2021-09-09 11:38:34 +03:00
if govalidator . IsNull ( payload . FilePathInRepository ) {
2022-12-01 08:40:52 +02:00
switch payload . DeploymentType {
case portainer . EdgeStackDeploymentCompose :
payload . FilePathInRepository = filesystem . ComposeFileDefaultName
case portainer . EdgeStackDeploymentKubernetes :
payload . FilePathInRepository = filesystem . ManifestFileDefaultName
}
2020-05-14 05:14:28 +03:00
}
2022-12-30 15:26:46 -03:00
if len ( payload . EdgeGroups ) == 0 {
2023-05-04 10:01:33 +12:00
return edgestackservice . NewInvalidPayloadError ( "Edge Groups are mandatory for an Edge stack" )
2020-05-14 05:14:28 +03:00
}
return nil
}
2023-04-27 11:03:55 +07:00
// @id EdgeStackCreateRepository
// @summary Create an EdgeStack from a git repository
// @description **Access policy**: administrator
// @tags edge_stacks
// @security ApiKeyAuth
// @security jwt
// @produce json
// @param method query string true "Creation Method" Enums(file,string,repository)
// @param body body swarmStackFromGitRepositoryPayload true "stack config"
// @param dryrun query string false "if true, will not create an edge stack, but just will check the settings and return a non-persisted edge stack object"
// @success 200 {object} portainer.EdgeStack
2023-05-04 10:01:33 +12:00
// @failure 400 "Bad request"
// @failure 500 "Internal server error"
2023-04-27 11:03:55 +07:00
// @failure 503 "Edge compute features are disabled"
// @router /edge_stacks/create/repository [post]
2022-12-01 08:40:52 +02:00
func ( handler * Handler ) createSwarmStackFromGitRepository ( r * http . Request , dryrun bool , userID portainer . UserID ) ( * portainer . EdgeStack , error ) {
2020-05-14 05:14:28 +03:00
var payload swarmStackFromGitRepositoryPayload
err := request . DecodeAndValidateJSONPayload ( r , & payload )
if err != nil {
return nil , err
}
2022-12-13 22:56:47 +02:00
stack , err := handler . edgeStacksService . BuildEdgeStack ( payload . Name , payload . DeploymentType , payload . EdgeGroups , payload . Registries , payload . UseManifestNamespaces )
2020-05-14 05:14:28 +03:00
if err != nil {
2022-12-01 08:40:52 +02:00
return nil , errors . Wrap ( err , "failed to create edge stack object" )
2020-05-14 05:14:28 +03:00
}
2022-12-01 08:40:52 +02:00
if dryrun {
return stack , nil
2020-05-14 05:14:28 +03:00
}
2022-12-01 08:40:52 +02:00
repoConfig := gittypes . RepoConfig {
2022-12-06 10:26:18 -03:00
URL : payload . RepositoryURL ,
ReferenceName : payload . RepositoryReferenceName ,
ConfigFilePath : payload . FilePathInRepository ,
2023-04-03 09:19:17 +03:00
TLSSkipVerify : payload . TLSSkipVerify ,
2021-06-22 19:59:05 +12:00
}
2022-12-01 08:40:52 +02:00
if payload . RepositoryAuthentication {
repoConfig . Authentication = & gittypes . GitAuthentication {
Username : payload . RepositoryUsername ,
Password : payload . RepositoryPassword ,
2021-09-09 11:38:34 +03:00
}
2020-05-14 05:14:28 +03:00
}
2022-12-01 08:40:52 +02:00
return handler . edgeStacksService . PersistEdgeStack ( stack , func ( stackFolder string , relatedEndpointIds [ ] portainer . EndpointID ) ( composePath string , manifestPath string , projectPath string , err error ) {
return handler . storeManifestFromGitRepository ( stackFolder , relatedEndpointIds , payload . DeploymentType , userID , repoConfig )
} )
2020-05-14 05:14:28 +03:00
}
type swarmStackFromFileUploadPayload struct {
Name string
StackFileContent [ ] byte
EdgeGroups [ ] portainer . EdgeGroupID
2022-12-01 08:40:52 +02:00
// Deployment type to deploy this stack
// Valid values are: 0 - 'compose', 1 - 'kubernetes', 2 - 'nomad'
// for compose stacks will use kompose to convert to kubernetes manifest for kubernetes environments(endpoints)
// kubernetes deploytype is enabled only for kubernetes environments(endpoints)
// nomad deploytype is enabled only for nomad environments(endpoints)
DeploymentType portainer . EdgeStackDeploymentType ` example:"0" enums:"0,1,2" `
Registries [ ] portainer . RegistryID
2022-12-13 22:56:47 +02:00
// Uses the manifest's namespaces instead of the default one
UseManifestNamespaces bool
2020-05-14 05:14:28 +03:00
}
func ( payload * swarmStackFromFileUploadPayload ) Validate ( r * http . Request ) error {
name , err := request . RetrieveMultiPartFormValue ( r , "Name" , false )
if err != nil {
2023-05-04 10:01:33 +12:00
return edgestackservice . NewInvalidPayloadError ( "Invalid stack name" )
2020-05-14 05:14:28 +03:00
}
payload . Name = name
composeFileContent , _ , err := request . RetrieveMultiPartFormFile ( r , "file" )
if err != nil {
2023-05-04 10:01:33 +12:00
return edgestackservice . NewInvalidPayloadError ( "Invalid Compose file. Ensure that the Compose file is uploaded correctly" )
2020-05-14 05:14:28 +03:00
}
payload . StackFileContent = composeFileContent
var edgeGroups [ ] portainer . EdgeGroupID
err = request . RetrieveMultiPartFormJSONValue ( r , "EdgeGroups" , & edgeGroups , false )
if err != nil || len ( edgeGroups ) == 0 {
2023-05-04 10:01:33 +12:00
return edgestackservice . NewInvalidPayloadError ( "Edge Groups are mandatory for an Edge stack" )
2020-05-14 05:14:28 +03:00
}
payload . EdgeGroups = edgeGroups
2021-09-09 11:38:34 +03:00
2023-04-27 11:03:55 +07:00
deploymentType , err := request . RetrieveNumericMultiPartFormValue ( r , "DeploymentType" , false )
2021-09-09 11:38:34 +03:00
if err != nil {
2023-05-04 10:01:33 +12:00
return edgestackservice . NewInvalidPayloadError ( "Invalid deployment type" )
2021-09-09 11:38:34 +03:00
}
payload . DeploymentType = portainer . EdgeStackDeploymentType ( deploymentType )
2022-12-01 08:40:52 +02:00
var registries [ ] portainer . RegistryID
2023-04-27 11:03:55 +07:00
err = request . RetrieveMultiPartFormJSONValue ( r , "Registries" , & registries , true )
2022-12-01 08:40:52 +02:00
if err != nil {
return errors . New ( "Invalid registry type" )
}
payload . Registries = registries
2022-12-13 22:56:47 +02:00
useManifestNamespaces , _ := request . RetrieveBooleanMultiPartFormValue ( r , "UseManifestNamespaces" , true )
payload . UseManifestNamespaces = useManifestNamespaces
2020-05-14 05:14:28 +03:00
return nil
}
2023-04-27 11:03:55 +07:00
// @id EdgeStackCreateFile
// @summary Create an EdgeStack from file
// @description **Access policy**: administrator
// @tags edge_stacks
// @security ApiKeyAuth
// @security jwt
// @accept multipart/form-data
// @produce json
// @param Name formData string true "Name of the stack"
// @param file formData file true "Content of the Stack file"
// @param EdgeGroups formData string true "JSON stringified array of Edge Groups ids"
// @param DeploymentType formData int true "deploy type 0 - 'compose', 1 - 'kubernetes', 2 - 'nomad'"
// @param Registries formData string false "JSON stringified array of Registry ids to use for this stack"
// @param UseManifestNamespaces formData bool false "Uses the manifest's namespaces instead of the default one, relevant only for kube environments"
// @param PrePullImage formData bool false "Pre Pull image"
// @param RetryDeploy formData bool false "Retry deploy"
// @param dryrun query string false "if true, will not create an edge stack, but just will check the settings and return a non-persisted edge stack object"
// @success 200 {object} portainer.EdgeStack
2023-05-04 10:01:33 +12:00
// @failure 400 "Bad request"
// @failure 500 "Internal server error"
2023-04-27 11:03:55 +07:00
// @failure 503 "Edge compute features are disabled"
// @router /edge_stacks/create/file [post]
2022-12-01 08:40:52 +02:00
func ( handler * Handler ) createSwarmStackFromFileUpload ( r * http . Request , dryrun bool ) ( * portainer . EdgeStack , error ) {
2020-05-14 05:14:28 +03:00
payload := & swarmStackFromFileUploadPayload { }
err := payload . Validate ( r )
if err != nil {
return nil , err
}
2022-12-13 22:56:47 +02:00
stack , err := handler . edgeStacksService . BuildEdgeStack ( payload . Name , payload . DeploymentType , payload . EdgeGroups , payload . Registries , payload . UseManifestNamespaces )
2021-09-09 11:38:34 +03:00
if err != nil {
2022-12-01 08:40:52 +02:00
return nil , errors . Wrap ( err , "failed to create edge stack object" )
2021-09-09 11:38:34 +03:00
}
2022-12-01 08:40:52 +02:00
if dryrun {
return stack , nil
2020-05-14 05:14:28 +03:00
}
2022-12-01 08:40:52 +02:00
return handler . edgeStacksService . PersistEdgeStack ( stack , func ( stackFolder string , relatedEndpointIds [ ] portainer . EndpointID ) ( composePath string , manifestPath string , projectPath string , err error ) {
return handler . storeFileContent ( stackFolder , payload . DeploymentType , relatedEndpointIds , payload . StackFileContent )
} )
}
2021-09-09 11:38:34 +03:00
2022-12-01 08:40:52 +02:00
func ( handler * Handler ) storeManifestFromGitRepository ( stackFolder string , relatedEndpointIds [ ] portainer . EndpointID , deploymentType portainer . EdgeStackDeploymentType , currentUserID portainer . UserID , repositoryConfig gittypes . RepoConfig ) ( composePath , manifestPath , projectPath string , err error ) {
projectPath = handler . FileService . GetEdgeStackProjectPath ( stackFolder )
repositoryUsername := ""
repositoryPassword := ""
2023-01-03 10:49:29 -03:00
if repositoryConfig . Authentication != nil && repositoryConfig . Authentication . Password != "" {
repositoryUsername = repositoryConfig . Authentication . Username
repositoryPassword = repositoryConfig . Authentication . Password
2021-09-09 11:38:34 +03:00
}
2023-04-03 09:19:17 +03:00
err = handler . GitService . CloneRepository ( projectPath , repositoryConfig . URL , repositoryConfig . ReferenceName , repositoryUsername , repositoryPassword , repositoryConfig . TLSSkipVerify )
2020-05-14 05:14:28 +03:00
if err != nil {
2022-12-01 08:40:52 +02:00
return "" , "" , "" , err
2020-05-14 05:14:28 +03:00
}
2022-12-01 08:40:52 +02:00
if deploymentType == portainer . EdgeStackDeploymentCompose {
composePath := repositoryConfig . ConfigFilePath
2020-05-14 05:14:28 +03:00
2022-12-01 08:40:52 +02:00
manifestPath , err := handler . convertAndStoreKubeManifestIfNeeded ( stackFolder , projectPath , composePath , relatedEndpointIds )
2021-09-09 11:38:34 +03:00
if err != nil {
2022-12-01 08:40:52 +02:00
return "" , "" , "" , fmt . Errorf ( "Failed creating and storing kube manifest: %w" , err )
2021-09-09 11:38:34 +03:00
}
2022-12-01 08:40:52 +02:00
return composePath , manifestPath , projectPath , nil
}
2021-09-09 11:38:34 +03:00
2022-12-01 08:40:52 +02:00
if deploymentType == portainer . EdgeStackDeploymentKubernetes {
return "" , repositoryConfig . ConfigFilePath , projectPath , nil
2021-09-09 11:38:34 +03:00
}
2023-05-04 10:01:33 +12:00
errMessage := fmt . Sprintf ( "unknown deployment type: %d" , deploymentType )
return "" , "" , "" , edgestackservice . NewInvalidPayloadError ( errMessage )
2021-09-09 11:38:34 +03:00
}