Skip to content
This repository has been archived by the owner on Mar 17, 2021. It is now read-only.

Add search folder by UID #22

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
117 changes: 105 additions & 12 deletions dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,23 @@ import (
"fmt"
"io/ioutil"
"log"
"net/url"
"os"
)

type DashboardMeta struct {
IsStarred bool `json:"isStarred"`
Slug string `json:"slug"`
Folder int64 `json:"folderId"`
IsStarred bool `json:"isStarred"`
Slug string `json:"slug"`
Folder int64 `json:"folderId"`
FolderTitle string `json:"folderTitle"`
}

// DashboardSaveResponse grafana response for create dashboard
type DashboardSaveResponse struct {
Slug string `json:"slug"`
Id int64 `json:"id"`
Uid string `json:"uid"`
ID int64 `json:"id"`
UID string `json:"uid"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's a great idea to be renaming these, as we tend to follow the Id and Uid convention for these fields. Would you be alright keeping these as-is?

URL string `json:"url"`
Status string `json:"status"`
Version int64 `json:"version"`
}
Expand All @@ -31,6 +35,24 @@ type Dashboard struct {
Overwrite bool `json:overwrite`
}

// Dashboards represent json returned by search API
type Dashboards struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is specific to the search endpoint can we name it something more along the lines of DashboardSearchResponse?

ID int64 `json:"id"`
UID string `json:"uid"`
Comment on lines +40 to +41
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

Title string `json:"title"`
URI string `json:"uri"`
URL string `json:"url"`
Starred bool `json:"isStarred"`
FolderID int64 `json:"folderId"`
FolderUID string `json:"folderUid"`
Comment on lines +46 to +47
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

FolderTitle string `json:"folderTitle"`
}

// DashboardDeleteResponse grafana response for delete dashboard
type DashboardDeleteResponse struct {
Title string `json:title`
}

// Deprecated: use NewDashboard instead
func (c *Client) SaveDashboard(model map[string]interface{}, overwrite bool) (*DashboardSaveResponse, error) {
wrapper := map[string]interface{}{
Expand Down Expand Up @@ -93,6 +115,68 @@ func (c *Client) NewDashboard(dashboard Dashboard) (*DashboardSaveResponse, erro
return result, err
}

// SearchDashboard search a dashboard in Grafana
func (c *Client) SearchDashboard(query string, folderID string) ([]Dashboards, error) {
dashboards := make([]Dashboards, 0)
path := "/api/search"

params := url.Values{}
params.Add("type", "dash-db")
params.Add("query", query)
params.Add("folderIds", folderID)

req, err := c.newRequest("GET", path, params, nil)
if err != nil {
return dashboards, err
}
resp, err := c.Do(req)
if err != nil {
return dashboards, err
}
if resp.StatusCode != 200 {
return dashboards, errors.New(resp.Status)
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return dashboards, err
}

err = json.Unmarshal(data, &dashboards)

return dashboards, err
}

// GetDashboard get a dashboard by UID
func (c *Client) GetDashboard(uid string) (*Dashboard, error) {
path := fmt.Sprintf("/api/dashboards/uid/%s", uid)
req, err := c.newRequest("GET", path, nil, nil)
if err != nil {
return nil, err
}

resp, err := c.Do(req)
if err != nil {
return nil, err
}
if resp.StatusCode != 200 {
return nil, errors.New(resp.Status)
}

data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}

result := &Dashboard{}
err = json.Unmarshal(data, &result)
result.Folder = result.Meta.Folder
if os.Getenv("GF_LOG") != "" {
log.Printf("got back dashboard response %s", data)
}
return result, err
}

// Deprecated: use GetDashboard instead
func (c *Client) Dashboard(slug string) (*Dashboard, error) {
path := fmt.Sprintf("/api/dashboards/db/%s", slug)
req, err := c.newRequest("GET", path, nil, nil)
Expand Down Expand Up @@ -122,20 +206,29 @@ func (c *Client) Dashboard(slug string) (*Dashboard, error) {
return result, err
}

func (c *Client) DeleteDashboard(slug string) error {
path := fmt.Sprintf("/api/dashboards/db/%s", slug)
// DeleteDashboard deletes a grafana dashoboard
func (c *Client) DeleteDashboard(uid string) (string, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a DeleteDashboardByUid function and mark the existing one as deprecated?

deleted := &DashboardDeleteResponse{}
path := fmt.Sprintf("/api/dashboards/uid/%s", uid)
req, err := c.newRequest("DELETE", path, nil, nil)
if err != nil {
return err
return "", err
}

resp, err := c.Do(req)
if err != nil {
return err
return "", err
}
if resp.StatusCode != 200 {
return errors.New(resp.Status)
return "", errors.New(resp.Status)
}

return nil
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
err = json.Unmarshal(data, &deleted)
if err != nil {
return "", err
}
return deleted.Title, nil
}
82 changes: 82 additions & 0 deletions folder.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"io/ioutil"
"net/url"
)

type Folder struct {
Expand Down Expand Up @@ -57,6 +58,87 @@ func (c *Client) Folder(id int64) (*Folder, error) {
return folder, err
}

// SearchFolder search a folder in Grafana
func (c *Client) SearchFolder(query string) ([]Folder, error) {
folders := make([]Folder, 0)
path := "/api/search"

params := url.Values{}
params.Add("type", "dash-folder")
params.Add("query", query)

req, err := c.newRequest("GET", path, params, nil)
if err != nil {
return folders, err
}
resp, err := c.Do(req)
if err != nil {
return folders, err
}
if resp.StatusCode != 200 {
return folders, errors.New(resp.Status)
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return folders, err
}
err = json.Unmarshal(data, &folders)
return folders, err
}

func (c *Client) FolderByUID(uid string) (*Folder, error) {
folder := &Folder{}
req, err := c.newRequest("GET", fmt.Sprintf("/api/folders/%s", uid), nil, nil)
if err != nil {
return folder, err
}
resp, err := c.Do(req)
if err != nil {
return folder, err
}
if resp.StatusCode != 200 {
return folder, errors.New(resp.Status)
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return folder, err
}
err = json.Unmarshal(data, &folder)
return folder, err
}

// NewFolderWithUID allows to create a new folder by specifying a custom
// UID. It is duplicated in order to maintain compatibility with existent tools
func (c *Client) NewFolderWithUID(title, uid string) (Folder, error) {
folder := Folder{}
dataMap := map[string]string{
"title": title,
"uid": uid,
}
data, err := json.Marshal(dataMap)
req, err := c.newRequest("POST", "/api/folders", nil, bytes.NewBuffer(data))
if err != nil {
return folder, err
}
resp, err := c.Do(req)
if err != nil {
return folder, err
}
if resp.StatusCode != 200 {
data, _ = ioutil.ReadAll(resp.Body)
return folder, fmt.Errorf("status: %s body: %s", resp.Status, data)
}
data, err = ioutil.ReadAll(resp.Body)
if err != nil {
return folder, err
}
err = json.Unmarshal(data, &folder)
if err != nil {
return folder, err
}
return folder, err
}

func (c *Client) NewFolder(title string) (Folder, error) {
folder := Folder{}
dataMap := map[string]string{
Expand Down