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

Commit 8327c40

Browse files
authored
Merge branch 'master' into feature/impl-folder-permission
2 parents 7f96414 + ab1d628 commit 8327c40

16 files changed

+1099
-35
lines changed

.drone.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ steps:
88
image: golang
99
commands:
1010
- go mod download
11-
- go test
11+
- go test -cover -race -vet all -mod readonly ./...

admin.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ import (
1111
func (c *Client) CreateUser(user User) (int64, error) {
1212
id := int64(0)
1313
data, err := json.Marshal(user)
14+
if err != nil {
15+
return id, err
16+
}
17+
1418
req, err := c.newRequest("POST", "/api/admin/users", nil, bytes.NewBuffer(data))
1519
if err != nil {
1620
return id, err

alertnotification.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
type AlertNotification struct {
1212
Id int64 `json:"id,omitempty"`
13+
Uid string `json:"uid"`
1314
Name string `json:"name"`
1415
Type string `json:"type"`
1516
IsDefault bool `json:"isDefault"`

client.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ func New(auth, baseURL string) (*Client, error) {
2929
}
3030
key := ""
3131
if strings.Contains(auth, ":") {
32-
split := strings.Split(auth, ":")
32+
split := strings.SplitN(auth, ":", 2)
3333
u.User = url.UserPassword(split[0], split[1])
34-
} else {
34+
} else if auth != "" {
3535
key = fmt.Sprintf("Bearer %s", auth)
3636
}
3737
return &Client{

dashboard.go

100755100644
Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"fmt"
88
"io/ioutil"
99
"log"
10+
"net/url"
1011
"os"
1112
)
1213

@@ -24,11 +25,27 @@ type DashboardSaveResponse struct {
2425
Version int64 `json:"version"`
2526
}
2627

28+
type DashboardSearchResponse struct {
29+
Id uint `json:"id"`
30+
Uid string `json:"uid"`
31+
Title string `json:"title"`
32+
Uri string `json:"uri"`
33+
Url string `json:"url"`
34+
Slug string `json:"slug"`
35+
Type string `json:"type"`
36+
Tags []string `json:"tags"`
37+
IsStarred bool `json:"isStarred"`
38+
FolderId uint `json:"folderId"`
39+
FolderUid string `json:"folderUid"`
40+
FolderTitle string `json:"folderTitle"`
41+
FolderUrl string `json:"folderUrl"`
42+
}
43+
2744
type Dashboard struct {
2845
Meta DashboardMeta `json:"meta"`
2946
Model map[string]interface{} `json:"dashboard"`
3047
Folder int64 `json:"folderId"`
31-
Overwrite bool `json:overwrite`
48+
Overwrite bool `json:"overwrite"`
3249
}
3350

3451
// Deprecated: use NewDashboard instead
@@ -93,6 +110,33 @@ func (c *Client) NewDashboard(dashboard Dashboard) (*DashboardSaveResponse, erro
93110
return result, err
94111
}
95112

113+
func (c *Client) Dashboards() ([]DashboardSearchResponse, error) {
114+
dashboards := make([]DashboardSearchResponse, 0)
115+
query := url.Values{}
116+
// search only dashboards
117+
query.Add("type", "dash-db")
118+
req, err := c.newRequest("GET", "/api/search", query, nil)
119+
if err != nil {
120+
return nil, err
121+
}
122+
123+
resp, err := c.Do(req)
124+
if err != nil {
125+
return dashboards, err
126+
}
127+
if resp.StatusCode != 200 {
128+
return dashboards, errors.New(resp.Status)
129+
}
130+
131+
data, err := ioutil.ReadAll(resp.Body)
132+
if err != nil {
133+
return dashboards, err
134+
}
135+
136+
err = json.Unmarshal(data, &dashboards)
137+
return dashboards, err
138+
}
139+
96140
// Deprecated: Starting from Grafana v5.0. Please update to use DashboardByUID instead.
97141
func (c *Client) Dashboard(slug string) (*Dashboard, error) {
98142
return c.dashboard(fmt.Sprintf("/api/dashboards/db/%s", slug))
@@ -154,4 +198,4 @@ func (c *Client) deleteDashboard(path string) error {
154198
}
155199

156200
return nil
157-
}
201+
}

dashboard_test.go

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
package gapi
2+
3+
import (
4+
"testing"
5+
6+
"github.com/gobs/pretty"
7+
)
8+
9+
const (
10+
createdAndUpdateDashboardResponse = `{
11+
"slug": "test",
12+
"id": 1,
13+
"uid": "nErXDvCkzz",
14+
"status": "success",
15+
"version": 1
16+
}`
17+
18+
getDashboardResponse = `{
19+
"dashboard": {
20+
"id": 1,
21+
"uid": "cIBgcSjkk",
22+
"title": "Production Overview",
23+
"version": 0
24+
},
25+
"meta": {
26+
"isStarred": false,
27+
"url": "/d/cIBgcSjkk/production-overview",
28+
"slug": "production-overview"
29+
}
30+
}`
31+
32+
getDashboardsJSON = `[
33+
{
34+
"id": 1,
35+
"uid": "RGAPB1cZz",
36+
"title": "Grafana Stats",
37+
"uri": "db/grafana-stats",
38+
"url": "/dashboards/d/RGAPB1cZz/grafana-stat",
39+
"slug": "",
40+
"type": "dash-db",
41+
"tags": [],
42+
"isStarred": false
43+
}
44+
]`
45+
)
46+
47+
func TestDashboardCreateAndUpdate(t *testing.T) {
48+
server, client := gapiTestTools(200, createdAndUpdateDashboardResponse)
49+
defer server.Close()
50+
51+
dashboard := Dashboard{
52+
Model: map[string]interface{}{
53+
"title": "test",
54+
},
55+
Folder: 0,
56+
Overwrite: false,
57+
}
58+
59+
resp, err := client.NewDashboard(dashboard)
60+
if err != nil {
61+
t.Fatal(err)
62+
}
63+
64+
t.Log(pretty.PrettyFormat(resp))
65+
66+
if resp.Uid != "nErXDvCkzz" {
67+
t.Errorf("Invalid uid - %s, Expected %s", resp.Uid, "nErXDvCkzz")
68+
}
69+
70+
for _, code := range []int{400, 401, 403, 412} {
71+
server.code = code
72+
_, err = client.NewDashboard(dashboard)
73+
if err == nil {
74+
t.Errorf("%d not detected", code)
75+
}
76+
}
77+
}
78+
79+
func TestDashboardGet(t *testing.T) {
80+
server, client := gapiTestTools(200, getDashboardResponse)
81+
defer server.Close()
82+
83+
resp, err := client.Dashboard("test")
84+
if err != nil {
85+
t.Error(err)
86+
}
87+
uid, ok := resp.Model["uid"]
88+
if !ok || uid != "cIBgcSjkk" {
89+
t.Errorf("Invalid uid - %s, Expected %s", uid, "cIBgcSjkk")
90+
}
91+
92+
resp, err = client.DashboardByUID("cIBgcSjkk")
93+
if err != nil {
94+
t.Error(err)
95+
}
96+
uid, ok = resp.Model["uid"]
97+
if !ok || uid != "cIBgcSjkk" {
98+
t.Errorf("Invalid uid - %s, Expected %s", uid, "cIBgcSjkk")
99+
}
100+
101+
for _, code := range []int{401, 403, 404} {
102+
server.code = code
103+
_, err = client.Dashboard("test")
104+
if err == nil {
105+
t.Errorf("%d not detected", code)
106+
}
107+
108+
_, err = client.DashboardByUID("cIBgcSjkk")
109+
if err == nil {
110+
t.Errorf("%d not detected", code)
111+
}
112+
}
113+
}
114+
115+
func TestDashboardDelete(t *testing.T) {
116+
server, client := gapiTestTools(200, "")
117+
defer server.Close()
118+
119+
err := client.DeleteDashboard("test")
120+
if err != nil {
121+
t.Error(err)
122+
}
123+
124+
err = client.DeleteDashboardByUID("cIBgcSjkk")
125+
if err != nil {
126+
t.Error(err)
127+
}
128+
129+
for _, code := range []int{401, 403, 404, 412} {
130+
server.code = code
131+
132+
err = client.DeleteDashboard("test")
133+
if err == nil {
134+
t.Errorf("%d not detected", code)
135+
}
136+
137+
err = client.DeleteDashboardByUID("cIBgcSjkk")
138+
if err == nil {
139+
t.Errorf("%d not detected", code)
140+
}
141+
}
142+
}
143+
144+
func TestDashboards(t *testing.T) {
145+
server, client := gapiTestTools(200, getDashboardsJSON)
146+
defer server.Close()
147+
148+
dashboards, err := client.Dashboards()
149+
if err != nil {
150+
t.Error(err)
151+
}
152+
153+
t.Log(pretty.PrettyFormat(dashboards))
154+
155+
if len(dashboards) != 1 {
156+
t.Error("Length of returned dashboards should be 1")
157+
}
158+
159+
if dashboards[0].Id != 1 || dashboards[0].Title != "Grafana Stats" {
160+
t.Error("Not correctly parsing returned dashboards.")
161+
}
162+
}

datasource.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ type JSONData struct {
7878
// Used by Prometheus
7979
HttpMethod string `json:"httpMethod,omitempty"`
8080
QueryTimeout string `json:"queryTimeout,omitempty"`
81+
82+
// Used by Stackdriver
83+
AuthenticationType string `json:"authenticationType,omitempty"`
84+
ClientEmail string `json:"clientEmail,omitempty"`
85+
DefaultProject string `json:"defaultProject,omitempty"`
86+
TokenUri string `json:"tokenUri,omitempty"`
8187
}
8288

8389
// SecureJSONData is a representation of the datasource `secureJsonData` property
@@ -92,6 +98,9 @@ type SecureJSONData struct {
9298
// Used by Cloudwatch
9399
AccessKey string `json:"accessKey,omitempty"`
94100
SecretKey string `json:"secretKey,omitempty"`
101+
102+
// Used by Stackdriver
103+
PrivateKey string `json:"privateKey,omitempty"`
95104
}
96105

97106
func (c *Client) NewDataSource(s *DataSource) (int64, error) {

datasource_test.go

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
package gapi
22

33
import (
4-
"fmt"
5-
"net/http"
6-
"net/http/httptest"
7-
"net/url"
84
"testing"
95

106
"github.com/gobs/pretty"
@@ -14,31 +10,6 @@ const (
1410
createdDataSourceJSON = `{"id":1,"message":"Datasource added", "name": "test_datasource"}`
1511
)
1612

17-
func gapiTestTools(code int, body string) (*httptest.Server, *Client) {
18-
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
19-
w.WriteHeader(code)
20-
w.Header().Set("Content-Type", "application/json")
21-
fmt.Fprintf(w, body)
22-
}))
23-
24-
tr := &http.Transport{
25-
Proxy: func(req *http.Request) (*url.URL, error) {
26-
return url.Parse(server.URL)
27-
},
28-
}
29-
30-
httpClient := &http.Client{Transport: tr}
31-
32-
url := url.URL{
33-
Scheme: "http",
34-
Host: "my-grafana.com",
35-
}
36-
37-
client := &Client{"my-key", url, httpClient}
38-
39-
return server, client
40-
}
41-
4213
func TestNewDataSource(t *testing.T) {
4314
server, client := gapiTestTools(200, createdDataSourceJSON)
4415
defer server.Close()

folder.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ func (c *Client) NewFolder(title string) (Folder, error) {
6363
"title": title,
6464
}
6565
data, err := json.Marshal(dataMap)
66+
if err != nil {
67+
return folder, err
68+
}
6669
req, err := c.newRequest("POST", "/api/folders", nil, bytes.NewBuffer(data))
6770
if err != nil {
6871
return folder, err
@@ -91,6 +94,9 @@ func (c *Client) UpdateFolder(id string, name string) error {
9194
"name": name,
9295
}
9396
data, err := json.Marshal(dataMap)
97+
if err != nil {
98+
return err
99+
}
94100
req, err := c.newRequest("PUT", fmt.Sprintf("/api/folders/%s", id), nil, bytes.NewBuffer(data))
95101
if err != nil {
96102
return err

0 commit comments

Comments
 (0)