forked from jianyuan/go-sentry
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from Canva/merge-with-upstream
Merge with upstream [ODC-764]
- Loading branch information
Showing
38 changed files
with
4,318 additions
and
1,822 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,60 @@ | ||
# go-sentry [![CircleCI](https://circleci.com/gh/jianyuan/go-sentry/tree/master.svg?style=svg)](https://circleci.com/gh/jianyuan/go-sentry/tree/master) [![GoDoc](https://godoc.org/github.com/jianyuan/go-sentry/sentry?status.svg)](https://godoc.org/github.com/jianyuan/go-sentry/sentry) | ||
# go-sentry [![Go Reference](https://pkg.go.dev/badge/github.com/jianyuan/go-sentry/v2/sentry.svg)](https://pkg.go.dev/github.com/jianyuan/go-sentry/v2/sentry) | ||
|
||
Go library for accessing the [Sentry Web API](https://docs.sentry.io/api/). | ||
|
||
## Install | ||
## Installation | ||
go-sentry is compatible with modern Go releases in module mode, with Go installed: | ||
|
||
```sh | ||
go get -u github.com/jianyuan/go-sentry/sentry | ||
go get github.com/jianyuan/go-sentry/v2/sentry | ||
``` | ||
|
||
## Usage | ||
|
||
```go | ||
import "github.com/jianyuan/go-sentry/v2/sentry" | ||
``` | ||
|
||
Create a new Sentry client. Then, use the various services on the client to access different parts of the | ||
Sentry Web API. For example: | ||
|
||
```go | ||
client := sentry.NewClient(nil) | ||
|
||
// List all organizations | ||
orgs, _, err := client.Organizations.List(ctx, nil) | ||
``` | ||
|
||
## Documentation | ||
Read the [GoDoc](https://godoc.org/github.com/jianyuan/go-sentry/sentry). | ||
### Authentication | ||
|
||
The library does not directly handle authentication. When creating a new client, pass an | ||
`http.Client` that can handle authentication for you. We recommend the [oauth2](https://pkg.go.dev/golang.org/x/oauth2) | ||
library. For example: | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"github.com/jianyuan/go-sentry/v2/sentry" | ||
"golang.org/x/oauth2" | ||
) | ||
|
||
func main() { | ||
ctx := context.Background() | ||
tokenSrc := oauth2.StaticTokenSource( | ||
&oauth2.Token{AccessToken: "YOUR-API-KEY"}, | ||
) | ||
httpClient := oauth2.NewClient(ctx, tokenSrc) | ||
|
||
client := sentry.NewClient(httpClient) | ||
|
||
// List all organizations | ||
orgs, _, err := client.Organizations.List(ctx, nil) | ||
} | ||
``` | ||
|
||
## Code structure | ||
The code structure was inspired by [dghubble/go-twitter](https://github.com/dghubble/go-twitter). | ||
The code structure was inspired by [google/go-github](https://github.com/google/go-github). | ||
|
||
## License | ||
This library is distributed under the [MIT License](LICENSE). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,28 @@ | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/dghubble/sling v1.4.0 h1:/n8MRosVTthvMbwlNZgLx579OGVjUOy3GNEv5BIqAWY= | ||
github.com/dghubble/sling v1.4.0/go.mod h1:0r40aNsU9EdDUVBNhfCstAtFgutjgJGYbO1oNzkMoM8= | ||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= | ||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= | ||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= | ||
github.com/peterhellberg/link v1.1.0 h1:s2+RH8EGuI/mI4QwrWGSYQCRz7uNgip9BaM04HKu5kc= | ||
github.com/peterhellberg/link v1.1.0/go.mod h1:gtSlOT4jmkY8P47hbTc8PTgiDDWpdPbFYl75keYyBB8= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= | ||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= | ||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 h1:nrZ3ySNYwJbSpD6ce9duiP+QkD3JuLCcWkdaehUS/3Y= | ||
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80/go.mod h1:iFyPdL66DjUD96XmzVL3ZntbzcflLnznH0fr99w5VqE= | ||
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= | ||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= | ||
github.com/stretchr/testify v1.7.4 h1:wZRexSlwd7ZXfKINDLsO4r7WBt3gTKONc6K/VesHvHM= | ||
github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= | ||
github.com/stretchr/testify v1.7.5 h1:s5PTfem8p8EbKQOctVV53k6jCJt3UX4IEJzwh+C324Q= | ||
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= | ||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= | ||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= | ||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= | ||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"extends": [ | ||
"config:base" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package sentry | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
) | ||
|
||
// DashboardWidget represents a Dashboard Widget. | ||
// https://github.com/getsentry/sentry/blob/22.5.0/src/sentry/api/serializers/rest_framework/dashboard.py#L230-L243 | ||
type DashboardWidget struct { | ||
ID *string `json:"id,omitempty"` | ||
Title *string `json:"title,omitempty"` | ||
DisplayType *string `json:"displayType,omitempty"` | ||
Interval *string `json:"interval,omitempty"` | ||
Queries []*DashboardWidgetQuery `json:"queries,omitempty"` | ||
WidgetType *string `json:"widgetType,omitempty"` | ||
Limit *int `json:"limit,omitempty"` | ||
Layout *DashboardWidgetLayout `json:"layout,omitempty"` | ||
} | ||
|
||
type DashboardWidgetLayout struct { | ||
X *int `json:"x,omitempty"` | ||
Y *int `json:"y,omitempty"` | ||
W *int `json:"w,omitempty"` | ||
H *int `json:"h,omitempty"` | ||
MinH *int `json:"minH,omitempty"` | ||
} | ||
|
||
type DashboardWidgetQuery struct { | ||
ID *string `json:"id,omitempty"` | ||
Fields []string `json:"fields,omitempty"` | ||
Aggregates []string `json:"aggregates,omitempty"` | ||
Columns []string `json:"columns,omitempty"` | ||
FieldAliases []string `json:"fieldAliases,omitempty"` | ||
Name *string `json:"name,omitempty"` | ||
Conditions *string `json:"conditions,omitempty"` | ||
OrderBy *string `json:"orderby,omitempty"` | ||
} | ||
|
||
// DashboardWidgetsService provides methods for accessing Sentry dashboard widget API endpoints. | ||
type DashboardWidgetsService service | ||
|
||
type DashboardWidgetErrors map[string][]string | ||
|
||
// Validate a dashboard widget configuration. | ||
func (s *DashboardWidgetsService) Validate(ctx context.Context, organizationSlug string, widget *DashboardWidget) (DashboardWidgetErrors, *Response, error) { | ||
u := fmt.Sprintf("0/organizations/%v/dashboards/widgets/", organizationSlug) | ||
|
||
req, err := s.client.NewRequest("POST", u, widget) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
widgetErrors := make(DashboardWidgetErrors) | ||
resp, err := s.client.Do(ctx, req, &widgetErrors) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
if len(widgetErrors) == 0 { | ||
return nil, resp, err | ||
} | ||
return widgetErrors, resp, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package sentry | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestDashboardWidgetsService_Validate_pass(t *testing.T) { | ||
client, mux, _, teardown := setup() | ||
defer teardown() | ||
|
||
mux.HandleFunc("/api/0/organizations/the-interstellar-jurisdiction/dashboards/widgets/", func(w http.ResponseWriter, r *http.Request) { | ||
assertMethod(t, "POST", r) | ||
w.Header().Set("Content-Type", "application/json") | ||
fmt.Fprint(w, `{}`) | ||
}) | ||
|
||
widget := &DashboardWidget{ | ||
Title: String("Number of Errors"), | ||
DisplayType: String("big_number"), | ||
Interval: String("5m"), | ||
Queries: []*DashboardWidgetQuery{ | ||
{ | ||
ID: String("115037"), | ||
Fields: []string{"count()"}, | ||
Aggregates: []string{"count()"}, | ||
Columns: []string{}, | ||
FieldAliases: []string{}, | ||
Name: String(""), | ||
Conditions: String("!event.type:transaction"), | ||
OrderBy: String(""), | ||
}, | ||
}, | ||
WidgetType: String("discover"), | ||
Layout: &DashboardWidgetLayout{ | ||
X: Int(0), | ||
Y: Int(0), | ||
W: Int(2), | ||
H: Int(1), | ||
MinH: Int(1), | ||
}, | ||
} | ||
ctx := context.Background() | ||
widgetErrors, _, err := client.DashboardWidgets.Validate(ctx, "the-interstellar-jurisdiction", widget) | ||
assert.Nil(t, widgetErrors) | ||
assert.NoError(t, err) | ||
} | ||
|
||
func TestDashboardWidgetsService_Validate_fail(t *testing.T) { | ||
client, mux, _, teardown := setup() | ||
defer teardown() | ||
|
||
mux.HandleFunc("/api/0/organizations/the-interstellar-jurisdiction/dashboards/widgets/", func(w http.ResponseWriter, r *http.Request) { | ||
assertMethod(t, "POST", r) | ||
w.Header().Set("Content-Type", "application/json") | ||
fmt.Fprint(w, `{"widgetType":["\"discover-invalid\" is not a valid choice."]}`) | ||
}) | ||
|
||
widget := &DashboardWidget{ | ||
Title: String("Number of Errors"), | ||
DisplayType: String("big_number"), | ||
Interval: String("5m"), | ||
Queries: []*DashboardWidgetQuery{ | ||
{ | ||
ID: String("115037"), | ||
Fields: []string{"count()"}, | ||
Aggregates: []string{"count()"}, | ||
Columns: []string{}, | ||
FieldAliases: []string{}, | ||
Name: String(""), | ||
Conditions: String("!event.type:transaction"), | ||
OrderBy: String(""), | ||
}, | ||
}, | ||
WidgetType: String("discover-invalid"), | ||
Layout: &DashboardWidgetLayout{ | ||
X: Int(0), | ||
Y: Int(0), | ||
W: Int(2), | ||
H: Int(1), | ||
MinH: Int(1), | ||
}, | ||
} | ||
ctx := context.Background() | ||
widgetErrors, _, err := client.DashboardWidgets.Validate(ctx, "the-interstellar-jurisdiction", widget) | ||
expected := DashboardWidgetErrors{ | ||
"widgetType": []string{`"discover-invalid" is not a valid choice.`}, | ||
} | ||
assert.Equal(t, expected, widgetErrors) | ||
assert.NoError(t, err) | ||
} |
Oops, something went wrong.