1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-02 20:35:25 +02:00

feat(waiting-room): show and filter by check in [EE-5186] (#8701)

This commit is contained in:
Chaim Lev-Ari 2023-04-27 09:22:05 +07:00 committed by GitHub
parent b5771df6a8
commit 4b9c857d85
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 108 additions and 25 deletions

View file

@ -34,7 +34,7 @@ func NewService(connection portainer.Connection) (*Service, error) {
idxEdgeID: make(map[string]portainer.EndpointID),
}
es, err := s.Endpoints()
es, err := s.endpoints()
if err != nil {
return nil, err
}
@ -89,8 +89,7 @@ func (service *Service) DeleteEndpoint(ID portainer.EndpointID) error {
})
}
// Endpoints return an array containing all the environments(endpoints).
func (service *Service) Endpoints() ([]portainer.Endpoint, error) {
func (service *Service) endpoints() ([]portainer.Endpoint, error) {
var endpoints []portainer.Endpoint
var err error
@ -99,8 +98,14 @@ func (service *Service) Endpoints() ([]portainer.Endpoint, error) {
return err
})
return endpoints, err
}
// Endpoints return an array containing all the environments(endpoints).
func (service *Service) Endpoints() ([]portainer.Endpoint, error) {
endpoints, err := service.endpoints()
if err != nil {
return endpoints, err
return nil, err
}
for i, e := range endpoints {

View file

@ -117,6 +117,11 @@ func (handler *Handler) endpointEdgeStatusInspect(w http.ResponseWriter, r *http
return httperror.InternalServerError("Unable to Unable to persist environment changes inside the database", err)
}
err = handler.requestBouncer.TrustedEdgeEnvironmentAccess(endpoint)
if err != nil {
return httperror.Forbidden("Permission denied to access environment", err)
}
checkinInterval := endpoint.EdgeCheckinInterval
if endpoint.EdgeCheckinInterval == 0 {
settings, err := handler.DataStore.Settings().Settings()

View file

@ -45,6 +45,7 @@ const (
// @param agentVersions query []string false "will return only environments with on of these agent versions"
// @param edgeAsync query bool false "if exists true show only edge async agents, false show only standard edge agents. if missing, will show both types (relevant only for edge agents)"
// @param edgeDeviceUntrusted query bool false "if true, show only untrusted edge agents, if false show only trusted edge agents (relevant only for edge agents)"
// @param edgeCheckInPassedSeconds query number false "if bigger then zero, show only edge agents that checked-in in the last provided seconds (relevant only for edge agents)"
// @param name query string false "will return only environments(endpoints) with this name"
// @success 200 {array} portainer.Endpoint "Endpoints"
// @failure 500 "Server error"

View file

@ -23,11 +23,12 @@ type EnvironmentsQuery struct {
groupIds []portainer.EndpointGroupID
status []portainer.EndpointStatus
// if edgeAsync not nil, will filter edge endpoints based on this value
edgeAsync *bool
edgeDeviceUntrusted bool
excludeSnapshots bool
name string
agentVersions []string
edgeAsync *bool
edgeDeviceUntrusted bool
excludeSnapshots bool
name string
agentVersions []string
edgeCheckInPassedSeconds int
}
func parseQuery(r *http.Request) (EnvironmentsQuery, error) {
@ -77,19 +78,22 @@ func parseQuery(r *http.Request) (EnvironmentsQuery, error) {
excludeSnapshots, _ := request.RetrieveBooleanQueryParameter(r, "excludeSnapshots", true)
edgeCheckInPassedSeconds, _ := request.RetrieveNumericQueryParameter(r, "edgeCheckInPassedSeconds", true)
return EnvironmentsQuery{
search: search,
types: endpointTypes,
tagIds: tagIDs,
endpointIds: endpointIDs,
tagsPartialMatch: tagsPartialMatch,
groupIds: groupIDs,
status: status,
edgeAsync: edgeAsync,
edgeDeviceUntrusted: edgeDeviceUntrusted,
excludeSnapshots: excludeSnapshots,
name: name,
agentVersions: agentVersions,
search: search,
types: endpointTypes,
tagIds: tagIDs,
endpointIds: endpointIDs,
tagsPartialMatch: tagsPartialMatch,
groupIds: groupIDs,
status: status,
edgeAsync: edgeAsync,
edgeDeviceUntrusted: edgeDeviceUntrusted,
excludeSnapshots: excludeSnapshots,
name: name,
agentVersions: agentVersions,
edgeCheckInPassedSeconds: edgeCheckInPassedSeconds,
}, nil
}
@ -128,6 +132,22 @@ func (handler *Handler) filterEndpointsByQuery(filteredEndpoints []portainer.End
return endpoint.UserTrusted == !query.edgeDeviceUntrusted
})
if query.edgeCheckInPassedSeconds > 0 {
filteredEndpoints = filter(filteredEndpoints, func(endpoint portainer.Endpoint) bool {
// ignore non-edge endpoints
if !endpointutils.IsEdgeEndpoint(&endpoint) {
return true
}
// filter out endpoints that have never checked in
if endpoint.LastCheckInDate == 0 {
return false
}
return time.Now().Unix()-endpoint.LastCheckInDate < int64(query.edgeCheckInPassedSeconds)
})
}
if len(query.status) > 0 {
filteredEndpoints = filterEndpointsByStatuses(filteredEndpoints, query.status, settings)
}

View file

@ -1,12 +1,11 @@
package security
import (
"errors"
"fmt"
"net/http"
"strings"
"time"
"github.com/pkg/errors"
httperror "github.com/portainer/libhttp/error"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/apikey"
@ -147,13 +146,19 @@ func (bouncer *RequestBouncer) AuthorizedEdgeEndpointOperation(r *http.Request,
return errors.New("invalid Edge identifier")
}
if endpoint.LastCheckInDate > 0 || endpoint.UserTrusted {
return nil
}
// TrustedEdgeEnvironmentAccess defines a security check for Edge environments, checks if
// the request is coming from a trusted Edge environment
func (bouncer *RequestBouncer) TrustedEdgeEnvironmentAccess(endpoint *portainer.Endpoint) error {
if endpoint.UserTrusted {
return nil
}
settings, err := bouncer.dataStore.Settings().Settings()
if err != nil {
return fmt.Errorf("could not retrieve the settings: %w", err)
return errors.WithMessage(err, "could not retrieve the settings")
}
if !settings.TrustOnFirstConnect {