diff --git a/admin.go b/admin.go index 96a9fd16..fd88df28 100644 --- a/admin.go +++ b/admin.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -25,7 +24,7 @@ func (c *Client) CreateUser(user User) (int64, error) { ID int64 `json:"id"` }{} - err = c.request("POST", "/api/admin/users", nil, bytes.NewBuffer(data), &created) + err = c.request("POST", "/api/admin/users", nil, data, &created) if err != nil { return id, err } @@ -45,7 +44,7 @@ func (c *Client) UpdateUserPassword(id int64, password string) error { if err != nil { return err } - return c.request("PUT", fmt.Sprintf("/api/admin/users/%d/password", id), nil, bytes.NewBuffer(data), nil) + return c.request("PUT", fmt.Sprintf("/api/admin/users/%d/password", id), nil, data, nil) } // UpdateUserPermissions sets a user's admin status. @@ -55,7 +54,7 @@ func (c *Client) UpdateUserPermissions(id int64, isAdmin bool) error { if err != nil { return err } - return c.request("PUT", fmt.Sprintf("/api/admin/users/%d/permissions", id), nil, bytes.NewBuffer(data), nil) + return c.request("PUT", fmt.Sprintf("/api/admin/users/%d/permissions", id), nil, data, nil) } // PauseAllAlerts pauses all Grafana alerts. @@ -68,7 +67,7 @@ func (c *Client) PauseAllAlerts() (PauseAllAlertsResponse, error) { return result, err } - err = c.request("POST", "/api/admin/pause-all-alerts", nil, bytes.NewBuffer(data), &result) + err = c.request("POST", "/api/admin/pause-all-alerts", nil, data, &result) return result, err } diff --git a/alert.go b/alert.go index c3eb6025..39f567c4 100644 --- a/alert.go +++ b/alert.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "net/url" @@ -68,7 +67,7 @@ func (c *Client) PauseAlert(id int64) (PauseAlertResponse, error) { return result, err } - err = c.request("POST", path, nil, bytes.NewBuffer(data), &result) + err = c.request("POST", path, nil, data, &result) if err != nil { return result, err } diff --git a/alerting_alert_rule.go b/alerting_alert_rule.go index 87521f28..1eaffc59 100644 --- a/alerting_alert_rule.go +++ b/alerting_alert_rule.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "time" @@ -93,7 +92,7 @@ func (c *Client) SetAlertRuleGroup(group RuleGroup) error { } uri := fmt.Sprintf("/api/v1/provisioning/folder/%s/rule-groups/%s", folderUID, name) - return c.request("PUT", uri, nil, bytes.NewBuffer(req), nil) + return c.request("PUT", uri, nil, req, nil) } // NewAlertRule creates a new alert rule and returns its UID. @@ -104,7 +103,7 @@ func (c *Client) NewAlertRule(ar *AlertRule) (string, error) { return "", err } result := AlertRule{} - err = c.request("POST", "/api/v1/provisioning/alert-rules", nil, bytes.NewBuffer(req), &result) + err = c.request("POST", "/api/v1/provisioning/alert-rules", nil, req, &result) if err != nil { return "", err } @@ -120,7 +119,7 @@ func (c *Client) UpdateAlertRule(ar *AlertRule) error { return err } - return c.request("PUT", uri, nil, bytes.NewBuffer(req), nil) + return c.request("PUT", uri, nil, req, nil) } // DeleteAlertRule deletes a alert rule, identified by the alert rule's UID. diff --git a/alerting_contact_point.go b/alerting_contact_point.go index 00659c06..023e4f4c 100644 --- a/alerting_contact_point.go +++ b/alerting_contact_point.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "net/url" @@ -62,7 +61,7 @@ func (c *Client) NewContactPoint(p *ContactPoint) (string, error) { } result := ContactPoint{} - err = c.request("POST", "/api/v1/provisioning/contact-points", nil, bytes.NewBuffer(req), &result) + err = c.request("POST", "/api/v1/provisioning/contact-points", nil, req, &result) if err != nil { return "", err } @@ -77,7 +76,7 @@ func (c *Client) UpdateContactPoint(p *ContactPoint) error { return err } - return c.request("PUT", uri, nil, bytes.NewBuffer(req), nil) + return c.request("PUT", uri, nil, req, nil) } // DeleteContactPoint deletes a contact point. diff --git a/alerting_message_template.go b/alerting_message_template.go index 75edb2da..e8b82cef 100644 --- a/alerting_message_template.go +++ b/alerting_message_template.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -44,7 +43,7 @@ func (c *Client) SetMessageTemplate(name, content string) error { } uri := fmt.Sprintf("/api/v1/provisioning/templates/%s", name) - return c.request("PUT", uri, nil, bytes.NewBuffer(body), nil) + return c.request("PUT", uri, nil, body, nil) } // DeleteMessageTemplate deletes a message template. diff --git a/alerting_mute_timing.go b/alerting_mute_timing.go index dbb14d91..b6d79bb6 100644 --- a/alerting_mute_timing.go +++ b/alerting_mute_timing.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -65,7 +64,7 @@ func (c *Client) NewMuteTiming(mt *MuteTiming) error { return err } - return c.request("POST", "/api/v1/provisioning/mute-timings", nil, bytes.NewBuffer(req), nil) + return c.request("POST", "/api/v1/provisioning/mute-timings", nil, req, nil) } // UpdateMuteTiming updates a mute timing. @@ -76,7 +75,7 @@ func (c *Client) UpdateMuteTiming(mt *MuteTiming) error { return err } - return c.request("PUT", uri, nil, bytes.NewBuffer(req), nil) + return c.request("PUT", uri, nil, req, nil) } // DeleteMutetiming deletes a mute timing. diff --git a/alerting_notification_policy.go b/alerting_notification_policy.go index 8b87301e..2011cd95 100644 --- a/alerting_notification_policy.go +++ b/alerting_notification_policy.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -116,7 +115,7 @@ func (c *Client) SetNotificationPolicyTree(np *NotificationPolicyTree) error { if err != nil { return err } - return c.request("PUT", "/api/v1/provisioning/policies", nil, bytes.NewBuffer(req), nil) + return c.request("PUT", "/api/v1/provisioning/policies", nil, req, nil) } func (c *Client) ResetNotificationPolicyTree() error { diff --git a/alertnotification.go b/alertnotification.go index d98e7905..172f15bf 100644 --- a/alertnotification.go +++ b/alertnotification.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -59,7 +58,7 @@ func (c *Client) NewAlertNotification(a *AlertNotification) (int64, error) { ID int64 `json:"id"` }{} - err = c.request("POST", "/api/alert-notifications", nil, bytes.NewBuffer(data), &result) + err = c.request("POST", "/api/alert-notifications", nil, data, &result) if err != nil { return 0, err } @@ -75,7 +74,7 @@ func (c *Client) UpdateAlertNotification(a *AlertNotification) error { if err != nil { return err } - err = c.request("PUT", path, nil, bytes.NewBuffer(data), nil) + err = c.request("PUT", path, nil, data, nil) return err } diff --git a/annotation.go b/annotation.go index 341eee01..48911d70 100644 --- a/annotation.go +++ b/annotation.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "net/url" @@ -58,7 +57,7 @@ func (c *Client) NewAnnotation(a *Annotation) (int64, error) { ID int64 `json:"id"` }{} - err = c.request("POST", "/api/annotations", nil, bytes.NewBuffer(data), &result) + err = c.request("POST", "/api/annotations", nil, data, &result) if err != nil { return 0, err } @@ -77,7 +76,7 @@ func (c *Client) NewGraphiteAnnotation(gfa *GraphiteAnnotation) (int64, error) { ID int64 `json:"id"` }{} - err = c.request("POST", "/api/annotations/graphite", nil, bytes.NewBuffer(data), &result) + err = c.request("POST", "/api/annotations/graphite", nil, data, &result) if err != nil { return 0, err } @@ -97,7 +96,7 @@ func (c *Client) UpdateAnnotation(id int64, a *Annotation) (string, error) { Message string `json:"message"` }{} - err = c.request("PUT", path, nil, bytes.NewBuffer(data), &result) + err = c.request("PUT", path, nil, data, &result) if err != nil { return "", err } @@ -117,7 +116,7 @@ func (c *Client) PatchAnnotation(id int64, a *Annotation) (string, error) { Message string `json:"message"` }{} - err = c.request("PATCH", path, nil, bytes.NewBuffer(data), &result) + err = c.request("PATCH", path, nil, data, &result) if err != nil { return "", err } @@ -132,7 +131,7 @@ func (c *Client) DeleteAnnotation(id int64) (string, error) { Message string `json:"message"` }{} - err := c.request("DELETE", path, nil, bytes.NewBuffer(nil), &result) + err := c.request("DELETE", path, nil, nil, &result) if err != nil { return "", err } @@ -147,7 +146,7 @@ func (c *Client) DeleteAnnotationByRegionID(id int64) (string, error) { Message string `json:"message"` }{} - err := c.request("DELETE", path, nil, bytes.NewBuffer(nil), &result) + err := c.request("DELETE", path, nil, nil, &result) if err != nil { return "", err } diff --git a/api_key.go b/api_key.go index e6482362..1065b383 100644 --- a/api_key.go +++ b/api_key.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "net/url" @@ -42,7 +41,7 @@ func (c *Client) CreateAPIKey(request CreateAPIKeyRequest) (CreateAPIKeyResponse return response, err } - err = c.request("POST", "/api/auth/keys", nil, bytes.NewBuffer(data), &response) + err = c.request("POST", "/api/auth/keys", nil, data, &response) return response, err } diff --git a/builtin_role_assignments.go b/builtin_role_assignments.go index 080e4a60..e364525a 100644 --- a/builtin_role_assignments.go +++ b/builtin_role_assignments.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -33,7 +32,7 @@ func (c *Client) NewBuiltInRoleAssignment(builtInRoleAssignment BuiltInRoleAssig br := &BuiltInRoleAssignment{} - err = c.request("POST", baseURL, nil, bytes.NewBuffer(body), &br) + err = c.request("POST", baseURL, nil, body, &br) if err != nil { return nil, err } @@ -52,7 +51,7 @@ func (c *Client) DeleteBuiltInRoleAssignment(builtInRole BuiltInRoleAssignment) "global": {fmt.Sprint(builtInRole.Global)}, } url := fmt.Sprintf("%s/%s/roles/%s", baseURL, builtInRole.BuiltinRole, builtInRole.RoleUID) - err = c.request("DELETE", url, qp, bytes.NewBuffer(data), nil) + err = c.request("DELETE", url, qp, data, nil) return err } diff --git a/client.go b/client.go index 2f43100f..e3f5aed3 100644 --- a/client.go +++ b/client.go @@ -40,6 +40,8 @@ type Config struct { OrgID int64 // NumRetries contains the number of attempted retries NumRetries int + // RetryTimeout says how long to wait before retrying a request + RetryTimeout time.Duration } // New creates a new Grafana client. @@ -71,7 +73,7 @@ func (c Client) WithOrgID(orgID int64) *Client { return &c } -func (c *Client) request(method, requestPath string, query url.Values, body io.Reader, responseStruct interface{}) error { +func (c *Client) request(method, requestPath string, query url.Values, body []byte, responseStruct interface{}) error { var ( req *http.Request resp *http.Response @@ -79,27 +81,19 @@ func (c *Client) request(method, requestPath string, query url.Values, body io.R bodyContents []byte ) - // If we want to retry a request that sends data, we'll need to stash the request data in memory. Otherwise, we lose it since readers cannot be replayed. - var bodyBuffer bytes.Buffer - if c.config.NumRetries > 0 && body != nil { - body = io.TeeReader(body, &bodyBuffer) - } - // retry logic for n := 0; n <= c.config.NumRetries; n++ { - // If it's not the first request, re-use the request body we stashed earlier. - if n > 0 { - body = bytes.NewReader(bodyBuffer.Bytes()) - } - - req, err = c.newRequest(method, requestPath, query, body) + req, err = c.newRequest(method, requestPath, query, bytes.NewReader(body)) if err != nil { return err } // Wait a bit if that's not the first request if n != 0 { - time.Sleep(time.Second * 5) + if c.config.RetryTimeout == 0 { + c.config.RetryTimeout = time.Second * 5 + } + time.Sleep(c.config.RetryTimeout) } resp, err = c.client.Do(req) diff --git a/client_test.go b/client_test.go index b7552597..47d2dee3 100644 --- a/client_test.go +++ b/client_test.go @@ -3,8 +3,13 @@ package gapi import ( "bytes" "encoding/json" + "errors" + "io/ioutil" + "net/http" + "net/http/httptest" "net/url" "testing" + "time" ) func TestNew_basicAuth(t *testing.T) { @@ -164,7 +169,7 @@ func TestRequest_200UnmarshalPut(t *testing.T) { }{} q := url.Values{} q.Add("a", "b") - err = client.request("PUT", "/foo", q, bytes.NewBuffer(data), &result) + err = client.request("PUT", "/foo", q, data, &result) if err != nil { t.Error(err) } @@ -173,3 +178,91 @@ func TestRequest_200UnmarshalPut(t *testing.T) { t.Errorf("expected: name; got: %s", result.Name) } } + +func TestClient_requestWithRetries(t *testing.T) { + // Test that calls to c.client.Do will retry correctly, + // even if the original request fails prematurely + + body := []byte(`lorem ipsum dolor sit amet`) + + var try int + + // This is our actual test, checking that we do in fact receive a body. + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer r.Body.Close() + + try++ + + got, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Errorf("retry %d: unexpected error reading body: %v", try, err) + } + + if !bytes.Equal(body, got) { + t.Errorf("retry %d: request body doesn't match body sent by client:\nexp: %v\ngot: %v", try, body, got) + } + + switch try { + case 1: + http.Error(w, `{"error":"waiting for the right time"}`, http.StatusInternalServerError) + + case 2: + http.Error(w, `{"error":"calm down"}`, http.StatusTooManyRequests) + + default: + w.Write([]byte(`{"foo":"bar"}`)) //nolint:errcheck + } + })) + defer ts.Close() + + // From http.Client.Do documentation: an error is returned if + // caused by client policy (such as CheckRedirect), or failure to + // speak HTTP (such as a network connectivity problem). A non-2xx + // status code doesn't cause an error. + // + // For this reason we build a custom http.Client that will fail + // the first time with an error *before* the request is sent, and + // succeed afterwards. See customRoundTripper below. + httpClient := &http.Client{ + Transport: &customRoundTripper{}, + } + + c, err := New(ts.URL, Config{ + NumRetries: 5, + Client: httpClient, + RetryTimeout: 50 * time.Millisecond, + }) + if err != nil { + t.Fatalf("unexpected error creating client: %v", err) + } + + type res struct { + Foo string `json:"foo"` + } + + var got res + + if err := c.request(http.MethodPost, "/", nil, body, &got); err != nil { + t.Fatalf("unexpected error sending request: %v", err) + } + + exp := res{Foo: "bar"} + + if exp != got { + t.Fatalf("response doesn't match\nexp: %#v\ngot: %#v", exp, got) + } + + t.Logf("request successful after %d retries", try) +} + +type customRoundTripper struct { + try int +} + +func (rt *customRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { + if rt.try++; rt.try < 2 { + return nil, errors.New("failure") + } + + return http.DefaultTransport.RoundTrip(r) +} diff --git a/cloud_access_policy.go b/cloud_access_policy.go index 432abe9f..06b1018e 100644 --- a/cloud_access_policy.go +++ b/cloud_access_policy.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "net/url" @@ -76,7 +75,7 @@ func (c *Client) CreateCloudAccessPolicy(region string, input CreateCloudAccessP err = c.request("POST", "/api/v1/accesspolicies", url.Values{ "region": []string{region}, - }, bytes.NewBuffer(data), &result) + }, data, &result) return result, err } @@ -91,7 +90,7 @@ func (c *Client) UpdateCloudAccessPolicy(region, id string, input UpdateCloudAcc err = c.request("POST", fmt.Sprintf("/api/v1/accesspolicies/%s", id), url.Values{ "region": []string{region}, - }, bytes.NewBuffer(data), &result) + }, data, &result) return result, err } diff --git a/cloud_access_policy_token.go b/cloud_access_policy_token.go index 3c44255f..63803861 100644 --- a/cloud_access_policy_token.go +++ b/cloud_access_policy_token.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "net/url" @@ -65,7 +64,7 @@ func (c *Client) CreateCloudAccessPolicyToken(region string, input CreateCloudAc err = c.request("POST", "/api/v1/tokens", url.Values{ "region": []string{region}, - }, bytes.NewBuffer(data), &token) + }, data, &token) return token, err } @@ -80,7 +79,7 @@ func (c *Client) UpdateCloudAccessPolicyToken(region, id string, input UpdateClo err = c.request("POST", fmt.Sprintf("/api/v1/tokens/%s", id), url.Values{ "region": []string{region}, - }, bytes.NewBuffer(data), &token) + }, data, &token) return token, err } diff --git a/cloud_api_key.go b/cloud_api_key.go index 78c85ad5..f2a95b82 100644 --- a/cloud_api_key.go +++ b/cloud_api_key.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -30,7 +29,7 @@ func (c *Client) CreateCloudAPIKey(org string, input *CreateCloudAPIKeyInput) (* return nil, err } - err = c.request("POST", fmt.Sprintf("/api/orgs/%s/api-keys", org), nil, bytes.NewBuffer(data), &resp) + err = c.request("POST", fmt.Sprintf("/api/orgs/%s/api-keys", org), nil, data, &resp) return &resp, err } diff --git a/cloud_grafana_api_key.go b/cloud_grafana_api_key.go index ab4b2bf5..30c96752 100644 --- a/cloud_grafana_api_key.go +++ b/cloud_grafana_api_key.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -17,6 +16,6 @@ func (c *Client) CreateGrafanaAPIKeyFromCloud(stack string, input *CreateAPIKeyR } resp := &CreateAPIKeyResponse{} - err = c.request("POST", fmt.Sprintf("/api/instances/%s/api/auth/keys", stack), nil, bytes.NewBuffer(data), resp) + err = c.request("POST", fmt.Sprintf("/api/instances/%s/api/auth/keys", stack), nil, data, resp) return resp, err } diff --git a/cloud_grafana_service_account.go b/cloud_grafana_service_account.go index 3fbb2c72..5bc28f70 100644 --- a/cloud_grafana_service_account.go +++ b/cloud_grafana_service_account.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "net/http" @@ -17,7 +16,7 @@ func (c *Client) CreateGrafanaServiceAccountFromCloud(stack string, input *Creat } resp := &ServiceAccountDTO{} - err = c.request(http.MethodPost, fmt.Sprintf("/api/instances/%s/api/serviceaccounts", stack), nil, bytes.NewBuffer(data), resp) + err = c.request(http.MethodPost, fmt.Sprintf("/api/instances/%s/api/serviceaccounts", stack), nil, data, resp) return resp, err } @@ -30,7 +29,7 @@ func (c *Client) CreateGrafanaServiceAccountTokenFromCloud(stack string, input * } resp := &CreateServiceAccountTokenResponse{} - err = c.request(http.MethodPost, fmt.Sprintf("/api/instances/%s/api/serviceaccounts/%d/tokens", stack, input.ServiceAccountID), nil, bytes.NewBuffer(data), resp) + err = c.request(http.MethodPost, fmt.Sprintf("/api/instances/%s/api/serviceaccounts/%d/tokens", stack, input.ServiceAccountID), nil, data, resp) return resp, err } diff --git a/cloud_plugin.go b/cloud_plugin.go index 10ca2506..e47d2c01 100644 --- a/cloud_plugin.go +++ b/cloud_plugin.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "io/ioutil" @@ -44,7 +43,7 @@ func (c *Client) InstallCloudPlugin(stackSlug string, pluginSlug string, pluginV var installation CloudPluginInstallation - err = c.request("POST", fmt.Sprintf("/api/instances/%s/plugins", stackSlug), nil, bytes.NewBuffer(data), &installation) + err = c.request("POST", fmt.Sprintf("/api/instances/%s/plugins", stackSlug), nil, data, &installation) if err != nil { return nil, err } diff --git a/cloud_stack.go b/cloud_stack.go index e5dbff0d..a4f84f3d 100644 --- a/cloud_stack.go +++ b/cloud_stack.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "time" @@ -155,7 +154,7 @@ func (c *Client) NewStack(stack *CreateStackInput) (int64, error) { ID int64 `json:"id"` }{} - err = c.request("POST", "/api/instances", nil, bytes.NewBuffer(data), &result) + err = c.request("POST", "/api/instances", nil, data, &result) if err != nil { return 0, err } @@ -171,7 +170,7 @@ func (c *Client) UpdateStack(id int64, stack *UpdateStackInput) error { return err } - return c.request("POST", fmt.Sprintf("/api/instances/%d", id), nil, bytes.NewBuffer(data), nil) + return c.request("POST", fmt.Sprintf("/api/instances/%d", id), nil, data, nil) } // DeleteStack deletes the Grafana stack whose slug it passed in. diff --git a/dashboard.go b/dashboard.go index 683a879f..ba77c9a0 100644 --- a/dashboard.go +++ b/dashboard.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "net/url" @@ -52,7 +51,7 @@ func (c *Client) SaveDashboard(model map[string]interface{}, overwrite bool) (*D } result := &DashboardSaveResponse{} - err = c.request("POST", "/api/dashboards/db", nil, bytes.NewBuffer(data), &result) + err = c.request("POST", "/api/dashboards/db", nil, data, &result) if err != nil { return nil, err } @@ -68,7 +67,7 @@ func (c *Client) NewDashboard(dashboard Dashboard) (*DashboardSaveResponse, erro } result := &DashboardSaveResponse{} - err = c.request("POST", "/api/dashboards/db", nil, bytes.NewBuffer(data), &result) + err = c.request("POST", "/api/dashboards/db", nil, data, &result) if err != nil { return nil, err } diff --git a/dashboard_permissions.go b/dashboard_permissions.go index cad1612e..abb50f73 100644 --- a/dashboard_permissions.go +++ b/dashboard_permissions.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -39,7 +38,7 @@ func (c *Client) UpdateDashboardPermissions(id int64, items *PermissionItems) er return err } - return c.request("POST", path, nil, bytes.NewBuffer(data), nil) + return c.request("POST", path, nil, data, nil) } // DashboardPermissionsByUID fetches and returns the permissions for the dashboard whose UID it's passed. @@ -57,5 +56,5 @@ func (c *Client) UpdateDashboardPermissionsByUID(uid string, items *PermissionIt return err } - return c.request("POST", path, nil, bytes.NewBuffer(data), nil) + return c.request("POST", path, nil, data, nil) } diff --git a/datasource.go b/datasource.go index b1857f3d..72fff526 100644 --- a/datasource.go +++ b/datasource.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -46,7 +45,7 @@ func (c *Client) NewDataSource(s *DataSource) (int64, error) { ID int64 `json:"id"` }{} - err = c.request("POST", "/api/datasources", nil, bytes.NewBuffer(data), &result) + err = c.request("POST", "/api/datasources", nil, data, &result) if err != nil { return 0, err } @@ -62,7 +61,7 @@ func (c *Client) UpdateDataSource(s *DataSource) error { return err } - return c.request("PUT", path, nil, bytes.NewBuffer(data), nil) + return c.request("PUT", path, nil, data, nil) } func (c *Client) UpdateDataSourceByUID(s *DataSource) error { @@ -72,7 +71,7 @@ func (c *Client) UpdateDataSourceByUID(s *DataSource) error { return err } - return c.request("PUT", path, nil, bytes.NewBuffer(data), nil) + return c.request("PUT", path, nil, data, nil) } // DataSource fetches and returns the Grafana data source whose ID it's passed. diff --git a/datasource_permissions.go b/datasource_permissions.go index 7a70fb3d..a95d2eef 100644 --- a/datasource_permissions.go +++ b/datasource_permissions.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -81,7 +80,7 @@ func (c *Client) AddDatasourcePermission(id int64, item *DatasourcePermissionAdd return fmt.Errorf("marshal err: %w", err) } - if err = c.request("POST", path, nil, bytes.NewBuffer(data), nil); err != nil { + if err = c.request("POST", path, nil, data, nil); err != nil { return fmt.Errorf("error adding permissions at %s: %w", path, err) } diff --git a/folder.go b/folder.go index d9b223ae..07cf7f4e 100644 --- a/folder.go +++ b/folder.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "net/url" @@ -87,7 +86,7 @@ func (c *Client) NewFolder(title string, uid ...string) (Folder, error) { return folder, err } - err = c.request("POST", "/api/folders", nil, bytes.NewBuffer(data), &folder) + err = c.request("POST", "/api/folders", nil, data, &folder) if err != nil { return folder, err } @@ -109,7 +108,7 @@ func (c *Client) UpdateFolder(uid string, title string, newUID ...string) error return err } - return c.request("PUT", fmt.Sprintf("/api/folders/%s", uid), nil, bytes.NewBuffer(data), nil) + return c.request("PUT", fmt.Sprintf("/api/folders/%s", uid), nil, data, nil) } func ForceDeleteFolderRules() url.Values { diff --git a/folder_permissions.go b/folder_permissions.go index fb74dee0..ea266350 100644 --- a/folder_permissions.go +++ b/folder_permissions.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -61,5 +60,5 @@ func (c *Client) UpdateFolderPermissions(fid string, items *PermissionItems) err return err } - return c.request("POST", path, nil, bytes.NewBuffer(data), nil) + return c.request("POST", path, nil, data, nil) } diff --git a/library_panel.go b/library_panel.go index 21cf2af6..80a4f21d 100644 --- a/library_panel.go +++ b/library_panel.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "time" @@ -78,7 +77,7 @@ func (c *Client) NewLibraryPanel(panel LibraryPanel) (*LibraryPanel, error) { } resp := &LibraryPanelCreateResponse{} - err = c.request("POST", "/api/library-elements", nil, bytes.NewBuffer(data), &resp) + err = c.request("POST", "/api/library-elements", nil, data, &resp) if err != nil { return nil, err } @@ -151,7 +150,7 @@ func (c *Client) PatchLibraryPanel(uid string, panel LibraryPanel) (*LibraryPane } resp := &LibraryPanelCreateResponse{} - err = c.request("PATCH", path, nil, bytes.NewBuffer(data), &resp) + err = c.request("PATCH", path, nil, data, &resp) if err != nil { return nil, err } @@ -164,7 +163,7 @@ func (c *Client) DeleteLibraryPanel(uid string) (*LibraryPanelDeleteResponse, er path := fmt.Sprintf("/api/library-elements/%s", uid) resp := &LibraryPanelDeleteResponse{} - err := c.request("DELETE", path, nil, bytes.NewBuffer(nil), &resp) + err := c.request("DELETE", path, nil, nil, &resp) if err != nil { return nil, err } @@ -180,7 +179,7 @@ func (c *Client) LibraryPanelConnections(uid string) (*[]LibraryPanelConnection, Result []LibraryPanelConnection `json:"result"` }{} - err := c.request("GET", path, nil, bytes.NewBuffer(nil), &resp) + err := c.request("GET", path, nil, nil, &resp) if err != nil { return nil, err } diff --git a/org_preferences.go b/org_preferences.go index 5dcad872..d7210036 100644 --- a/org_preferences.go +++ b/org_preferences.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" ) @@ -26,7 +25,7 @@ func (c *Client) UpdateOrgPreferences(p Preferences) (UpdateOrgPreferencesRespon return resp, err } - err = c.request("PATCH", "/api/org/preferences", nil, bytes.NewBuffer(data), &resp) + err = c.request("PATCH", "/api/org/preferences", nil, data, &resp) if err != nil { return resp, err } @@ -42,7 +41,7 @@ func (c *Client) UpdateAllOrgPreferences(p Preferences) (UpdateOrgPreferencesRes return resp, err } - err = c.request("PUT", "/api/org/preferences", nil, bytes.NewBuffer(data), &resp) + err = c.request("PUT", "/api/org/preferences", nil, data, &resp) if err != nil { return resp, err } diff --git a/org_users.go b/org_users.go index 026e5d4a..98b17a3f 100644 --- a/org_users.go +++ b/org_users.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -48,7 +47,7 @@ func (c *Client) AddOrgUser(orgID int64, user, role string) error { return err } - return c.request("POST", fmt.Sprintf("/api/orgs/%d/users", orgID), nil, bytes.NewBuffer(data), nil) + return c.request("POST", fmt.Sprintf("/api/orgs/%d/users", orgID), nil, data, nil) } // UpdateOrgUser updates and org user. @@ -61,7 +60,7 @@ func (c *Client) UpdateOrgUser(orgID, userID int64, role string) error { return err } - return c.request("PATCH", fmt.Sprintf("/api/orgs/%d/users/%d", orgID, userID), nil, bytes.NewBuffer(data), nil) + return c.request("PATCH", fmt.Sprintf("/api/orgs/%d/users/%d", orgID, userID), nil, data, nil) } // RemoveOrgUser removes a user from an org. diff --git a/orgs.go b/orgs.go index 510af1f8..59553665 100644 --- a/orgs.go +++ b/orgs.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -60,7 +59,7 @@ func (c *Client) NewOrg(name string) (int64, error) { ID int64 `json:"orgId"` }{} - err = c.request("POST", "/api/orgs", nil, bytes.NewBuffer(data), &tmp) + err = c.request("POST", "/api/orgs", nil, data, &tmp) if err != nil { return id, err } @@ -78,7 +77,7 @@ func (c *Client) UpdateOrg(id int64, name string) error { return err } - return c.request("PUT", fmt.Sprintf("/api/orgs/%d", id), nil, bytes.NewBuffer(data), nil) + return c.request("PUT", fmt.Sprintf("/api/orgs/%d", id), nil, data, nil) } // DeleteOrg deletes the Grafana org whose ID it's passed. diff --git a/playlist.go b/playlist.go index 077b157b..f37682c0 100644 --- a/playlist.go +++ b/playlist.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -53,7 +52,7 @@ func (c *Client) NewPlaylist(playlist Playlist) (string, error) { var result Playlist - err = c.request("POST", "/api/playlists", nil, bytes.NewBuffer(data), &result) + err = c.request("POST", "/api/playlists", nil, data, &result) if err != nil { return "", err } @@ -69,7 +68,7 @@ func (c *Client) UpdatePlaylist(playlist Playlist) error { return err } - return c.request("PUT", path, nil, bytes.NewBuffer(data), nil) + return c.request("PUT", path, nil, data, nil) } // DeletePlaylist deletes the Grafana playlist whose ID it's passed. diff --git a/report.go b/report.go index a793a687..36775bb5 100644 --- a/report.go +++ b/report.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "time" @@ -90,7 +89,7 @@ func (c *Client) NewReport(report Report) (int64, error) { ID int64 }{} - err = c.request("POST", "/api/reports", nil, bytes.NewBuffer(data), &result) + err = c.request("POST", "/api/reports", nil, data, &result) if err != nil { return 0, err } @@ -106,7 +105,7 @@ func (c *Client) UpdateReport(report Report) error { return err } - return c.request("PUT", path, nil, bytes.NewBuffer(data), nil) + return c.request("PUT", path, nil, data, nil) } // DeleteReport deletes the Grafana report whose ID it's passed. diff --git a/role.go b/role.go index 06a4b21a..53236007 100644 --- a/role.go +++ b/role.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -42,7 +41,7 @@ func (c *Client) NewRole(role Role) (*Role, error) { r := &Role{} - err = c.request("POST", "/api/access-control/roles", nil, bytes.NewBuffer(data), &r) + err = c.request("POST", "/api/access-control/roles", nil, data, &r) if err != nil { return nil, err } @@ -57,7 +56,7 @@ func (c *Client) UpdateRole(role Role) error { return err } - err = c.request("PUT", buildURL(role.UID), nil, bytes.NewBuffer(data), nil) + err = c.request("PUT", buildURL(role.UID), nil, data, nil) return err } diff --git a/role_assignments.go b/role_assignments.go index e3fc59d6..100ba5da 100644 --- a/role_assignments.go +++ b/role_assignments.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "net/http" @@ -33,7 +32,7 @@ func (c *Client) UpdateRoleAssignments(ra *RoleAssignments) (*RoleAssignments, e } url := fmt.Sprintf("/api/access-control/roles/%s/assignments", ra.RoleUID) - err = c.request(http.MethodPut, url, nil, bytes.NewBuffer(data), &response) + err = c.request(http.MethodPut, url, nil, data, &response) if err != nil { return nil, err } diff --git a/service_account.go b/service_account.go index 9991d4ba..0fe6737b 100644 --- a/service_account.go +++ b/service_account.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "net/http" @@ -81,7 +80,7 @@ func (c *Client) CreateServiceAccount(request CreateServiceAccountRequest) (*Ser return nil, err } - err = c.request(http.MethodPost, "/api/serviceaccounts/", nil, bytes.NewBuffer(data), &response) + err = c.request(http.MethodPost, "/api/serviceaccounts/", nil, data, &response) return &response, err } @@ -96,7 +95,7 @@ func (c *Client) CreateServiceAccountToken(request CreateServiceAccountTokenRequ err = c.request(http.MethodPost, fmt.Sprintf("/api/serviceaccounts/%d/tokens", request.ServiceAccountID), - nil, bytes.NewBuffer(data), &response) + nil, data, &response) return &response, err } @@ -111,7 +110,7 @@ func (c *Client) UpdateServiceAccount(serviceAccountID int64, request UpdateServ err = c.request(http.MethodPatch, fmt.Sprintf("/api/serviceaccounts/%d", serviceAccountID), - nil, bytes.NewBuffer(data), &response) + nil, data, &response) return &response, err } diff --git a/service_account_permissions.go b/service_account_permissions.go index 2c69e71e..d877fb3a 100644 --- a/service_account_permissions.go +++ b/service_account_permissions.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -46,5 +45,5 @@ func (c *Client) UpdateServiceAccountPermissions(id int64, items *ServiceAccount return err } - return c.request("POST", path, nil, bytes.NewBuffer(data), nil) + return c.request("POST", path, nil, data, nil) } diff --git a/slo.go b/slo.go index 1ee4f03d..ae04b20a 100644 --- a/slo.go +++ b/slo.go @@ -2,7 +2,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -147,7 +146,7 @@ func (c *Client) CreateSlo(slo Slo) (CreateSLOResponse, error) { return response, err } - if err := c.request("POST", sloPath, nil, bytes.NewBuffer(data), &response); err != nil { + if err := c.request("POST", sloPath, nil, data, &response); err != nil { return CreateSLOResponse{}, err } @@ -169,7 +168,7 @@ func (c *Client) UpdateSlo(uuid string, slo Slo) error { return err } - if err := c.request("PUT", path, nil, bytes.NewBuffer(data), nil); err != nil { + if err := c.request("PUT", path, nil, data, nil); err != nil { return err } diff --git a/snapshot.go b/snapshot.go index 8cea9a5c..1219c798 100644 --- a/snapshot.go +++ b/snapshot.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" ) @@ -28,7 +27,7 @@ func (c *Client) NewSnapshot(snapshot Snapshot) (*SnapshotCreateResponse, error) } result := &SnapshotCreateResponse{} - err = c.request("POST", "/api/snapshots", nil, bytes.NewBuffer(data), &result) + err = c.request("POST", "/api/snapshots", nil, data, &result) if err != nil { return nil, err } diff --git a/team.go b/team.go index 016c37d8..910bbe58 100644 --- a/team.go +++ b/team.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "net/url" @@ -90,7 +89,7 @@ func (c *Client) AddTeam(name string, email string) (int64, error) { ID int64 `json:"teamId"` }{} - err = c.request("POST", path, nil, bytes.NewBuffer(data), &tmp) + err = c.request("POST", path, nil, data, &tmp) if err != nil { return id, err } @@ -113,7 +112,7 @@ func (c *Client) UpdateTeam(id int64, name string, email string) error { return err } - return c.request("PUT", path, nil, bytes.NewBuffer(data), nil) + return c.request("PUT", path, nil, data, nil) } // DeleteTeam deletes the Grafana team whose ID it's passed. @@ -141,7 +140,7 @@ func (c *Client) AddTeamMember(id int64, userID int64) error { return err } - return c.request("POST", path, nil, bytes.NewBuffer(data), nil) + return c.request("POST", path, nil, data, nil) } // RemoveMemberFromTeam removes a user from the Grafana team whose ID it's passed. @@ -170,5 +169,5 @@ func (c *Client) UpdateTeamPreferences(id int64, preferences Preferences) error return err } - return c.request("PUT", path, nil, bytes.NewBuffer(data), nil) + return c.request("PUT", path, nil, data, nil) } diff --git a/team_external_group.go b/team_external_group.go index a2564492..5ec055ab 100644 --- a/team_external_group.go +++ b/team_external_group.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" ) @@ -34,7 +33,7 @@ func (c *Client) NewTeamGroup(id int64, groupID string) error { return err } - return c.request("POST", fmt.Sprintf("/api/teams/%d/groups", id), nil, bytes.NewBuffer(data), nil) + return c.request("POST", fmt.Sprintf("/api/teams/%d/groups", id), nil, data, nil) } // DeleteTeam deletes the Grafana team whose ID it's passed. diff --git a/user.go b/user.go index aeade329..16486c23 100644 --- a/user.go +++ b/user.go @@ -1,7 +1,6 @@ package gapi import ( - "bytes" "encoding/json" "fmt" "net/url" @@ -83,5 +82,5 @@ func (c *Client) UserUpdate(u User) error { if err != nil { return err } - return c.request("PUT", fmt.Sprintf("/api/users/%d", u.ID), nil, bytes.NewBuffer(data), nil) + return c.request("PUT", fmt.Sprintf("/api/users/%d", u.ID), nil, data, nil) }