func (library *Library) expandGroup(name string, groupType int, sourceName string) []string { item, err := library.GetItemByName(name, groupType) if err != nil { logger.Log(logger.LevelError, "library", "expand group: unknown group `%s': %s", name, err) return []string{} } // Parse group entries for patterns group := item.(*Group) result := []string{} for _, entry := range group.Entries { subResult := []string{} if groupType == LibraryItemSourceGroup { origin, err := library.Catalog.GetOrigin(entry.Origin) if err != nil { logger.Log(logger.LevelError, "library", "%s", err) continue } for _, source := range origin.GetSources() { if utils.FilterMatch(entry.Pattern, source.Name) { subResult = append(subResult, source.Name) } } } else { source, err := library.Catalog.GetSource(entry.Origin, sourceName) if err != nil { logger.Log(logger.LevelError, "library", "%s", err) continue } for _, metric := range source.GetMetrics() { if utils.FilterMatch(entry.Pattern, metric.Name) { subResult = append(subResult, metric.Name) } } } // Preserve manual ordering if grouped with `Single' matching type if strings.HasPrefix(entry.Pattern, "glob:") || strings.HasPrefix(entry.Pattern, "regexp:") { sort.Strings(subResult) } // Merge all group items subresults result = append(result, subResult...) } return result }
func (server *Server) serveOriginList(writer http.ResponseWriter, request *http.Request) { var offset, limit int if response, status := server.parseListRequest(writer, request, &offset, &limit); status != http.StatusOK { server.serveResponse(writer, response, status) return } originSet := set.New(set.ThreadSafe) for _, origin := range server.Catalog.Origins { if request.FormValue("filter") != "" && !utils.FilterMatch(request.FormValue("filter"), origin.Name) { continue } originSet.Add(origin.Name) } response := &listResponse{ list: StringListResponse(set.StringSlice(originSet)), offset: offset, limit: limit, } server.applyResponseLimit(writer, request, response) server.serveResponse(writer, response.list, http.StatusOK) }
func (server *Server) serveScaleList(writer http.ResponseWriter, request *http.Request) { var offset, limit int if response, status := server.parseListRequest(writer, request, &offset, &limit); status != http.StatusOK { server.serveResponse(writer, response, status) return } // Fill scales list items := make(ItemListResponse, 0) for _, scale := range server.Library.Scales { if request.FormValue("filter") != "" && !utils.FilterMatch(request.FormValue("filter"), scale.Name) { continue } items = append(items, &ItemResponse{ ID: scale.ID, Name: scale.Name, Description: scale.Description, Modified: scale.Modified.Format(time.RFC3339), }) } response := &listResponse{ list: items, offset: offset, limit: limit, } server.applyResponseLimit(writer, request, response) server.serveResponse(writer, response.list, http.StatusOK) }
func (server *Server) serveGraphList(writer http.ResponseWriter, request *http.Request) { var offset, limit int if response, status := server.parseListRequest(writer, request, &offset, &limit); status != http.StatusOK { server.serveResponse(writer, response, status) return } graphSet := set.New(set.ThreadSafe) // Filter on collection if any if request.FormValue("collection") != "" { item, err := server.Library.GetItem(request.FormValue("collection"), library.LibraryItemCollection) if os.IsNotExist(err) { server.serveResponse(writer, serverResponse{mesgResourceNotFound}, http.StatusNotFound) return } else if err != nil { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, serverResponse{mesgUnhandledError}, http.StatusInternalServerError) return } collection := item.(*library.Collection) for _, graph := range collection.Entries { graphSet.Add(graph.ID) } } // Fill graphs list items := make(ItemListResponse, 0) for _, graph := range server.Library.Graphs { if !graphSet.IsEmpty() && !graphSet.Has(graph.ID) { continue } if request.FormValue("filter") != "" && !utils.FilterMatch(request.FormValue("filter"), graph.Name) { continue } items = append(items, &ItemResponse{ ID: graph.ID, Name: graph.Name, Description: graph.Description, Modified: graph.Modified.Format(time.RFC3339), }) } response := &listResponse{ list: items, offset: offset, limit: limit, } server.applyResponseLimit(writer, request, response) server.serveResponse(writer, response.list, http.StatusOK) }
func (server *Server) serveMetricList(writer http.ResponseWriter, request *http.Request) { var offset, limit int if response, status := server.parseListRequest(writer, request, &offset, &limit); status != http.StatusOK { server.serveResponse(writer, response, status) return } originName := request.FormValue("origin") sourceName := request.FormValue("source") sourceSet := set.New(set.ThreadSafe) if strings.HasPrefix(sourceName, library.LibraryGroupPrefix) { for _, entryName := range server.Library.ExpandGroup( strings.TrimPrefix(sourceName, library.LibraryGroupPrefix), library.LibraryItemSourceGroup, ) { sourceSet.Add(entryName) } } else if sourceName != "" { sourceSet.Add(sourceName) } metricSet := set.New(set.ThreadSafe) for _, origin := range server.Catalog.Origins { if originName != "" && origin.Name != originName { continue } for _, source := range origin.Sources { if sourceName != "" && sourceSet.IsEmpty() || !sourceSet.IsEmpty() && !sourceSet.Has(source.Name) { continue } for key := range source.Metrics { if request.FormValue("filter") != "" && !utils.FilterMatch(request.FormValue("filter"), key) { continue } metricSet.Add(key) } } } response := &listResponse{ list: StringListResponse(set.StringSlice(metricSet)), offset: offset, limit: limit, } server.applyResponseLimit(writer, request, response) server.serveResponse(writer, response.list, http.StatusOK) }
func (server *Server) serveGroupList(writer http.ResponseWriter, request *http.Request) { var ( items ItemListResponse offset, limit int ) if response, status := server.parseListRequest(writer, request, &offset, &limit); status != http.StatusOK { server.serveResponse(writer, response, status) return } // Fill groups list items = make(ItemListResponse, 0) isSource := routeMatch(request.URL.Path, urlLibraryPath+"sourcegroups") for _, group := range server.Library.Groups { if isSource && group.Type != library.LibraryItemSourceGroup || !isSource && group.Type != library.LibraryItemMetricGroup { continue } if request.FormValue("filter") != "" && !utils.FilterMatch(request.FormValue("filter"), group.Name) { continue } items = append(items, &ItemResponse{ ID: group.ID, Name: group.Name, Description: group.Description, Modified: group.Modified.Format(time.RFC3339), }) } response := &listResponse{ list: items, offset: offset, limit: limit, } server.applyResponseLimit(writer, request, response) server.serveResponse(writer, response.list, http.StatusOK) }
func (server *Server) serveCollectionList(writer http.ResponseWriter, request *http.Request) { var ( collection *library.Collection collectionStack []*library.Collection items CollectionListResponse offset, limit int ) if response, status := server.parseListRequest(writer, request, &offset, &limit); status != http.StatusOK { server.serveResponse(writer, response, status) return } // Check for item exclusion excludeSet := set.New(set.ThreadSafe) if request.FormValue("exclude") != "" { if item, err := server.Library.GetItem(request.FormValue("exclude"), library.LibraryItemCollection); err == nil { collectionStack = append(collectionStack, item.(*library.Collection)) } for len(collectionStack) > 0 { collection, collectionStack = collectionStack[0], collectionStack[1:] excludeSet.Add(collection.ID) collectionStack = append(collectionStack, collection.Children...) } } // Fill collections list items = make(CollectionListResponse, 0) for _, collection := range server.Library.Collections { if request.FormValue("parent") == "null" && collection.Parent != nil || request.FormValue("parent") != "" && request.FormValue("parent") != "null" && (collection.Parent == nil || collection.Parent.ID != request.FormValue("parent")) { continue } if request.FormValue("filter") != "" && !utils.FilterMatch(request.FormValue("filter"), collection.Name) { continue } // Skip excluded items if excludeSet.Has(collection.ID) { continue } collectionItem := &CollectionResponse{ ItemResponse: ItemResponse{ ID: collection.ID, Name: collection.Name, Description: collection.Description, Modified: collection.Modified.Format(time.RFC3339), }, Options: collection.Options, HasChildren: len(collection.Children) > 0, } if collection.Parent != nil { collectionItem.Parent = &collection.Parent.ID } items = append(items, collectionItem) } response := &listResponse{ list: items, offset: offset, limit: limit, } server.applyResponseLimit(writer, request, response) server.serveResponse(writer, response.list, http.StatusOK) }
func (server *Server) serveGraphList(writer http.ResponseWriter, request *http.Request) { var ( items GraphListResponse offset, limit int ) if response, status := server.parseListRequest(writer, request, &offset, &limit); status != http.StatusOK { server.serveResponse(writer, response, status) return } graphSet := set.New(set.ThreadSafe) // Filter on collection if any if request.FormValue("collection") != "" { item, err := server.Library.GetItem(request.FormValue("collection"), library.LibraryItemCollection) if os.IsNotExist(err) { server.serveResponse(writer, serverResponse{mesgResourceNotFound}, http.StatusNotFound) return } else if err != nil { logger.Log(logger.LevelError, "server", "%s", err) server.serveResponse(writer, serverResponse{mesgUnhandledError}, http.StatusInternalServerError) return } collection := item.(*library.Collection) for _, graph := range collection.Entries { graphSet.Add(graph.ID) } } // Fill graphs list items = make(GraphListResponse, 0) // Flag for listing only graph templates listType := request.FormValue("type") if listType == "" { listType = "all" } else if listType != "raw" && listType != "template" && listType != "all" { logger.Log(logger.LevelWarning, "server", "unknown list type: %s", listType) server.serveResponse(writer, serverResponse{mesgRequestInvalid}, http.StatusBadRequest) return } for _, graph := range server.Library.Graphs { // Depending on the template flag, filter out either graphs or graph templates if request.FormValue("type") != "all" && (graph.Template && listType == "raw" || !graph.Template && listType == "template") { continue } // Filter out graphs that don't belong in the targeted collection if !graphSet.IsEmpty() && !graphSet.Has(graph.ID) { continue } if request.FormValue("filter") != "" && !utils.FilterMatch(request.FormValue("filter"), graph.Name) { continue } // If linked graph, expand the templated description field description := graph.Description if graph.Link != "" { item, err := server.Library.GetItem(graph.Link, library.LibraryItemGraph) if err != nil { logger.Log(logger.LevelError, "server", "graph template not found") } else { graphTemplate := item.(*library.Graph) if description, err = expandStringTemplate( graphTemplate.Description, graph.Attributes, ); err != nil { logger.Log(logger.LevelError, "server", "failed to expand graph description: %s", err) } } } items = append(items, &GraphResponse{ ItemResponse: ItemResponse{ ID: graph.ID, Name: graph.Name, Description: description, Modified: graph.Modified.Format(time.RFC3339), }, Link: graph.Link, Template: graph.Template, }) } response := &listResponse{ list: items, offset: offset, limit: limit, } server.applyResponseLimit(writer, request, response) server.serveResponse(writer, response.list, http.StatusOK) }