Skip to content

Commit

Permalink
Merge pull request #86 from grafana-tools/search-refactor
Browse files Browse the repository at this point in the history
Add SearchWithParams method
  • Loading branch information
d-ulyanov authored May 6, 2020
2 parents 784ae0c + 0dca3a1 commit b2c0c29
Show file tree
Hide file tree
Showing 3 changed files with 400 additions and 9 deletions.
117 changes: 109 additions & 8 deletions rest-dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"encoding/json"
"fmt"
"net/url"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -170,7 +171,24 @@ type FoundBoard struct {
// only starred dashboards and only for tags (logical OR applied to multiple tags).
//
// Reflects GET /api/search API call.
// Deprecated: This interface does not allow for API extension and is out of date.
// Please use Search(SearchType(SearchTypeDashboard))
func (r *Client) SearchDashboards(ctx context.Context, query string, starred bool, tags ...string) ([]FoundBoard, error) {
params := []SearchParam{
SearchType(SearchTypeDashboard),
SearchQuery(query),
SearchStarred(starred),
}
for _, tag := range tags {
params = append(params, SearchTag(tag))
}
return r.Search(ctx, params...)
}

// Search searches folders and dashboards with query params specified.
//
// Reflects GET /api/search API call.
func (r *Client) Search(ctx context.Context, params ...SearchParam) ([]FoundBoard, error) {
var (
raw []byte
boards []FoundBoard
Expand All @@ -179,14 +197,8 @@ func (r *Client) SearchDashboards(ctx context.Context, query string, starred boo
)
u := url.URL{}
q := u.Query()
if query != "" {
q.Set("query", query)
}
if starred {
q.Set("starred", "true")
}
for _, tag := range tags {
q.Add("tag", tag)
for _, p := range params {
p(&q)
}
if raw, code, err = r.get(ctx, "api/search", q); err != nil {
return nil, err
Expand Down Expand Up @@ -308,6 +320,95 @@ func (r *Client) DeleteDashboard(ctx context.Context, slug string) (StatusMessag
return reply, err
}

type (
// SearchParam is a type for specifying Search params.
SearchParam func(*url.Values)
// SearchParamType is a type accepted by SearchType func.
SearchParamType string
)

// Search entities to be used with SearchType().
const (
SearchTypeFolder SearchParamType = "dash-folder"
SearchTypeDashboard SearchParamType = "dash-db"
)

// SearchQuery specifies Search search query.
// Empty query is silently ignored.
// Specifying it multiple times is futile, only last one will be sent.
func SearchQuery(query string) SearchParam {
return func(v *url.Values) {
if query != "" {
v.Set("query", query)
}
}
}

// SearchTag specifies Search tag to search for.
// Empty tag is silently ignored.
// Can be specified multiple times, logical OR is applied.
func SearchTag(tag string) SearchParam {
return func(v *url.Values) {
if tag != "" {
v.Add("tag", tag)
}
}
}

// SearchType specifies Search type to search for.
// Specifying it multiple times is futile, only last one will be sent.
func SearchType(searchType SearchParamType) SearchParam {
return func(v *url.Values) {
v.Set("type", string(searchType))
}
}

// SearchDashboardID specifies Search dashboard id's to search for.
// Can be specified multiple times, logical OR is applied.
func SearchDashboardID(dashboardID int) SearchParam {
return func(v *url.Values) {
v.Add("dashboardIds", strconv.Itoa(dashboardID))
}
}

// SearchFolderID specifies Search folder id's to search for.
// Can be specified multiple times, logical OR is applied.
func SearchFolderID(folderID int) SearchParam {
return func(v *url.Values) {
v.Add("folderIds", strconv.Itoa(folderID))
}
}

// SearchStarred specifies if Search should search for starred dashboards only.
// Specifying it multiple times is futile, only last one will be sent.
func SearchStarred(starred bool) SearchParam {
return func(v *url.Values) {
v.Set("starred", strconv.FormatBool(starred))
}
}

// SearchLimit specifies maximum number of results from Search query.
// As of grafana 6.7 it has to be <= 5000. 0 stands for absence of parameter in a query.
// Specifying it multiple times is futile, only last one will be sent.
func SearchLimit(limit uint) SearchParam {
return func(v *url.Values) {
if limit > 0 {
v.Set("limit", strconv.FormatUint(uint64(limit), 10))
}
}
}

// SearchPage specifies Search page number to be queried for.
// Zero page is silently ignored, page numbers start from one.
// Specifying it multiple times is futile, only last one will be sent.
func SearchPage(page uint) SearchParam {
return func(v *url.Values) {
if page > 0 {
v.Set("page", strconv.FormatUint(uint64(page), 10))
}
}
}

// implicitly use dashboards from Grafana DB not from a file system
func setPrefix(slug string) string {
if strings.HasPrefix(slug, "db") {
Expand Down
7 changes: 6 additions & 1 deletion rest-dashboard_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func Test_Dashboard_CRUD(t *testing.T) {
client := getClient(t)

var board sdk.Board

raw, _ := ioutil.ReadFile("testdata/new-empty-dashboard-2.6.json")

if err = json.Unmarshal(raw, &board); err != nil {
Expand All @@ -38,10 +39,14 @@ func Test_Dashboard_CRUD(t *testing.T) {
t.Fatal(err)
}

if boardLinks, err = client.SearchDashboards(ctx, "", false); err != nil {
if boardLinks, err = client.Search(ctx, sdk.SearchType(sdk.SearchTypeDashboard)); err != nil {
t.Fatal(err)
}

if len(boardLinks) == 0 {
t.Fatal("search query returned empty dashboard list")
}

for _, link := range boardLinks {
_, _, err = client.GetDashboardByUID(ctx, link.UID)
if err != nil {
Expand Down
Loading

0 comments on commit b2c0c29

Please sign in to comment.