diff --git a/.changelog/1202.txt b/.changelog/1202.txt new file mode 100644 index 00000000000..58c21d62c2b --- /dev/null +++ b/.changelog/1202.txt @@ -0,0 +1,3 @@ +```release-note:bug +stream: renamed `RequiredSignedURLs` to `RequireSignedURLs` +``` diff --git a/.changelog/1206.txt b/.changelog/1206.txt new file mode 100644 index 00000000000..fb12a08ebe0 --- /dev/null +++ b/.changelog/1206.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +tunnels: automatically paginate `ListTunnels` +``` diff --git a/.changelog/1208.txt b/.changelog/1208.txt new file mode 100644 index 00000000000..8075ecc7939 --- /dev/null +++ b/.changelog/1208.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +teams_accounts: Add new root_certificate_installation_enabled field +``` diff --git a/.changelog/1210.txt b/.changelog/1210.txt new file mode 100644 index 00000000000..a05f5531d17 --- /dev/null +++ b/.changelog/1210.txt @@ -0,0 +1,3 @@ +```release-note:dependency +deps: bumps github.com/urfave/cli/v2 from 2.24.3 to 2.24.4 +``` diff --git a/CHANGELOG.md b/CHANGELOG.md index 8286a86bb4d..792686e249f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,16 @@ -## 0.61.0 (Unreleased) +## 0.62.0 (Unreleased) + +ENHANCEMENTS: + +* dex_test: add CRUD functionality for DEX test configurations ([#1209](https://github.com/cloudflare/cloudflare-go/issues/1209)) +* teams_accounts: Add new root_certificate_installation_enabled field ([#1208](https://github.com/cloudflare/cloudflare-go/issues/1208)) +* tunnels: automatically paginate `ListTunnels` ([#1206](https://github.com/cloudflare/cloudflare-go/issues/1206)) + +DEPENDENCIES: + +* deps: bumps github.com/urfave/cli/v2 from 2.24.3 to 2.24.4 ([#1210](https://github.com/cloudflare/cloudflare-go/issues/1210)) + +## 0.61.0 (15th February, 2023) ENHANCEMENTS: @@ -9,6 +21,7 @@ ENHANCEMENTS: BUG FIXES: * dns: always send `tags` to allow clearing ([#1196](https://github.com/cloudflare/cloudflare-go/issues/1196)) +* stream: renamed `RequiredSignedURLs` to `RequireSignedURLs` ([#1202](https://github.com/cloudflare/cloudflare-go/issues/1202)) DEPENDENCIES: diff --git a/go.mod b/go.mod index 44c3b974d67..4731b3bea1f 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.2 github.com/olekukonko/tablewriter v0.0.5 github.com/stretchr/testify v1.8.1 - github.com/urfave/cli/v2 v2.24.3 + github.com/urfave/cli/v2 v2.24.4 golang.org/x/net v0.0.0-20220722155237-a158d28d115b golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 ) diff --git a/go.sum b/go.sum index 5cc537c34fe..dd22cce7c2a 100644 --- a/go.sum +++ b/go.sum @@ -60,8 +60,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/urfave/cli/v2 v2.24.3 h1:7Q1w8VN8yE0MJEHP06bv89PjYsN4IHWED2s1v/Zlfm0= -github.com/urfave/cli/v2 v2.24.3/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/urfave/cli/v2 v2.24.4 h1:0gyJJEBYtCV87zI/x2nZCPyDxD51K6xM8SkwjHFCNEU= +github.com/urfave/cli/v2 v2.24.4/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= diff --git a/stream.go b/stream.go index e12630495ae..95edd6b5e7f 100644 --- a/stream.go +++ b/stream.go @@ -101,7 +101,7 @@ type StreamUploadFromURLParameters struct { Creator string `json:"creator,omitempty"` ThumbnailTimestampPct float64 `json:"thumbnailTimestampPct,omitempty"` AllowedOrigins []string `json:"allowedOrigins,omitempty"` - RequiredSignedURLs bool `json:"requiredSignedURLs,omitempty"` + RequireSignedURLs bool `json:"requireSignedURLs,omitempty"` Watermark UploadVideoURLWatermark `json:"watermark,omitempty"` } @@ -113,7 +113,7 @@ type StreamCreateVideoParameters struct { Creator string `json:"creator,omitempty"` ThumbnailTimestampPct float64 `json:"thumbnailTimestampPct,omitempty"` AllowedOrigins []string `json:"allowedOrigins,omitempty"` - RequiredSignedURLs bool `json:"requiredSignedURLs,omitempty"` + RequireSignedURLs bool `json:"requireSignedURLs,omitempty"` Watermark UploadVideoURLWatermark `json:"watermark,omitempty"` } diff --git a/teams_accounts.go b/teams_accounts.go index f90707147cf..7667a155beb 100644 --- a/teams_accounts.go +++ b/teams_accounts.go @@ -97,8 +97,9 @@ type TeamsLoggingSettings struct { } type TeamsDeviceSettings struct { - GatewayProxyEnabled bool `json:"gateway_proxy_enabled"` - GatewayProxyUDPEnabled bool `json:"gateway_udp_proxy_enabled"` + GatewayProxyEnabled bool `json:"gateway_proxy_enabled"` + GatewayProxyUDPEnabled bool `json:"gateway_udp_proxy_enabled"` + RootCertificateInstallationEnabled bool `json:"root_certificate_installation_enabled"` } type TeamsDeviceSettingsResponse struct { diff --git a/teams_accounts_test.go b/teams_accounts_test.go index a9535528bfc..1741217355e 100644 --- a/teams_accounts_test.go +++ b/teams_accounts_test.go @@ -239,7 +239,7 @@ func TestTeamsAccountGetDeviceConfiguration(t *testing.T) { "success": true, "errors": [], "messages": [], - "result": {"gateway_proxy_enabled": true,"gateway_udp_proxy_enabled":false} + "result": {"gateway_proxy_enabled": true,"gateway_udp_proxy_enabled":false, "root_certificate_installation_enabled":true} }`) } @@ -249,8 +249,9 @@ func TestTeamsAccountGetDeviceConfiguration(t *testing.T) { if assert.NoError(t, err) { assert.Equal(t, actual, TeamsDeviceSettings{ - GatewayProxyEnabled: true, - GatewayProxyUDPEnabled: false, + GatewayProxyEnabled: true, + GatewayProxyUDPEnabled: false, + RootCertificateInstallationEnabled: true, }) } } @@ -266,21 +267,23 @@ func TestTeamsAccountUpdateDeviceConfiguration(t *testing.T) { "success": true, "errors": [], "messages": [], - "result": {"gateway_proxy_enabled": true,"gateway_udp_proxy_enabled":true} + "result": {"gateway_proxy_enabled": true,"gateway_udp_proxy_enabled":true, "root_certificate_installation_enabled":true} }`) } mux.HandleFunc("/accounts/"+testAccountID+"/devices/settings", handler) actual, err := client.TeamsAccountDeviceUpdateConfiguration(context.Background(), testAccountID, TeamsDeviceSettings{ - GatewayProxyUDPEnabled: true, - GatewayProxyEnabled: true, + GatewayProxyUDPEnabled: true, + GatewayProxyEnabled: true, + RootCertificateInstallationEnabled: true, }) if assert.NoError(t, err) { assert.Equal(t, actual, TeamsDeviceSettings{ - GatewayProxyEnabled: true, - GatewayProxyUDPEnabled: true, + GatewayProxyEnabled: true, + GatewayProxyUDPEnabled: true, + RootCertificateInstallationEnabled: true, }) } } diff --git a/testdata/fixtures/tunnel/multiple_full.json b/testdata/fixtures/tunnel/multiple_full.json index 409911a8f2b..586dd9003a7 100644 --- a/testdata/fixtures/tunnel/multiple_full.json +++ b/testdata/fixtures/tunnel/multiple_full.json @@ -20,5 +20,11 @@ } ] } - ] + ], + "result_info": { + "count": 1, + "page": 1, + "per_page": 20, + "total_count": 1 + } } diff --git a/tunnel.go b/tunnel.go index d933eedfc88..8ae91d391d0 100644 --- a/tunnel.go +++ b/tunnel.go @@ -51,8 +51,12 @@ type TunnelConnection struct { type TunnelsDetailResponse struct { Result []Tunnel `json:"result"` Response + ResultInfo `json:"result_info"` } +// listTunnelsDefaultPageSize represents the default per_page size of the API. +var listTunnelsDefaultPageSize int = 100 + // TunnelDetailResponse is used for representing the API response payload for // a single tunnel. type TunnelDetailResponse struct { @@ -171,29 +175,54 @@ type TunnelListParams struct { UUID string `url:"uuid,omitempty"` // the tunnel ID IsDeleted *bool `url:"is_deleted,omitempty"` ExistedAt *time.Time `url:"existed_at,omitempty"` + + ResultInfo } // Tunnels lists all tunnels. // // API reference: https://api.cloudflare.com/#cloudflare-tunnel-list-cloudflare-tunnels -func (api *API) Tunnels(ctx context.Context, rc *ResourceContainer, params TunnelListParams) ([]Tunnel, error) { +func (api *API) Tunnels(ctx context.Context, rc *ResourceContainer, params TunnelListParams) ([]Tunnel, *ResultInfo, error) { if rc.Identifier == "" { - return []Tunnel{}, ErrMissingAccountID + return []Tunnel{}, &ResultInfo{}, ErrMissingAccountID } - uri := buildURI(fmt.Sprintf("/accounts/%s/cfd_tunnel", rc.Identifier), params) + autoPaginate := true + if params.PerPage >= 1 || params.Page >= 1 { + autoPaginate = false + } - res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) - if err != nil { - return []Tunnel{}, err + if params.PerPage < 1 { + params.PerPage = listTunnelsDefaultPageSize } - var argoDetailsResponse TunnelsDetailResponse - err = json.Unmarshal(res, &argoDetailsResponse) - if err != nil { - return []Tunnel{}, fmt.Errorf("%s: %w", errUnmarshalError, err) + if params.Page < 1 { + params.Page = 1 } - return argoDetailsResponse.Result, nil + + var records []Tunnel + var listResponse TunnelsDetailResponse + + for { + uri := buildURI(fmt.Sprintf("/accounts/%s/cfd_tunnel", rc.Identifier), params) + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return []Tunnel{}, &ResultInfo{}, err + } + + err = json.Unmarshal(res, &listResponse) + if err != nil { + return []Tunnel{}, &ResultInfo{}, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + + records = append(records, listResponse.Result...) + params.ResultInfo = listResponse.ResultInfo.Next() + if params.ResultInfo.Done() || !autoPaginate { + break + } + } + + return records, &listResponse.ResultInfo, nil } // Tunnel returns a single Argo tunnel. diff --git a/tunnel_test.go b/tunnel_test.go index 48f8f386c60..5e629104716 100644 --- a/tunnel_test.go +++ b/tunnel_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "net/http" + "net/url" "testing" "time" @@ -40,7 +41,57 @@ func TestTunnels(t *testing.T) { }}, }} - actual, err := client.Tunnels(context.Background(), AccountIdentifier(testAccountID), TunnelListParams{UUID: "f174e90a-fafe-4643-bbbc-4a0ed4fc8415"}) + actual, _, err := client.Tunnels(context.Background(), AccountIdentifier(testAccountID), TunnelListParams{UUID: "f174e90a-fafe-4643-bbbc-4a0ed4fc8415"}) + + if assert.NoError(t, err) { + assert.Equal(t, want, actual) + } +} + +func TestTunnelsPagination(t *testing.T) { + setup() + defer teardown() + + handler := func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method) + w.Header().Set("content-type", "application/json") + qry, _ := url.Parse(r.RequestURI) + assert.Equal(t, "blog", qry.Query().Get("name")) + assert.Equal(t, "2", qry.Query().Get("page")) + assert.Equal(t, "1", qry.Query().Get("per_page")) + fmt.Fprint(w, loadFixture("tunnel", "multiple_full")) + } + + mux.HandleFunc("/accounts/"+testAccountID+"/cfd_tunnel", handler) + + createdAt, _ := time.Parse(time.RFC3339, "2009-11-10T23:00:00Z") + deletedAt, _ := time.Parse(time.RFC3339, "2009-11-10T23:00:00Z") + want := []Tunnel{ + { + ID: "f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + Name: "blog", + CreatedAt: &createdAt, + DeletedAt: &deletedAt, + Connections: []TunnelConnection{{ + ColoName: "DFW", + ID: "f174e90a-fafe-4643-bbbc-4a0ed4fc8415", + IsPendingReconnect: false, + ClientID: "dc6472cc-f1ae-44a0-b795-6b8a0ce29f90", + ClientVersion: "2022.2.0", + OpenedAt: "2021-01-25T18:22:34.317854Z", + OriginIP: "198.51.100.1", + }}, + }, + } + + actual, _, err := client.Tunnels(context.Background(), AccountIdentifier(testAccountID), + TunnelListParams{ + Name: "blog", + ResultInfo: ResultInfo{ + Page: 2, + PerPage: 1, + }, + }) if assert.NoError(t, err) { assert.Equal(t, want, actual)