Repository: cloudflare/cloudflare-go
Pull request #1336 (2023-07-17 16:04:53)

Add Regional Tiered Cache API support
## Description

Closes https://github.com/cloudflare/cloudflare-go/issues/1334

## Has your change been tested?
Tests added in: `regional_tiered_cache_test.go`

## Types of changes

What sort of change does your code introduce/modify?

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist:

- [x] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [x] I have added tests to cover my changes.
- [x] All new and existing tests passed.
- [ ] This change is using publicly documented in [cloudflare/api-schemas](https://github.com/cloudflare/api-schemas) 
      and relies on stable APIs.

> **Note**: contrary to the docs on: https://developers.cloudflare.com/api/operations/zone-cache-settings-change-regional-tiered-cache-setting, this API does in-fact return `result.value`:
```
❯ curl https://api.cloudflare.com/client/v4/zones/<REDACTED>/cache/regional_tiered_cache | jq
{
  "result": {
    "editable": true,
    "id": "tc_regional",
    "value": "off"
  },
  "success": true,
  "errors": [],
  "messages": []
}
```



Patch:
diff --git a/.changelog/1336.txt b/.changelog/1336.txt
new file mode 100644
index 000000000..f949bdc25
--- /dev/null
+++ b/.changelog/1336.txt
@@ -0,0 +1,3 @@
+```release-note:enhancement
+zone: Added `GetRegionalTieredCache` and `UpdateRegionalTieredCache` to allow setting Regional Tiered Cache for a zone.
+```
diff --git a/regional_tiered_cache.go b/regional_tiered_cache.go
new file mode 100644
index 000000000..31471178a
--- /dev/null
+++ b/regional_tiered_cache.go
@@ -0,0 +1,84 @@
+package cloudflare
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"time"
+)
+
+// RegionalTieredCache is the structure of the API object for the regional tiered cache
+// setting.
+type RegionalTieredCache struct {
+	ID         string    `json:"id,omitempty"`
+	ModifiedOn time.Time `json:"modified_on,omitempty"`
+	Value      string    `json:"value"`
+}
+
+// RegionalTieredCacheDetailsResponse is the API response for the regional tiered cache
+// setting.
+type RegionalTieredCacheDetailsResponse struct {
+	Result RegionalTieredCache `json:"result"`
+	Response
+}
+
+type zoneRegionalTieredCacheSingleResponse struct {
+	Response
+	Result RegionalTieredCache `json:"result"`
+}
+
+type GetRegionalTieredCacheParams struct{}
+
+type UpdateRegionalTieredCacheParams struct {
+	Value string `json:"value"`
+}
+
+// GetRegionalTieredCache returns information about the current regional tiered
+// cache settings.
+//
+// API reference: https://developers.cloudflare.com/api/operations/zone-cache-settings-get-regional-tiered-cache-setting
+func (api *API) GetRegionalTieredCache(ctx context.Context, rc *ResourceContainer, params GetRegionalTieredCacheParams) (RegionalTieredCache, error) {
+	if rc.Level != ZoneRouteLevel {
+		return RegionalTieredCache{}, ErrRequiredZoneLevelResourceContainer
+	}
+
+	uri := fmt.Sprintf("/%s/%s/cache/regional_tiered_cache", rc.Level, rc.Identifier)
+
+	res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil)
+	if err != nil {
+		return RegionalTieredCache{}, err
+	}
+
+	var RegionalTieredCacheDetailsResponse RegionalTieredCacheDetailsResponse
+	err = json.Unmarshal(res, &RegionalTieredCacheDetailsResponse)
+	if err != nil {
+		return RegionalTieredCache{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
+	}
+	return RegionalTieredCacheDetailsResponse.Result, nil
+}
+
+// UpdateRegionalTieredCache updates the regional tiered cache setting for a
+// zone.
+//
+// API reference: https://developers.cloudflare.com/api/operations/zone-cache-settings-change-regional-tiered-cache-setting
+func (api *API) UpdateRegionalTieredCache(ctx context.Context, rc *ResourceContainer, params UpdateRegionalTieredCacheParams) (RegionalTieredCache, error) {
+	if rc.Level != ZoneRouteLevel {
+		return RegionalTieredCache{}, ErrRequiredZoneLevelResourceContainer
+	}
+
+	uri := fmt.Sprintf("/%s/%s/cache/regional_tiered_cache", rc.Level, rc.Identifier)
+
+	res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, params)
+	if err != nil {
+		return RegionalTieredCache{}, err
+	}
+
+	response := &zoneRegionalTieredCacheSingleResponse{}
+	err = json.Unmarshal(res, &response)
+	if err != nil {
+		return RegionalTieredCache{}, fmt.Errorf("%s: %w", errUnmarshalError, err)
+	}
+
+	return response.Result, nil
+}


Test patch:
diff --git a/regional_tiered_cache_test.go b/regional_tiered_cache_test.go
new file mode 100644
index 000000000..df74f3bfe
--- /dev/null
+++ b/regional_tiered_cache_test.go
@@ -0,0 +1,90 @@
+package cloudflare
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/assert"
+)
+
+var regionalTieredCacheTimestampString = "2019-02-20T22:37:07.107449Z"
+var regionalTieredCacheTimestamp, _ = time.Parse(time.RFC3339Nano, regionalTieredCacheTimestampString)
+
+func TestRegionalTieredCache(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")
+		fmt.Fprintf(w, `{
+			"success": true,
+			"errors": [],
+			"messages": [],
+			"result": {
+				"id": "regional_tiered_cache",
+				"value": "on",
+				"modified_on": "%s"
+			}
+		}
+		`, regionalTieredCacheTimestampString)
+	}
+
+	mux.HandleFunc("/zones/"+testZoneID+"/cache/regional_tiered_cache", handler)
+	want := RegionalTieredCache{
+		ID:         "regional_tiered_cache",
+		Value:      "on",
+		ModifiedOn: regionalTieredCacheTimestamp,
+	}
+
+	actual, err := client.GetRegionalTieredCache(
+		context.Background(),
+		ZoneIdentifier(testZoneID),
+		GetRegionalTieredCacheParams{},
+	)
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, want, actual)
+	}
+}
+
+func TestUpdateRegionalTieredCache(t *testing.T) {
+	setup()
+	defer teardown()
+
+	handler := func(w http.ResponseWriter, r *http.Request) {
+		assert.Equal(t, http.MethodPatch, r.Method, "Expected method 'PATCH', got %s", r.Method)
+		w.Header().Set("content-type", "application/json")
+		fmt.Fprintf(w, `{
+			"success": true,
+			"errors": [],
+			"messages": [],
+			"result": {
+				"id": "regional_tiered_cache",
+				"value": "off",
+				"modified_on": "%s"
+			}
+		}
+		`, regionalTieredCacheTimestampString)
+	}
+
+	mux.HandleFunc("/zones/"+testZoneID+"/cache/regional_tiered_cache", handler)
+	want := RegionalTieredCache{
+		ID:         "regional_tiered_cache",
+		Value:      "off",
+		ModifiedOn: regionalTieredCacheTimestamp,
+	}
+
+	actual, err := client.UpdateRegionalTieredCache(
+		context.Background(),
+		ZoneIdentifier(testZoneID),
+		UpdateRegionalTieredCacheParams{Value: "off"},
+	)
+
+	if assert.NoError(t, err) {
+		assert.Equal(t, want, actual)
+	}
+}