From 4d9aeb6785bdef456212a34711a52db9027005d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20L=C3=B3pez=20=28inkel=29?= Date: Thu, 11 May 2023 16:13:05 -0300 Subject: [PATCH 1/8] Add regression test for retries with empty body MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Leandro López (inkel) --- client_test.go | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/client_test.go b/client_test.go index b7552597..e2352d44 100644 --- a/client_test.go +++ b/client_test.go @@ -3,6 +3,10 @@ package gapi import ( "bytes" "encoding/json" + "errors" + "io" + "net/http" + "net/http/httptest" "net/url" "testing" ) @@ -173,3 +177,92 @@ func TestRequest_200UnmarshalPut(t *testing.T) { t.Errorf("expected: name; got: %s", result.Name) } } + +func TestClient_requestWithRetries(t *testing.T) { + // It looks like if the call to c.client.Do doesn't read the body + // before returning an error, then bodyBuffer never gets populated + // and every retry ends up with a blank body. + + 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 := io.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"}`)) + } + })) + 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, + }) + 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, bytes.NewReader(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 { + rt http.RoundTripper + 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) +} From 3e5bd17e2c5fde8da7dd6f10f8c1f80bebb170a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20L=C3=B3pez=20=28inkel=29?= Date: Thu, 11 May 2023 16:19:43 -0300 Subject: [PATCH 2/8] Read request body on first try MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even if successful by always reading the body we can make certain that the body will be sent to the server, even if the request fails before reading the body. See parent commit for further reference. Signed-off-by: Leandro López (inkel) --- client.go | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/client.go b/client.go index 2f43100f..7ecc3999 100644 --- a/client.go +++ b/client.go @@ -71,7 +71,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, bodyRd io.Reader, responseStruct interface{}) error { var ( req *http.Request resp *http.Response @@ -79,20 +79,14 @@ 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) + body, err := io.ReadAll(bodyRd) + if err != nil { + return fmt.Errorf("cannot read request body: %w", err) } // 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 } From 7967b4bcf995bbb3696331c728b3843caf493c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20L=C3=B3pez=20=28inkel=29?= Date: Thu, 11 May 2023 16:27:03 -0300 Subject: [PATCH 3/8] Add RetryTimeout to configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Leandro López (inkel) --- client.go | 7 ++++++- client_test.go | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/client.go b/client.go index 7ecc3999..703a2ab3 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. @@ -93,7 +95,10 @@ func (c *Client) request(method, requestPath string, query url.Values, bodyRd io // 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 e2352d44..b9a3a7d4 100644 --- a/client_test.go +++ b/client_test.go @@ -9,6 +9,7 @@ import ( "net/http/httptest" "net/url" "testing" + "time" ) func TestNew_basicAuth(t *testing.T) { @@ -228,8 +229,9 @@ func TestClient_requestWithRetries(t *testing.T) { } c, err := New(ts.URL, Config{ - NumRetries: 5, - Client: httpClient, + NumRetries: 5, + Client: httpClient, + RetryTimeout: 50 * time.Millisecond, }) if err != nil { t.Fatalf("unexpected error creating client: %v", err) From 35980b7de247b22db3cbfc19828458c668e7d3e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20L=C3=B3pez=20=28inkel=29?= Date: Thu, 11 May 2023 16:47:31 -0300 Subject: [PATCH 4/8] Fix linters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Leandro López (inkel) --- client_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client_test.go b/client_test.go index b9a3a7d4..6331d6c0 100644 --- a/client_test.go +++ b/client_test.go @@ -211,7 +211,7 @@ func TestClient_requestWithRetries(t *testing.T) { http.Error(w, `{"error":"calm down"}`, http.StatusTooManyRequests) default: - w.Write([]byte(`{"foo":"bar"}`)) + w.Write([]byte(`{"foo":"bar"}`)) //nolint:errcheck } })) defer ts.Close() @@ -257,7 +257,6 @@ func TestClient_requestWithRetries(t *testing.T) { } type customRoundTripper struct { - rt http.RoundTripper try int } From 0945c55dd3067029a9ee2126d08643ab0dca251e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20L=C3=B3pez=20=28inkel=29?= Date: Thu, 11 May 2023 16:47:40 -0300 Subject: [PATCH 5/8] Pass slice of bytes instead of io.Reader in Client.request MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Leandro López (inkel) --- admin.go | 9 ++++----- alert.go | 3 +-- alerting_alert_rule.go | 7 +++---- alerting_contact_point.go | 5 ++--- alerting_message_template.go | 3 +-- alerting_mute_timing.go | 5 ++--- alerting_notification_policy.go | 3 +-- alertnotification.go | 5 ++--- annotation.go | 13 ++++++------- api_key.go | 3 +-- api_key_test.go | 2 +- builtin_role_assignments.go | 5 ++--- client.go | 7 +------ client_test.go | 4 ++-- cloud_access_policy.go | 5 ++--- cloud_access_policy_token.go | 5 ++--- cloud_api_key.go | 3 +-- cloud_grafana_api_key.go | 3 +-- cloud_grafana_service_account.go | 5 ++--- cloud_plugin.go | 3 +-- cloud_stack.go | 5 ++--- dashboard.go | 5 ++--- dashboard_permissions.go | 5 ++--- datasource.go | 7 +++---- datasource_permissions.go | 3 +-- folder.go | 5 ++--- folder_permissions.go | 3 +-- library_panel.go | 9 ++++----- org_preferences.go | 5 ++--- org_users.go | 5 ++--- orgs.go | 5 ++--- playlist.go | 5 ++--- report.go | 5 ++--- role.go | 5 ++--- role_assignments.go | 3 +-- service_account.go | 7 +++---- service_account_permissions.go | 3 +-- service_account_test.go | 2 +- slo.go | 5 ++--- snapshot.go | 3 +-- team.go | 9 ++++----- team_external_group.go | 3 +-- user.go | 3 +-- 43 files changed, 82 insertions(+), 126 deletions(-) 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/api_key_test.go b/api_key_test.go index def55c15..46131c80 100644 --- a/api_key_test.go +++ b/api_key_test.go @@ -22,7 +22,7 @@ const ( "role": "Admin", "expiration": "2021-10-30T10:52:03+03:00" } - ]` //#nosec + ]` //#nosec ) func TestCreateAPIKey(t *testing.T) { 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 703a2ab3..e3f5aed3 100644 --- a/client.go +++ b/client.go @@ -73,7 +73,7 @@ func (c Client) WithOrgID(orgID int64) *Client { return &c } -func (c *Client) request(method, requestPath string, query url.Values, bodyRd 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 @@ -81,11 +81,6 @@ func (c *Client) request(method, requestPath string, query url.Values, bodyRd io bodyContents []byte ) - body, err := io.ReadAll(bodyRd) - if err != nil { - return fmt.Errorf("cannot read request body: %w", err) - } - // retry logic for n := 0; n <= c.config.NumRetries; n++ { req, err = c.newRequest(method, requestPath, query, bytes.NewReader(body)) diff --git a/client_test.go b/client_test.go index 6331d6c0..7b18189e 100644 --- a/client_test.go +++ b/client_test.go @@ -169,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) } @@ -243,7 +243,7 @@ func TestClient_requestWithRetries(t *testing.T) { var got res - if err := c.request(http.MethodPost, "/", nil, bytes.NewReader(body), &got); err != nil { + if err := c.request(http.MethodPost, "/", nil, body, &got); err != nil { t.Fatalf("unexpected error sending request: %v", err) } 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/service_account_test.go b/service_account_test.go index 4f8ab287..9819fc7a 100644 --- a/service_account_test.go +++ b/service_account_test.go @@ -74,7 +74,7 @@ const ( "secondsUntilExpiration": 0, "hasExpired": false } - ]` //#nosec + ]` //#nosec ) func TestCreateServiceAccountToken(t *testing.T) { 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) } From 0dc1db5355c057c15866cec1df978bcf1004e329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20L=C3=B3pez=20=28inkel=29?= Date: Fri, 12 May 2023 09:53:12 -0300 Subject: [PATCH 6/8] Use ioutil.ReadAll instead of io.ReadAll MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are declaring Go 1.14 for this library, so the new io.ReadAll function doesn't exist (yet). Signed-off-by: Leandro López (inkel) --- client_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client_test.go b/client_test.go index 7b18189e..a9b53a22 100644 --- a/client_test.go +++ b/client_test.go @@ -4,7 +4,7 @@ import ( "bytes" "encoding/json" "errors" - "io" + "io/ioutil" "net/http" "net/http/httptest" "net/url" @@ -194,7 +194,7 @@ func TestClient_requestWithRetries(t *testing.T) { try++ - got, err := io.ReadAll(r.Body) + got, err := ioutil.ReadAll(r.Body) if err != nil { t.Errorf("retry %d: unexpected error reading body: %v", try, err) } From 271195b25174b4e80f94179e55d4fb24d64e6fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20L=C3=B3pez=20=28inkel=29?= Date: Fri, 12 May 2023 10:48:05 -0300 Subject: [PATCH 7/8] Make golangci-lint happy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Never versions of golangci-lint will complain about this and we'll need to revert this commit. Signed-off-by: Leandro López (inkel) --- api_key_test.go | 2 +- service_account_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api_key_test.go b/api_key_test.go index 46131c80..def55c15 100644 --- a/api_key_test.go +++ b/api_key_test.go @@ -22,7 +22,7 @@ const ( "role": "Admin", "expiration": "2021-10-30T10:52:03+03:00" } - ]` //#nosec + ]` //#nosec ) func TestCreateAPIKey(t *testing.T) { diff --git a/service_account_test.go b/service_account_test.go index 9819fc7a..4f8ab287 100644 --- a/service_account_test.go +++ b/service_account_test.go @@ -74,7 +74,7 @@ const ( "secondsUntilExpiration": 0, "hasExpired": false } - ]` //#nosec + ]` //#nosec ) func TestCreateServiceAccountToken(t *testing.T) { From 09a55c8013b15bfafa28647b5acb5dc8501acc75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20L=C3=B3pez?= Date: Fri, 12 May 2023 15:09:33 +0100 Subject: [PATCH 8/8] Update test comment Co-authored-by: Julien Duchesne --- client_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client_test.go b/client_test.go index a9b53a22..47d2dee3 100644 --- a/client_test.go +++ b/client_test.go @@ -180,9 +180,8 @@ func TestRequest_200UnmarshalPut(t *testing.T) { } func TestClient_requestWithRetries(t *testing.T) { - // It looks like if the call to c.client.Do doesn't read the body - // before returning an error, then bodyBuffer never gets populated - // and every retry ends up with a blank body. + // Test that calls to c.client.Do will retry correctly, + // even if the original request fails prematurely body := []byte(`lorem ipsum dolor sit amet`)