-
Notifications
You must be signed in to change notification settings - Fork 593
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds support for utilizing previously undocumented APIs for Tiered Caching endpoints. It allows for setting zones to utilize either generic, smart or off. Implementation: * Adds three new api methods for manipulating tiered cache settings * GetTieredCache which returns the current setting * SetTieredCache which allows for manipulation of existing settings * DeleteTieredCache which allows for unsetting tiered cache
- Loading branch information
Mikey Sleevi
committed
Dec 21, 2022
1 parent
e3f6574
commit 6e8972f
Showing
2 changed files
with
621 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,300 @@ | ||
package cloudflare | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
"time" | ||
) | ||
|
||
type TieredCacheType int | ||
|
||
const ( | ||
TieredCacheOff TieredCacheType = 0 | ||
TieredCacheGeneric TieredCacheType = 1 | ||
TieredCacheSmart TieredCacheType = 2 | ||
) | ||
|
||
type TieredCache struct { | ||
Type TieredCacheType | ||
LastModified time.Time | ||
} | ||
|
||
const notFoundError = "Unable to retrieve tiered_cache_smart_topology_enable setting value. The zone setting does not exist. (1142)" | ||
|
||
// GetTieredCache allows you to retrive the current Tiered Cache Settings for a Zone | ||
// This function does not support custom topologies, only Generic and Smart Tiered Caching | ||
// | ||
// API Reference: TODO | ||
func (api *API) GetTieredCache(ctx context.Context, rc *ResourceContainer) (TieredCache, error) { | ||
var lastModified time.Time | ||
|
||
generic, err := getGenericTieredCache(api, ctx, rc) | ||
if err != nil { | ||
return TieredCache{}, err | ||
} | ||
lastModified = generic.LastModified | ||
|
||
smart, err := getSmartTieredCache(api, ctx, rc) | ||
if err != nil { | ||
return TieredCache{}, err | ||
} | ||
|
||
if smart.LastModified.After(lastModified) { | ||
lastModified = smart.LastModified | ||
} | ||
|
||
if generic.Type == TieredCacheOff { | ||
return TieredCache{Type: TieredCacheOff, LastModified: lastModified}, nil | ||
} | ||
|
||
if smart.Type == TieredCacheOff { | ||
return TieredCache{Type: TieredCacheGeneric, LastModified: lastModified}, nil | ||
} | ||
|
||
return TieredCache{Type: TieredCacheSmart, LastModified: lastModified}, nil | ||
} | ||
|
||
// SetTieredCache allows you to set a zone's tiered cache topology between the available types | ||
// Using the value of TieredCacheOff will disable Tiered Cache entirely | ||
// | ||
// API Reference: TODO | ||
func (api *API) SetTieredCache(ctx context.Context, rc *ResourceContainer, value TieredCacheType) (TieredCache, error) { | ||
if value == TieredCacheOff { | ||
return api.DeleteTieredCache(ctx, rc) | ||
} | ||
|
||
var lastModified time.Time | ||
|
||
if value == TieredCacheGeneric { | ||
result, err := deleteSmartTieredCache(api, ctx, rc) | ||
if err != nil { | ||
return TieredCache{}, err | ||
} | ||
lastModified = result.LastModified | ||
|
||
result, err = enableGenericTieredCache(api, ctx, rc) | ||
if err != nil { | ||
return TieredCache{}, err | ||
} | ||
|
||
if result.LastModified.After(lastModified) { | ||
lastModified = result.LastModified | ||
} | ||
return TieredCache{Type: TieredCacheGeneric, LastModified: lastModified}, nil | ||
} | ||
|
||
result, err := enableGenericTieredCache(api, ctx, rc) | ||
if err != nil { | ||
return TieredCache{}, err | ||
} | ||
lastModified = result.LastModified | ||
|
||
result, err = enableSmartTieredCache(api, ctx, rc) | ||
if err != nil { | ||
return TieredCache{}, err | ||
} | ||
|
||
if result.LastModified.After(lastModified) { | ||
lastModified = result.LastModified | ||
} | ||
return TieredCache{Type: TieredCacheSmart, LastModified: lastModified}, nil | ||
} | ||
|
||
// DeleteTieredCache allows you to delete the tiered cache settings for a zone | ||
// This is equivalent to using SetTieredCache with the value of TieredCacheOff | ||
// | ||
// API Reference: TODO | ||
func (api *API) DeleteTieredCache(ctx context.Context, rc *ResourceContainer) (TieredCache, error) { | ||
var lastModified time.Time | ||
|
||
result, err := deleteSmartTieredCache(api, ctx, rc) | ||
if err != nil { | ||
return TieredCache{}, err | ||
} | ||
lastModified = result.LastModified | ||
|
||
result, err = disableGenericTieredCache(api, ctx, rc) | ||
if err != nil { | ||
return TieredCache{}, err | ||
} | ||
|
||
if result.LastModified.After(lastModified) { | ||
lastModified = result.LastModified | ||
} | ||
return TieredCache{Type: TieredCacheOff, LastModified: lastModified}, nil | ||
} | ||
|
||
type tieredCacheResult struct { | ||
ID string `json:"id"` | ||
Value string `json:"value,omitempty"` | ||
LastModified time.Time `json:"modified_on"` | ||
} | ||
|
||
type tieredCacheResponse struct { | ||
Result tieredCacheResult `json:"result"` | ||
Response | ||
} | ||
|
||
type tieredCacheSetting struct { | ||
Value string `json:"value"` | ||
} | ||
|
||
func getGenericTieredCache(api *API, ctx context.Context, rc *ResourceContainer) (TieredCache, error) { | ||
uri := fmt.Sprintf("/zones/%s/argo/tiered_caching", rc.Identifier) | ||
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) | ||
if err != nil { | ||
return TieredCache{Type: TieredCacheOff}, err | ||
} | ||
|
||
var response tieredCacheResponse | ||
err = json.Unmarshal(res, &response) | ||
if err != nil { | ||
return TieredCache{Type: TieredCacheOff}, err | ||
} | ||
|
||
if !response.Success { | ||
return TieredCache{Type: TieredCacheOff}, errors.New("Request to retrieve generic tiered cache failed") | ||
} | ||
|
||
if response.Result.Value == "off" { | ||
return TieredCache{Type: TieredCacheOff, LastModified: response.Result.LastModified}, nil | ||
} | ||
|
||
return TieredCache{Type: TieredCacheGeneric, LastModified: response.Result.LastModified}, nil | ||
} | ||
|
||
func getSmartTieredCache(api *API, ctx context.Context, rc *ResourceContainer) (TieredCache, error) { | ||
uri := fmt.Sprintf("/zones/%s/cache/tiered_cache_smart_topology_enable", rc.Identifier) | ||
res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) | ||
if err != nil { | ||
if err.Error() == notFoundError { | ||
return TieredCache{Type: TieredCacheOff}, nil | ||
} | ||
return TieredCache{Type: TieredCacheOff}, err | ||
} | ||
|
||
var response tieredCacheResponse | ||
err = json.Unmarshal(res, &response) | ||
if err != nil { | ||
return TieredCache{Type: TieredCacheOff}, err | ||
} | ||
|
||
if !response.Success { | ||
return TieredCache{Type: TieredCacheOff}, errors.New("Request to retrieve smart tiered cache failed") | ||
} | ||
|
||
if response.Result.Value == "off" { | ||
return TieredCache{Type: TieredCacheOff, LastModified: response.Result.LastModified}, nil | ||
} | ||
return TieredCache{Type: TieredCacheSmart, LastModified: response.Result.LastModified}, nil | ||
} | ||
|
||
func enableGenericTieredCache(api *API, ctx context.Context, rc *ResourceContainer) (TieredCache, error) { | ||
uri := fmt.Sprintf("/zones/%s/argo/tiered_caching", rc.Identifier) | ||
setting := tieredCacheSetting{ | ||
Value: "on", | ||
} | ||
body, err := json.Marshal(setting) | ||
if err != nil { | ||
return TieredCache{Type: TieredCacheOff}, err | ||
} | ||
|
||
res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, body) | ||
if err != nil { | ||
return TieredCache{Type: TieredCacheOff}, err | ||
} | ||
|
||
var response tieredCacheResponse | ||
err = json.Unmarshal(res, &response) | ||
if err != nil { | ||
return TieredCache{Type: TieredCacheOff}, err | ||
} | ||
|
||
if !response.Success { | ||
return TieredCache{Type: TieredCacheOff}, errors.New("Request to enable generic tiered cache failed") | ||
} | ||
|
||
return TieredCache{Type: TieredCacheGeneric, LastModified: response.Result.LastModified}, nil | ||
} | ||
|
||
func enableSmartTieredCache(api *API, ctx context.Context, rc *ResourceContainer) (TieredCache, error) { | ||
uri := fmt.Sprintf("/zones/%s/cache/tiered_cache_smart_topology_enable", rc.Identifier) | ||
setting := tieredCacheSetting{ | ||
Value: "on", | ||
} | ||
body, err := json.Marshal(setting) | ||
if err != nil { | ||
return TieredCache{Type: TieredCacheOff}, err | ||
} | ||
|
||
res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, body) | ||
if err != nil { | ||
return TieredCache{Type: TieredCacheOff}, err | ||
} | ||
|
||
var response tieredCacheResponse | ||
err = json.Unmarshal(res, &response) | ||
if err != nil { | ||
return TieredCache{Type: TieredCacheOff}, err | ||
} | ||
|
||
if !response.Success { | ||
return TieredCache{Type: TieredCacheOff}, errors.New("Request to enable smart tiered cache failed") | ||
} | ||
|
||
return TieredCache{Type: TieredCacheSmart, LastModified: response.Result.LastModified}, nil | ||
} | ||
|
||
func disableGenericTieredCache(api *API, ctx context.Context, rc *ResourceContainer) (TieredCache, error) { | ||
uri := fmt.Sprintf("/zones/%s/argo/tiered_caching", rc.Identifier) | ||
setting := tieredCacheSetting{ | ||
Value: "off", | ||
} | ||
body, err := json.Marshal(setting) | ||
if err != nil { | ||
return TieredCache{Type: TieredCacheOff}, err | ||
} | ||
|
||
res, err := api.makeRequestContext(ctx, http.MethodPatch, uri, body) | ||
if err != nil { | ||
return TieredCache{Type: TieredCacheOff}, err | ||
} | ||
|
||
var response tieredCacheResponse | ||
err = json.Unmarshal(res, &response) | ||
if err != nil { | ||
return TieredCache{Type: TieredCacheOff}, err | ||
} | ||
|
||
if !response.Success { | ||
return TieredCache{Type: TieredCacheOff}, errors.New("Request to disable generic tiered cache failed") | ||
} | ||
|
||
return TieredCache{Type: TieredCacheOff, LastModified: response.Result.LastModified}, nil | ||
} | ||
|
||
func deleteSmartTieredCache(api *API, ctx context.Context, rc *ResourceContainer) (TieredCache, error) { | ||
uri := fmt.Sprintf("/zones/%s/cache/tiered_cache_smart_topology_enable", rc.Identifier) | ||
res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil) | ||
if err != nil { | ||
if err.Error() == notFoundError { | ||
return TieredCache{Type: TieredCacheOff}, nil | ||
} | ||
return TieredCache{Type: TieredCacheOff}, err | ||
} | ||
|
||
var response tieredCacheResponse | ||
err = json.Unmarshal(res, &response) | ||
if err != nil { | ||
return TieredCache{Type: TieredCacheOff}, err | ||
} | ||
|
||
if !response.Success { | ||
return TieredCache{Type: TieredCacheOff}, errors.New("Request to disable smart tiered cache failed") | ||
} | ||
|
||
return TieredCache{Type: TieredCacheOff, LastModified: response.Result.LastModified}, nil | ||
} |
Oops, something went wrong.