Пример #1
0
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
}
Пример #2
0
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)
}
Пример #3
0
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)
}
Пример #4
0
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)
}
Пример #5
0
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)
}
Пример #6
0
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)
}
Пример #7
0
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)
}
Пример #8
0
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)
}