From 6697d85d4df8e9f59d01b7dee6311b0c9abeb0ed Mon Sep 17 00:00:00 2001 From: Mikey Sleevi Date: Wed, 21 Dec 2022 11:24:08 -0700 Subject: [PATCH] Adds support for Tiered Caching This adds support for manipulation, creating and deletion of tiered cache settings through the existing mechanisms in the Cloudflare API. This adds support for settings generic and smart tiered cache topologies through the terraform provider. Implementation: * Create/Update, Delete and Get methods for Tiered Cache settings --- .changelog/2101.txt | 3 + internal/provider/provider.go | 1 + .../resource_cloudflare_tiered_cache.go | 76 +++++++++++++++++++ .../resource_cloudflare_tiered_cache_test.go | 58 ++++++++++++++ .../schema_cloudflare_tiered_cache.go | 26 +++++++ 5 files changed, 164 insertions(+) create mode 100644 .changelog/2101.txt create mode 100644 internal/provider/resource_cloudflare_tiered_cache.go create mode 100644 internal/provider/resource_cloudflare_tiered_cache_test.go create mode 100644 internal/provider/schema_cloudflare_tiered_cache.go 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/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..cfd545587c --- /dev/null +++ b/internal/provider/resource_cloudflare_tiered_cache.go @@ -0,0 +1,76 @@ +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 between Off, Smart and Generic 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) + 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..a0cf4cb171 --- /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 TestCloudflareSmartTieredCache(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 TestCloudflareGenericTieredCache(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..b9b1f146d1 --- /dev/null +++ b/internal/provider/schema_cloudflare_tiered_cache.go @@ -0,0 +1,26 @@ +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"})), + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{"generic", "smart"}, false), + }, + } +}