Skip to content

Commit

Permalink
Fix ZT lists update
Browse files Browse the repository at this point in the history
When updating the `cloudflare_zero_trust_list` only changes to the `items`
field was being considered to determine the list elements to store.
However, customers can also use the `items_with_description` field to
declare list elements with a description, so it also needs to be
considered. This commit fixes the issue, adding an acceptance test to
prove its effectiveness.
  • Loading branch information
sebassimoes committed Oct 30, 2024
1 parent d0fa327 commit bef5629
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 12 deletions.
3 changes: 3 additions & 0 deletions .changelog/4477.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/cloudflare_zero_trust_list: Consider `items_with_description` when updating a ZT list
```
63 changes: 52 additions & 11 deletions internal/sdkv2provider/resource_cloudflare_teams_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,52 @@ func resourceCloudflareTeamsListUpdate(ctx context.Context, d *schema.ResourceDa
return diag.FromErr(fmt.Errorf("failed to find Teams List ID in update response; resource was empty"))
}

if d.HasChange("items") {
if d.HasChange("items") || d.HasChange("items_with_description") {

Check failure on line 153 in internal/sdkv2provider/resource_cloudflare_teams_list.go

View workflow job for this annotation

GitHub Actions / tfproviderlint (ubuntu-latest)

R005: multiple ResourceData.HasChange() calls can be combined with single HasChanges() call
oldItemsIface, newItemsIface := d.GetChange("items")
oldItemsWithDescriptionIface, newItemsWithDescriptionIface := d.GetChange("items_with_description")

oldItems := oldItemsIface.(*schema.Set).List()
newItems := newItemsIface.(*schema.Set).List()
oldItemsWithDescription := oldItemsWithDescriptionIface.(*schema.Set).List()
newItemsWithDescription := newItemsWithDescriptionIface.(*schema.Set).List()

convertedOldItems := []cloudflare.TeamsListItem{}
convertedNewItems := []cloudflare.TeamsListItem{}

for _, v := range oldItems {
item, err := convertItemCFTeamsListItems(v)
if err != nil {
return diag.FromErr(fmt.Errorf("error creating Teams List for account %q: %w", accountID, err))
}
convertedOldItems = append(convertedOldItems, *item)
}

for _, v := range oldItemsWithDescription {
item, err := convertItemCFTeamsListItems(v)
if err != nil {
return diag.FromErr(fmt.Errorf("error creating Teams List for account %q: %w", accountID, err))
}
convertedOldItems = append(convertedOldItems, *item)
}

for _, v := range newItems {
item, err := convertItemCFTeamsListItems(v)
if err != nil {
return diag.FromErr(fmt.Errorf("error creating Teams List for account %q: %w", accountID, err))
}
convertedNewItems = append(convertedNewItems, *item)
}

for _, v := range newItemsWithDescription {
item, err := convertItemCFTeamsListItems(v)
if err != nil {
return diag.FromErr(fmt.Errorf("error creating Teams List for account %q: %w", accountID, err))
}
convertedNewItems = append(convertedNewItems, *item)
}

patchTeamsList := cloudflare.PatchTeamsListParams{ID: d.Id()}
setListItemDiff(&patchTeamsList, oldItems, newItems)
setListItemDiff(&patchTeamsList, convertedOldItems, convertedNewItems)

l, err := client.PatchTeamsList(ctx, identifier, patchTeamsList)

Expand Down Expand Up @@ -206,21 +246,22 @@ func resourceCloudflareTeamsListImport(ctx context.Context, d *schema.ResourceDa
return []*schema.ResourceData{d}, nil
}

func setListItemDiff(patchList *cloudflare.PatchTeamsListParams, oldItems, newItems []interface{}) {
counts := make(map[string]int)
for _, val := range newItems {
counts[val.(string)] += 1
func setListItemDiff(patchList *cloudflare.PatchTeamsListParams, oldItems, newItems []cloudflare.TeamsListItem) {
counts := make(map[cloudflare.TeamsListItem]int)

for _, item := range newItems {
counts[item] += 1
}
for _, val := range oldItems {
counts[val.(string)] -= 1
for _, item := range oldItems {
counts[item] -= 1
}

for key, val := range counts {
for item, val := range counts {
if val > 0 {
patchList.Append = append(patchList.Append, cloudflare.TeamsListItem{Value: key})
patchList.Append = append(patchList.Append, item)
}
if val < 0 {
patchList.Remove = append(patchList.Remove, key)
patchList.Remove = append(patchList.Remove, item.Value)
}
}
}
Expand Down
29 changes: 28 additions & 1 deletion internal/sdkv2provider/resource_cloudflare_teams_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,20 @@ func TestAccCloudflareTeamsList_BasicWithDescription(t *testing.T) {
resource.TestCheckResourceAttr(name, "items_with_description.1.description", "test-2"),
),
},
{
Config: testAccCloudflareTeamsListUpdatedConfigBasicWithDescription(rnd, accountID),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(name, consts.AccountIDSchemaKey, accountID),
resource.TestCheckResourceAttr(name, "name", rnd),
resource.TestCheckResourceAttr(name, "type", "DOMAIN"),
resource.TestCheckResourceAttr(name, "description", "My description"),
resource.TestCheckResourceAttr(name, "items.#", "1"),
resource.TestCheckResourceAttr(name, "items_with_description.#", "1"),
resource.TestCheckResourceAttr(name, "items.0", "fedcba.com"),
resource.TestCheckResourceAttr(name, "items_with_description.0.value", "abcd.com"),
resource.TestCheckResourceAttr(name, "items_with_description.0.description", "updated test"),
),
},
},
})
}
Expand Down Expand Up @@ -162,12 +176,25 @@ resource "cloudflare_zero_trust_list" "%[1]s" {
name = "%[1]s"
description = "My description"
type = "DOMAIN"
items = [ "abcdef.com"]
items = ["abcdef.com"]
items_with_description = [{"value" : "abcd.com", "description": "test"}, {"value" : "abcdefghijk.com", "description": "test-2"}]
}
`, rnd, accountID)
}

func testAccCloudflareTeamsListUpdatedConfigBasicWithDescription(rnd, accountID string) string {
return fmt.Sprintf(`
resource "cloudflare_zero_trust_list" "%[1]s" {
account_id = "%[2]s"
name = "%[1]s"
description = "My description"
type = "DOMAIN"
items = ["fedcba.com"]
items_with_description = [{"value" : "abcd.com", "description": "updated test"}]
}
`, rnd, accountID)
}

func testAccCloudflareTeamsListConfigBigItemCount(rnd, accountID string) string {
items := []string{}
for i := 0; i < 1000; i++ {
Expand Down

0 comments on commit bef5629

Please sign in to comment.