From e851a4e9704842e63dd3cdaee6103d909e42e739 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 00:04:40 +0000 Subject: [PATCH] Bump github.com/cloudflare/cloudflare-go from 0.77.0 to 0.78.0 Bumps [github.com/cloudflare/cloudflare-go](https://github.com/cloudflare/cloudflare-go) from 0.77.0 to 0.78.0. - [Release notes](https://github.com/cloudflare/cloudflare-go/releases) - [Changelog](https://github.com/cloudflare/cloudflare-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/cloudflare/cloudflare-go/compare/v0.77.0...v0.78.0) --- updated-dependencies: - dependency-name: github.com/cloudflare/cloudflare-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 +- .../cloudflare/cloudflare-go/.semgrep.yml | 15 +- .../cloudflare/cloudflare-go/CHANGELOG.md | 25 +- .../cloudflare-go/access_application.go | 3 + .../cloudflare/cloudflare-go/access_tag.go | 85 ++++ .../cloudflare/cloudflare-go/account_roles.go | 64 ++- .../cloudflare-go/api_shield_operations.go | 185 +++++++++ .../cloudflare-go/bot_management.go | 3 +- .../cloudflare/cloudflare-go/list.go | 17 +- .../cloudflare/cloudflare-go/observatory.go | 388 ++++++++++++++++++ .../per_hostname_tls_settings.go | 3 +- .../cloudflare/cloudflare-go/web_analytics.go | 3 +- vendor/modules.txt | 2 +- 14 files changed, 765 insertions(+), 34 deletions(-) create mode 100644 vendor/github.com/cloudflare/cloudflare-go/access_tag.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/api_shield_operations.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/observatory.go diff --git a/go.mod b/go.mod index d44d47c3..56fb370a 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/ThalesIgnite/crypto11 v1.2.5 github.com/cloudflare/backoff v0.0.0-20161212185259-647f3cdfc87a github.com/cloudflare/cfssl v1.6.4 - github.com/cloudflare/cloudflare-go v0.77.0 + github.com/cloudflare/cloudflare-go v0.78.0 github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41 github.com/davecgh/go-spew v1.1.1 github.com/googleapis/gax-go/v2 v2.12.0 diff --git a/go.sum b/go.sum index 9b7933cd..0852cca3 100644 --- a/go.sum +++ b/go.sum @@ -92,8 +92,8 @@ github.com/cloudflare/backoff v0.0.0-20161212185259-647f3cdfc87a h1:8d1CEOF1xlde github.com/cloudflare/backoff v0.0.0-20161212185259-647f3cdfc87a/go.mod h1:rzgs2ZOiguV6/NpiDgADjRLPNyZlApIWxKpkT+X8SdY= github.com/cloudflare/cfssl v1.6.4 h1:NMOvfrEjFfC63K3SGXgAnFdsgkmiq4kATme5BfcqrO8= github.com/cloudflare/cfssl v1.6.4/go.mod h1:8b3CQMxfWPAeom3zBnGJ6sd+G1NkL5TXqmDXacb+1J0= -github.com/cloudflare/cloudflare-go v0.77.0 h1:bVUGkSKdXEz8+u2Yj3ASqZsqlcsPkeB+PDqVs9OE7TY= -github.com/cloudflare/cloudflare-go v0.77.0/go.mod h1:R+Q/Im0G0MzKJxj3eXOBBE8xpnchVA9tSiQwOEvfW4Y= +github.com/cloudflare/cloudflare-go v0.78.0 h1:xMPdjJ+e2tGNUkw5LyduPlsMCaILEoN1Kqq/uEMx78w= +github.com/cloudflare/cloudflare-go v0.78.0/go.mod h1:R+Q/Im0G0MzKJxj3eXOBBE8xpnchVA9tSiQwOEvfW4Y= github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41 h1:/8sZyuGTAU2+fYv0Sz9lBcipqX0b7i4eUl8pSStk/4g= github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41/go.mod h1:eaZPlJWD+G9wseg1BuRXlHnjntPMrywMsyxf+LTOdP4= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= diff --git a/vendor/github.com/cloudflare/cloudflare-go/.semgrep.yml b/vendor/github.com/cloudflare/cloudflare-go/.semgrep.yml index 000f8a23..7e46eadd 100644 --- a/vendor/github.com/cloudflare/cloudflare-go/.semgrep.yml +++ b/vendor/github.com/cloudflare/cloudflare-go/.semgrep.yml @@ -7,7 +7,7 @@ rules: include: - '*.go' patterns: - - pattern-regex: '\d+\.\d+\.\d+\.\d+' + - pattern-regex: '(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' - pattern-not-regex: '10\.\d+\.\d+.\d+' - pattern-not-regex: '192\.168\.\d+.\d+' - pattern-not-regex: '192\.0\.2\.\d+' # 192.0.2.0/24 (TEST-NET-1, rfc5737) @@ -33,3 +33,16 @@ rules: - pattern: | errors.Wrap(...) severity: WARNING + - id: no-use-of-stdlib-json + languages: + - go + message: Favour "github.com/goccy/go-json" instead of "encoding/json" to allow better customisation of marshaling and unmarshaling JSON attributes. See https://github.com/cloudflare/cloudflare-go/pull/1360 for full details. + paths: + include: + - '*.go' + patterns: + - pattern-regex: '\"encoding\/json\"' + fix-regex: + regex: \".*\" + replacement: '"github.com/goccy/go-json"' + severity: WARNING diff --git a/vendor/github.com/cloudflare/cloudflare-go/CHANGELOG.md b/vendor/github.com/cloudflare/cloudflare-go/CHANGELOG.md index 55d52cb8..f7530e8d 100644 --- a/vendor/github.com/cloudflare/cloudflare-go/CHANGELOG.md +++ b/vendor/github.com/cloudflare/cloudflare-go/CHANGELOG.md @@ -1,4 +1,27 @@ -## 0.78.0 (Unreleased) +## 0.79.0 (Unreleased) + +## 0.78.0 (September 27th, 2023) + +BREAKING CHANGES: + +* account_role: `AccountRole` has been renamed to `GetAccountRole` to align with the updated method conventions ([#1405](https://github.com/cloudflare/cloudflare-go/issues/1405)) +* account_role: `AccountRoles` has been renamed to `ListAccountRoles` to align with the updated method conventions ([#1405](https://github.com/cloudflare/cloudflare-go/issues/1405)) + +ENHANCEMENTS: + +* access_application: Add support for tags ([#1403](https://github.com/cloudflare/cloudflare-go/issues/1403)) +* access_tag: Add support for tags ([#1403](https://github.com/cloudflare/cloudflare-go/issues/1403)) +* list_item: allow filtering by search term, cursor and per page attributes ([#1409](https://github.com/cloudflare/cloudflare-go/issues/1409)) +* observatory: add support for observatory API ([#1401](https://github.com/cloudflare/cloudflare-go/issues/1401)) + +BUG FIXES: + +* account_role: autopaginate all available results instead of a static number ([#1405](https://github.com/cloudflare/cloudflare-go/issues/1405)) +* semgrep: Improved IPv4 validation by implementing a new pattern to handle cases where non-IPv4 addresses were previously accepted. ([#1382](https://github.com/cloudflare/cloudflare-go/issues/1382)) + +DEPENDENCIES: + +* deps: bumps codecov/codecov-action from 3 to 4 ([#1402](https://github.com/cloudflare/cloudflare-go/issues/1402)) ## 0.77.0 (September 13th, 2023) diff --git a/vendor/github.com/cloudflare/cloudflare-go/access_application.go b/vendor/github.com/cloudflare/cloudflare-go/access_application.go index 898b3a63..e99bd000 100644 --- a/vendor/github.com/cloudflare/cloudflare-go/access_application.go +++ b/vendor/github.com/cloudflare/cloudflare-go/access_application.go @@ -53,6 +53,7 @@ type AccessApplication struct { ServiceAuth401Redirect *bool `json:"service_auth_401_redirect,omitempty"` PathCookieAttribute *bool `json:"path_cookie_attribute,omitempty"` CustomPages []string `json:"custom_pages,omitempty"` + Tags []string `json:"tags,omitempty"` } type AccessApplicationGatewayRule struct { @@ -144,6 +145,7 @@ type CreateAccessApplicationParams struct { SkipInterstitial *bool `json:"skip_interstitial,omitempty"` Type AccessApplicationType `json:"type,omitempty"` CustomPages []string `json:"custom_pages,omitempty"` + Tags []string `json:"tags,omitempty"` } type UpdateAccessApplicationParams struct { @@ -172,6 +174,7 @@ type UpdateAccessApplicationParams struct { SkipInterstitial *bool `json:"skip_interstitial,omitempty"` Type AccessApplicationType `json:"type,omitempty"` CustomPages []string `json:"custom_pages,omitempty"` + Tags []string `json:"tags,omitempty"` } // ListAccessApplications returns all applications within an account or zone. diff --git a/vendor/github.com/cloudflare/cloudflare-go/access_tag.go b/vendor/github.com/cloudflare/cloudflare-go/access_tag.go new file mode 100644 index 00000000..9bba613d --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/access_tag.go @@ -0,0 +1,85 @@ +package cloudflare + +import ( + "context" + "fmt" + "net/http" + + "github.com/goccy/go-json" +) + +type AccessTag struct { + Name string `json:"name,omitempty"` + AppCount int `json:"app_count,omitempty"` +} + +type AccessTagListResponse struct { + Response + Result []AccessTag `json:"result"` + ResultInfo `json:"result_info"` +} + +type AccessTagResponse struct { + Response + Result AccessTag `json:"result"` +} + +type ListAccessTagsParams struct{} + +type CreateAccessTagParams struct { + Name string `json:"name,omitempty"` +} + +func (api *API) ListAccessTags(ctx context.Context, rc *ResourceContainer, params ListAccessTagsParams) ([]AccessTag, error) { + uri := buildURI(fmt.Sprintf("/%s/%s/access/tags", rc.Level, rc.Identifier), params) + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return []AccessTag{}, err + } + + var TagsResponse AccessTagListResponse + err = json.Unmarshal(res, &TagsResponse) + if err != nil { + return []AccessTag{}, err + } + return TagsResponse.Result, nil +} + +func (api *API) GetAccessTag(ctx context.Context, rc *ResourceContainer, tagName string) (AccessTag, error) { + uri := fmt.Sprintf("/%s/%s/access/tags/%s", rc.Level, rc.Identifier, tagName) + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return AccessTag{}, err + } + + var TagResponse AccessTagResponse + err = json.Unmarshal(res, &TagResponse) + if err != nil { + return AccessTag{}, err + } + return TagResponse.Result, nil +} + +func (api *API) CreateAccessTag(ctx context.Context, rc *ResourceContainer, params CreateAccessTagParams) (AccessTag, error) { + uri := fmt.Sprintf("/%s/%s/access/tags", rc.Level, rc.Identifier) + res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params) + if err != nil { + return AccessTag{}, err + } + + var TagResponse AccessTagResponse + err = json.Unmarshal(res, &TagResponse) + if err != nil { + return AccessTag{}, err + } + return TagResponse.Result, nil +} + +func (api *API) DeleteAccessTag(ctx context.Context, rc *ResourceContainer, tagName string) error { + uri := fmt.Sprintf("/%s/%s/access/tags/%s", rc.Level, rc.Identifier, tagName) + _, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil) + if err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/account_roles.go b/vendor/github.com/cloudflare/cloudflare-go/account_roles.go index dec1da81..d216ae31 100644 --- a/vendor/github.com/cloudflare/cloudflare-go/account_roles.go +++ b/vendor/github.com/cloudflare/cloudflare-go/account_roles.go @@ -40,35 +40,65 @@ type AccountRoleDetailResponse struct { Result AccountRole `json:"result"` } -// AccountRoles returns all roles of an account. +type ListAccountRolesParams struct { + ResultInfo +} + +// ListAccountRoles returns all roles of an account. // -// API reference: https://api.cloudflare.com/#account-roles-list-roles -func (api *API) AccountRoles(ctx context.Context, accountID string) ([]AccountRole, error) { - uri := fmt.Sprintf("/accounts/%s/roles?per_page=50", accountID) +// API reference: https://developers.cloudflare.com/api/operations/account-roles-list-roles +func (api *API) ListAccountRoles(ctx context.Context, rc *ResourceContainer, params ListAccountRolesParams) ([]AccountRole, error) { + if rc.Identifier == "" { + return []AccountRole{}, ErrMissingAccountID + } + autoPaginate := true + if params.PerPage >= 1 || params.Page >= 1 { + autoPaginate = false + } - res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) - if err != nil { - return []AccountRole{}, err + if params.PerPage < 1 { + params.PerPage = 25 } - var accountRolesListResponse AccountRolesListResponse - err = json.Unmarshal(res, &accountRolesListResponse) - if err != nil { - return []AccountRole{}, fmt.Errorf("%s: %w", errUnmarshalError, err) + if params.Page < 1 { + params.Page = 1 } + var roles []AccountRole + var r AccountRolesListResponse + for { + uri := buildURI(fmt.Sprintf("/accounts/%s/roles", rc.Identifier), params) + + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return []AccountRole{}, err + } - return accountRolesListResponse.Result, nil + err = json.Unmarshal(res, &r) + if err != nil { + return []AccountRole{}, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + roles = append(roles, r.Result...) + params.ResultInfo = r.ResultInfo.Next() + if params.ResultInfo.Done() || !autoPaginate { + break + } + } + + return roles, nil } -// AccountRole returns the details of a single account role. +// GetAccountRole returns the details of a single account role. // -// API reference: https://api.cloudflare.com/#account-roles-role-details -func (api *API) AccountRole(ctx context.Context, accountID string, roleID string) (AccountRole, error) { - uri := fmt.Sprintf("/accounts/%s/roles/%s", accountID, roleID) +// API reference: https://developers.cloudflare.com/api/operations/account-roles-role-details +func (api *API) GetAccountRole(ctx context.Context, rc *ResourceContainer, roleID string) (AccountRole, error) { + if rc.Identifier == "" { + return AccountRole{}, ErrMissingAccountID + } + uri := fmt.Sprintf("/accounts/%s/roles/%s", rc.Identifier, roleID) res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) if err != nil { - return AccountRole{}, err + return AccountRole{}, fmt.Errorf("%s: %w", errMakeRequestError, err) } var accountRole AccountRoleDetailResponse diff --git a/vendor/github.com/cloudflare/cloudflare-go/api_shield_operations.go b/vendor/github.com/cloudflare/cloudflare-go/api_shield_operations.go new file mode 100644 index 00000000..1d89a175 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/api_shield_operations.go @@ -0,0 +1,185 @@ +package cloudflare + +import ( + "context" + "fmt" + "net/http" + "time" + + "github.com/goccy/go-json" +) + +// APIShieldOperation represents an operation stored in API Shield Endpoint Management. +type APIShieldOperation struct { + APIShieldBasicOperation + ID string `json:"operation_id"` + LastUpdated *time.Time `json:"last_updated"` + Features map[string]any `json:"features,omitempty"` +} + +// GetAPIShieldOperationParams represents the parameters to pass when retrieving an operation. +// +// API documentation: https://developers.cloudflare.com/api/operations/api-shield-endpoint-management-retrieve-information-about-an-operation +type GetAPIShieldOperationParams struct { + // The Operation ID to retrieve + OperationID string `url:"-"` + // Features represents a set of features to return in `features` object when + // performing making read requests against an Operation or listing operations. + Features []string `url:"feature,omitempty"` +} + +// CreateAPIShieldOperationsParams represents the parameters to pass when adding one or more operations. +// +// API documentation: https://developers.cloudflare.com/api/operations/api-shield-endpoint-management-add-operations-to-a-zone +type CreateAPIShieldOperationsParams struct { + // Operations are a slice of operations to be created in API Shield Endpoint Management + Operations []APIShieldBasicOperation `url:"-"` +} + +// APIShieldBasicOperation should be used when creating an operation in API Shield Endpoint Management. +type APIShieldBasicOperation struct { + Method string `json:"method"` + Host string `json:"host"` + Endpoint string `json:"endpoint"` +} + +// DeleteAPIShieldOperationParams represents the parameters to pass to delete an operation. +// +// API documentation: https://developers.cloudflare.com/api/operations/api-shield-endpoint-management-delete-an-operation +type DeleteAPIShieldOperationParams struct { + // OperationID is the operation to be deleted + OperationID string `url:"-"` +} + +// ListAPIShieldOperationsParams represents the parameters to pass when retrieving operations +// +// API documentation: https://developers.cloudflare.com/api/operations/api-shield-endpoint-management-retrieve-information-about-all-operations-on-a-zone +type ListAPIShieldOperationsParams struct { + // Features represents a set of features to return in `features` object when + // performing making read requests against an Operation or listing operations. + Features []string `url:"feature,omitempty"` + // Direction to order results. + Direction string `url:"direction,omitempty"` + // OrderBy when requesting a feature, the feature keys are available for ordering as well, e.g., thresholds.suggested_threshold. + OrderBy string `url:"order,omitempty"` + // Filters to only return operations that match filtering criteria, see APIShieldGetOperationsFilters + APIShieldListOperationsFilters + // Pagination options to apply to the request. + PaginationOptions +} + +// APIShieldListOperationsFilters represents the filtering query parameters to set when retrieving operations +// +// API documentation: https://developers.cloudflare.com/api/operations/api-shield-endpoint-management-retrieve-information-about-all-operations-on-a-zone +type APIShieldListOperationsFilters struct { + // Hosts filters results to only include the specified hosts. + Hosts []string `url:"host,omitempty"` + // Methods filters results to only include the specified methods. + Methods []string `url:"method,omitempty"` + // Endpoint filter results to only include endpoints containing this pattern. + Endpoint string `url:"endpoint,omitempty"` +} + +// APIShieldGetOperationResponse represents the response from the api_gateway/operations/{id} endpoint. +type APIShieldGetOperationResponse struct { + Result APIShieldOperation `json:"result"` + Response +} + +// APIShieldGetOperationsResponse represents the response from the api_gateway/operations endpoint. +type APIShieldGetOperationsResponse struct { + Result []APIShieldOperation `json:"result"` + ResultInfo `json:"result_info"` + Response +} + +// APIShieldDeleteOperationResponse represents the response from the api_gateway/operations/{id} endpoint (DELETE). +type APIShieldDeleteOperationResponse struct { + Result interface{} `json:"result"` + Response +} + +// GetAPIShieldOperation returns information about an operation +// +// API documentation https://developers.cloudflare.com/api/operations/api-shield-endpoint-management-retrieve-information-about-an-operation +func (api *API) GetAPIShieldOperation(ctx context.Context, rc *ResourceContainer, params GetAPIShieldOperationParams) (*APIShieldOperation, error) { + path := fmt.Sprintf("/zones/%s/api_gateway/operations/%s", rc.Identifier, params.OperationID) + + uri := buildURI(path, params) + + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return nil, err + } + + var asResponse APIShieldGetOperationResponse + err = json.Unmarshal(res, &asResponse) + if err != nil { + return nil, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + + return &asResponse.Result, nil +} + +// ListAPIShieldOperations retrieve information about all operations on a zone +// +// API documentation https://developers.cloudflare.com/api/operations/api-shield-endpoint-management-retrieve-information-about-all-operations-on-a-zone +func (api *API) ListAPIShieldOperations(ctx context.Context, rc *ResourceContainer, params ListAPIShieldOperationsParams) ([]APIShieldOperation, ResultInfo, error) { + path := fmt.Sprintf("/zones/%s/api_gateway/operations", rc.Identifier) + + uri := buildURI(path, params) + + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return nil, ResultInfo{}, err + } + + var asResponse APIShieldGetOperationsResponse + err = json.Unmarshal(res, &asResponse) + if err != nil { + return nil, ResultInfo{}, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + + return asResponse.Result, asResponse.ResultInfo, nil +} + +// CreateAPIShieldOperations add one or more operations to a zone. +// +// API documentation https://developers.cloudflare.com/api/operations/api-shield-endpoint-management-add-operations-to-a-zone +func (api *API) CreateAPIShieldOperations(ctx context.Context, rc *ResourceContainer, params CreateAPIShieldOperationsParams) ([]APIShieldOperation, error) { + uri := fmt.Sprintf("/zones/%s/api_gateway/operations", rc.Identifier) + + res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params.Operations) + if err != nil { + return nil, err + } + + // Result should be all the operations added to the zone, similar to doing GetAPIShieldOperations + var asResponse APIShieldGetOperationsResponse + err = json.Unmarshal(res, &asResponse) + if err != nil { + return nil, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + + return asResponse.Result, nil +} + +// DeleteAPIShieldOperation deletes a single operation +// +// API documentation https://developers.cloudflare.com/api/operations/api-shield-endpoint-management-delete-an-operation +func (api *API) DeleteAPIShieldOperation(ctx context.Context, rc *ResourceContainer, params DeleteAPIShieldOperationParams) error { + uri := fmt.Sprintf("/zones/%s/api_gateway/operations/%s", rc.Identifier, params.OperationID) + + res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil) + if err != nil { + return err + } + + var asResponse APIShieldDeleteOperationResponse + err = json.Unmarshal(res, &asResponse) + if err != nil { + return fmt.Errorf("%s: %w", errUnmarshalError, err) + } + + return nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/bot_management.go b/vendor/github.com/cloudflare/cloudflare-go/bot_management.go index f44d39ff..f77968f4 100644 --- a/vendor/github.com/cloudflare/cloudflare-go/bot_management.go +++ b/vendor/github.com/cloudflare/cloudflare-go/bot_management.go @@ -2,9 +2,10 @@ package cloudflare import ( "context" - "encoding/json" "fmt" "net/http" + + "github.com/goccy/go-json" ) // BotManagement represents the bots config for a zone. diff --git a/vendor/github.com/cloudflare/cloudflare-go/list.go b/vendor/github.com/cloudflare/cloudflare-go/list.go index e7893c35..f7cef4ac 100644 --- a/vendor/github.com/cloudflare/cloudflare-go/list.go +++ b/vendor/github.com/cloudflare/cloudflare-go/list.go @@ -177,7 +177,10 @@ type ListDeleteParams struct { } type ListListItemsParams struct { - ID string + ID string `url:"-"` + Search string `url:"search,omitempty"` + PerPage int `url:"per_page,omitempty"` + Cursor string `url:"cursor,omitempty"` } type ListCreateItemsParams struct { @@ -336,14 +339,10 @@ func (api *API) DeleteList(ctx context.Context, rc *ResourceContainer, listID st // API reference: https://api.cloudflare.com/#rules-lists-list-list-items func (api *API) ListListItems(ctx context.Context, rc *ResourceContainer, params ListListItemsParams) ([]ListItem, error) { var list []ListItem - var cursor string - var cursorQuery string for { - if len(cursor) > 0 { - cursorQuery = fmt.Sprintf("?cursor=%s", cursor) - } - uri := fmt.Sprintf("/accounts/%s/rules/lists/%s/items%s", rc.Identifier, params.ID, cursorQuery) + uri := buildURI(fmt.Sprintf("/accounts/%s/rules/lists/%s/items", rc.Identifier, params.ID), params) + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) if err != nil { return []ListItem{}, err @@ -355,8 +354,10 @@ func (api *API) ListListItems(ctx context.Context, rc *ResourceContainer, params } list = append(list, result.Result...) - if cursor = result.ResultInfo.Cursors.After; cursor == "" { + if cursor := result.ResultInfo.Cursors.After; cursor == "" { break + } else { + params.Cursor = cursor } } diff --git a/vendor/github.com/cloudflare/cloudflare-go/observatory.go b/vendor/github.com/cloudflare/cloudflare-go/observatory.go new file mode 100644 index 00000000..488640fc --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/observatory.go @@ -0,0 +1,388 @@ +package cloudflare + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/url" + "time" + + "github.com/goccy/go-json" +) + +var ( + ErrMissingObservatoryUrl = errors.New("missing required page url") + ErrMissingObservatoryTestID = errors.New("missing required test id") +) + +// ObservatoryPage describes all the tests for a web page. +type ObservatoryPage struct { + URL string `json:"url"` + Region labeledRegion `json:"region"` + ScheduleFrequency string `json:"scheduleFrequency"` + Tests []ObservatoryPageTest `json:"tests"` +} + +// ObservatoryPageTest describes a single test for a web page. +type ObservatoryPageTest struct { + ID string `json:"id"` + Date *time.Time `json:"date"` + URL string `json:"url"` + Region labeledRegion `json:"region"` + ScheduleFrequency *string `json:"scheduleFrequency"` + MobileReport ObservatoryLighthouseReport `json:"mobileReport"` + DesktopReport ObservatoryLighthouseReport `json:"desktopReport"` +} + +// labeledRegion describes a region the test was run in. +type labeledRegion struct { + Value string `json:"value"` + Label string `json:"label"` +} + +// ObservatorySchedule describe a test schedule. +type ObservatorySchedule struct { + URL string `json:"url"` + Region string `json:"region"` + Frequency string `json:"frequency"` +} + +// ObservatoryLighthouseReport describes the web vital metrics result. +type ObservatoryLighthouseReport struct { + PerformanceScore int `json:"performanceScore"` + State string `json:"state"` + DeviceType string `json:"deviceType"` + // TTFB is time to first byte + TTFB int `json:"ttfb"` + // FCP is first contentful paint + FCP int `json:"fcp"` + // LCP is largest contentful pain + LCP int `json:"lcp"` + // TTI is time to interactive + TTI int `json:"tti"` + // TBT is total blocking time + TBT int `json:"tbt"` + // SI is speed index + SI int `json:"si"` + // CLS is cumulative layout shift + CLS float64 `json:"cls"` + Error *lighthouseError `json:"error,omitempty"` +} + +// lighthouseError describes the test error. +type lighthouseError struct { + Code string `json:"code"` + Detail string `json:"detail"` + FinalDisplayedURL string `json:"finalDisplayedUrl"` +} + +// ObservatoryPageTrend describes the web vital metrics trend. +type ObservatoryPageTrend struct { + PerformanceScore []*int `json:"performanceScore"` + TTFB []*int `json:"ttfb"` + FCP []*int `json:"fcp"` + LCP []*int `json:"lcp"` + TTI []*int `json:"tti"` + TBT []*int `json:"tbt"` + SI []*int `json:"si"` + CLS []*float64 `json:"cls"` +} + +type ListObservatoryPagesParams struct { +} + +// ObservatoryPagesResponse is the API response, containing a list of ObservatoryPage. +type ObservatoryPagesResponse struct { + Response + Result []ObservatoryPage `json:"result"` +} + +// ListObservatoryPages returns a list of pages which have been tested. +// +// API reference: https://api.cloudflare.com/#speed-list-pages +func (api *API) ListObservatoryPages(ctx context.Context, rc *ResourceContainer, params ListObservatoryPagesParams) ([]ObservatoryPage, error) { + uri := fmt.Sprintf("/zones/%s/speed_api/pages", rc.Identifier) + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return nil, err + } + var r ObservatoryPagesResponse + err = json.Unmarshal(res, &r) + if err != nil { + return nil, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + return r.Result, nil +} + +type GetObservatoryPageTrendParams struct { + URL string `url:"-"` + Region string `url:"region"` + DeviceType string `url:"deviceType"` + Start *time.Time `url:"start"` + End *time.Time `url:"end,omitempty"` + Timezone string `url:"tz"` + Metrics []string `url:"metrics"` +} + +type ObservatoryPageTrendResponse struct { + Response + Result ObservatoryPageTrend `json:"result"` +} + +// GetObservatoryPageTrend returns a the trend of web vital metrics for a page in a specific region. +// +// API reference: https://api.cloudflare.com/#speed-list-page-trend +func (api *API) GetObservatoryPageTrend(ctx context.Context, rc *ResourceContainer, params GetObservatoryPageTrendParams) (*ObservatoryPageTrend, error) { + if params.URL == "" { + return nil, ErrMissingObservatoryUrl + } + uri := buildURI(fmt.Sprintf("/zones/%s/speed_api/pages/%s/trend", rc.Identifier, url.PathEscape(params.URL)), params) + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return nil, err + } + var r ObservatoryPageTrendResponse + err = json.Unmarshal(res, &r) + if err != nil { + return nil, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + return &r.Result, nil +} + +var listObservatoryPageTestDefaultPageSize = 20 + +type ListObservatoryPageTestParams struct { + URL string `url:"-"` + Region string `url:"region"` + ResultInfo +} + +type ObservatoryPageTestsResponse struct { + Response + Result []ObservatoryPageTest `json:"result"` + ResultInfo `json:"result_info"` +} + +// ListObservatoryPageTests returns a list of tests for a page in a specific region. +// +// API reference: https://api.cloudflare.com/#speed-list-test-history +func (api *API) ListObservatoryPageTests(ctx context.Context, rc *ResourceContainer, params ListObservatoryPageTestParams) ([]ObservatoryPageTest, *ResultInfo, error) { + if params.URL == "" { + return nil, nil, ErrMissingObservatoryUrl + } + autoPaginate := true + if params.PerPage >= 1 || params.Page >= 1 { + autoPaginate = false + } + if params.PerPage < 1 { + params.PerPage = listObservatoryPageTestDefaultPageSize + } + if params.Page < 1 { + params.Page = 1 + } + var tests []ObservatoryPageTest + var lastResultInfo ResultInfo + for { + uri := buildURI(fmt.Sprintf("/zones/%s/speed_api/pages/%s/tests", rc.Identifier, url.PathEscape(params.URL)), params) + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return nil, nil, err + } + var r ObservatoryPageTestsResponse + err = json.Unmarshal(res, &r) + if err != nil { + return nil, nil, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + tests = append(tests, r.Result...) + lastResultInfo = r.ResultInfo.Next() + if params.ResultInfo.Done() || !autoPaginate { + break + } + } + return tests, &lastResultInfo, nil +} + +type CreateObservatoryPageTestParams struct { + URL string + Settings CreateObservatoryPageTestSettings +} +type CreateObservatoryPageTestSettings struct { + Region string `json:"region"` +} + +type ObservatoryPageTestResponse struct { + Response + Result ObservatoryPageTest `json:"result"` +} + +// CreateObservatoryPageTest starts a test for a page in a specific region. +// +// API reference: https://api.cloudflare.com/#speed-create-test +func (api *API) CreateObservatoryPageTest(ctx context.Context, rc *ResourceContainer, params CreateObservatoryPageTestParams) (*ObservatoryPageTest, error) { + if params.URL == "" { + return nil, ErrMissingObservatoryUrl + } + uri := fmt.Sprintf("/zones/%s/speed_api/pages/%s/tests", rc.Identifier, url.PathEscape(params.URL)) + res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params.Settings) + if err != nil { + return nil, err + } + var r ObservatoryPageTestResponse + err = json.Unmarshal(res, &r) + if err != nil { + return nil, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + return &r.Result, nil +} + +type DeleteObservatoryPageTestsParams struct { + URL string `url:"-"` + Region string `url:"region"` +} + +type ObservatoryCountResponse struct { + Response + Result struct { + Count int `json:"count"` + } `json:"result"` +} + +// DeleteObservatoryPageTests deletes all tests for a page in a specific region. +// +// API reference: https://api.cloudflare.com/#speed-delete-tests +func (api *API) DeleteObservatoryPageTests(ctx context.Context, rc *ResourceContainer, params DeleteObservatoryPageTestsParams) (*int, error) { + if params.URL == "" { + return nil, ErrMissingObservatoryUrl + } + uri := buildURI(fmt.Sprintf("/zones/%s/speed_api/pages/%s/tests", rc.Identifier, url.PathEscape(params.URL)), params) + res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil) + if err != nil { + return nil, err + } + var r ObservatoryCountResponse + err = json.Unmarshal(res, &r) + if err != nil { + return nil, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + return &r.Result.Count, nil +} + +type GetObservatoryPageTestParams struct { + URL string + TestID string +} + +// GetObservatoryPageTest returns a specific test for a page. +// +// API reference: https://api.cloudflare.com/#speed-get-test +func (api *API) GetObservatoryPageTest(ctx context.Context, rc *ResourceContainer, params GetObservatoryPageTestParams) (*ObservatoryPageTest, error) { + if params.URL == "" { + return nil, ErrMissingObservatoryUrl + } + if params.TestID == "" { + return nil, ErrMissingObservatoryTestID + } + uri := fmt.Sprintf("/zones/%s/speed_api/pages/%s/tests/%s", rc.Identifier, url.PathEscape(params.URL), params.TestID) + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return nil, err + } + var r ObservatoryPageTestResponse + err = json.Unmarshal(res, &r) + if err != nil { + return nil, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + return &r.Result, nil +} + +type CreateObservatoryScheduledPageTestParams struct { + URL string `url:"-" json:"-"` + Region string `url:"region" json:"region"` + Frequency string `url:"frequency" json:"-"` +} + +type ObservatoryScheduledPageTest struct { + Schedule ObservatorySchedule `json:"schedule"` + Test ObservatoryPageTest `json:"test"` +} + +type CreateObservatoryScheduledPageTestResponse struct { + Response + Result ObservatoryScheduledPageTest `json:"result"` +} + +// CreateObservatoryScheduledPageTest creates a scheduled test for a page in a specific region. +// +// API reference: https://api.cloudflare.com/#speed-create-scheduled-test +func (api *API) CreateObservatoryScheduledPageTest(ctx context.Context, rc *ResourceContainer, params CreateObservatoryScheduledPageTestParams) (*ObservatoryScheduledPageTest, error) { + if params.URL == "" { + return nil, ErrMissingObservatoryUrl + } + uri := buildURI(fmt.Sprintf("/zones/%s/speed_api/schedule/%s", rc.Identifier, url.PathEscape(params.URL)), params) + res, err := api.makeRequestContext(ctx, http.MethodPost, uri, params) + if err != nil { + return nil, err + } + var r CreateObservatoryScheduledPageTestResponse + err = json.Unmarshal(res, &r) + if err != nil { + return nil, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + return &r.Result, nil +} + +type GetObservatoryScheduledPageTestParams struct { + URL string `url:"-"` + Region string `url:"region"` +} + +type ObservatoryScheduleResponse struct { + Response + Result ObservatorySchedule `json:"result"` +} + +// GetObservatoryScheduledPageTest returns the test schedule for a page in a specific region. +// +// API reference: https://api.cloudflare.com/#speed-get-scheduled-test +func (api *API) GetObservatoryScheduledPageTest(ctx context.Context, rc *ResourceContainer, params GetObservatoryScheduledPageTestParams) (*ObservatorySchedule, error) { + if params.URL == "" { + return nil, ErrMissingObservatoryUrl + } + uri := buildURI(fmt.Sprintf("/zones/%s/speed_api/schedule/%s", rc.Identifier, url.PathEscape(params.URL)), params) + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return nil, err + } + var r ObservatoryScheduleResponse + err = json.Unmarshal(res, &r) + if err != nil { + return nil, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + return &r.Result, nil +} + +type DeleteObservatoryScheduledPageTestParams struct { + URL string `url:"-"` + Region string `url:"region"` +} + +// DeleteObservatoryScheduledPageTest deletes the test schedule for a page in a specific region. +// +// API reference: https://api.cloudflare.com/#speed-delete-scheduled-test +func (api *API) DeleteObservatoryScheduledPageTest(ctx context.Context, rc *ResourceContainer, params DeleteObservatoryScheduledPageTestParams) (*int, error) { + if params.URL == "" { + return nil, ErrMissingObservatoryUrl + } + uri := buildURI(fmt.Sprintf("/zones/%s/speed_api/schedule/%s", rc.Identifier, url.PathEscape(params.URL)), params) + res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil) + if err != nil { + return nil, err + } + var r ObservatoryCountResponse + err = json.Unmarshal(res, &r) + if err != nil { + return nil, fmt.Errorf("%s: %w", errUnmarshalError, err) + } + return &r.Result.Count, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/per_hostname_tls_settings.go b/vendor/github.com/cloudflare/cloudflare-go/per_hostname_tls_settings.go index 26beec88..74b3ce73 100644 --- a/vendor/github.com/cloudflare/cloudflare-go/per_hostname_tls_settings.go +++ b/vendor/github.com/cloudflare/cloudflare-go/per_hostname_tls_settings.go @@ -2,11 +2,12 @@ package cloudflare import ( "context" - "encoding/json" "errors" "fmt" "net/http" "time" + + "github.com/goccy/go-json" ) // HostnameTLSSetting represents the metadata for a user-created tls setting. diff --git a/vendor/github.com/cloudflare/cloudflare-go/web_analytics.go b/vendor/github.com/cloudflare/cloudflare-go/web_analytics.go index 40e6d1bd..9f3041f1 100644 --- a/vendor/github.com/cloudflare/cloudflare-go/web_analytics.go +++ b/vendor/github.com/cloudflare/cloudflare-go/web_analytics.go @@ -2,11 +2,12 @@ package cloudflare import ( "context" - "encoding/json" "errors" "fmt" "net/http" "time" + + "github.com/goccy/go-json" ) var ( diff --git a/vendor/modules.txt b/vendor/modules.txt index 29bf7d55..0e6ff14c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -70,7 +70,7 @@ github.com/cloudflare/cfssl/errors github.com/cloudflare/cfssl/helpers github.com/cloudflare/cfssl/helpers/derhelpers github.com/cloudflare/cfssl/log -# github.com/cloudflare/cloudflare-go v0.77.0 +# github.com/cloudflare/cloudflare-go v0.78.0 ## explicit; go 1.18 github.com/cloudflare/cloudflare-go # github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41