package endpoints import ( "net/http" "strconv" "strings" "github.com/portainer/portainer/api" "github.com/portainer/libhttp/request" httperror "github.com/portainer/libhttp/error" "github.com/portainer/libhttp/response" "github.com/portainer/portainer/api/http/security" ) // GET request on /api/endpoints?(start=)&(limit=)&(search=)&(groupId= endpointCount { start = endpointCount } end := start + limit if end > endpointCount { end = endpointCount } return endpoints[start:end] } func filterEndpointsByGroupID(endpoints []portainer.Endpoint, endpointGroupID portainer.EndpointGroupID) []portainer.Endpoint { filteredEndpoints := make([]portainer.Endpoint, 0) for _, endpoint := range endpoints { if endpoint.GroupID == endpointGroupID { filteredEndpoints = append(filteredEndpoints, endpoint) } } return filteredEndpoints } func filterEndpointsBySearchCriteria(endpoints []portainer.Endpoint, endpointGroups []portainer.EndpointGroup, tagsMap map[portainer.TagID]string, searchCriteria string) []portainer.Endpoint { filteredEndpoints := make([]portainer.Endpoint, 0) for _, endpoint := range endpoints { endpointTags := convertTagIDsToTags(tagsMap, endpoint.TagIDs) if endpointMatchSearchCriteria(&endpoint, endpointTags, searchCriteria) { filteredEndpoints = append(filteredEndpoints, endpoint) continue } if endpointGroupMatchSearchCriteria(&endpoint, endpointGroups, tagsMap, searchCriteria) { filteredEndpoints = append(filteredEndpoints, endpoint) } } return filteredEndpoints } func endpointMatchSearchCriteria(endpoint *portainer.Endpoint, tags []string, searchCriteria string) bool { if strings.Contains(strings.ToLower(endpoint.Name), searchCriteria) { return true } if strings.Contains(strings.ToLower(endpoint.URL), searchCriteria) { return true } if endpoint.Status == portainer.EndpointStatusUp && searchCriteria == "up" { return true } else if endpoint.Status == portainer.EndpointStatusDown && searchCriteria == "down" { return true } for _, tag := range tags { if strings.Contains(strings.ToLower(tag), searchCriteria) { return true } } return false } func endpointGroupMatchSearchCriteria(endpoint *portainer.Endpoint, endpointGroups []portainer.EndpointGroup, tagsMap map[portainer.TagID]string, searchCriteria string) bool { for _, group := range endpointGroups { if group.ID == endpoint.GroupID { if strings.Contains(strings.ToLower(group.Name), searchCriteria) { return true } tags := convertTagIDsToTags(tagsMap, group.TagIDs) for _, tag := range tags { if strings.Contains(strings.ToLower(tag), searchCriteria) { return true } } } } return false } func filterEndpointsByType(endpoints []portainer.Endpoint, endpointType portainer.EndpointType) []portainer.Endpoint { filteredEndpoints := make([]portainer.Endpoint, 0) for _, endpoint := range endpoints { if endpoint.Type == endpointType { filteredEndpoints = append(filteredEndpoints, endpoint) } } return filteredEndpoints } func convertTagIDsToTags(tagsMap map[portainer.TagID]string, tagIDs []portainer.TagID) []string { tags := make([]string, 0) for _, tagID := range tagIDs { tags = append(tags, tagsMap[tagID]) } return tags } func filteredEndpointsByTags(endpoints []portainer.Endpoint, tagIDs []portainer.TagID, endpointGroups []portainer.EndpointGroup, partialMatch bool) []portainer.Endpoint { filteredEndpoints := make([]portainer.Endpoint, 0) for _, endpoint := range endpoints { endpointGroup := getEndpointGroup(endpoint.GroupID, endpointGroups) endpointMatched := false if partialMatch { endpointMatched = endpointPartialMatchTags(endpoint, endpointGroup, tagIDs) } else { endpointMatched = endpointFullMatchTags(endpoint, endpointGroup, tagIDs) } if endpointMatched { filteredEndpoints = append(filteredEndpoints, endpoint) } } return filteredEndpoints } func getEndpointGroup(groupID portainer.EndpointGroupID, groups []portainer.EndpointGroup) portainer.EndpointGroup { var endpointGroup portainer.EndpointGroup for _, group := range groups { if group.ID == groupID { endpointGroup = group break } } return endpointGroup } func endpointPartialMatchTags(endpoint portainer.Endpoint, endpointGroup portainer.EndpointGroup, tagIDs []portainer.TagID) bool { tagSet := make(map[portainer.TagID]bool) for _, tagID := range tagIDs { tagSet[tagID] = true } for _, tagID := range endpoint.TagIDs { if tagSet[tagID] { return true } } for _, tagID := range endpointGroup.TagIDs { if tagSet[tagID] { return true } } return false } func endpointFullMatchTags(endpoint portainer.Endpoint, endpointGroup portainer.EndpointGroup, tagIDs []portainer.TagID) bool { missingTags := make(map[portainer.TagID]bool) for _, tagID := range tagIDs { missingTags[tagID] = true } for _, tagID := range endpoint.TagIDs { if missingTags[tagID] { delete(missingTags, tagID) } } for _, tagID := range endpointGroup.TagIDs { if missingTags[tagID] { delete(missingTags, tagID) } } return len(missingTags) == 0 } 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 }