Skip to content

Commit

Permalink
APISHI-2365 Add support for Get/Patch API Shield API Discovery Operat…
Browse files Browse the repository at this point in the history
…ions

This change adds support for the following API Shield related endpoints related to API Discovery:

- Retrieve discovered operations on a zone
- Patch discovered operations
- Patch discovered operation
  • Loading branch information
djhworld committed Oct 3, 2023
1 parent 33708b3 commit 01e4f42
Show file tree
Hide file tree
Showing 3 changed files with 576 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/1413.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
Add support for Get/Patch API Shield API Discovery Operations
```
174 changes: 174 additions & 0 deletions api_shield_api_discovery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package cloudflare

import (
"context"
"fmt"
"net/http"
"time"

"github.com/goccy/go-json"
)

// APIShieldDiscoveryOperation is an operation that was discovered by API Discovery.
type APIShieldDiscoveryOperation struct {
// ID represents the ID of the operation
ID string `json:"id"`
// Origin represents the API discovery engine(s) that discovered this operation
Origin []string `json:"origin"`
// State represents the state of operation in API Discovery
State string `json:"state"`
// LastUpdated timestamp of when this operation was last updated
LastUpdated *time.Time `json:"last_updated,omitempty"`
// Features are additional data about the operation
Features map[string]any `json:"features,omitempty"`

Method string `json:"method"`
Host string `json:"host"`
Endpoint string `json:"endpoint"`
}

// ListAPIShieldDiscoveryOperationsParams represents the parameters to pass when retrieving discovered operations.
//
// API documentation: https://developers.cloudflare.com/api/operations/api-shield-api-discovery-retrieve-discovered-operations-on-a-zone
type ListAPIShieldDiscoveryOperationsParams struct {
// 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
APIShieldListDiscoveryOperationsFilters
// Pagination options to apply to the request.
PaginationOptions
}

// APIShieldListDiscoveryOperationsFilters represents the filtering query parameters to set when retrieving discovery operations.
//
// API documentation: https://developers.cloudflare.com/api/operations/api-shield-api-discovery-retrieve-discovered-operations-on-a-zone
type APIShieldListDiscoveryOperationsFilters 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"`
// Diff when true, only return API Discovery results that are not saved into API Shield Endpoint Management
Diff bool `url:"diff,omitempty"`
// Origin filter results to only include discovery results sourced from a particular discovery engine
Origin string `url:"origin,omitempty"`
// State filter results to only include discovery results in a particular state.
State string `url:"state,omitempty"`
}

// PatchAPIShieldDiscoveryOperationParams represents the parameters to pass to patch a discovery operation
//
// API documentation: https://developers.cloudflare.com/api/operations/api-shield-api-patch-discovered-operation
type PatchAPIShieldDiscoveryOperationParams struct {
// OperationID is the operation to be patched
OperationID string `json:"-" url:"-"`

PatchAPIShieldDiscoveryOperation
}

// PatchAPIShieldDiscoveryOperationsParams maps discovery operation IDs to PatchAPIShieldDiscoveryOperation structs
//
// Example:
//
// PatchAPIShieldDiscoveryOperations{
// "99522293-a505-45e5-bbad-bbc339f5dc40": PatchAPIShieldDiscoveryOperation{ State: "review" },
// }
//
// API documentation: https://developers.cloudflare.com/api/operations/api-shield-api-patch-discovered-operations
type PatchAPIShieldDiscoveryOperationsParams map[string]PatchAPIShieldDiscoveryOperation

// PatchAPIShieldDiscoveryOperation represents the state to set on a discovery operation.
type PatchAPIShieldDiscoveryOperation struct {
// State is the state to set on the operation
State string `json:"state" url:"-"`
}

// APIShieldListDiscoveryOperationsResponse represents the response from the api_gateway/discovery/operations endpoint.
type APIShieldListDiscoveryOperationsResponse struct {
Result []APIShieldDiscoveryOperation `json:"result"`
ResultInfo `json:"result_info"`
Response
}

// APIShieldPatchDiscoveryOperationResponse represents the response from the PATCH api_gateway/discovery/operations/{id} endpoint.
type APIShieldPatchDiscoveryOperationResponse struct {
Result PatchAPIShieldDiscoveryOperation `json:"result"`
Response
}

// APIShieldPatchDiscoveryOperationsResponse represents the response from the PATCH api_gateway/discovery/operations endpoint.
type APIShieldPatchDiscoveryOperationsResponse struct {
Result PatchAPIShieldDiscoveryOperationsParams `json:"result"`
Response
}

// ListAPIShieldDiscoveryOperations retrieve the most up to date view of discovered operations.
//
// API documentation: https://developers.cloudflare.com/api/operations/api-shield-api-discovery-retrieve-discovered-operations-on-a-zone
func (api *API) ListAPIShieldDiscoveryOperations(ctx context.Context, rc *ResourceContainer, params ListAPIShieldDiscoveryOperationsParams) ([]APIShieldDiscoveryOperation, ResultInfo, error) {
path := fmt.Sprintf("/zones/%s/api_gateway/discovery/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 APIShieldListDiscoveryOperationsResponse
err = json.Unmarshal(res, &asResponse)
if err != nil {
return nil, ResultInfo{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
}

return asResponse.Result, asResponse.ResultInfo, nil
}

// PatchAPIShieldDiscoveryOperation updates certain fields on a discovered operation
//
// API Documentation: https://developers.cloudflare.com/api/operations/api-shield-api-patch-discovered-operation
func (api *API) PatchAPIShieldDiscoveryOperation(ctx context.Context, rc *ResourceContainer, params PatchAPIShieldDiscoveryOperationParams) (*PatchAPIShieldDiscoveryOperation, error) {
if params.OperationID == "" {
return nil, fmt.Errorf("params.OperationID must be provided")
}

uri := fmt.Sprintf("/zones/%s/api_gateway/discovery/operations/%s", rc.Identifier, params.OperationID)

res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
if err != nil {
return nil, err
}

// Result should be the updated schema that was patched
var asResponse APIShieldPatchDiscoveryOperationResponse
err = json.Unmarshal(res, &asResponse)
if err != nil {
return nil, fmt.Errorf("%s: %w", errUnmarshalError, err)
}

return &asResponse.Result, nil
}

// PatchAPIShieldDiscoveryOperations bulk updates certain fields on multiple discovered operations
//
// API documentation: https://developers.cloudflare.com/api/operations/api-shield-api-patch-discovered-operations
func (api *API) PatchAPIShieldDiscoveryOperations(ctx context.Context, rc *ResourceContainer, params PatchAPIShieldDiscoveryOperationsParams) (*PatchAPIShieldDiscoveryOperationsParams, error) {
uri := fmt.Sprintf("/zones/%s/api_gateway/discovery/operations", rc.Identifier)

res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
if err != nil {
return nil, err
}

// Result should be the updated schema that was patched
var asResponse APIShieldPatchDiscoveryOperationsResponse
err = json.Unmarshal(res, &asResponse)
if err != nil {
return nil, fmt.Errorf("%s: %w", errUnmarshalError, err)
}

return &asResponse.Result, nil
}

0 comments on commit 01e4f42

Please sign in to comment.