Skip to content

Commit

Permalink
Merge branch 'master' into feature/impl-team
Browse files Browse the repository at this point in the history
  • Loading branch information
tonglil authored Jun 2, 2020
2 parents b5beb26 + 7d74f3b commit 30d2c1f
Show file tree
Hide file tree
Showing 14 changed files with 526 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ steps:
image: golang
commands:
- go mod download
- go test
- go test -cover -race -vet all -mod readonly ./...
4 changes: 4 additions & 0 deletions admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import (
func (c *Client) CreateUser(user User) (int64, error) {
id := int64(0)
data, err := json.Marshal(user)
if err != nil {
return id, err
}

req, err := c.newRequest("POST", "/api/admin/users", nil, bytes.NewBuffer(data))
if err != nil {
return id, err
Expand Down
1 change: 1 addition & 0 deletions alertnotification.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

type AlertNotification struct {
Id int64 `json:"id,omitempty"`
Uid string `json:"uid"`
Name string `json:"name"`
Type string `json:"type"`
IsDefault bool `json:"isDefault"`
Expand Down
4 changes: 2 additions & 2 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ func New(auth, baseURL string) (*Client, error) {
}
key := ""
if strings.Contains(auth, ":") {
split := strings.Split(auth, ":")
split := strings.SplitN(auth, ":", 2)
u.User = url.UserPassword(split[0], split[1])
} else {
} else if auth != "" {
key = fmt.Sprintf("Bearer %s", auth)
}
return &Client{
Expand Down
48 changes: 46 additions & 2 deletions dashboard.go
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io/ioutil"
"log"
"net/url"
"os"
)

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

type DashboardSearchResponse struct {
Id uint `json:"id"`
Uid string `json:"uid"`
Title string `json:"title"`
Uri string `json:"uri"`
Url string `json:"url"`
Slug string `json:"slug"`
Type string `json:"type"`
Tags []string `json:"tags"`
IsStarred bool `json:"isStarred"`
FolderId uint `json:"folderId"`
FolderUid string `json:"folderUid"`
FolderTitle string `json:"folderTitle"`
FolderUrl string `json:"folderUrl"`
}

type Dashboard struct {
Meta DashboardMeta `json:"meta"`
Model map[string]interface{} `json:"dashboard"`
Folder int64 `json:"folderId"`
Overwrite bool `json:overwrite`
Overwrite bool `json:"overwrite"`
}

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

func (c *Client) Dashboards() ([]DashboardSearchResponse, error) {
dashboards := make([]DashboardSearchResponse, 0)
query := url.Values{}
// search only dashboards
query.Add("type", "dash-db")
req, err := c.newRequest("GET", "/api/search", query, nil)
if err != nil {
return nil, 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
}

// Deprecated: Starting from Grafana v5.0. Please update to use DashboardByUID instead.
func (c *Client) Dashboard(slug string) (*Dashboard, error) {
return c.dashboard(fmt.Sprintf("/api/dashboards/db/%s", slug))
Expand Down Expand Up @@ -154,4 +198,4 @@ func (c *Client) deleteDashboard(path string) error {
}

return nil
}
}
162 changes: 162 additions & 0 deletions dashboard_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package gapi

import (
"testing"

"github.com/gobs/pretty"
)

const (
createdAndUpdateDashboardResponse = `{
"slug": "test",
"id": 1,
"uid": "nErXDvCkzz",
"status": "success",
"version": 1
}`

getDashboardResponse = `{
"dashboard": {
"id": 1,
"uid": "cIBgcSjkk",
"title": "Production Overview",
"version": 0
},
"meta": {
"isStarred": false,
"url": "/d/cIBgcSjkk/production-overview",
"slug": "production-overview"
}
}`

getDashboardsJSON = `[
{
"id": 1,
"uid": "RGAPB1cZz",
"title": "Grafana Stats",
"uri": "db/grafana-stats",
"url": "/dashboards/d/RGAPB1cZz/grafana-stat",
"slug": "",
"type": "dash-db",
"tags": [],
"isStarred": false
}
]`
)

func TestDashboardCreateAndUpdate(t *testing.T) {
server, client := gapiTestTools(200, createdAndUpdateDashboardResponse)
defer server.Close()

dashboard := Dashboard{
Model: map[string]interface{}{
"title": "test",
},
Folder: 0,
Overwrite: false,
}

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

t.Log(pretty.PrettyFormat(resp))

if resp.Uid != "nErXDvCkzz" {
t.Errorf("Invalid uid - %s, Expected %s", resp.Uid, "nErXDvCkzz")
}

for _, code := range []int{400, 401, 403, 412} {
server.code = code
_, err = client.NewDashboard(dashboard)
if err == nil {
t.Errorf("%d not detected", code)
}
}
}

func TestDashboardGet(t *testing.T) {
server, client := gapiTestTools(200, getDashboardResponse)
defer server.Close()

resp, err := client.Dashboard("test")
if err != nil {
t.Error(err)
}
uid, ok := resp.Model["uid"]
if !ok || uid != "cIBgcSjkk" {
t.Errorf("Invalid uid - %s, Expected %s", uid, "cIBgcSjkk")
}

resp, err = client.DashboardByUID("cIBgcSjkk")
if err != nil {
t.Error(err)
}
uid, ok = resp.Model["uid"]
if !ok || uid != "cIBgcSjkk" {
t.Errorf("Invalid uid - %s, Expected %s", uid, "cIBgcSjkk")
}

for _, code := range []int{401, 403, 404} {
server.code = code
_, err = client.Dashboard("test")
if err == nil {
t.Errorf("%d not detected", code)
}

_, err = client.DashboardByUID("cIBgcSjkk")
if err == nil {
t.Errorf("%d not detected", code)
}
}
}

func TestDashboardDelete(t *testing.T) {
server, client := gapiTestTools(200, "")
defer server.Close()

err := client.DeleteDashboard("test")
if err != nil {
t.Error(err)
}

err = client.DeleteDashboardByUID("cIBgcSjkk")
if err != nil {
t.Error(err)
}

for _, code := range []int{401, 403, 404, 412} {
server.code = code

err = client.DeleteDashboard("test")
if err == nil {
t.Errorf("%d not detected", code)
}

err = client.DeleteDashboardByUID("cIBgcSjkk")
if err == nil {
t.Errorf("%d not detected", code)
}
}
}

func TestDashboards(t *testing.T) {
server, client := gapiTestTools(200, getDashboardsJSON)
defer server.Close()

dashboards, err := client.Dashboards()
if err != nil {
t.Error(err)
}

t.Log(pretty.PrettyFormat(dashboards))

if len(dashboards) != 1 {
t.Error("Length of returned dashboards should be 1")
}

if dashboards[0].Id != 1 || dashboards[0].Title != "Grafana Stats" {
t.Error("Not correctly parsing returned dashboards.")
}
}
9 changes: 9 additions & 0 deletions datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ type JSONData struct {
// Used by Prometheus
HttpMethod string `json:"httpMethod,omitempty"`
QueryTimeout string `json:"queryTimeout,omitempty"`

// Used by Stackdriver
AuthenticationType string `json:"authenticationType,omitempty"`
ClientEmail string `json:"clientEmail,omitempty"`
DefaultProject string `json:"defaultProject,omitempty"`
TokenUri string `json:"tokenUri,omitempty"`
}

// SecureJSONData is a representation of the datasource `secureJsonData` property
Expand All @@ -92,6 +98,9 @@ type SecureJSONData struct {
// Used by Cloudwatch
AccessKey string `json:"accessKey,omitempty"`
SecretKey string `json:"secretKey,omitempty"`

// Used by Stackdriver
PrivateKey string `json:"privateKey,omitempty"`
}

func (c *Client) NewDataSource(s *DataSource) (int64, error) {
Expand Down
29 changes: 0 additions & 29 deletions datasource_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package gapi

import (
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"testing"

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

func gapiTestTools(code int, body string) (*httptest.Server, *Client) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(code)
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, body)
}))

tr := &http.Transport{
Proxy: func(req *http.Request) (*url.URL, error) {
return url.Parse(server.URL)
},
}

httpClient := &http.Client{Transport: tr}

url := url.URL{
Scheme: "http",
Host: "my-grafana.com",
}

client := &Client{"my-key", url, httpClient}

return server, client
}

func TestNewDataSource(t *testing.T) {
server, client := gapiTestTools(200, createdDataSourceJSON)
defer server.Close()
Expand Down
6 changes: 6 additions & 0 deletions folder.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ func (c *Client) NewFolder(title string) (Folder, error) {
"title": title,
}
data, err := json.Marshal(dataMap)
if err != nil {
return folder, err
}
req, err := c.newRequest("POST", "/api/folders", nil, bytes.NewBuffer(data))
if err != nil {
return folder, err
Expand Down Expand Up @@ -91,6 +94,9 @@ func (c *Client) UpdateFolder(id string, name string) error {
"name": name,
}
data, err := json.Marshal(dataMap)
if err != nil {
return err
}
req, err := c.newRequest("PUT", fmt.Sprintf("/api/folders/%s", id), nil, bytes.NewBuffer(data))
if err != nil {
return err
Expand Down
Loading

0 comments on commit 30d2c1f

Please sign in to comment.