feat(stacks): prevent name collision with external stacks (#16)

* feat(stacks): check for name collision within external stacks

* feat(stacks): check for name collisions

* feat(stacks): check for running stacks

* feat(stacks): change name collision message

* feat(stack): check for existing services only on swarm

* fix(http): supply docker factory to handler

* feat(stacks): look at all containers
This commit is contained in:
Chaim Lev-Ari
2020-11-03 04:50:18 +02:00
committed by GitHub
parent 812c0b34ea
commit 0e7cb4cb42
5 changed files with 89 additions and 43 deletions
+13 -22
View File
@@ -2,10 +2,10 @@ package stacks
import (
"errors"
"fmt"
"net/http"
"path"
"strconv"
"strings"
"github.com/asaskevich/govalidator"
httperror "github.com/portainer/libhttp/error"
@@ -42,15 +42,12 @@ func (handler *Handler) createSwarmStackFromFileContent(w http.ResponseWriter, r
return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err}
}
stacks, err := handler.DataStore.Stack().Stacks()
isUnique, err := handler.checkUniqueName(endpoint, payload.Name, 0, true)
if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve stacks from the database", err}
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to check for name collision", err}
}
for _, stack := range stacks {
if strings.EqualFold(stack.Name, payload.Name) {
return &httperror.HandlerError{http.StatusConflict, "A stack with this name already exists", errStackAlreadyExists}
}
if !isUnique {
return &httperror.HandlerError{http.StatusConflict, fmt.Sprintf("A stack with the name '%s' already exists", payload.Name), errStackAlreadyExists}
}
stackID := handler.DataStore.Stack().GetNextIdentifier()
@@ -132,15 +129,12 @@ func (handler *Handler) createSwarmStackFromGitRepository(w http.ResponseWriter,
return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err}
}
stacks, err := handler.DataStore.Stack().Stacks()
isUnique, err := handler.checkUniqueName(endpoint, payload.Name, 0, true)
if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve stacks from the database", err}
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to check for name collision", err}
}
for _, stack := range stacks {
if strings.EqualFold(stack.Name, payload.Name) {
return &httperror.HandlerError{http.StatusConflict, "A stack with this name already exists", errStackAlreadyExists}
}
if !isUnique {
return &httperror.HandlerError{http.StatusConflict, fmt.Sprintf("A stack with the name '%s' already exists", payload.Name), errStackAlreadyExists}
}
stackID := handler.DataStore.Stack().GetNextIdentifier()
@@ -236,15 +230,12 @@ func (handler *Handler) createSwarmStackFromFileUpload(w http.ResponseWriter, r
return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err}
}
stacks, err := handler.DataStore.Stack().Stacks()
isUnique, err := handler.checkUniqueName(endpoint, payload.Name, 0, true)
if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve stacks from the database", err}
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to check for name collision", err}
}
for _, stack := range stacks {
if strings.EqualFold(stack.Name, payload.Name) {
return &httperror.HandlerError{http.StatusConflict, "A stack with this name already exists", errStackAlreadyExists}
}
if !isUnique {
return &httperror.HandlerError{http.StatusConflict, fmt.Sprintf("A stack with the name '%s' already exists", payload.Name), errStackAlreadyExists}
}
stackID := handler.DataStore.Stack().GetNextIdentifier()