mirror of
https://github.com/portainer/portainer.git
synced 2025-07-24 07:49:41 +02:00
fix(edgegroups): fix data-race in edgeGroupCreate EE-4435 (#8477)
This commit is contained in:
parent
e66dea44e3
commit
f081631808
15 changed files with 800 additions and 317 deletions
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/dataservices"
|
||||
"github.com/portainer/portainer/api/internal/endpointutils"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
|
@ -54,45 +55,58 @@ func (handler *Handler) edgeGroupCreate(w http.ResponseWriter, r *http.Request)
|
|||
return httperror.BadRequest("Invalid request payload", err)
|
||||
}
|
||||
|
||||
edgeGroups, err := handler.DataStore.EdgeGroup().EdgeGroups()
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to retrieve Edge groups from the database", err)
|
||||
}
|
||||
var edgeGroup *portainer.EdgeGroup
|
||||
|
||||
for _, edgeGroup := range edgeGroups {
|
||||
if edgeGroup.Name == payload.Name {
|
||||
return httperror.BadRequest("Edge group name must be unique", errors.New("edge group name must be unique"))
|
||||
err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error {
|
||||
edgeGroups, err := tx.EdgeGroup().EdgeGroups()
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to retrieve Edge groups from the database", err)
|
||||
}
|
||||
}
|
||||
|
||||
edgeGroup := &portainer.EdgeGroup{
|
||||
Name: payload.Name,
|
||||
Dynamic: payload.Dynamic,
|
||||
TagIDs: []portainer.TagID{},
|
||||
Endpoints: []portainer.EndpointID{},
|
||||
PartialMatch: payload.PartialMatch,
|
||||
}
|
||||
|
||||
if edgeGroup.Dynamic {
|
||||
edgeGroup.TagIDs = payload.TagIDs
|
||||
} else {
|
||||
endpointIDs := []portainer.EndpointID{}
|
||||
for _, endpointID := range payload.Endpoints {
|
||||
endpoint, err := handler.DataStore.Endpoint().Endpoint(endpointID)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to retrieve environment from the database", err)
|
||||
}
|
||||
|
||||
if endpointutils.IsEdgeEndpoint(endpoint) {
|
||||
endpointIDs = append(endpointIDs, endpoint.ID)
|
||||
for _, edgeGroup := range edgeGroups {
|
||||
if edgeGroup.Name == payload.Name {
|
||||
return httperror.BadRequest("Edge group name must be unique", errors.New("edge group name must be unique"))
|
||||
}
|
||||
}
|
||||
edgeGroup.Endpoints = endpointIDs
|
||||
}
|
||||
|
||||
err = handler.DataStore.EdgeGroup().Create(edgeGroup)
|
||||
edgeGroup = &portainer.EdgeGroup{
|
||||
Name: payload.Name,
|
||||
Dynamic: payload.Dynamic,
|
||||
TagIDs: []portainer.TagID{},
|
||||
Endpoints: []portainer.EndpointID{},
|
||||
PartialMatch: payload.PartialMatch,
|
||||
}
|
||||
|
||||
if edgeGroup.Dynamic {
|
||||
edgeGroup.TagIDs = payload.TagIDs
|
||||
} else {
|
||||
endpointIDs := []portainer.EndpointID{}
|
||||
for _, endpointID := range payload.Endpoints {
|
||||
endpoint, err := tx.Endpoint().Endpoint(endpointID)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to retrieve environment from the database", err)
|
||||
}
|
||||
|
||||
if endpointutils.IsEdgeEndpoint(endpoint) {
|
||||
endpointIDs = append(endpointIDs, endpoint.ID)
|
||||
}
|
||||
}
|
||||
edgeGroup.Endpoints = endpointIDs
|
||||
}
|
||||
|
||||
err = tx.EdgeGroup().Create(edgeGroup)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to persist the Edge group inside the database", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to persist the Edge group inside the database", err)
|
||||
if httpErr, ok := err.(*httperror.HandlerError); ok {
|
||||
return httpErr
|
||||
}
|
||||
|
||||
return httperror.InternalServerError("Unexpected error", err)
|
||||
}
|
||||
|
||||
return response.JSON(w, edgeGroup)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue