mirror of https://github.com/portainer/portainer
feat(stack): make stack created from app template editable EE-1941 (#6104)
feat(stack): make stack from app template editablepull/6233/head
parent
0627e16b35
commit
9f5ac154aa
|
@ -25,6 +25,8 @@ type composeStackFromFileContentPayload struct {
|
||||||
StackFileContent string `example:"version: 3\n services:\n web:\n image:nginx" validate:"required"`
|
StackFileContent string `example:"version: 3\n services:\n web:\n image:nginx" validate:"required"`
|
||||||
// A list of environment(endpoint) variables used during stack deployment
|
// A list of environment(endpoint) variables used during stack deployment
|
||||||
Env []portainer.Pair `example:""`
|
Env []portainer.Pair `example:""`
|
||||||
|
// Whether the stack is from a app template
|
||||||
|
FromAppTemplate bool `example:"false"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (payload *composeStackFromFileContentPayload) Validate(r *http.Request) error {
|
func (payload *composeStackFromFileContentPayload) Validate(r *http.Request) error {
|
||||||
|
@ -109,6 +111,7 @@ func (handler *Handler) createComposeStackFromFileContent(w http.ResponseWriter,
|
||||||
Env: payload.Env,
|
Env: payload.Env,
|
||||||
Status: portainer.StackStatusActive,
|
Status: portainer.StackStatusActive,
|
||||||
CreationDate: time.Now().Unix(),
|
CreationDate: time.Now().Unix(),
|
||||||
|
FromAppTemplate: payload.FromAppTemplate,
|
||||||
}
|
}
|
||||||
|
|
||||||
stackFolder := strconv.Itoa(int(stack.ID))
|
stackFolder := strconv.Itoa(int(stack.ID))
|
||||||
|
@ -163,6 +166,8 @@ type composeStackFromGitRepositoryPayload struct {
|
||||||
AutoUpdate *portainer.StackAutoUpdate
|
AutoUpdate *portainer.StackAutoUpdate
|
||||||
// A list of environment(endpoint) variables used during stack deployment
|
// A list of environment(endpoint) variables used during stack deployment
|
||||||
Env []portainer.Pair
|
Env []portainer.Pair
|
||||||
|
// Whether the stack is from a app template
|
||||||
|
FromAppTemplate bool `example:"false"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (payload *composeStackFromGitRepositoryPayload) Validate(r *http.Request) error {
|
func (payload *composeStackFromGitRepositoryPayload) Validate(r *http.Request) error {
|
||||||
|
@ -239,6 +244,7 @@ func (handler *Handler) createComposeStackFromGitRepository(w http.ResponseWrite
|
||||||
AdditionalFiles: payload.AdditionalFiles,
|
AdditionalFiles: payload.AdditionalFiles,
|
||||||
AutoUpdate: payload.AutoUpdate,
|
AutoUpdate: payload.AutoUpdate,
|
||||||
Env: payload.Env,
|
Env: payload.Env,
|
||||||
|
FromAppTemplate: payload.FromAppTemplate,
|
||||||
GitConfig: &gittypes.RepoConfig{
|
GitConfig: &gittypes.RepoConfig{
|
||||||
URL: payload.RepositoryURL,
|
URL: payload.RepositoryURL,
|
||||||
ReferenceName: payload.RepositoryReferenceName,
|
ReferenceName: payload.RepositoryReferenceName,
|
||||||
|
|
|
@ -26,6 +26,8 @@ type swarmStackFromFileContentPayload struct {
|
||||||
StackFileContent string `example:"version: 3\n services:\n web:\n image:nginx" validate:"required"`
|
StackFileContent string `example:"version: 3\n services:\n web:\n image:nginx" validate:"required"`
|
||||||
// A list of environment(endpoint) variables used during stack deployment
|
// A list of environment(endpoint) variables used during stack deployment
|
||||||
Env []portainer.Pair
|
Env []portainer.Pair
|
||||||
|
// Whether the stack is from a app template
|
||||||
|
FromAppTemplate bool `example:"false"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (payload *swarmStackFromFileContentPayload) Validate(r *http.Request) error {
|
func (payload *swarmStackFromFileContentPayload) Validate(r *http.Request) error {
|
||||||
|
@ -70,6 +72,7 @@ func (handler *Handler) createSwarmStackFromFileContent(w http.ResponseWriter, r
|
||||||
Env: payload.Env,
|
Env: payload.Env,
|
||||||
Status: portainer.StackStatusActive,
|
Status: portainer.StackStatusActive,
|
||||||
CreationDate: time.Now().Unix(),
|
CreationDate: time.Now().Unix(),
|
||||||
|
FromAppTemplate: payload.FromAppTemplate,
|
||||||
}
|
}
|
||||||
|
|
||||||
stackFolder := strconv.Itoa(int(stack.ID))
|
stackFolder := strconv.Itoa(int(stack.ID))
|
||||||
|
@ -121,6 +124,8 @@ type swarmStackFromGitRepositoryPayload struct {
|
||||||
RepositoryUsername string `example:"myGitUsername"`
|
RepositoryUsername string `example:"myGitUsername"`
|
||||||
// Password used in basic authentication. Required when RepositoryAuthentication is true.
|
// Password used in basic authentication. Required when RepositoryAuthentication is true.
|
||||||
RepositoryPassword string `example:"myGitPassword"`
|
RepositoryPassword string `example:"myGitPassword"`
|
||||||
|
// Whether the stack is from a app template
|
||||||
|
FromAppTemplate bool `example:"false"`
|
||||||
// Path to the Stack file inside the Git repository
|
// Path to the Stack file inside the Git repository
|
||||||
ComposeFile string `example:"docker-compose.yml" default:"docker-compose.yml"`
|
ComposeFile string `example:"docker-compose.yml" default:"docker-compose.yml"`
|
||||||
// Applicable when deploying with multiple stack files
|
// Applicable when deploying with multiple stack files
|
||||||
|
@ -189,6 +194,7 @@ func (handler *Handler) createSwarmStackFromGitRepository(w http.ResponseWriter,
|
||||||
EntryPoint: payload.ComposeFile,
|
EntryPoint: payload.ComposeFile,
|
||||||
AdditionalFiles: payload.AdditionalFiles,
|
AdditionalFiles: payload.AdditionalFiles,
|
||||||
AutoUpdate: payload.AutoUpdate,
|
AutoUpdate: payload.AutoUpdate,
|
||||||
|
FromAppTemplate: payload.FromAppTemplate,
|
||||||
GitConfig: &gittypes.RepoConfig{
|
GitConfig: &gittypes.RepoConfig{
|
||||||
URL: payload.RepositoryURL,
|
URL: payload.RepositoryURL,
|
||||||
ReferenceName: payload.RepositoryReferenceName,
|
ReferenceName: payload.RepositoryReferenceName,
|
||||||
|
|
|
@ -849,6 +849,8 @@ type (
|
||||||
AutoUpdate *StackAutoUpdate `json:"AutoUpdate"`
|
AutoUpdate *StackAutoUpdate `json:"AutoUpdate"`
|
||||||
// The git config of this stack
|
// The git config of this stack
|
||||||
GitConfig *gittypes.RepoConfig
|
GitConfig *gittypes.RepoConfig
|
||||||
|
// Whether the stack is from a app template
|
||||||
|
FromAppTemplate bool `example:"false"`
|
||||||
// Kubernetes namespace if stack is a kube application
|
// Kubernetes namespace if stack is a kube application
|
||||||
Namespace string `example:"default"`
|
Namespace string `example:"default"`
|
||||||
// IsComposeFormat indicates if the Kubernetes stack is created from a Docker Compose file
|
// IsComposeFormat indicates if the Kubernetes stack is created from a Docker Compose file
|
||||||
|
|
|
@ -21,6 +21,7 @@ export function StackViewModel(data) {
|
||||||
this.Orphaned = false;
|
this.Orphaned = false;
|
||||||
this.Checked = false;
|
this.Checked = false;
|
||||||
this.GitConfig = data.GitConfig;
|
this.GitConfig = data.GitConfig;
|
||||||
|
this.FromAppTemplate = data.FromAppTemplate;
|
||||||
this.AdditionalFiles = data.AdditionalFiles;
|
this.AdditionalFiles = data.AdditionalFiles;
|
||||||
this.AutoUpdate = data.AutoUpdate;
|
this.AutoUpdate = data.AutoUpdate;
|
||||||
}
|
}
|
||||||
|
|
|
@ -363,6 +363,7 @@ angular.module('portainer.app').factory('StackService', [
|
||||||
RepositoryUsername: repositoryOptions.RepositoryUsername,
|
RepositoryUsername: repositoryOptions.RepositoryUsername,
|
||||||
RepositoryPassword: repositoryOptions.RepositoryPassword,
|
RepositoryPassword: repositoryOptions.RepositoryPassword,
|
||||||
Env: env,
|
Env: env,
|
||||||
|
FromAppTemplate: repositoryOptions.FromAppTemplate,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (repositoryOptions.AutoUpdate) {
|
if (repositoryOptions.AutoUpdate) {
|
||||||
|
@ -389,6 +390,7 @@ angular.module('portainer.app').factory('StackService', [
|
||||||
RepositoryUsername: repositoryOptions.RepositoryUsername,
|
RepositoryUsername: repositoryOptions.RepositoryUsername,
|
||||||
RepositoryPassword: repositoryOptions.RepositoryPassword,
|
RepositoryPassword: repositoryOptions.RepositoryPassword,
|
||||||
Env: env,
|
Env: env,
|
||||||
|
FromAppTemplate: repositoryOptions.FromAppTemplate,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (repositoryOptions.AutoUpdate) {
|
if (repositoryOptions.AutoUpdate) {
|
||||||
|
|
|
@ -110,7 +110,8 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- !associate -->
|
<!-- !associate -->
|
||||||
|
|
||||||
<stack-redeploy-git-form ng-if="stack.GitConfig" model="stack.GitConfig" stack="stack" authorization="PortainerStackUpdate"> </stack-redeploy-git-form>
|
<stack-redeploy-git-form ng-if="stack.GitConfig && !stack.FromAppTemplate" model="stack.GitConfig" stack="stack" authorization="PortainerStackUpdate">
|
||||||
|
</stack-redeploy-git-form>
|
||||||
<stack-duplication-form
|
<stack-duplication-form
|
||||||
ng-if="regular && endpoints.length > 0"
|
ng-if="regular && endpoints.length > 0"
|
||||||
endpoints="endpoints"
|
endpoints="endpoints"
|
||||||
|
@ -125,7 +126,7 @@
|
||||||
</uib-tab>
|
</uib-tab>
|
||||||
<!-- !tab-info -->
|
<!-- !tab-info -->
|
||||||
<!-- tab-file -->
|
<!-- tab-file -->
|
||||||
<uib-tab index="1" select="showEditor()" ng-if="!external && !stack.GitConfig">
|
<uib-tab index="1" select="showEditor()" ng-if="!external && (!stack.GitConfig || stack.FromAppTemplate)">
|
||||||
<uib-tab-heading> <i class="fa fa-pencil-alt space-right" aria-hidden="true"></i> Editor </uib-tab-heading>
|
<uib-tab-heading> <i class="fa fa-pencil-alt space-right" aria-hidden="true"></i> Editor </uib-tab-heading>
|
||||||
<form class="form-horizontal" ng-if="state.showEditorTab" style="margin-top: 10px;" name="stackUpdateForm">
|
<form class="form-horizontal" ng-if="state.showEditorTab" style="margin-top: 10px;" name="stackUpdateForm">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -141,6 +141,7 @@ angular.module('portainer.app').controller('TemplatesController', [
|
||||||
var repositoryOptions = {
|
var repositoryOptions = {
|
||||||
RepositoryURL: template.Repository.url,
|
RepositoryURL: template.Repository.url,
|
||||||
ComposeFilePathInRepository: template.Repository.stackfile,
|
ComposeFilePathInRepository: template.Repository.stackfile,
|
||||||
|
FromAppTemplate: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const endpointId = +$state.params.endpointId;
|
const endpointId = +$state.params.endpointId;
|
||||||
|
@ -178,6 +179,7 @@ angular.module('portainer.app').controller('TemplatesController', [
|
||||||
var repositoryOptions = {
|
var repositoryOptions = {
|
||||||
RepositoryURL: template.Repository.url,
|
RepositoryURL: template.Repository.url,
|
||||||
ComposeFilePathInRepository: template.Repository.stackfile,
|
ComposeFilePathInRepository: template.Repository.stackfile,
|
||||||
|
FromAppTemplate: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const endpointId = +$state.params.endpointId;
|
const endpointId = +$state.params.endpointId;
|
||||||
|
|
Loading…
Reference in New Issue