mirror of
https://github.com/grafana/grafana.git
synced 2024-11-26 02:40:26 -06:00
168 lines
3.3 KiB
Go
168 lines
3.3 KiB
Go
package search
|
|
|
|
import (
|
|
"log"
|
|
"path/filepath"
|
|
"sort"
|
|
|
|
"github.com/grafana/grafana/pkg/bus"
|
|
m "github.com/grafana/grafana/pkg/models"
|
|
"github.com/grafana/grafana/pkg/services/guardian"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
)
|
|
|
|
var jsonDashIndex *JsonDashIndex
|
|
|
|
func Init() {
|
|
bus.AddHandler("search", searchHandler)
|
|
|
|
jsonIndexCfg, _ := setting.Cfg.GetSection("dashboards.json")
|
|
|
|
if jsonIndexCfg == nil {
|
|
log.Fatal("Config section missing: dashboards.json")
|
|
return
|
|
}
|
|
|
|
jsonIndexEnabled := jsonIndexCfg.Key("enabled").MustBool(false)
|
|
|
|
if jsonIndexEnabled {
|
|
jsonFilesPath := jsonIndexCfg.Key("path").String()
|
|
if !filepath.IsAbs(jsonFilesPath) {
|
|
jsonFilesPath = filepath.Join(setting.HomePath, jsonFilesPath)
|
|
}
|
|
|
|
jsonDashIndex = NewJsonDashIndex(jsonFilesPath)
|
|
go jsonDashIndex.updateLoop()
|
|
}
|
|
}
|
|
|
|
func searchHandler(query *Query) error {
|
|
hits := make(HitList, 0)
|
|
|
|
dashQuery := FindPersistedDashboardsQuery{
|
|
Title: query.Title,
|
|
UserId: query.UserId,
|
|
IsStarred: query.IsStarred,
|
|
OrgId: query.OrgId,
|
|
DashboardIds: query.DashboardIds,
|
|
Type: query.Type,
|
|
ParentId: query.FolderId,
|
|
Mode: query.Mode,
|
|
}
|
|
|
|
if err := bus.Dispatch(&dashQuery); err != nil {
|
|
return err
|
|
}
|
|
|
|
hits = append(hits, dashQuery.Result...)
|
|
|
|
if jsonDashIndex != nil {
|
|
jsonHits, err := jsonDashIndex.Search(query)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
hits = append(hits, jsonHits...)
|
|
}
|
|
|
|
// filter out results with tag filter
|
|
if len(query.Tags) > 0 {
|
|
filtered := HitList{}
|
|
for _, hit := range hits {
|
|
if hasRequiredTags(query.Tags, hit.Tags) {
|
|
filtered = append(filtered, hit)
|
|
}
|
|
}
|
|
hits = filtered
|
|
}
|
|
|
|
hits, err := removeRestrictedDashboardsFromList(hits, query)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// sort main result array
|
|
sort.Sort(hits)
|
|
|
|
if len(hits) > query.Limit {
|
|
hits = hits[0:query.Limit]
|
|
}
|
|
|
|
// sort tags
|
|
for _, hit := range hits {
|
|
sort.Strings(hit.Tags)
|
|
}
|
|
|
|
// add isStarred info
|
|
if err := setIsStarredFlagOnSearchResults(query.UserId, hits); err != nil {
|
|
return err
|
|
}
|
|
|
|
query.Result = hits
|
|
return nil
|
|
}
|
|
|
|
func removeRestrictedDashboardsFromList(hits HitList, query *Query) (HitList, error) {
|
|
var dashboardIds = []int64{}
|
|
for _, hit := range hits {
|
|
dashboardIds = append(dashboardIds, hit.Id)
|
|
}
|
|
|
|
filteredHits, err := guardian.FilterRestrictedDashboards(dashboardIds, query.OrgId, query.UserId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
filtered := HitList{}
|
|
for _, hit := range hits {
|
|
for _, dashId := range filteredHits {
|
|
if hit.Id == dashId {
|
|
filtered = append(filtered, hit)
|
|
}
|
|
}
|
|
}
|
|
|
|
return filtered, nil
|
|
}
|
|
|
|
func stringInSlice(a string, list []string) bool {
|
|
for _, b := range list {
|
|
if b == a {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func hasRequiredTags(queryTags, hitTags []string) bool {
|
|
for _, queryTag := range queryTags {
|
|
if !stringInSlice(queryTag, hitTags) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func setIsStarredFlagOnSearchResults(userId int64, hits []*Hit) error {
|
|
query := m.GetUserStarsQuery{UserId: userId}
|
|
if err := bus.Dispatch(&query); err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, dash := range hits {
|
|
if _, exists := query.Result[dash.Id]; exists {
|
|
dash.IsStarred = true
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetDashboardFromJsonIndex(filename string) *m.Dashboard {
|
|
if jsonDashIndex == nil {
|
|
return nil
|
|
}
|
|
return jsonDashIndex.GetDashboard(filename)
|
|
}
|