From 8aa6ea667b3781751030a662948cb08d39c1c647 Mon Sep 17 00:00:00 2001 From: Jakub Michalak Date: Wed, 20 Nov 2024 15:38:23 +0100 Subject: [PATCH] Cleanup --- docs/resources/tag_association.md | 2 + pkg/resources/helpers.go | 24 ++---- pkg/resources/helpers_test.go | 77 +++++++++++++++++ pkg/resources/tag_association.go | 2 +- pkg/sdk/testint/tags_integration_test.go | 92 +++++++-------------- templates/resources/tag_association.md.tmpl | 2 + 6 files changed, 119 insertions(+), 80 deletions(-) diff --git a/docs/resources/tag_association.md b/docs/resources/tag_association.md index 5c39787bb5..13a41d5606 100644 --- a/docs/resources/tag_association.md +++ b/docs/resources/tag_association.md @@ -7,6 +7,8 @@ description: |- !> **V1 release candidate** This resource was reworked and is a release candidate for the V1. We do not expect significant changes in it before the V1. We will welcome any feedback and adjust the resource if needed. Any errors reported will be resolved with a higher priority. We encourage checking this resource out before the V1 release. Please follow the [migration guide](https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/main/MIGRATION_GUIDE.md#v0980--v0990) to use it. +-> **Note** For `ACCOUNT` object type, only identifiers with organization name are supported. See [account identifier docs](https://docs.snowflake.com/en/user-guide/admin-account-identifier#format-1-preferred-account-name-in-your-organization) for more details. + # snowflake_tag_association (Resource) Resource used to manage tag associations. For more information, check [object tagging documentation](https://docs.snowflake.com/en/user-guide/object-tagging). diff --git a/pkg/resources/helpers.go b/pkg/resources/helpers.go index 8534b5b831..8fe036e1c8 100644 --- a/pkg/resources/helpers.go +++ b/pkg/resources/helpers.go @@ -310,30 +310,16 @@ func JoinDiags(diagnostics ...diag.Diagnostics) diag.Diagnostics { return result } -// ListDiff Compares two lists (before and after), then compares and returns two lists that include +// ListDiff compares two lists (before and after), then compares and returns two lists that include // added and removed items between those lists. func ListDiff[T comparable](beforeList []T, afterList []T) (added []T, removed []T) { - added = make([]T, 0) - removed = make([]T, 0) - - for _, beforeItem := range beforeList { - if !slices.Contains(afterList, beforeItem) { - removed = append(removed, beforeItem) - } - } - - for _, afterItem := range afterList { - if !slices.Contains(beforeList, afterItem) { - added = append(added, afterItem) - } - } - - return added, removed + added, removed, _ = ListDiffWithCommonItems(beforeList, afterList) + return } -// ListDiffWithCommon Compares two lists (before and after), then compares and returns three lists that include +// ListDiffWithCommonItems compares two lists (before and after), then compares and returns three lists that include // added, removed and common items between those lists. -func ListDiffWithCommon[T comparable](beforeList []T, afterList []T) (added []T, removed []T, common []T) { +func ListDiffWithCommonItems[T comparable](beforeList []T, afterList []T) (added []T, removed []T, common []T) { added = make([]T, 0) removed = make([]T, 0) common = make([]T, 0) diff --git a/pkg/resources/helpers_test.go b/pkg/resources/helpers_test.go index c143d40f03..c60807c9ac 100644 --- a/pkg/resources/helpers_test.go +++ b/pkg/resources/helpers_test.go @@ -260,6 +260,83 @@ func TestListDiff(t *testing.T) { } } +func TestListDiffWithCommonItems(t *testing.T) { + testCases := []struct { + Name string + Before []any + After []any + Added []any + Removed []any + Common []any + }{ + { + Name: "no changes", + Before: []any{1, 2, 3, 4}, + After: []any{1, 2, 3, 4}, + Removed: []any{}, + Added: []any{}, + Common: []any{1, 2, 3, 4}, + }, + { + Name: "only removed", + Before: []any{1, 2, 3, 4}, + After: []any{}, + Removed: []any{1, 2, 3, 4}, + Added: []any{}, + Common: []any{}, + }, + { + Name: "only added", + Before: []any{}, + After: []any{1, 2, 3, 4}, + Removed: []any{}, + Added: []any{1, 2, 3, 4}, + Common: []any{}, + }, + { + Name: "added repeated items", + Before: []any{2}, + After: []any{1, 2, 1}, + Removed: []any{}, + Added: []any{1, 1}, + Common: []any{2}, + }, + { + Name: "removed repeated items", + Before: []any{1, 2, 1}, + After: []any{2}, + Removed: []any{1, 1}, + Added: []any{}, + Common: []any{2}, + }, + { + Name: "simple diff: ints", + Before: []any{1, 2, 3, 4, 5, 6, 7, 8, 9}, + After: []any{1, 3, 5, 7, 9, 12, 13, 14}, + Removed: []any{2, 4, 6, 8}, + Added: []any{12, 13, 14}, + Common: []any{1, 3, 5, 7, 9}, + }, + { + Name: "simple diff: strings", + Before: []any{"one", "two", "three", "four"}, + After: []any{"five", "two", "four", "six"}, + Removed: []any{"one", "three"}, + Added: []any{"five", "six"}, + Common: []any{"two", "four"}, + }, + } + + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + added, removed, common := resources.ListDiffWithCommonItems(tc.Before, tc.After) + assert.Equal(t, tc.Added, added) + assert.Equal(t, tc.Removed, removed) + assert.Equal(t, tc.Common, common) + }) + } +} + func Test_DataTypeIssue3007DiffSuppressFunc(t *testing.T) { testCases := []struct { name string diff --git a/pkg/resources/tag_association.go b/pkg/resources/tag_association.go index 20e160ebd2..95afa70982 100644 --- a/pkg/resources/tag_association.go +++ b/pkg/resources/tag_association.go @@ -216,7 +216,7 @@ func UpdateContextTagAssociation(ctx context.Context, d *schema.ResourceData, me return diag.FromErr(err) } - _, _, commonIds := ListDiffWithCommon(oldIds, newIds) + _, _, commonIds := ListDiffWithCommonItems(oldIds, newIds) for _, id := range commonIds { request := sdk.NewSetTagRequest(objectType, id).WithSetTags([]sdk.TagAssociation{ diff --git a/pkg/sdk/testint/tags_integration_test.go b/pkg/sdk/testint/tags_integration_test.go index 73c9c0a731..e87b79ccb1 100644 --- a/pkg/sdk/testint/tags_integration_test.go +++ b/pkg/sdk/testint/tags_integration_test.go @@ -320,20 +320,28 @@ func TestInt_TagsAssociations(t *testing.T) { tag.ID(), } - testTagSet := func(id sdk.ObjectIdentifier, objectType sdk.ObjectType) { - err := client.Tags.Set(ctx, sdk.NewSetTagRequest(objectType, id).WithSetTags(tags)) + assertTagSet := func(id sdk.ObjectIdentifier, objectType sdk.ObjectType) { + returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, objectType) require.NoError(t, err) + assert.Equal(t, sdk.Pointer(tagValue), returnedTagValue) + } + assertTagUnset := func(id sdk.ObjectIdentifier, objectType sdk.ObjectType) { returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, objectType) require.NoError(t, err) - assert.Equal(t, sdk.Pointer(tagValue), returnedTagValue) + assert.Nil(t, returnedTagValue) + } - err = client.Tags.Unset(ctx, sdk.NewUnsetTagRequest(objectType, id).WithUnsetTags(unsetTags)) + testTagSet := func(id sdk.ObjectIdentifier, objectType sdk.ObjectType) { + err := client.Tags.Set(ctx, sdk.NewSetTagRequest(objectType, id).WithSetTags(tags)) require.NoError(t, err) - returnedTagValue, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, objectType) + assertTagSet(id, objectType) + + err = client.Tags.Unset(ctx, sdk.NewUnsetTagRequest(objectType, id).WithUnsetTags(unsetTags)) require.NoError(t, err) - assert.Nil(t, returnedTagValue) + + assertTagUnset(id, objectType) } t.Run("TestInt_TagAssociationForAccount_locator", func(t *testing.T) { @@ -343,33 +351,25 @@ func TestInt_TagsAssociations(t *testing.T) { }) require.NoError(t, err) - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeAccount) - require.NoError(t, err) - assert.Equal(t, tagValue, returnedTagValue) + assertTagSet(id, sdk.ObjectTypeAccount) err = client.Accounts.Alter(ctx, &sdk.AlterAccountOptions{ UnsetTag: unsetTags, }) require.NoError(t, err) - returnedTagValue, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeAccount) - require.NoError(t, err) - assert.Nil(t, returnedTagValue) + assertTagUnset(id, sdk.ObjectTypeAccount) // test tag sdk method err = client.Tags.SetOnCurrentAccount(ctx, sdk.NewSetTagOnCurrentAccountRequest().WithSetTags(tags)) require.NoError(t, err) - returnedTagValue, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeAccount) - require.NoError(t, err) - assert.Equal(t, tagValue, returnedTagValue) + assertTagSet(id, sdk.ObjectTypeAccount) err = client.Tags.UnsetOnCurrentAccount(ctx, sdk.NewUnsetTagOnCurrentAccountRequest().WithUnsetTags(unsetTags)) require.NoError(t, err) - returnedTagValue, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeAccount) - require.NoError(t, err) - assert.Nil(t, returnedTagValue) + assertTagUnset(id, sdk.ObjectTypeAccount) }) t.Run("TestInt_TagAssociationForAccount", func(t *testing.T) { @@ -381,16 +381,12 @@ func TestInt_TagsAssociations(t *testing.T) { err := client.Tags.Set(ctx, sdk.NewSetTagRequest(sdk.ObjectTypeAccount, id).WithSetTags(tags)) require.NoError(t, err) - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeAccount) - require.NoError(t, err) - assert.Equal(t, sdk.Pointer(tagValue), returnedTagValue) + assertTagSet(id, sdk.ObjectTypeAccount) err = client.Tags.UnsetOnCurrentAccount(ctx, sdk.NewUnsetTagOnCurrentAccountRequest().WithUnsetTags(unsetTags)) require.NoError(t, err) - returnedTagValue, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeAccount) - require.NoError(t, err) - assert.Nil(t, returnedTagValue) + assertTagUnset(id, sdk.ObjectTypeAccount) }) accountObjectTestCases := []struct { @@ -653,16 +649,12 @@ func TestInt_TagsAssociations(t *testing.T) { err := tc.setTags(id, tags) require.NoError(t, err) - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) - require.NoError(t, err) - assert.Equal(t, tagValue, returnedTagValue) + assertTagSet(id, tc.objectType) err = tc.unsetTags(id, unsetTags) require.NoError(t, err) - returnedTagValue, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) - require.NoError(t, err) - assert.Nil(t, returnedTagValue) + assertTagUnset(id, tc.objectType) // test object methods testTagSet(id, tc.objectType) @@ -745,16 +737,12 @@ func TestInt_TagsAssociations(t *testing.T) { err := tc.setTags(id, tags) require.NoError(t, err) - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) - require.NoError(t, err) - assert.Equal(t, tagValue, returnedTagValue) + assertTagSet(id, tc.objectType) err = tc.unsetTags(id, unsetTags) require.NoError(t, err) - returnedTagValue, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) - require.NoError(t, err) - assert.Nil(t, returnedTagValue) + assertTagUnset(id, tc.objectType) // test object methods testTagSet(id, tc.objectType) @@ -933,16 +921,12 @@ func TestInt_TagsAssociations(t *testing.T) { err := tc.setTags(id, tags) require.NoError(t, err) - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) - require.NoError(t, err) - assert.Equal(t, tagValue, returnedTagValue) + assertTagSet(id, tc.objectType) err = tc.unsetTags(id, unsetTags) require.NoError(t, err) - returnedTagValue, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) - require.NoError(t, err) - assert.Nil(t, returnedTagValue) + assertTagUnset(id, tc.objectType) // test object methods testTagSet(id, tc.objectType) @@ -958,9 +942,7 @@ func TestInt_TagsAssociations(t *testing.T) { }) require.NoError(t, err) - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeMaskingPolicy) - require.NoError(t, err) - assert.Equal(t, sdk.Pointer(tagValue), returnedTagValue) + assertTagSet(id, sdk.ObjectTypeMaskingPolicy) // assert that setting masking policy does not apply the tag on the masking policy refs, err := testClientHelper().PolicyReferences.GetPolicyReferences(t, tag.ID(), sdk.PolicyEntityDomainTag) @@ -972,9 +954,7 @@ func TestInt_TagsAssociations(t *testing.T) { }) require.NoError(t, err) - returnedTagValue, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeMaskingPolicy) - require.NoError(t, err) - assert.Nil(t, returnedTagValue) + assertTagUnset(id, sdk.ObjectTypeMaskingPolicy) // test object methods testTagSet(id, sdk.ObjectTypeMaskingPolicy) @@ -1030,16 +1010,12 @@ func TestInt_TagsAssociations(t *testing.T) { err := tc.setTags(id, tags) require.NoError(t, err) - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeColumn) - require.NoError(t, err) - assert.Equal(t, tagValue, returnedTagValue) + assertTagSet(id, sdk.ObjectTypeColumn) err = tc.unsetTags(id, unsetTags) require.NoError(t, err) - returnedTagValue, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeColumn) - require.NoError(t, err) - assert.Nil(t, returnedTagValue) + assertTagUnset(id, sdk.ObjectTypeColumn) // test object methods testTagSet(id, sdk.ObjectTypeColumn) @@ -1108,16 +1084,12 @@ func TestInt_TagsAssociations(t *testing.T) { err := tc.setTags(id, tags) require.NoError(t, err) - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) - require.NoError(t, err) - assert.Equal(t, tagValue, returnedTagValue) + assertTagSet(id, tc.objectType) err = tc.unsetTags(id, unsetTags) require.NoError(t, err) - returnedTagValue, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) - require.NoError(t, err) - assert.Nil(t, returnedTagValue) + assertTagUnset(id, tc.objectType) // test object methods testTagSet(id, tc.objectType) diff --git a/templates/resources/tag_association.md.tmpl b/templates/resources/tag_association.md.tmpl index 6f9efa5370..f27f992ecc 100644 --- a/templates/resources/tag_association.md.tmpl +++ b/templates/resources/tag_association.md.tmpl @@ -11,6 +11,8 @@ description: |- !> **V1 release candidate** This resource was reworked and is a release candidate for the V1. We do not expect significant changes in it before the V1. We will welcome any feedback and adjust the resource if needed. Any errors reported will be resolved with a higher priority. We encourage checking this resource out before the V1 release. Please follow the [migration guide](https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/main/MIGRATION_GUIDE.md#v0980--v0990) to use it. +-> **Note** For `ACCOUNT` object type, only identifiers with organization name are supported. See [account identifier docs](https://docs.snowflake.com/en/user-guide/admin-account-identifier#format-1-preferred-account-name-in-your-organization) for more details. + # {{.Name}} ({{.Type}}) {{ .Description | trimspace }}