Skip to content

Commit f0431e4

Browse files
authored
sdk: add context.Context to REST calls (#77)
* sdk: add context.Context to REST calls Add `context.Context` as the first argument to functions which do requests. This allows users to have fine-grained control over the timeouts in the typical Go manner - they will not have to have the same timeout on all operations that is set via `http.Client`. This also informs our users that these functions do requests and that they *do* block for a good reason - a HTTP request is made and then we block until a response comes. * rest-request: make it compatible with older versions Go 1.13 has introduced `NewRequestWithContext()` so for compatibility reasons let's do it the old way - via `NewRequest()` + `WithContext()`.
1 parent 63c6c7e commit f0431e4

24 files changed

+232
-192
lines changed

cmd/backup-dashboards/main.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ package main
2626
*/
2727

2828
import (
29+
"context"
2930
"fmt"
3031
"io/ioutil"
3132
"os"
@@ -44,13 +45,14 @@ func main() {
4445
fmt.Fprint(os.Stderr, "Usage: backup-dashboards http://grafana.host:3000 api-key-string-here\n")
4546
os.Exit(0)
4647
}
48+
ctx := context.Background()
4749
c := sdk.NewClient(os.Args[1], os.Args[2], sdk.DefaultHTTPClient)
48-
if boardLinks, err = c.SearchDashboards("", false); err != nil {
50+
if boardLinks, err = c.SearchDashboards(ctx, "", false); err != nil {
4951
fmt.Fprintf(os.Stderr, fmt.Sprintf("%s\n", err))
5052
os.Exit(1)
5153
}
5254
for _, link := range boardLinks {
53-
if rawBoard, meta, err = c.GetRawDashboardBySlug(link.URI); err != nil {
55+
if rawBoard, meta, err = c.GetRawDashboardBySlug(ctx, link.URI); err != nil {
5456
fmt.Fprintf(os.Stderr, fmt.Sprintf("%s for %s\n", err, link.URI))
5557
continue
5658
}

cmd/backup-datasources/main.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ package main
2626
*/
2727

2828
import (
29+
"context"
2930
"encoding/json"
3031
"fmt"
3132
"io/ioutil"
@@ -46,8 +47,9 @@ func main() {
4647
fmt.Fprint(os.Stderr, "Usage: backup-datasources http://sdk.host:3000 api-key-string-here\n")
4748
os.Exit(0)
4849
}
50+
ctx := context.Background()
4951
c := sdk.NewClient(os.Args[1], os.Args[2], sdk.DefaultHTTPClient)
50-
if datasources, err = c.GetAllDatasources(); err != nil {
52+
if datasources, err = c.GetAllDatasources(ctx); err != nil {
5153
fmt.Fprintf(os.Stderr, fmt.Sprintf("%s\n", err))
5254
os.Exit(1)
5355
}

cmd/import-dashboards-raw/main.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ package main
3131
*/
3232

3333
import (
34+
"context"
3435
"fmt"
3536
"io/ioutil"
3637
"log"
@@ -50,6 +51,7 @@ func main() {
5051
fmt.Fprint(os.Stderr, "Usage: import-dashboards http://grafana.host:3000 api-key-string-here\n")
5152
os.Exit(0)
5253
}
54+
ctx := context.Background()
5355
c := sdk.NewClient(os.Args[1], os.Args[2], sdk.DefaultHTTPClient)
5456
filesInDir, err = ioutil.ReadDir(".")
5557
if err != nil {
@@ -61,7 +63,7 @@ func main() {
6163
log.Println(err)
6264
continue
6365
}
64-
_, err := c.SetRawDashboard(rawBoard)
66+
_, err := c.SetRawDashboard(ctx, rawBoard)
6567
if err != nil {
6668
log.Printf("error on importing dashboard from %s", file.Name())
6769
continue

cmd/import-dashboards/main.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ package main
2929
*/
3030

3131
import (
32+
"context"
3233
"encoding/json"
3334
"fmt"
3435
"io/ioutil"
@@ -49,6 +50,7 @@ func main() {
4950
fmt.Fprint(os.Stderr, "Usage: import-dashboards http://grafana-host:3000 api-key-string-here\n")
5051
os.Exit(0)
5152
}
53+
ctx := context.Background()
5254
c := sdk.NewClient(os.Args[1], os.Args[2], sdk.DefaultHTTPClient)
5355
filesInDir, err = ioutil.ReadDir(".")
5456
if err != nil {
@@ -65,12 +67,12 @@ func main() {
6567
log.Println(err)
6668
continue
6769
}
68-
c.DeleteDashboard(board.UpdateSlug())
70+
c.DeleteDashboard(ctx, board.UpdateSlug())
6971
params := sdk.SetDashboardParams{
7072
FolderID: sdk.DefaultFolderId,
7173
Overwrite: false,
7274
}
73-
_, err := c.SetDashboard(board, params)
75+
_, err := c.SetDashboard(ctx, board, params)
7476
if err != nil {
7577
log.Printf("error on importing dashboard %s", board.Title)
7678
continue

cmd/import-datasources/main.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ package main
2929
*/
3030

3131
import (
32+
"context"
3233
"encoding/json"
3334
"fmt"
3435
"io/ioutil"
@@ -50,8 +51,9 @@ func main() {
5051
fmt.Fprint(os.Stderr, "Usage: import-datasources http://sdk-host:3000 api-key-string-here\n")
5152
os.Exit(0)
5253
}
54+
ctx := context.Background()
5355
c := sdk.NewClient(os.Args[1], os.Args[2], sdk.DefaultHTTPClient)
54-
if datasources, err = c.GetAllDatasources(); err != nil {
56+
if datasources, err = c.GetAllDatasources(ctx); err != nil {
5557
fmt.Fprintf(os.Stderr, fmt.Sprintf("%s\n", err))
5658
os.Exit(1)
5759
}
@@ -72,11 +74,11 @@ func main() {
7274
}
7375
for _, existingDS := range datasources {
7476
if existingDS.Name == newDS.Name {
75-
c.DeleteDatasource(existingDS.ID)
77+
c.DeleteDatasource(ctx, existingDS.ID)
7678
break
7779
}
7880
}
79-
if status, err = c.CreateDatasource(newDS); err != nil {
81+
if status, err = c.CreateDatasource(ctx, newDS); err != nil {
8082
fmt.Fprint(os.Stderr, fmt.Sprintf("error on importing datasource %s with %s (%s)", newDS.Name, err, *status.Message))
8183
}
8284
}

rest-admin.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
package sdk
22

33
import (
4+
"context"
45
"encoding/json"
56
"fmt"
67
)
78

89
// CreateUser creates a new global user.
910
// Requires basic authentication and that the authenticated user is a Grafana Admin.
1011
// Reflects POST /api/admin/users API call.
11-
func (r *Client) CreateUser(user User) (StatusMessage, error) {
12+
func (r *Client) CreateUser(ctx context.Context, user User) (StatusMessage, error) {
1213
var (
1314
raw []byte
1415
resp StatusMessage
@@ -17,7 +18,7 @@ func (r *Client) CreateUser(user User) (StatusMessage, error) {
1718
if raw, err = json.Marshal(user); err != nil {
1819
return StatusMessage{}, err
1920
}
20-
if raw, _, err = r.post("api/admin/users", nil, raw); err != nil {
21+
if raw, _, err = r.post(ctx, "api/admin/users", nil, raw); err != nil {
2122
return StatusMessage{}, err
2223
}
2324
if err = json.Unmarshal(raw, &resp); err != nil {
@@ -29,7 +30,7 @@ func (r *Client) CreateUser(user User) (StatusMessage, error) {
2930
// UpdateUserPermissions updates the permissions of a global user.
3031
// Requires basic authentication and that the authenticated user is a Grafana Admin.
3132
// Reflects PUT /api/admin/users/:userId/password API call.
32-
func (r *Client) UpdateUserPermissions(permissions UserPermissions, uid uint) (StatusMessage, error) {
33+
func (r *Client) UpdateUserPermissions(ctx context.Context, permissions UserPermissions, uid uint) (StatusMessage, error) {
3334
var (
3435
raw []byte
3536
reply StatusMessage
@@ -38,7 +39,7 @@ func (r *Client) UpdateUserPermissions(permissions UserPermissions, uid uint) (S
3839
if raw, err = json.Marshal(permissions); err != nil {
3940
return StatusMessage{}, err
4041
}
41-
if raw, _, err = r.put(fmt.Sprintf("api/admin/users/%d/permissions", uid), nil, raw); err != nil {
42+
if raw, _, err = r.put(ctx, fmt.Sprintf("api/admin/users/%d/permissions", uid), nil, raw); err != nil {
4243
return StatusMessage{}, err
4344
}
4445
err = json.Unmarshal(raw, &reply)
@@ -48,14 +49,14 @@ func (r *Client) UpdateUserPermissions(permissions UserPermissions, uid uint) (S
4849
// SwitchUserContext switches user context to the given organization.
4950
// Requires basic authentication and that the authenticated user is a Grafana Admin.
5051
// Reflects POST /api/users/:userId/using/:organizationId API call.
51-
func (r *Client) SwitchUserContext(uid uint, oid uint) (StatusMessage, error) {
52+
func (r *Client) SwitchUserContext(ctx context.Context, uid uint, oid uint) (StatusMessage, error) {
5253
var (
5354
raw []byte
5455
resp StatusMessage
5556
err error
5657
)
5758

58-
if raw, _, err = r.post(fmt.Sprintf("/api/users/%d/using/%d", uid, oid), nil, raw); err != nil {
59+
if raw, _, err = r.post(ctx, fmt.Sprintf("/api/users/%d/using/%d", uid, oid), nil, raw); err != nil {
5960
return StatusMessage{}, err
6061
}
6162
if err = json.Unmarshal(raw, &resp); err != nil {

rest-admin_integration_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package sdk_test
22

33
import (
4+
"context"
45
"testing"
56

67
"github.com/grafana-tools/sdk"
@@ -9,6 +10,7 @@ import (
910
func TestAdminOperations(t *testing.T) {
1011
shouldSkip(t)
1112
client := getClient(t)
13+
ctx := context.Background()
1214

1315
u := sdk.User{
1416
Login: "test",
@@ -19,7 +21,7 @@ func TestAdminOperations(t *testing.T) {
1921
IsGrafanaAdmin: false,
2022
}
2123

22-
st, err := client.CreateUser(u)
24+
st, err := client.CreateUser(ctx, u)
2325
if err != nil {
2426
t.Fatalf("failed to create an user: %s", err.Error())
2527
}
@@ -29,7 +31,7 @@ func TestAdminOperations(t *testing.T) {
2931

3032
uid := *st.ID
3133

32-
retrievedUser, err := client.GetUser(uid)
34+
retrievedUser, err := client.GetUser(ctx, uid)
3335
if err != nil {
3436
t.Fatalf("failed to get user: %s", err.Error())
3537
}
@@ -38,12 +40,12 @@ func TestAdminOperations(t *testing.T) {
3840
t.Fatal("retrieved data does not match what was created")
3941
}
4042

41-
_, err = client.UpdateUserPermissions(sdk.UserPermissions{IsGrafanaAdmin: true}, uid)
43+
_, err = client.UpdateUserPermissions(ctx, sdk.UserPermissions{IsGrafanaAdmin: true}, uid)
4244
if err != nil {
4345
t.Fatalf("failed to convert the user into an admin: %s", err)
4446
}
4547

46-
retrievedUser, err = client.GetUser(uid)
48+
retrievedUser, err = client.GetUser(ctx, uid)
4749
if err != nil {
4850
t.Fatalf("failed to get user: %s", err.Error())
4951
}

rest-alertnotification.go

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,21 @@ package sdk
1717
*/
1818

1919
import (
20+
"context"
2021
"encoding/json"
2122
"fmt"
2223
)
2324

2425
// GetAllAlertNotifications gets all alert notification channels.
2526
// Reflects GET /api/alert-notifications API call.
26-
func (c *Client) GetAllAlertNotifications() ([]AlertNotification, error) {
27+
func (c *Client) GetAllAlertNotifications(ctx context.Context) ([]AlertNotification, error) {
2728
var (
2829
raw []byte
2930
an []AlertNotification
3031
code int
3132
err error
3233
)
33-
if raw, code, err = c.get("api/alert-notifications", nil); err != nil {
34+
if raw, code, err = c.get(ctx, "api/alert-notifications", nil); err != nil {
3435
return nil, err
3536
}
3637
if code != 200 {
@@ -42,14 +43,14 @@ func (c *Client) GetAllAlertNotifications() ([]AlertNotification, error) {
4243

4344
// GetAlertNotificationUID gets the alert notification channel which has the specified uid.
4445
// Reflects GET /api/alert-notifications/uid/:uid API call.
45-
func (c *Client) GetAlertNotificationUID(uid string) (AlertNotification, error) {
46+
func (c *Client) GetAlertNotificationUID(ctx context.Context, uid string) (AlertNotification, error) {
4647
var (
4748
raw []byte
4849
an AlertNotification
4950
code int
5051
err error
5152
)
52-
if raw, code, err = c.get(fmt.Sprintf("api/alert-notifications/uid/%s", uid), nil); err != nil {
53+
if raw, code, err = c.get(ctx, fmt.Sprintf("api/alert-notifications/uid/%s", uid), nil); err != nil {
5354
return an, err
5455
}
5556
if code != 200 {
@@ -61,14 +62,14 @@ func (c *Client) GetAlertNotificationUID(uid string) (AlertNotification, error)
6162

6263
// GetAlertNotificationID gets the alert notification channel which has the specified id.
6364
// Reflects GET /api/alert-notifications/:id API call.
64-
func (c *Client) GetAlertNotificationID(id uint) (AlertNotification, error) {
65+
func (c *Client) GetAlertNotificationID(ctx context.Context, id uint) (AlertNotification, error) {
6566
var (
6667
raw []byte
6768
an AlertNotification
6869
code int
6970
err error
7071
)
71-
if raw, code, err = c.get(fmt.Sprintf("api/alert-notifications/%d", id), nil); err != nil {
72+
if raw, code, err = c.get(ctx, fmt.Sprintf("api/alert-notifications/%d", id), nil); err != nil {
7273
return an, err
7374
}
7475
if code != 200 {
@@ -80,7 +81,7 @@ func (c *Client) GetAlertNotificationID(id uint) (AlertNotification, error) {
8081

8182
// CreateAlertNotification creates a new alert notification channel.
8283
// Reflects POST /api/alert-notifications API call.
83-
func (c *Client) CreateAlertNotification(an AlertNotification) (int64, error) {
84+
func (c *Client) CreateAlertNotification(ctx context.Context, an AlertNotification) (int64, error) {
8485
var (
8586
raw []byte
8687
code int
@@ -89,7 +90,7 @@ func (c *Client) CreateAlertNotification(an AlertNotification) (int64, error) {
8990
if raw, err = json.Marshal(an); err != nil {
9091
return -1, err
9192
}
92-
if raw, code, err = c.post(fmt.Sprintf("api/alert-notifications"), nil, raw); err != nil {
93+
if raw, code, err = c.post(ctx, fmt.Sprintf("api/alert-notifications"), nil, raw); err != nil {
9394
return -1, err
9495
}
9596
if code != 200 {
@@ -104,7 +105,7 @@ func (c *Client) CreateAlertNotification(an AlertNotification) (int64, error) {
104105

105106
// UpdateAlertNotificationUID updates the specified alert notification channel.
106107
// Reflects PUT /api/alert-notifications/uid/:uid API call.
107-
func (c *Client) UpdateAlertNotificationUID(an AlertNotification, uid string) error {
108+
func (c *Client) UpdateAlertNotificationUID(ctx context.Context, an AlertNotification, uid string) error {
108109
var (
109110
raw []byte
110111
code int
@@ -113,7 +114,7 @@ func (c *Client) UpdateAlertNotificationUID(an AlertNotification, uid string) er
113114
if raw, err = json.Marshal(an); err != nil {
114115
return err
115116
}
116-
if raw, code, err = c.put(fmt.Sprintf("api/alert-notifications/uid/%s", uid), nil, raw); err != nil {
117+
if raw, code, err = c.put(ctx, fmt.Sprintf("api/alert-notifications/uid/%s", uid), nil, raw); err != nil {
117118
return err
118119
}
119120
if code != 200 {
@@ -124,7 +125,7 @@ func (c *Client) UpdateAlertNotificationUID(an AlertNotification, uid string) er
124125

125126
// UpdateAlertNotificationID updates the specified alert notification channel.
126127
// Reflects PUT /api/alert-notifications/:id API call.
127-
func (c *Client) UpdateAlertNotificationID(an AlertNotification, id uint) error {
128+
func (c *Client) UpdateAlertNotificationID(ctx context.Context, an AlertNotification, id uint) error {
128129
var (
129130
raw []byte
130131
code int
@@ -133,7 +134,7 @@ func (c *Client) UpdateAlertNotificationID(an AlertNotification, id uint) error
133134
if raw, err = json.Marshal(an); err != nil {
134135
return err
135136
}
136-
if raw, code, err = c.put(fmt.Sprintf("api/alert-notifications/%d", id), nil, raw); err != nil {
137+
if raw, code, err = c.put(ctx, fmt.Sprintf("api/alert-notifications/%d", id), nil, raw); err != nil {
137138
return err
138139
}
139140
if code != 200 {
@@ -144,13 +145,13 @@ func (c *Client) UpdateAlertNotificationID(an AlertNotification, id uint) error
144145

145146
// DeleteAlertNotificationUID deletes the specified alert notification channel.
146147
// Reflects DELETE /api/alert-notifications/uid/:uid API call.
147-
func (c *Client) DeleteAlertNotificationUID(uid string) error {
148+
func (c *Client) DeleteAlertNotificationUID(ctx context.Context, uid string) error {
148149
var (
149150
raw []byte
150151
code int
151152
err error
152153
)
153-
if raw, code, err = c.delete(fmt.Sprintf("api/alert-notifications/uid/%s", uid)); err != nil {
154+
if raw, code, err = c.delete(ctx, fmt.Sprintf("api/alert-notifications/uid/%s", uid)); err != nil {
154155
return err
155156
}
156157
if code != 200 {
@@ -161,13 +162,13 @@ func (c *Client) DeleteAlertNotificationUID(uid string) error {
161162

162163
// DeleteAlertNotificationID deletes the specified alert notification channel.
163164
// Reflects DELETE /api/alert-notifications/:id API call.
164-
func (c *Client) DeleteAlertNotificationID(id uint) error {
165+
func (c *Client) DeleteAlertNotificationID(ctx context.Context, id uint) error {
165166
var (
166167
raw []byte
167168
code int
168169
err error
169170
)
170-
if raw, code, err = c.delete(fmt.Sprintf("api/alert-notifications/%d", id)); err != nil {
171+
if raw, code, err = c.delete(ctx, fmt.Sprintf("api/alert-notifications/%d", id)); err != nil {
171172
return err
172173
}
173174
if code != 200 {

0 commit comments

Comments
 (0)