From ff5abf1294e04837d25e2c9a0acbc8e50b773972 Mon Sep 17 00:00:00 2001 From: Mihaela Balutoiu Date: Wed, 19 Jul 2023 20:11:11 +0300 Subject: [PATCH] Implement API client functionality in the `garm-cli` Signed-off-by: Mihaela Balutoiu --- cmd/garm-cli/client/client.go | 301 ----- cmd/garm-cli/client/enterprises.go | 179 --- cmd/garm-cli/client/organizations.go | 196 --- cmd/garm-cli/client/repositories.go | 179 --- cmd/garm-cli/cmd/credentials.go | 6 +- cmd/garm-cli/cmd/enterprise.go | 32 +- cmd/garm-cli/cmd/init.go | 19 +- cmd/garm-cli/cmd/jobs.go | 6 +- cmd/garm-cli/cmd/metrics.go | 6 +- cmd/garm-cli/cmd/organization.go | 32 +- cmd/garm-cli/cmd/pool.go | 66 +- cmd/garm-cli/cmd/profile.go | 19 +- cmd/garm-cli/cmd/provider.go | 6 +- cmd/garm-cli/cmd/repository.go | 33 +- cmd/garm-cli/cmd/root.go | 34 +- cmd/garm-cli/cmd/runner.go | 43 +- go.mod | 1 - go.sum | 3 - .../github.com/go-resty/resty/v2/.gitignore | 30 - .../github.com/go-resty/resty/v2/BUILD.bazel | 48 - vendor/github.com/go-resty/resty/v2/LICENSE | 21 - vendor/github.com/go-resty/resty/v2/README.md | 906 -------------- vendor/github.com/go-resty/resty/v2/WORKSPACE | 31 - vendor/github.com/go-resty/resty/v2/client.go | 1115 ----------------- .../go-resty/resty/v2/middleware.go | 543 -------- .../github.com/go-resty/resty/v2/redirect.go | 101 -- .../github.com/go-resty/resty/v2/request.go | 896 ------------- .../github.com/go-resty/resty/v2/response.go | 175 --- vendor/github.com/go-resty/resty/v2/resty.go | 40 - vendor/github.com/go-resty/resty/v2/retry.go | 221 ---- vendor/github.com/go-resty/resty/v2/trace.go | 130 -- .../github.com/go-resty/resty/v2/transport.go | 35 - .../go-resty/resty/v2/transport112.go | 34 - vendor/github.com/go-resty/resty/v2/util.go | 391 ------ vendor/modules.txt | 3 - 35 files changed, 220 insertions(+), 5661 deletions(-) delete mode 100644 cmd/garm-cli/client/client.go delete mode 100644 cmd/garm-cli/client/enterprises.go delete mode 100644 cmd/garm-cli/client/organizations.go delete mode 100644 cmd/garm-cli/client/repositories.go delete mode 100644 vendor/github.com/go-resty/resty/v2/.gitignore delete mode 100644 vendor/github.com/go-resty/resty/v2/BUILD.bazel delete mode 100644 vendor/github.com/go-resty/resty/v2/LICENSE delete mode 100644 vendor/github.com/go-resty/resty/v2/README.md delete mode 100644 vendor/github.com/go-resty/resty/v2/WORKSPACE delete mode 100644 vendor/github.com/go-resty/resty/v2/client.go delete mode 100644 vendor/github.com/go-resty/resty/v2/middleware.go delete mode 100644 vendor/github.com/go-resty/resty/v2/redirect.go delete mode 100644 vendor/github.com/go-resty/resty/v2/request.go delete mode 100644 vendor/github.com/go-resty/resty/v2/response.go delete mode 100644 vendor/github.com/go-resty/resty/v2/resty.go delete mode 100644 vendor/github.com/go-resty/resty/v2/retry.go delete mode 100644 vendor/github.com/go-resty/resty/v2/trace.go delete mode 100644 vendor/github.com/go-resty/resty/v2/transport.go delete mode 100644 vendor/github.com/go-resty/resty/v2/transport112.go delete mode 100644 vendor/github.com/go-resty/resty/v2/util.go diff --git a/cmd/garm-cli/client/client.go b/cmd/garm-cli/client/client.go deleted file mode 100644 index d9e07c3c..00000000 --- a/cmd/garm-cli/client/client.go +++ /dev/null @@ -1,301 +0,0 @@ -// Copyright 2022 Cloudbase Solutions SRL -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package client - -import ( - "encoding/json" - "fmt" - - apiParams "github.com/cloudbase/garm/apiserver/params" - "github.com/cloudbase/garm/cmd/garm-cli/config" - "github.com/cloudbase/garm/params" - - "github.com/go-resty/resty/v2" - "github.com/pkg/errors" -) - -func NewClient(name string, cfg config.Manager, debug bool) *Client { - cli := resty.New() - if cfg.Token != "" { - cli = cli.SetAuthToken(cfg.Token) - } - cli = cli. - SetHeader("Accept", "application/json"). - SetDebug(debug) - return &Client{ - ManagerName: name, - Config: cfg, - client: cli, - } -} - -type Client struct { - ManagerName string - Config config.Manager - client *resty.Client -} - -func (c *Client) handleError(err error, resp *resty.Response) error { - var ret error - if err != nil { - ret = fmt.Errorf("request returned error: %s", err) - } - - if resp != nil && resp.IsError() { - body := resp.Body() - if len(body) > 0 { - apiErr, decErr := c.decodeAPIError(resp.Body()) - if decErr == nil { - ret = fmt.Errorf("API returned error: %s", apiErr.Details) - } - } - } - return ret -} - -func (c *Client) decodeAPIError(body []byte) (apiParams.APIErrorResponse, error) { - var errDetails apiParams.APIErrorResponse - if err := json.Unmarshal(body, &errDetails); err != nil { - return apiParams.APIErrorResponse{}, fmt.Errorf("invalid response from server, use --debug for more info") - } - - return errDetails, fmt.Errorf("error in API call: %s", errDetails.Details) -} - -func (c *Client) InitManager(url string, param params.NewUserParams) (params.User, error) { - body, err := json.Marshal(param) - if err != nil { - return params.User{}, errors.Wrap(err, "marshaling body") - } - url = fmt.Sprintf("%s/api/v1/first-run/", url) - - var response params.User - resp, err := c.client.R(). - SetBody(body). - SetResult(&response). - Post(url) - if err != nil || resp.IsError() { - apiErr, decErr := c.decodeAPIError(resp.Body()) - if decErr != nil { - return params.User{}, errors.Wrap(decErr, "sending request") - } - return params.User{}, fmt.Errorf("error running init: %s", apiErr.Details) - } - - return response, nil -} - -func (c *Client) Login(url string, param params.PasswordLoginParams) (string, error) { - body, err := json.Marshal(param) - if err != nil { - return "", errors.Wrap(err, "marshaling body") - } - url = fmt.Sprintf("%s/api/v1/auth/login", url) - - var response params.JWTResponse - resp, err := c.client.R(). - SetBody(body). - SetResult(&response). - Post(url) - if err != nil || resp.IsError() { - apiErr, decErr := c.decodeAPIError(resp.Body()) - if decErr != nil { - return "", errors.Wrap(decErr, "sending request") - } - return "", fmt.Errorf("error performing login: %s", apiErr.Details) - } - - return response.Token, nil -} - -func (c *Client) ListCredentials() ([]params.GithubCredentials, error) { - var ghCreds []params.GithubCredentials - url := fmt.Sprintf("%s/api/v1/credentials", c.Config.BaseURL) - resp, err := c.client.R(). - SetResult(&ghCreds). - Get(url) - if err != nil || resp.IsError() { - apiErr, decErr := c.decodeAPIError(resp.Body()) - if decErr != nil { - return nil, errors.Wrap(decErr, "sending request") - } - return nil, fmt.Errorf("error fetching credentials: %s", apiErr.Details) - } - return ghCreds, nil -} - -func (c *Client) ListProviders() ([]params.Provider, error) { - var providers []params.Provider - url := fmt.Sprintf("%s/api/v1/providers", c.Config.BaseURL) - resp, err := c.client.R(). - SetResult(&providers). - Get(url) - if err != nil || resp.IsError() { - apiErr, decErr := c.decodeAPIError(resp.Body()) - if decErr != nil { - return nil, errors.Wrap(decErr, "sending request") - } - return nil, fmt.Errorf("error fetching providers: %s", apiErr.Details) - } - return providers, nil -} - -func (c *Client) GetInstanceByName(instanceName string) (params.Instance, error) { - url := fmt.Sprintf("%s/api/v1/instances/%s", c.Config.BaseURL, instanceName) - - var response params.Instance - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err != nil || resp.IsError() { - apiErr, decErr := c.decodeAPIError(resp.Body()) - if decErr != nil { - return response, errors.Wrap(decErr, "sending request") - } - return response, fmt.Errorf("error performing login: %s", apiErr.Details) - } - return response, nil -} - -func (c *Client) DeleteRunner(instanceName string) error { - url := fmt.Sprintf("%s/api/v1/instances/%s", c.Config.BaseURL, instanceName) - resp, err := c.client.R(). - Delete(url) - if err != nil || resp.IsError() { - apiErr, decErr := c.decodeAPIError(resp.Body()) - if decErr != nil { - return errors.Wrap(decErr, "sending request") - } - return fmt.Errorf("error deleting runner: %s", apiErr.Details) - } - return nil -} - -func (c *Client) ListAllJobs() ([]params.Job, error) { - url := fmt.Sprintf("%s/api/v1/jobs", c.Config.BaseURL) - - var response []params.Job - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err != nil || resp.IsError() { - return response, c.handleError(err, resp) - } - return response, nil -} - -func (c *Client) ListPoolInstances(poolID string) ([]params.Instance, error) { - url := fmt.Sprintf("%s/api/v1/pools/%s/instances", c.Config.BaseURL, poolID) - - var response []params.Instance - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err != nil || resp.IsError() { - apiErr, decErr := c.decodeAPIError(resp.Body()) - if decErr != nil { - return response, errors.Wrap(decErr, "sending request") - } - return response, fmt.Errorf("error performing login: %s", apiErr.Details) - } - return response, nil -} - -func (c *Client) ListAllInstances() ([]params.Instance, error) { - url := fmt.Sprintf("%s/api/v1/instances", c.Config.BaseURL) - - var response []params.Instance - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err != nil || resp.IsError() { - apiErr, decErr := c.decodeAPIError(resp.Body()) - if decErr != nil { - return response, errors.Wrap(decErr, "sending request") - } - return response, fmt.Errorf("error performing login: %s", apiErr.Details) - } - return response, nil -} - -func (c *Client) GetPoolByID(poolID string) (params.Pool, error) { - url := fmt.Sprintf("%s/api/v1/pools/%s", c.Config.BaseURL, poolID) - - var response params.Pool - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err != nil || resp.IsError() { - apiErr, decErr := c.decodeAPIError(resp.Body()) - if decErr != nil { - return response, errors.Wrap(decErr, "sending request") - } - return response, fmt.Errorf("error performing login: %s", apiErr.Details) - } - return response, nil -} - -func (c *Client) ListAllPools() ([]params.Pool, error) { - url := fmt.Sprintf("%s/api/v1/pools", c.Config.BaseURL) - - var response []params.Pool - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err != nil || resp.IsError() { - apiErr, decErr := c.decodeAPIError(resp.Body()) - if decErr != nil { - return response, errors.Wrap(decErr, "sending request") - } - return response, fmt.Errorf("error performing login: %s", apiErr.Details) - } - return response, nil -} - -func (c *Client) DeletePoolByID(poolID string) error { - url := fmt.Sprintf("%s/api/v1/pools/%s", c.Config.BaseURL, poolID) - resp, err := c.client.R(). - Delete(url) - if err != nil || resp.IsError() { - apiErr, decErr := c.decodeAPIError(resp.Body()) - if decErr != nil { - return errors.Wrap(decErr, "sending request") - } - return fmt.Errorf("error deleting pool by ID: %s", apiErr.Details) - } - return nil -} - -func (c *Client) UpdatePoolByID(poolID string, param params.UpdatePoolParams) (params.Pool, error) { - url := fmt.Sprintf("%s/api/v1/pools/%s", c.Config.BaseURL, poolID) - - var response params.Pool - body, err := json.Marshal(param) - if err != nil { - return response, err - } - resp, err := c.client.R(). - SetBody(body). - SetResult(&response). - Put(url) - if err != nil || resp.IsError() { - apiErr, decErr := c.decodeAPIError(resp.Body()) - if decErr != nil { - return response, errors.Wrap(decErr, "sending request") - } - return response, fmt.Errorf("error performing login: %s", apiErr.Details) - } - return response, nil -} diff --git a/cmd/garm-cli/client/enterprises.go b/cmd/garm-cli/client/enterprises.go deleted file mode 100644 index ddb26445..00000000 --- a/cmd/garm-cli/client/enterprises.go +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2022 Cloudbase Solutions SRL -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package client - -import ( - "encoding/json" - "fmt" - - "github.com/cloudbase/garm/params" -) - -func (c *Client) ListEnterprises() ([]params.Enterprise, error) { - var enterprises []params.Enterprise - url := fmt.Sprintf("%s/api/v1/enterprises", c.Config.BaseURL) - resp, err := c.client.R(). - SetResult(&enterprises). - Get(url) - if err := c.handleError(err, resp); err != nil { - return nil, err - } - return enterprises, nil -} - -func (c *Client) CreateEnterprise(param params.CreateEnterpriseParams) (params.Enterprise, error) { - var response params.Enterprise - url := fmt.Sprintf("%s/api/v1/enterprises", c.Config.BaseURL) - - body, err := json.Marshal(param) - if err != nil { - return params.Enterprise{}, err - } - resp, err := c.client.R(). - SetBody(body). - SetResult(&response). - Post(url) - if err := c.handleError(err, resp); err != nil { - return params.Enterprise{}, err - } - return response, nil -} - -func (c *Client) UpdateEnterprise(enterpriseID string, param params.UpdateEntityParams) (params.Enterprise, error) { - url := fmt.Sprintf("%s/api/v1/enterprises/%s", c.Config.BaseURL, enterpriseID) - - var response params.Enterprise - body, err := json.Marshal(param) - if err != nil { - return response, err - } - resp, err := c.client.R(). - SetBody(body). - SetResult(&response). - Put(url) - if err := c.handleError(err, resp); err != nil { - return params.Enterprise{}, err - } - return response, nil -} - -func (c *Client) GetEnterprise(enterpriseID string) (params.Enterprise, error) { - var response params.Enterprise - url := fmt.Sprintf("%s/api/v1/enterprises/%s", c.Config.BaseURL, enterpriseID) - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err := c.handleError(err, resp); err != nil { - return params.Enterprise{}, err - } - return response, nil -} - -func (c *Client) DeleteEnterprise(enterpriseID string) error { - url := fmt.Sprintf("%s/api/v1/enterprises/%s", c.Config.BaseURL, enterpriseID) - resp, err := c.client.R(). - Delete(url) - if err := c.handleError(err, resp); err != nil { - return err - } - return nil -} - -func (c *Client) CreateEnterprisePool(enterpriseID string, param params.CreatePoolParams) (params.Pool, error) { - url := fmt.Sprintf("%s/api/v1/enterprises/%s/pools", c.Config.BaseURL, enterpriseID) - - var response params.Pool - body, err := json.Marshal(param) - if err != nil { - return response, err - } - resp, err := c.client.R(). - SetBody(body). - SetResult(&response). - Post(url) - if err := c.handleError(err, resp); err != nil { - return params.Pool{}, err - } - return response, nil -} - -func (c *Client) ListEnterprisePools(enterpriseID string) ([]params.Pool, error) { - url := fmt.Sprintf("%s/api/v1/enterprises/%s/pools", c.Config.BaseURL, enterpriseID) - - var response []params.Pool - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err := c.handleError(err, resp); err != nil { - return nil, err - } - return response, nil -} - -func (c *Client) GetEnterprisePool(enterpriseID, poolID string) (params.Pool, error) { - url := fmt.Sprintf("%s/api/v1/enterprises/%s/pools/%s", c.Config.BaseURL, enterpriseID, poolID) - - var response params.Pool - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err := c.handleError(err, resp); err != nil { - return params.Pool{}, err - } - return response, nil -} - -func (c *Client) DeleteEnterprisePool(enterpriseID, poolID string) error { - url := fmt.Sprintf("%s/api/v1/enterprises/%s/pools/%s", c.Config.BaseURL, enterpriseID, poolID) - - resp, err := c.client.R(). - Delete(url) - - if err := c.handleError(err, resp); err != nil { - return err - } - return nil -} - -func (c *Client) UpdateEnterprisePool(enterpriseID, poolID string, param params.UpdatePoolParams) (params.Pool, error) { - url := fmt.Sprintf("%s/api/v1/enterprises/%s/pools/%s", c.Config.BaseURL, enterpriseID, poolID) - - var response params.Pool - body, err := json.Marshal(param) - if err != nil { - return response, err - } - resp, err := c.client.R(). - SetBody(body). - SetResult(&response). - Put(url) - if err := c.handleError(err, resp); err != nil { - return params.Pool{}, err - } - return response, nil -} - -func (c *Client) ListEnterpriseInstances(enterpriseID string) ([]params.Instance, error) { - url := fmt.Sprintf("%s/api/v1/enterprises/%s/instances", c.Config.BaseURL, enterpriseID) - - var response []params.Instance - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err := c.handleError(err, resp); err != nil { - return nil, err - } - return response, nil -} diff --git a/cmd/garm-cli/client/organizations.go b/cmd/garm-cli/client/organizations.go deleted file mode 100644 index 59411455..00000000 --- a/cmd/garm-cli/client/organizations.go +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2022 Cloudbase Solutions SRL -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package client - -import ( - "encoding/json" - "fmt" - - "github.com/cloudbase/garm/params" -) - -func (c *Client) ListOrganizations() ([]params.Organization, error) { - var orgs []params.Organization - url := fmt.Sprintf("%s/api/v1/organizations", c.Config.BaseURL) - resp, err := c.client.R(). - SetResult(&orgs). - Get(url) - if err := c.handleError(err, resp); err != nil { - return nil, err - } - return orgs, nil -} - -func (c *Client) CreateOrganization(param params.CreateOrgParams) (params.Organization, error) { - var response params.Organization - url := fmt.Sprintf("%s/api/v1/organizations", c.Config.BaseURL) - - body, err := json.Marshal(param) - if err != nil { - return params.Organization{}, err - } - resp, err := c.client.R(). - SetBody(body). - SetResult(&response). - Post(url) - if err := c.handleError(err, resp); err != nil { - return params.Organization{}, err - } - return response, nil -} - -func (c *Client) UpdateOrganization(orgID string, param params.UpdateEntityParams) (params.Organization, error) { - url := fmt.Sprintf("%s/api/v1/organizations/%s", c.Config.BaseURL, orgID) - - var response params.Organization - body, err := json.Marshal(param) - if err != nil { - return response, err - } - resp, err := c.client.R(). - SetBody(body). - SetResult(&response). - Put(url) - if err := c.handleError(err, resp); err != nil { - return params.Organization{}, err - } - return response, nil -} - -func (c *Client) GetOrganization(orgID string) (params.Organization, error) { - var response params.Organization - url := fmt.Sprintf("%s/api/v1/organizations/%s", c.Config.BaseURL, orgID) - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err := c.handleError(err, resp); err != nil { - return params.Organization{}, err - } - return response, nil -} - -func (c *Client) DeleteOrganization(orgID string) error { - url := fmt.Sprintf("%s/api/v1/organizations/%s", c.Config.BaseURL, orgID) - resp, err := c.client.R(). - Delete(url) - if err := c.handleError(err, resp); err != nil { - return err - } - return nil -} - -func (c *Client) CreateOrgPool(orgID string, param params.CreatePoolParams) (params.Pool, error) { - url := fmt.Sprintf("%s/api/v1/organizations/%s/pools", c.Config.BaseURL, orgID) - - var response params.Pool - body, err := json.Marshal(param) - if err != nil { - return response, err - } - resp, err := c.client.R(). - SetBody(body). - SetResult(&response). - Post(url) - if err := c.handleError(err, resp); err != nil { - return params.Pool{}, err - } - return response, nil -} - -func (c *Client) ListOrgPools(orgID string) ([]params.Pool, error) { - url := fmt.Sprintf("%s/api/v1/organizations/%s/pools", c.Config.BaseURL, orgID) - - var response []params.Pool - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err := c.handleError(err, resp); err != nil { - return nil, err - } - return response, nil -} - -func (c *Client) GetOrgPool(orgID, poolID string) (params.Pool, error) { - url := fmt.Sprintf("%s/api/v1/organizations/%s/pools/%s", c.Config.BaseURL, orgID, poolID) - - var response params.Pool - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err := c.handleError(err, resp); err != nil { - return params.Pool{}, err - } - return response, nil -} - -func (c *Client) DeleteOrgPool(orgID, poolID string) error { - url := fmt.Sprintf("%s/api/v1/organizations/%s/pools/%s", c.Config.BaseURL, orgID, poolID) - - resp, err := c.client.R(). - Delete(url) - - if err := c.handleError(err, resp); err != nil { - return err - } - return nil -} - -func (c *Client) UpdateOrgPool(orgID, poolID string, param params.UpdatePoolParams) (params.Pool, error) { - url := fmt.Sprintf("%s/api/v1/organizations/%s/pools/%s", c.Config.BaseURL, orgID, poolID) - - var response params.Pool - body, err := json.Marshal(param) - if err != nil { - return response, err - } - resp, err := c.client.R(). - SetBody(body). - SetResult(&response). - Put(url) - if err := c.handleError(err, resp); err != nil { - return params.Pool{}, err - } - return response, nil -} - -func (c *Client) ListOrgInstances(orgID string) ([]params.Instance, error) { - url := fmt.Sprintf("%s/api/v1/organizations/%s/instances", c.Config.BaseURL, orgID) - - var response []params.Instance - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err := c.handleError(err, resp); err != nil { - return nil, err - } - return response, nil -} - -func (c *Client) CreateMetricsToken() (string, error) { - url := fmt.Sprintf("%s/api/v1/metrics-token", c.Config.BaseURL) - - type response struct { - Token string `json:"token"` - } - - var t response - resp, err := c.client.R(). - SetResult(&t). - Get(url) - if err := c.handleError(err, resp); err != nil { - return "", err - } - return t.Token, nil -} diff --git a/cmd/garm-cli/client/repositories.go b/cmd/garm-cli/client/repositories.go deleted file mode 100644 index 744e7f81..00000000 --- a/cmd/garm-cli/client/repositories.go +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2022 Cloudbase Solutions SRL -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package client - -import ( - "encoding/json" - "fmt" - - "github.com/cloudbase/garm/params" -) - -func (c *Client) ListRepositories() ([]params.Repository, error) { - var repos []params.Repository - url := fmt.Sprintf("%s/api/v1/repositories", c.Config.BaseURL) - resp, err := c.client.R(). - SetResult(&repos). - Get(url) - if err := c.handleError(err, resp); err != nil { - return nil, err - } - return repos, nil -} - -func (c *Client) CreateRepository(param params.CreateRepoParams) (params.Repository, error) { - var response params.Repository - url := fmt.Sprintf("%s/api/v1/repositories", c.Config.BaseURL) - - body, err := json.Marshal(param) - if err != nil { - return params.Repository{}, err - } - resp, err := c.client.R(). - SetBody(body). - SetResult(&response). - Post(url) - if err := c.handleError(err, resp); err != nil { - return params.Repository{}, err - } - return response, nil -} - -func (c *Client) GetRepository(repoID string) (params.Repository, error) { - var response params.Repository - url := fmt.Sprintf("%s/api/v1/repositories/%s", c.Config.BaseURL, repoID) - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err := c.handleError(err, resp); err != nil { - return params.Repository{}, err - } - return response, nil -} - -func (c *Client) DeleteRepository(repoID string) error { - url := fmt.Sprintf("%s/api/v1/repositories/%s", c.Config.BaseURL, repoID) - resp, err := c.client.R(). - Delete(url) - if err := c.handleError(err, resp); err != nil { - return err - } - return nil -} - -func (c *Client) CreateRepoPool(repoID string, param params.CreatePoolParams) (params.Pool, error) { - url := fmt.Sprintf("%s/api/v1/repositories/%s/pools", c.Config.BaseURL, repoID) - - var response params.Pool - body, err := json.Marshal(param) - if err != nil { - return response, err - } - resp, err := c.client.R(). - SetBody(body). - SetResult(&response). - Post(url) - if err := c.handleError(err, resp); err != nil { - return params.Pool{}, err - } - return response, nil -} - -func (c *Client) ListRepoPools(repoID string) ([]params.Pool, error) { - url := fmt.Sprintf("%s/api/v1/repositories/%s/pools", c.Config.BaseURL, repoID) - - var response []params.Pool - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err := c.handleError(err, resp); err != nil { - return nil, err - } - return response, nil -} - -func (c *Client) GetRepoPool(repoID, poolID string) (params.Pool, error) { - url := fmt.Sprintf("%s/api/v1/repositories/%s/pools/%s", c.Config.BaseURL, repoID, poolID) - - var response params.Pool - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err := c.handleError(err, resp); err != nil { - return params.Pool{}, err - } - return response, nil -} - -func (c *Client) DeleteRepoPool(repoID, poolID string) error { - url := fmt.Sprintf("%s/api/v1/repositories/%s/pools/%s", c.Config.BaseURL, repoID, poolID) - - resp, err := c.client.R(). - Delete(url) - - if err := c.handleError(err, resp); err != nil { - return err - } - return nil -} - -func (c *Client) UpdateRepoPool(repoID, poolID string, param params.UpdatePoolParams) (params.Pool, error) { - url := fmt.Sprintf("%s/api/v1/repositories/%s/pools/%s", c.Config.BaseURL, repoID, poolID) - - var response params.Pool - body, err := json.Marshal(param) - if err != nil { - return response, err - } - resp, err := c.client.R(). - SetBody(body). - SetResult(&response). - Put(url) - if err := c.handleError(err, resp); err != nil { - return params.Pool{}, err - } - return response, nil -} - -func (c *Client) UpdateRepo(repoID string, param params.UpdateEntityParams) (params.Repository, error) { - url := fmt.Sprintf("%s/api/v1/repositories/%s", c.Config.BaseURL, repoID) - - var response params.Repository - body, err := json.Marshal(param) - if err != nil { - return response, err - } - resp, err := c.client.R(). - SetBody(body). - SetResult(&response). - Put(url) - if err := c.handleError(err, resp); err != nil { - return params.Repository{}, err - } - return response, nil -} - -func (c *Client) ListRepoInstances(repoID string) ([]params.Instance, error) { - url := fmt.Sprintf("%s/api/v1/repositories/%s/instances", c.Config.BaseURL, repoID) - - var response []params.Instance - resp, err := c.client.R(). - SetResult(&response). - Get(url) - if err := c.handleError(err, resp); err != nil { - return nil, err - } - return response, nil -} diff --git a/cmd/garm-cli/cmd/credentials.go b/cmd/garm-cli/cmd/credentials.go index 6559eeb6..ec73c95f 100644 --- a/cmd/garm-cli/cmd/credentials.go +++ b/cmd/garm-cli/cmd/credentials.go @@ -17,6 +17,7 @@ package cmd import ( "fmt" + apiClientCreds "github.com/cloudbase/garm/client/credentials" "github.com/cloudbase/garm/params" "github.com/jedib0t/go-pretty/v6/table" @@ -50,11 +51,12 @@ func init() { return errNeedsInitError } - creds, err := cli.ListCredentials() + listCredsReq := apiClientCreds.NewListCredentialsParams() + response, err := apiCli.Credentials.ListCredentials(listCredsReq, authToken) if err != nil { return err } - formatGithubCredentials(creds) + formatGithubCredentials(response.Payload) return nil }, }) diff --git a/cmd/garm-cli/cmd/enterprise.go b/cmd/garm-cli/cmd/enterprise.go index a16ee66d..c63e0c44 100644 --- a/cmd/garm-cli/cmd/enterprise.go +++ b/cmd/garm-cli/cmd/enterprise.go @@ -17,6 +17,7 @@ package cmd import ( "fmt" + apiClientEnterprises "github.com/cloudbase/garm/client/enterprises" "github.com/cloudbase/garm/params" "github.com/jedib0t/go-pretty/v6/table" @@ -54,16 +55,17 @@ var enterpriseAddCmd = &cobra.Command{ return errNeedsInitError } - newEnterpriseReq := params.CreateEnterpriseParams{ + newEnterpriseReq := apiClientEnterprises.NewCreateEnterpriseParams() + newEnterpriseReq.Body = params.CreateEnterpriseParams{ Name: enterpriseName, WebhookSecret: enterpriseWebhookSecret, CredentialsName: enterpriseCreds, } - enterprise, err := cli.CreateEnterprise(newEnterpriseReq) + response, err := apiCli.Enterprises.CreateEnterprise(newEnterpriseReq, authToken) if err != nil { return err } - formatOneEnterprise(enterprise) + formatOneEnterprise(response.Payload) return nil }, } @@ -79,11 +81,12 @@ var enterpriseListCmd = &cobra.Command{ return errNeedsInitError } - enterprises, err := cli.ListEnterprises() + listEnterprisesReq := apiClientEnterprises.NewListEnterprisesParams() + response, err := apiCli.Enterprises.ListEnterprises(listEnterprisesReq, authToken) if err != nil { return err } - formatEnterprises(enterprises) + formatEnterprises(response.Payload) return nil }, } @@ -103,11 +106,13 @@ var enterpriseShowCmd = &cobra.Command{ if len(args) > 1 { return fmt.Errorf("too many arguments") } - enterprise, err := cli.GetEnterprise(args[0]) + showEnterpriseReq := apiClientEnterprises.NewGetEnterpriseParams() + showEnterpriseReq.EnterpriseID = args[0] + response, err := apiCli.Enterprises.GetEnterprise(showEnterpriseReq, authToken) if err != nil { return err } - formatOneEnterprise(enterprise) + formatOneEnterprise(response.Payload) return nil }, } @@ -128,7 +133,9 @@ var enterpriseDeleteCmd = &cobra.Command{ if len(args) > 1 { return fmt.Errorf("too many arguments") } - if err := cli.DeleteEnterprise(args[0]); err != nil { + deleteEnterpriseReq := apiClientEnterprises.NewDeleteEnterpriseParams() + deleteEnterpriseReq.EnterpriseID = args[0] + if err := apiCli.Enterprises.DeleteEnterprise(deleteEnterpriseReq, authToken); err != nil { return err } return nil @@ -152,16 +159,17 @@ var enterpriseUpdateCmd = &cobra.Command{ if len(args) > 1 { return fmt.Errorf("too many arguments") } - - enterpriseUpdateReq := params.UpdateEntityParams{ + updateEnterpriseReq := apiClientEnterprises.NewUpdateEnterpriseParams() + updateEnterpriseReq.Body = params.UpdateEntityParams{ WebhookSecret: repoWebhookSecret, CredentialsName: repoCreds, } - enterprise, err := cli.UpdateEnterprise(args[0], enterpriseUpdateReq) + updateEnterpriseReq.EnterpriseID = args[0] + response, err := apiCli.Enterprises.UpdateEnterprise(updateEnterpriseReq, authToken) if err != nil { return err } - formatOneEnterprise(enterprise) + formatOneEnterprise(response.Payload) return nil }, } diff --git a/cmd/garm-cli/cmd/init.go b/cmd/garm-cli/cmd/init.go index 3c879c3f..b85c5a8f 100644 --- a/cmd/garm-cli/cmd/init.go +++ b/cmd/garm-cli/cmd/init.go @@ -22,6 +22,8 @@ import ( "github.com/cloudbase/garm/cmd/garm-cli/config" "github.com/cloudbase/garm/params" + apiClientFirstRun "github.com/cloudbase/garm/client/first_run" + apiClientLogin "github.com/cloudbase/garm/client/login" "github.com/jedib0t/go-pretty/v6/table" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -54,7 +56,8 @@ garm-cli init --name=dev --url=https://runner.example.com --username=admin --pas return err } - newUser := params.NewUserParams{ + newUserReq := apiClientFirstRun.NewFirstRunParams() + newUserReq.Body = params.NewUserParams{ Username: loginUserName, Password: loginPassword, FullName: loginFullName, @@ -62,17 +65,21 @@ garm-cli init --name=dev --url=https://runner.example.com --username=admin --pas } url := strings.TrimSuffix(loginURL, "/") - response, err := cli.InitManager(url, newUser) + + initApiClient(url, "") + + response, err := apiCli.FirstRun.FirstRun(newUserReq, authToken) if err != nil { return errors.Wrap(err, "initializing manager") } - loginParams := params.PasswordLoginParams{ + newLoginParamsReq := apiClientLogin.NewLoginParams() + newLoginParamsReq.Body = params.PasswordLoginParams{ Username: loginUserName, Password: loginPassword, } - token, err := cli.Login(url, loginParams) + token, err := apiCli.Login.Login(newLoginParamsReq, authToken) if err != nil { return errors.Wrap(err, "authenticating") } @@ -80,7 +87,7 @@ garm-cli init --name=dev --url=https://runner.example.com --username=admin --pas cfg.Managers = append(cfg.Managers, config.Manager{ Name: loginProfileName, BaseURL: url, - Token: token, + Token: token.Payload.Token, }) cfg.ActiveManager = loginProfileName @@ -89,7 +96,7 @@ garm-cli init --name=dev --url=https://runner.example.com --username=admin --pas return errors.Wrap(err, "saving config") } - renderUserTable(response) + renderUserTable(response.Payload) return nil }, } diff --git a/cmd/garm-cli/cmd/jobs.go b/cmd/garm-cli/cmd/jobs.go index f64d94b6..36f61e8e 100644 --- a/cmd/garm-cli/cmd/jobs.go +++ b/cmd/garm-cli/cmd/jobs.go @@ -18,6 +18,7 @@ import ( "fmt" "strings" + apiClientJobs "github.com/cloudbase/garm/client/jobs" "github.com/cloudbase/garm/params" "github.com/google/uuid" "github.com/jedib0t/go-pretty/v6/table" @@ -44,11 +45,12 @@ var jobsListCmd = &cobra.Command{ return errNeedsInitError } - jobs, err := cli.ListAllJobs() + listJobsReq := apiClientJobs.NewListJobsParams() + response, err := apiCli.Jobs.ListJobs(listJobsReq, authToken) if err != nil { return err } - formatJobs(jobs) + formatJobs(response.Payload) return nil }, } diff --git a/cmd/garm-cli/cmd/metrics.go b/cmd/garm-cli/cmd/metrics.go index 4069e3e6..e79d9456 100644 --- a/cmd/garm-cli/cmd/metrics.go +++ b/cmd/garm-cli/cmd/metrics.go @@ -17,6 +17,7 @@ package cmd import ( "fmt" + apiClientMetricToken "github.com/cloudbase/garm/client/metrics_token" "github.com/spf13/cobra" ) @@ -39,11 +40,12 @@ var metricsTokenCreateCmd = &cobra.Command{ return errNeedsInitError } - token, err := cli.CreateMetricsToken() + showMetricsTokenReq := apiClientMetricToken.NewGetMetricsTokenParams() + response, err := apiCli.MetricsToken.GetMetricsToken(showMetricsTokenReq, authToken) if err != nil { return err } - fmt.Println(token) + fmt.Println(response.Payload.Token) return nil }, diff --git a/cmd/garm-cli/cmd/organization.go b/cmd/garm-cli/cmd/organization.go index 1338d3ae..56de989b 100644 --- a/cmd/garm-cli/cmd/organization.go +++ b/cmd/garm-cli/cmd/organization.go @@ -17,6 +17,7 @@ package cmd import ( "fmt" + apiClientOrgs "github.com/cloudbase/garm/client/organizations" "github.com/cloudbase/garm/params" "github.com/jedib0t/go-pretty/v6/table" @@ -54,16 +55,17 @@ var orgAddCmd = &cobra.Command{ return errNeedsInitError } - newOrgReq := params.CreateOrgParams{ + newOrgReq := apiClientOrgs.NewCreateOrgParams() + newOrgReq.Body = params.CreateOrgParams{ Name: orgName, WebhookSecret: orgWebhookSecret, CredentialsName: orgCreds, } - org, err := cli.CreateOrganization(newOrgReq) + response, err := apiCli.Organizations.CreateOrg(newOrgReq, authToken) if err != nil { return err } - formatOneOrganization(org) + formatOneOrganization(response.Payload) return nil }, } @@ -85,16 +87,17 @@ var orgUpdateCmd = &cobra.Command{ if len(args) > 1 { return fmt.Errorf("too many arguments") } - - orgUpdateReq := params.UpdateEntityParams{ + updateOrgReq := apiClientOrgs.NewUpdateOrgParams() + updateOrgReq.Body = params.UpdateEntityParams{ WebhookSecret: repoWebhookSecret, CredentialsName: orgCreds, } - org, err := cli.UpdateOrganization(args[0], orgUpdateReq) + updateOrgReq.OrgID = args[0] + response, err := apiCli.Organizations.UpdateOrg(updateOrgReq, authToken) if err != nil { return err } - formatOneOrganization(org) + formatOneOrganization(response.Payload) return nil }, } @@ -110,11 +113,12 @@ var orgListCmd = &cobra.Command{ return errNeedsInitError } - orgs, err := cli.ListOrganizations() + listOrgsReq := apiClientOrgs.NewListOrgsParams() + response, err := apiCli.Organizations.ListOrgs(listOrgsReq, authToken) if err != nil { return err } - formatOrganizations(orgs) + formatOrganizations(response.Payload) return nil }, } @@ -134,11 +138,13 @@ var orgShowCmd = &cobra.Command{ if len(args) > 1 { return fmt.Errorf("too many arguments") } - org, err := cli.GetOrganization(args[0]) + showOrgReq := apiClientOrgs.NewGetOrgParams() + showOrgReq.OrgID = args[0] + response, err := apiCli.Organizations.GetOrg(showOrgReq, authToken) if err != nil { return err } - formatOneOrganization(org) + formatOneOrganization(response.Payload) return nil }, } @@ -159,7 +165,9 @@ var orgDeleteCmd = &cobra.Command{ if len(args) > 1 { return fmt.Errorf("too many arguments") } - if err := cli.DeleteOrganization(args[0]); err != nil { + deleteOrgReq := apiClientOrgs.NewDeleteOrgParams() + deleteOrgReq.OrgID = args[0] + if err := apiCli.Organizations.DeleteOrg(deleteOrgReq, authToken); err != nil { return err } return nil diff --git a/cmd/garm-cli/cmd/pool.go b/cmd/garm-cli/cmd/pool.go index 829566b8..024a58b7 100644 --- a/cmd/garm-cli/cmd/pool.go +++ b/cmd/garm-cli/cmd/pool.go @@ -20,6 +20,11 @@ import ( "os" "strings" + apiClientEnterprises "github.com/cloudbase/garm/client/enterprises" + apiClientOrgs "github.com/cloudbase/garm/client/organizations" + apiClientPools "github.com/cloudbase/garm/client/pools" + apiClientRepos "github.com/cloudbase/garm/client/repositories" + "github.com/cloudbase/garm/params" "github.com/jedib0t/go-pretty/v6/table" @@ -96,13 +101,28 @@ Example: switch len(args) { case 0: if cmd.Flags().Changed("repo") { - pools, err = cli.ListRepoPools(poolRepository) + var response *apiClientRepos.ListRepoPoolsOK + listRepoPoolsReq := apiClientRepos.NewListRepoPoolsParams() + listRepoPoolsReq.RepoID = poolRepository + response, err = apiCli.Repositories.ListRepoPools(listRepoPoolsReq, authToken) + pools = response.Payload } else if cmd.Flags().Changed("org") { - pools, err = cli.ListOrgPools(poolOrganization) + var response *apiClientOrgs.ListOrgPoolsOK + listOrgPoolsReq := apiClientOrgs.NewListOrgPoolsParams() + listOrgPoolsReq.OrgID = poolOrganization + response, err = apiCli.Organizations.ListOrgPools(listOrgPoolsReq, authToken) + pools = response.Payload } else if cmd.Flags().Changed("enterprise") { - pools, err = cli.ListEnterprisePools(poolEnterprise) + var response *apiClientEnterprises.ListEnterprisePoolsOK + listEnterprisePoolsReq := apiClientEnterprises.NewListEnterprisePoolsParams() + listEnterprisePoolsReq.EnterpriseID = poolEnterprise + response, err = apiCli.Enterprises.ListEnterprisePools(listEnterprisePoolsReq, authToken) + pools = response.Payload } else if cmd.Flags().Changed("all") { - pools, err = cli.ListAllPools() + var response *apiClientPools.ListPoolsOK + listPoolsReq := apiClientPools.NewListPoolsParams() + response, err = apiCli.Pools.ListPools(listPoolsReq, authToken) + pools = response.Payload } else { cmd.Help() //nolint os.Exit(0) @@ -138,11 +158,13 @@ var poolShowCmd = &cobra.Command{ return fmt.Errorf("too many arguments") } - pool, err := cli.GetPoolByID(args[0]) + getPoolReq := apiClientPools.NewGetPoolParams() + getPoolReq.PoolID = args[0] + response, err := apiCli.Pools.GetPool(getPoolReq, authToken) if err != nil { return err } - formatOnePool(pool) + formatOnePool(response.Payload) return nil }, } @@ -166,7 +188,9 @@ var poolDeleteCmd = &cobra.Command{ return fmt.Errorf("too many arguments") } - if err := cli.DeletePoolByID(args[0]); err != nil { + deletePoolReq := apiClientPools.NewDeletePoolParams() + deletePoolReq.PoolID = args[0] + if err := apiCli.Pools.DeletePool(deletePoolReq, authToken); err != nil { return err } return nil @@ -226,11 +250,26 @@ var poolAddCmd = &cobra.Command{ var err error if cmd.Flags().Changed("repo") { - pool, err = cli.CreateRepoPool(poolRepository, newPoolParams) + var response *apiClientRepos.CreateRepoPoolOK + newRepoPoolReq := apiClientRepos.NewCreateRepoPoolParams() + newRepoPoolReq.RepoID = poolRepository + newRepoPoolReq.Body = newPoolParams + response, err = apiCli.Repositories.CreateRepoPool(newRepoPoolReq, authToken) + pool = response.Payload } else if cmd.Flags().Changed("org") { - pool, err = cli.CreateOrgPool(poolOrganization, newPoolParams) + var response *apiClientOrgs.CreateOrgPoolOK + newOrgPoolReq := apiClientOrgs.NewCreateOrgPoolParams() + newOrgPoolReq.OrgID = poolOrganization + newOrgPoolReq.Body = newPoolParams + response, err = apiCli.Organizations.CreateOrgPool(newOrgPoolReq, authToken) + pool = response.Payload } else if cmd.Flags().Changed("enterprise") { - pool, err = cli.CreateEnterprisePool(poolEnterprise, newPoolParams) + var response *apiClientEnterprises.CreateEnterprisePoolOK + newEnterprisePoolReq := apiClientEnterprises.NewCreateEnterprisePoolParams() + newEnterprisePoolReq.EnterpriseID = poolEnterprise + newEnterprisePoolReq.Body = newPoolParams + response, err = apiCli.Enterprises.CreateEnterprisePool(newEnterprisePoolReq, authToken) + pool = response.Payload } else { cmd.Help() //nolint os.Exit(0) @@ -267,6 +306,7 @@ explicitly remove them using the runner delete command. return fmt.Errorf("too many arguments") } + updatePoolReq := apiClientPools.NewUpdatePoolParams() poolUpdateParams := params.UpdatePoolParams{} if cmd.Flags().Changed("image") { @@ -331,12 +371,14 @@ explicitly remove them using the runner delete command. poolUpdateParams.ExtraSpecs = data } - pool, err := cli.UpdatePoolByID(args[0], poolUpdateParams) + updatePoolReq.PoolID = args[0] + updatePoolReq.Body = poolUpdateParams + response, err := apiCli.Pools.UpdatePool(updatePoolReq, authToken) if err != nil { return err } - formatOnePool(pool) + formatOnePool(response.Payload) return nil }, } diff --git a/cmd/garm-cli/cmd/profile.go b/cmd/garm-cli/cmd/profile.go index 29c74323..71843df8 100644 --- a/cmd/garm-cli/cmd/profile.go +++ b/cmd/garm-cli/cmd/profile.go @@ -18,6 +18,7 @@ import ( "fmt" "strings" + apiClientLogin "github.com/cloudbase/garm/client/login" "github.com/cloudbase/garm/cmd/garm-cli/common" "github.com/cloudbase/garm/cmd/garm-cli/config" "github.com/cloudbase/garm/params" @@ -143,12 +144,15 @@ var profileAddCmd = &cobra.Command{ } url := strings.TrimSuffix(loginURL, "/") - loginParams := params.PasswordLoginParams{ + + initApiClient(url, "") + + newLoginParamsReq := apiClientLogin.NewLoginParams() + newLoginParamsReq.Body = params.PasswordLoginParams{ Username: loginUserName, Password: loginPassword, } - - resp, err := cli.Login(url, loginParams) + resp, err := apiCli.Login.Login(newLoginParamsReq, authToken) if err != nil { return err } @@ -156,7 +160,7 @@ var profileAddCmd = &cobra.Command{ cfg.Managers = append(cfg.Managers, config.Manager{ Name: loginProfileName, BaseURL: url, - Token: resp, + Token: resp.Payload.Token, }) cfg.ActiveManager = loginProfileName @@ -190,16 +194,17 @@ installation, by performing a login. return err } - loginParams := params.PasswordLoginParams{ + newLoginParamsReq := apiClientLogin.NewLoginParams() + newLoginParamsReq.Body = params.PasswordLoginParams{ Username: loginUserName, Password: loginPassword, } - resp, err := cli.Login(mgr.BaseURL, loginParams) + resp, err := apiCli.Login.Login(newLoginParamsReq, authToken) if err != nil { return err } - if err := cfg.SetManagerToken(mgr.Name, resp); err != nil { + if err := cfg.SetManagerToken(mgr.Name, resp.Payload.Token); err != nil { return fmt.Errorf("error saving new token: %s", err) } diff --git a/cmd/garm-cli/cmd/provider.go b/cmd/garm-cli/cmd/provider.go index 40840abf..e9635dd0 100644 --- a/cmd/garm-cli/cmd/provider.go +++ b/cmd/garm-cli/cmd/provider.go @@ -17,6 +17,7 @@ package cmd import ( "fmt" + apiClientProviders "github.com/cloudbase/garm/client/providers" "github.com/cloudbase/garm/params" "github.com/jedib0t/go-pretty/v6/table" @@ -49,11 +50,12 @@ func init() { return errNeedsInitError } - providers, err := cli.ListProviders() + listProvidersReq := apiClientProviders.NewListProvidersParams() + response, err := apiCli.Providers.ListProviders(listProvidersReq, authToken) if err != nil { return err } - formatProviders(providers) + formatProviders(response.Payload) return nil }, }) diff --git a/cmd/garm-cli/cmd/repository.go b/cmd/garm-cli/cmd/repository.go index 49b86a0a..8466b318 100644 --- a/cmd/garm-cli/cmd/repository.go +++ b/cmd/garm-cli/cmd/repository.go @@ -17,6 +17,7 @@ package cmd import ( "fmt" + apiClientRepos "github.com/cloudbase/garm/client/repositories" "github.com/cloudbase/garm/params" "github.com/jedib0t/go-pretty/v6/table" @@ -55,17 +56,18 @@ var repoAddCmd = &cobra.Command{ return errNeedsInitError } - newRepoReq := params.CreateRepoParams{ + newRepoReq := apiClientRepos.NewCreateRepoParams() + newRepoReq.Body = params.CreateRepoParams{ Owner: repoOwner, Name: repoName, WebhookSecret: repoWebhookSecret, CredentialsName: repoCreds, } - repo, err := cli.CreateRepository(newRepoReq) + response, err := apiCli.Repositories.CreateRepo(newRepoReq, authToken) if err != nil { return err } - formatOneRepository(repo) + formatOneRepository(response.Payload) return nil }, } @@ -81,11 +83,12 @@ var repoListCmd = &cobra.Command{ return errNeedsInitError } - repos, err := cli.ListRepositories() + listReposReq := apiClientRepos.NewListReposParams() + response, err := apiCli.Repositories.ListRepos(listReposReq, authToken) if err != nil { return err } - formatRepositories(repos) + formatRepositories(response.Payload) return nil }, } @@ -107,16 +110,18 @@ var repoUpdateCmd = &cobra.Command{ if len(args) > 1 { return fmt.Errorf("too many arguments") } - - repoUpdateReq := params.UpdateEntityParams{ + updateReposReq := apiClientRepos.NewUpdateRepoParams() + updateReposReq.Body = params.UpdateEntityParams{ WebhookSecret: repoWebhookSecret, CredentialsName: repoCreds, } - repo, err := cli.UpdateRepo(args[0], repoUpdateReq) + updateReposReq.RepoID = args[0] + + response, err := apiCli.Repositories.UpdateRepo(updateReposReq, authToken) if err != nil { return err } - formatOneRepository(repo) + formatOneRepository(response.Payload) return nil }, } @@ -136,11 +141,13 @@ var repoShowCmd = &cobra.Command{ if len(args) > 1 { return fmt.Errorf("too many arguments") } - repo, err := cli.GetRepository(args[0]) + showRepoReq := apiClientRepos.NewGetRepoParams() + showRepoReq.RepoID = args[0] + response, err := apiCli.Repositories.GetRepo(showRepoReq, authToken) if err != nil { return err } - formatOneRepository(repo) + formatOneRepository(response.Payload) return nil }, } @@ -161,7 +168,9 @@ var repoDeleteCmd = &cobra.Command{ if len(args) > 1 { return fmt.Errorf("too many arguments") } - if err := cli.DeleteRepository(args[0]); err != nil { + deleteRepoReq := apiClientRepos.NewDeleteRepoParams() + deleteRepoReq.RepoID = args[0] + if err := apiCli.Repositories.DeleteRepo(deleteRepoReq, authToken); err != nil { return err } return nil diff --git a/cmd/garm-cli/cmd/root.go b/cmd/garm-cli/cmd/root.go index 716b8038..c491e263 100644 --- a/cmd/garm-cli/cmd/root.go +++ b/cmd/garm-cli/cmd/root.go @@ -16,11 +16,14 @@ package cmd import ( "fmt" + "net/url" "os" - "github.com/cloudbase/garm/cmd/garm-cli/client" + apiClient "github.com/cloudbase/garm/client" "github.com/cloudbase/garm/cmd/garm-cli/config" + "github.com/go-openapi/runtime" + openapiRuntimeClient "github.com/go-openapi/runtime/client" "github.com/spf13/cobra" ) @@ -29,8 +32,8 @@ var Version string var ( cfg *config.Config mgr config.Manager - cli *client.Client - active string + apiCli *apiClient.GarmAPI + authToken runtime.ClientAuthInfoWriter needsInit bool debug bool errNeedsInitError = fmt.Errorf("please log into a garm installation first") @@ -55,6 +58,28 @@ func Execute() { } } +func initApiClient(baseUrl, token string) { + baseUrlParsed, err := url.Parse(baseUrl) + if err != nil { + fmt.Printf("Failed to parse base url %s: %s", baseUrl, err) + os.Exit(1) + } + apiPath, err := url.JoinPath(baseUrlParsed.Path, apiClient.DefaultBasePath) + if err != nil { + fmt.Printf("Failed to join base url path %s with %s: %s", baseUrlParsed.Path, apiClient.DefaultBasePath, err) + os.Exit(1) + } + if debug { + os.Setenv("SWAGGER_DEBUG", "true") + } + transportCfg := apiClient.DefaultTransportConfig(). + WithHost(baseUrlParsed.Host). + WithBasePath(apiPath). + WithSchemes([]string{baseUrlParsed.Scheme}) + apiCli = apiClient.NewHTTPClientWithConfig(nil, transportCfg) + authToken = openapiRuntimeClient.BearerToken(token) +} + func initConfig() { var err error cfg, err = config.LoadConfig() @@ -70,7 +95,6 @@ func initConfig() { if err != nil { mgr = cfg.Managers[0] } - active = mgr.Name } - cli = client.NewClient(active, mgr, debug) + initApiClient(mgr.BaseURL, mgr.Token) } diff --git a/cmd/garm-cli/cmd/runner.go b/cmd/garm-cli/cmd/runner.go index ea17ea26..b4cfbcfe 100644 --- a/cmd/garm-cli/cmd/runner.go +++ b/cmd/garm-cli/cmd/runner.go @@ -20,6 +20,10 @@ import ( "github.com/cloudbase/garm/params" + apiClientEnterprises "github.com/cloudbase/garm/client/enterprises" + apiClientInstances "github.com/cloudbase/garm/client/instances" + apiClientOrgs "github.com/cloudbase/garm/client/organizations" + apiClientRepos "github.com/cloudbase/garm/client/repositories" "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" ) @@ -88,16 +92,35 @@ Example: return fmt.Errorf("specifying a pool ID and any of [all org repo enterprise] are mutually exclusive") } - instances, err = cli.ListPoolInstances(args[0]) + var response *apiClientInstances.ListPoolInstancesOK + listPoolInstancesReq := apiClientInstances.NewListPoolInstancesParams() + listPoolInstancesReq.PoolID = args[0] + response, err = apiCli.Instances.ListPoolInstances(listPoolInstancesReq, authToken) + instances = response.Payload case 0: if cmd.Flags().Changed("repo") { - instances, err = cli.ListRepoInstances(runnerRepository) + var response *apiClientRepos.ListRepoInstancesOK + listRepoInstancesReq := apiClientRepos.NewListRepoInstancesParams() + listRepoInstancesReq.RepoID = runnerRepository + response, err = apiCli.Repositories.ListRepoInstances(listRepoInstancesReq, authToken) + instances = response.Payload } else if cmd.Flags().Changed("org") { - instances, err = cli.ListOrgInstances(runnerOrganization) + var response *apiClientOrgs.ListOrgInstancesOK + listOrgInstancesReq := apiClientOrgs.NewListOrgInstancesParams() + listOrgInstancesReq.OrgID = runnerOrganization + response, err = apiCli.Organizations.ListOrgInstances(listOrgInstancesReq, authToken) + instances = response.Payload } else if cmd.Flags().Changed("enterprise") { - instances, err = cli.ListEnterpriseInstances(runnerEnterprise) + var response *apiClientEnterprises.ListEnterpriseInstancesOK + listEnterpriseInstancesReq := apiClientEnterprises.NewListEnterpriseInstancesParams() + listEnterpriseInstancesReq.EnterpriseID = runnerEnterprise + response, err = apiCli.Enterprises.ListEnterpriseInstances(listEnterpriseInstancesReq, authToken) + instances = response.Payload } else if cmd.Flags().Changed("all") { - instances, err = cli.ListAllInstances() + var response *apiClientInstances.ListInstancesOK + listInstancesReq := apiClientInstances.NewListInstancesParams() + response, err = apiCli.Instances.ListInstances(listInstancesReq, authToken) + instances = response.Payload } else { cmd.Help() //nolint os.Exit(0) @@ -133,11 +156,13 @@ var runnerShowCmd = &cobra.Command{ return fmt.Errorf("too many arguments") } - instance, err := cli.GetInstanceByName(args[0]) + showInstanceReq := apiClientInstances.NewGetInstanceParams() + showInstanceReq.InstanceName = args[0] + response, err := apiCli.Instances.GetInstance(showInstanceReq, authToken) if err != nil { return err } - formatSingleInstance(instance) + formatSingleInstance(response.Payload) return nil }, } @@ -170,7 +195,9 @@ to either cancel the workflow or wait for it to finish. return fmt.Errorf("use --force-remove-runner=true to remove a runner") } - if err := cli.DeleteRunner(args[0]); err != nil { + deleteInstanceReq := apiClientInstances.NewDeleteInstanceParams() + deleteInstanceReq.InstanceName = args[0] + if err := apiCli.Instances.DeleteInstance(deleteInstanceReq, authToken); err != nil { return err } return nil diff --git a/go.mod b/go.mod index 99fa50c9..150c2b3b 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,6 @@ require ( github.com/go-openapi/errors v0.20.4 github.com/go-openapi/runtime v0.26.0 github.com/go-openapi/strfmt v0.21.7 - github.com/go-resty/resty/v2 v2.7.0 github.com/golang-jwt/jwt v3.2.2+incompatible github.com/google/go-github/v53 v53.2.0 github.com/google/uuid v1.3.0 diff --git a/go.sum b/go.sum index cfd7aa66..eadba3dd 100644 --- a/go.sum +++ b/go.sum @@ -92,8 +92,6 @@ github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogB github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= -github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= -github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -369,7 +367,6 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= -golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= diff --git a/vendor/github.com/go-resty/resty/v2/.gitignore b/vendor/github.com/go-resty/resty/v2/.gitignore deleted file mode 100644 index 9e856bd4..00000000 --- a/vendor/github.com/go-resty/resty/v2/.gitignore +++ /dev/null @@ -1,30 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof - -coverage.out -coverage.txt - -# Exclude intellij IDE folders -.idea/* diff --git a/vendor/github.com/go-resty/resty/v2/BUILD.bazel b/vendor/github.com/go-resty/resty/v2/BUILD.bazel deleted file mode 100644 index 03bb44c3..00000000 --- a/vendor/github.com/go-resty/resty/v2/BUILD.bazel +++ /dev/null @@ -1,48 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -load("@bazel_gazelle//:def.bzl", "gazelle") - -# gazelle:prefix github.com/go-resty/resty/v2 -# gazelle:go_naming_convention import_alias -gazelle(name = "gazelle") - -go_library( - name = "resty", - srcs = [ - "client.go", - "middleware.go", - "redirect.go", - "request.go", - "response.go", - "resty.go", - "retry.go", - "trace.go", - "transport.go", - "transport112.go", - "util.go", - ], - importpath = "github.com/go-resty/resty/v2", - visibility = ["//visibility:public"], - deps = ["@org_golang_x_net//publicsuffix:go_default_library"], -) - -go_test( - name = "resty_test", - srcs = [ - "client_test.go", - "context_test.go", - "example_test.go", - "request_test.go", - "resty_test.go", - "retry_test.go", - "util_test.go", - ], - data = glob([".testdata/*"]), - embed = [":resty"], - deps = ["@org_golang_x_net//proxy:go_default_library"], -) - -alias( - name = "go_default_library", - actual = ":resty", - visibility = ["//visibility:public"], -) diff --git a/vendor/github.com/go-resty/resty/v2/LICENSE b/vendor/github.com/go-resty/resty/v2/LICENSE deleted file mode 100644 index 27326a65..00000000 --- a/vendor/github.com/go-resty/resty/v2/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015-2021 Jeevanandam M., https://myjeeva.com - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/go-resty/resty/v2/README.md b/vendor/github.com/go-resty/resty/v2/README.md deleted file mode 100644 index 8ec65182..00000000 --- a/vendor/github.com/go-resty/resty/v2/README.md +++ /dev/null @@ -1,906 +0,0 @@ -

-

Resty

-

Simple HTTP and REST client library for Go (inspired by Ruby rest-client)

-

Features section describes in detail about Resty capabilities

-

-

-

Build Status Code Coverage Go Report Card Release Version GoDoc License Mentioned in Awesome Go

-

-

-

Resty Communication Channels

-

Chat on Gitter - Resty Community Twitter @go_resty

-

- -## News - - * v2.7.0 [released](https://github.com/go-resty/resty/releases/tag/v2.7.0) and tagged on Nov 03, 2021. - * v2.0.0 [released](https://github.com/go-resty/resty/releases/tag/v2.0.0) and tagged on Jul 16, 2019. - * v1.12.0 [released](https://github.com/go-resty/resty/releases/tag/v1.12.0) and tagged on Feb 27, 2019. - * v1.0 released and tagged on Sep 25, 2017. - Resty's first version was released on Sep 15, 2015 then it grew gradually as a very handy and helpful library. Its been a two years since first release. I'm very thankful to Resty users and its [contributors](https://github.com/go-resty/resty/graphs/contributors). - -## Features - - * GET, POST, PUT, DELETE, HEAD, PATCH, OPTIONS, etc. - * Simple and chainable methods for settings and request - * [Request](https://pkg.go.dev/github.com/go-resty/resty/v2#Request) Body can be `string`, `[]byte`, `struct`, `map`, `slice` and `io.Reader` too - * Auto detects `Content-Type` - * Buffer less processing for `io.Reader` - * Native `*http.Request` instance may be accessed during middleware and request execution via `Request.RawRequest` - * Request Body can be read multiple times via `Request.RawRequest.GetBody()` - * [Response](https://pkg.go.dev/github.com/go-resty/resty/v2#Response) object gives you more possibility - * Access as `[]byte` array - `response.Body()` OR Access as `string` - `response.String()` - * Know your `response.Time()` and when we `response.ReceivedAt()` - * Automatic marshal and unmarshal for `JSON` and `XML` content type - * Default is `JSON`, if you supply `struct/map` without header `Content-Type` - * For auto-unmarshal, refer to - - - Success scenario [Request.SetResult()](https://pkg.go.dev/github.com/go-resty/resty/v2#Request.SetResult) and [Response.Result()](https://pkg.go.dev/github.com/go-resty/resty/v2#Response.Result). - - Error scenario [Request.SetError()](https://pkg.go.dev/github.com/go-resty/resty/v2#Request.SetError) and [Response.Error()](https://pkg.go.dev/github.com/go-resty/resty/v2#Response.Error). - - Supports [RFC7807](https://tools.ietf.org/html/rfc7807) - `application/problem+json` & `application/problem+xml` - * Resty provides an option to override [JSON Marshal/Unmarshal and XML Marshal/Unmarshal](#override-json--xml-marshalunmarshal) - * Easy to upload one or more file(s) via `multipart/form-data` - * Auto detects file content type - * Request URL [Path Params (aka URI Params)](https://pkg.go.dev/github.com/go-resty/resty/v2#Request.SetPathParams) - * Backoff Retry Mechanism with retry condition function [reference](retry_test.go) - * Resty client HTTP & REST [Request](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.OnBeforeRequest) and [Response](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.OnAfterResponse) middlewares - * `Request.SetContext` supported - * Authorization option of `BasicAuth` and `Bearer` token - * Set request `ContentLength` value for all request or particular request - * Custom [Root Certificates](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.SetRootCertificate) and Client [Certificates](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.SetCertificates) - * Download/Save HTTP response directly into File, like `curl -o` flag. See [SetOutputDirectory](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.SetOutputDirectory) & [SetOutput](https://pkg.go.dev/github.com/go-resty/resty/v2#Request.SetOutput). - * Cookies for your request and CookieJar support - * SRV Record based request instead of Host URL - * Client settings like `Timeout`, `RedirectPolicy`, `Proxy`, `TLSClientConfig`, `Transport`, etc. - * Optionally allows GET request with payload, see [SetAllowGetMethodPayload](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.SetAllowGetMethodPayload) - * Supports registering external JSON library into resty, see [how to use](https://github.com/go-resty/resty/issues/76#issuecomment-314015250) - * Exposes Response reader without reading response (no auto-unmarshaling) if need be, see [how to use](https://github.com/go-resty/resty/issues/87#issuecomment-322100604) - * Option to specify expected `Content-Type` when response `Content-Type` header missing. Refer to [#92](https://github.com/go-resty/resty/issues/92) - * Resty design - * Have client level settings & options and also override at Request level if you want to - * Request and Response middleware - * Create Multiple clients if you want to `resty.New()` - * Supports `http.RoundTripper` implementation, see [SetTransport](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.SetTransport) - * goroutine concurrent safe - * Resty Client trace, see [Client.EnableTrace](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.EnableTrace) and [Request.EnableTrace](https://pkg.go.dev/github.com/go-resty/resty/v2#Request.EnableTrace) - * Since v2.4.0, trace info contains a `RequestAttempt` value, and the `Request` object contains an `Attempt` attribute - * Debug mode - clean and informative logging presentation - * Gzip - Go does it automatically also resty has fallback handling too - * Works fine with `HTTP/2` and `HTTP/1.1` - * [Bazel support](#bazel-support) - * Easily mock Resty for testing, [for e.g.](#mocking-http-requests-using-httpmock-library) - * Well tested client library - -### Included Batteries - - * Redirect Policies - see [how to use](#redirect-policy) - * NoRedirectPolicy - * FlexibleRedirectPolicy - * DomainCheckRedirectPolicy - * etc. [more info](redirect.go) - * Retry Mechanism [how to use](#retries) - * Backoff Retry - * Conditional Retry - * Since v2.6.0, Retry Hooks - [Client](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.AddRetryHook), [Request](https://pkg.go.dev/github.com/go-resty/resty/v2#Request.AddRetryHook) - * SRV Record based request instead of Host URL [how to use](resty_test.go#L1412) - * etc (upcoming - throw your idea's [here](https://github.com/go-resty/resty/issues)). - - -#### Supported Go Versions - -Initially Resty started supporting `go modules` since `v1.10.0` release. - -Starting Resty v2 and higher versions, it fully embraces [go modules](https://github.com/golang/go/wiki/Modules) package release. It requires a Go version capable of understanding `/vN` suffixed imports: - -- 1.9.7+ -- 1.10.3+ -- 1.11+ - - -## It might be beneficial for your project :smile: - -Resty author also published following projects for Go Community. - - * [aah framework](https://aahframework.org) - A secure, flexible, rapid Go web framework. - * [THUMBAI](https://thumbai.app) - Go Mod Repository, Go Vanity Service and Simple Proxy Server. - * [go-model](https://github.com/jeevatkm/go-model) - Robust & Easy to use model mapper and utility methods for Go `struct`. - - -## Installation - -```bash -# Go Modules -require github.com/go-resty/resty/v2 v2.7.0 -``` - -## Usage - -The following samples will assist you to become as comfortable as possible with resty library. - -```go -// Import resty into your code and refer it as `resty`. -import "github.com/go-resty/resty/v2" -``` - -#### Simple GET - -```go -// Create a Resty Client -client := resty.New() - -resp, err := client.R(). - EnableTrace(). - Get("https://httpbin.org/get") - -// Explore response object -fmt.Println("Response Info:") -fmt.Println(" Error :", err) -fmt.Println(" Status Code:", resp.StatusCode()) -fmt.Println(" Status :", resp.Status()) -fmt.Println(" Proto :", resp.Proto()) -fmt.Println(" Time :", resp.Time()) -fmt.Println(" Received At:", resp.ReceivedAt()) -fmt.Println(" Body :\n", resp) -fmt.Println() - -// Explore trace info -fmt.Println("Request Trace Info:") -ti := resp.Request.TraceInfo() -fmt.Println(" DNSLookup :", ti.DNSLookup) -fmt.Println(" ConnTime :", ti.ConnTime) -fmt.Println(" TCPConnTime :", ti.TCPConnTime) -fmt.Println(" TLSHandshake :", ti.TLSHandshake) -fmt.Println(" ServerTime :", ti.ServerTime) -fmt.Println(" ResponseTime :", ti.ResponseTime) -fmt.Println(" TotalTime :", ti.TotalTime) -fmt.Println(" IsConnReused :", ti.IsConnReused) -fmt.Println(" IsConnWasIdle :", ti.IsConnWasIdle) -fmt.Println(" ConnIdleTime :", ti.ConnIdleTime) -fmt.Println(" RequestAttempt:", ti.RequestAttempt) -fmt.Println(" RemoteAddr :", ti.RemoteAddr.String()) - -/* Output -Response Info: - Error : - Status Code: 200 - Status : 200 OK - Proto : HTTP/2.0 - Time : 457.034718ms - Received At: 2020-09-14 15:35:29.784681 -0700 PDT m=+0.458137045 - Body : - { - "args": {}, - "headers": { - "Accept-Encoding": "gzip", - "Host": "httpbin.org", - "User-Agent": "go-resty/2.4.0 (https://github.com/go-resty/resty)", - "X-Amzn-Trace-Id": "Root=1-5f5ff031-000ff6292204aa6898e4de49" - }, - "origin": "0.0.0.0", - "url": "https://httpbin.org/get" - } - -Request Trace Info: - DNSLookup : 4.074657ms - ConnTime : 381.709936ms - TCPConnTime : 77.428048ms - TLSHandshake : 299.623597ms - ServerTime : 75.414703ms - ResponseTime : 79.337µs - TotalTime : 457.034718ms - IsConnReused : false - IsConnWasIdle : false - ConnIdleTime : 0s - RequestAttempt: 1 - RemoteAddr : 3.221.81.55:443 -*/ -``` - -#### Enhanced GET - -```go -// Create a Resty Client -client := resty.New() - -resp, err := client.R(). - SetQueryParams(map[string]string{ - "page_no": "1", - "limit": "20", - "sort":"name", - "order": "asc", - "random":strconv.FormatInt(time.Now().Unix(), 10), - }). - SetHeader("Accept", "application/json"). - SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F"). - Get("/search_result") - - -// Sample of using Request.SetQueryString method -resp, err := client.R(). - SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more"). - SetHeader("Accept", "application/json"). - SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F"). - Get("/show_product") - - -// If necessary, you can force response content type to tell Resty to parse a JSON response into your struct -resp, err := client.R(). - SetResult(result). - ForceContentType("application/json"). - Get("v2/alpine/manifests/latest") -``` - -#### Various POST method combinations - -```go -// Create a Resty Client -client := resty.New() - -// POST JSON string -// No need to set content type, if you have client level setting -resp, err := client.R(). - SetHeader("Content-Type", "application/json"). - SetBody(`{"username":"testuser", "password":"testpass"}`). - SetResult(&AuthSuccess{}). // or SetResult(AuthSuccess{}). - Post("https://myapp.com/login") - -// POST []byte array -// No need to set content type, if you have client level setting -resp, err := client.R(). - SetHeader("Content-Type", "application/json"). - SetBody([]byte(`{"username":"testuser", "password":"testpass"}`)). - SetResult(&AuthSuccess{}). // or SetResult(AuthSuccess{}). - Post("https://myapp.com/login") - -// POST Struct, default is JSON content type. No need to set one -resp, err := client.R(). - SetBody(User{Username: "testuser", Password: "testpass"}). - SetResult(&AuthSuccess{}). // or SetResult(AuthSuccess{}). - SetError(&AuthError{}). // or SetError(AuthError{}). - Post("https://myapp.com/login") - -// POST Map, default is JSON content type. No need to set one -resp, err := client.R(). - SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"}). - SetResult(&AuthSuccess{}). // or SetResult(AuthSuccess{}). - SetError(&AuthError{}). // or SetError(AuthError{}). - Post("https://myapp.com/login") - -// POST of raw bytes for file upload. For example: upload file to Dropbox -fileBytes, _ := ioutil.ReadFile("/Users/jeeva/mydocument.pdf") - -// See we are not setting content-type header, since go-resty automatically detects Content-Type for you -resp, err := client.R(). - SetBody(fileBytes). - SetContentLength(true). // Dropbox expects this value - SetAuthToken(""). - SetError(&DropboxError{}). // or SetError(DropboxError{}). - Post("https://content.dropboxapi.com/1/files_put/auto/resty/mydocument.pdf") // for upload Dropbox supports PUT too - -// Note: resty detects Content-Type for request body/payload if content type header is not set. -// * For struct and map data type defaults to 'application/json' -// * Fallback is plain text content type -``` - -#### Sample PUT - -You can use various combinations of `PUT` method call like demonstrated for `POST`. - -```go -// Note: This is one sample of PUT method usage, refer POST for more combination - -// Create a Resty Client -client := resty.New() - -// Request goes as JSON content type -// No need to set auth token, error, if you have client level settings -resp, err := client.R(). - SetBody(Article{ - Title: "go-resty", - Content: "This is my article content, oh ya!", - Author: "Jeevanandam M", - Tags: []string{"article", "sample", "resty"}, - }). - SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD"). - SetError(&Error{}). // or SetError(Error{}). - Put("https://myapp.com/article/1234") -``` - -#### Sample PATCH - -You can use various combinations of `PATCH` method call like demonstrated for `POST`. - -```go -// Note: This is one sample of PUT method usage, refer POST for more combination - -// Create a Resty Client -client := resty.New() - -// Request goes as JSON content type -// No need to set auth token, error, if you have client level settings -resp, err := client.R(). - SetBody(Article{ - Tags: []string{"new tag1", "new tag2"}, - }). - SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD"). - SetError(&Error{}). // or SetError(Error{}). - Patch("https://myapp.com/articles/1234") -``` - -#### Sample DELETE, HEAD, OPTIONS - -```go -// Create a Resty Client -client := resty.New() - -// DELETE a article -// No need to set auth token, error, if you have client level settings -resp, err := client.R(). - SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD"). - SetError(&Error{}). // or SetError(Error{}). - Delete("https://myapp.com/articles/1234") - -// DELETE a articles with payload/body as a JSON string -// No need to set auth token, error, if you have client level settings -resp, err := client.R(). - SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD"). - SetError(&Error{}). // or SetError(Error{}). - SetHeader("Content-Type", "application/json"). - SetBody(`{article_ids: [1002, 1006, 1007, 87683, 45432] }`). - Delete("https://myapp.com/articles") - -// HEAD of resource -// No need to set auth token, if you have client level settings -resp, err := client.R(). - SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD"). - Head("https://myapp.com/videos/hi-res-video") - -// OPTIONS of resource -// No need to set auth token, if you have client level settings -resp, err := client.R(). - SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD"). - Options("https://myapp.com/servers/nyc-dc-01") -``` - -#### Override JSON & XML Marshal/Unmarshal - -User could register choice of JSON/XML library into resty or write your own. By default resty registers standard `encoding/json` and `encoding/xml` respectively. -```go -// Example of registering json-iterator -import jsoniter "github.com/json-iterator/go" - -json := jsoniter.ConfigCompatibleWithStandardLibrary - -client := resty.New() -client.JSONMarshal = json.Marshal -client.JSONUnmarshal = json.Unmarshal - -// similarly user could do for XML too with - -client.XMLMarshal -client.XMLUnmarshal -``` - -### Multipart File(s) upload - -#### Using io.Reader - -```go -profileImgBytes, _ := ioutil.ReadFile("/Users/jeeva/test-img.png") -notesBytes, _ := ioutil.ReadFile("/Users/jeeva/text-file.txt") - -// Create a Resty Client -client := resty.New() - -resp, err := client.R(). - SetFileReader("profile_img", "test-img.png", bytes.NewReader(profileImgBytes)). - SetFileReader("notes", "text-file.txt", bytes.NewReader(notesBytes)). - SetFormData(map[string]string{ - "first_name": "Jeevanandam", - "last_name": "M", - }). - Post("http://myapp.com/upload") -``` - -#### Using File directly from Path - -```go -// Create a Resty Client -client := resty.New() - -// Single file scenario -resp, err := client.R(). - SetFile("profile_img", "/Users/jeeva/test-img.png"). - Post("http://myapp.com/upload") - -// Multiple files scenario -resp, err := client.R(). - SetFiles(map[string]string{ - "profile_img": "/Users/jeeva/test-img.png", - "notes": "/Users/jeeva/text-file.txt", - }). - Post("http://myapp.com/upload") - -// Multipart of form fields and files -resp, err := client.R(). - SetFiles(map[string]string{ - "profile_img": "/Users/jeeva/test-img.png", - "notes": "/Users/jeeva/text-file.txt", - }). - SetFormData(map[string]string{ - "first_name": "Jeevanandam", - "last_name": "M", - "zip_code": "00001", - "city": "my city", - "access_token": "C6A79608-782F-4ED0-A11D-BD82FAD829CD", - }). - Post("http://myapp.com/profile") -``` - -#### Sample Form submission - -```go -// Create a Resty Client -client := resty.New() - -// just mentioning about POST as an example with simple flow -// User Login -resp, err := client.R(). - SetFormData(map[string]string{ - "username": "jeeva", - "password": "mypass", - }). - Post("http://myapp.com/login") - -// Followed by profile update -resp, err := client.R(). - SetFormData(map[string]string{ - "first_name": "Jeevanandam", - "last_name": "M", - "zip_code": "00001", - "city": "new city update", - }). - Post("http://myapp.com/profile") - -// Multi value form data -criteria := url.Values{ - "search_criteria": []string{"book", "glass", "pencil"}, -} -resp, err := client.R(). - SetFormDataFromValues(criteria). - Post("http://myapp.com/search") -``` - -#### Save HTTP Response into File - -```go -// Create a Resty Client -client := resty.New() - -// Setting output directory path, If directory not exists then resty creates one! -// This is optional one, if you're planning using absoule path in -// `Request.SetOutput` and can used together. -client.SetOutputDirectory("/Users/jeeva/Downloads") - -// HTTP response gets saved into file, similar to curl -o flag -_, err := client.R(). - SetOutput("plugin/ReplyWithHeader-v5.1-beta.zip"). - Get("http://bit.ly/1LouEKr") - -// OR using absolute path -// Note: output directory path is not used for absolute path -_, err := client.R(). - SetOutput("/MyDownloads/plugin/ReplyWithHeader-v5.1-beta.zip"). - Get("http://bit.ly/1LouEKr") -``` - -#### Request URL Path Params - -Resty provides easy to use dynamic request URL path params. Params can be set at client and request level. Client level params value can be overridden at request level. - -```go -// Create a Resty Client -client := resty.New() - -client.R().SetPathParams(map[string]string{ - "userId": "sample@sample.com", - "subAccountId": "100002", -}). -Get("/v1/users/{userId}/{subAccountId}/details") - -// Result: -// Composed URL - /v1/users/sample@sample.com/100002/details -``` - -#### Request and Response Middleware - -Resty provides middleware ability to manipulate for Request and Response. It is more flexible than callback approach. - -```go -// Create a Resty Client -client := resty.New() - -// Registering Request Middleware -client.OnBeforeRequest(func(c *resty.Client, req *resty.Request) error { - // Now you have access to Client and current Request object - // manipulate it as per your need - - return nil // if its success otherwise return error - }) - -// Registering Response Middleware -client.OnAfterResponse(func(c *resty.Client, resp *resty.Response) error { - // Now you have access to Client and current Response object - // manipulate it as per your need - - return nil // if its success otherwise return error - }) -``` - -#### OnError Hooks - -Resty provides OnError hooks that may be called because: - -- The client failed to send the request due to connection timeout, TLS handshake failure, etc... -- The request was retried the maximum amount of times, and still failed. - -If there was a response from the server, the original error will be wrapped in `*resty.ResponseError` which contains the last response received. - -```go -// Create a Resty Client -client := resty.New() - -client.OnError(func(req *resty.Request, err error) { - if v, ok := err.(*resty.ResponseError); ok { - // v.Response contains the last response from the server - // v.Err contains the original error - } - // Log the error, increment a metric, etc... -}) -``` - -#### Redirect Policy - -Resty provides few ready to use redirect policy(s) also it supports multiple policies together. - -```go -// Create a Resty Client -client := resty.New() - -// Assign Client Redirect Policy. Create one as per you need -client.SetRedirectPolicy(resty.FlexibleRedirectPolicy(15)) - -// Wanna multiple policies such as redirect count, domain name check, etc -client.SetRedirectPolicy(resty.FlexibleRedirectPolicy(20), - resty.DomainCheckRedirectPolicy("host1.com", "host2.org", "host3.net")) -``` - -##### Custom Redirect Policy - -Implement [RedirectPolicy](redirect.go#L20) interface and register it with resty client. Have a look [redirect.go](redirect.go) for more information. - -```go -// Create a Resty Client -client := resty.New() - -// Using raw func into resty.SetRedirectPolicy -client.SetRedirectPolicy(resty.RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error { - // Implement your logic here - - // return nil for continue redirect otherwise return error to stop/prevent redirect - return nil -})) - -//--------------------------------------------------- - -// Using struct create more flexible redirect policy -type CustomRedirectPolicy struct { - // variables goes here -} - -func (c *CustomRedirectPolicy) Apply(req *http.Request, via []*http.Request) error { - // Implement your logic here - - // return nil for continue redirect otherwise return error to stop/prevent redirect - return nil -} - -// Registering in resty -client.SetRedirectPolicy(CustomRedirectPolicy{/* initialize variables */}) -``` - -#### Custom Root Certificates and Client Certificates - -```go -// Create a Resty Client -client := resty.New() - -// Custom Root certificates, just supply .pem file. -// you can add one or more root certificates, its get appended -client.SetRootCertificate("/path/to/root/pemFile1.pem") -client.SetRootCertificate("/path/to/root/pemFile2.pem") -// ... and so on! - -// Adding Client Certificates, you add one or more certificates -// Sample for creating certificate object -// Parsing public/private key pair from a pair of files. The files must contain PEM encoded data. -cert1, err := tls.LoadX509KeyPair("certs/client.pem", "certs/client.key") -if err != nil { - log.Fatalf("ERROR client certificate: %s", err) -} -// ... - -// You add one or more certificates -client.SetCertificates(cert1, cert2, cert3) -``` - -#### Custom Root Certificates and Client Certificates from string - -```go -// Custom Root certificates from string -// You can pass you certificates throught env variables as strings -// you can add one or more root certificates, its get appended -client.SetRootCertificateFromString("-----BEGIN CERTIFICATE-----content-----END CERTIFICATE-----") -client.SetRootCertificateFromString("-----BEGIN CERTIFICATE-----content-----END CERTIFICATE-----") -// ... and so on! - -// Adding Client Certificates, you add one or more certificates -// Sample for creating certificate object -// Parsing public/private key pair from a pair of files. The files must contain PEM encoded data. -cert1, err := tls.X509KeyPair([]byte("-----BEGIN CERTIFICATE-----content-----END CERTIFICATE-----"), []byte("-----BEGIN CERTIFICATE-----content-----END CERTIFICATE-----")) -if err != nil { - log.Fatalf("ERROR client certificate: %s", err) -} -// ... - -// You add one or more certificates -client.SetCertificates(cert1, cert2, cert3) -``` - -#### Proxy Settings - Client as well as at Request Level - -Default `Go` supports Proxy via environment variable `HTTP_PROXY`. Resty provides support via `SetProxy` & `RemoveProxy`. -Choose as per your need. - -**Client Level Proxy** settings applied to all the request - -```go -// Create a Resty Client -client := resty.New() - -// Setting a Proxy URL and Port -client.SetProxy("http://proxyserver:8888") - -// Want to remove proxy setting -client.RemoveProxy() -``` - -#### Retries - -Resty uses [backoff](http://www.awsarchitectureblog.com/2015/03/backoff.html) -to increase retry intervals after each attempt. - -Usage example: - -```go -// Create a Resty Client -client := resty.New() - -// Retries are configured per client -client. - // Set retry count to non zero to enable retries - SetRetryCount(3). - // You can override initial retry wait time. - // Default is 100 milliseconds. - SetRetryWaitTime(5 * time.Second). - // MaxWaitTime can be overridden as well. - // Default is 2 seconds. - SetRetryMaxWaitTime(20 * time.Second). - // SetRetryAfter sets callback to calculate wait time between retries. - // Default (nil) implies exponential backoff with jitter - SetRetryAfter(func(client *resty.Client, resp *resty.Response) (time.Duration, error) { - return 0, errors.New("quota exceeded") - }) -``` - -Above setup will result in resty retrying requests returned non nil error up to -3 times with delay increased after each attempt. - -You can optionally provide client with [custom retry conditions](https://pkg.go.dev/github.com/go-resty/resty/v2#RetryConditionFunc): - -```go -// Create a Resty Client -client := resty.New() - -client.AddRetryCondition( - // RetryConditionFunc type is for retry condition function - // input: non-nil Response OR request execution error - func(r *resty.Response, err error) bool { - return r.StatusCode() == http.StatusTooManyRequests - }, -) -``` - -Above example will make resty retry requests ended with `429 Too Many Requests` -status code. - -Multiple retry conditions can be added. - -It is also possible to use `resty.Backoff(...)` to get arbitrary retry scenarios -implemented. [Reference](retry_test.go). - -#### Allow GET request with Payload - -```go -// Create a Resty Client -client := resty.New() - -// Allow GET request with Payload. This is disabled by default. -client.SetAllowGetMethodPayload(true) -``` - -#### Wanna Multiple Clients - -```go -// Here you go! -// Client 1 -client1 := resty.New() -client1.R().Get("http://httpbin.org") -// ... - -// Client 2 -client2 := resty.New() -client2.R().Head("http://httpbin.org") -// ... - -// Bend it as per your need!!! -``` - -#### Remaining Client Settings & its Options - -```go -// Create a Resty Client -client := resty.New() - -// Unique settings at Client level -//-------------------------------- -// Enable debug mode -client.SetDebug(true) - -// Assign Client TLSClientConfig -// One can set custom root-certificate. Refer: http://golang.org/pkg/crypto/tls/#example_Dial -client.SetTLSClientConfig(&tls.Config{ RootCAs: roots }) - -// or One can disable security check (https) -client.SetTLSClientConfig(&tls.Config{ InsecureSkipVerify: true }) - -// Set client timeout as per your need -client.SetTimeout(1 * time.Minute) - - -// You can override all below settings and options at request level if you want to -//-------------------------------------------------------------------------------- -// Host URL for all request. So you can use relative URL in the request -client.SetHostURL("http://httpbin.org") - -// Headers for all request -client.SetHeader("Accept", "application/json") -client.SetHeaders(map[string]string{ - "Content-Type": "application/json", - "User-Agent": "My custom User Agent String", - }) - -// Cookies for all request -client.SetCookie(&http.Cookie{ - Name:"go-resty", - Value:"This is cookie value", - Path: "/", - Domain: "sample.com", - MaxAge: 36000, - HttpOnly: true, - Secure: false, - }) -client.SetCookies(cookies) - -// URL query parameters for all request -client.SetQueryParam("user_id", "00001") -client.SetQueryParams(map[string]string{ // sample of those who use this manner - "api_key": "api-key-here", - "api_secert": "api-secert", - }) -client.R().SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more") - -// Form data for all request. Typically used with POST and PUT -client.SetFormData(map[string]string{ - "access_token": "BC594900-518B-4F7E-AC75-BD37F019E08F", - }) - -// Basic Auth for all request -client.SetBasicAuth("myuser", "mypass") - -// Bearer Auth Token for all request -client.SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F") - -// Enabling Content length value for all request -client.SetContentLength(true) - -// Registering global Error object structure for JSON/XML request -client.SetError(&Error{}) // or resty.SetError(Error{}) -``` - -#### Unix Socket - -```go -unixSocket := "/var/run/my_socket.sock" - -// Create a Go's http.Transport so we can set it in resty. -transport := http.Transport{ - Dial: func(_, _ string) (net.Conn, error) { - return net.Dial("unix", unixSocket) - }, -} - -// Create a Resty Client -client := resty.New() - -// Set the previous transport that we created, set the scheme of the communication to the -// socket and set the unixSocket as the HostURL. -client.SetTransport(&transport).SetScheme("http").SetHostURL(unixSocket) - -// No need to write the host's URL on the request, just the path. -client.R().Get("/index.html") -``` - -#### Bazel Support - -Resty can be built, tested and depended upon via [Bazel](https://bazel.build). -For example, to run all tests: - -```shell -bazel test :resty_test -``` - -#### Mocking http requests using [httpmock](https://github.com/jarcoal/httpmock) library - -In order to mock the http requests when testing your application you -could use the `httpmock` library. - -When using the default resty client, you should pass the client to the library as follow: - -```go -// Create a Resty Client -client := resty.New() - -// Get the underlying HTTP Client and set it to Mock -httpmock.ActivateNonDefault(client.GetClient()) -``` - -More detailed example of mocking resty http requests using ginko could be found [here](https://github.com/jarcoal/httpmock#ginkgo--resty-example). - -## Versioning - -Resty releases versions according to [Semantic Versioning](http://semver.org) - - * Resty v2 does not use `gopkg.in` service for library versioning. - * Resty fully adapted to `go mod` capabilities since `v1.10.0` release. - * Resty v1 series was using `gopkg.in` to provide versioning. `gopkg.in/resty.vX` points to appropriate tagged versions; `X` denotes version series number and it's a stable release for production use. For e.g. `gopkg.in/resty.v0`. - * Development takes place at the master branch. Although the code in master should always compile and test successfully, it might break API's. I aim to maintain backwards compatibility, but sometimes API's and behavior might be changed to fix a bug. - -## Contribution - -I would welcome your contribution! If you find any improvement or issue you want to fix, feel free to send a pull request, I like pull requests that include test cases for fix/enhancement. I have done my best to bring pretty good code coverage. Feel free to write tests. - -BTW, I'd like to know what you think about `Resty`. Kindly open an issue or send me an email; it'd mean a lot to me. - -## Creator - -[Jeevanandam M.](https://github.com/jeevatkm) (jeeva@myjeeva.com) - -## Core Team - -Have a look on [Members](https://github.com/orgs/go-resty/people) page. - -## Contributors - -Have a look on [Contributors](https://github.com/go-resty/resty/graphs/contributors) page. - -## License - -Resty released under MIT license, refer [LICENSE](LICENSE) file. diff --git a/vendor/github.com/go-resty/resty/v2/WORKSPACE b/vendor/github.com/go-resty/resty/v2/WORKSPACE deleted file mode 100644 index 9ef03e95..00000000 --- a/vendor/github.com/go-resty/resty/v2/WORKSPACE +++ /dev/null @@ -1,31 +0,0 @@ -workspace(name = "resty") - -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -http_archive( - name = "io_bazel_rules_go", - sha256 = "69de5c704a05ff37862f7e0f5534d4f479418afc21806c887db544a316f3cb6b", - urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.27.0/rules_go-v0.27.0.tar.gz", - "https://github.com/bazelbuild/rules_go/releases/download/v0.27.0/rules_go-v0.27.0.tar.gz", - ], -) - -http_archive( - name = "bazel_gazelle", - sha256 = "62ca106be173579c0a167deb23358fdfe71ffa1e4cfdddf5582af26520f1c66f", - urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.23.0/bazel-gazelle-v0.23.0.tar.gz", - "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.23.0/bazel-gazelle-v0.23.0.tar.gz", - ], -) - -load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") - -go_rules_dependencies() - -go_register_toolchains(version = "1.16") - -load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") - -gazelle_dependencies() diff --git a/vendor/github.com/go-resty/resty/v2/client.go b/vendor/github.com/go-resty/resty/v2/client.go deleted file mode 100644 index 1a03efa3..00000000 --- a/vendor/github.com/go-resty/resty/v2/client.go +++ /dev/null @@ -1,1115 +0,0 @@ -// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved. -// resty source code and usage is governed by a MIT style -// license that can be found in the LICENSE file. - -package resty - -import ( - "bytes" - "compress/gzip" - "crypto/tls" - "crypto/x509" - "encoding/json" - "encoding/xml" - "errors" - "fmt" - "io" - "io/ioutil" - "math" - "net/http" - "net/url" - "reflect" - "regexp" - "strings" - "sync" - "time" -) - -const ( - // MethodGet HTTP method - MethodGet = "GET" - - // MethodPost HTTP method - MethodPost = "POST" - - // MethodPut HTTP method - MethodPut = "PUT" - - // MethodDelete HTTP method - MethodDelete = "DELETE" - - // MethodPatch HTTP method - MethodPatch = "PATCH" - - // MethodHead HTTP method - MethodHead = "HEAD" - - // MethodOptions HTTP method - MethodOptions = "OPTIONS" -) - -var ( - hdrUserAgentKey = http.CanonicalHeaderKey("User-Agent") - hdrAcceptKey = http.CanonicalHeaderKey("Accept") - hdrContentTypeKey = http.CanonicalHeaderKey("Content-Type") - hdrContentLengthKey = http.CanonicalHeaderKey("Content-Length") - hdrContentEncodingKey = http.CanonicalHeaderKey("Content-Encoding") - hdrLocationKey = http.CanonicalHeaderKey("Location") - - plainTextType = "text/plain; charset=utf-8" - jsonContentType = "application/json" - formContentType = "application/x-www-form-urlencoded" - - jsonCheck = regexp.MustCompile(`(?i:(application|text)/(json|.*\+json|json\-.*)(;|$))`) - xmlCheck = regexp.MustCompile(`(?i:(application|text)/(xml|.*\+xml)(;|$))`) - - hdrUserAgentValue = "go-resty/" + Version + " (https://github.com/go-resty/resty)" - bufPool = &sync.Pool{New: func() interface{} { return &bytes.Buffer{} }} -) - -type ( - // RequestMiddleware type is for request middleware, called before a request is sent - RequestMiddleware func(*Client, *Request) error - - // ResponseMiddleware type is for response middleware, called after a response has been received - ResponseMiddleware func(*Client, *Response) error - - // PreRequestHook type is for the request hook, called right before the request is sent - PreRequestHook func(*Client, *http.Request) error - - // RequestLogCallback type is for request logs, called before the request is logged - RequestLogCallback func(*RequestLog) error - - // ResponseLogCallback type is for response logs, called before the response is logged - ResponseLogCallback func(*ResponseLog) error - - // ErrorHook type is for reacting to request errors, called after all retries were attempted - ErrorHook func(*Request, error) -) - -// Client struct is used to create Resty client with client level settings, -// these settings are applicable to all the request raised from the client. -// -// Resty also provides an options to override most of the client settings -// at request level. -type Client struct { - BaseURL string - HostURL string // Deprecated: use BaseURL instead. To be removed in v3.0.0 release. - QueryParam url.Values - FormData url.Values - PathParams map[string]string - Header http.Header - UserInfo *User - Token string - AuthScheme string - Cookies []*http.Cookie - Error reflect.Type - Debug bool - DisableWarn bool - AllowGetMethodPayload bool - RetryCount int - RetryWaitTime time.Duration - RetryMaxWaitTime time.Duration - RetryConditions []RetryConditionFunc - RetryHooks []OnRetryFunc - RetryAfter RetryAfterFunc - JSONMarshal func(v interface{}) ([]byte, error) - JSONUnmarshal func(data []byte, v interface{}) error - XMLMarshal func(v interface{}) ([]byte, error) - XMLUnmarshal func(data []byte, v interface{}) error - - // HeaderAuthorizationKey is used to set/access Request Authorization header - // value when `SetAuthToken` option is used. - HeaderAuthorizationKey string - - jsonEscapeHTML bool - setContentLength bool - closeConnection bool - notParseResponse bool - trace bool - debugBodySizeLimit int64 - outputDirectory string - scheme string - log Logger - httpClient *http.Client - proxyURL *url.URL - beforeRequest []RequestMiddleware - udBeforeRequest []RequestMiddleware - preReqHook PreRequestHook - afterResponse []ResponseMiddleware - requestLog RequestLogCallback - responseLog ResponseLogCallback - errorHooks []ErrorHook -} - -// User type is to hold an username and password information -type User struct { - Username, Password string -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// Client methods -//___________________________________ - -// SetHostURL method is to set Host URL in the client instance. It will be used with request -// raised from this client with relative URL -// // Setting HTTP address -// client.SetHostURL("http://myjeeva.com") -// -// // Setting HTTPS address -// client.SetHostURL("https://myjeeva.com") -// -// Deprecated: use SetBaseURL instead. To be removed in v3.0.0 release. -func (c *Client) SetHostURL(url string) *Client { - c.SetBaseURL(url) - return c -} - -// SetBaseURL method is to set Base URL in the client instance. It will be used with request -// raised from this client with relative URL -// // Setting HTTP address -// client.SetBaseURL("http://myjeeva.com") -// -// // Setting HTTPS address -// client.SetBaseURL("https://myjeeva.com") -// -// Since v2.7.0 -func (c *Client) SetBaseURL(url string) *Client { - c.BaseURL = strings.TrimRight(url, "/") - c.HostURL = c.BaseURL - return c -} - -// SetHeader method sets a single header field and its value in the client instance. -// These headers will be applied to all requests raised from this client instance. -// Also it can be overridden at request level header options. -// -// See `Request.SetHeader` or `Request.SetHeaders`. -// -// For Example: To set `Content-Type` and `Accept` as `application/json` -// -// client. -// SetHeader("Content-Type", "application/json"). -// SetHeader("Accept", "application/json") -func (c *Client) SetHeader(header, value string) *Client { - c.Header.Set(header, value) - return c -} - -// SetHeaders method sets multiple headers field and its values at one go in the client instance. -// These headers will be applied to all requests raised from this client instance. Also it can be -// overridden at request level headers options. -// -// See `Request.SetHeaders` or `Request.SetHeader`. -// -// For Example: To set `Content-Type` and `Accept` as `application/json` -// -// client.SetHeaders(map[string]string{ -// "Content-Type": "application/json", -// "Accept": "application/json", -// }) -func (c *Client) SetHeaders(headers map[string]string) *Client { - for h, v := range headers { - c.Header.Set(h, v) - } - return c -} - -// SetHeaderVerbatim method is to set a single header field and its value verbatim in the current request. -// -// For Example: To set `all_lowercase` and `UPPERCASE` as `available`. -// client.R(). -// SetHeaderVerbatim("all_lowercase", "available"). -// SetHeaderVerbatim("UPPERCASE", "available") -// -// Also you can override header value, which was set at client instance level. -// -// Since v2.6.0 -func (c *Client) SetHeaderVerbatim(header, value string) *Client { - c.Header[header] = []string{value} - return c -} - -// SetCookieJar method sets custom http.CookieJar in the resty client. Its way to override default. -// -// For Example: sometimes we don't want to save cookies in api contacting, we can remove the default -// CookieJar in resty client. -// -// client.SetCookieJar(nil) -func (c *Client) SetCookieJar(jar http.CookieJar) *Client { - c.httpClient.Jar = jar - return c -} - -// SetCookie method appends a single cookie in the client instance. -// These cookies will be added to all the request raised from this client instance. -// client.SetCookie(&http.Cookie{ -// Name:"go-resty", -// Value:"This is cookie value", -// }) -func (c *Client) SetCookie(hc *http.Cookie) *Client { - c.Cookies = append(c.Cookies, hc) - return c -} - -// SetCookies method sets an array of cookies in the client instance. -// These cookies will be added to all the request raised from this client instance. -// cookies := []*http.Cookie{ -// &http.Cookie{ -// Name:"go-resty-1", -// Value:"This is cookie 1 value", -// }, -// &http.Cookie{ -// Name:"go-resty-2", -// Value:"This is cookie 2 value", -// }, -// } -// -// // Setting a cookies into resty -// client.SetCookies(cookies) -func (c *Client) SetCookies(cs []*http.Cookie) *Client { - c.Cookies = append(c.Cookies, cs...) - return c -} - -// SetQueryParam method sets single parameter and its value in the client instance. -// It will be formed as query string for the request. -// -// For Example: `search=kitchen%20papers&size=large` -// in the URL after `?` mark. These query params will be added to all the request raised from -// this client instance. Also it can be overridden at request level Query Param options. -// -// See `Request.SetQueryParam` or `Request.SetQueryParams`. -// client. -// SetQueryParam("search", "kitchen papers"). -// SetQueryParam("size", "large") -func (c *Client) SetQueryParam(param, value string) *Client { - c.QueryParam.Set(param, value) - return c -} - -// SetQueryParams method sets multiple parameters and their values at one go in the client instance. -// It will be formed as query string for the request. -// -// For Example: `search=kitchen%20papers&size=large` -// in the URL after `?` mark. These query params will be added to all the request raised from this -// client instance. Also it can be overridden at request level Query Param options. -// -// See `Request.SetQueryParams` or `Request.SetQueryParam`. -// client.SetQueryParams(map[string]string{ -// "search": "kitchen papers", -// "size": "large", -// }) -func (c *Client) SetQueryParams(params map[string]string) *Client { - for p, v := range params { - c.SetQueryParam(p, v) - } - return c -} - -// SetFormData method sets Form parameters and their values in the client instance. -// It's applicable only HTTP method `POST` and `PUT` and requets content type would be set as -// `application/x-www-form-urlencoded`. These form data will be added to all the request raised from -// this client instance. Also it can be overridden at request level form data. -// -// See `Request.SetFormData`. -// client.SetFormData(map[string]string{ -// "access_token": "BC594900-518B-4F7E-AC75-BD37F019E08F", -// "user_id": "3455454545", -// }) -func (c *Client) SetFormData(data map[string]string) *Client { - for k, v := range data { - c.FormData.Set(k, v) - } - return c -} - -// SetBasicAuth method sets the basic authentication header in the HTTP request. For Example: -// Authorization: Basic -// -// For Example: To set the header for username "go-resty" and password "welcome" -// client.SetBasicAuth("go-resty", "welcome") -// -// This basic auth information gets added to all the request rasied from this client instance. -// Also it can be overridden or set one at the request level is supported. -// -// See `Request.SetBasicAuth`. -func (c *Client) SetBasicAuth(username, password string) *Client { - c.UserInfo = &User{Username: username, Password: password} - return c -} - -// SetAuthToken method sets the auth token of the `Authorization` header for all HTTP requests. -// The default auth scheme is `Bearer`, it can be customized with the method `SetAuthScheme`. For Example: -// Authorization: -// -// For Example: To set auth token BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F -// -// client.SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F") -// -// This auth token gets added to all the requests rasied from this client instance. -// Also it can be overridden or set one at the request level is supported. -// -// See `Request.SetAuthToken`. -func (c *Client) SetAuthToken(token string) *Client { - c.Token = token - return c -} - -// SetAuthScheme method sets the auth scheme type in the HTTP request. For Example: -// Authorization: -// -// For Example: To set the scheme to use OAuth -// -// client.SetAuthScheme("OAuth") -// -// This auth scheme gets added to all the requests rasied from this client instance. -// Also it can be overridden or set one at the request level is supported. -// -// Information about auth schemes can be found in RFC7235 which is linked to below -// along with the page containing the currently defined official authentication schemes: -// https://tools.ietf.org/html/rfc7235 -// https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml#authschemes -// -// See `Request.SetAuthToken`. -func (c *Client) SetAuthScheme(scheme string) *Client { - c.AuthScheme = scheme - return c -} - -// R method creates a new request instance, its used for Get, Post, Put, Delete, Patch, Head, Options, etc. -func (c *Client) R() *Request { - r := &Request{ - QueryParam: url.Values{}, - FormData: url.Values{}, - Header: http.Header{}, - Cookies: make([]*http.Cookie, 0), - - client: c, - multipartFiles: []*File{}, - multipartFields: []*MultipartField{}, - PathParams: map[string]string{}, - jsonEscapeHTML: true, - } - return r -} - -// NewRequest is an alias for method `R()`. Creates a new request instance, its used for -// Get, Post, Put, Delete, Patch, Head, Options, etc. -func (c *Client) NewRequest() *Request { - return c.R() -} - -// OnBeforeRequest method appends request middleware into the before request chain. -// Its gets applied after default Resty request middlewares and before request -// been sent from Resty to host server. -// client.OnBeforeRequest(func(c *resty.Client, r *resty.Request) error { -// // Now you have access to Client and Request instance -// // manipulate it as per your need -// -// return nil // if its success otherwise return error -// }) -func (c *Client) OnBeforeRequest(m RequestMiddleware) *Client { - c.udBeforeRequest = append(c.udBeforeRequest, m) - return c -} - -// OnAfterResponse method appends response middleware into the after response chain. -// Once we receive response from host server, default Resty response middleware -// gets applied and then user assigened response middlewares applied. -// client.OnAfterResponse(func(c *resty.Client, r *resty.Response) error { -// // Now you have access to Client and Response instance -// // manipulate it as per your need -// -// return nil // if its success otherwise return error -// }) -func (c *Client) OnAfterResponse(m ResponseMiddleware) *Client { - c.afterResponse = append(c.afterResponse, m) - return c -} - -// OnError method adds a callback that will be run whenever a request execution fails. -// This is called after all retries have been attempted (if any). -// If there was a response from the server, the error will be wrapped in *ResponseError -// which has the last response received from the server. -// -// client.OnError(func(req *resty.Request, err error) { -// if v, ok := err.(*resty.ResponseError); ok { -// // Do something with v.Response -// } -// // Log the error, increment a metric, etc... -// }) -func (c *Client) OnError(h ErrorHook) *Client { - c.errorHooks = append(c.errorHooks, h) - return c -} - -// SetPreRequestHook method sets the given pre-request function into resty client. -// It is called right before the request is fired. -// -// Note: Only one pre-request hook can be registered. Use `client.OnBeforeRequest` for mutilple. -func (c *Client) SetPreRequestHook(h PreRequestHook) *Client { - if c.preReqHook != nil { - c.log.Warnf("Overwriting an existing pre-request hook: %s", functionName(h)) - } - c.preReqHook = h - return c -} - -// SetDebug method enables the debug mode on Resty client. Client logs details of every request and response. -// For `Request` it logs information such as HTTP verb, Relative URL path, Host, Headers, Body if it has one. -// For `Response` it logs information such as Status, Response Time, Headers, Body if it has one. -// client.SetDebug(true) -func (c *Client) SetDebug(d bool) *Client { - c.Debug = d - return c -} - -// SetDebugBodyLimit sets the maximum size for which the response and request body will be logged in debug mode. -// client.SetDebugBodyLimit(1000000) -func (c *Client) SetDebugBodyLimit(sl int64) *Client { - c.debugBodySizeLimit = sl - return c -} - -// OnRequestLog method used to set request log callback into Resty. Registered callback gets -// called before the resty actually logs the information. -func (c *Client) OnRequestLog(rl RequestLogCallback) *Client { - if c.requestLog != nil { - c.log.Warnf("Overwriting an existing on-request-log callback from=%s to=%s", - functionName(c.requestLog), functionName(rl)) - } - c.requestLog = rl - return c -} - -// OnResponseLog method used to set response log callback into Resty. Registered callback gets -// called before the resty actually logs the information. -func (c *Client) OnResponseLog(rl ResponseLogCallback) *Client { - if c.responseLog != nil { - c.log.Warnf("Overwriting an existing on-response-log callback from=%s to=%s", - functionName(c.responseLog), functionName(rl)) - } - c.responseLog = rl - return c -} - -// SetDisableWarn method disables the warning message on Resty client. -// -// For Example: Resty warns the user when BasicAuth used on non-TLS mode. -// client.SetDisableWarn(true) -func (c *Client) SetDisableWarn(d bool) *Client { - c.DisableWarn = d - return c -} - -// SetAllowGetMethodPayload method allows the GET method with payload on Resty client. -// -// For Example: Resty allows the user sends request with a payload on HTTP GET method. -// client.SetAllowGetMethodPayload(true) -func (c *Client) SetAllowGetMethodPayload(a bool) *Client { - c.AllowGetMethodPayload = a - return c -} - -// SetLogger method sets given writer for logging Resty request and response details. -// -// Compliant to interface `resty.Logger`. -func (c *Client) SetLogger(l Logger) *Client { - c.log = l - return c -} - -// SetContentLength method enables the HTTP header `Content-Length` value for every request. -// By default Resty won't set `Content-Length`. -// client.SetContentLength(true) -// -// Also you have an option to enable for particular request. See `Request.SetContentLength` -func (c *Client) SetContentLength(l bool) *Client { - c.setContentLength = l - return c -} - -// SetTimeout method sets timeout for request raised from client. -// client.SetTimeout(time.Duration(1 * time.Minute)) -func (c *Client) SetTimeout(timeout time.Duration) *Client { - c.httpClient.Timeout = timeout - return c -} - -// SetError method is to register the global or client common `Error` object into Resty. -// It is used for automatic unmarshalling if response status code is greater than 399 and -// content type either JSON or XML. Can be pointer or non-pointer. -// client.SetError(&Error{}) -// // OR -// client.SetError(Error{}) -func (c *Client) SetError(err interface{}) *Client { - c.Error = typeOf(err) - return c -} - -// SetRedirectPolicy method sets the client redirect poilicy. Resty provides ready to use -// redirect policies. Wanna create one for yourself refer to `redirect.go`. -// -// client.SetRedirectPolicy(FlexibleRedirectPolicy(20)) -// -// // Need multiple redirect policies together -// client.SetRedirectPolicy(FlexibleRedirectPolicy(20), DomainCheckRedirectPolicy("host1.com", "host2.net")) -func (c *Client) SetRedirectPolicy(policies ...interface{}) *Client { - for _, p := range policies { - if _, ok := p.(RedirectPolicy); !ok { - c.log.Errorf("%v does not implement resty.RedirectPolicy (missing Apply method)", - functionName(p)) - } - } - - c.httpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error { - for _, p := range policies { - if err := p.(RedirectPolicy).Apply(req, via); err != nil { - return err - } - } - return nil // looks good, go ahead - } - - return c -} - -// SetRetryCount method enables retry on Resty client and allows you -// to set no. of retry count. Resty uses a Backoff mechanism. -func (c *Client) SetRetryCount(count int) *Client { - c.RetryCount = count - return c -} - -// SetRetryWaitTime method sets default wait time to sleep before retrying -// request. -// -// Default is 100 milliseconds. -func (c *Client) SetRetryWaitTime(waitTime time.Duration) *Client { - c.RetryWaitTime = waitTime - return c -} - -// SetRetryMaxWaitTime method sets max wait time to sleep before retrying -// request. -// -// Default is 2 seconds. -func (c *Client) SetRetryMaxWaitTime(maxWaitTime time.Duration) *Client { - c.RetryMaxWaitTime = maxWaitTime - return c -} - -// SetRetryAfter sets callback to calculate wait time between retries. -// Default (nil) implies exponential backoff with jitter -func (c *Client) SetRetryAfter(callback RetryAfterFunc) *Client { - c.RetryAfter = callback - return c -} - -// AddRetryCondition method adds a retry condition function to array of functions -// that are checked to determine if the request is retried. The request will -// retry if any of the functions return true and error is nil. -// -// Note: These retry conditions are applied on all Request made using this Client. -// For Request specific retry conditions check *Request.AddRetryCondition -func (c *Client) AddRetryCondition(condition RetryConditionFunc) *Client { - c.RetryConditions = append(c.RetryConditions, condition) - return c -} - -// AddRetryAfterErrorCondition adds the basic condition of retrying after encountering -// an error from the http response -// -// Since v2.6.0 -func (c *Client) AddRetryAfterErrorCondition() *Client { - c.AddRetryCondition(func(response *Response, err error) bool { - return response.IsError() - }) - return c -} - -// AddRetryHook adds a side-effecting retry hook to an array of hooks -// that will be executed on each retry. -// -// Since v2.6.0 -func (c *Client) AddRetryHook(hook OnRetryFunc) *Client { - c.RetryHooks = append(c.RetryHooks, hook) - return c -} - -// SetTLSClientConfig method sets TLSClientConfig for underling client Transport. -// -// For Example: -// // One can set custom root-certificate. Refer: http://golang.org/pkg/crypto/tls/#example_Dial -// client.SetTLSClientConfig(&tls.Config{ RootCAs: roots }) -// -// // or One can disable security check (https) -// client.SetTLSClientConfig(&tls.Config{ InsecureSkipVerify: true }) -// -// Note: This method overwrites existing `TLSClientConfig`. -func (c *Client) SetTLSClientConfig(config *tls.Config) *Client { - transport, err := c.transport() - if err != nil { - c.log.Errorf("%v", err) - return c - } - transport.TLSClientConfig = config - return c -} - -// SetProxy method sets the Proxy URL and Port for Resty client. -// client.SetProxy("http://proxyserver:8888") -// -// OR Without this `SetProxy` method, you could also set Proxy via environment variable. -// -// Refer to godoc `http.ProxyFromEnvironment`. -func (c *Client) SetProxy(proxyURL string) *Client { - transport, err := c.transport() - if err != nil { - c.log.Errorf("%v", err) - return c - } - - pURL, err := url.Parse(proxyURL) - if err != nil { - c.log.Errorf("%v", err) - return c - } - - c.proxyURL = pURL - transport.Proxy = http.ProxyURL(c.proxyURL) - return c -} - -// RemoveProxy method removes the proxy configuration from Resty client -// client.RemoveProxy() -func (c *Client) RemoveProxy() *Client { - transport, err := c.transport() - if err != nil { - c.log.Errorf("%v", err) - return c - } - c.proxyURL = nil - transport.Proxy = nil - return c -} - -// SetCertificates method helps to set client certificates into Resty conveniently. -func (c *Client) SetCertificates(certs ...tls.Certificate) *Client { - config, err := c.tlsConfig() - if err != nil { - c.log.Errorf("%v", err) - return c - } - config.Certificates = append(config.Certificates, certs...) - return c -} - -// SetRootCertificate method helps to add one or more root certificates into Resty client -// client.SetRootCertificate("/path/to/root/pemFile.pem") -func (c *Client) SetRootCertificate(pemFilePath string) *Client { - rootPemData, err := ioutil.ReadFile(pemFilePath) - if err != nil { - c.log.Errorf("%v", err) - return c - } - - config, err := c.tlsConfig() - if err != nil { - c.log.Errorf("%v", err) - return c - } - if config.RootCAs == nil { - config.RootCAs = x509.NewCertPool() - } - - config.RootCAs.AppendCertsFromPEM(rootPemData) - return c -} - -// SetRootCertificateFromString method helps to add one or more root certificates into Resty client -// client.SetRootCertificateFromString("pem file content") -func (c *Client) SetRootCertificateFromString(pemContent string) *Client { - config, err := c.tlsConfig() - if err != nil { - c.log.Errorf("%v", err) - return c - } - if config.RootCAs == nil { - config.RootCAs = x509.NewCertPool() - } - - config.RootCAs.AppendCertsFromPEM([]byte(pemContent)) - return c -} - -// SetOutputDirectory method sets output directory for saving HTTP response into file. -// If the output directory not exists then resty creates one. This setting is optional one, -// if you're planning using absolute path in `Request.SetOutput` and can used together. -// client.SetOutputDirectory("/save/http/response/here") -func (c *Client) SetOutputDirectory(dirPath string) *Client { - c.outputDirectory = dirPath - return c -} - -// SetTransport method sets custom `*http.Transport` or any `http.RoundTripper` -// compatible interface implementation in the resty client. -// -// Note: -// -// - If transport is not type of `*http.Transport` then you may not be able to -// take advantage of some of the Resty client settings. -// -// - It overwrites the Resty client transport instance and it's configurations. -// -// transport := &http.Transport{ -// // somthing like Proxying to httptest.Server, etc... -// Proxy: func(req *http.Request) (*url.URL, error) { -// return url.Parse(server.URL) -// }, -// } -// -// client.SetTransport(transport) -func (c *Client) SetTransport(transport http.RoundTripper) *Client { - if transport != nil { - c.httpClient.Transport = transport - } - return c -} - -// SetScheme method sets custom scheme in the Resty client. It's way to override default. -// client.SetScheme("http") -func (c *Client) SetScheme(scheme string) *Client { - if !IsStringEmpty(scheme) { - c.scheme = strings.TrimSpace(scheme) - } - return c -} - -// SetCloseConnection method sets variable `Close` in http request struct with the given -// value. More info: https://golang.org/src/net/http/request.go -func (c *Client) SetCloseConnection(close bool) *Client { - c.closeConnection = close - return c -} - -// SetDoNotParseResponse method instructs `Resty` not to parse the response body automatically. -// Resty exposes the raw response body as `io.ReadCloser`. Also do not forget to close the body, -// otherwise you might get into connection leaks, no connection reuse. -// -// Note: Response middlewares are not applicable, if you use this option. Basically you have -// taken over the control of response parsing from `Resty`. -func (c *Client) SetDoNotParseResponse(parse bool) *Client { - c.notParseResponse = parse - return c -} - -// SetPathParam method sets single URL path key-value pair in the -// Resty client instance. -// client.SetPathParam("userId", "sample@sample.com") -// -// Result: -// URL - /v1/users/{userId}/details -// Composed URL - /v1/users/sample@sample.com/details -// It replaces the value of the key while composing the request URL. -// -// Also it can be overridden at request level Path Params options, -// see `Request.SetPathParam` or `Request.SetPathParams`. -func (c *Client) SetPathParam(param, value string) *Client { - c.PathParams[param] = value - return c -} - -// SetPathParams method sets multiple URL path key-value pairs at one go in the -// Resty client instance. -// client.SetPathParams(map[string]string{ -// "userId": "sample@sample.com", -// "subAccountId": "100002", -// }) -// -// Result: -// URL - /v1/users/{userId}/{subAccountId}/details -// Composed URL - /v1/users/sample@sample.com/100002/details -// It replaces the value of the key while composing the request URL. -// -// Also it can be overridden at request level Path Params options, -// see `Request.SetPathParam` or `Request.SetPathParams`. -func (c *Client) SetPathParams(params map[string]string) *Client { - for p, v := range params { - c.SetPathParam(p, v) - } - return c -} - -// SetJSONEscapeHTML method is to enable/disable the HTML escape on JSON marshal. -// -// Note: This option only applicable to standard JSON Marshaller. -func (c *Client) SetJSONEscapeHTML(b bool) *Client { - c.jsonEscapeHTML = b - return c -} - -// EnableTrace method enables the Resty client trace for the requests fired from -// the client using `httptrace.ClientTrace` and provides insights. -// -// client := resty.New().EnableTrace() -// -// resp, err := client.R().Get("https://httpbin.org/get") -// fmt.Println("Error:", err) -// fmt.Println("Trace Info:", resp.Request.TraceInfo()) -// -// Also `Request.EnableTrace` available too to get trace info for single request. -// -// Since v2.0.0 -func (c *Client) EnableTrace() *Client { - c.trace = true - return c -} - -// DisableTrace method disables the Resty client trace. Refer to `Client.EnableTrace`. -// -// Since v2.0.0 -func (c *Client) DisableTrace() *Client { - c.trace = false - return c -} - -// IsProxySet method returns the true is proxy is set from resty client otherwise -// false. By default proxy is set from environment, refer to `http.ProxyFromEnvironment`. -func (c *Client) IsProxySet() bool { - return c.proxyURL != nil -} - -// GetClient method returns the current `http.Client` used by the resty client. -func (c *Client) GetClient() *http.Client { - return c.httpClient -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// Client Unexported methods -//_______________________________________________________________________ - -// Executes method executes the given `Request` object and returns response -// error. -func (c *Client) execute(req *Request) (*Response, error) { - // Apply Request middleware - var err error - - // user defined on before request methods - // to modify the *resty.Request object - for _, f := range c.udBeforeRequest { - if err = f(c, req); err != nil { - return nil, wrapNoRetryErr(err) - } - } - - // resty middlewares - for _, f := range c.beforeRequest { - if err = f(c, req); err != nil { - return nil, wrapNoRetryErr(err) - } - } - - if hostHeader := req.Header.Get("Host"); hostHeader != "" { - req.RawRequest.Host = hostHeader - } - - // call pre-request if defined - if c.preReqHook != nil { - if err = c.preReqHook(c, req.RawRequest); err != nil { - return nil, wrapNoRetryErr(err) - } - } - - if err = requestLogger(c, req); err != nil { - return nil, wrapNoRetryErr(err) - } - - req.RawRequest.Body = newRequestBodyReleaser(req.RawRequest.Body, req.bodyBuf) - - req.Time = time.Now() - resp, err := c.httpClient.Do(req.RawRequest) - - response := &Response{ - Request: req, - RawResponse: resp, - } - - if err != nil || req.notParseResponse || c.notParseResponse { - response.setReceivedAt() - return response, err - } - - if !req.isSaveResponse { - defer closeq(resp.Body) - body := resp.Body - - // GitHub #142 & #187 - if strings.EqualFold(resp.Header.Get(hdrContentEncodingKey), "gzip") && resp.ContentLength != 0 { - if _, ok := body.(*gzip.Reader); !ok { - body, err = gzip.NewReader(body) - if err != nil { - response.setReceivedAt() - return response, err - } - defer closeq(body) - } - } - - if response.body, err = ioutil.ReadAll(body); err != nil { - response.setReceivedAt() - return response, err - } - - response.size = int64(len(response.body)) - } - - response.setReceivedAt() // after we read the body - - // Apply Response middleware - for _, f := range c.afterResponse { - if err = f(c, response); err != nil { - break - } - } - - return response, wrapNoRetryErr(err) -} - -// getting TLS client config if not exists then create one -func (c *Client) tlsConfig() (*tls.Config, error) { - transport, err := c.transport() - if err != nil { - return nil, err - } - if transport.TLSClientConfig == nil { - transport.TLSClientConfig = &tls.Config{} - } - return transport.TLSClientConfig, nil -} - -// Transport method returns `*http.Transport` currently in use or error -// in case currently used `transport` is not a `*http.Transport`. -func (c *Client) transport() (*http.Transport, error) { - if transport, ok := c.httpClient.Transport.(*http.Transport); ok { - return transport, nil - } - return nil, errors.New("current transport is not an *http.Transport instance") -} - -// just an internal helper method -func (c *Client) outputLogTo(w io.Writer) *Client { - c.log.(*logger).l.SetOutput(w) - return c -} - -// ResponseError is a wrapper for including the server response with an error. -// Neither the err nor the response should be nil. -type ResponseError struct { - Response *Response - Err error -} - -func (e *ResponseError) Error() string { - return e.Err.Error() -} - -func (e *ResponseError) Unwrap() error { - return e.Err -} - -// Helper to run onErrorHooks hooks. -// It wraps the error in a ResponseError if the resp is not nil -// so hooks can access it. -func (c *Client) onErrorHooks(req *Request, resp *Response, err error) { - if err != nil { - if resp != nil { // wrap with ResponseError - err = &ResponseError{Response: resp, Err: err} - } - for _, h := range c.errorHooks { - h(req, err) - } - } -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// File struct and its methods -//_______________________________________________________________________ - -// File struct represent file information for multipart request -type File struct { - Name string - ParamName string - io.Reader -} - -// String returns string value of current file details -func (f *File) String() string { - return fmt.Sprintf("ParamName: %v; FileName: %v", f.ParamName, f.Name) -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// MultipartField struct -//_______________________________________________________________________ - -// MultipartField struct represent custom data part for multipart request -type MultipartField struct { - Param string - FileName string - ContentType string - io.Reader -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// Unexported package methods -//_______________________________________________________________________ - -func createClient(hc *http.Client) *Client { - if hc.Transport == nil { - hc.Transport = createTransport(nil) - } - - c := &Client{ // not setting lang default values - QueryParam: url.Values{}, - FormData: url.Values{}, - Header: http.Header{}, - Cookies: make([]*http.Cookie, 0), - RetryWaitTime: defaultWaitTime, - RetryMaxWaitTime: defaultMaxWaitTime, - PathParams: make(map[string]string), - JSONMarshal: json.Marshal, - JSONUnmarshal: json.Unmarshal, - XMLMarshal: xml.Marshal, - XMLUnmarshal: xml.Unmarshal, - HeaderAuthorizationKey: http.CanonicalHeaderKey("Authorization"), - - jsonEscapeHTML: true, - httpClient: hc, - debugBodySizeLimit: math.MaxInt32, - } - - // Logger - c.SetLogger(createLogger()) - - // default before request middlewares - c.beforeRequest = []RequestMiddleware{ - parseRequestURL, - parseRequestHeader, - parseRequestBody, - createHTTPRequest, - addCredentials, - } - - // user defined request middlewares - c.udBeforeRequest = []RequestMiddleware{} - - // default after response middlewares - c.afterResponse = []ResponseMiddleware{ - responseLogger, - parseResponseBody, - saveResponseIntoFile, - } - - return c -} diff --git a/vendor/github.com/go-resty/resty/v2/middleware.go b/vendor/github.com/go-resty/resty/v2/middleware.go deleted file mode 100644 index 0e8ac2b6..00000000 --- a/vendor/github.com/go-resty/resty/v2/middleware.go +++ /dev/null @@ -1,543 +0,0 @@ -// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved. -// resty source code and usage is governed by a MIT style -// license that can be found in the LICENSE file. - -package resty - -import ( - "bytes" - "errors" - "fmt" - "io" - "io/ioutil" - "mime/multipart" - "net/http" - "net/url" - "os" - "path/filepath" - "reflect" - "strings" - "time" -) - -const debugRequestLogKey = "__restyDebugRequestLog" - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// Request Middleware(s) -//_______________________________________________________________________ - -func parseRequestURL(c *Client, r *Request) error { - // GitHub #103 Path Params - if len(r.PathParams) > 0 { - for p, v := range r.PathParams { - r.URL = strings.Replace(r.URL, "{"+p+"}", url.PathEscape(v), -1) - } - } - if len(c.PathParams) > 0 { - for p, v := range c.PathParams { - r.URL = strings.Replace(r.URL, "{"+p+"}", url.PathEscape(v), -1) - } - } - - // Parsing request URL - reqURL, err := url.Parse(r.URL) - if err != nil { - return err - } - - // If Request.URL is relative path then added c.HostURL into - // the request URL otherwise Request.URL will be used as-is - if !reqURL.IsAbs() { - r.URL = reqURL.String() - if len(r.URL) > 0 && r.URL[0] != '/' { - r.URL = "/" + r.URL - } - - reqURL, err = url.Parse(c.HostURL + r.URL) - if err != nil { - return err - } - } - - // GH #407 && #318 - if reqURL.Scheme == "" && len(c.scheme) > 0 { - reqURL.Scheme = c.scheme - } - - // Adding Query Param - query := make(url.Values) - for k, v := range c.QueryParam { - for _, iv := range v { - query.Add(k, iv) - } - } - - for k, v := range r.QueryParam { - // remove query param from client level by key - // since overrides happens for that key in the request - query.Del(k) - - for _, iv := range v { - query.Add(k, iv) - } - } - - // GitHub #123 Preserve query string order partially. - // Since not feasible in `SetQuery*` resty methods, because - // standard package `url.Encode(...)` sorts the query params - // alphabetically - if len(query) > 0 { - if IsStringEmpty(reqURL.RawQuery) { - reqURL.RawQuery = query.Encode() - } else { - reqURL.RawQuery = reqURL.RawQuery + "&" + query.Encode() - } - } - - r.URL = reqURL.String() - - return nil -} - -func parseRequestHeader(c *Client, r *Request) error { - hdr := make(http.Header) - for k := range c.Header { - hdr[k] = append(hdr[k], c.Header[k]...) - } - - for k := range r.Header { - hdr.Del(k) - hdr[k] = append(hdr[k], r.Header[k]...) - } - - if IsStringEmpty(hdr.Get(hdrUserAgentKey)) { - hdr.Set(hdrUserAgentKey, hdrUserAgentValue) - } - - ct := hdr.Get(hdrContentTypeKey) - if IsStringEmpty(hdr.Get(hdrAcceptKey)) && !IsStringEmpty(ct) && - (IsJSONType(ct) || IsXMLType(ct)) { - hdr.Set(hdrAcceptKey, hdr.Get(hdrContentTypeKey)) - } - - r.Header = hdr - - return nil -} - -func parseRequestBody(c *Client, r *Request) (err error) { - if isPayloadSupported(r.Method, c.AllowGetMethodPayload) { - // Handling Multipart - if r.isMultiPart && !(r.Method == MethodPatch) { - if err = handleMultipart(c, r); err != nil { - return - } - - goto CL - } - - // Handling Form Data - if len(c.FormData) > 0 || len(r.FormData) > 0 { - handleFormData(c, r) - - goto CL - } - - // Handling Request body - if r.Body != nil { - handleContentType(c, r) - - if err = handleRequestBody(c, r); err != nil { - return - } - } - } - -CL: - // by default resty won't set content length, you can if you want to :) - if (c.setContentLength || r.setContentLength) && r.bodyBuf != nil { - r.Header.Set(hdrContentLengthKey, fmt.Sprintf("%d", r.bodyBuf.Len())) - } - - return -} - -func createHTTPRequest(c *Client, r *Request) (err error) { - if r.bodyBuf == nil { - if reader, ok := r.Body.(io.Reader); ok { - r.RawRequest, err = http.NewRequest(r.Method, r.URL, reader) - } else if c.setContentLength || r.setContentLength { - r.RawRequest, err = http.NewRequest(r.Method, r.URL, http.NoBody) - } else { - r.RawRequest, err = http.NewRequest(r.Method, r.URL, nil) - } - } else { - r.RawRequest, err = http.NewRequest(r.Method, r.URL, r.bodyBuf) - } - - if err != nil { - return - } - - // Assign close connection option - r.RawRequest.Close = c.closeConnection - - // Add headers into http request - r.RawRequest.Header = r.Header - - // Add cookies from client instance into http request - for _, cookie := range c.Cookies { - r.RawRequest.AddCookie(cookie) - } - - // Add cookies from request instance into http request - for _, cookie := range r.Cookies { - r.RawRequest.AddCookie(cookie) - } - - // Enable trace - if c.trace || r.trace { - r.clientTrace = &clientTrace{} - r.ctx = r.clientTrace.createContext(r.Context()) - } - - // Use context if it was specified - if r.ctx != nil { - r.RawRequest = r.RawRequest.WithContext(r.ctx) - } - - bodyCopy, err := getBodyCopy(r) - if err != nil { - return err - } - - // assign get body func for the underlying raw request instance - r.RawRequest.GetBody = func() (io.ReadCloser, error) { - if bodyCopy != nil { - return ioutil.NopCloser(bytes.NewReader(bodyCopy.Bytes())), nil - } - return nil, nil - } - - return -} - -func addCredentials(c *Client, r *Request) error { - var isBasicAuth bool - // Basic Auth - if r.UserInfo != nil { // takes precedence - r.RawRequest.SetBasicAuth(r.UserInfo.Username, r.UserInfo.Password) - isBasicAuth = true - } else if c.UserInfo != nil { - r.RawRequest.SetBasicAuth(c.UserInfo.Username, c.UserInfo.Password) - isBasicAuth = true - } - - if !c.DisableWarn { - if isBasicAuth && !strings.HasPrefix(r.URL, "https") { - c.log.Warnf("Using Basic Auth in HTTP mode is not secure, use HTTPS") - } - } - - // Set the Authorization Header Scheme - var authScheme string - if !IsStringEmpty(r.AuthScheme) { - authScheme = r.AuthScheme - } else if !IsStringEmpty(c.AuthScheme) { - authScheme = c.AuthScheme - } else { - authScheme = "Bearer" - } - - // Build the Token Auth header - if !IsStringEmpty(r.Token) { // takes precedence - r.RawRequest.Header.Set(c.HeaderAuthorizationKey, authScheme+" "+r.Token) - } else if !IsStringEmpty(c.Token) { - r.RawRequest.Header.Set(c.HeaderAuthorizationKey, authScheme+" "+c.Token) - } - - return nil -} - -func requestLogger(c *Client, r *Request) error { - if c.Debug { - rr := r.RawRequest - rl := &RequestLog{Header: copyHeaders(rr.Header), Body: r.fmtBodyString(c.debugBodySizeLimit)} - if c.requestLog != nil { - if err := c.requestLog(rl); err != nil { - return err - } - } - // fmt.Sprintf("COOKIES:\n%s\n", composeCookies(c.GetClient().Jar, *rr.URL)) + - - reqLog := "\n==============================================================================\n" + - "~~~ REQUEST ~~~\n" + - fmt.Sprintf("%s %s %s\n", r.Method, rr.URL.RequestURI(), rr.Proto) + - fmt.Sprintf("HOST : %s\n", rr.URL.Host) + - fmt.Sprintf("HEADERS:\n%s\n", composeHeaders(c, r, rl.Header)) + - fmt.Sprintf("BODY :\n%v\n", rl.Body) + - "------------------------------------------------------------------------------\n" - - r.initValuesMap() - r.values[debugRequestLogKey] = reqLog - } - - return nil -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// Response Middleware(s) -//_______________________________________________________________________ - -func responseLogger(c *Client, res *Response) error { - if c.Debug { - rl := &ResponseLog{Header: copyHeaders(res.Header()), Body: res.fmtBodyString(c.debugBodySizeLimit)} - if c.responseLog != nil { - if err := c.responseLog(rl); err != nil { - return err - } - } - - debugLog := res.Request.values[debugRequestLogKey].(string) - debugLog += "~~~ RESPONSE ~~~\n" + - fmt.Sprintf("STATUS : %s\n", res.Status()) + - fmt.Sprintf("PROTO : %s\n", res.RawResponse.Proto) + - fmt.Sprintf("RECEIVED AT : %v\n", res.ReceivedAt().Format(time.RFC3339Nano)) + - fmt.Sprintf("TIME DURATION: %v\n", res.Time()) + - "HEADERS :\n" + - composeHeaders(c, res.Request, rl.Header) + "\n" - if res.Request.isSaveResponse { - debugLog += "BODY :\n***** RESPONSE WRITTEN INTO FILE *****\n" - } else { - debugLog += fmt.Sprintf("BODY :\n%v\n", rl.Body) - } - debugLog += "==============================================================================\n" - - c.log.Debugf("%s", debugLog) - } - - return nil -} - -func parseResponseBody(c *Client, res *Response) (err error) { - if res.StatusCode() == http.StatusNoContent { - return - } - // Handles only JSON or XML content type - ct := firstNonEmpty(res.Request.forceContentType, res.Header().Get(hdrContentTypeKey), res.Request.fallbackContentType) - if IsJSONType(ct) || IsXMLType(ct) { - // HTTP status code > 199 and < 300, considered as Result - if res.IsSuccess() { - res.Request.Error = nil - if res.Request.Result != nil { - err = Unmarshalc(c, ct, res.body, res.Request.Result) - return - } - } - - // HTTP status code > 399, considered as Error - if res.IsError() { - // global error interface - if res.Request.Error == nil && c.Error != nil { - res.Request.Error = reflect.New(c.Error).Interface() - } - - if res.Request.Error != nil { - err = Unmarshalc(c, ct, res.body, res.Request.Error) - } - } - } - - return -} - -func handleMultipart(c *Client, r *Request) (err error) { - r.bodyBuf = acquireBuffer() - w := multipart.NewWriter(r.bodyBuf) - - for k, v := range c.FormData { - for _, iv := range v { - if err = w.WriteField(k, iv); err != nil { - return err - } - } - } - - for k, v := range r.FormData { - for _, iv := range v { - if strings.HasPrefix(k, "@") { // file - err = addFile(w, k[1:], iv) - if err != nil { - return - } - } else { // form value - if err = w.WriteField(k, iv); err != nil { - return err - } - } - } - } - - // #21 - adding io.Reader support - if len(r.multipartFiles) > 0 { - for _, f := range r.multipartFiles { - err = addFileReader(w, f) - if err != nil { - return - } - } - } - - // GitHub #130 adding multipart field support with content type - if len(r.multipartFields) > 0 { - for _, mf := range r.multipartFields { - if err = addMultipartFormField(w, mf); err != nil { - return - } - } - } - - r.Header.Set(hdrContentTypeKey, w.FormDataContentType()) - err = w.Close() - - return -} - -func handleFormData(c *Client, r *Request) { - formData := url.Values{} - - for k, v := range c.FormData { - for _, iv := range v { - formData.Add(k, iv) - } - } - - for k, v := range r.FormData { - // remove form data field from client level by key - // since overrides happens for that key in the request - formData.Del(k) - - for _, iv := range v { - formData.Add(k, iv) - } - } - - r.bodyBuf = bytes.NewBuffer([]byte(formData.Encode())) - r.Header.Set(hdrContentTypeKey, formContentType) - r.isFormData = true -} - -func handleContentType(c *Client, r *Request) { - contentType := r.Header.Get(hdrContentTypeKey) - if IsStringEmpty(contentType) { - contentType = DetectContentType(r.Body) - r.Header.Set(hdrContentTypeKey, contentType) - } -} - -func handleRequestBody(c *Client, r *Request) (err error) { - var bodyBytes []byte - contentType := r.Header.Get(hdrContentTypeKey) - kind := kindOf(r.Body) - r.bodyBuf = nil - - if reader, ok := r.Body.(io.Reader); ok { - if c.setContentLength || r.setContentLength { // keep backward compatibility - r.bodyBuf = acquireBuffer() - _, err = r.bodyBuf.ReadFrom(reader) - r.Body = nil - } else { - // Otherwise buffer less processing for `io.Reader`, sounds good. - return - } - } else if b, ok := r.Body.([]byte); ok { - bodyBytes = b - } else if s, ok := r.Body.(string); ok { - bodyBytes = []byte(s) - } else if IsJSONType(contentType) && - (kind == reflect.Struct || kind == reflect.Map || kind == reflect.Slice) { - r.bodyBuf, err = jsonMarshal(c, r, r.Body) - if err != nil { - return - } - } else if IsXMLType(contentType) && (kind == reflect.Struct) { - bodyBytes, err = c.XMLMarshal(r.Body) - if err != nil { - return - } - } - - if bodyBytes == nil && r.bodyBuf == nil { - err = errors.New("unsupported 'Body' type/value") - } - - // if any errors during body bytes handling, return it - if err != nil { - return - } - - // []byte into Buffer - if bodyBytes != nil && r.bodyBuf == nil { - r.bodyBuf = acquireBuffer() - _, _ = r.bodyBuf.Write(bodyBytes) - } - - return -} - -func saveResponseIntoFile(c *Client, res *Response) error { - if res.Request.isSaveResponse { - file := "" - - if len(c.outputDirectory) > 0 && !filepath.IsAbs(res.Request.outputFile) { - file += c.outputDirectory + string(filepath.Separator) - } - - file = filepath.Clean(file + res.Request.outputFile) - if err := createDirectory(filepath.Dir(file)); err != nil { - return err - } - - outFile, err := os.Create(file) - if err != nil { - return err - } - defer closeq(outFile) - - // io.Copy reads maximum 32kb size, it is perfect for large file download too - defer closeq(res.RawResponse.Body) - - written, err := io.Copy(outFile, res.RawResponse.Body) - if err != nil { - return err - } - - res.size = written - } - - return nil -} - -func getBodyCopy(r *Request) (*bytes.Buffer, error) { - // If r.bodyBuf present, return the copy - if r.bodyBuf != nil { - return bytes.NewBuffer(r.bodyBuf.Bytes()), nil - } - - // Maybe body is `io.Reader`. - // Note: Resty user have to watchout for large body size of `io.Reader` - if r.RawRequest.Body != nil { - b, err := ioutil.ReadAll(r.RawRequest.Body) - if err != nil { - return nil, err - } - - // Restore the Body - closeq(r.RawRequest.Body) - r.RawRequest.Body = ioutil.NopCloser(bytes.NewBuffer(b)) - - // Return the Body bytes - return bytes.NewBuffer(b), nil - } - return nil, nil -} diff --git a/vendor/github.com/go-resty/resty/v2/redirect.go b/vendor/github.com/go-resty/resty/v2/redirect.go deleted file mode 100644 index 7d7e43bc..00000000 --- a/vendor/github.com/go-resty/resty/v2/redirect.go +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved. -// resty source code and usage is governed by a MIT style -// license that can be found in the LICENSE file. - -package resty - -import ( - "errors" - "fmt" - "net" - "net/http" - "strings" -) - -type ( - // RedirectPolicy to regulate the redirects in the resty client. - // Objects implementing the RedirectPolicy interface can be registered as - // - // Apply function should return nil to continue the redirect jounery, otherwise - // return error to stop the redirect. - RedirectPolicy interface { - Apply(req *http.Request, via []*http.Request) error - } - - // The RedirectPolicyFunc type is an adapter to allow the use of ordinary functions as RedirectPolicy. - // If f is a function with the appropriate signature, RedirectPolicyFunc(f) is a RedirectPolicy object that calls f. - RedirectPolicyFunc func(*http.Request, []*http.Request) error -) - -// Apply calls f(req, via). -func (f RedirectPolicyFunc) Apply(req *http.Request, via []*http.Request) error { - return f(req, via) -} - -// NoRedirectPolicy is used to disable redirects in the HTTP client -// resty.SetRedirectPolicy(NoRedirectPolicy()) -func NoRedirectPolicy() RedirectPolicy { - return RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error { - return errors.New("auto redirect is disabled") - }) -} - -// FlexibleRedirectPolicy is convenient method to create No of redirect policy for HTTP client. -// resty.SetRedirectPolicy(FlexibleRedirectPolicy(20)) -func FlexibleRedirectPolicy(noOfRedirect int) RedirectPolicy { - return RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error { - if len(via) >= noOfRedirect { - return fmt.Errorf("stopped after %d redirects", noOfRedirect) - } - checkHostAndAddHeaders(req, via[0]) - return nil - }) -} - -// DomainCheckRedirectPolicy is convenient method to define domain name redirect rule in resty client. -// Redirect is allowed for only mentioned host in the policy. -// resty.SetRedirectPolicy(DomainCheckRedirectPolicy("host1.com", "host2.org", "host3.net")) -func DomainCheckRedirectPolicy(hostnames ...string) RedirectPolicy { - hosts := make(map[string]bool) - for _, h := range hostnames { - hosts[strings.ToLower(h)] = true - } - - fn := RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error { - if ok := hosts[getHostname(req.URL.Host)]; !ok { - return errors.New("redirect is not allowed as per DomainCheckRedirectPolicy") - } - - return nil - }) - - return fn -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// Package Unexported methods -//_______________________________________________________________________ - -func getHostname(host string) (hostname string) { - if strings.Index(host, ":") > 0 { - host, _, _ = net.SplitHostPort(host) - } - hostname = strings.ToLower(host) - return -} - -// By default Golang will not redirect request headers -// after go throughing various discussion comments from thread -// https://github.com/golang/go/issues/4800 -// Resty will add all the headers during a redirect for the same host -func checkHostAndAddHeaders(cur *http.Request, pre *http.Request) { - curHostname := getHostname(cur.URL.Host) - preHostname := getHostname(pre.URL.Host) - if strings.EqualFold(curHostname, preHostname) { - for key, val := range pre.Header { - cur.Header[key] = val - } - } else { // only library User-Agent header is added - cur.Header.Set(hdrUserAgentKey, hdrUserAgentValue) - } -} diff --git a/vendor/github.com/go-resty/resty/v2/request.go b/vendor/github.com/go-resty/resty/v2/request.go deleted file mode 100644 index 672df88c..00000000 --- a/vendor/github.com/go-resty/resty/v2/request.go +++ /dev/null @@ -1,896 +0,0 @@ -// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved. -// resty source code and usage is governed by a MIT style -// license that can be found in the LICENSE file. - -package resty - -import ( - "bytes" - "context" - "encoding/json" - "encoding/xml" - "fmt" - "io" - "net" - "net/http" - "net/url" - "reflect" - "strings" - "time" -) - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// Request struct and methods -//_______________________________________________________________________ - -// Request struct is used to compose and fire individual request from -// resty client. Request provides an options to override client level -// settings and also an options for the request composition. -type Request struct { - URL string - Method string - Token string - AuthScheme string - QueryParam url.Values - FormData url.Values - PathParams map[string]string - Header http.Header - Time time.Time - Body interface{} - Result interface{} - Error interface{} - RawRequest *http.Request - SRV *SRVRecord - UserInfo *User - Cookies []*http.Cookie - - // Attempt is to represent the request attempt made during a Resty - // request execution flow, including retry count. - // - // Since v2.4.0 - Attempt int - - isMultiPart bool - isFormData bool - setContentLength bool - isSaveResponse bool - notParseResponse bool - jsonEscapeHTML bool - trace bool - outputFile string - fallbackContentType string - forceContentType string - ctx context.Context - values map[string]interface{} - client *Client - bodyBuf *bytes.Buffer - clientTrace *clientTrace - multipartFiles []*File - multipartFields []*MultipartField - retryConditions []RetryConditionFunc -} - -// Context method returns the Context if its already set in request -// otherwise it creates new one using `context.Background()`. -func (r *Request) Context() context.Context { - if r.ctx == nil { - return context.Background() - } - return r.ctx -} - -// SetContext method sets the context.Context for current Request. It allows -// to interrupt the request execution if ctx.Done() channel is closed. -// See https://blog.golang.org/context article and the "context" package -// documentation. -func (r *Request) SetContext(ctx context.Context) *Request { - r.ctx = ctx - return r -} - -// SetHeader method is to set a single header field and its value in the current request. -// -// For Example: To set `Content-Type` and `Accept` as `application/json`. -// client.R(). -// SetHeader("Content-Type", "application/json"). -// SetHeader("Accept", "application/json") -// -// Also you can override header value, which was set at client instance level. -func (r *Request) SetHeader(header, value string) *Request { - r.Header.Set(header, value) - return r -} - -// SetHeaders method sets multiple headers field and its values at one go in the current request. -// -// For Example: To set `Content-Type` and `Accept` as `application/json` -// -// client.R(). -// SetHeaders(map[string]string{ -// "Content-Type": "application/json", -// "Accept": "application/json", -// }) -// Also you can override header value, which was set at client instance level. -func (r *Request) SetHeaders(headers map[string]string) *Request { - for h, v := range headers { - r.SetHeader(h, v) - } - return r -} - -// SetHeaderMultiValues sets multiple headers fields and its values is list of strings at one go in the current request. -// -// For Example: To set `Accept` as `text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8` -// -// client.R(). -// SetHeaderMultiValues(map[string][]string{ -// "Accept": []string{"text/html", "application/xhtml+xml", "application/xml;q=0.9", "image/webp", "*/*;q=0.8"}, -// }) -// Also you can override header value, which was set at client instance level. -func (r *Request) SetHeaderMultiValues(headers map[string][]string) *Request { - for key, values := range headers { - r.SetHeader(key, strings.Join(values, ", ")) - } - return r -} - -// SetHeaderVerbatim method is to set a single header field and its value verbatim in the current request. -// -// For Example: To set `all_lowercase` and `UPPERCASE` as `available`. -// client.R(). -// SetHeaderVerbatim("all_lowercase", "available"). -// SetHeaderVerbatim("UPPERCASE", "available") -// -// Also you can override header value, which was set at client instance level. -// -// Since v2.6.0 -func (r *Request) SetHeaderVerbatim(header, value string) *Request { - r.Header[header] = []string{value} - return r -} - -// SetQueryParam method sets single parameter and its value in the current request. -// It will be formed as query string for the request. -// -// For Example: `search=kitchen%20papers&size=large` in the URL after `?` mark. -// client.R(). -// SetQueryParam("search", "kitchen papers"). -// SetQueryParam("size", "large") -// Also you can override query params value, which was set at client instance level. -func (r *Request) SetQueryParam(param, value string) *Request { - r.QueryParam.Set(param, value) - return r -} - -// SetQueryParams method sets multiple parameters and its values at one go in the current request. -// It will be formed as query string for the request. -// -// For Example: `search=kitchen%20papers&size=large` in the URL after `?` mark. -// client.R(). -// SetQueryParams(map[string]string{ -// "search": "kitchen papers", -// "size": "large", -// }) -// Also you can override query params value, which was set at client instance level. -func (r *Request) SetQueryParams(params map[string]string) *Request { - for p, v := range params { - r.SetQueryParam(p, v) - } - return r -} - -// SetQueryParamsFromValues method appends multiple parameters with multi-value -// (`url.Values`) at one go in the current request. It will be formed as -// query string for the request. -// -// For Example: `status=pending&status=approved&status=open` in the URL after `?` mark. -// client.R(). -// SetQueryParamsFromValues(url.Values{ -// "status": []string{"pending", "approved", "open"}, -// }) -// Also you can override query params value, which was set at client instance level. -func (r *Request) SetQueryParamsFromValues(params url.Values) *Request { - for p, v := range params { - for _, pv := range v { - r.QueryParam.Add(p, pv) - } - } - return r -} - -// SetQueryString method provides ability to use string as an input to set URL query string for the request. -// -// Using String as an input -// client.R(). -// SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more") -func (r *Request) SetQueryString(query string) *Request { - params, err := url.ParseQuery(strings.TrimSpace(query)) - if err == nil { - for p, v := range params { - for _, pv := range v { - r.QueryParam.Add(p, pv) - } - } - } else { - r.client.log.Errorf("%v", err) - } - return r -} - -// SetFormData method sets Form parameters and their values in the current request. -// It's applicable only HTTP method `POST` and `PUT` and requests content type would be set as -// `application/x-www-form-urlencoded`. -// client.R(). -// SetFormData(map[string]string{ -// "access_token": "BC594900-518B-4F7E-AC75-BD37F019E08F", -// "user_id": "3455454545", -// }) -// Also you can override form data value, which was set at client instance level. -func (r *Request) SetFormData(data map[string]string) *Request { - for k, v := range data { - r.FormData.Set(k, v) - } - return r -} - -// SetFormDataFromValues method appends multiple form parameters with multi-value -// (`url.Values`) at one go in the current request. -// client.R(). -// SetFormDataFromValues(url.Values{ -// "search_criteria": []string{"book", "glass", "pencil"}, -// }) -// Also you can override form data value, which was set at client instance level. -func (r *Request) SetFormDataFromValues(data url.Values) *Request { - for k, v := range data { - for _, kv := range v { - r.FormData.Add(k, kv) - } - } - return r -} - -// SetBody method sets the request body for the request. It supports various realtime needs as easy. -// We can say its quite handy or powerful. Supported request body data types is `string`, -// `[]byte`, `struct`, `map`, `slice` and `io.Reader`. Body value can be pointer or non-pointer. -// Automatic marshalling for JSON and XML content type, if it is `struct`, `map`, or `slice`. -// -// Note: `io.Reader` is processed as bufferless mode while sending request. -// -// For Example: Struct as a body input, based on content type, it will be marshalled. -// client.R(). -// SetBody(User{ -// Username: "jeeva@myjeeva.com", -// Password: "welcome2resty", -// }) -// -// Map as a body input, based on content type, it will be marshalled. -// client.R(). -// SetBody(map[string]interface{}{ -// "username": "jeeva@myjeeva.com", -// "password": "welcome2resty", -// "address": &Address{ -// Address1: "1111 This is my street", -// Address2: "Apt 201", -// City: "My City", -// State: "My State", -// ZipCode: 00000, -// }, -// }) -// -// String as a body input. Suitable for any need as a string input. -// client.R(). -// SetBody(`{ -// "username": "jeeva@getrightcare.com", -// "password": "admin" -// }`) -// -// []byte as a body input. Suitable for raw request such as file upload, serialize & deserialize, etc. -// client.R(). -// SetBody([]byte("This is my raw request, sent as-is")) -func (r *Request) SetBody(body interface{}) *Request { - r.Body = body - return r -} - -// SetResult method is to register the response `Result` object for automatic unmarshalling for the request, -// if response status code is between 200 and 299 and content type either JSON or XML. -// -// Note: Result object can be pointer or non-pointer. -// client.R().SetResult(&AuthToken{}) -// // OR -// client.R().SetResult(AuthToken{}) -// -// Accessing a result value from response instance. -// response.Result().(*AuthToken) -func (r *Request) SetResult(res interface{}) *Request { - r.Result = getPointer(res) - return r -} - -// SetError method is to register the request `Error` object for automatic unmarshalling for the request, -// if response status code is greater than 399 and content type either JSON or XML. -// -// Note: Error object can be pointer or non-pointer. -// client.R().SetError(&AuthError{}) -// // OR -// client.R().SetError(AuthError{}) -// -// Accessing a error value from response instance. -// response.Error().(*AuthError) -func (r *Request) SetError(err interface{}) *Request { - r.Error = getPointer(err) - return r -} - -// SetFile method is to set single file field name and its path for multipart upload. -// client.R(). -// SetFile("my_file", "/Users/jeeva/Gas Bill - Sep.pdf") -func (r *Request) SetFile(param, filePath string) *Request { - r.isMultiPart = true - r.FormData.Set("@"+param, filePath) - return r -} - -// SetFiles method is to set multiple file field name and its path for multipart upload. -// client.R(). -// SetFiles(map[string]string{ -// "my_file1": "/Users/jeeva/Gas Bill - Sep.pdf", -// "my_file2": "/Users/jeeva/Electricity Bill - Sep.pdf", -// "my_file3": "/Users/jeeva/Water Bill - Sep.pdf", -// }) -func (r *Request) SetFiles(files map[string]string) *Request { - r.isMultiPart = true - for f, fp := range files { - r.FormData.Set("@"+f, fp) - } - return r -} - -// SetFileReader method is to set single file using io.Reader for multipart upload. -// client.R(). -// SetFileReader("profile_img", "my-profile-img.png", bytes.NewReader(profileImgBytes)). -// SetFileReader("notes", "user-notes.txt", bytes.NewReader(notesBytes)) -func (r *Request) SetFileReader(param, fileName string, reader io.Reader) *Request { - r.isMultiPart = true - r.multipartFiles = append(r.multipartFiles, &File{ - Name: fileName, - ParamName: param, - Reader: reader, - }) - return r -} - -// SetMultipartFormData method allows simple form data to be attached to the request as `multipart:form-data` -func (r *Request) SetMultipartFormData(data map[string]string) *Request { - for k, v := range data { - r = r.SetMultipartField(k, "", "", strings.NewReader(v)) - } - - return r -} - -// SetMultipartField method is to set custom data using io.Reader for multipart upload. -func (r *Request) SetMultipartField(param, fileName, contentType string, reader io.Reader) *Request { - r.isMultiPart = true - r.multipartFields = append(r.multipartFields, &MultipartField{ - Param: param, - FileName: fileName, - ContentType: contentType, - Reader: reader, - }) - return r -} - -// SetMultipartFields method is to set multiple data fields using io.Reader for multipart upload. -// -// For Example: -// client.R().SetMultipartFields( -// &resty.MultipartField{ -// Param: "uploadManifest1", -// FileName: "upload-file-1.json", -// ContentType: "application/json", -// Reader: strings.NewReader(`{"input": {"name": "Uploaded document 1", "_filename" : ["file1.txt"]}}`), -// }, -// &resty.MultipartField{ -// Param: "uploadManifest2", -// FileName: "upload-file-2.json", -// ContentType: "application/json", -// Reader: strings.NewReader(`{"input": {"name": "Uploaded document 2", "_filename" : ["file2.txt"]}}`), -// }) -// -// If you have slice already, then simply call- -// client.R().SetMultipartFields(fields...) -func (r *Request) SetMultipartFields(fields ...*MultipartField) *Request { - r.isMultiPart = true - r.multipartFields = append(r.multipartFields, fields...) - return r -} - -// SetContentLength method sets the HTTP header `Content-Length` value for current request. -// By default Resty won't set `Content-Length`. Also you have an option to enable for every -// request. -// -// See `Client.SetContentLength` -// client.R().SetContentLength(true) -func (r *Request) SetContentLength(l bool) *Request { - r.setContentLength = l - return r -} - -// SetBasicAuth method sets the basic authentication header in the current HTTP request. -// -// For Example: -// Authorization: Basic -// -// To set the header for username "go-resty" and password "welcome" -// client.R().SetBasicAuth("go-resty", "welcome") -// -// This method overrides the credentials set by method `Client.SetBasicAuth`. -func (r *Request) SetBasicAuth(username, password string) *Request { - r.UserInfo = &User{Username: username, Password: password} - return r -} - -// SetAuthToken method sets the auth token header(Default Scheme: Bearer) in the current HTTP request. Header example: -// Authorization: Bearer -// -// For Example: To set auth token BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F -// -// client.R().SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F") -// -// This method overrides the Auth token set by method `Client.SetAuthToken`. -func (r *Request) SetAuthToken(token string) *Request { - r.Token = token - return r -} - -// SetAuthScheme method sets the auth token scheme type in the HTTP request. For Example: -// Authorization: -// -// For Example: To set the scheme to use OAuth -// -// client.R().SetAuthScheme("OAuth") -// -// This auth header scheme gets added to all the request rasied from this client instance. -// Also it can be overridden or set one at the request level is supported. -// -// Information about Auth schemes can be found in RFC7235 which is linked to below along with the page containing -// the currently defined official authentication schemes: -// https://tools.ietf.org/html/rfc7235 -// https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml#authschemes -// -// This method overrides the Authorization scheme set by method `Client.SetAuthScheme`. -func (r *Request) SetAuthScheme(scheme string) *Request { - r.AuthScheme = scheme - return r -} - -// SetOutput method sets the output file for current HTTP request. Current HTTP response will be -// saved into given file. It is similar to `curl -o` flag. Absolute path or relative path can be used. -// If is it relative path then output file goes under the output directory, as mentioned -// in the `Client.SetOutputDirectory`. -// client.R(). -// SetOutput("/Users/jeeva/Downloads/ReplyWithHeader-v5.1-beta.zip"). -// Get("http://bit.ly/1LouEKr") -// -// Note: In this scenario `Response.Body` might be nil. -func (r *Request) SetOutput(file string) *Request { - r.outputFile = file - r.isSaveResponse = true - return r -} - -// SetSRV method sets the details to query the service SRV record and execute the -// request. -// client.R(). -// SetSRV(SRVRecord{"web", "testservice.com"}). -// Get("/get") -func (r *Request) SetSRV(srv *SRVRecord) *Request { - r.SRV = srv - return r -} - -// SetDoNotParseResponse method instructs `Resty` not to parse the response body automatically. -// Resty exposes the raw response body as `io.ReadCloser`. Also do not forget to close the body, -// otherwise you might get into connection leaks, no connection reuse. -// -// Note: Response middlewares are not applicable, if you use this option. Basically you have -// taken over the control of response parsing from `Resty`. -func (r *Request) SetDoNotParseResponse(parse bool) *Request { - r.notParseResponse = parse - return r -} - -// SetPathParam method sets single URL path key-value pair in the -// Resty current request instance. -// client.R().SetPathParam("userId", "sample@sample.com") -// -// Result: -// URL - /v1/users/{userId}/details -// Composed URL - /v1/users/sample@sample.com/details -// It replaces the value of the key while composing the request URL. Also you can -// override Path Params value, which was set at client instance level. -func (r *Request) SetPathParam(param, value string) *Request { - r.PathParams[param] = value - return r -} - -// SetPathParams method sets multiple URL path key-value pairs at one go in the -// Resty current request instance. -// client.R().SetPathParams(map[string]string{ -// "userId": "sample@sample.com", -// "subAccountId": "100002", -// }) -// -// Result: -// URL - /v1/users/{userId}/{subAccountId}/details -// Composed URL - /v1/users/sample@sample.com/100002/details -// It replaces the value of the key while composing request URL. Also you can -// override Path Params value, which was set at client instance level. -func (r *Request) SetPathParams(params map[string]string) *Request { - for p, v := range params { - r.SetPathParam(p, v) - } - return r -} - -// ExpectContentType method allows to provide fallback `Content-Type` for automatic unmarshalling -// when `Content-Type` response header is unavailable. -func (r *Request) ExpectContentType(contentType string) *Request { - r.fallbackContentType = contentType - return r -} - -// ForceContentType method provides a strong sense of response `Content-Type` for automatic unmarshalling. -// Resty gives this a higher priority than the `Content-Type` response header. This means that if both -// `Request.ForceContentType` is set and the response `Content-Type` is available, `ForceContentType` will win. -func (r *Request) ForceContentType(contentType string) *Request { - r.forceContentType = contentType - return r -} - -// SetJSONEscapeHTML method is to enable/disable the HTML escape on JSON marshal. -// -// Note: This option only applicable to standard JSON Marshaller. -func (r *Request) SetJSONEscapeHTML(b bool) *Request { - r.jsonEscapeHTML = b - return r -} - -// SetCookie method appends a single cookie in the current request instance. -// client.R().SetCookie(&http.Cookie{ -// Name:"go-resty", -// Value:"This is cookie value", -// }) -// -// Note: Method appends the Cookie value into existing Cookie if already existing. -// -// Since v2.1.0 -func (r *Request) SetCookie(hc *http.Cookie) *Request { - r.Cookies = append(r.Cookies, hc) - return r -} - -// SetCookies method sets an array of cookies in the current request instance. -// cookies := []*http.Cookie{ -// &http.Cookie{ -// Name:"go-resty-1", -// Value:"This is cookie 1 value", -// }, -// &http.Cookie{ -// Name:"go-resty-2", -// Value:"This is cookie 2 value", -// }, -// } -// -// // Setting a cookies into resty's current request -// client.R().SetCookies(cookies) -// -// Note: Method appends the Cookie value into existing Cookie if already existing. -// -// Since v2.1.0 -func (r *Request) SetCookies(rs []*http.Cookie) *Request { - r.Cookies = append(r.Cookies, rs...) - return r -} - -// AddRetryCondition method adds a retry condition function to the request's -// array of functions that are checked to determine if the request is retried. -// The request will retry if any of the functions return true and error is nil. -// -// Note: These retry conditions are checked before all retry conditions of the client. -// -// Since v2.7.0 -func (r *Request) AddRetryCondition(condition RetryConditionFunc) *Request { - r.retryConditions = append(r.retryConditions, condition) - return r -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// HTTP request tracing -//_______________________________________________________________________ - -// EnableTrace method enables trace for the current request -// using `httptrace.ClientTrace` and provides insights. -// -// client := resty.New() -// -// resp, err := client.R().EnableTrace().Get("https://httpbin.org/get") -// fmt.Println("Error:", err) -// fmt.Println("Trace Info:", resp.Request.TraceInfo()) -// -// See `Client.EnableTrace` available too to get trace info for all requests. -// -// Since v2.0.0 -func (r *Request) EnableTrace() *Request { - r.trace = true - return r -} - -// TraceInfo method returns the trace info for the request. -// If either the Client or Request EnableTrace function has not been called -// prior to the request being made, an empty TraceInfo object will be returned. -// -// Since v2.0.0 -func (r *Request) TraceInfo() TraceInfo { - ct := r.clientTrace - - if ct == nil { - return TraceInfo{} - } - - ti := TraceInfo{ - DNSLookup: ct.dnsDone.Sub(ct.dnsStart), - TLSHandshake: ct.tlsHandshakeDone.Sub(ct.tlsHandshakeStart), - ServerTime: ct.gotFirstResponseByte.Sub(ct.gotConn), - IsConnReused: ct.gotConnInfo.Reused, - IsConnWasIdle: ct.gotConnInfo.WasIdle, - ConnIdleTime: ct.gotConnInfo.IdleTime, - RequestAttempt: r.Attempt, - } - - // Calculate the total time accordingly, - // when connection is reused - if ct.gotConnInfo.Reused { - ti.TotalTime = ct.endTime.Sub(ct.getConn) - } else { - ti.TotalTime = ct.endTime.Sub(ct.dnsStart) - } - - // Only calculate on successful connections - if !ct.connectDone.IsZero() { - ti.TCPConnTime = ct.connectDone.Sub(ct.dnsDone) - } - - // Only calculate on successful connections - if !ct.gotConn.IsZero() { - ti.ConnTime = ct.gotConn.Sub(ct.getConn) - } - - // Only calculate on successful connections - if !ct.gotFirstResponseByte.IsZero() { - ti.ResponseTime = ct.endTime.Sub(ct.gotFirstResponseByte) - } - - // Capture remote address info when connection is non-nil - if ct.gotConnInfo.Conn != nil { - ti.RemoteAddr = ct.gotConnInfo.Conn.RemoteAddr() - } - - return ti -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// HTTP verb method starts here -//_______________________________________________________________________ - -// Get method does GET HTTP request. It's defined in section 4.3.1 of RFC7231. -func (r *Request) Get(url string) (*Response, error) { - return r.Execute(MethodGet, url) -} - -// Head method does HEAD HTTP request. It's defined in section 4.3.2 of RFC7231. -func (r *Request) Head(url string) (*Response, error) { - return r.Execute(MethodHead, url) -} - -// Post method does POST HTTP request. It's defined in section 4.3.3 of RFC7231. -func (r *Request) Post(url string) (*Response, error) { - return r.Execute(MethodPost, url) -} - -// Put method does PUT HTTP request. It's defined in section 4.3.4 of RFC7231. -func (r *Request) Put(url string) (*Response, error) { - return r.Execute(MethodPut, url) -} - -// Delete method does DELETE HTTP request. It's defined in section 4.3.5 of RFC7231. -func (r *Request) Delete(url string) (*Response, error) { - return r.Execute(MethodDelete, url) -} - -// Options method does OPTIONS HTTP request. It's defined in section 4.3.7 of RFC7231. -func (r *Request) Options(url string) (*Response, error) { - return r.Execute(MethodOptions, url) -} - -// Patch method does PATCH HTTP request. It's defined in section 2 of RFC5789. -func (r *Request) Patch(url string) (*Response, error) { - return r.Execute(MethodPatch, url) -} - -// Send method performs the HTTP request using the method and URL already defined -// for current `Request`. -// req := client.R() -// req.Method = resty.GET -// req.URL = "http://httpbin.org/get" -// resp, err := client.R().Send() -func (r *Request) Send() (*Response, error) { - return r.Execute(r.Method, r.URL) -} - -// Execute method performs the HTTP request with given HTTP method and URL -// for current `Request`. -// resp, err := client.R().Execute(resty.GET, "http://httpbin.org/get") -func (r *Request) Execute(method, url string) (*Response, error) { - var addrs []*net.SRV - var resp *Response - var err error - - if r.isMultiPart && !(method == MethodPost || method == MethodPut || method == MethodPatch) { - // No OnError hook here since this is a request validation error - return nil, fmt.Errorf("multipart content is not allowed in HTTP verb [%v]", method) - } - - if r.SRV != nil { - _, addrs, err = net.LookupSRV(r.SRV.Service, "tcp", r.SRV.Domain) - if err != nil { - r.client.onErrorHooks(r, nil, err) - return nil, err - } - } - - r.Method = method - r.URL = r.selectAddr(addrs, url, 0) - - if r.client.RetryCount == 0 { - r.Attempt = 1 - resp, err = r.client.execute(r) - r.client.onErrorHooks(r, resp, unwrapNoRetryErr(err)) - return resp, unwrapNoRetryErr(err) - } - - err = Backoff( - func() (*Response, error) { - r.Attempt++ - - r.URL = r.selectAddr(addrs, url, r.Attempt) - - resp, err = r.client.execute(r) - if err != nil { - r.client.log.Errorf("%v, Attempt %v", err, r.Attempt) - } - - return resp, err - }, - Retries(r.client.RetryCount), - WaitTime(r.client.RetryWaitTime), - MaxWaitTime(r.client.RetryMaxWaitTime), - RetryConditions(append(r.retryConditions, r.client.RetryConditions...)), - RetryHooks(r.client.RetryHooks), - ) - - r.client.onErrorHooks(r, resp, unwrapNoRetryErr(err)) - - return resp, unwrapNoRetryErr(err) -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// SRVRecord struct -//_______________________________________________________________________ - -// SRVRecord struct holds the data to query the SRV record for the -// following service. -type SRVRecord struct { - Service string - Domain string -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// Request Unexported methods -//_______________________________________________________________________ - -func (r *Request) fmtBodyString(sl int64) (body string) { - body = "***** NO CONTENT *****" - if !isPayloadSupported(r.Method, r.client.AllowGetMethodPayload) { - return - } - - if _, ok := r.Body.(io.Reader); ok { - body = "***** BODY IS io.Reader *****" - return - } - - // multipart or form-data - if r.isMultiPart || r.isFormData { - bodySize := int64(r.bodyBuf.Len()) - if bodySize > sl { - body = fmt.Sprintf("***** REQUEST TOO LARGE (size - %d) *****", bodySize) - return - } - body = r.bodyBuf.String() - return - } - - // request body data - if r.Body == nil { - return - } - var prtBodyBytes []byte - var err error - - contentType := r.Header.Get(hdrContentTypeKey) - kind := kindOf(r.Body) - if canJSONMarshal(contentType, kind) { - prtBodyBytes, err = json.MarshalIndent(&r.Body, "", " ") - } else if IsXMLType(contentType) && (kind == reflect.Struct) { - prtBodyBytes, err = xml.MarshalIndent(&r.Body, "", " ") - } else if b, ok := r.Body.(string); ok { - if IsJSONType(contentType) { - bodyBytes := []byte(b) - out := acquireBuffer() - defer releaseBuffer(out) - if err = json.Indent(out, bodyBytes, "", " "); err == nil { - prtBodyBytes = out.Bytes() - } - } else { - body = b - } - } else if b, ok := r.Body.([]byte); ok { - body = fmt.Sprintf("***** BODY IS byte(s) (size - %d) *****", len(b)) - return - } - - if prtBodyBytes != nil && err == nil { - body = string(prtBodyBytes) - } - - if len(body) > 0 { - bodySize := int64(len([]byte(body))) - if bodySize > sl { - body = fmt.Sprintf("***** REQUEST TOO LARGE (size - %d) *****", bodySize) - } - } - - return -} - -func (r *Request) selectAddr(addrs []*net.SRV, path string, attempt int) string { - if addrs == nil { - return path - } - - idx := attempt % len(addrs) - domain := strings.TrimRight(addrs[idx].Target, ".") - path = strings.TrimLeft(path, "/") - - return fmt.Sprintf("%s://%s:%d/%s", r.client.scheme, domain, addrs[idx].Port, path) -} - -func (r *Request) initValuesMap() { - if r.values == nil { - r.values = make(map[string]interface{}) - } -} - -var noescapeJSONMarshal = func(v interface{}) (*bytes.Buffer, error) { - buf := acquireBuffer() - encoder := json.NewEncoder(buf) - encoder.SetEscapeHTML(false) - if err := encoder.Encode(v); err != nil { - releaseBuffer(buf) - return nil, err - } - - return buf, nil -} diff --git a/vendor/github.com/go-resty/resty/v2/response.go b/vendor/github.com/go-resty/resty/v2/response.go deleted file mode 100644 index 8ae0e10b..00000000 --- a/vendor/github.com/go-resty/resty/v2/response.go +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved. -// resty source code and usage is governed by a MIT style -// license that can be found in the LICENSE file. - -package resty - -import ( - "encoding/json" - "fmt" - "io" - "net/http" - "strings" - "time" -) - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// Response struct and methods -//_______________________________________________________________________ - -// Response struct holds response values of executed request. -type Response struct { - Request *Request - RawResponse *http.Response - - body []byte - size int64 - receivedAt time.Time -} - -// Body method returns HTTP response as []byte array for the executed request. -// -// Note: `Response.Body` might be nil, if `Request.SetOutput` is used. -func (r *Response) Body() []byte { - if r.RawResponse == nil { - return []byte{} - } - return r.body -} - -// Status method returns the HTTP status string for the executed request. -// Example: 200 OK -func (r *Response) Status() string { - if r.RawResponse == nil { - return "" - } - return r.RawResponse.Status -} - -// StatusCode method returns the HTTP status code for the executed request. -// Example: 200 -func (r *Response) StatusCode() int { - if r.RawResponse == nil { - return 0 - } - return r.RawResponse.StatusCode -} - -// Proto method returns the HTTP response protocol used for the request. -func (r *Response) Proto() string { - if r.RawResponse == nil { - return "" - } - return r.RawResponse.Proto -} - -// Result method returns the response value as an object if it has one -func (r *Response) Result() interface{} { - return r.Request.Result -} - -// Error method returns the error object if it has one -func (r *Response) Error() interface{} { - return r.Request.Error -} - -// Header method returns the response headers -func (r *Response) Header() http.Header { - if r.RawResponse == nil { - return http.Header{} - } - return r.RawResponse.Header -} - -// Cookies method to access all the response cookies -func (r *Response) Cookies() []*http.Cookie { - if r.RawResponse == nil { - return make([]*http.Cookie, 0) - } - return r.RawResponse.Cookies() -} - -// String method returns the body of the server response as String. -func (r *Response) String() string { - if r.body == nil { - return "" - } - return strings.TrimSpace(string(r.body)) -} - -// Time method returns the time of HTTP response time that from request we sent and received a request. -// -// See `Response.ReceivedAt` to know when client received response and see `Response.Request.Time` to know -// when client sent a request. -func (r *Response) Time() time.Duration { - if r.Request.clientTrace != nil { - return r.Request.TraceInfo().TotalTime - } - return r.receivedAt.Sub(r.Request.Time) -} - -// ReceivedAt method returns when response got received from server for the request. -func (r *Response) ReceivedAt() time.Time { - return r.receivedAt -} - -// Size method returns the HTTP response size in bytes. Ya, you can relay on HTTP `Content-Length` header, -// however it won't be good for chucked transfer/compressed response. Since Resty calculates response size -// at the client end. You will get actual size of the http response. -func (r *Response) Size() int64 { - return r.size -} - -// RawBody method exposes the HTTP raw response body. Use this method in-conjunction with `SetDoNotParseResponse` -// option otherwise you get an error as `read err: http: read on closed response body`. -// -// Do not forget to close the body, otherwise you might get into connection leaks, no connection reuse. -// Basically you have taken over the control of response parsing from `Resty`. -func (r *Response) RawBody() io.ReadCloser { - if r.RawResponse == nil { - return nil - } - return r.RawResponse.Body -} - -// IsSuccess method returns true if HTTP status `code >= 200 and <= 299` otherwise false. -func (r *Response) IsSuccess() bool { - return r.StatusCode() > 199 && r.StatusCode() < 300 -} - -// IsError method returns true if HTTP status `code >= 400` otherwise false. -func (r *Response) IsError() bool { - return r.StatusCode() > 399 -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// Response Unexported methods -//_______________________________________________________________________ - -func (r *Response) setReceivedAt() { - r.receivedAt = time.Now() - if r.Request.clientTrace != nil { - r.Request.clientTrace.endTime = r.receivedAt - } -} - -func (r *Response) fmtBodyString(sl int64) string { - if r.body != nil { - if int64(len(r.body)) > sl { - return fmt.Sprintf("***** RESPONSE TOO LARGE (size - %d) *****", len(r.body)) - } - ct := r.Header().Get(hdrContentTypeKey) - if IsJSONType(ct) { - out := acquireBuffer() - defer releaseBuffer(out) - err := json.Indent(out, r.body, "", " ") - if err != nil { - return fmt.Sprintf("*** Error: Unable to format response body - \"%s\" ***\n\nLog Body as-is:\n%s", err, r.String()) - } - return out.String() - } - return r.String() - } - - return "***** NO CONTENT *****" -} diff --git a/vendor/github.com/go-resty/resty/v2/resty.go b/vendor/github.com/go-resty/resty/v2/resty.go deleted file mode 100644 index 6f9c8b4c..00000000 --- a/vendor/github.com/go-resty/resty/v2/resty.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved. -// resty source code and usage is governed by a MIT style -// license that can be found in the LICENSE file. - -// Package resty provides Simple HTTP and REST client library for Go. -package resty - -import ( - "net" - "net/http" - "net/http/cookiejar" - - "golang.org/x/net/publicsuffix" -) - -// Version # of resty -const Version = "2.7.0" - -// New method creates a new Resty client. -func New() *Client { - cookieJar, _ := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List}) - return createClient(&http.Client{ - Jar: cookieJar, - }) -} - -// NewWithClient method creates a new Resty client with given `http.Client`. -func NewWithClient(hc *http.Client) *Client { - return createClient(hc) -} - -// NewWithLocalAddr method creates a new Resty client with given Local Address -// to dial from. -func NewWithLocalAddr(localAddr net.Addr) *Client { - cookieJar, _ := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List}) - return createClient(&http.Client{ - Jar: cookieJar, - Transport: createTransport(localAddr), - }) -} diff --git a/vendor/github.com/go-resty/resty/v2/retry.go b/vendor/github.com/go-resty/resty/v2/retry.go deleted file mode 100644 index 00b8514a..00000000 --- a/vendor/github.com/go-resty/resty/v2/retry.go +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved. -// resty source code and usage is governed by a MIT style -// license that can be found in the LICENSE file. - -package resty - -import ( - "context" - "math" - "math/rand" - "sync" - "time" -) - -const ( - defaultMaxRetries = 3 - defaultWaitTime = time.Duration(100) * time.Millisecond - defaultMaxWaitTime = time.Duration(2000) * time.Millisecond -) - -type ( - // Option is to create convenient retry options like wait time, max retries, etc. - Option func(*Options) - - // RetryConditionFunc type is for retry condition function - // input: non-nil Response OR request execution error - RetryConditionFunc func(*Response, error) bool - - // OnRetryFunc is for side-effecting functions triggered on retry - OnRetryFunc func(*Response, error) - - // RetryAfterFunc returns time to wait before retry - // For example, it can parse HTTP Retry-After header - // https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html - // Non-nil error is returned if it is found that request is not retryable - // (0, nil) is a special result means 'use default algorithm' - RetryAfterFunc func(*Client, *Response) (time.Duration, error) - - // Options struct is used to hold retry settings. - Options struct { - maxRetries int - waitTime time.Duration - maxWaitTime time.Duration - retryConditions []RetryConditionFunc - retryHooks []OnRetryFunc - } -) - -// Retries sets the max number of retries -func Retries(value int) Option { - return func(o *Options) { - o.maxRetries = value - } -} - -// WaitTime sets the default wait time to sleep between requests -func WaitTime(value time.Duration) Option { - return func(o *Options) { - o.waitTime = value - } -} - -// MaxWaitTime sets the max wait time to sleep between requests -func MaxWaitTime(value time.Duration) Option { - return func(o *Options) { - o.maxWaitTime = value - } -} - -// RetryConditions sets the conditions that will be checked for retry. -func RetryConditions(conditions []RetryConditionFunc) Option { - return func(o *Options) { - o.retryConditions = conditions - } -} - -// RetryHooks sets the hooks that will be executed after each retry -func RetryHooks(hooks []OnRetryFunc) Option { - return func(o *Options) { - o.retryHooks = hooks - } -} - -// Backoff retries with increasing timeout duration up until X amount of retries -// (Default is 3 attempts, Override with option Retries(n)) -func Backoff(operation func() (*Response, error), options ...Option) error { - // Defaults - opts := Options{ - maxRetries: defaultMaxRetries, - waitTime: defaultWaitTime, - maxWaitTime: defaultMaxWaitTime, - retryConditions: []RetryConditionFunc{}, - } - - for _, o := range options { - o(&opts) - } - - var ( - resp *Response - err error - ) - - for attempt := 0; attempt <= opts.maxRetries; attempt++ { - resp, err = operation() - ctx := context.Background() - if resp != nil && resp.Request.ctx != nil { - ctx = resp.Request.ctx - } - if ctx.Err() != nil { - return err - } - - err1 := unwrapNoRetryErr(err) // raw error, it used for return users callback. - needsRetry := err != nil && err == err1 // retry on a few operation errors by default - - for _, condition := range opts.retryConditions { - needsRetry = condition(resp, err1) - if needsRetry { - break - } - } - - if !needsRetry { - return err - } - - for _, hook := range opts.retryHooks { - hook(resp, err) - } - - // Don't need to wait when no retries left. - // Still run retry hooks even on last retry to keep compatibility. - if attempt == opts.maxRetries { - return err - } - - waitTime, err2 := sleepDuration(resp, opts.waitTime, opts.maxWaitTime, attempt) - if err2 != nil { - if err == nil { - err = err2 - } - return err - } - - select { - case <-time.After(waitTime): - case <-ctx.Done(): - return ctx.Err() - } - } - - return err -} - -func sleepDuration(resp *Response, min, max time.Duration, attempt int) (time.Duration, error) { - const maxInt = 1<<31 - 1 // max int for arch 386 - if max < 0 { - max = maxInt - } - if resp == nil { - return jitterBackoff(min, max, attempt), nil - } - - retryAfterFunc := resp.Request.client.RetryAfter - - // Check for custom callback - if retryAfterFunc == nil { - return jitterBackoff(min, max, attempt), nil - } - - result, err := retryAfterFunc(resp.Request.client, resp) - if err != nil { - return 0, err // i.e. 'API quota exceeded' - } - if result == 0 { - return jitterBackoff(min, max, attempt), nil - } - if result < 0 || max < result { - result = max - } - if result < min { - result = min - } - return result, nil -} - -// Return capped exponential backoff with jitter -// http://www.awsarchitectureblog.com/2015/03/backoff.html -func jitterBackoff(min, max time.Duration, attempt int) time.Duration { - base := float64(min) - capLevel := float64(max) - - temp := math.Min(capLevel, base*math.Exp2(float64(attempt))) - ri := time.Duration(temp / 2) - result := randDuration(ri) - - if result < min { - result = min - } - - return result -} - -var rnd = newRnd() -var rndMu sync.Mutex - -func randDuration(center time.Duration) time.Duration { - rndMu.Lock() - defer rndMu.Unlock() - - var ri = int64(center) - var jitter = rnd.Int63n(ri) - return time.Duration(math.Abs(float64(ri + jitter))) -} - -func newRnd() *rand.Rand { - var seed = time.Now().UnixNano() - var src = rand.NewSource(seed) - return rand.New(src) -} diff --git a/vendor/github.com/go-resty/resty/v2/trace.go b/vendor/github.com/go-resty/resty/v2/trace.go deleted file mode 100644 index 23cf7033..00000000 --- a/vendor/github.com/go-resty/resty/v2/trace.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved. -// resty source code and usage is governed by a MIT style -// license that can be found in the LICENSE file. - -package resty - -import ( - "context" - "crypto/tls" - "net" - "net/http/httptrace" - "time" -) - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// TraceInfo struct -//_______________________________________________________________________ - -// TraceInfo struct is used provide request trace info such as DNS lookup -// duration, Connection obtain duration, Server processing duration, etc. -// -// Since v2.0.0 -type TraceInfo struct { - // DNSLookup is a duration that transport took to perform - // DNS lookup. - DNSLookup time.Duration - - // ConnTime is a duration that took to obtain a successful connection. - ConnTime time.Duration - - // TCPConnTime is a duration that took to obtain the TCP connection. - TCPConnTime time.Duration - - // TLSHandshake is a duration that TLS handshake took place. - TLSHandshake time.Duration - - // ServerTime is a duration that server took to respond first byte. - ServerTime time.Duration - - // ResponseTime is a duration since first response byte from server to - // request completion. - ResponseTime time.Duration - - // TotalTime is a duration that total request took end-to-end. - TotalTime time.Duration - - // IsConnReused is whether this connection has been previously - // used for another HTTP request. - IsConnReused bool - - // IsConnWasIdle is whether this connection was obtained from an - // idle pool. - IsConnWasIdle bool - - // ConnIdleTime is a duration how long the connection was previously - // idle, if IsConnWasIdle is true. - ConnIdleTime time.Duration - - // RequestAttempt is to represent the request attempt made during a Resty - // request execution flow, including retry count. - RequestAttempt int - - // RemoteAddr returns the remote network address. - RemoteAddr net.Addr -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// ClientTrace struct and its methods -//_______________________________________________________________________ - -// tracer struct maps the `httptrace.ClientTrace` hooks into Fields -// with same naming for easy understanding. Plus additional insights -// Request. -type clientTrace struct { - getConn time.Time - dnsStart time.Time - dnsDone time.Time - connectDone time.Time - tlsHandshakeStart time.Time - tlsHandshakeDone time.Time - gotConn time.Time - gotFirstResponseByte time.Time - endTime time.Time - gotConnInfo httptrace.GotConnInfo -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// Trace unexported methods -//_______________________________________________________________________ - -func (t *clientTrace) createContext(ctx context.Context) context.Context { - return httptrace.WithClientTrace( - ctx, - &httptrace.ClientTrace{ - DNSStart: func(_ httptrace.DNSStartInfo) { - t.dnsStart = time.Now() - }, - DNSDone: func(_ httptrace.DNSDoneInfo) { - t.dnsDone = time.Now() - }, - ConnectStart: func(_, _ string) { - if t.dnsDone.IsZero() { - t.dnsDone = time.Now() - } - if t.dnsStart.IsZero() { - t.dnsStart = t.dnsDone - } - }, - ConnectDone: func(net, addr string, err error) { - t.connectDone = time.Now() - }, - GetConn: func(_ string) { - t.getConn = time.Now() - }, - GotConn: func(ci httptrace.GotConnInfo) { - t.gotConn = time.Now() - t.gotConnInfo = ci - }, - GotFirstResponseByte: func() { - t.gotFirstResponseByte = time.Now() - }, - TLSHandshakeStart: func() { - t.tlsHandshakeStart = time.Now() - }, - TLSHandshakeDone: func(_ tls.ConnectionState, _ error) { - t.tlsHandshakeDone = time.Now() - }, - }, - ) -} diff --git a/vendor/github.com/go-resty/resty/v2/transport.go b/vendor/github.com/go-resty/resty/v2/transport.go deleted file mode 100644 index e15b48c5..00000000 --- a/vendor/github.com/go-resty/resty/v2/transport.go +++ /dev/null @@ -1,35 +0,0 @@ -// +build go1.13 - -// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved. -// resty source code and usage is governed by a MIT style -// license that can be found in the LICENSE file. - -package resty - -import ( - "net" - "net/http" - "runtime" - "time" -) - -func createTransport(localAddr net.Addr) *http.Transport { - dialer := &net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - DualStack: true, - } - if localAddr != nil { - dialer.LocalAddr = localAddr - } - return &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: dialer.DialContext, - ForceAttemptHTTP2: true, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1, - } -} diff --git a/vendor/github.com/go-resty/resty/v2/transport112.go b/vendor/github.com/go-resty/resty/v2/transport112.go deleted file mode 100644 index fbbbc591..00000000 --- a/vendor/github.com/go-resty/resty/v2/transport112.go +++ /dev/null @@ -1,34 +0,0 @@ -// +build !go1.13 - -// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved. -// resty source code and usage is governed by a MIT style -// license that can be found in the LICENSE file. - -package resty - -import ( - "net" - "net/http" - "runtime" - "time" -) - -func createTransport(localAddr net.Addr) *http.Transport { - dialer := &net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - DualStack: true, - } - if localAddr != nil { - dialer.LocalAddr = localAddr - } - return &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: dialer.DialContext, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1, - } -} diff --git a/vendor/github.com/go-resty/resty/v2/util.go b/vendor/github.com/go-resty/resty/v2/util.go deleted file mode 100644 index 1d563bef..00000000 --- a/vendor/github.com/go-resty/resty/v2/util.go +++ /dev/null @@ -1,391 +0,0 @@ -// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved. -// resty source code and usage is governed by a MIT style -// license that can be found in the LICENSE file. - -package resty - -import ( - "bytes" - "fmt" - "io" - "log" - "mime/multipart" - "net/http" - "net/textproto" - "os" - "path/filepath" - "reflect" - "runtime" - "sort" - "strings" - "sync" -) - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// Logger interface -//_______________________________________________________________________ - -// Logger interface is to abstract the logging from Resty. Gives control to -// the Resty users, choice of the logger. -type Logger interface { - Errorf(format string, v ...interface{}) - Warnf(format string, v ...interface{}) - Debugf(format string, v ...interface{}) -} - -func createLogger() *logger { - l := &logger{l: log.New(os.Stderr, "", log.Ldate|log.Lmicroseconds)} - return l -} - -var _ Logger = (*logger)(nil) - -type logger struct { - l *log.Logger -} - -func (l *logger) Errorf(format string, v ...interface{}) { - l.output("ERROR RESTY "+format, v...) -} - -func (l *logger) Warnf(format string, v ...interface{}) { - l.output("WARN RESTY "+format, v...) -} - -func (l *logger) Debugf(format string, v ...interface{}) { - l.output("DEBUG RESTY "+format, v...) -} - -func (l *logger) output(format string, v ...interface{}) { - if len(v) == 0 { - l.l.Print(format) - return - } - l.l.Printf(format, v...) -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// Package Helper methods -//_______________________________________________________________________ - -// IsStringEmpty method tells whether given string is empty or not -func IsStringEmpty(str string) bool { - return len(strings.TrimSpace(str)) == 0 -} - -// DetectContentType method is used to figure out `Request.Body` content type for request header -func DetectContentType(body interface{}) string { - contentType := plainTextType - kind := kindOf(body) - switch kind { - case reflect.Struct, reflect.Map: - contentType = jsonContentType - case reflect.String: - contentType = plainTextType - default: - if b, ok := body.([]byte); ok { - contentType = http.DetectContentType(b) - } else if kind == reflect.Slice { - contentType = jsonContentType - } - } - - return contentType -} - -// IsJSONType method is to check JSON content type or not -func IsJSONType(ct string) bool { - return jsonCheck.MatchString(ct) -} - -// IsXMLType method is to check XML content type or not -func IsXMLType(ct string) bool { - return xmlCheck.MatchString(ct) -} - -// Unmarshalc content into object from JSON or XML -func Unmarshalc(c *Client, ct string, b []byte, d interface{}) (err error) { - if IsJSONType(ct) { - err = c.JSONUnmarshal(b, d) - } else if IsXMLType(ct) { - err = c.XMLUnmarshal(b, d) - } - - return -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// RequestLog and ResponseLog type -//_______________________________________________________________________ - -// RequestLog struct is used to collected information from resty request -// instance for debug logging. It sent to request log callback before resty -// actually logs the information. -type RequestLog struct { - Header http.Header - Body string -} - -// ResponseLog struct is used to collected information from resty response -// instance for debug logging. It sent to response log callback before resty -// actually logs the information. -type ResponseLog struct { - Header http.Header - Body string -} - -//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ -// Package Unexported methods -//_______________________________________________________________________ - -// way to disable the HTML escape as opt-in -func jsonMarshal(c *Client, r *Request, d interface{}) (*bytes.Buffer, error) { - if !r.jsonEscapeHTML || !c.jsonEscapeHTML { - return noescapeJSONMarshal(d) - } - - data, err := c.JSONMarshal(d) - if err != nil { - return nil, err - } - - buf := acquireBuffer() - _, _ = buf.Write(data) - return buf, nil -} - -func firstNonEmpty(v ...string) string { - for _, s := range v { - if !IsStringEmpty(s) { - return s - } - } - return "" -} - -var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"") - -func escapeQuotes(s string) string { - return quoteEscaper.Replace(s) -} - -func createMultipartHeader(param, fileName, contentType string) textproto.MIMEHeader { - hdr := make(textproto.MIMEHeader) - - var contentDispositionValue string - if IsStringEmpty(fileName) { - contentDispositionValue = fmt.Sprintf(`form-data; name="%s"`, param) - } else { - contentDispositionValue = fmt.Sprintf(`form-data; name="%s"; filename="%s"`, - param, escapeQuotes(fileName)) - } - hdr.Set("Content-Disposition", contentDispositionValue) - - if !IsStringEmpty(contentType) { - hdr.Set(hdrContentTypeKey, contentType) - } - return hdr -} - -func addMultipartFormField(w *multipart.Writer, mf *MultipartField) error { - partWriter, err := w.CreatePart(createMultipartHeader(mf.Param, mf.FileName, mf.ContentType)) - if err != nil { - return err - } - - _, err = io.Copy(partWriter, mf.Reader) - return err -} - -func writeMultipartFormFile(w *multipart.Writer, fieldName, fileName string, r io.Reader) error { - // Auto detect actual multipart content type - cbuf := make([]byte, 512) - size, err := r.Read(cbuf) - if err != nil && err != io.EOF { - return err - } - - partWriter, err := w.CreatePart(createMultipartHeader(fieldName, fileName, http.DetectContentType(cbuf))) - if err != nil { - return err - } - - if _, err = partWriter.Write(cbuf[:size]); err != nil { - return err - } - - _, err = io.Copy(partWriter, r) - return err -} - -func addFile(w *multipart.Writer, fieldName, path string) error { - file, err := os.Open(path) - if err != nil { - return err - } - defer closeq(file) - return writeMultipartFormFile(w, fieldName, filepath.Base(path), file) -} - -func addFileReader(w *multipart.Writer, f *File) error { - return writeMultipartFormFile(w, f.ParamName, f.Name, f.Reader) -} - -func getPointer(v interface{}) interface{} { - vv := valueOf(v) - if vv.Kind() == reflect.Ptr { - return v - } - return reflect.New(vv.Type()).Interface() -} - -func isPayloadSupported(m string, allowMethodGet bool) bool { - return !(m == MethodHead || m == MethodOptions || (m == MethodGet && !allowMethodGet)) -} - -func typeOf(i interface{}) reflect.Type { - return indirect(valueOf(i)).Type() -} - -func valueOf(i interface{}) reflect.Value { - return reflect.ValueOf(i) -} - -func indirect(v reflect.Value) reflect.Value { - return reflect.Indirect(v) -} - -func kindOf(v interface{}) reflect.Kind { - return typeOf(v).Kind() -} - -func createDirectory(dir string) (err error) { - if _, err = os.Stat(dir); err != nil { - if os.IsNotExist(err) { - if err = os.MkdirAll(dir, 0755); err != nil { - return - } - } - } - return -} - -func canJSONMarshal(contentType string, kind reflect.Kind) bool { - return IsJSONType(contentType) && (kind == reflect.Struct || kind == reflect.Map || kind == reflect.Slice) -} - -func functionName(i interface{}) string { - return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() -} - -func acquireBuffer() *bytes.Buffer { - return bufPool.Get().(*bytes.Buffer) -} - -func releaseBuffer(buf *bytes.Buffer) { - if buf != nil { - buf.Reset() - bufPool.Put(buf) - } -} - -// requestBodyReleaser wraps requests's body and implements custom Close for it. -// The Close method closes original body and releases request body back to sync.Pool. -type requestBodyReleaser struct { - releaseOnce sync.Once - reqBuf *bytes.Buffer - io.ReadCloser -} - -func newRequestBodyReleaser(respBody io.ReadCloser, reqBuf *bytes.Buffer) io.ReadCloser { - if reqBuf == nil { - return respBody - } - - return &requestBodyReleaser{ - reqBuf: reqBuf, - ReadCloser: respBody, - } -} - -func (rr *requestBodyReleaser) Close() error { - err := rr.ReadCloser.Close() - rr.releaseOnce.Do(func() { - releaseBuffer(rr.reqBuf) - }) - - return err -} - -func closeq(v interface{}) { - if c, ok := v.(io.Closer); ok { - silently(c.Close()) - } -} - -func silently(_ ...interface{}) {} - -func composeHeaders(c *Client, r *Request, hdrs http.Header) string { - str := make([]string, 0, len(hdrs)) - for _, k := range sortHeaderKeys(hdrs) { - var v string - if k == "Cookie" { - cv := strings.TrimSpace(strings.Join(hdrs[k], ", ")) - if c.GetClient().Jar != nil { - for _, c := range c.GetClient().Jar.Cookies(r.RawRequest.URL) { - if cv != "" { - cv = cv + "; " + c.String() - } else { - cv = c.String() - } - } - } - v = strings.TrimSpace(fmt.Sprintf("%25s: %s", k, cv)) - } else { - v = strings.TrimSpace(fmt.Sprintf("%25s: %s", k, strings.Join(hdrs[k], ", "))) - } - if v != "" { - str = append(str, "\t"+v) - } - } - return strings.Join(str, "\n") -} - -func sortHeaderKeys(hdrs http.Header) []string { - keys := make([]string, 0, len(hdrs)) - for key := range hdrs { - keys = append(keys, key) - } - sort.Strings(keys) - return keys -} - -func copyHeaders(hdrs http.Header) http.Header { - nh := http.Header{} - for k, v := range hdrs { - nh[k] = v - } - return nh -} - -type noRetryErr struct { - err error -} - -func (e *noRetryErr) Error() string { - return e.err.Error() -} - -func wrapNoRetryErr(err error) error { - if err != nil { - err = &noRetryErr{err: err} - } - return err -} - -func unwrapNoRetryErr(err error) error { - if e, ok := err.(*noRetryErr); ok { - err = e.err - } - return err -} diff --git a/vendor/modules.txt b/vendor/modules.txt index d014341d..19f48071 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -129,9 +129,6 @@ github.com/go-openapi/swag # github.com/go-openapi/validate v0.22.1 ## explicit; go 1.14 github.com/go-openapi/validate -# github.com/go-resty/resty/v2 v2.7.0 -## explicit; go 1.11 -github.com/go-resty/resty/v2 # github.com/go-sql-driver/mysql v1.7.0 ## explicit; go 1.13 github.com/go-sql-driver/mysql