From f8ed8e9cd6a1599092902644d59296cc60434077 Mon Sep 17 00:00:00 2001 From: Lena Garber <114949949+lgarber-akamai@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:41:55 -0500 Subject: [PATCH] new: (PROPOSAL) Add API request & pagination helpers using generics (#456) * cool * Respect page * Add method helpers * one more * oops * tidy up * Add basic tests * Add unit tests * make tidy * oops * Re-use mock function * Use t.Helper * Aggregate -> Get * pls * nolint * Re-run image fixtures * oops * Store pages and results in listoptions * Maintain ListOptions backwards compatibility * Rerun example fixtures --------- Co-authored-by: Zhiwei Liang <121905282+zliang-akamai@users.noreply.github.com> --- go.mod | 9 +- go.sum | 19 ++ go.work.sum | 2 + images.go | 114 ++----- internal/testutil/mock.go | 77 +++++ k8s/go.mod | 4 +- k8s/go.sum | 9 +- pagination_test.go | 3 +- request_helpers.go | 187 ++++++++++ request_helpers_test.go | 249 ++++++++++++++ test/go.mod | 6 +- test/go.sum | 14 +- test/integration/account_availability_test.go | 1 - test/integration/account_logins_test.go | 1 - test/integration/betas_test.go | 2 - test/integration/cache_test.go | 3 +- test/integration/client_test.go | 3 +- test/integration/example_integration_test.go | 3 +- .../fixtures/ExampleListImages_all.yaml | 226 ++++++------ .../fixtures/ExampleListImages_badfilter.yaml | 14 +- .../fixtures/ExampleListImages_notfound.yaml | 15 +- .../fixtures/TestImage_CloudInit.yaml | 323 +++++++++++------- .../fixtures/TestImage_CreateUpload.yaml | 270 ++++++++++----- .../fixtures/TestImage_GetFound.yaml | 17 +- .../fixtures/TestImage_GetMissing.yaml | 12 +- .../fixtures/TestImage_Upload.yaml | 98 +----- .../integration/fixtures/TestImages_List.yaml | 240 ++++++------- test/integration/instance_config_test.go | 5 +- test/integration/instance_stats_test.go | 14 +- test/integration/instances_test.go | 6 +- test/integration/integration_suite_test.go | 19 +- test/integration/lke_clusters_test.go | 1 + test/integration/longview_test.go | 1 - test/integration/profile_grants_list_test.go | 8 +- test/integration/profile_logins_test.go | 1 - test/integration/util_test.go | 48 +-- test/integration/vpc_subnet_test.go | 2 - test/integration/waitfor_test.go | 3 +- 38 files changed, 1319 insertions(+), 710 deletions(-) create mode 100644 internal/testutil/mock.go create mode 100644 request_helpers.go create mode 100644 request_helpers_test.go diff --git a/go.mod b/go.mod index 7415846fe..b4903b447 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,19 @@ module github.com/linode/linodego require ( github.com/go-resty/resty/v2 v2.11.0 github.com/google/go-cmp v0.6.0 + github.com/jarcoal/httpmock v1.3.1 golang.org/x/net v0.21.0 + golang.org/x/oauth2 v0.17.0 golang.org/x/text v0.14.0 gopkg.in/ini.v1 v1.66.6 ) -require github.com/stretchr/testify v1.8.4 // indirect +require ( + github.com/golang/protobuf v1.5.3 // indirect + github.com/stretchr/testify v1.8.4 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.31.0 // indirect +) go 1.20 diff --git a/go.sum b/go.sum index 5426fc8b5..58cb0eb9e 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,16 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8= github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww= +github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= +github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -12,6 +20,7 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -20,6 +29,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -37,6 +48,7 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= @@ -51,6 +63,13 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/go.work.sum b/go.work.sum index 78006117a..072cf38f0 100644 --- a/go.work.sum +++ b/go.work.sum @@ -193,7 +193,9 @@ golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= diff --git a/images.go b/images.go index 7875d6fdc..539420c50 100644 --- a/images.go +++ b/images.go @@ -3,9 +3,7 @@ package linodego import ( "context" "encoding/json" - "fmt" "io" - "net/url" "time" "github.com/go-resty/resty/v2" @@ -105,110 +103,66 @@ func (i Image) GetUpdateOptions() (iu ImageUpdateOptions) { return } -// ImagesPagedResponse represents a linode API response for listing of images -type ImagesPagedResponse struct { - *PageOptions - Data []Image `json:"data"` -} - -func (ImagesPagedResponse) endpoint(_ ...any) string { - return "images" -} - -func (resp *ImagesPagedResponse) castResult(r *resty.Request, e string) (int, int, error) { - res, err := coupleAPIErrors(r.SetResult(ImagesPagedResponse{}).Get(e)) - if err != nil { - return 0, 0, err - } - castedRes := res.Result().(*ImagesPagedResponse) - resp.Data = append(resp.Data, castedRes.Data...) - return castedRes.Pages, castedRes.Results, nil -} - // ListImages lists Images func (c *Client) ListImages(ctx context.Context, opts *ListOptions) ([]Image, error) { - response := ImagesPagedResponse{} - err := c.listHelper(ctx, &response, opts) - if err != nil { - return nil, err - } - return response.Data, nil + return getPaginatedResults[Image]( + ctx, + c, + "images", + opts, + ) } // GetImage gets the Image with the provided ID func (c *Client) GetImage(ctx context.Context, imageID string) (*Image, error) { - imageID = url.PathEscape(imageID) - - e := fmt.Sprintf("images/%s", imageID) - req := c.R(ctx).SetResult(&Image{}) - r, err := coupleAPIErrors(req.Get(e)) - if err != nil { - return nil, err - } - return r.Result().(*Image), nil + return doGETRequest[Image]( + ctx, + c, + formatAPIPath("images/%s", imageID), + ) } // CreateImage creates an Image func (c *Client) CreateImage(ctx context.Context, opts ImageCreateOptions) (*Image, error) { - body, err := json.Marshal(opts) - if err != nil { - return nil, err - } - - e := "images" - req := c.R(ctx).SetResult(&Image{}).SetBody(string(body)) - r, err := coupleAPIErrors(req.Post(e)) - if err != nil { - return nil, err - } - return r.Result().(*Image), nil + return doPOSTRequest[Image]( + ctx, + c, + "images", + opts, + ) } // UpdateImage updates the Image with the specified id func (c *Client) UpdateImage(ctx context.Context, imageID string, opts ImageUpdateOptions) (*Image, error) { - body, err := json.Marshal(opts) - if err != nil { - return nil, err - } - - imageID = url.PathEscape(imageID) - - e := fmt.Sprintf("images/%s", imageID) - req := c.R(ctx).SetResult(&Image{}).SetBody(string(body)) - r, err := coupleAPIErrors(req.Put(e)) - if err != nil { - return nil, err - } - return r.Result().(*Image), nil + return doPUTRequest[Image]( + ctx, + c, + formatAPIPath("images/%s", imageID), + opts, + ) } // DeleteImage deletes the Image with the specified id func (c *Client) DeleteImage(ctx context.Context, imageID string) error { - imageID = url.PathEscape(imageID) - e := fmt.Sprintf("images/%s", imageID) - _, err := coupleAPIErrors(c.R(ctx).Delete(e)) - return err + return doDELETERequest( + ctx, + c, + formatAPIPath("images/%s", imageID), + ) } // CreateImageUpload creates an Image and an upload URL func (c *Client) CreateImageUpload(ctx context.Context, opts ImageCreateUploadOptions) (*Image, string, error) { - body, err := json.Marshal(opts) + result, err := doPOSTRequest[ImageCreateUploadResponse]( + ctx, + c, + "images/upload", + opts, + ) if err != nil { return nil, "", err } - e := "images/upload" - req := c.R(ctx).SetResult(&ImageCreateUploadResponse{}).SetBody(string(body)) - r, err := coupleAPIErrors(req.Post(e)) - if err != nil { - return nil, "", err - } - - result, ok := r.Result().(*ImageCreateUploadResponse) - if !ok { - return nil, "", fmt.Errorf("failed to parse result") - } - return result.Image, result.UploadTo, nil } diff --git a/internal/testutil/mock.go b/internal/testutil/mock.go new file mode 100644 index 000000000..1f7147931 --- /dev/null +++ b/internal/testutil/mock.go @@ -0,0 +1,77 @@ +package testutil + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "reflect" + "regexp" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/jarcoal/httpmock" + "golang.org/x/oauth2" +) + +var validTestAPIKey = "NOTANAPIKEY" + +func MockRequestURL(path string) *regexp.Regexp { + return regexp.MustCompile(fmt.Sprintf("/[a-zA-Z0-9]+/%s", strings.TrimPrefix(path, "/"))) +} + +func MockRequestBodyValidate(t *testing.T, expected interface{}, response interface{}) httpmock.Responder { + t.Helper() + + return func(request *http.Request) (*http.Response, error) { + eType := reflect.TypeOf(expected) + result := reflect.New(eType) + + i := result.Interface() + + data, err := io.ReadAll(request.Body) + if err != nil { + t.Fatal(err) + } + + if err := json.Unmarshal(data, &i); err != nil { + t.Fatal(err) + } + + // Deref the pointer if necessary + if result.Kind() == reflect.Pointer { + result = result.Elem() + } + + resultValue := result.Interface() + + if !reflect.DeepEqual(expected, resultValue) { + t.Fatalf("request body does not match request options: %s", cmp.Diff(expected, resultValue)) + } + + return httpmock.NewJsonResponse(200, response) + } +} + +// CreateMockClient is generic because importing the linodego package will result +// in a cyclic dependency. This pattern isn't ideal but works for now. +func CreateMockClient[T any](t *testing.T, createFunc func(*http.Client) T) *T { + t.Helper() + + tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: validTestAPIKey}) + + client := &http.Client{ + Transport: &oauth2.Transport{ + Source: tokenSource, + }, + } + httpmock.ActivateNonDefault(client) + + t.Cleanup(func() { + httpmock.DeactivateAndReset() + }) + + result := createFunc(client) + return &result +} diff --git a/k8s/go.mod b/k8s/go.mod index 74a522e55..a8ac2c9d1 100644 --- a/k8s/go.mod +++ b/k8s/go.mod @@ -30,13 +30,13 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/net v0.21.0 // indirect - golang.org/x/oauth2 v0.8.0 // indirect + golang.org/x/oauth2 v0.17.0 // indirect golang.org/x/sys v0.17.0 // indirect golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/k8s/go.sum b/k8s/go.sum index 0cf3c1b54..608d57fe0 100644 --- a/k8s/go.sum +++ b/k8s/go.sum @@ -35,6 +35,7 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -95,8 +96,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= -golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -147,8 +148,8 @@ google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6 google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/pagination_test.go b/pagination_test.go index 15a1f4207..b6b7bf50e 100644 --- a/pagination_test.go +++ b/pagination_test.go @@ -1,9 +1,10 @@ package linodego import ( - "github.com/google/go-cmp/cmp" "reflect" "testing" + + "github.com/google/go-cmp/cmp" ) func TestFlattenQueryStruct(t *testing.T) { diff --git a/request_helpers.go b/request_helpers.go new file mode 100644 index 000000000..abaf5bc74 --- /dev/null +++ b/request_helpers.go @@ -0,0 +1,187 @@ +package linodego + +import ( + "context" + "encoding/json" + "fmt" + "net/url" + "strconv" +) + +// paginatedResponse represents a single response from a paginated +// endpoint. +type paginatedResponse[T any] struct { + Page int `json:"page" url:"page,omitempty"` + Pages int `json:"pages" url:"pages,omitempty"` + Results int `json:"results" url:"results,omitempty"` + Data []T `json:"data"` +} + +// getPaginatedResults aggregates results from the given +// paginated endpoint using the provided ListOptions. +// nolint:funlen +func getPaginatedResults[T any]( + ctx context.Context, + client *Client, + endpoint string, + opts *ListOptions, +) ([]T, error) { + var resultType paginatedResponse[T] + + result := make([]T, 0) + + req := client.R(ctx).SetResult(resultType) + + if opts == nil { + opts = &ListOptions{PageOptions: &PageOptions{Page: 0}} + } + + if opts.PageOptions == nil { + opts.PageOptions = &PageOptions{Page: 0} + } + + // Apply all user-provided list options to the base request + if err := applyListOptionsToRequest(opts, req); err != nil { + return nil, err + } + + // Makes a request to a particular page and + // appends the response to the result + handlePage := func(page int) error { + req.SetQueryParam("page", strconv.Itoa(page)) + + res, err := coupleAPIErrors(req.Get(endpoint)) + if err != nil { + return err + } + + response := res.Result().(*paginatedResponse[T]) + + opts.Page = page + opts.Pages = response.Pages + opts.Results = response.Results + + result = append(result, response.Data...) + return nil + } + + // This helps simplify the logic below + startingPage := 1 + pageDefined := opts.Page > 0 + + if pageDefined { + startingPage = opts.Page + } + + // Get the first page + if err := handlePage(startingPage); err != nil { + return nil, err + } + + // If the user has explicitly specified a page, we don't + // need to get any other pages. + if pageDefined { + return result, nil + } + + // Get the rest of the pages + for page := 2; page <= opts.Pages; page++ { + if err := handlePage(page); err != nil { + return nil, err + } + } + + return result, nil +} + +// doGETRequest runs a GET request using the given client and API endpoint, +// and returns the result +func doGETRequest[T any]( + ctx context.Context, + client *Client, + endpoint string, +) (*T, error) { + var resultType T + + req := client.R(ctx).SetResult(&resultType) + r, err := coupleAPIErrors(req.Get(endpoint)) + if err != nil { + return nil, err + } + + return r.Result().(*T), nil +} + +// doPOSTRequest runs a PUT request using the given client, API endpoint, +// and options/body. +func doPOSTRequest[T, O any]( + ctx context.Context, + client *Client, + endpoint string, + options O, +) (*T, error) { + var resultType T + + body, err := json.Marshal(options) + if err != nil { + return nil, err + } + + req := client.R(ctx).SetResult(&resultType).SetBody(string(body)) + r, err := coupleAPIErrors(req.Post(endpoint)) + if err != nil { + return nil, err + } + + return r.Result().(*T), nil +} + +// doPUTRequest runs a PUT request using the given client, API endpoint, +// and options/body. +func doPUTRequest[T, O any]( + ctx context.Context, + client *Client, + endpoint string, + options O, +) (*T, error) { + var resultType T + + body, err := json.Marshal(options) + if err != nil { + return nil, err + } + + req := client.R(ctx).SetResult(&resultType).SetBody(string(body)) + r, err := coupleAPIErrors(req.Put(endpoint)) + if err != nil { + return nil, err + } + + return r.Result().(*T), nil +} + +// doDELETERequest runs a DELETE request using the given client +// and API endpoint. +func doDELETERequest( + ctx context.Context, + client *Client, + endpoint string, +) error { + req := client.R(ctx) + _, err := coupleAPIErrors(req.Delete(endpoint)) + return err +} + +// formatAPIPath allows us to safely build an API request with path escaping +func formatAPIPath(format string, args ...any) string { + escapedArgs := make([]any, len(args)) + for i, arg := range args { + if typeStr, ok := arg.(string); ok { + arg = url.PathEscape(typeStr) + } + + escapedArgs[i] = arg + } + + return fmt.Sprintf(format, escapedArgs...) +} diff --git a/request_helpers_test.go b/request_helpers_test.go new file mode 100644 index 000000000..65a9160e1 --- /dev/null +++ b/request_helpers_test.go @@ -0,0 +1,249 @@ +package linodego + +import ( + "context" + "math" + "net/http" + "reflect" + "strconv" + "testing" + + "github.com/linode/linodego/internal/testutil" + + "github.com/google/go-cmp/cmp" + "github.com/jarcoal/httpmock" +) + +type testResultNestedType struct { + NestedInt int `json:"nested_int"` + NestedString string `json:"nested_string"` +} + +type testResultType struct { + ID int `json:"id"` + Foo string `json:"foo"` + Cool testResultNestedType `json:"cool"` +} + +var testResponse = testResultType{ + Foo: "test", + ID: 123, + Cool: testResultNestedType{ + NestedInt: 456, + NestedString: "test2", + }, +} + +func TestRequestHelpers_get(t *testing.T) { + client := testutil.CreateMockClient(t, NewClient) + + httpmock.RegisterRegexpResponder("GET", testutil.MockRequestURL("/foo/bar"), + httpmock.NewJsonResponderOrPanic(200, &testResponse)) + + result, err := doGETRequest[testResultType]( + context.Background(), + client, + "/foo/bar", + ) + if err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(*result, testResponse) { + t.Fatalf("actual response does not equal desired response: %s", cmp.Diff(result, testResponse)) + } +} + +func TestRequestHelpers_post(t *testing.T) { + client := testutil.CreateMockClient(t, NewClient) + + httpmock.RegisterRegexpResponder("POST", testutil.MockRequestURL("/foo/bar"), + testutil.MockRequestBodyValidate(t, testResponse, testResponse)) + + result, err := doPOSTRequest[testResultType]( + context.Background(), + client, + "/foo/bar", + testResponse, + ) + if err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(*result, testResponse) { + t.Fatalf("actual response does not equal desired response: %s", cmp.Diff(result, testResponse)) + } +} + +func TestRequestHelpers_put(t *testing.T) { + client := testutil.CreateMockClient(t, NewClient) + + httpmock.RegisterRegexpResponder("PUT", testutil.MockRequestURL("/foo/bar"), + testutil.MockRequestBodyValidate(t, testResponse, testResponse)) + + result, err := doPUTRequest[testResultType]( + context.Background(), + client, + "/foo/bar", + testResponse, + ) + if err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(*result, testResponse) { + t.Fatalf("actual response does not equal desired response: %s", cmp.Diff(result, testResponse)) + } +} + +func TestRequestHelpers_delete(t *testing.T) { + client := testutil.CreateMockClient(t, NewClient) + + httpmock.RegisterRegexpResponder( + "DELETE", + testutil.MockRequestURL("/foo/bar/foo%20bar"), + httpmock.NewStringResponder(200, "{}"), + ) + + if err := doDELETERequest( + context.Background(), + client, + formatAPIPath("/foo/bar/%s", "foo bar"), + ); err != nil { + t.Fatal(err) + } +} + +func TestRequestHelpers_paginateAll(t *testing.T) { + client := testutil.CreateMockClient(t, NewClient) + + numRequests := 0 + + httpmock.RegisterRegexpResponder( + "GET", + testutil.MockRequestURL("/foo/bar"), + mockPaginatedResponse( + buildPaginatedEntries(12), + &numRequests, + ), + ) + + response, err := getPaginatedResults[testResultType]( + context.Background(), + client, + "/foo/bar", + &ListOptions{ + PageSize: 4, + Filter: "{\"foo\": \"bar\"}", + }, + ) + if err != nil { + t.Fatal(err) + } + + if numRequests != 3 { + t.Fatalf("expected 3 requests, got %d", numRequests) + } + + if len(response) != 12 { + t.Fatalf("expected 12 results, got %d", len(response)) + } + + for i := 0; i < 12; i++ { + entry := response[i] + if entry.ID != i { + t.Fatalf("expected id %d, got %d", i, entry.ID) + } + } +} + +func TestRequestHelpers_paginateSingle(t *testing.T) { + client := testutil.CreateMockClient(t, NewClient) + + numRequests := 0 + + httpmock.RegisterRegexpResponder( + "GET", + testutil.MockRequestURL("/foo/bar"), + mockPaginatedResponse( + buildPaginatedEntries(12), + &numRequests, + ), + ) + + response, err := getPaginatedResults[testResultType]( + context.Background(), + client, + "/foo/bar", + &ListOptions{ + PageOptions: &PageOptions{ + Page: 3, + }, + }, + ) + if err != nil { + t.Fatal(err) + } + + if numRequests != 1 { + t.Fatalf("expected 1 request, got %d", numRequests) + } + + if len(response) != 3 { + t.Fatalf("expected 3 results, got %d", len(response)) + } + + for i := 0; i < 3; i++ { + entry := response[i] + desiredID := i + 6 + if entry.ID != desiredID { + t.Fatalf("expected id %d, got %d", desiredID, entry.ID) + } + } +} + +func buildPaginatedEntries(numEntries int) []testResultType { + result := make([]testResultType, numEntries) + + for i := 0; i < numEntries; i++ { + result[i] = testResultType{ + Foo: "foo", + ID: i, + } + } + + return result +} + +func mockPaginatedResponse( + entries []testResultType, numRequests *int, +) httpmock.Responder { + return func(request *http.Request) (*http.Response, error) { + *numRequests++ + + // Default page size for testing purposes + pageSize := 3 + + page, err := strconv.Atoi(request.URL.Query().Get("page")) + if err != nil { + return nil, err + } + + if request.URL.Query().Has("page_size") { + pageSize, err = strconv.Atoi(request.URL.Query().Get("page_size")) + if err != nil { + return nil, err + } + } + + return httpmock.NewJsonResponse( + 200, + paginatedResponse[testResultType]{ + Page: page, + Pages: int(math.Ceil(float64(len(entries)) / float64(pageSize))), + Results: pageSize, + Data: entries[pageSize*(page-1) : pageSize*page], + }, + ) + } +} diff --git a/test/go.mod b/test/go.mod index e1308cf1b..9b7b52ca1 100644 --- a/test/go.mod +++ b/test/go.mod @@ -3,11 +3,11 @@ module github.com/linode/linodego/test require ( github.com/dnaeon/go-vcr v1.1.0 github.com/google/go-cmp v0.6.0 - github.com/jarcoal/httpmock v1.2.0 + github.com/jarcoal/httpmock v1.3.1 github.com/linode/linodego v1.25.0 github.com/linode/linodego/k8s v0.0.0-00010101000000-000000000000 golang.org/x/net v0.21.0 - golang.org/x/oauth2 v0.8.0 + golang.org/x/oauth2 v0.17.0 k8s.io/client-go v0.28.1 ) @@ -37,7 +37,7 @@ require ( golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/test/go.sum b/test/go.sum index da9fb1ac0..7d530e00d 100644 --- a/test/go.sum +++ b/test/go.sum @@ -37,8 +37,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/jarcoal/httpmock v1.2.0 h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc= -github.com/jarcoal/httpmock v1.2.0/go.mod h1:oCoTsnAz4+UoOUIf5lJOWV2QQIW5UoeUI6aM2YnWAZk= +github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww= +github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -53,7 +53,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/maxatome/go-testdeep v1.11.0 h1:Tgh5efyCYyJFGUYiT0qxBSIDeXw0F5zSoatlou685kk= +github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -101,8 +101,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= -golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -153,8 +153,8 @@ google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6 google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/test/integration/account_availability_test.go b/test/integration/account_availability_test.go index 4a308ccdd..1c9f96ce5 100644 --- a/test/integration/account_availability_test.go +++ b/test/integration/account_availability_test.go @@ -27,7 +27,6 @@ func TestAccountAvailability_Get(t *testing.T) { regionID := "us-east" availability, err := client.GetAccountAvailability(context.Background(), regionID) - if err != nil { t.Errorf("Error getting Account Availability, expected struct, got error %v", err) } diff --git a/test/integration/account_logins_test.go b/test/integration/account_logins_test.go index 8f4a33151..adeb37d01 100644 --- a/test/integration/account_logins_test.go +++ b/test/integration/account_logins_test.go @@ -10,7 +10,6 @@ func TestAccountLogins_List(t *testing.T) { defer teardown() logins, err := client.ListLogins(context.Background(), nil) - if err != nil { t.Errorf("Error getting Account Logins, expected struct, got error %v", err) } diff --git a/test/integration/betas_test.go b/test/integration/betas_test.go index dbea28b07..4755afa5d 100644 --- a/test/integration/betas_test.go +++ b/test/integration/betas_test.go @@ -29,7 +29,6 @@ func TestBetaProgram_Get(t *testing.T) { betaID := "active_closed" beta, err := client.GetBetaProgram(context.Background(), betaID) - if err != nil { t.Errorf("Error getting Beta program, expected struct, got error %v", err) } @@ -37,5 +36,4 @@ func TestBetaProgram_Get(t *testing.T) { if beta.ID != betaID { t.Errorf("expected beta ID to be %s; got %s", betaID, beta.ID) } - } diff --git a/test/integration/cache_test.go b/test/integration/cache_test.go index 05af3eab1..2c0212f55 100644 --- a/test/integration/cache_test.go +++ b/test/integration/cache_test.go @@ -2,11 +2,12 @@ package integration import ( "context" - "github.com/linode/linodego" "strings" "sync/atomic" "testing" "time" + + "github.com/linode/linodego" ) func TestCache_RegionList(t *testing.T) { diff --git a/test/integration/client_test.go b/test/integration/client_test.go index db55a1c68..2493957c7 100644 --- a/test/integration/client_test.go +++ b/test/integration/client_test.go @@ -2,10 +2,11 @@ package integration import ( "context" - "golang.org/x/net/http2" "net/http" "testing" + "golang.org/x/net/http2" + "github.com/jarcoal/httpmock" "github.com/linode/linodego" ) diff --git a/test/integration/example_integration_test.go b/test/integration/example_integration_test.go index 8a26756b2..7417aa2ab 100644 --- a/test/integration/example_integration_test.go +++ b/test/integration/example_integration_test.go @@ -3,12 +3,13 @@ package integration import ( "context" "fmt" - "github.com/linode/linodego" "log" "math" "math/rand" "os" "strconv" + + "github.com/linode/linodego" ) var spendMoney = false diff --git a/test/integration/fixtures/ExampleListImages_all.yaml b/test/integration/fixtures/ExampleListImages_all.yaml index 2810519e7..55e1851ef 100644 --- a/test/integration/fixtures/ExampleListImages_all.yaml +++ b/test/integration/fixtures/ExampleListImages_all.yaml @@ -11,42 +11,46 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/images + url: https://api.linode.com/v4beta/images?page=1 method: GET response: - body: '{"pages": 1, "data": [{"id": "private/20403225", "label": "splunk-build - - Alpine 3.17 Disk", "description": "", "created": "2018-01-02T03:04:05", "updated": - null, "size": 5463, "created_by": null, "type": "automatic", "is_public": false, + body: '{"pages": 1, "data": [{"id": "private/23849498", "label": "linode54973909 + - AlmaLinux 8 Disk", "description": "", "created": "2018-01-02T03:04:05", "updated": + null, "size": 3719, "created_by": null, "type": "automatic", "is_public": false, "deprecated": false, "vendor": null, "expiry": "2018-01-02T03:04:05", "eol": - null, "status": "available", "capabilities": []}, {"id": "linode/almalinux8", - "label": "AlmaLinux 8", "deprecated": false, "size": 1700, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "AlmaLinux", "expiry": null, - "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": - "linode/almalinux9", "label": "AlmaLinux 9", "deprecated": false, "size": 1700, - "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + null, "status": "available", "capabilities": []}, {"id": "private/23849499", + "label": "linode54973867 - AlmaLinux 8 Disk", "description": "", "created": + "2018-01-02T03:04:05", "updated": null, "size": 3741, "created_by": null, "type": + "automatic", "is_public": false, "deprecated": false, "vendor": null, "expiry": + "2018-01-02T03:04:05", "eol": null, "status": "available", "capabilities": []}, + {"id": "private/23849731", "label": "test-image", "description": "", "created": + "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "size": 358, "created_by": + "lgarber-dev", "type": "manual", "is_public": false, "deprecated": false, "vendor": + null, "expiry": null, "eol": null, "status": "available", "capabilities": []}, + {"id": "linode/almalinux8", "label": "AlmaLinux 8", "deprecated": false, "size": + 1700, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "AlmaLinux", "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": - []}, {"id": "linode/alpine3.14", "label": "Alpine 3.14", "deprecated": false, - "size": 400, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + []}, {"id": "linode/almalinux9", "label": "AlmaLinux 9", "deprecated": false, + "size": 1700, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, - "vendor": "Alpine", "expiry": null, "eol": "2018-01-02T03:04:05", "status": - "available", "capabilities": []}, {"id": "linode/alpine3.15", "label": "Alpine - 3.15", "deprecated": false, "size": 400, "created": "2018-01-02T03:04:05", "updated": + "vendor": "AlmaLinux", "expiry": null, "eol": "2018-01-02T03:04:05", "status": + "available", "capabilities": []}, {"id": "linode/alpine3.16", "label": "Alpine + 3.16", "deprecated": false, "size": 400, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Alpine", "expiry": null, "eol": "2018-01-02T03:04:05", - "status": "available", "capabilities": []}, {"id": "linode/alpine3.16", "label": - "Alpine 3.16", "deprecated": false, "size": 400, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Alpine", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/alpine3.17", - "label": "Alpine 3.17", "deprecated": false, "size": 400, "created": "2018-01-02T03:04:05", + "status": "available", "capabilities": []}, {"id": "linode/alpine3.17", "label": + "Alpine 3.17", "deprecated": false, "size": 400, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Alpine", "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/alpine3.18", "label": "Alpine 3.18", "deprecated": false, "size": 400, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Alpine", "expiry": null, "eol": + "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/alpine3.19", + "label": "Alpine 3.19", "deprecated": false, "size": 400, "created": "2018-01-02T03:04:05", + "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", + "type": "manual", "is_public": true, "vendor": "Alpine", "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/arch", "label": "Arch Linux", "deprecated": false, "size": 1500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", @@ -68,102 +72,126 @@ interactions: "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/debian11", - "label": "Debian 11", "deprecated": false, "size": 1300, "created": "2018-01-02T03:04:05", + "label": "Debian 11", "deprecated": false, "size": 1500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/fedora36", - "label": "Fedora 36", "deprecated": false, "size": 1600, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Fedora", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/fedora37", - "label": "Fedora 37", "deprecated": false, "size": 1800, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Fedora", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/fedora38", - "label": "Fedora 38", "deprecated": false, "size": 1600, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Fedora", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/gentoo", - "label": "Gentoo", "deprecated": false, "size": 5500, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Gentoo", "expiry": null, "eol": - null, "status": "available", "capabilities": []}, {"id": "linode/kali", "label": - "Kali Linux", "deprecated": false, "size": 1536, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Kali", "expiry": null, "eol": - null, "status": "available", "capabilities": []}, {"id": "linode/debian11-kube-v1.24.8", - "label": "Kubernetes 1.24.8 on Debian 11", "deprecated": false, "size": 3500, - "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "2018-01-02T03:04:05", "status": "available", "capabilities": ["cloud-init"]}, + {"id": "linode/debian12", "label": "Debian 12", "deprecated": false, "size": + 1500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": - []}, {"id": "linode/debian11-kube-v1.25.4", "label": "Kubernetes 1.25.4 on Debian + []}, {"id": "linode/fedora38", "label": "Fedora 38", "deprecated": false, "size": + 1600, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Fedora", + "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": + []}, {"id": "linode/fedora39", "label": "Fedora 39", "deprecated": false, "size": + 1800, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Fedora", + "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": + []}, {"id": "linode/gentoo", "label": "Gentoo", "deprecated": false, "size": + 6500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Gentoo", + "expiry": null, "eol": null, "status": "available", "capabilities": []}, {"id": + "linode/kali", "label": "Kali Linux", "deprecated": false, "size": 1536, "created": + "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", + "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Kali", + "expiry": null, "eol": null, "status": "available", "capabilities": []}, {"id": + "linode/debian11-kube-v1.26.1", "label": "Kubernetes 1.26.1 on Debian 11", "deprecated": + false, "size": 3500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "description": "", "created_by": "linode", "type": "manual", "is_public": true, + "vendor": "Debian", "expiry": null, "eol": "2018-01-02T03:04:05", "status": + "available", "capabilities": []}, {"id": "linode/debian11-kube-v1.26.12", "label": + "Kubernetes 1.26.12 on Debian 11", "deprecated": false, "size": 3500, "created": + "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", + "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", + "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": + []}, {"id": "linode/debian11-kube-v1.26.3", "label": "Kubernetes 1.26.3 on Debian 11", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", "expiry": null, "eol": "2018-01-02T03:04:05", - "status": "available", "capabilities": []}, {"id": "linode/debian11-kube-v1.26.1", - "label": "Kubernetes 1.26.1 on Debian 11", "deprecated": false, "size": 3500, + "status": "available", "capabilities": []}, {"id": "linode/debian11-kube-v1.27.5", + "label": "Kubernetes 1.27.5 on Debian 11", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": - []}, {"id": "linode/debian11-kube-v1.26.3", "label": "Kubernetes 1.26.3 on Debian + []}, {"id": "linode/debian11-kube-v1.27.9", "label": "Kubernetes 1.27.9 on Debian 11", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", "expiry": null, "eol": "2018-01-02T03:04:05", - "status": "available", "capabilities": []}, {"id": "linode/opensuse15.4", "label": - "openSUSE Leap 15.4", "deprecated": false, "size": 1550, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "openSUSE", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/rocky8", - "label": "Rocky Linux 8", "deprecated": false, "size": 2300, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Rocky", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/rocky9", - "label": "Rocky Linux 9", "deprecated": false, "size": 2300, "created": "2018-01-02T03:04:05", + "status": "available", "capabilities": []}, {"id": "linode/debian11-kube-v1.28.3", + "label": "Kubernetes 1.28.3 on Debian 11", "deprecated": false, "size": 3500, + "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", + "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": + []}, {"id": "linode/opensuse15.5", "label": "openSUSE Leap 15.5", "deprecated": + false, "size": 1550, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "description": "", "created_by": "linode", "type": "manual", "is_public": true, + "vendor": "openSUSE", "expiry": null, "eol": "2018-01-02T03:04:05", "status": + "available", "capabilities": []}, {"id": "linode/rocky8", "label": "Rocky Linux + 8", "deprecated": false, "size": 2300, "created": "2018-01-02T03:04:05", "updated": + "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", + "is_public": true, "vendor": "Rocky", "expiry": null, "eol": "2018-01-02T03:04:05", + "status": "available", "capabilities": []}, {"id": "linode/rocky9", "label": + "Rocky Linux 9", "deprecated": false, "size": 2300, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Rocky", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/slackware14.2", - "label": "Slackware 14.2", "deprecated": false, "size": 6000, "created": "2018-01-02T03:04:05", + "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/slackware15.0", + "label": "Slackware 15.0", "deprecated": false, "size": 11000, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Slackware", "expiry": null, - "eol": "1970-01-01T05:00:00", "status": "available", "capabilities": []}, {"id": - "linode/slackware15.0", "label": "Slackware 15.0", "deprecated": false, "size": - 11000, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": - "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Slackware", - "expiry": null, "eol": null, "status": "available", "capabilities": []}, {"id": - "linode/ubuntu16.04lts", "label": "Ubuntu 16.04 LTS", "deprecated": false, "size": - 2700, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": - "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Ubuntu", - "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": - []}, {"id": "linode/ubuntu18.04", "label": "Ubuntu 18.04 LTS", "deprecated": - false, "size": 2700, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "eol": null, "status": "available", "capabilities": []}, {"id": "linode/ubuntu20.04", + "label": "Ubuntu 20.04 LTS", "deprecated": false, "size": 2000, "created": "2018-01-02T03:04:05", + "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", + "type": "manual", "is_public": true, "vendor": "Ubuntu", "expiry": null, "eol": + "2018-01-02T03:04:05", "status": "available", "capabilities": ["cloud-init"]}, + {"id": "linode/ubuntu22.04", "label": "Ubuntu 22.04 LTS", "deprecated": false, + "size": 3500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Ubuntu", "expiry": null, "eol": "2018-01-02T03:04:05", "status": - "available", "capabilities": []}, {"id": "linode/ubuntu20.04", "label": "Ubuntu - 20.04 LTS", "deprecated": false, "size": 2000, "created": "2018-01-02T03:04:05", + "available", "capabilities": ["cloud-init"]}, {"id": "linode/ubuntu23.04", "label": + "Ubuntu 23.04", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Ubuntu", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/ubuntu22.04", - "label": "Ubuntu 22.04 LTS", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", + "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/ubuntu23.10", + "label": "Ubuntu 23.10", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Ubuntu", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/ubuntu22.10", - "label": "Ubuntu 22.10", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", + "2018-01-02T03:04:05", "status": "available", "capabilities": ["cloud-init"]}, + {"id": "linode/debian9", "label": "Debian 9", "deprecated": true, "size": 1600, + "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", + "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": + []}, {"id": "linode/fedora37", "label": "Fedora 37", "deprecated": true, "size": + 1800, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Fedora", + "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": + []}, {"id": "linode/opensuse15.4", "label": "openSUSE Leap 15.4", "deprecated": + true, "size": 1550, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "description": "", "created_by": "linode", "type": "manual", "is_public": true, + "vendor": "openSUSE", "expiry": null, "eol": "2018-01-02T03:04:05", "status": + "available", "capabilities": []}, {"id": "linode/slackware14.1", "label": "Slackware + 14.1", "deprecated": true, "size": 1000, "created": "2018-01-02T03:04:05", "updated": + "2018-01-02T03:04:05", "description": null, "created_by": "linode", "type": + "manual", "is_public": true, "vendor": "Slackware", "expiry": null, "eol": "2018-01-02T03:04:05", + "status": "available", "capabilities": []}, {"id": "linode/slackware14.2", "label": + "Slackware 14.2", "deprecated": true, "size": 6000, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Ubuntu", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/ubuntu23.04", - "label": "Ubuntu 23.04", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", + "type": "manual", "is_public": true, "vendor": "Slackware", "expiry": null, + "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": + "linode/ubuntu16.04lts", "label": "Ubuntu 16.04 LTS", "deprecated": true, "size": + 2700, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Ubuntu", + "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": + []}, {"id": "linode/ubuntu18.04", "label": "Ubuntu 18.04 LTS", "deprecated": + true, "size": 2700, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "description": "", "created_by": "linode", "type": "manual", "is_public": true, + "vendor": "Ubuntu", "expiry": null, "eol": "2018-01-02T03:04:05", "status": + "available", "capabilities": []}, {"id": "linode/ubuntu22.10", "label": "Ubuntu + 22.10", "deprecated": true, "size": 3500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Ubuntu", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/debian9", - "label": "Debian 9", "deprecated": true, "size": 1600, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Debian", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/slackware14.1", - "label": "Slackware 14.1", "deprecated": true, "size": 1000, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": null, "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Slackware", "expiry": null, - "eol": null, "status": "available", "capabilities": []}], "results": 36, "page": - 1}' + "2018-01-02T03:04:05", "status": "available", "capabilities": []}], "results": + 42, "page": 1}' headers: Access-Control-Allow-Credentials: - "true" @@ -176,19 +204,23 @@ interactions: Access-Control-Expose-Headers: - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status Cache-Control: - - private, max-age=0, s-maxage=0, no-cache, no-store - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store + Connection: + - keep-alive Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx + Expires: + - Fri, 16 Feb 2024 17:56:11 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 Vary: - Authorization, X-Filter - Authorization, X-Filter + - Accept-Encoding X-Accepted-Oauth-Scopes: - '*' X-Content-Type-Options: @@ -199,7 +231,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "20" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/ExampleListImages_badfilter.yaml b/test/integration/fixtures/ExampleListImages_badfilter.yaml index 4a4ea2d5a..93b06f80f 100644 --- a/test/integration/fixtures/ExampleListImages_badfilter.yaml +++ b/test/integration/fixtures/ExampleListImages_badfilter.yaml @@ -13,7 +13,7 @@ interactions: - linodego/dev https://github.com/linode/linodego X-Filter: - '{"foo":"bar"}' - url: https://api.linode.com/v4beta/images + url: https://api.linode.com/v4beta/images?page=1 method: GET response: body: '{"errors": [{"reason": "Cannot filter on foo", "field": "X-Filter"}]}' @@ -25,13 +25,17 @@ interactions: Access-Control-Allow-Origin: - '*' Cache-Control: - - private, max-age=0, s-maxage=0, no-cache, no-store + - max-age=0, no-cache, no-store + Connection: + - keep-alive Content-Length: - "69" Content-Type: - application/json - Server: - - nginx + Expires: + - Fri, 16 Feb 2024 17:56:11 GMT + Pragma: + - no-cache Vary: - Authorization, X-Filter X-Accepted-Oauth-Scopes: @@ -41,7 +45,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "20" status: 400 Bad Request code: 400 duration: "" diff --git a/test/integration/fixtures/ExampleListImages_notfound.yaml b/test/integration/fixtures/ExampleListImages_notfound.yaml index 234b9d2b7..446422b7a 100644 --- a/test/integration/fixtures/ExampleListImages_notfound.yaml +++ b/test/integration/fixtures/ExampleListImages_notfound.yaml @@ -13,7 +13,7 @@ interactions: - linodego/dev https://github.com/linode/linodego X-Filter: - '{"label":"not-found"}' - url: https://api.linode.com/v4beta/images + url: https://api.linode.com/v4beta/images?page=1 method: GET response: body: '{"pages": 0, "data": [], "results": 0, "page": 0}' @@ -29,16 +29,19 @@ interactions: Access-Control-Expose-Headers: - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status Cache-Control: - - private, max-age=0, s-maxage=0, no-cache, no-store - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store + Connection: + - keep-alive Content-Length: - "49" Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx + Expires: + - Fri, 16 Feb 2024 17:56:11 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 Vary: @@ -54,7 +57,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "20" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestImage_CloudInit.yaml b/test/integration/fixtures/TestImage_CloudInit.yaml index 7c8d250de..4da5abfac 100644 --- a/test/integration/fixtures/TestImage_CloudInit.yaml +++ b/test/integration/fixtures/TestImage_CloudInit.yaml @@ -41,103 +41,173 @@ interactions: 1234::5678, 1234::5678, 1234::5678"}}, {"id": "us-iad", "label": "Washington, DC", "country": "us", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "Managed Databases", "Metadata", "Premium Plans"], - "status": "ok", "resolvers": {"ipv4": "139.144.192.62, 139.144.192.60, 139.144.192.61, 139.144.192.53, 139.144.192.54, 139.144.192.67, 139.144.192.69, 139.144.192.66, 139.144.192.52, 139.144.192.68", - "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, + "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium + Plans"], "status": "ok", "resolvers": {"ipv4": "139.144.192.62, 139.144.192.60, + 139.144.192.61, 139.144.192.53, 139.144.192.54, 139.144.192.67, 139.144.192.69, + 139.144.192.66, 139.144.192.52, 139.144.192.68", "ipv6": "1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678"}}, {"id": "us-ord", "label": "Chicago, IL", "country": "us", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "Managed Databases", "Premium Plans"], "status": "ok", "resolvers": - {"ipv4": "172.232.0.17, 172.232.0.16, 172.232.0.21, 172.232.0.13, 172.232.0.22, 172.232.0.9, 172.232.0.19, 172.232.0.20, 172.232.0.15, 172.232.0.18", + "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans"], "status": + "ok", "resolvers": {"ipv4": "172.232.0.17, 172.232.0.16, 172.232.0.21, 172.232.0.13, 172.232.0.22, 172.232.0.9, 172.232.0.19, 172.232.0.20, 172.232.0.15, 172.232.0.18", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, {"id": "fr-par", "label": "Paris, FR", "country": "fr", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "Managed Databases", "Metadata", "Premium Plans"], "status": "ok", - "resolvers": {"ipv4": "172.232.32.21, 172.232.32.23, 172.232.32.17, 172.232.32.18, 172.232.32.16, 172.232.32.22, 172.232.32.20, 172.232.32.14, 172.232.32.11, 172.232.32.12", + "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans"], "status": + "ok", "resolvers": {"ipv4": "172.232.32.21, 172.232.32.23, 172.232.32.17, 172.232.32.18, 172.232.32.16, 172.232.32.22, 172.232.32.20, 172.232.32.14, 172.232.32.11, 172.232.32.12", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, {"id": "us-sea", "label": "Seattle, WA", "country": "us", "capabilities": ["Linodes", - "NodeBalancers", "Block Storage", "Object Storage", "Cloud Firewall", "Vlans", - "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.232.160.19, 172.232.160.21, - 172.232.160.17, 172.232.160.15, 172.232.160.18, 172.232.160.8, 172.232.160.12, - 172.232.160.11, 172.232.160.14, 172.232.160.16", "ipv6": "1234::5678, + "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", + "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": + {"ipv4": "172.232.160.19, 172.232.160.21, 172.232.160.17, 172.232.160.15, 172.232.160.18, + 172.232.160.8, 172.232.160.12, 172.232.160.11, 172.232.160.14, 172.232.160.16", + "ipv6": "1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678"}}, {"id": "br-gru", "label": "Sao Paulo, BR", + "country": "br", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.233.0.4, 172.233.0.9, + 172.233.0.7, 172.233.0.12, 172.233.0.5, 172.233.0.13, 172.233.0.10, 172.233.0.6, + 172.233.0.8, 172.233.0.11", "ipv6": "1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678"}}, {"id": "nl-ams", + "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", + "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": + "172.233.33.36, 172.233.33.38, 172.233.33.35, 172.233.33.39, 172.233.33.34, + 172.233.33.33, 172.233.33.31, 172.233.33.30, 172.233.33.37, 172.233.33.32", + "ipv6": "1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678"}}, {"id": "se-sto", "label": "Stockholm, SE", + "country": "se", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.232.128.24, 172.232.128.26, + 172.232.128.20, 172.232.128.22, 172.232.128.25, 172.232.128.19, 172.232.128.23, + 172.232.128.18, 172.232.128.21, 172.232.128.27", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, - {"id": "se-sto", "label": "Stockholm, SE", "country": "se", "capabilities": - ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "Managed Databases", "Premium Plans"], "status": - "ok", "resolvers": {"ipv4": "172.232.128.24, 172.232.128.26, 172.232.128.20, - 172.232.128.22, 172.232.128.25, 172.232.128.19, 172.232.128.23, 172.232.128.18, - 172.232.128.21, 172.232.128.27", "ipv6": "1234::5678, 1234::5678, + {"id": "es-mad", "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", + "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", + "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": + {"ipv4": "172.233.111.6, 172.233.111.17, 172.233.111.21, 172.233.111.25, 172.233.111.19, + 172.233.111.12, 172.233.111.26, 172.233.111.16, 172.233.111.18, 172.233.111.9", + "ipv6": "1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, + 1234::5678"}}, {"id": "in-maa", "label": "Chennai, IN", + "country": "in", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.232.96.17, 172.232.96.26, + 172.232.96.19, 172.232.96.20, 172.232.96.25, 172.232.96.21, 172.232.96.18, 172.232.96.22, + 172.232.96.23, 172.232.96.24", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}}, {"id": "in-maa", - "label": "Chennai, IN", "country": "in", "capabilities": ["Linodes", "NodeBalancers", + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678"}}, {"id": "jp-osa", + "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "Managed Databases", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": - "172.232.96.17, 172.232.96.26, 172.232.96.19, 172.232.96.20, 172.232.96.25, 172.232.96.21, 172.232.96.18, 172.232.96.22, 172.232.96.23, 172.232.96.24", - "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, - {"id": "it-mil", "label": "Milan, IT", "country": "it", "capabilities": ["Linodes", - "NodeBalancers", "Block Storage", "Object Storage", "Cloud Firewall", "Vlans", - "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.232.192.19, 172.232.192.18, 172.232.192.16, 172.232.192.20, 172.232.192.24, 172.232.192.21, 172.232.192.22, 172.232.192.17, 172.232.192.15, 172.232.192.23", - "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, - {"id": "id-cgk", "label": "Jakarta, ID", "country": "id", "capabilities": ["Linodes", + "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": + "172.233.64.44, 172.233.64.43, 172.233.64.37, 172.233.64.40, 172.233.64.46, + 172.233.64.41, 172.233.64.39, 172.233.64.42, 172.233.64.45, 172.233.64.38", + "ipv6": "1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678"}}, {"id": "it-mil", "label": "Milan, IT", "country": + "it", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object + Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium + Plans"], "status": "ok", "resolvers": {"ipv4": "172.232.192.19, 172.232.192.18, + 172.232.192.16, 172.232.192.20, 172.232.192.24, 172.232.192.21, 172.232.192.22, + 172.232.192.17, 172.232.192.15, 172.232.192.23", "ipv6": "1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678"}}, + {"id": "us-mia", "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.232.224.23, 172.232.224.32, 172.232.224.26, 172.232.224.27, 172.232.224.21, 172.232.224.24, 172.232.224.22, 172.232.224.20, 172.232.224.31, 172.232.224.28", - "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, - {"id": "us-central", "label": "Dallas, TX", "country": "us", "capabilities": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Block Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": - {"ipv4": "72.14.179.5, 72.14.188.5, 173.255.199.5, 66.228.53.5, 96.126.122.5, - 96.126.124.5, 96.126.127.5, 198.58.107.5, 198.58.111.5, 23.239.24.5", "ipv6": - "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, {"id": "us-west", - "label": "Fremont, CA", "country": "us", "capabilities": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes", "Cloud Firewall", "Block Storage Migrations", - "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "173.230.145.5, - 173.230.147.5, 173.230.155.5, 173.255.212.5, 173.255.219.5, 173.255.241.5, 173.255.243.5, - 173.255.244.5, 74.207.241.5, 74.207.242.5", "ipv6": "1234::5678, 1234::5678, + "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": + {"ipv4": "172.233.160.34, 172.233.160.27, 172.233.160.30, 172.233.160.29, 172.233.160.32, + 172.233.160.28, 172.233.160.33, 172.233.160.26, 172.233.160.25, 172.233.160.31", + "ipv6": "1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678"}}, {"id": "id-cgk", "label": "Jakarta, ID", + "country": "id", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.232.224.23, 172.232.224.32, + 172.232.224.26, 172.232.224.27, 172.232.224.21, 172.232.224.24, 172.232.224.22, + 172.232.224.20, 172.232.224.31, 172.232.224.28", "ipv6": "1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678"}}, + {"id": "us-lax", "label": "Los Angeles, CA", "country": "us", "capabilities": + ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", + "resolvers": {"ipv4": "172.233.128.45, 172.233.128.38, 172.233.128.53, 172.233.128.37, + 172.233.128.34, 172.233.128.36, 172.233.128.33, 172.233.128.39, 172.233.128.43, + 172.233.128.44", "ipv6": "1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678"}}, {"id": "us-central", + "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "72.14.179.5, 72.14.188.5, + 173.255.199.5, 66.228.53.5, 96.126.122.5, 96.126.124.5, 96.126.127.5, 198.58.107.5, + 198.58.111.5, 23.239.24.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}}, {"id": "us-southeast", "label": "Atlanta, GA", - "country": "us", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", - "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": {"ipv4": - "74.207.231.5, 173.230.128.5, 173.230.129.5, 173.230.136.5, 173.230.140.5, 66.228.59.5, - 66.228.62.5, 50.116.35.5, 50.116.41.5, 23.239.18.5", "ipv6": "1234::5678, + 1234::5678"}}, {"id": "us-west", "label": "Fremont, CA", "country": "us", + "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases"], + "status": "ok", "resolvers": {"ipv4": "173.230.145.5, 173.230.147.5, 173.230.155.5, + 173.255.212.5, 173.255.219.5, 173.255.241.5, 173.255.243.5, 173.255.244.5, 74.207.241.5, + 74.207.242.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, + {"id": "us-southeast", "label": "Atlanta, GA", "country": "us", "capabilities": + ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", + "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed + Databases"], "status": "ok", "resolvers": {"ipv4": "74.207.231.5, 173.230.128.5, + 173.230.129.5, 173.230.136.5, 173.230.140.5, 66.228.59.5, 66.228.62.5, 50.116.35.5, + 50.116.41.5, 23.239.18.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}}, {"id": "us-east", "label": "Newark, - NJ", "country": "us", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", - "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Bare Metal", - "Vlans", "Block Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": - {"ipv4": "66.228.42.5, 96.126.106.5, 50.116.53.5, 50.116.58.5, 50.116.61.5, - 50.116.62.5, 66.175.211.5, 97.107.133.4, 207.192.69.4, 207.192.69.5", "ipv6": - "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, {"id": "eu-west", - "label": "London, UK", "country": "gb", "capabilities": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "178.79.182.5, 176.58.107.5, 176.58.116.5, 176.58.121.5, 151.236.220.5, 212.71.252.5, 212.71.253.5, 109.74.192.20, 109.74.193.20, 109.74.194.20", - "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, - {"id": "ap-south", "label": "Singapore, SG", "country": "sg", "capabilities": + 1234::5678"}}, {"id": "us-east", "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed - Databases"], "status": "ok", "resolvers": {"ipv4": "139.162.11.5, 139.162.13.5, - 139.162.14.5, 139.162.15.5, 139.162.16.5, 139.162.21.5, 139.162.27.5, 103.3.60.18, - 103.3.60.19, 103.3.60.20", "ipv6": "1234::5678, 1234::5678, 1234::5678, + Databases"], "status": "ok", "resolvers": {"ipv4": "66.228.42.5, 96.126.106.5, + 50.116.53.5, 50.116.58.5, 50.116.61.5, 50.116.62.5, 66.175.211.5, 97.107.133.4, + 207.192.69.4, 207.192.69.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}}, {"id": "eu-central", "label": "Frankfurt, DE", "country": "de", - "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "139.162.130.5, - 139.162.131.5, 139.162.132.5, 139.162.133.5, 139.162.134.5, 139.162.135.5, 139.162.136.5, - 139.162.137.5, 139.162.138.5, 139.162.139.5", "ipv6": "1234::5678, 1234::5678, + 1234::5678"}}, {"id": "eu-west", "label": "London, UK", "country": "gb", "capabilities": + ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": + {"ipv4": "178.79.182.5, 176.58.107.5, 176.58.116.5, 176.58.121.5, 151.236.220.5, + 212.71.252.5, 212.71.253.5, 109.74.192.20, 109.74.193.20, 109.74.194.20", "ipv6": + "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, {"id": "ap-south", + "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": + {"ipv4": "139.162.11.5, 139.162.13.5, 139.162.14.5, 139.162.15.5, 139.162.16.5, + 139.162.21.5, 139.162.27.5, 103.3.60.18, 103.3.60.19, 103.3.60.20", "ipv6": + "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, {"id": "eu-central", + "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": + {"ipv4": "139.162.130.5, 139.162.131.5, 139.162.132.5, 139.162.133.5, 139.162.134.5, + 139.162.135.5, 139.162.136.5, 139.162.137.5, 139.162.138.5, 139.162.139.5", + "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, {"id": + "ap-northeast", "label": "Tokyo, JP", "country": "jp", "capabilities": ["Linodes", + "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": {"ipv4": + "139.162.66.5, 139.162.67.5, 139.162.68.5, 139.162.69.5, 139.162.70.5, 139.162.71.5, + 139.162.72.5, 139.162.73.5, 139.162.74.5, 139.162.75.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}}, {"id": "ap-northeast", "label": "Tokyo, JP", - "country": "jp", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes", "Cloud Firewall", "Block Storage Migrations", "Managed Databases"], - "status": "ok", "resolvers": {"ipv4": "139.162.66.5, 139.162.67.5, 139.162.68.5, - 139.162.69.5, 139.162.70.5, 139.162.71.5, 139.162.72.5, 139.162.73.5, 139.162.74.5, - 139.162.75.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}], - "page": 1, "pages": 1, "results": 19}' + 1234::5678, 1234::5678, 1234::5678"}}], "page": 1, "pages": 1, "results": + 25}' headers: Access-Control-Allow-Credentials: - "true" @@ -150,19 +220,23 @@ interactions: Access-Control-Expose-Headers: - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status Cache-Control: - - private, max-age=900 - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store + Connection: + - keep-alive Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx + Expires: + - Fri, 16 Feb 2024 17:48:31 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 Vary: - Authorization, X-Filter - Authorization, X-Filter + - Accept-Encoding X-Accepted-Oauth-Scopes: - '*' X-Content-Type-Options: @@ -173,14 +247,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "400" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"region":"us-iad","type":"g6-nanode-1","label":"go-test-ins-pj9yl6ja3466","root_pass":"R34lBAdP455LONGLONGLONGLONG","image":"linode/debian9","booted":false}' + body: '{"region":"us-iad","type":"g6-nanode-1","label":"go-test-ins-3zb14h3crs00","root_pass":"zVg\u0026U2K:Ym]]40oG`eoBkI3btD{Av\\(I[6C9}W1|s7m?me[2$1H\u0026E9m^60NH6y48","image":"linode/debian9","booted":false}' form: {} headers: Accept: @@ -192,15 +266,15 @@ interactions: url: https://api.linode.com/v4beta/linode/instances method: POST response: - body: '{"id": 48318118, "label": "go-test-ins-pj9yl6ja3466", "group": "", "status": + body: '{"id": 55007110, "label": "go-test-ins-3zb14h3crs00", "group": "", "status": "provisioning", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "type": "g6-nanode-1", "ipv4": ["139.144.220.123"], "ipv6": "1234::5678/128", + "type": "g6-nanode-1", "ipv4": ["172.233.227.132"], "ipv6": "1234::5678/128", "image": "linode/debian9", "region": "us-iad", "specs": {"disk": 25600, "memory": 1024, "vcpus": 1, "gpus": 0, "transfer": 1000}, "alerts": {"cpu": 90, "network_in": 10, "network_out": 10, "transfer_quota": 80, "io": 10000}, "backups": {"enabled": false, "available": false, "schedule": {"day": null, "window": null}, "last_successful": null}, "hypervisor": "kvm", "watchdog_enabled": true, "tags": [], "host_uuid": - "f2ba68fc09abb37647b40361d72acf2f8ad6cfb6"}' + "17525a9b784c785585af0acdf8ccd47117e5532c", "has_user_data": false}' headers: Access-Control-Allow-Credentials: - "true" @@ -213,15 +287,19 @@ interactions: Access-Control-Expose-Headers: - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status Cache-Control: - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store + Connection: + - keep-alive Content-Length: - - "718" + - "742" Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx + Expires: + - Fri, 16 Feb 2024 17:48:31 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 Vary: @@ -252,12 +330,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/48318118/disks + url: https://api.linode.com/v4beta/linode/instances/55007110/disks method: GET response: - body: '{"data": [{"id": 96193446, "status": "not ready", "label": "Debian 9 Disk", + body: '{"data": [{"id": 108889104, "status": "not ready", "label": "Debian 9 Disk", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "filesystem": - "ext4", "size": 25088}, {"id": 96193447, "status": "not ready", "label": "512 + "ext4", "size": 25088}, {"id": 108889105, "status": "not ready", "label": "512 MB Swap Image", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "filesystem": "swap", "size": 512}], "page": 1, "pages": 1, "results": 2}' headers: @@ -272,16 +350,19 @@ interactions: Access-Control-Expose-Headers: - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status Cache-Control: - - private, max-age=0, s-maxage=0, no-cache, no-store - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store + Connection: + - keep-alive Content-Length: - - "393" + - "395" Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx + Expires: + - Fri, 16 Feb 2024 17:48:31 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 Vary: @@ -297,14 +378,14 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "400" X-Xss-Protection: - 1; mode=block status: 200 OK code: 200 duration: "" - request: - body: '{"disk_id":96193446,"label":"linodego-test-cloud-init","cloud_init":true}' + body: '{"disk_id":108889104,"label":"linodego-test-cloud-init","cloud_init":true}' form: {} headers: Accept: @@ -316,7 +397,7 @@ interactions: url: https://api.linode.com/v4beta/images method: POST response: - body: '{"id": "private/21112146", "label": "linodego-test-cloud-init", "description": + body: '{"id": "private/23851701", "label": "linodego-test-cloud-init", "description": "", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "size": 25088, "created_by": "lgarber-dev", "type": "manual", "is_public": false, "deprecated": false, "vendor": null, "expiry": null, "eol": null, "status": "creating", "capabilities": @@ -333,15 +414,19 @@ interactions: Access-Control-Expose-Headers: - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status Cache-Control: - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store + Connection: + - keep-alive Content-Length: - "352" Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx + Expires: + - Fri, 16 Feb 2024 17:48:32 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 Vary: @@ -356,7 +441,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "400" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -372,7 +457,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/images/private%2F21112146 + url: https://api.linode.com/v4beta/images/private%2F23851701 method: DELETE response: body: '{}' @@ -388,15 +473,19 @@ interactions: Access-Control-Expose-Headers: - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status Cache-Control: - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store + Connection: + - keep-alive Content-Length: - "2" Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx + Expires: + - Fri, 16 Feb 2024 17:48:32 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 Vary: @@ -411,7 +500,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "400" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -427,7 +516,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/linode/instances/48318118 + url: https://api.linode.com/v4beta/linode/instances/55007110 method: DELETE response: body: '{}' @@ -443,15 +532,19 @@ interactions: Access-Control-Expose-Headers: - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status Cache-Control: - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store + Connection: + - keep-alive Content-Length: - "2" Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx + Expires: + - Fri, 16 Feb 2024 17:48:32 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 Vary: @@ -466,7 +559,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "400" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestImage_CreateUpload.yaml b/test/integration/fixtures/TestImage_CreateUpload.yaml index 5b2dba0b2..9532aa453 100644 --- a/test/integration/fixtures/TestImage_CreateUpload.yaml +++ b/test/integration/fixtures/TestImage_CreateUpload.yaml @@ -41,103 +41,173 @@ interactions: 1234::5678, 1234::5678, 1234::5678"}}, {"id": "us-iad", "label": "Washington, DC", "country": "us", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "Managed Databases", "Metadata", "Premium Plans"], - "status": "ok", "resolvers": {"ipv4": "139.144.192.62, 139.144.192.60, 139.144.192.61, 139.144.192.53, 139.144.192.54, 139.144.192.67, 139.144.192.69, 139.144.192.66, 139.144.192.52, 139.144.192.68", - "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, + "Cloud Firewall", "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium + Plans"], "status": "ok", "resolvers": {"ipv4": "139.144.192.62, 139.144.192.60, + 139.144.192.61, 139.144.192.53, 139.144.192.54, 139.144.192.67, 139.144.192.69, + 139.144.192.66, 139.144.192.52, 139.144.192.68", "ipv6": "1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678"}}, {"id": "us-ord", "label": "Chicago, IL", "country": "us", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "Managed Databases", "Premium Plans"], "status": "ok", "resolvers": - {"ipv4": "172.232.0.17, 172.232.0.16, 172.232.0.21, 172.232.0.13, 172.232.0.22, 172.232.0.9, 172.232.0.19, 172.232.0.20, 172.232.0.15, 172.232.0.18", + "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans"], "status": + "ok", "resolvers": {"ipv4": "172.232.0.17, 172.232.0.16, 172.232.0.21, 172.232.0.13, 172.232.0.22, 172.232.0.9, 172.232.0.19, 172.232.0.20, 172.232.0.15, 172.232.0.18", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, {"id": "fr-par", "label": "Paris, FR", "country": "fr", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "Managed Databases", "Metadata", "Premium Plans"], "status": "ok", - "resolvers": {"ipv4": "172.232.32.21, 172.232.32.23, 172.232.32.17, 172.232.32.18, 172.232.32.16, 172.232.32.22, 172.232.32.20, 172.232.32.14, 172.232.32.11, 172.232.32.12", + "Vlans", "VPCs", "Managed Databases", "Metadata", "Premium Plans"], "status": + "ok", "resolvers": {"ipv4": "172.232.32.21, 172.232.32.23, 172.232.32.17, 172.232.32.18, 172.232.32.16, 172.232.32.22, 172.232.32.20, 172.232.32.14, 172.232.32.11, 172.232.32.12", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, {"id": "us-sea", "label": "Seattle, WA", "country": "us", "capabilities": ["Linodes", - "NodeBalancers", "Block Storage", "Object Storage", "Cloud Firewall", "Vlans", - "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.232.160.19, 172.232.160.21, - 172.232.160.17, 172.232.160.15, 172.232.160.18, 172.232.160.8, 172.232.160.12, - 172.232.160.11, 172.232.160.14, 172.232.160.16", "ipv6": "1234::5678, + "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", + "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": + {"ipv4": "172.232.160.19, 172.232.160.21, 172.232.160.17, 172.232.160.15, 172.232.160.18, + 172.232.160.8, 172.232.160.12, 172.232.160.11, 172.232.160.14, 172.232.160.16", + "ipv6": "1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678"}}, {"id": "br-gru", "label": "Sao Paulo, BR", + "country": "br", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.233.0.4, 172.233.0.9, + 172.233.0.7, 172.233.0.12, 172.233.0.5, 172.233.0.13, 172.233.0.10, 172.233.0.6, + 172.233.0.8, 172.233.0.11", "ipv6": "1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678"}}, {"id": "nl-ams", + "label": "Amsterdam, NL", "country": "nl", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", + "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": + "172.233.33.36, 172.233.33.38, 172.233.33.35, 172.233.33.39, 172.233.33.34, + 172.233.33.33, 172.233.33.31, 172.233.33.30, 172.233.33.37, 172.233.33.32", + "ipv6": "1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678"}}, {"id": "se-sto", "label": "Stockholm, SE", + "country": "se", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.232.128.24, 172.232.128.26, + 172.232.128.20, 172.232.128.22, 172.232.128.25, 172.232.128.19, 172.232.128.23, + 172.232.128.18, 172.232.128.21, 172.232.128.27", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, - {"id": "se-sto", "label": "Stockholm, SE", "country": "se", "capabilities": - ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", - "Cloud Firewall", "Vlans", "Managed Databases", "Premium Plans"], "status": - "ok", "resolvers": {"ipv4": "172.232.128.24, 172.232.128.26, 172.232.128.20, - 172.232.128.22, 172.232.128.25, 172.232.128.19, 172.232.128.23, 172.232.128.18, - 172.232.128.21, 172.232.128.27", "ipv6": "1234::5678, 1234::5678, + {"id": "es-mad", "label": "Madrid, ES", "country": "es", "capabilities": ["Linodes", + "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", + "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": + {"ipv4": "172.233.111.6, 172.233.111.17, 172.233.111.21, 172.233.111.25, 172.233.111.19, + 172.233.111.12, 172.233.111.26, 172.233.111.16, 172.233.111.18, 172.233.111.9", + "ipv6": "1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, + 1234::5678"}}, {"id": "in-maa", "label": "Chennai, IN", + "country": "in", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.232.96.17, 172.232.96.26, + 172.232.96.19, 172.232.96.20, 172.232.96.25, 172.232.96.21, 172.232.96.18, 172.232.96.22, + 172.232.96.23, 172.232.96.24", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}}, {"id": "in-maa", - "label": "Chennai, IN", "country": "in", "capabilities": ["Linodes", "NodeBalancers", + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678"}}, {"id": "jp-osa", + "label": "Osaka, JP", "country": "jp", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", - "Managed Databases", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": - "172.232.96.17, 172.232.96.26, 172.232.96.19, 172.232.96.20, 172.232.96.25, 172.232.96.21, 172.232.96.18, 172.232.96.22, 172.232.96.23, 172.232.96.24", - "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, - {"id": "it-mil", "label": "Milan, IT", "country": "it", "capabilities": ["Linodes", - "NodeBalancers", "Block Storage", "Object Storage", "Cloud Firewall", "Vlans", - "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.232.192.19, 172.232.192.18, 172.232.192.16, 172.232.192.20, 172.232.192.24, 172.232.192.21, 172.232.192.22, 172.232.192.17, 172.232.192.15, 172.232.192.23", - "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, - {"id": "id-cgk", "label": "Jakarta, ID", "country": "id", "capabilities": ["Linodes", + "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": + "172.233.64.44, 172.233.64.43, 172.233.64.37, 172.233.64.40, 172.233.64.46, + 172.233.64.41, 172.233.64.39, 172.233.64.42, 172.233.64.45, 172.233.64.38", + "ipv6": "1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678"}}, {"id": "it-mil", "label": "Milan, IT", "country": + "it", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object + Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium + Plans"], "status": "ok", "resolvers": {"ipv4": "172.232.192.19, 172.232.192.18, + 172.232.192.16, 172.232.192.20, 172.232.192.24, 172.232.192.21, 172.232.192.22, + 172.232.192.17, 172.232.192.15, 172.232.192.23", "ipv6": "1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678"}}, + {"id": "us-mia", "label": "Miami, FL", "country": "us", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", "Cloud Firewall", - "Vlans", "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.232.224.23, 172.232.224.32, 172.232.224.26, 172.232.224.27, 172.232.224.21, 172.232.224.24, 172.232.224.22, 172.232.224.20, 172.232.224.31, 172.232.224.28", - "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, - {"id": "us-central", "label": "Dallas, TX", "country": "us", "capabilities": - ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", - "Block Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": - {"ipv4": "72.14.179.5, 72.14.188.5, 173.255.199.5, 66.228.53.5, 96.126.122.5, - 96.126.124.5, 96.126.127.5, 198.58.107.5, 198.58.111.5, 23.239.24.5", "ipv6": - "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, {"id": "us-west", - "label": "Fremont, CA", "country": "us", "capabilities": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes", "Cloud Firewall", "Block Storage Migrations", - "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "173.230.145.5, - 173.230.147.5, 173.230.155.5, 173.255.212.5, 173.255.219.5, 173.255.241.5, 173.255.243.5, - 173.255.244.5, 74.207.241.5, 74.207.242.5", "ipv6": "1234::5678, 1234::5678, + "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", "resolvers": + {"ipv4": "172.233.160.34, 172.233.160.27, 172.233.160.30, 172.233.160.29, 172.233.160.32, + 172.233.160.28, 172.233.160.33, 172.233.160.26, 172.233.160.25, 172.233.160.31", + "ipv6": "1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678"}}, {"id": "id-cgk", "label": "Jakarta, ID", + "country": "id", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", + "Object Storage", "Kubernetes", "Cloud Firewall", "Vlans", "VPCs", "Metadata", + "Premium Plans"], "status": "ok", "resolvers": {"ipv4": "172.232.224.23, 172.232.224.32, + 172.232.224.26, 172.232.224.27, 172.232.224.21, 172.232.224.24, 172.232.224.22, + 172.232.224.20, 172.232.224.31, 172.232.224.28", "ipv6": "1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678"}}, + {"id": "us-lax", "label": "Los Angeles, CA", "country": "us", "capabilities": + ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "VPCs", "Metadata", "Premium Plans"], "status": "ok", + "resolvers": {"ipv4": "172.233.128.45, 172.233.128.38, 172.233.128.53, 172.233.128.37, + 172.233.128.34, 172.233.128.36, 172.233.128.33, 172.233.128.39, 172.233.128.43, + 172.233.128.44", "ipv6": "1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678"}}, {"id": "us-central", + "label": "Dallas, TX", "country": "us", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", + "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "72.14.179.5, 72.14.188.5, + 173.255.199.5, 66.228.53.5, 96.126.122.5, 96.126.124.5, 96.126.127.5, 198.58.107.5, + 198.58.111.5, 23.239.24.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}}, {"id": "us-southeast", "label": "Atlanta, GA", - "country": "us", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", - "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block - Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": {"ipv4": - "74.207.231.5, 173.230.128.5, 173.230.129.5, 173.230.136.5, 173.230.140.5, 66.228.59.5, - 66.228.62.5, 50.116.35.5, 50.116.41.5, 23.239.18.5", "ipv6": "1234::5678, + 1234::5678"}}, {"id": "us-west", "label": "Fremont, CA", "country": "us", + "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes", + "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed Databases"], + "status": "ok", "resolvers": {"ipv4": "173.230.145.5, 173.230.147.5, 173.230.155.5, + 173.255.212.5, 173.255.219.5, 173.255.241.5, 173.255.243.5, 173.255.244.5, 74.207.241.5, + 74.207.242.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, + {"id": "us-southeast", "label": "Atlanta, GA", "country": "us", "capabilities": + ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", + "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed + Databases"], "status": "ok", "resolvers": {"ipv4": "74.207.231.5, 173.230.128.5, + 173.230.129.5, 173.230.136.5, 173.230.140.5, 66.228.59.5, 66.228.62.5, 50.116.35.5, + 50.116.41.5, 23.239.18.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678"}}, {"id": "us-east", "label": "Newark, - NJ", "country": "us", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", - "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Bare Metal", - "Vlans", "Block Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": - {"ipv4": "66.228.42.5, 96.126.106.5, 50.116.53.5, 50.116.58.5, 50.116.61.5, - 50.116.62.5, 66.175.211.5, 97.107.133.4, 207.192.69.4, 207.192.69.5", "ipv6": - "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, {"id": "eu-west", - "label": "London, UK", "country": "gb", "capabilities": ["Linodes", "NodeBalancers", - "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "178.79.182.5, 176.58.107.5, 176.58.116.5, 176.58.121.5, 151.236.220.5, 212.71.252.5, 212.71.253.5, 109.74.192.20, 109.74.193.20, 109.74.194.20", - "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, - {"id": "ap-south", "label": "Singapore, SG", "country": "sg", "capabilities": + 1234::5678"}}, {"id": "us-east", "label": "Newark, NJ", "country": "us", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", "Managed - Databases"], "status": "ok", "resolvers": {"ipv4": "139.162.11.5, 139.162.13.5, - 139.162.14.5, 139.162.15.5, 139.162.16.5, 139.162.21.5, 139.162.27.5, 103.3.60.18, - 103.3.60.19, 103.3.60.20", "ipv6": "1234::5678, 1234::5678, 1234::5678, + Databases"], "status": "ok", "resolvers": {"ipv4": "66.228.42.5, 96.126.106.5, + 50.116.53.5, 50.116.58.5, 50.116.61.5, 50.116.62.5, 66.175.211.5, 97.107.133.4, + 207.192.69.4, 207.192.69.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678"}}, {"id": "eu-central", "label": "Frankfurt, DE", "country": "de", - "capabilities": ["Linodes", "NodeBalancers", "Block Storage", "Object Storage", - "GPU Linodes", "Kubernetes", "Cloud Firewall", "Vlans", "Block Storage Migrations", - "Managed Databases"], "status": "ok", "resolvers": {"ipv4": "139.162.130.5, - 139.162.131.5, 139.162.132.5, 139.162.133.5, 139.162.134.5, 139.162.135.5, 139.162.136.5, - 139.162.137.5, 139.162.138.5, 139.162.139.5", "ipv6": "1234::5678, 1234::5678, + 1234::5678"}}, {"id": "eu-west", "label": "London, UK", "country": "gb", "capabilities": + ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": + {"ipv4": "178.79.182.5, 176.58.107.5, 176.58.116.5, 176.58.121.5, 151.236.220.5, + 212.71.252.5, 212.71.253.5, 109.74.192.20, 109.74.193.20, 109.74.194.20", "ipv6": + "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, {"id": "ap-south", + "label": "Singapore, SG", "country": "sg", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": + {"ipv4": "139.162.11.5, 139.162.13.5, 139.162.14.5, 139.162.15.5, 139.162.16.5, + 139.162.21.5, 139.162.27.5, 103.3.60.18, 103.3.60.19, 103.3.60.20", "ipv6": + "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, {"id": "eu-central", + "label": "Frankfurt, DE", "country": "de", "capabilities": ["Linodes", "NodeBalancers", + "Block Storage", "Object Storage", "GPU Linodes", "Kubernetes", "Cloud Firewall", + "Vlans", "Block Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": + {"ipv4": "139.162.130.5, 139.162.131.5, 139.162.132.5, 139.162.133.5, 139.162.134.5, + 139.162.135.5, 139.162.136.5, 139.162.137.5, 139.162.138.5, 139.162.139.5", + "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, + 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}, {"id": + "ap-northeast", "label": "Tokyo, JP", "country": "jp", "capabilities": ["Linodes", + "NodeBalancers", "Block Storage", "Kubernetes", "Cloud Firewall", "Vlans", "Block + Storage Migrations", "Managed Databases"], "status": "ok", "resolvers": {"ipv4": + "139.162.66.5, 139.162.67.5, 139.162.68.5, 139.162.69.5, 139.162.70.5, 139.162.71.5, + 139.162.72.5, 139.162.73.5, 139.162.74.5, 139.162.75.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678"}}, {"id": "ap-northeast", "label": "Tokyo, JP", - "country": "jp", "capabilities": ["Linodes", "NodeBalancers", "Block Storage", - "Kubernetes", "Cloud Firewall", "Block Storage Migrations", "Managed Databases"], - "status": "ok", "resolvers": {"ipv4": "139.162.66.5, 139.162.67.5, 139.162.68.5, - 139.162.69.5, 139.162.70.5, 139.162.71.5, 139.162.72.5, 139.162.73.5, 139.162.74.5, - 139.162.75.5", "ipv6": "1234::5678, 1234::5678, 1234::5678, 1234::5678, - 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678, 1234::5678"}}], - "page": 1, "pages": 1, "results": 19}' + 1234::5678, 1234::5678, 1234::5678"}}], "page": 1, "pages": 1, "results": + 25}' headers: Access-Control-Allow-Credentials: - "true" @@ -150,19 +220,23 @@ interactions: Access-Control-Expose-Headers: - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status Cache-Control: - - private, max-age=900 - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store + Connection: + - keep-alive Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx + Expires: + - Fri, 16 Feb 2024 17:48:29 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 Vary: - Authorization, X-Filter - Authorization, X-Filter + - Accept-Encoding X-Accepted-Oauth-Scopes: - '*' X-Content-Type-Options: @@ -173,7 +247,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "400" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -193,8 +267,8 @@ interactions: url: https://api.linode.com/v4beta/images/upload method: POST response: - body: '{"upload_to": "https://us-iad-1.linodeobjects.com:443/linode-production-machine-images-uploads/21112145?Signature=FA2n9yO2%2FXWQa1SrF8WADuYsrZM%3D&Expires=1691078230&AWSAccessKeyID=SANITIZED", - "image": {"id": "private/21112145", "label": "linodego-image-create-upload", + body: '{"upload_to": "https://us-iad-1.linodeobjects.com:443/linode-production-machine-images-uploads/23851700?Signature=VrqcwsOn48f%2Bs%2FrebQh06qdUkAo%3D&Expires=1708192110&AWSAccessKeyID=SANITIZED", + "image": {"id": "private/23851700", "label": "linodego-image-create-upload", "description": "An image that does stuff.", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "size": 0, "created_by": "lgarber-dev", "type": "manual", "is_public": false, "deprecated": false, "vendor": null, "expiry": @@ -211,15 +285,19 @@ interactions: Access-Control-Expose-Headers: - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status Cache-Control: - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store + Connection: + - keep-alive Content-Length: - - "597" + - "599" Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx + Expires: + - Fri, 16 Feb 2024 17:48:30 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 Vary: @@ -234,7 +312,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "400" X-Xss-Protection: - 1; mode=block status: 200 OK @@ -250,7 +328,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/images/private%2F21112145 + url: https://api.linode.com/v4beta/images/private%2F23851700 method: DELETE response: body: '{}' @@ -266,15 +344,19 @@ interactions: Access-Control-Expose-Headers: - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status Cache-Control: - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store + Connection: + - keep-alive Content-Length: - "2" Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx + Expires: + - Fri, 16 Feb 2024 17:48:30 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 Vary: @@ -289,7 +371,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "400" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestImage_GetFound.yaml b/test/integration/fixtures/TestImage_GetFound.yaml index b32e4e9a2..35154d2b4 100644 --- a/test/integration/fixtures/TestImage_GetFound.yaml +++ b/test/integration/fixtures/TestImage_GetFound.yaml @@ -15,7 +15,7 @@ interactions: method: GET response: body: '{"id": "linode/ubuntu16.04lts", "label": "Ubuntu 16.04 LTS", "deprecated": - false, "size": 2700, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + true, "size": 2700, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Ubuntu", "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": []}' @@ -31,16 +31,19 @@ interactions: Access-Control-Expose-Headers: - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status Cache-Control: - - private, max-age=0, s-maxage=0, no-cache, no-store - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store + Connection: + - keep-alive Content-Length: - - "352" + - "351" Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx + Expires: + - Fri, 16 Feb 2024 17:47:58 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 Vary: @@ -56,7 +59,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "400" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/fixtures/TestImage_GetMissing.yaml b/test/integration/fixtures/TestImage_GetMissing.yaml index 3fd2fa791..cd4238db2 100644 --- a/test/integration/fixtures/TestImage_GetMissing.yaml +++ b/test/integration/fixtures/TestImage_GetMissing.yaml @@ -23,13 +23,17 @@ interactions: Access-Control-Allow-Origin: - '*' Cache-Control: - - private, max-age=0, s-maxage=0, no-cache, no-store + - max-age=0, no-cache, no-store + Connection: + - keep-alive Content-Length: - "37" Content-Type: - application/json - Server: - - nginx + Expires: + - Fri, 16 Feb 2024 17:47:58 GMT + Pragma: + - no-cache Vary: - Authorization, X-Filter X-Accepted-Oauth-Scopes: @@ -39,7 +43,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "400" status: 404 Not Found code: 404 duration: "" diff --git a/test/integration/fixtures/TestImage_Upload.yaml b/test/integration/fixtures/TestImage_Upload.yaml index b1b29bf0f..6c41989b8 100644 --- a/test/integration/fixtures/TestImage_Upload.yaml +++ b/test/integration/fixtures/TestImage_Upload.yaml @@ -15,10 +15,10 @@ interactions: url: https://api.linode.com/v4beta/images/upload method: POST response: - body: '{"upload_to": "https://us-ord-1.linodeobjects.com:443/linode-production-machine-images-uploads/22961819?Signature=GRF9N7TR3tEl1JPipZFOT%2FKQd9g%3D&Expires=1702420468&AWSAccessKeyID=SANITIZED", - "image": {"id": "private/22961819", "label": "linodego-image-test", "description": + body: '{"upload_to": "https://us-ord-1.linodeobjects.com:443/linode-production-machine-images-uploads/23851696?Signature=Sv2YDjn0fC5o6oi2YBHDPIdLOz4%3D&Expires=1708192079&AWSAccessKeyID=SANITIZED", + "image": {"id": "private/23851696", "label": "linodego-image-test", "description": "An image that does stuff.", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "size": 0, "created_by": "youjungk01", "type": "manual", "is_public": false, + "size": 0, "created_by": "lgarber-dev", "type": "manual", "is_public": false, "deprecated": false, "vendor": null, "expiry": null, "eol": null, "status": "pending_upload", "capabilities": []}}' headers: @@ -37,13 +37,13 @@ interactions: Connection: - keep-alive Content-Length: - - "575" + - "574" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 11 Dec 2023 22:34:28 GMT + - Fri, 16 Feb 2024 17:47:59 GMT Pragma: - no-cache Strict-Transport-Security: @@ -76,12 +76,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/images/private%2F22961819 + url: https://api.linode.com/v4beta/images/private%2F23851696 method: GET response: - body: '{"id": "private/22961819", "label": "linodego-image-test", "description": + body: '{"id": "private/23851696", "label": "linodego-image-test", "description": "An image that does stuff.", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "size": 0, "created_by": "youjungk01", "type": "manual", "is_public": false, + "size": 0, "created_by": "lgarber-dev", "type": "manual", "is_public": false, "deprecated": false, "vendor": null, "expiry": null, "eol": null, "status": "pending_upload", "capabilities": []}' headers: @@ -100,13 +100,13 @@ interactions: Connection: - keep-alive Content-Length: - - "361" + - "362" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 11 Dec 2023 22:34:43 GMT + - Fri, 16 Feb 2024 17:48:14 GMT Pragma: - no-cache Strict-Transport-Security: @@ -140,76 +140,12 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/images/private%2F22961819 + url: https://api.linode.com/v4beta/images/private%2F23851696 method: GET response: - body: '{"id": "private/22961819", "label": "linodego-image-test", "description": + body: '{"id": "private/23851696", "label": "linodego-image-test", "description": "An image that does stuff.", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "size": 0, "created_by": "youjungk01", "type": "manual", "is_public": false, - "deprecated": false, "vendor": null, "expiry": null, "eol": null, "status": - "pending_upload", "capabilities": []}' - headers: - Access-Control-Allow-Credentials: - - "true" - Access-Control-Allow-Headers: - - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter - Access-Control-Allow-Methods: - - HEAD, GET, OPTIONS, POST, PUT, DELETE - Access-Control-Allow-Origin: - - '*' - Access-Control-Expose-Headers: - - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status - Cache-Control: - - max-age=0, no-cache, no-store - Connection: - - keep-alive - Content-Length: - - "361" - Content-Security-Policy: - - default-src 'none' - Content-Type: - - application/json - Expires: - - Mon, 11 Dec 2023 22:34:59 GMT - Pragma: - - no-cache - Strict-Transport-Security: - - max-age=31536000 - Vary: - - Authorization, X-Filter - - Authorization, X-Filter - X-Accepted-Oauth-Scopes: - - images:read_only - X-Content-Type-Options: - - nosniff - X-Frame-Options: - - DENY - - DENY - X-Oauth-Scopes: - - '*' - X-Ratelimit-Limit: - - "400" - X-Xss-Protection: - - 1; mode=block - status: 200 OK - code: 200 - duration: "" -- request: - body: "" - form: {} - headers: - Accept: - - application/json - Content-Type: - - application/json - User-Agent: - - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/images/private%2F22961819 - method: GET - response: - body: '{"id": "private/22961819", "label": "linodego-image-test", "description": - "An image that does stuff.", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "size": 1, "created_by": "youjungk01", "type": "manual", "is_public": false, + "size": 1, "created_by": "lgarber-dev", "type": "manual", "is_public": false, "deprecated": false, "vendor": null, "expiry": null, "eol": null, "status": "available", "capabilities": []}' headers: @@ -228,13 +164,13 @@ interactions: Connection: - keep-alive Content-Length: - - "356" + - "357" Content-Security-Policy: - default-src 'none' Content-Type: - application/json Expires: - - Mon, 11 Dec 2023 22:35:14 GMT + - Fri, 16 Feb 2024 17:48:29 GMT Pragma: - no-cache Strict-Transport-Security: @@ -268,7 +204,7 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/images/private%2F22961819 + url: https://api.linode.com/v4beta/images/private%2F23851696 method: DELETE response: body: '{}' @@ -294,7 +230,7 @@ interactions: Content-Type: - application/json Expires: - - Mon, 11 Dec 2023 22:35:14 GMT + - Fri, 16 Feb 2024 17:48:29 GMT Pragma: - no-cache Strict-Transport-Security: diff --git a/test/integration/fixtures/TestImages_List.yaml b/test/integration/fixtures/TestImages_List.yaml index c422dcbd2..6a5b84adb 100644 --- a/test/integration/fixtures/TestImages_List.yaml +++ b/test/integration/fixtures/TestImages_List.yaml @@ -11,59 +11,46 @@ interactions: - application/json User-Agent: - linodego/dev https://github.com/linode/linodego - url: https://api.linode.com/v4beta/images + url: https://api.linode.com/v4beta/images?page=1 method: GET response: - body: '{"pages": 1, "data": [{"id": "private/21037832", "label": "packer-image-20230726161731", - "description": "Packer Sandbox Image", "created": "2018-01-02T03:04:05", "updated": - "2018-01-02T03:04:05", "size": 1480, "created_by": "lgarber-dev", "type": "manual", - "is_public": false, "deprecated": false, "vendor": null, "expiry": null, "eol": - null, "status": "available", "capabilities": []}, {"id": "private/21037876", - "label": "packer-image-20230726162148", "description": "Packer Sandbox Image", - "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "size": - 1480, "created_by": "lgarber-dev", "type": "manual", "is_public": false, "deprecated": - false, "vendor": null, "expiry": null, "eol": null, "status": "available", "capabilities": - []}, {"id": "private/21038088", "label": "packer-image-20230726164246", "description": - "Packer Sandbox Image", "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "size": 3913, "created_by": "lgarber-dev", "type": "manual", "is_public": false, - "deprecated": false, "vendor": null, "expiry": null, "eol": null, "status": - "available", "capabilities": []}, {"id": "private/21038204", "label": "vault-test - - Alpine 3.18 Disk", "description": "", "created": "2018-01-02T03:04:05", "updated": - null, "size": 381, "created_by": null, "type": "automatic", "is_public": false, + body: '{"pages": 1, "data": [{"id": "private/23849498", "label": "linode54973909 + - AlmaLinux 8 Disk", "description": "", "created": "2018-01-02T03:04:05", "updated": + null, "size": 3719, "created_by": null, "type": "automatic", "is_public": false, "deprecated": false, "vendor": null, "expiry": "2018-01-02T03:04:05", "eol": - null, "status": "available", "capabilities": []}, {"id": "private/21100915", - "label": "ami-ubuntu-22.04-20230801.1835", "description": "Ubuntu 22.04 LTS", - "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "size": - 7272, "created_by": "lgarber-dev", "type": "manual", "is_public": false, "deprecated": - false, "vendor": null, "expiry": null, "eol": null, "status": "available", "capabilities": - []}, {"id": "linode/almalinux8", "label": "AlmaLinux 8", "deprecated": false, + null, "status": "available", "capabilities": []}, {"id": "private/23849499", + "label": "linode54973867 - AlmaLinux 8 Disk", "description": "", "created": + "2018-01-02T03:04:05", "updated": null, "size": 3741, "created_by": null, "type": + "automatic", "is_public": false, "deprecated": false, "vendor": null, "expiry": + "2018-01-02T03:04:05", "eol": null, "status": "available", "capabilities": []}, + {"id": "private/23849731", "label": "test-image", "description": "", "created": + "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "size": 358, "created_by": + "lgarber-dev", "type": "manual", "is_public": false, "deprecated": false, "vendor": + null, "expiry": null, "eol": null, "status": "available", "capabilities": []}, + {"id": "linode/almalinux8", "label": "AlmaLinux 8", "deprecated": false, "size": + 1700, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "AlmaLinux", + "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": + []}, {"id": "linode/almalinux9", "label": "AlmaLinux 9", "deprecated": false, "size": 1700, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "AlmaLinux", "expiry": null, "eol": "2018-01-02T03:04:05", "status": - "available", "capabilities": []}, {"id": "linode/almalinux9", "label": "AlmaLinux - 9", "deprecated": false, "size": 1700, "created": "2018-01-02T03:04:05", "updated": + "available", "capabilities": []}, {"id": "linode/alpine3.16", "label": "Alpine + 3.16", "deprecated": false, "size": 400, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", - "is_public": true, "vendor": "AlmaLinux", "expiry": null, "eol": "2018-01-02T03:04:05", - "status": "available", "capabilities": []}, {"id": "linode/alpine3.14", "label": - "Alpine 3.14", "deprecated": false, "size": 400, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Alpine", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/alpine3.15", - "label": "Alpine 3.15", "deprecated": false, "size": 400, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Alpine", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/alpine3.16", - "label": "Alpine 3.16", "deprecated": false, "size": 400, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Alpine", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/alpine3.17", - "label": "Alpine 3.17", "deprecated": false, "size": 400, "created": "2018-01-02T03:04:05", + "is_public": true, "vendor": "Alpine", "expiry": null, "eol": "2018-01-02T03:04:05", + "status": "available", "capabilities": []}, {"id": "linode/alpine3.17", "label": + "Alpine 3.17", "deprecated": false, "size": 400, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Alpine", "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/alpine3.18", "label": "Alpine 3.18", "deprecated": false, "size": 400, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Alpine", "expiry": null, "eol": + "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/alpine3.19", + "label": "Alpine 3.19", "deprecated": false, "size": 400, "created": "2018-01-02T03:04:05", + "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", + "type": "manual", "is_public": true, "vendor": "Alpine", "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/arch", "label": "Arch Linux", "deprecated": false, "size": 1500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", @@ -85,82 +72,75 @@ interactions: "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/debian11", - "label": "Debian 11", "deprecated": false, "size": 1300, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Debian", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/debian12", - "label": "Debian 12", "deprecated": false, "size": 1500, "created": "2018-01-02T03:04:05", + "label": "Debian 11", "deprecated": false, "size": 1500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/fedora36", - "label": "Fedora 36", "deprecated": false, "size": 1600, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Fedora", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/fedora37", - "label": "Fedora 37", "deprecated": false, "size": 1800, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Fedora", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/fedora38", - "label": "Fedora 38", "deprecated": false, "size": 1600, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Fedora", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/gentoo", - "label": "Gentoo", "deprecated": false, "size": 5500, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Gentoo", "expiry": null, "eol": - null, "status": "available", "capabilities": []}, {"id": "linode/kali", "label": - "Kali Linux", "deprecated": false, "size": 1536, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Kali", "expiry": null, "eol": - null, "status": "available", "capabilities": []}, {"id": "linode/debian11-kube-v1.25.4", - "label": "Kubernetes 1.25.4 on Debian 11", "deprecated": false, "size": 3500, + "2018-01-02T03:04:05", "status": "available", "capabilities": ["cloud-init"]}, + {"id": "linode/debian12", "label": "Debian 12", "deprecated": false, "size": + 1500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", + "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": + []}, {"id": "linode/fedora38", "label": "Fedora 38", "deprecated": false, "size": + 1600, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Fedora", + "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": + []}, {"id": "linode/fedora39", "label": "Fedora 39", "deprecated": false, "size": + 1800, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Fedora", + "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": + []}, {"id": "linode/gentoo", "label": "Gentoo", "deprecated": false, "size": + 6500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Gentoo", + "expiry": null, "eol": null, "status": "available", "capabilities": []}, {"id": + "linode/kali", "label": "Kali Linux", "deprecated": false, "size": 1536, "created": + "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", + "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Kali", + "expiry": null, "eol": null, "status": "available", "capabilities": []}, {"id": + "linode/debian11-kube-v1.26.1", "label": "Kubernetes 1.26.1 on Debian 11", "deprecated": + false, "size": 3500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "description": "", "created_by": "linode", "type": "manual", "is_public": true, + "vendor": "Debian", "expiry": null, "eol": "2018-01-02T03:04:05", "status": + "available", "capabilities": []}, {"id": "linode/debian11-kube-v1.26.12", "label": + "Kubernetes 1.26.12 on Debian 11", "deprecated": false, "size": 3500, "created": + "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", + "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", + "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": + []}, {"id": "linode/debian11-kube-v1.26.3", "label": "Kubernetes 1.26.3 on Debian + 11", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", "updated": + "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", + "is_public": true, "vendor": "Debian", "expiry": null, "eol": "2018-01-02T03:04:05", + "status": "available", "capabilities": []}, {"id": "linode/debian11-kube-v1.27.5", + "label": "Kubernetes 1.27.5 on Debian 11", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": - []}, {"id": "linode/debian11-kube-v1.26.1", "label": "Kubernetes 1.26.1 on Debian + []}, {"id": "linode/debian11-kube-v1.27.9", "label": "Kubernetes 1.27.9 on Debian 11", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", "expiry": null, "eol": "2018-01-02T03:04:05", - "status": "available", "capabilities": []}, {"id": "linode/debian11-kube-v1.26.3", - "label": "Kubernetes 1.26.3 on Debian 11", "deprecated": false, "size": 3500, + "status": "available", "capabilities": []}, {"id": "linode/debian11-kube-v1.28.3", + "label": "Kubernetes 1.28.3 on Debian 11", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": - []}, {"id": "linode/opensuse15.4", "label": "openSUSE Leap 15.4", "deprecated": + []}, {"id": "linode/opensuse15.5", "label": "openSUSE Leap 15.5", "deprecated": false, "size": 1550, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "openSUSE", "expiry": null, "eol": "2018-01-02T03:04:05", "status": - "available", "capabilities": []}, {"id": "linode/opensuse15.5", "label": "openSUSE - Leap 15.5", "deprecated": false, "size": 1550, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "openSUSE", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/rocky8", - "label": "Rocky Linux 8", "deprecated": false, "size": 2300, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Rocky", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/rocky9", - "label": "Rocky Linux 9", "deprecated": false, "size": 2300, "created": "2018-01-02T03:04:05", + "available", "capabilities": []}, {"id": "linode/rocky8", "label": "Rocky Linux + 8", "deprecated": false, "size": 2300, "created": "2018-01-02T03:04:05", "updated": + "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", + "is_public": true, "vendor": "Rocky", "expiry": null, "eol": "2018-01-02T03:04:05", + "status": "available", "capabilities": []}, {"id": "linode/rocky9", "label": + "Rocky Linux 9", "deprecated": false, "size": 2300, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Rocky", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/slackware14.2", - "label": "Slackware 14.2", "deprecated": false, "size": 6000, "created": "2018-01-02T03:04:05", + "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/slackware15.0", + "label": "Slackware 15.0", "deprecated": false, "size": 11000, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Slackware", "expiry": null, - "eol": "1970-01-01T05:00:00", "status": "available", "capabilities": []}, {"id": - "linode/slackware15.0", "label": "Slackware 15.0", "deprecated": false, "size": - 11000, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": - "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Slackware", - "expiry": null, "eol": null, "status": "available", "capabilities": []}, {"id": - "linode/ubuntu16.04lts", "label": "Ubuntu 16.04 LTS", "deprecated": false, "size": - 2700, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": - "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Ubuntu", - "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": - []}, {"id": "linode/ubuntu18.04", "label": "Ubuntu 18.04 LTS", "deprecated": - false, "size": 2700, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", - "description": "", "created_by": "linode", "type": "manual", "is_public": true, - "vendor": "Ubuntu", "expiry": null, "eol": "2018-01-02T03:04:05", "status": - "available", "capabilities": []}, {"id": "linode/ubuntu20.04", "label": "Ubuntu - 20.04 LTS", "deprecated": false, "size": 2000, "created": "2018-01-02T03:04:05", + "eol": null, "status": "available", "capabilities": []}, {"id": "linode/ubuntu20.04", + "label": "Ubuntu 20.04 LTS", "deprecated": false, "size": 2000, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Ubuntu", "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": ["cloud-init"]}, @@ -168,24 +148,50 @@ interactions: "size": 3500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Ubuntu", "expiry": null, "eol": "2018-01-02T03:04:05", "status": - "available", "capabilities": ["cloud-init"]}, {"id": "linode/ubuntu22.10", "label": - "Ubuntu 22.10", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", + "available", "capabilities": ["cloud-init"]}, {"id": "linode/ubuntu23.04", "label": + "Ubuntu 23.04", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Ubuntu", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/ubuntu23.04", - "label": "Ubuntu 23.04", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", + "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/ubuntu23.10", + "label": "Ubuntu 23.10", "deprecated": false, "size": 3500, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Ubuntu", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/debian9", - "label": "Debian 9", "deprecated": true, "size": 1600, "created": "2018-01-02T03:04:05", + "2018-01-02T03:04:05", "status": "available", "capabilities": ["cloud-init"]}, + {"id": "linode/debian9", "label": "Debian 9", "deprecated": true, "size": 1600, + "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Debian", + "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": + []}, {"id": "linode/fedora37", "label": "Fedora 37", "deprecated": true, "size": + 1800, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Fedora", + "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": + []}, {"id": "linode/opensuse15.4", "label": "openSUSE Leap 15.4", "deprecated": + true, "size": 1550, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "description": "", "created_by": "linode", "type": "manual", "is_public": true, + "vendor": "openSUSE", "expiry": null, "eol": "2018-01-02T03:04:05", "status": + "available", "capabilities": []}, {"id": "linode/slackware14.1", "label": "Slackware + 14.1", "deprecated": true, "size": 1000, "created": "2018-01-02T03:04:05", "updated": + "2018-01-02T03:04:05", "description": null, "created_by": "linode", "type": + "manual", "is_public": true, "vendor": "Slackware", "expiry": null, "eol": "2018-01-02T03:04:05", + "status": "available", "capabilities": []}, {"id": "linode/slackware14.2", "label": + "Slackware 14.2", "deprecated": true, "size": 6000, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", - "type": "manual", "is_public": true, "vendor": "Debian", "expiry": null, "eol": - "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": "linode/slackware14.1", - "label": "Slackware 14.1", "deprecated": true, "size": 1000, "created": "2018-01-02T03:04:05", - "updated": "2018-01-02T03:04:05", "description": null, "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Slackware", "expiry": null, - "eol": null, "status": "available", "capabilities": []}], "results": 41, "page": - 1}' + "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": []}, {"id": + "linode/ubuntu16.04lts", "label": "Ubuntu 16.04 LTS", "deprecated": true, "size": + 2700, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", "description": + "", "created_by": "linode", "type": "manual", "is_public": true, "vendor": "Ubuntu", + "expiry": null, "eol": "2018-01-02T03:04:05", "status": "available", "capabilities": + []}, {"id": "linode/ubuntu18.04", "label": "Ubuntu 18.04 LTS", "deprecated": + true, "size": 2700, "created": "2018-01-02T03:04:05", "updated": "2018-01-02T03:04:05", + "description": "", "created_by": "linode", "type": "manual", "is_public": true, + "vendor": "Ubuntu", "expiry": null, "eol": "2018-01-02T03:04:05", "status": + "available", "capabilities": []}, {"id": "linode/ubuntu22.10", "label": "Ubuntu + 22.10", "deprecated": true, "size": 3500, "created": "2018-01-02T03:04:05", + "updated": "2018-01-02T03:04:05", "description": "", "created_by": "linode", + "type": "manual", "is_public": true, "vendor": "Ubuntu", "expiry": null, "eol": + "2018-01-02T03:04:05", "status": "available", "capabilities": []}], "results": + 42, "page": 1}' headers: Access-Control-Allow-Credentials: - "true" @@ -198,19 +204,23 @@ interactions: Access-Control-Expose-Headers: - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status Cache-Control: - - private, max-age=0, s-maxage=0, no-cache, no-store - - private, max-age=60, s-maxage=60 + - max-age=0, no-cache, no-store + Connection: + - keep-alive Content-Security-Policy: - default-src 'none' Content-Type: - application/json - Server: - - nginx + Expires: + - Fri, 16 Feb 2024 17:47:58 GMT + Pragma: + - no-cache Strict-Transport-Security: - max-age=31536000 Vary: - Authorization, X-Filter - Authorization, X-Filter + - Accept-Encoding X-Accepted-Oauth-Scopes: - '*' X-Content-Type-Options: @@ -221,7 +231,7 @@ interactions: X-Oauth-Scopes: - '*' X-Ratelimit-Limit: - - "800" + - "20" X-Xss-Protection: - 1; mode=block status: 200 OK diff --git a/test/integration/instance_config_test.go b/test/integration/instance_config_test.go index d839227d5..1bdbed250 100644 --- a/test/integration/instance_config_test.go +++ b/test/integration/instance_config_test.go @@ -48,7 +48,7 @@ func setupVPCWithSubnetWithInstance( teardownAll := func() { instanceTeardown() - vpcWithSubnetTeardown() + vpcWithSubnetTeardown() fixtureTeardown() } return client, vpc, vpcSubnet, instance, instanceConfig, teardownAll, err @@ -183,7 +183,6 @@ func TestInstance_ConfigInterfaces_AppendDelete(t *testing.T) { } func TestInstance_ConfigInterfaces_Reorder(t *testing.T) { - client, _, _, instance, config, teardown := setupInstanceWith3Interfaces( t, "fixtures/TestInstance_ConfigInterfaces_Reorder", @@ -242,7 +241,6 @@ func TestInstance_ConfigInterfaces_List(t *testing.T) { instance.ID, config.ID, ) - if err != nil { t.Error(err) } @@ -366,7 +364,6 @@ func TestInstance_ConfigInterface_Update(t *testing.T) { intfc.ID, updateOpts, ) - if err != nil { t.Errorf("an error occurs when updating an interface in config %v", config.ID) } diff --git a/test/integration/instance_stats_test.go b/test/integration/instance_stats_test.go index 13ccdee42..523a5616f 100644 --- a/test/integration/instance_stats_test.go +++ b/test/integration/instance_stats_test.go @@ -18,19 +18,19 @@ func TestInstanceStats_Get(t *testing.T) { Data: linodego.InstanceStatsData{ CPU: [][]float64{}, IO: linodego.StatsIO{ - IO: [][]float64{{1.2, 2.3}, {3.4, 4.5}}, + IO: [][]float64{{1.2, 2.3}, {3.4, 4.5}}, Swap: [][]float64{{14, 2.3}, {34, 4.5}}, }, NetV4: linodego.StatsNet{ - In: [][]float64{{1.2, 2.3}, {3.4, 4.5}}, - Out: [][]float64{{1, 2}, {3, 4}}, - PrivateIn: [][]float64{{2, 3}, {4, 5}}, + In: [][]float64{{1.2, 2.3}, {3.4, 4.5}}, + Out: [][]float64{{1, 2}, {3, 4}}, + PrivateIn: [][]float64{{2, 3}, {4, 5}}, PrivateOut: [][]float64{{12.1, 2.33}, {4.4, 4.5}}, }, NetV6: linodego.StatsNet{ - In: [][]float64{{1.2, .3}, {3.4, .5}}, - Out: [][]float64{{0, 2.3}, {3, 4.55}}, - PrivateIn: [][]float64{{1.24, 3}, {3, 5}}, + In: [][]float64{{1.2, .3}, {3.4, .5}}, + Out: [][]float64{{0, 2.3}, {3, 4.55}}, + PrivateIn: [][]float64{{1.24, 3}, {3, 5}}, PrivateOut: [][]float64{{1, 6}, {7, 8}}, }, }, diff --git a/test/integration/instances_test.go b/test/integration/instances_test.go index 8351350c3..7a9e64003 100644 --- a/test/integration/instances_test.go +++ b/test/integration/instances_test.go @@ -89,7 +89,7 @@ func TestInstance_Resize(t *testing.T) { options.Booted = &boot }, ) - + defer teardown() if err != nil { t.Error(err) @@ -109,7 +109,7 @@ func TestInstance_Resize(t *testing.T) { context.Background(), instance.ID, linodego.InstanceResizeOptions{ - Type: "g6-standard-1", + Type: "g6-standard-1", MigrationType: "warm", }, ) @@ -318,7 +318,6 @@ func TestInstance_Volumes_List(t *testing.T) { } func TestInstance_CreateUnderFirewall(t *testing.T) { - client, firewall, firewallTeardown, err := setupFirewall( t, []firewallModifier{}, @@ -449,7 +448,6 @@ func TestInstance_Clone(t *testing.T) { context.Background(), clonedInstance.ID, ) - if err != nil { t.Fatal(err) } diff --git a/test/integration/integration_suite_test.go b/test/integration/integration_suite_test.go index b3ed6e484..157185cb0 100644 --- a/test/integration/integration_suite_test.go +++ b/test/integration/integration_suite_test.go @@ -11,11 +11,10 @@ import ( "testing" "time" - "github.com/jarcoal/httpmock" - "github.com/dnaeon/go-vcr/cassette" "github.com/dnaeon/go-vcr/recorder" "github.com/linode/linodego" + "github.com/linode/linodego/internal/testutil" "golang.org/x/oauth2" "k8s.io/client-go/transport" ) @@ -155,21 +154,7 @@ func createTestClient(t *testing.T, fixturesYaml string) (*linodego.Client, func } func createMockClient(t *testing.T) *linodego.Client { - tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: validTestAPIKey}) - - client := &http.Client{ - Transport: &oauth2.Transport{ - Source: tokenSource, - }, - } - httpmock.ActivateNonDefault(client) - - t.Cleanup(func() { - httpmock.DeactivateAndReset() - }) - - c := linodego.NewClient(client) - return &c + return testutil.CreateMockClient(t, linodego.NewClient) } // transportRecordWrapper returns a tranport.WrapperFunc which provides the test diff --git a/test/integration/lke_clusters_test.go b/test/integration/lke_clusters_test.go index 9f33a1ea7..dc16a8147 100644 --- a/test/integration/lke_clusters_test.go +++ b/test/integration/lke_clusters_test.go @@ -244,6 +244,7 @@ func TestLKECluster_DeleteServiceToken(t *testing.T) { t.Fatal(err) } } + func TestLKEVersion_GetFound(t *testing.T) { client, teardown := createTestClient(t, "fixtures/TestLKEVersion_GetFound") defer teardown() diff --git a/test/integration/longview_test.go b/test/integration/longview_test.go index da0a29339..994a13f26 100644 --- a/test/integration/longview_test.go +++ b/test/integration/longview_test.go @@ -212,7 +212,6 @@ func TestLongviewPlan_Update(t *testing.T) { if updatedLongviewPlan.ID != "longview-10" { t.Errorf("Longview plan not updated") } - } func contains(arr []string, elem string) bool { diff --git a/test/integration/profile_grants_list_test.go b/test/integration/profile_grants_list_test.go index 45138b948..635308581 100644 --- a/test/integration/profile_grants_list_test.go +++ b/test/integration/profile_grants_list_test.go @@ -2,15 +2,16 @@ package integration import ( "context" + "reflect" + "testing" + "github.com/google/go-cmp/cmp" "github.com/jarcoal/httpmock" "github.com/linode/linodego" - "reflect" - "testing" ) func TestGrantsList(t *testing.T) { - //username := usernamePrefix + "grantslist" + // username := usernamePrefix + "grantslist" client := createMockClient(t) accessLevel := linodego.AccessLevelReadOnly desiredResponse := linodego.GrantsListResponse{ @@ -100,7 +101,6 @@ func TestGrantsList(t *testing.T) { httpmock.NewJsonResponderOrPanic(200, &desiredResponse), ) grants, err := client.GrantsList(context.Background()) - if err != nil { t.Fatal(err) } diff --git a/test/integration/profile_logins_test.go b/test/integration/profile_logins_test.go index 10958d387..e379ce02c 100644 --- a/test/integration/profile_logins_test.go +++ b/test/integration/profile_logins_test.go @@ -10,7 +10,6 @@ func TestProfileLogins_List(t *testing.T) { defer teardown() logins, err := client.ListProfileLogins(context.Background(), nil) - if err != nil { t.Errorf("Error getting Profile Logins, expected struct, got error %v", err) } diff --git a/test/integration/util_test.go b/test/integration/util_test.go index aa8ef0a90..7269c21d6 100644 --- a/test/integration/util_test.go +++ b/test/integration/util_test.go @@ -1,18 +1,13 @@ package integration import ( - "encoding/json" - "fmt" - "io" - "net/http" - "reflect" "regexp" "strconv" - "strings" "testing" "time" - "github.com/google/go-cmp/cmp" + "github.com/linode/linodego/internal/testutil" + "github.com/jarcoal/httpmock" ) @@ -24,38 +19,11 @@ func assertDateSet(t *testing.T, compared *time.Time) { } func mockRequestBodyValidate(t *testing.T, expected interface{}, response interface{}) httpmock.Responder { - return func(request *http.Request) (*http.Response, error) { - eType := reflect.TypeOf(expected) - result := reflect.New(eType) - - i := result.Interface() - - data, err := io.ReadAll(request.Body) - if err != nil { - t.Fatal(err) - } - - if err := json.Unmarshal(data, &i); err != nil { - t.Fatal(err) - } - - // Deref the pointer if necessary - if result.Kind() == reflect.Pointer { - result = result.Elem() - } - - resultValue := result.Interface() - - if !reflect.DeepEqual(expected, resultValue) { - t.Fatalf("request body does not match request options: %s", cmp.Diff(expected, resultValue)) - } - - return httpmock.NewJsonResponse(200, response) - } + return testutil.MockRequestBodyValidate(t, expected, response) } func mockRequestURL(t *testing.T, path string) *regexp.Regexp { - return regexp.MustCompile(fmt.Sprintf("/[a-zA-Z0-9]+/%s", strings.TrimPrefix(path, "/"))) + return testutil.MockRequestURL(path) } func assertSliceContains[T comparable](t *testing.T, slice []T, target T) { @@ -69,10 +37,10 @@ func assertSliceContains[T comparable](t *testing.T, slice []T, target T) { } func minInt(a, b int) int { - if a < b { - return a - } - return b + if a < b { + return a + } + return b } // return the current nanosecond in string type as a unique text. diff --git a/test/integration/vpc_subnet_test.go b/test/integration/vpc_subnet_test.go index 45dee8c3b..fa0162738 100644 --- a/test/integration/vpc_subnet_test.go +++ b/test/integration/vpc_subnet_test.go @@ -118,7 +118,6 @@ func createSubnetInVPC( func(), error, ) { - t.Helper() createOpts := linodego.VPCSubnetCreateOptions{ Label: "linodego-vpc-test-" + getUniqueText(), @@ -330,5 +329,4 @@ func TestVPC_Subnet_WithInstance(t *testing.T) { if nat1To1.Address != config.Interfaces[2].IPv4.VPC { t.Fatalf("nat_1_1 subnet IP mismatch") } - } diff --git a/test/integration/waitfor_test.go b/test/integration/waitfor_test.go index 5dc198cf2..8775598ea 100644 --- a/test/integration/waitfor_test.go +++ b/test/integration/waitfor_test.go @@ -3,8 +3,9 @@ package integration import ( "context" "fmt" - "github.com/linode/linodego" "testing" + + "github.com/linode/linodego" ) func TestEventPoller_InstancePower(t *testing.T) {