diff --git a/.changelog/2210.txt b/.changelog/2210.txt new file mode 100644 index 0000000000..c7a087411b --- /dev/null +++ b/.changelog/2210.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/cloudflare_dlp_profile: Add new `allowed_match_count` field to profiles +``` diff --git a/docs/resources/dlp_profile.md b/docs/resources/dlp_profile.md index d3faa0ecbe..1624ed431a 100644 --- a/docs/resources/dlp_profile.md +++ b/docs/resources/dlp_profile.md @@ -18,9 +18,10 @@ They are referenced in Zero Trust Gateway rules. ```terraform # Predefined profile resource "cloudflare_dlp_profile" "example_predefined" { - account_id = "0da42c8d2132a9ddaf714f9e7c920711" - name = "Example Predefined Profile" - type = "predefined" + account_id = "0da42c8d2132a9ddaf714f9e7c920711" + name = "Example Predefined Profile" + type = "predefined" + allowed_match_count = 0 entry { name = "Mastercard Card Number" @@ -35,10 +36,11 @@ resource "cloudflare_dlp_profile" "example_predefined" { # Custom profile resource "cloudflare_dlp_profile" "example_custom" { - account_id = "0da42c8d2132a9ddaf714f9e7c920711" - name = "Example Custom Profile" - description = "A profile with example entries" - type = "custom" + account_id = "0da42c8d2132a9ddaf714f9e7c920711" + name = "Example Custom Profile" + description = "A profile with example entries" + type = "custom" + allowed_match_count = 0 entry { name = "Matches visa credit cards" @@ -65,6 +67,7 @@ resource "cloudflare_dlp_profile" "example_custom" { ### Required - `account_id` (String) The account identifier to target for the resource. **Modifying this attribute will force creation of a new resource.** +- `allowed_match_count` (Number) Related DLP policies will trigger when the match count exceeds the number set. - `entry` (Block Set, Min: 1) List of entries to apply to the profile. (see [below for nested schema](#nestedblock--entry)) - `name` (String) Name of the profile. **Modifying this attribute will force creation of a new resource.** - `type` (String) The type of the profile. Available values: `custom`, `predefined`. **Modifying this attribute will force creation of a new resource.** diff --git a/examples/resources/cloudflare_dlp_profile/resource.tf b/examples/resources/cloudflare_dlp_profile/resource.tf index a7c3499d81..c5170c2170 100644 --- a/examples/resources/cloudflare_dlp_profile/resource.tf +++ b/examples/resources/cloudflare_dlp_profile/resource.tf @@ -1,8 +1,9 @@ # Predefined profile resource "cloudflare_dlp_profile" "example_predefined" { - account_id = "0da42c8d2132a9ddaf714f9e7c920711" - name = "Example Predefined Profile" - type = "predefined" + account_id = "0da42c8d2132a9ddaf714f9e7c920711" + name = "Example Predefined Profile" + type = "predefined" + allowed_match_count = 0 entry { name = "Mastercard Card Number" @@ -17,10 +18,11 @@ resource "cloudflare_dlp_profile" "example_predefined" { # Custom profile resource "cloudflare_dlp_profile" "example_custom" { - account_id = "0da42c8d2132a9ddaf714f9e7c920711" - name = "Example Custom Profile" - description = "A profile with example entries" - type = "custom" + account_id = "0da42c8d2132a9ddaf714f9e7c920711" + name = "Example Custom Profile" + description = "A profile with example entries" + type = "custom" + allowed_match_count = 0 entry { name = "Matches visa credit cards" diff --git a/internal/sdkv2provider/resource_cloudflare_dlp_profile.go b/internal/sdkv2provider/resource_cloudflare_dlp_profile.go index 9e638797b4..876560d934 100644 --- a/internal/sdkv2provider/resource_cloudflare_dlp_profile.go +++ b/internal/sdkv2provider/resource_cloudflare_dlp_profile.go @@ -106,6 +106,7 @@ func resourceCloudflareDLPProfileRead(ctx context.Context, d *schema.ResourceDat if dlpProfile.Description != "" { d.Set("description", dlpProfile.Description) } + d.Set("allowed_match_count", dlpProfile.AllowedMatchCount) entries := make([]interface{}, 0, len(dlpProfile.Entries)) for _, entry := range dlpProfile.Entries { entries = append(entries, dlpEntryToSchema(entry)) @@ -122,9 +123,10 @@ func resourceCloudflareDLPProfileCreate(ctx context.Context, d *schema.ResourceD identifier := cloudflare.AccountIdentifier(d.Get(consts.AccountIDSchemaKey).(string)) newDLPProfile := cloudflare.DLPProfile{ - Name: d.Get("name").(string), - Type: d.Get("type").(string), - Description: d.Get("description").(string), + Name: d.Get("name").(string), + Type: d.Get("type").(string), + Description: d.Get("description").(string), + AllowedMatchCount: d.Get("allowed_match_count").(int), } if newDLPProfile.Type == DLPProfileTypePredefined { @@ -156,9 +158,10 @@ func resourceCloudflareDLPProfileUpdate(ctx context.Context, d *schema.ResourceD client := meta.(*cloudflare.API) updatedDLPProfile := cloudflare.DLPProfile{ - ID: d.Id(), - Name: d.Get("name").(string), - Type: d.Get("type").(string), + ID: d.Id(), + Name: d.Get("name").(string), + Type: d.Get("type").(string), + AllowedMatchCount: d.Get("allowed_match_count").(int), } updatedDLPProfile.Description, _ = d.Get("description").(string) if entries, ok := d.GetOk("entry"); ok { diff --git a/internal/sdkv2provider/resource_cloudflare_dlp_profile_test.go b/internal/sdkv2provider/resource_cloudflare_dlp_profile_test.go index cd3454e65a..e02335332e 100644 --- a/internal/sdkv2provider/resource_cloudflare_dlp_profile_test.go +++ b/internal/sdkv2provider/resource_cloudflare_dlp_profile_test.go @@ -24,6 +24,7 @@ func TestAccCloudflareDLPProfile_Custom(t *testing.T) { resource.TestCheckResourceAttr(name, "name", rnd), resource.TestCheckResourceAttr(name, "description", "custom profile"), resource.TestCheckResourceAttr(name, "type", "custom"), + resource.TestCheckResourceAttr(name, "allowed_match_count", "0"), resource.TestCheckResourceAttr(name, "entry.0.name", fmt.Sprintf("%s_entry1", rnd)), resource.TestCheckResourceAttr(name, "entry.0.enabled", "true"), resource.TestCheckResourceAttr(name, "entry.0.pattern.0.regex", "^4[0-9]"), @@ -49,6 +50,7 @@ func TestAccCloudflareDLPProfile_Custom_MultipleEntries(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(name, "account_id", accountID), resource.TestCheckResourceAttr(name, "name", rnd), + resource.TestCheckResourceAttr(name, "allowed_match_count", "0"), resource.TestCheckResourceAttr(name, "description", "custom profile 2"), resource.TestCheckResourceAttr(name, "type", "custom"), @@ -71,6 +73,34 @@ func TestAccCloudflareDLPProfile_Custom_MultipleEntries(t *testing.T) { }) } +func TestAccCloudflareDLPProfile_CustomWithAllowedMatchCount(t *testing.T) { + rnd := generateRandomResourceName() + name := fmt.Sprintf("cloudflare_dlp_profile.%s", rnd) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheckAccount(t) + }, + ProviderFactories: providerFactories, + Steps: []resource.TestStep{ + { + Config: testAccCloudflareDLPProfileConfigCustomWithAllowedMatchCount(accountID, rnd, "custom profile", 42), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(name, "account_id", accountID), + resource.TestCheckResourceAttr(name, "name", rnd), + resource.TestCheckResourceAttr(name, "description", "custom profile"), + resource.TestCheckResourceAttr(name, "allowed_match_count", "42"), + resource.TestCheckResourceAttr(name, "type", "custom"), + resource.TestCheckResourceAttr(name, "entry.0.name", fmt.Sprintf("%s_entry1", rnd)), + resource.TestCheckResourceAttr(name, "entry.0.enabled", "true"), + resource.TestCheckResourceAttr(name, "entry.0.pattern.0.regex", "^4[0-9]"), + resource.TestCheckResourceAttr(name, "entry.0.pattern.0.validation", "luhn"), + ), + }, + }, + }) +} + func testAccCloudflareDLPProfileConfigCustom(accountID, rnd, description string) string { return fmt.Sprintf(` resource "cloudflare_dlp_profile" "%[1]s" { @@ -78,6 +108,7 @@ resource "cloudflare_dlp_profile" "%[1]s" { name = "%[1]s" description = "%[2]s" type = "custom" + allowed_match_count = 0 entry { name = "%[1]s_entry1" enabled = true @@ -93,9 +124,10 @@ resource "cloudflare_dlp_profile" "%[1]s" { func testAccCloudflareDLPProfileConfigCustomMultipleEntries(accountID, rnd, description string) string { return fmt.Sprintf(` resource "cloudflare_dlp_profile" "%[1]s" { - account_id = "%[3]s" + account_id = "%[3]s" name = "%[1]s" description = "%[2]s" + allowed_match_count = 0 type = "custom" entry { name = "%[1]s_entry1" @@ -117,3 +149,23 @@ resource "cloudflare_dlp_profile" "%[1]s" { } `, rnd, description, accountID) } + +func testAccCloudflareDLPProfileConfigCustomWithAllowedMatchCount(accountID, rnd, description string, allowedMatchCount uint) string { + return fmt.Sprintf(` +resource "cloudflare_dlp_profile" "%[1]s" { + account_id = "%[3]s" + name = "%[1]s" + description = "%[2]s" + allowed_match_count = %[4]d + type = "custom" + entry { + name = "%[1]s_entry1" + enabled = true + pattern { + regex = "^4[0-9]" + validation = "luhn" + } + } +} +`, rnd, description, accountID, allowedMatchCount) +} diff --git a/internal/sdkv2provider/schema_cloudflare_dlp_profile.go b/internal/sdkv2provider/schema_cloudflare_dlp_profile.go index ae9e121768..91a732ae13 100644 --- a/internal/sdkv2provider/schema_cloudflare_dlp_profile.go +++ b/internal/sdkv2provider/schema_cloudflare_dlp_profile.go @@ -92,5 +92,11 @@ func resourceCloudflareDLPProfileSchema() map[string]*schema.Schema { Schema: resourceCloudflareDLPEntrySchema(), }, }, + "allowed_match_count": { + Type: schema.TypeInt, + Description: "Related DLP policies will trigger when the match count exceeds the number set.", + Required: true, + ValidateFunc: validation.IntBetween(0, 1000), + }, } }