mirror of https://github.com/portainer/portainer
feat(endpoints): filter by ids and/or tag ids (#3690)
* feat(endpoints): add filter by tagIds * refactor(endpoints): change endpoints service to query by tagIds * fix(endpoints): filter by tags * feat(endpoints): filter by endpoint groups tags * feat(endpoints): filter by idspull/3692/head^2
parent
df13f3b4cc
commit
2542d30a09
|
@ -30,6 +30,12 @@ func (handler *Handler) endpointList(w http.ResponseWriter, r *http.Request) *ht
|
||||||
limit, _ := request.RetrieveNumericQueryParameter(r, "limit", true)
|
limit, _ := request.RetrieveNumericQueryParameter(r, "limit", true)
|
||||||
endpointType, _ := request.RetrieveNumericQueryParameter(r, "type", true)
|
endpointType, _ := request.RetrieveNumericQueryParameter(r, "type", true)
|
||||||
|
|
||||||
|
var tagIDs []portainer.TagID
|
||||||
|
request.RetrieveJSONQueryParameter(r, "tagIds", &tagIDs, true)
|
||||||
|
|
||||||
|
var endpointIDs []portainer.EndpointID
|
||||||
|
request.RetrieveJSONQueryParameter(r, "endpointIds", &endpointIDs, true)
|
||||||
|
|
||||||
endpointGroups, err := handler.EndpointGroupService.EndpointGroups()
|
endpointGroups, err := handler.EndpointGroupService.EndpointGroups()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve endpoint groups from the database", err}
|
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve endpoint groups from the database", err}
|
||||||
|
@ -47,6 +53,10 @@ func (handler *Handler) endpointList(w http.ResponseWriter, r *http.Request) *ht
|
||||||
|
|
||||||
filteredEndpoints := security.FilterEndpoints(endpoints, endpointGroups, securityContext)
|
filteredEndpoints := security.FilterEndpoints(endpoints, endpointGroups, securityContext)
|
||||||
|
|
||||||
|
if endpointIDs != nil {
|
||||||
|
filteredEndpoints = filteredEndpointsByIds(filteredEndpoints, endpointIDs)
|
||||||
|
}
|
||||||
|
|
||||||
if groupID != 0 {
|
if groupID != 0 {
|
||||||
filteredEndpoints = filterEndpointsByGroupID(filteredEndpoints, portainer.EndpointGroupID(groupID))
|
filteredEndpoints = filterEndpointsByGroupID(filteredEndpoints, portainer.EndpointGroupID(groupID))
|
||||||
}
|
}
|
||||||
|
@ -67,6 +77,10 @@ func (handler *Handler) endpointList(w http.ResponseWriter, r *http.Request) *ht
|
||||||
filteredEndpoints = filterEndpointsByType(filteredEndpoints, portainer.EndpointType(endpointType))
|
filteredEndpoints = filterEndpointsByType(filteredEndpoints, portainer.EndpointType(endpointType))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tagIDs != nil {
|
||||||
|
filteredEndpoints = filteredEndpointsByTags(filteredEndpoints, tagIDs, endpointGroups)
|
||||||
|
}
|
||||||
|
|
||||||
filteredEndpointCount := len(filteredEndpoints)
|
filteredEndpointCount := len(filteredEndpoints)
|
||||||
|
|
||||||
paginatedEndpoints := paginateEndpoints(filteredEndpoints, start, limit)
|
paginatedEndpoints := paginateEndpoints(filteredEndpoints, start, limit)
|
||||||
|
@ -187,3 +201,58 @@ func convertTagIDsToTags(tagsMap map[portainer.TagID]string, tagIDs []portainer.
|
||||||
}
|
}
|
||||||
return tags
|
return tags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func filteredEndpointsByTags(endpoints []portainer.Endpoint, tagIDs []portainer.TagID, endpointGroups []portainer.EndpointGroup) []portainer.Endpoint {
|
||||||
|
filteredEndpoints := make([]portainer.Endpoint, 0)
|
||||||
|
|
||||||
|
for _, endpoint := range endpoints {
|
||||||
|
missingTags := make(map[portainer.TagID]bool)
|
||||||
|
for _, tagID := range tagIDs {
|
||||||
|
missingTags[tagID] = true
|
||||||
|
}
|
||||||
|
for _, tagID := range endpoint.TagIDs {
|
||||||
|
if missingTags[tagID] {
|
||||||
|
delete(missingTags, tagID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
missingTags = endpointGroupHasTags(endpoint.GroupID, endpointGroups, missingTags)
|
||||||
|
if len(missingTags) == 0 {
|
||||||
|
filteredEndpoints = append(filteredEndpoints, endpoint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filteredEndpoints
|
||||||
|
}
|
||||||
|
|
||||||
|
func endpointGroupHasTags(groupID portainer.EndpointGroupID, groups []portainer.EndpointGroup, missingTags map[portainer.TagID]bool) map[portainer.TagID]bool {
|
||||||
|
var endpointGroup portainer.EndpointGroup
|
||||||
|
for _, group := range groups {
|
||||||
|
if group.ID == groupID {
|
||||||
|
endpointGroup = group
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, tagID := range endpointGroup.TagIDs {
|
||||||
|
if missingTags[tagID] {
|
||||||
|
delete(missingTags, tagID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return missingTags
|
||||||
|
}
|
||||||
|
|
||||||
|
func filteredEndpointsByIds(endpoints []portainer.Endpoint, ids []portainer.EndpointID) []portainer.Endpoint {
|
||||||
|
filteredEndpoints := make([]portainer.Endpoint, 0)
|
||||||
|
|
||||||
|
idsSet := make(map[portainer.EndpointID]bool)
|
||||||
|
for _, id := range ids {
|
||||||
|
idsSet[id] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, endpoint := range endpoints {
|
||||||
|
if idsSet[endpoint.ID] {
|
||||||
|
filteredEndpoints = append(filteredEndpoints, endpoint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filteredEndpoints
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ function EndpointServiceFactory($q, Endpoints, FileUploadService) {
|
||||||
return Endpoints.get({id: endpointID}).$promise;
|
return Endpoints.get({id: endpointID}).$promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
service.endpoints = function(start, limit, search) {
|
service.endpoints = function(start, limit, { search, type, tagIds, endpointIds } = {}) {
|
||||||
return Endpoints.query({start, limit, search}).$promise;
|
return Endpoints.query({ start, limit, search, type, tagIds, endpointIds }).$promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
service.snapshotEndpoints = function() {
|
service.snapshotEndpoints = function() {
|
||||||
|
|
|
@ -22,10 +22,10 @@ function ($q, $scope, $state, EndpointService, GroupService, EndpointHelper, Not
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.getPaginatedEndpoints = getPaginatedEndpoints;
|
$scope.getPaginatedEndpoints = getPaginatedEndpoints;
|
||||||
function getPaginatedEndpoints(lastId, limit, filter) {
|
function getPaginatedEndpoints(lastId, limit, search) {
|
||||||
const deferred = $q.defer();
|
const deferred = $q.defer();
|
||||||
$q.all({
|
$q.all({
|
||||||
endpoints: EndpointService.endpoints(lastId, limit, filter),
|
endpoints: EndpointService.endpoints(lastId, limit, { search }),
|
||||||
groups: GroupService.groups()
|
groups: GroupService.groups()
|
||||||
})
|
})
|
||||||
.then(function success(data) {
|
.then(function success(data) {
|
||||||
|
|
|
@ -146,10 +146,10 @@ angular.module('portainer.app')
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.getPaginatedEndpoints = getPaginatedEndpoints;
|
$scope.getPaginatedEndpoints = getPaginatedEndpoints;
|
||||||
function getPaginatedEndpoints(lastId, limit, filter) {
|
function getPaginatedEndpoints(lastId, limit, search) {
|
||||||
const deferred = $q.defer();
|
const deferred = $q.defer();
|
||||||
$q.all({
|
$q.all({
|
||||||
endpoints: EndpointService.endpoints(lastId, limit, filter),
|
endpoints: EndpointService.endpoints(lastId, limit, {search}),
|
||||||
groups: GroupService.groups()
|
groups: GroupService.groups()
|
||||||
})
|
})
|
||||||
.then(function success(data) {
|
.then(function success(data) {
|
||||||
|
|
Loading…
Reference in New Issue