Skip to content

Commit

Permalink
Merge pull request #706 from terraform-providers/feature/SDK-95_cache…
Browse files Browse the repository at this point in the history
…_ttl_by_status

SDK-95: cache_ttl_by_status support for Page Rules
  • Loading branch information
jacobbednarz authored Jun 17, 2020
2 parents c3e16f0 + 04fa7ca commit cd0cff7
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 1 deletion.
55 changes: 55 additions & 0 deletions cloudflare/resource_cloudflare_page_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,22 @@ func resourceCloudflarePageRule() *schema.Resource {
},
},
},
"cache_ttl_by_status": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"codes": {
Type: schema.TypeString,
Required: true,
},
"ttl": {
Type: schema.TypeInt,
Required: true,
},
},
},
},
},
},
},
Expand Down Expand Up @@ -746,6 +762,30 @@ func transformFromCloudflarePageRuleAction(pageRuleAction *cloudflare.PageRuleAc
value = []interface{}{output}
break

case pageRuleAction.ID == "cache_ttl_by_status":
output := make([]map[string]interface{}, 0)

for key, value := range pageRuleAction.Value.(map[string]interface{}) {
entry := map[string]interface{}{"codes": key}

switch value := value.(type) {
case float64:
entry["ttl"] = int32(value)
case string:
switch value {
case "no-cache":
entry["ttl"] = 0
case "no-store":
entry["ttl"] = -1
}
}

output = append(output, entry)
}

value = output
break

default:
// User supplied ID is already validated, so this is always an internal error
err = fmt.Errorf("Unimplemented action ID %q - this is always an internal error", pageRuleAction.ID)
Expand Down Expand Up @@ -845,6 +885,21 @@ func transformToCloudflarePageRuleAction(id string, value interface{}, d *schema
output[sectionID] = sectionOutput
}

pageRuleAction.Value = output
}
} else if id == "cache_ttl_by_status" {
cacheTTLActionSchema := value.(*schema.Set)

log.Printf("[DEBUG] cache_ttl_by_status action to be applied: %#v", cacheTTLActionSchema)

if cacheTTLActionSchema.Len() != 0 {
output := make(map[string]int)

for _, code := range cacheTTLActionSchema.List() {
code := code.(map[string]interface{})
output[code["codes"].(string)] = code["ttl"].(int)
}

pageRuleAction.Value = output
}
} else {
Expand Down
57 changes: 57 additions & 0 deletions cloudflare/resource_cloudflare_page_rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,30 @@ func TestAccCloudflarePageRuleCacheKeyFields2(t *testing.T) {
})
}

func TestAccCloudflarePageRuleCacheTTLByStatus(t *testing.T) {
var pageRule cloudflare.PageRule
domain := os.Getenv("CLOUDFLARE_DOMAIN")
zoneID := os.Getenv("CLOUDFLARE_ZONE_ID")

rnd := generateRandomResourceName()
name := fmt.Sprintf("cloudflare_page_rule.%s", rnd)
target := fmt.Sprintf("test-cache-ttl-by-status.%s", domain)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudflarePageRuleDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckCloudflarePageRuleConfigCacheTTLByStatus(zoneID, target, rnd),
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudflarePageRuleExists(name, &pageRule),
),
},
},
})
}

func testAccCheckCloudflarePageRuleRecreated(before, after *cloudflare.PageRule) resource.TestCheckFunc {
return func(s *terraform.State) error {
if before.ID == after.ID {
Expand Down Expand Up @@ -767,6 +791,39 @@ resource "cloudflare_page_rule" "test" {
}`, zoneID, target)
}

func testAccCheckCloudflarePageRuleConfigCacheTTLByStatus(zoneID, target, rnd string) string {
return fmt.Sprintf(`
resource "cloudflare_page_rule" "%[3]s" {
zone_id = "%[1]s"
target = "%[2]s"
actions {
cache_ttl_by_status {
codes = "200-299"
ttl = 300
}
cache_ttl_by_status {
codes = "300-399"
ttl = 60
}
cache_ttl_by_status {
codes = "400-403"
ttl = -1
}
cache_ttl_by_status {
codes = "404"
ttl = 30
}
cache_ttl_by_status {
codes = "405-499"
ttl = -1
}
cache_ttl_by_status {
codes = "500-599"
ttl = 0
}
}
}`, zoneID, target, rnd)
}
func buildPageRuleConfig(resourceName string, actions string) string {
domain := os.Getenv("CLOUDFLARE_DOMAIN")
zoneID := os.Getenv("CLOUDFLARE_ZONE_ID")
Expand Down
54 changes: 53 additions & 1 deletion website/docs/r/page_rule.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ Action blocks support the following:
* `bypass_cache_on_cookie` - (Optional) String value of cookie name to conditionally bypass cache the page.
* `cache_by_device_type` - (Optional) Whether this action is `"on"` or `"off"`.
* `cache_deception_armor` - (Optional) Whether this action is `"on"` or `"off"`.
* `cache_key_fields` - (Optional) Controls how Cloudflare creates Cache Keys used to identify files in cache. See below for full description.
* `cache_key_fields` - (Optional) Controls how Cloudflare creates Cache Keys used to identify files in cache. [See below](#cache-key-fields) for full description.
* `cache_level` - (Optional) Whether to set the cache level to `"bypass"`, `"basic"`, `"simplified"`, `"aggressive"`, or `"cache_everything"`.
* `cache_on_cookie` - (Optional) String value of cookie name to conditionally cache the page.
* `cache_ttl_by_status` - (Optional) Set cache TTL based on the response status from the origin web server. Can be specified multiple times. [See below](#cache-ttl-by-status) for full description.
* `disable_apps` - (Optional) Boolean of whether this action is enabled. Default: false.
* `disable_performance` - (Optional) Boolean of whether this action is enabled. Default: false.
* `disable_railgun` - (Optional) Boolean of whether this action is enabled. Default: false.
Expand Down Expand Up @@ -183,6 +184,57 @@ resource "cloudflare_page_rule" "foobar" {
}
```

### Cache TTL by status

-> This setting is available to Enterprise customers only.

Set cache TTL based on the response status from the origin web server. Cache TTL (time-to-live) refers to the duration a resource lives in the Cloudflare network before it is marked as stale or discarded from cache. Status codes are returned by a resource’s origin.

For detailed description please refer to [Cloudflare Support article](https://support.cloudflare.com/hc/en-us/articles/360043842472-Configuring-cache-TTL-by-status-code).

* `codes` - (Required) A HTTP code (e.g. `404`) or range of codes (e.g. `400-499`)
* `ttl` - (Required) Duration a resource lives in the Cloudflare cache.
* positive number - cache for specified duration in seconds
* `0` - sets `no-cache`, saved to cache, but expired immediately (revalidate from origin every time)
* `-1` - sets `no-store`, never save to cache

Example:

```hcl
resource "cloudflare_page_rule" "test" {
zone_id = var.cloudflare_zone_id
target = "${var.cloudflare_zone}/app/*"
priority = 1
actions {
cache_ttl_by_status {
codes = "200-299"
ttl = 300
}
cache_ttl_by_status {
codes = "300-399"
ttl = 60
}
cache_ttl_by_status {
codes = "400-403"
ttl = -1
}
cache_ttl_by_status {
codes = "404"
ttl = 30
}
cache_ttl_by_status {
codes = "405-499"
ttl = -1
}
cache_ttl_by_status {
codes = "500-599"
ttl = 0
}
}
}
```

## Attributes Reference

The following attributes are exported:
Expand Down

0 comments on commit cd0cff7

Please sign in to comment.