diff --git a/api/http/handler/edgegroups/edgegroup_update.go b/api/http/handler/edgegroups/edgegroup_update.go index e67607d92..319a1b03b 100644 --- a/api/http/handler/edgegroups/edgegroup_update.go +++ b/api/http/handler/edgegroups/edgegroup_update.go @@ -186,6 +186,7 @@ func (handler *Handler) updateEndpointStacks(tx dataservices.DataStoreTx, endpoi if relation == nil { relation = &portainer.EndpointRelation{ EndpointID: endpoint.ID, + EdgeStacks: make(map[portainer.EdgeStackID]bool), } } relation.EdgeStacks = edgeStackSet diff --git a/api/http/handler/edgestacks/edgestack_update.go b/api/http/handler/edgestacks/edgestack_update.go index 9b5bb623d..593e403ef 100644 --- a/api/http/handler/edgestacks/edgestack_update.go +++ b/api/http/handler/edgestacks/edgestack_update.go @@ -107,7 +107,7 @@ func (handler *Handler) updateEdgeStack(tx dataservices.DataStoreTx, stackID por hasWrongType, err := hasWrongEnvironmentType(tx.Endpoint(), relatedEndpointIds, payload.DeploymentType) if err != nil { - return nil, httperror.BadRequest("unable to check for existence of non fitting environments: %w", err) + return nil, httperror.InternalServerError("unable to check for existence of non fitting environments: %w", err) } if hasWrongType { return nil, httperror.BadRequest("edge stack with config do not match the environment type", nil) @@ -151,6 +151,9 @@ func (handler *Handler) handleChangeEdgeGroups(tx dataservices.DataStoreTx, edge for endpointID := range endpointsToRemove { relation, err := tx.EndpointRelation().EndpointRelation(endpointID) if err != nil { + if tx.IsErrObjectNotFound(err) { + continue + } return nil, nil, errors.WithMessage(err, "Unable to find environment relation in database") } @@ -170,10 +173,16 @@ func (handler *Handler) handleChangeEdgeGroups(tx dataservices.DataStoreTx, edge for endpointID := range endpointsToAdd { relation, err := tx.EndpointRelation().EndpointRelation(endpointID) - if err != nil { + if err != nil && !tx.IsErrObjectNotFound(err) { return nil, nil, errors.WithMessage(err, "Unable to find environment relation in database") } + if relation == nil { + relation = &portainer.EndpointRelation{ + EndpointID: endpointID, + EdgeStacks: map[portainer.EdgeStackID]bool{}, + } + } relation.EdgeStacks[edgeStackID] = true if err := tx.EndpointRelation().UpdateEndpointRelation(endpointID, relation); err != nil { diff --git a/api/http/handler/endpointedge/endpointedge_status_inspect.go b/api/http/handler/endpointedge/endpointedge_status_inspect.go index 9bd341561..4d6368493 100644 --- a/api/http/handler/endpointedge/endpointedge_status_inspect.go +++ b/api/http/handler/endpointedge/endpointedge_status_inspect.go @@ -264,6 +264,9 @@ func (handler *Handler) buildSchedules(tx dataservices.DataStoreTx, endpointID p func (handler *Handler) buildEdgeStacks(tx dataservices.DataStoreTx, endpointID portainer.EndpointID) ([]stackStatusResponse, *httperror.HandlerError) { relation, err := tx.EndpointRelation().EndpointRelation(endpointID) if err != nil { + if tx.IsErrObjectNotFound(err) { + return nil, nil + } return nil, httperror.InternalServerError("Unable to retrieve relation object from the database", err) } diff --git a/api/http/handler/endpointgroups/endpoints.go b/api/http/handler/endpointgroups/endpoints.go index b7c9771bb..b34032d9e 100644 --- a/api/http/handler/endpointgroups/endpoints.go +++ b/api/http/handler/endpointgroups/endpoints.go @@ -21,10 +21,17 @@ func (handler *Handler) updateEndpointRelations(tx dataservices.DataStoreTx, end } endpointRelation, err := tx.EndpointRelation().EndpointRelation(endpoint.ID) - if err != nil { + if err != nil && !tx.IsErrObjectNotFound(err) { return err } + if endpointRelation == nil { + endpointRelation = &portainer.EndpointRelation{ + EndpointID: endpoint.ID, + EdgeStacks: make(map[portainer.EdgeStackID]bool), + } + } + edgeGroups, err := tx.EdgeGroup().ReadAll() if err != nil { return err @@ -32,6 +39,9 @@ func (handler *Handler) updateEndpointRelations(tx dataservices.DataStoreTx, end edgeStacks, err := tx.EdgeStack().EdgeStacks() if err != nil { + if tx.IsErrObjectNotFound(err) { + return nil + } return err } diff --git a/api/http/handler/endpoints/update_edge_relations.go b/api/http/handler/endpoints/update_edge_relations.go index 8bebadedd..1390c9fd4 100644 --- a/api/http/handler/endpoints/update_edge_relations.go +++ b/api/http/handler/endpoints/update_edge_relations.go @@ -23,6 +23,7 @@ func (handler *Handler) updateEdgeRelations(tx dataservices.DataStoreTx, endpoin relation = &portainer.EndpointRelation{ EndpointID: endpoint.ID, + EdgeStacks: map[portainer.EdgeStackID]bool{}, } if err := tx.EndpointRelation().Create(relation); err != nil { return errors.WithMessage(err, "Unable to create environment relation inside the database") diff --git a/api/http/handler/tags/tag_delete.go b/api/http/handler/tags/tag_delete.go index ad8ef1347..4f8554faf 100644 --- a/api/http/handler/tags/tag_delete.go +++ b/api/http/handler/tags/tag_delete.go @@ -133,10 +133,17 @@ func deleteTag(tx dataservices.DataStoreTx, tagID portainer.TagID) error { func updateEndpointRelations(tx dataservices.DataStoreTx, endpoint portainer.Endpoint, edgeGroups []portainer.EdgeGroup, edgeStacks []portainer.EdgeStack) error { endpointRelation, err := tx.EndpointRelation().EndpointRelation(endpoint.ID) - if err != nil { + if err != nil && !tx.IsErrObjectNotFound(err) { return err } + if endpointRelation == nil { + endpointRelation = &portainer.EndpointRelation{ + EndpointID: endpoint.ID, + EdgeStacks: make(map[portainer.EdgeStackID]bool), + } + } + endpointGroup, err := tx.EndpointGroup().Read(endpoint.GroupID) if err != nil { return err @@ -147,6 +154,7 @@ func updateEndpointRelations(tx dataservices.DataStoreTx, endpoint portainer.End for _, edgeStackID := range endpointStacks { stacksSet[edgeStackID] = true } + endpointRelation.EdgeStacks = stacksSet return tx.EndpointRelation().UpdateEndpointRelation(endpoint.ID, endpointRelation) diff --git a/api/internal/edge/edgestacks/service.go b/api/internal/edge/edgestacks/service.go index 4fc6943af..3a19e8c9d 100644 --- a/api/internal/edge/edgestacks/service.go +++ b/api/internal/edge/edgestacks/service.go @@ -11,6 +11,7 @@ import ( httperrors "github.com/portainer/portainer/api/http/errors" "github.com/portainer/portainer/api/internal/edge" edgetypes "github.com/portainer/portainer/api/internal/edge/types" + "github.com/rs/zerolog/log" "github.com/pkg/errors" ) @@ -119,6 +120,9 @@ func (service *Service) updateEndpointRelations(tx dataservices.DataStoreTx, edg for _, endpointID := range relatedEndpointIds { relation, err := endpointRelationService.EndpointRelation(endpointID) if err != nil { + if tx.IsErrObjectNotFound(err) { + continue + } return fmt.Errorf("unable to find endpoint relation in database: %w", err) } @@ -147,6 +151,14 @@ func (service *Service) DeleteEdgeStack(tx dataservices.DataStoreTx, edgeStackID for _, endpointID := range relatedEndpointIds { relation, err := tx.EndpointRelation().EndpointRelation(endpointID) if err != nil { + if tx.IsErrObjectNotFound(err) { + log.Warn(). + Int("endpoint_id", int(endpointID)). + Msg("Unable to find endpoint relation in database, skipping") + + continue + } + return errors.WithMessage(err, "Unable to find environment relation in database") }