Skip to content

Commit

Permalink
Add public dashboards support (grafana#161)
Browse files Browse the repository at this point in the history
* Add public dashboards support

* fix lint issues

* remove bool pointers

* gofmt file
  • Loading branch information
evictorero authored Sep 11, 2023
1 parent c093bc7 commit b3a3c20
Show file tree
Hide file tree
Showing 2 changed files with 264 additions and 0 deletions.
106 changes: 106 additions & 0 deletions dashboard_public.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package gapi

import (
"encoding/json"
"fmt"
"time"
)

// PublicDashboardPayload represents a public dashboard payload.
type PublicDashboardPayload struct {
UID string `json:"uid"`
AccessToken string `json:"accessToken"`
TimeSelectionEnabled bool `json:"timeSelectionEnabled"`
IsEnabled bool `json:"isEnabled"`
AnnotationsEnabled bool `json:"annotationsEnabled"`
Share string `json:"share"`
}

// PublicDashboard represents a public dashboard.
type PublicDashboard struct {
UID string `json:"uid"`
DashboardUID string `json:"dashboardUid"`
AccessToken string `json:"accessToken"`
TimeSelectionEnabled bool `json:"timeSelectionEnabled"`
IsEnabled bool `json:"isEnabled"`
AnnotationsEnabled bool `json:"annotationsEnabled"`
Share string `json:"share"`
CreatedBy int64 `json:"createdBy"`
UpdatedBy int64 `json:"updatedBy"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}

type PublicDashboardListResponseWithPagination struct {
PublicDashboards []*PublicDashboardListResponse `json:"publicDashboards"`
TotalCount int64 `json:"totalCount"`
Page int `json:"page"`
PerPage int `json:"perPage"`
}

type PublicDashboardListResponse struct {
UID string `json:"uid"`
AccessToken string `json:"accessToken"`
Title string `json:"title"`
DashboardUID string `json:"dashboardUid"`
IsEnabled bool `json:"isEnabled"`
}

// NewPublicDashboard creates a new Grafana public dashboard.
func (c *Client) NewPublicDashboard(dashboardUID string, publicDashboard PublicDashboardPayload) (*PublicDashboard, error) {
data, err := json.Marshal(publicDashboard)
if err != nil {
return nil, err
}

result := &PublicDashboard{}
err = c.request("POST", fmt.Sprintf("/api/dashboards/uid/%s/public-dashboards", dashboardUID), nil, data, &result)
if err != nil {
return nil, err
}

return result, err
}

// DeletePublicDashboard deletes a Grafana public dashboard.
func (c *Client) DeletePublicDashboard(dashboardUID string, publicDashboardUID string) error {
return c.request("DELETE", fmt.Sprintf("/api/dashboards/uid/%s/public-dashboards/%s", dashboardUID, publicDashboardUID), nil, nil, nil)
}

// PublicDashboards fetches and returns the Grafana public dashboards.
func (c *Client) PublicDashboards() (*PublicDashboardListResponseWithPagination, error) {
publicdashboards := &PublicDashboardListResponseWithPagination{}
err := c.request("GET", "/api/dashboards/public-dashboards", nil, nil, &publicdashboards)
if err != nil {
return publicdashboards, err
}

return publicdashboards, err
}

// PublicDashboardbyUID fetches and returns a Grafana public dashboard by uid.
func (c *Client) PublicDashboardbyUID(dashboardUID string) (*PublicDashboard, error) {
publicDashboard := &PublicDashboard{}
err := c.request("GET", fmt.Sprintf("/api/dashboards/uid/%s/public-dashboards", dashboardUID), nil, nil, &publicDashboard)
if err != nil {
return publicDashboard, err
}

return publicDashboard, err
}

// UpdatePublicDashboard updates a Grafana public dashboard.
func (c *Client) UpdatePublicDashboard(dashboardUID string, publicDashboardUID string, publicDashboard PublicDashboardPayload) (*PublicDashboard, error) {
data, err := json.Marshal(publicDashboard)
if err != nil {
return nil, err
}

result := &PublicDashboard{}
err = c.request("PATCH", fmt.Sprintf("/api/dashboards/uid/%s/public-dashboards/%s", dashboardUID, publicDashboardUID), nil, data, &result)
if err != nil {
return nil, err
}

return result, err
}
158 changes: 158 additions & 0 deletions dashboard_public_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package gapi

import (
"testing"

"github.com/gobs/pretty"
)

const (
createPublicDashboard = `{
"uid": "fdc8b8fd-72cb-45d2-927a-75900e4f6e70",
"dashboardUid": "nErXDvCkzz",
"isEnabled": true,
"share": "public"
}`
updatePublicDashboard = `{
"timeSelectionEnabled": true,
"isEnabled": true,
"annotationsEnabled": true
}`
publicDashboardByUID = `{
"uid": "cd56d9fd-f3d4-486d-afba-a21760e2acbe",
"dashboardUid": "xCpsVuc4z",
"accessToken": "5c948bf96e6a4b13bd91975f9a2028b7",
"createdBy": 1,
"updatedBy": 1,
"createdAt": "2023-09-05T11:41:14-03:00",
"updatedAt": "2023-09-05T11:41:14-03:00",
"timeSelectionEnabled": false,
"isEnabled": true,
"annotationsEnabled": false,
"share": "public"
}`
publicDashboardList = `{
"publicDashboards": [
{
"uid": "e9f29a3c-fcc3-4fc5-a690-ae39c97d24ba",
"accessToken": "6c13ec1997ba48c5af8c9c5079049692",
"title": "A Datasource not found query",
"dashboardUid": "d2f21d0a-76c7-47ec-b5f3-9dda16e5a996",
"isEnabled": true
},
{
"uid": "a174f604-6fe7-47de-97b4-48b7e401b540",
"accessToken": "d1fcff345c0f45e8a78c096c9696034a",
"title": "A Issue heatmap bargauge panel",
"dashboardUid": "51DiOw0Vz",
"isEnabled": true
}
],
"totalCount": 2,
"page": 1,
"perPage": 1000
}`
)

func TestNewPublicDashboard(t *testing.T) {
const dashboardUID = "nErXDvCkzz"

client := gapiTestTools(t, 200, createPublicDashboard)

publicDashboard := PublicDashboardPayload{
UID: "fdc8b8fd-72cb-45d2-927a-75900e4f6e70",
AccessToken: "b1d5f3f534d84375a897f3969b6157f3",
IsEnabled: true,
Share: "public",
}

resp, err := client.NewPublicDashboard(dashboardUID, publicDashboard)
if err != nil {
t.Fatal(err)
}

t.Log(pretty.PrettyFormat(resp))

if resp.UID != "fdc8b8fd-72cb-45d2-927a-75900e4f6e70" {
t.Errorf("Invalid uid - %s, Expected %s", resp.UID, "fdc8b8fd-72cb-45d2-927a-75900e4f6e70")
}

if resp.DashboardUID != dashboardUID {
t.Errorf("Invalid dashboard uid - %s, Expected %s", resp.DashboardUID, dashboardUID)
}
}

func TestDeletePublicDashboard(t *testing.T) {
client := gapiTestTools(t, 200, "")

err := client.DeletePublicDashboard("nErXDvCkza", "fdc8b8fd-72cb-45d2-927a-75900e4f6e70")
if err != nil {
t.Error(err)
}
}

func TestPublicDashboards(t *testing.T) {
client := gapiTestTools(t, 200, publicDashboardList)

resp, err := client.PublicDashboards()
if err != nil {
t.Fatal(err)
}

t.Log(pretty.PrettyFormat(resp))

if len(resp.PublicDashboards) != 2 || resp.TotalCount != 2 {
t.Error("Length of returned public dashboards should be 2")
}
if resp.PublicDashboards[0].UID != "e9f29a3c-fcc3-4fc5-a690-ae39c97d24ba" || resp.PublicDashboards[0].AccessToken != "6c13ec1997ba48c5af8c9c5079049692" {
t.Error("Not correctly parsing returned public dashboards.")
}
}

func TestPublicDashboardByUID(t *testing.T) {
client := gapiTestTools(t, 200, publicDashboardByUID)

resp, err := client.PublicDashboardbyUID("xCpsVuc4z")
if err != nil {
t.Fatal(err)
}

t.Log(pretty.PrettyFormat(resp))

if resp.UID != "cd56d9fd-f3d4-486d-afba-a21760e2acbe" {
t.Errorf("Invalid uid - %s, Expected %s", resp.UID, "cd56d9fd-f3d4-486d-afba-a21760e2acbe")
}

if resp.DashboardUID != "xCpsVuc4z" {
t.Errorf("Invalid dashboard uid - %s, Expected %s", resp.DashboardUID, "xCpsVuc4z")
}
}

func TestUpdatePublicDashboard(t *testing.T) {
client := gapiTestTools(t, 200, updatePublicDashboard)

publicDashboard := PublicDashboardPayload{
IsEnabled: true,
TimeSelectionEnabled: true,
AnnotationsEnabled: true,
}

resp, err := client.UpdatePublicDashboard("xCpsVuc4z", "cd56d9fd-f3d4-486d-afba-a21760e2acbe", publicDashboard)
if err != nil {
t.Fatal(err)
}

t.Log(pretty.PrettyFormat(resp))

if !resp.IsEnabled {
t.Errorf("Invalid IsEnabled - %t, Expected %t", resp.IsEnabled, true)
}

if !resp.TimeSelectionEnabled {
t.Errorf("Invalid TimeSelectionEnabled - %t, Expected %t", resp.TimeSelectionEnabled, true)
}

if !resp.AnnotationsEnabled {
t.Errorf("Invalid AnnotationsEnabled - %t, Expected %t", resp.AnnotationsEnabled, true)
}
}

0 comments on commit b3a3c20

Please sign in to comment.