diff --git a/.changelog/2101.txt b/.changelog/2101.txt new file mode 100644 index 0000000000..bcfbe8345f --- /dev/null +++ b/.changelog/2101.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +cloudflare_tiered_cache +``` diff --git a/docs/resources/tiered_cache.md b/docs/resources/tiered_cache.md new file mode 100644 index 0000000000..7f89c4c73f --- /dev/null +++ b/docs/resources/tiered_cache.md @@ -0,0 +1,34 @@ +--- +page_title: "cloudflare_tiered_cache Resource - Cloudflare" +subcategory: "" +description: |- + Provides a resource, that manages Cloudflare Tiered Cache settings. + This allows you to adjust topologies for your zone. +--- + +# cloudflare_tiered_cache (Resource) + +Provides a resource, that manages Cloudflare Tiered Cache settings. +This allows you to adjust topologies for your zone. + +## Example Usage + +```terraform +resource "cloudflare_tiered_cache" "example" { + zone_id = "0da42c8d2132a9ddaf714f9e7c920711" + cache_type = "smart" +} +``` + +## Schema + +### Required + +- `cache_type` (String) The typed of tiered cache to utilize on the zone. Available values: `generic`, `smart`, `off`. +- `zone_id` (String) The zone identifier to target for the resource. **Modifying this attribute will force creation of a new resource.** + +### Read-Only + +- `id` (String) The ID of this resource. + + diff --git a/examples/resources/cloudflare_tiered_cache/resource.tf b/examples/resources/cloudflare_tiered_cache/resource.tf new file mode 100644 index 0000000000..55eef03925 --- /dev/null +++ b/examples/resources/cloudflare_tiered_cache/resource.tf @@ -0,0 +1,4 @@ +resource "cloudflare_tiered_cache" "example" { + zone_id = "0da42c8d2132a9ddaf714f9e7c920711" + cache_type = "smart" +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index d4edd7a1e9..9cac8d64b1 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -260,6 +260,7 @@ func New(version string) func() *schema.Provider { "cloudflare_teams_list": resourceCloudflareTeamsList(), "cloudflare_teams_location": resourceCloudflareTeamsLocation(), "cloudflare_teams_proxy_endpoint": resourceCloudflareTeamsProxyEndpoint(), + "cloudflare_tiered_cache": resourceCloudflareTieredCache(), "cloudflare_tunnel_config": resourceCloudflareTunnelConfig(), "cloudflare_teams_rule": resourceCloudflareTeamsRule(), "cloudflare_total_tls": resourceCloudflareTotalTLS(), diff --git a/internal/provider/resource_cloudflare_tiered_cache.go b/internal/provider/resource_cloudflare_tiered_cache.go new file mode 100644 index 0000000000..e0fc4f9e00 --- /dev/null +++ b/internal/provider/resource_cloudflare_tiered_cache.go @@ -0,0 +1,78 @@ +package provider + +import ( + "context" + "fmt" + + "github.com/MakeNowJust/heredoc/v2" + "github.com/cloudflare/cloudflare-go" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceCloudflareTieredCache() *schema.Resource { + return &schema.Resource{ + Schema: resourceCloudflareTieredCacheSchema(), + ReadContext: resourceCloudflareTieredCacheRead, + UpdateContext: resourceCloudflareTieredCacheUpdate, + CreateContext: resourceCloudflareTieredCacheUpdate, + DeleteContext: resourceCloudflareTieredCacheDelete, + Description: heredoc.Doc(` + Provides a resource, that manages Cloudflare Tiered Cache settings. + This allows you to adjust topologies for your zone. + `), + } +} + +func resourceCloudflareTieredCacheUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*cloudflare.API) + zoneID := d.Get("zone_id").(string) + + var cacheType cloudflare.TieredCacheType + switch d.Get("cache_type").(string) { + case "smart": + cacheType = cloudflare.TieredCacheSmart + break + case "generic": + cacheType = cloudflare.TieredCacheGeneric + break + case "off": + cacheType = cloudflare.TieredCacheOff + break + default: + return diag.FromErr(fmt.Errorf("error updating tiered cache settings: Unsupported cache type requested")) + } + + _, err := client.SetTieredCache(ctx, cloudflare.ZoneIdentifier(zoneID), cacheType) + if err != nil { + return diag.FromErr(fmt.Errorf("error updating tiered cache settings: %w", err)) + } + d.SetId(zoneID) + return resourceCloudflareTieredCacheRead(ctx, d, meta) +} + +func resourceCloudflareTieredCacheRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*cloudflare.API) + zoneID := d.Get("zone_id").(string) + + result, err := client.GetTieredCache(ctx, cloudflare.ZoneIdentifier(zoneID)) + if err != nil { + return diag.FromErr(fmt.Errorf("error retrieving tiered cache settings: %w", err)) + } + + d.SetId(zoneID) + d.Set("cache_type", result.Type.String()) + return nil +} + +func resourceCloudflareTieredCacheDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*cloudflare.API) + zoneID := d.Get("zone_id").(string) + + _, err := client.DeleteTieredCache(ctx, cloudflare.ZoneIdentifier(zoneID)) + if err != nil { + return diag.FromErr(fmt.Errorf("error creating deleting tiered cache configuration: %w", err)) + } + + return nil +} diff --git a/internal/provider/resource_cloudflare_tiered_cache_test.go b/internal/provider/resource_cloudflare_tiered_cache_test.go new file mode 100644 index 0000000000..bd2ad1f999 --- /dev/null +++ b/internal/provider/resource_cloudflare_tiered_cache_test.go @@ -0,0 +1,58 @@ +package provider + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func testTieredCacheConfig(rnd, zoneID, cacheType string) string { + return fmt.Sprintf(` +resource "cloudflare_tiered_cache" "%[1]s" { + zone_id = "%[2]s" + cache_type = "%[3]s" +} +`, rnd, zoneID, cacheType) +} + +func TestAccCloudflareTieredCache_Smart(t *testing.T) { + rnd := generateRandomResourceName() + name := "cloudflare_tiered_cache." + rnd + zoneID := os.Getenv("CLOUDFLARE_ZONE_ID") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: providerFactories, + Steps: []resource.TestStep{ + { + Config: testTieredCacheConfig(rnd, zoneID, "smart"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(name, "zone_id", zoneID), + resource.TestCheckResourceAttr(name, "cache_type", "smart"), + ), + }, + }, + }) +} + +func TestAccCloudflareTieredCache_Generic(t *testing.T) { + rnd := generateRandomResourceName() + name := "cloudflare_tiered_cache." + rnd + zoneID := os.Getenv("CLOUDFLARE_ZONE_ID") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: providerFactories, + Steps: []resource.TestStep{ + { + Config: testTieredCacheConfig(rnd, zoneID, "generic"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(name, "zone_id", zoneID), + resource.TestCheckResourceAttr(name, "cache_type", "generic"), + ), + }, + }, + }) +} diff --git a/internal/provider/schema_cloudflare_tiered_cache.go b/internal/provider/schema_cloudflare_tiered_cache.go new file mode 100644 index 0000000000..441030a951 --- /dev/null +++ b/internal/provider/schema_cloudflare_tiered_cache.go @@ -0,0 +1,25 @@ +package provider + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceCloudflareTieredCacheSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "zone_id": { + Description: "The zone identifier to target for the resource.", + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "cache_type": { + Description: fmt.Sprintf("The typed of tiered cache to utilize on the zone. %s", renderAvailableDocumentationValuesStringSlice([]string{"generic", "smart", "off"})), + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"generic", "smart", "off"}, false), + }, + } +}