mirror of
https://github.com/portainer/portainer.git
synced 2025-07-19 13:29:41 +02:00
feat(stacks): scope stack names to endpoint (#4520)
* refactor(stack): create unique name function * refactor(stack): change stack resource control id * feat(stacks): validate stack unique name in endpoint * feat(stacks): prevent name collision with external stacks * refactor(stacks): move resource id util * refactor(stacks): supply resource id util with name and endpoint * fix(docker): calculate swarm resource id * feat(stack): prevent migration if stack name already exist * feat(authorization): use stackutils
This commit is contained in:
parent
a62e0496de
commit
86ad1c6af1
25 changed files with 245 additions and 99 deletions
|
@ -2,6 +2,7 @@ package stacks
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
|
@ -11,6 +12,7 @@ import (
|
|||
bolterrors "github.com/portainer/portainer/api/bolt/errors"
|
||||
httperrors "github.com/portainer/portainer/api/http/errors"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
"github.com/portainer/portainer/api/internal/stackutils"
|
||||
)
|
||||
|
||||
type stackMigratePayload struct {
|
||||
|
@ -76,7 +78,7 @@ func (handler *Handler) stackMigrate(w http.ResponseWriter, r *http.Request) *ht
|
|||
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access endpoint", err}
|
||||
}
|
||||
|
||||
resourceControl, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(stack.Name, portainer.StackResourceControl)
|
||||
resourceControl, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(stackutils.ResourceControlID(stack.EndpointID, stack.Name), portainer.StackResourceControl)
|
||||
if err != nil {
|
||||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve a resource control associated to the stack", err}
|
||||
}
|
||||
|
@ -122,6 +124,16 @@ func (handler *Handler) stackMigrate(w http.ResponseWriter, r *http.Request) *ht
|
|||
stack.Name = payload.Name
|
||||
}
|
||||
|
||||
isUnique, err := handler.checkUniqueName(targetEndpoint, stack.Name, stack.ID, stack.SwarmID != "")
|
||||
if err != nil {
|
||||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to check for name collision", err}
|
||||
}
|
||||
|
||||
if !isUnique {
|
||||
errorMessage := fmt.Sprintf("A stack with the name '%s' is already running on endpoint '%s'", stack.Name, targetEndpoint.Name)
|
||||
return &httperror.HandlerError{http.StatusConflict, errorMessage, errors.New(errorMessage)}
|
||||
}
|
||||
|
||||
migrationError := handler.migrateStack(r, stack, targetEndpoint)
|
||||
if migrationError != nil {
|
||||
return migrationError
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue