mirror of
https://github.com/portainer/portainer.git
synced 2025-08-05 05:45:22 +02:00
fix(endpointedge): optimize buildSchedules() BE-12099 (#955)
This commit is contained in:
parent
a46db61c4c
commit
e9ce3d2213
4 changed files with 114 additions and 26 deletions
|
@ -170,7 +170,7 @@ func (handler *Handler) inspectStatus(tx dataservices.DataStoreTx, r *http.Reque
|
|||
Credentials: tunnel.Credentials,
|
||||
}
|
||||
|
||||
schedules, handlerErr := handler.buildSchedules(tx, endpoint.ID)
|
||||
schedules, handlerErr := handler.buildSchedules(tx, endpoint)
|
||||
if handlerErr != nil {
|
||||
return nil, handlerErr
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ func parseAgentPlatform(r *http.Request) (portainer.EndpointType, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (handler *Handler) buildSchedules(tx dataservices.DataStoreTx, endpointID portainer.EndpointID) ([]edgeJobResponse, *httperror.HandlerError) {
|
||||
func (handler *Handler) buildSchedules(tx dataservices.DataStoreTx, endpoint *portainer.Endpoint) ([]edgeJobResponse, *httperror.HandlerError) {
|
||||
schedules := []edgeJobResponse{}
|
||||
|
||||
edgeJobs, err := tx.EdgeJob().ReadAll()
|
||||
|
@ -216,11 +216,16 @@ func (handler *Handler) buildSchedules(tx dataservices.DataStoreTx, endpointID p
|
|||
return nil, httperror.InternalServerError("Unable to retrieve Edge Jobs", err)
|
||||
}
|
||||
|
||||
endpointGroups, err := tx.EndpointGroup().ReadAll()
|
||||
if err != nil {
|
||||
return nil, httperror.InternalServerError("Unable to retrieve endpoint groups", err)
|
||||
}
|
||||
|
||||
for _, job := range edgeJobs {
|
||||
_, endpointHasJob := job.Endpoints[endpointID]
|
||||
_, endpointHasJob := job.Endpoints[endpoint.ID]
|
||||
if !endpointHasJob {
|
||||
for _, edgeGroupID := range job.EdgeGroups {
|
||||
member, _, err := edge.EndpointInEdgeGroup(tx, endpointID, edgeGroupID)
|
||||
member, _, err := edge.EndpointInEdgeGroup(tx, endpoint, edgeGroupID, endpointGroups)
|
||||
if err != nil {
|
||||
return nil, httperror.InternalServerError("Unable to retrieve relations", err)
|
||||
} else if member {
|
||||
|
@ -236,10 +241,10 @@ func (handler *Handler) buildSchedules(tx dataservices.DataStoreTx, endpointID p
|
|||
}
|
||||
|
||||
var collectLogs bool
|
||||
if _, ok := job.GroupLogsCollection[endpointID]; ok {
|
||||
collectLogs = job.GroupLogsCollection[endpointID].CollectLogs
|
||||
if _, ok := job.GroupLogsCollection[endpoint.ID]; ok {
|
||||
collectLogs = job.GroupLogsCollection[endpoint.ID].CollectLogs
|
||||
} else {
|
||||
collectLogs = job.Endpoints[endpointID].CollectLogs
|
||||
collectLogs = job.Endpoints[endpoint.ID].CollectLogs
|
||||
}
|
||||
|
||||
schedule := edgeJobResponse{
|
||||
|
|
|
@ -4,13 +4,22 @@ import (
|
|||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/dataservices"
|
||||
"github.com/portainer/portainer/api/internal/endpointutils"
|
||||
"github.com/portainer/portainer/api/roar"
|
||||
"github.com/portainer/portainer/api/tag"
|
||||
)
|
||||
|
||||
// EdgeGroupRelatedEndpoints returns a list of environments(endpoints) related to this Edge group
|
||||
func EdgeGroupRelatedEndpoints(edgeGroup *portainer.EdgeGroup, endpoints []portainer.Endpoint, endpointGroups []portainer.EndpointGroup) []portainer.EndpointID {
|
||||
if !edgeGroup.Dynamic {
|
||||
return edgeGroup.EndpointIDs.ToSlice()
|
||||
var r roar.Roar[portainer.EndpointID]
|
||||
|
||||
for _, endpoint := range endpoints {
|
||||
if edgeGroup.EndpointIDs.Contains(endpoint.ID) {
|
||||
r.Add(endpoint.ID)
|
||||
}
|
||||
}
|
||||
|
||||
return r.ToSlice()
|
||||
}
|
||||
|
||||
endpointGroupsMap := map[portainer.EndpointGroupID]*portainer.EndpointGroup{}
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
package edge
|
||||
|
||||
import (
|
||||
"slices"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/dataservices"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/portainer/portainer/api/internal/endpointutils"
|
||||
)
|
||||
|
||||
// EndpointRelatedEdgeStacks returns a list of Edge stacks related to this Environment(Endpoint)
|
||||
|
@ -47,27 +44,22 @@ func EffectiveCheckinInterval(tx dataservices.DataStoreTx, endpoint *portainer.E
|
|||
// EndpointInEdgeGroup returns true and the edge group name if the endpoint is in the edge group
|
||||
func EndpointInEdgeGroup(
|
||||
tx dataservices.DataStoreTx,
|
||||
endpointID portainer.EndpointID,
|
||||
endpoint *portainer.Endpoint,
|
||||
edgeGroupID portainer.EdgeGroupID,
|
||||
endpointGroups []portainer.EndpointGroup,
|
||||
) (bool, string, error) {
|
||||
endpointIDs, err := GetEndpointsFromEdgeGroups(
|
||||
[]portainer.EdgeGroupID{edgeGroupID}, tx,
|
||||
)
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
if !endpointutils.IsEdgeEndpoint(endpoint) || !endpoint.UserTrusted {
|
||||
return false, "", nil
|
||||
}
|
||||
|
||||
if slices.Contains(endpointIDs, endpointID) {
|
||||
edgeGroup, err := tx.EdgeGroup().Read(edgeGroupID)
|
||||
if err != nil {
|
||||
log.Warn().
|
||||
Err(err).
|
||||
Int("edgeGroupID", int(edgeGroupID)).
|
||||
Msg("Unable to retrieve edge group")
|
||||
|
||||
return false, "", err
|
||||
}
|
||||
|
||||
r := EdgeGroupRelatedEndpoints(edgeGroup, []portainer.Endpoint{*endpoint}, endpointGroups)
|
||||
|
||||
if len(r) > 0 {
|
||||
return true, edgeGroup.Name, nil
|
||||
}
|
||||
|
||||
|
|
82
api/internal/edge/endpoint_test.go
Normal file
82
api/internal/edge/endpoint_test.go
Normal file
|
@ -0,0 +1,82 @@
|
|||
package edge
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/datastore"
|
||||
"github.com/portainer/portainer/api/roar"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestEndpointInEdgeGroup(t *testing.T) {
|
||||
_, store := datastore.MustNewTestStore(t, true, false)
|
||||
|
||||
endpointGroups := []portainer.EndpointGroup{{ID: 1, Name: "test-group"}}
|
||||
|
||||
endpoint := &portainer.Endpoint{
|
||||
ID: 1,
|
||||
Name: "test-endpoint",
|
||||
Type: portainer.EdgeAgentOnDockerEnvironment,
|
||||
UserTrusted: true,
|
||||
GroupID: endpointGroups[0].ID,
|
||||
}
|
||||
edgeGroupID := portainer.EdgeGroupID(1)
|
||||
|
||||
untrustedEndpoint := &portainer.Endpoint{
|
||||
ID: 2,
|
||||
Name: "untrusted-endpoint",
|
||||
Type: portainer.EdgeAgentOnDockerEnvironment,
|
||||
UserTrusted: false,
|
||||
GroupID: endpointGroups[0].ID,
|
||||
}
|
||||
|
||||
nonEdgeEndpoint := &portainer.Endpoint{
|
||||
ID: 2,
|
||||
Name: "untrusted-endpoint",
|
||||
Type: portainer.AgentOnDockerEnvironment,
|
||||
UserTrusted: true,
|
||||
GroupID: endpointGroups[0].ID,
|
||||
}
|
||||
|
||||
err := store.EdgeGroup().Create(&portainer.EdgeGroup{
|
||||
ID: edgeGroupID,
|
||||
Name: "test-edge-group",
|
||||
Dynamic: false,
|
||||
EndpointIDs: roar.FromSlice([]portainer.EndpointID{endpoint.ID, untrustedEndpoint.ID}),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Related endpoint in a static edge group
|
||||
|
||||
inEdgeGroup, _, err := EndpointInEdgeGroup(store, endpoint, edgeGroupID, endpointGroups)
|
||||
require.NoError(t, err)
|
||||
require.True(t, inEdgeGroup)
|
||||
|
||||
// Unrelated endpoint in a static edge group
|
||||
|
||||
unrelatedEndpoint := &portainer.Endpoint{
|
||||
ID: 3,
|
||||
Name: "unrelated-endpoint",
|
||||
Type: portainer.EdgeAgentOnDockerEnvironment,
|
||||
UserTrusted: true,
|
||||
GroupID: 0,
|
||||
}
|
||||
|
||||
inEdgeGroup, _, err = EndpointInEdgeGroup(store, unrelatedEndpoint, edgeGroupID, endpointGroups)
|
||||
require.NoError(t, err)
|
||||
require.False(t, inEdgeGroup)
|
||||
|
||||
// Untrusted endpoint
|
||||
|
||||
inEdgeGroup, _, err = EndpointInEdgeGroup(store, untrustedEndpoint, edgeGroupID, endpointGroups)
|
||||
require.NoError(t, err)
|
||||
require.False(t, inEdgeGroup)
|
||||
|
||||
// Non-edge endpoint
|
||||
|
||||
inEdgeGroup, _, err = EndpointInEdgeGroup(store, nonEdgeEndpoint, edgeGroupID, endpointGroups)
|
||||
require.NoError(t, err)
|
||||
require.False(t, inEdgeGroup)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue