diff --git a/.changelog/2449.txt b/.changelog/2449.txt new file mode 100644 index 0000000000..6812791e84 --- /dev/null +++ b/.changelog/2449.txt @@ -0,0 +1,7 @@ +```release-note:enhancement +resource/cloudflare_email_routing_rule: add action type `drop` +``` + +```release-note:enhancement +resource/cloudflare_email_routing_rule: `action.value` is now optional to support `drop` rules not requiring it +``` diff --git a/docs/resources/email_routing_rule.md b/docs/resources/email_routing_rule.md index 9f83406840..a38f0ffa0d 100644 --- a/docs/resources/email_routing_rule.md +++ b/docs/resources/email_routing_rule.md @@ -54,8 +54,11 @@ resource "cloudflare_email_routing_rule" "main" { Required: -- `type` (String) Type of supported action. -- `value` (List of String) An array with items in the following form. +- `type` (String) Type of supported action. Available values: `forward`, `worker`, `drop`. + +Optional: + +- `value` (List of String) An array with items in the following form. Only required when `type` is `forward` or `worker`. @@ -63,7 +66,7 @@ Required: Required: -- `type` (String) Type of matcher. +- `type` (String) Type of matcher. Available values: `literal`, `all`. Optional: diff --git a/internal/sdkv2provider/resource_cloudflare_email_routing_address_test.go b/internal/sdkv2provider/resource_cloudflare_email_routing_address_test.go index c4fc0677b0..3fec5349a6 100644 --- a/internal/sdkv2provider/resource_cloudflare_email_routing_address_test.go +++ b/internal/sdkv2provider/resource_cloudflare_email_routing_address_test.go @@ -18,7 +18,7 @@ func testEmailRoutingAddressConfig(resourceID, accountID, email string) string { `, resourceID, accountID, email) } -func TestAccTestEmailRoutingAddress(t *testing.T) { +func TestAccCloudflareEmailRoutingAddress(t *testing.T) { rnd := generateRandomResourceName() name := "cloudflare_email_routing_address." + rnd accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID") diff --git a/internal/sdkv2provider/resource_cloudflare_email_routing_catch_all_test.go b/internal/sdkv2provider/resource_cloudflare_email_routing_catch_all_test.go index 5a5cd874f3..3d5b08cab7 100644 --- a/internal/sdkv2provider/resource_cloudflare_email_routing_catch_all_test.go +++ b/internal/sdkv2provider/resource_cloudflare_email_routing_catch_all_test.go @@ -28,7 +28,7 @@ func testEmailRoutingRuleCatchAllConfig(resourceID, zoneID string, enabled bool) `, resourceID, zoneID, enabled) } -func TestAccTestEmailRoutingCatchAll(t *testing.T) { +func TestAccCloudflareEmailRoutingCatchAll(t *testing.T) { rnd := generateRandomResourceName() name := "cloudflare_email_routing_catch_all." + rnd zoneID := os.Getenv("CLOUDFLARE_ZONE_ID") diff --git a/internal/sdkv2provider/resource_cloudflare_email_routing_rule.go b/internal/sdkv2provider/resource_cloudflare_email_routing_rule.go index 48c3ec1ab5..9892f17433 100644 --- a/internal/sdkv2provider/resource_cloudflare_email_routing_rule.go +++ b/internal/sdkv2provider/resource_cloudflare_email_routing_rule.go @@ -46,8 +46,10 @@ func buildMatchersAndActions(d *schema.ResourceData) (matchers []cloudflare.Emai action := item.(map[string]interface{}) ruleAction := cloudflare.EmailRoutingRuleAction{} ruleAction.Type = action["type"].(string) - for _, value := range action["value"].([]interface{}) { - ruleAction.Value = append(ruleAction.Value, value.(string)) + if val, ok := action["value"]; ok { + for _, value := range val.([]interface{}) { + ruleAction.Value = append(ruleAction.Value, value.(string)) + } } actions = append(actions, ruleAction) diff --git a/internal/sdkv2provider/resource_cloudflare_email_routing_rule_test.go b/internal/sdkv2provider/resource_cloudflare_email_routing_rule_test.go index 045f88df6b..d45f16f17e 100644 --- a/internal/sdkv2provider/resource_cloudflare_email_routing_rule_test.go +++ b/internal/sdkv2provider/resource_cloudflare_email_routing_rule_test.go @@ -30,7 +30,27 @@ func testEmailRoutingRuleConfig(resourceID, zoneID string, enabled bool, priorit `, resourceID, zoneID, enabled, priority) } -func TestAccTestEmailRoutingRule(t *testing.T) { +func testEmailRoutingRuleConfigDrop(resourceID, zoneID string, enabled bool, priority int) string { + return fmt.Sprintf(` + resource "cloudflare_email_routing_rule" "%[1]s" { + zone_id = "%[2]s" + enabled = "%[3]t" + priority = "%[4]d" + name = "%[1]s" + matcher { + field = "to" + type = "literal" + value = "test@example.com" + } + + action { + type = "drop" + } + } + `, resourceID, zoneID, enabled, priority) +} + +func TestAccCloudflareEmailRoutingRule_Basic(t *testing.T) { rnd := generateRandomResourceName() name := "cloudflare_email_routing_rule." + rnd zoneID := os.Getenv("CLOUDFLARE_ZONE_ID") @@ -59,3 +79,31 @@ func TestAccTestEmailRoutingRule(t *testing.T) { }, }) } + +func TestAccCloudflareEmailRoutingRule_Drop(t *testing.T) { + rnd := generateRandomResourceName() + name := "cloudflare_email_routing_rule." + rnd + zoneID := os.Getenv("CLOUDFLARE_ZONE_ID") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: providerFactories, + Steps: []resource.TestStep{ + { + Config: testEmailRoutingRuleConfigDrop(rnd, zoneID, true, 10), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(name, "enabled", "true"), + resource.TestCheckResourceAttr(name, consts.ZoneIDSchemaKey, zoneID), + resource.TestCheckResourceAttr(name, "priority", "10"), + resource.TestCheckResourceAttr(name, "name", rnd), + + resource.TestCheckResourceAttr(name, "matcher.0.type", "literal"), + resource.TestCheckResourceAttr(name, "matcher.0.field", "to"), + resource.TestCheckResourceAttr(name, "matcher.0.value", "test@example.com"), + + resource.TestCheckResourceAttr(name, "action.0.type", "drop"), + ), + }, + }, + }) +} diff --git a/internal/sdkv2provider/schema_cloudflare_email_routing_rules.go b/internal/sdkv2provider/schema_cloudflare_email_routing_rules.go index f8900948c0..f0978b448c 100644 --- a/internal/sdkv2provider/schema_cloudflare_email_routing_rules.go +++ b/internal/sdkv2provider/schema_cloudflare_email_routing_rules.go @@ -1,6 +1,8 @@ package sdkv2provider import ( + "fmt" + "github.com/cloudflare/terraform-provider-cloudflare/internal/consts" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -42,7 +44,7 @@ func resourceCloudflareEmailRoutingRuleSchema() map[string]*schema.Schema { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "type": { - Description: "Type of matcher.", + Description: fmt.Sprintf("Type of matcher. %s", renderAvailableDocumentationValuesStringSlice([]string{"literal", "all"})), Type: schema.TypeString, Required: true, ValidateFunc: validation.StringInSlice([]string{"literal", "all"}, true), @@ -68,15 +70,15 @@ func resourceCloudflareEmailRoutingRuleSchema() map[string]*schema.Schema { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "type": { - Description: "Type of supported action.", + Description: fmt.Sprintf("Type of supported action. %s", renderAvailableDocumentationValuesStringSlice([]string{"forward", "worker", "drop"})), Type: schema.TypeString, Required: true, - ValidateFunc: validation.StringInSlice([]string{"forward", "worker"}, true), + ValidateFunc: validation.StringInSlice([]string{"forward", "worker", "drop"}, true), }, "value": { - Description: "An array with items in the following form.", + Description: "An array with items in the following form. Only required when `type` is `forward` or `worker`.", Type: schema.TypeList, - Required: true, + Optional: true, Elem: &schema.Schema{ Type: schema.TypeString, ValidateFunc: validation.StringLenBetween(0, 90),