diff --git a/CHANGELOG.md b/CHANGELOG.md index 210373c9f..dad62bb9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,20 @@ +## 10.7.3 (May 1, 2024) + +BUG FIXES: + +* resource/artifactory_managed_user, resource/artifactory_unmanaged_user, resource/artifactory_user: Make `name` attribute trigger resource replacement if changed. Issue: [#944](https://github.com/jfrog/terraform-provider-artifactory/issues/944) PR: [#946](https://github.com/jfrog/terraform-provider-artifactory/pull/946) + ## 10.7.2 (Apr 26, 2024) BUG FIXES: -resource/artifactory_proxy: Fix hidden state drifts with resource created using SDKv2 (i.e. <= 10.1.0). Issue: [#941](https://github.com/jfrog/terraform-provider-artifactory/issues/941) PR: [#943](https://github.com/jfrog/terraform-provider-artifactory/pull/943) +* resource/artifactory_proxy: Fix hidden state drifts with resource created using SDKv2 (i.e. <= 10.1.0). Issue: [#941](https://github.com/jfrog/terraform-provider-artifactory/issues/941) PR: [#943](https://github.com/jfrog/terraform-provider-artifactory/pull/943) ## 10.7.1 (Apr 25, 2024) BUG FIXES: -resource/artifactory_managed_user, resource/artifactory_unmanaged_user, resource/artifactory_user: Toggle between using (old) Artifactory Security API and (new) Access API based on Artifactory version 7.84.3 due to Access API bug in updating user without password field. Issue: [#931](https://github.com/jfrog/terraform-provider-artifactory/issues/931) PR: [#940](https://github.com/jfrog/terraform-provider-artifactory/pull/940) +* resource/artifactory_managed_user, resource/artifactory_unmanaged_user, resource/artifactory_user: Toggle between using (old) Artifactory Security API and (new) Access API based on Artifactory version 7.84.3 due to Access API bug in updating user without password field. Issue: [#931](https://github.com/jfrog/terraform-provider-artifactory/issues/931) PR: [#940](https://github.com/jfrog/terraform-provider-artifactory/pull/940) ## 10.7.0 (Apr 18, 2024) @@ -20,7 +26,7 @@ FEATURES: BUG FIXES: -resource/artifactory_unmanaged_user, resource/artifactory_user: Revert storing auto-generated `password` attribute value in Terraform state. Revert back to Artifactory Security API until Artifactory version 7.83.1 due to Access API bug in updating user without password field. Issue: [#931](https://github.com/jfrog/terraform-provider-artifactory/issues/931) PR: [#937](https://github.com/jfrog/terraform-provider-artifactory/pull/937) +* resource/artifactory_unmanaged_user, resource/artifactory_user: Revert storing auto-generated `password` attribute value in Terraform state. Revert back to Artifactory Security API until Artifactory version 7.83.1 due to Access API bug in updating user without password field. Issue: [#931](https://github.com/jfrog/terraform-provider-artifactory/issues/931) PR: [#937](https://github.com/jfrog/terraform-provider-artifactory/pull/937) IMPROVEMENTS: diff --git a/go.mod b/go.mod index 111cbb553..1d2b7ca67 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,6 @@ require ( github.com/google/go-querystring v1.1.0 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/go-version v1.6.0 - github.com/hashicorp/terraform-json v0.18.0 github.com/hashicorp/terraform-plugin-docs v0.16.0 github.com/hashicorp/terraform-plugin-framework v1.5.0 github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 @@ -17,7 +16,7 @@ require ( github.com/hashicorp/terraform-plugin-mux v0.12.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0 github.com/hashicorp/terraform-plugin-testing v1.5.1 - github.com/jfrog/terraform-provider-shared v1.24.0 + github.com/jfrog/terraform-provider-shared v1.25.0 github.com/samber/lo v1.39.0 github.com/sethvargo/go-password v0.2.0 github.com/stretchr/testify v1.8.4 @@ -27,6 +26,8 @@ require ( gopkg.in/yaml.v3 v3.0.1 ) +require github.com/hashicorp/terraform-json v0.18.0 // indirect + require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.1.1 // indirect diff --git a/go.sum b/go.sum index 84b999ae3..25f69bc26 100644 --- a/go.sum +++ b/go.sum @@ -135,8 +135,8 @@ github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jfrog/terraform-provider-shared v1.24.0 h1:VItpElBn9Jku8gtN7DhOURUIyoUYYw8R9erPBPgKwv8= -github.com/jfrog/terraform-provider-shared v1.24.0/go.mod h1:OozwvfahZU4Q9u3kXdpQI3h/Etrs2DXoouQDrpxB1cQ= +github.com/jfrog/terraform-provider-shared v1.25.0 h1:FyubiyixS7QnUXb1JKKo957tCFZO2xVKSPLyKzBnvKk= +github.com/jfrog/terraform-provider-shared v1.25.0/go.mod h1:L987Z8XO4cuv7ys4Tw6sP/LESw7z0Dji0U2ysR8FUP4= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= diff --git a/pkg/acctest/test.go b/pkg/acctest/test.go index 0a0b7501a..3813e1f9f 100644 --- a/pkg/acctest/test.go +++ b/pkg/acctest/test.go @@ -2,7 +2,6 @@ package acctest import ( "context" - "encoding/json" "fmt" "net/http" "os" @@ -12,16 +11,12 @@ import ( "github.com/go-resty/resty/v2" "github.com/hashicorp/go-version" - tfjson "github.com/hashicorp/terraform-json" "github.com/hashicorp/terraform-plugin-framework/providerserver" "github.com/hashicorp/terraform-plugin-go/tfprotov6" - "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/hashicorp/terraform-plugin-mux/tf5to6server" "github.com/hashicorp/terraform-plugin-mux/tf6muxserver" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" terraform2 "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - "github.com/hashicorp/terraform-plugin-testing/helper/resource" - "github.com/hashicorp/terraform-plugin-testing/plancheck" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/jfrog/terraform-provider-artifactory/v10/pkg/artifactory/provider" "github.com/jfrog/terraform-provider-artifactory/v10/pkg/artifactory/resource/configuration" @@ -30,7 +25,6 @@ import ( "github.com/jfrog/terraform-provider-shared/client" "github.com/jfrog/terraform-provider-shared/testutil" "github.com/jfrog/terraform-provider-shared/util" - "github.com/samber/lo" "gopkg.in/yaml.v3" ) @@ -381,80 +375,3 @@ func CompareArtifactoryVersions(t *testing.T, instanceVersions string) (bool, er } return skipTest, nil } - -var ConfigPlanChecks = resource.ConfigPlanChecks{ - PostApplyPreRefresh: []plancheck.PlanCheck{ - DebugPlan("PostApplyPreRefresh"), - }, - PostApplyPostRefresh: []plancheck.PlanCheck{ - DebugPlan("PostApplyPostRefresh"), - }, -} - -var _ plancheck.PlanCheck = PlanCheck{} - -type PlanCheck struct { - Stage string -} - -func (p PlanCheck) CheckPlan(ctx context.Context, req plancheck.CheckPlanRequest, resp *plancheck.CheckPlanResponse) { - var err error - - rc, err := json.Marshal(req.Plan.ResourceChanges[0]) - if err != nil { - resp.Error = err - return - } - - pv, err := json.Marshal(req.Plan.PlannedValues) - if err != nil { - resp.Error = err - return - } - - ps, err := json.Marshal(req.Plan.PriorState) - if err != nil { - resp.Error = err - return - } - - rd, err := json.Marshal(req.Plan.ResourceDrift) - if err != nil { - resp.Error = err - return - } - - tflog.Debug(ctx, "CheckPlan", map[string]interface{}{ - "stage": p.Stage, - "req.Plan.ResourceChanges.ResourceDrift": string(rd), - "req.Plan.ResourceChanges": string(rc), - "req.Plan.PlannedValues": string(pv), - "req.Plan.PriorState": string(ps), - }) - - if len(req.Plan.ResourceDrift) > 0 { - drifts := lo.Map(req.Plan.ResourceDrift, func(c *tfjson.ResourceChange, index int) string { - return fmt.Sprintf("Name: %s, Before: %v, After: %v", c.Name, c.Change.Before, c.Change.After) - }) - resp.Error = fmt.Errorf("expected empty plan, but has resouce drifts(s): %v", strings.Join(drifts, ", ")) - return - } - - var errStrings []string - for _, rc := range req.Plan.ResourceChanges { - if !rc.Change.Actions.NoOp() { - errStrings = append(errStrings, fmt.Sprintf("expected empty plan, but %s has planned action(s): %v\n\nbefore: %v\n\nafter: %v\n\nunknown: %v", rc.Address, rc.Change.Actions, rc.Change.Before, rc.Change.After, rc.Change.AfterUnknown)) - } - } - - if len(errStrings) > 0 { - resp.Error = fmt.Errorf(strings.Join(errStrings, "\n")) - return - } -} - -func DebugPlan(stage string) plancheck.PlanCheck { - return PlanCheck{ - Stage: stage, - } -} diff --git a/pkg/artifactory/resource/configuration/resource_artifactory_ldap_group_setting_v2_test.go b/pkg/artifactory/resource/configuration/resource_artifactory_ldap_group_setting_v2_test.go index c912660df..4b4c470f3 100644 --- a/pkg/artifactory/resource/configuration/resource_artifactory_ldap_group_setting_v2_test.go +++ b/pkg/artifactory/resource/configuration/resource_artifactory_ldap_group_setting_v2_test.go @@ -69,7 +69,7 @@ func TestAccLdapGroupSettingV2_full(t *testing.T) { resource.TestCheckResourceAttr(fqrn, "description_attribute", "description"), resource.TestCheckResourceAttr(fqrn, "strategy", "STATIC"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { Config: LdapSettingTemplateFullUpdate, @@ -85,7 +85,7 @@ func TestAccLdapGroupSettingV2_full(t *testing.T) { resource.TestCheckResourceAttr(fqrn, "description_attribute", "description"), resource.TestCheckResourceAttr(fqrn, "strategy", "DYNAMIC"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ResourceName: fqrn, diff --git a/pkg/artifactory/resource/configuration/resource_artifactory_ldap_setting_v2_test.go b/pkg/artifactory/resource/configuration/resource_artifactory_ldap_setting_v2_test.go index ee3257dd7..fa4148152 100644 --- a/pkg/artifactory/resource/configuration/resource_artifactory_ldap_setting_v2_test.go +++ b/pkg/artifactory/resource/configuration/resource_artifactory_ldap_setting_v2_test.go @@ -48,7 +48,7 @@ func TestAccLdapSettingV2_full_no_search(t *testing.T) { resource.TestCheckResourceAttr(fqrn, "user_dn_pattern", params["user_dn_pattern"].(string)), resource.TestCheckResourceAttr(fqrn, "email_attribute", "mail_attr"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ResourceName: fqrn, @@ -102,7 +102,7 @@ func TestAccLdapSettingV2_full_with_search(t *testing.T) { resource.TestCheckResourceAttr(fqrn, "search_filter", "(uid={0})"), resource.TestCheckResourceAttr(fqrn, "search_base", params["search_base"].(string)), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ResourceName: fqrn, diff --git a/pkg/artifactory/resource/configuration/resource_artifactory_property_set_test.go b/pkg/artifactory/resource/configuration/resource_artifactory_property_set_test.go index ffb5eeaa8..0738f769c 100644 --- a/pkg/artifactory/resource/configuration/resource_artifactory_property_set_test.go +++ b/pkg/artifactory/resource/configuration/resource_artifactory_property_set_test.go @@ -43,13 +43,13 @@ func TestAccPropertySet_UpgradeFromSDKv2(t *testing.T) { }, Config: config, Check: resource.ComposeTestCheckFunc(verifyPropertySet(fqrn, testData)), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, Config: config, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, }) diff --git a/pkg/artifactory/resource/configuration/resource_artifactory_proxy_test.go b/pkg/artifactory/resource/configuration/resource_artifactory_proxy_test.go index 304569ad4..d1bd59188 100644 --- a/pkg/artifactory/resource/configuration/resource_artifactory_proxy_test.go +++ b/pkg/artifactory/resource/configuration/resource_artifactory_proxy_test.go @@ -87,13 +87,13 @@ func TestAccProxy_UpgradeFromSDKv2(t *testing.T) { resource.TestCheckNoResourceAttr(fqrn, "redirect_to_hosts"), resource.TestCheckNoResourceAttr(fqrn, "services"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, Config: config, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, }) diff --git a/pkg/artifactory/resource/configuration/resource_artifactory_repository_layout_test.go b/pkg/artifactory/resource/configuration/resource_artifactory_repository_layout_test.go index e65d80b54..ddfec8faa 100644 --- a/pkg/artifactory/resource/configuration/resource_artifactory_repository_layout_test.go +++ b/pkg/artifactory/resource/configuration/resource_artifactory_repository_layout_test.go @@ -53,13 +53,13 @@ func TestAccRepositoryLayout_UpgradeFromSDKv2(t *testing.T) { resource.TestCheckResourceAttr(fqrn, "folder_integration_revision_regexp", "SNAPSHOT"), resource.TestCheckResourceAttr(fqrn, "file_integration_revision_regexp", "SNAPSHOT|(?:(?:[0-9]{8}.[0-9]{6})-(?:[0-9]+))"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, Config: config, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, }) diff --git a/pkg/artifactory/resource/repository/remote/resource_artifactory_remote_repository_test.go b/pkg/artifactory/resource/repository/remote/resource_artifactory_remote_repository_test.go index e6abf26fa..8e3bb408a 100644 --- a/pkg/artifactory/resource/repository/remote/resource_artifactory_remote_repository_test.go +++ b/pkg/artifactory/resource/repository/remote/resource_artifactory_remote_repository_test.go @@ -59,7 +59,7 @@ func TestAccRemoteUpgradeFromVersionWithNoDisableProxyAttr(t *testing.T) { ProtoV6ProviderFactories: acctest.ProtoV6MuxProviderFactories, Config: config, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, }) diff --git a/pkg/artifactory/resource/security/resource_artifactory_certificate_test.go b/pkg/artifactory/resource/security/resource_artifactory_certificate_test.go index 56bab986d..1f7684d67 100644 --- a/pkg/artifactory/resource/security/resource_artifactory_certificate_test.go +++ b/pkg/artifactory/resource/security/resource_artifactory_certificate_test.go @@ -77,13 +77,13 @@ func TestAccCertificate_UpgradeFromSDKv2(t *testing.T) { resource.TestCheckResourceAttr(fqrn, "issued_to", "Unknown"), resource.TestCheckResourceAttr(fqrn, "valid_until", "2029-05-14T10:03:26.000Z"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ProtoV6ProviderFactories: acctest.ProtoV6MuxProviderFactories, Config: config, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, }) diff --git a/pkg/artifactory/resource/security/resource_artifactory_distribution_public_key_test.go b/pkg/artifactory/resource/security/resource_artifactory_distribution_public_key_test.go index 20279814b..30fe911fc 100644 --- a/pkg/artifactory/resource/security/resource_artifactory_distribution_public_key_test.go +++ b/pkg/artifactory/resource/security/resource_artifactory_distribution_public_key_test.go @@ -75,13 +75,13 @@ func TestAccDistributionPublicKey_UpgradeFromSDKv2(t *testing.T) { resource.TestCheckResourceAttr(fqrn, "fingerprint", "10:16:2c:c5:1c:db:d0:59:ad:86:d3:66:dc:d1:d9:02:65:03:a8:25"), resource.TestCheckResourceAttr(fqrn, "issued_by", "alan "), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, Config: keyBasic, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, }) diff --git a/pkg/artifactory/resource/security/resource_artifactory_group_test.go b/pkg/artifactory/resource/security/resource_artifactory_group_test.go index 010fde5d9..e25bed5b4 100644 --- a/pkg/artifactory/resource/security/resource_artifactory_group_test.go +++ b/pkg/artifactory/resource/security/resource_artifactory_group_test.go @@ -49,13 +49,13 @@ func TestAccGroup_UpgradeFromSDKv2(t *testing.T) { resource.TestCheckNoResourceAttr(fqrn, "users_names"), resource.TestCheckResourceAttr(fqrn, "watch_manager", "false"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, Config: config, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, }) diff --git a/pkg/artifactory/resource/security/resource_artifactory_keypair_test.go b/pkg/artifactory/resource/security/resource_artifactory_keypair_test.go index 1a50218e8..6879a2b6b 100644 --- a/pkg/artifactory/resource/security/resource_artifactory_keypair_test.go +++ b/pkg/artifactory/resource/security/resource_artifactory_keypair_test.go @@ -93,13 +93,13 @@ EOF resource.TestCheckResourceAttr(fqrn, "passphrase", "password"), resource.TestCheckResourceAttr(fqrn, "unavailable", "false"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ProtoV6ProviderFactories: acctest.ProtoV6MuxProviderFactories, Config: keyPairConfig, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, }) diff --git a/pkg/artifactory/resource/security/resource_artifactory_permission_target_test.go b/pkg/artifactory/resource/security/resource_artifactory_permission_target_test.go index 526e1f4ac..4a2903459 100644 --- a/pkg/artifactory/resource/security/resource_artifactory_permission_target_test.go +++ b/pkg/artifactory/resource/security/resource_artifactory_permission_target_test.go @@ -221,13 +221,13 @@ func TestAccPermissionTarget_MigrateFromFrameworkBackToSDKv2(t *testing.T) { resource.TestCheckResourceAttr(fqrn, "build.#", "1"), resource.TestCheckResourceAttr(fqrn, "release_bundle.#", "1"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ProtoV6ProviderFactories: acctest.ProtoV6MuxProviderFactories, Config: config, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, }) diff --git a/pkg/artifactory/resource/security/resource_artifactory_scoped_token_test.go b/pkg/artifactory/resource/security/resource_artifactory_scoped_token_test.go index 6f8f2db16..2ecf96966 100644 --- a/pkg/artifactory/resource/security/resource_artifactory_scoped_token_test.go +++ b/pkg/artifactory/resource/security/resource_artifactory_scoped_token_test.go @@ -79,13 +79,13 @@ func TestAccScopedToken_UpgradeGH_792(t *testing.T) { resource.TestCheckResourceAttrSet(fqrn, "issued_at"), resource.TestCheckResourceAttrSet(fqrn, "issuer"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ProtoV6ProviderFactories: acctest.ProtoV6MuxProviderFactories, Config: config, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, }) @@ -137,13 +137,13 @@ func TestAccScopedToken_UpgradeGH_818(t *testing.T) { resource.TestCheckResourceAttrSet(fqrn, "issued_at"), resource.TestCheckResourceAttrSet(fqrn, "issuer"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ProtoV6ProviderFactories: acctest.ProtoV6MuxProviderFactories, Config: config, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, }) @@ -197,13 +197,13 @@ func scopedTokenUpgradeTestCase(version string, t *testing.T) (*testing.T, resou resource.TestCheckResourceAttrSet(fqrn, "issued_at"), resource.TestCheckResourceAttrSet(fqrn, "issuer"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, Config: config, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, } diff --git a/pkg/artifactory/resource/user/resource_artifactory_managed_user_test.go b/pkg/artifactory/resource/user/resource_artifactory_managed_user_test.go index cc384c9f7..53b75c61e 100644 --- a/pkg/artifactory/resource/user/resource_artifactory_managed_user_test.go +++ b/pkg/artifactory/resource/user/resource_artifactory_managed_user_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/plancheck" "github.com/jfrog/terraform-provider-artifactory/v10/pkg/acctest" "github.com/jfrog/terraform-provider-shared/testutil" "github.com/jfrog/terraform-provider-shared/util" @@ -47,13 +48,13 @@ func TestAccManagedUser_UpgradeFromSDKv2(t *testing.T) { resource.TestCheckResourceAttr(fqrn, "internal_password_disabled", "false"), resource.TestCheckNoResourceAttr(fqrn, "groups"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, Config: userNoGroups, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, }) @@ -253,3 +254,65 @@ func TestAccManagedUser_basic(t *testing.T) { }, }) } + +func TestAccManagedUser_name_change(t *testing.T) { + id, fqrn, name := testutil.MkNames("test-user-", "artifactory_managed_user") + _, _, groupName := testutil.MkNames("test-group-", "artifactory_group") + username := fmt.Sprintf("dummy_user%d", id) + email := fmt.Sprintf(username + "@test.com") + + params := map[string]string{ + "name": name, + "username": username, + "email": email, + "groupName": groupName, + } + + userFull := util.ExecuteTemplate("TestAccManagedUser", ` + resource "artifactory_managed_user" "{{ .name }}" { + name = "{{ .username }}" + email = "{{ .email }}" + password = "Passsw0rd!12" + admin = true + profile_updatable = true + disable_ui_access = false + } + `, params) + + usernameChangedConfig := util.ExecuteTemplate("TestAccManagedUser", ` + resource "artifactory_managed_user" "{{ .name }}" { + name = "foobar" + email = "{{ .email }}" + password = "Passsw0rd!12" + admin = false + profile_updatable = false + } + `, params) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, + CheckDestroy: testAccCheckManagedUserDestroy(fqrn), + Steps: []resource.TestStep{ + { + Config: userFull, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(fqrn, "name", params["username"]), + resource.TestCheckResourceAttr(fqrn, "email", params["email"]), + resource.TestCheckResourceAttr(fqrn, "admin", "true"), + resource.TestCheckResourceAttr(fqrn, "profile_updatable", "true"), + resource.TestCheckResourceAttr(fqrn, "disable_ui_access", "false"), + resource.TestCheckResourceAttr(fqrn, "groups.#", "0"), + ), + }, + { + Config: usernameChangedConfig, + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(fqrn, plancheck.ResourceActionDestroyBeforeCreate), + }, + }, + }, + }, + }) +} diff --git a/pkg/artifactory/resource/user/resource_artifactory_unmanaged_user_test.go b/pkg/artifactory/resource/user/resource_artifactory_unmanaged_user_test.go index daacd12de..4ba677b1e 100644 --- a/pkg/artifactory/resource/user/resource_artifactory_unmanaged_user_test.go +++ b/pkg/artifactory/resource/user/resource_artifactory_unmanaged_user_test.go @@ -8,6 +8,7 @@ import ( "github.com/go-resty/resty/v2" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/plancheck" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/jfrog/terraform-provider-artifactory/v10/pkg/acctest" "github.com/jfrog/terraform-provider-artifactory/v10/pkg/artifactory/resource/user" @@ -52,13 +53,13 @@ func TestAccUnmanagedUser_UpgradeFromSDKv2(t *testing.T) { resource.TestCheckResourceAttr(fqrn, "internal_password_disabled", "false"), resource.TestCheckNoResourceAttr(fqrn, "groups"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, Config: config, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, }) @@ -339,6 +340,62 @@ func TestAccUnmanagedUser_internal_password_disabled_changed_with_password(t *te }) } +func TestAccUnmanagedUser_name_change(t *testing.T) { + const config = ` + resource "artifactory_unmanaged_user" "%s" { + name = "%s" + email = "dummy_user%d@a.com" + password = "Password!123" + profile_updatable = true + disable_ui_access = false + internal_password_disabled = true + } + ` + + const nameChangedConfig = ` + resource "artifactory_unmanaged_user" "%s" { + name = "foobar" + email = "dummy_user%d@a.com" + password = "Password!123" + profile_updatable = true + disable_ui_access = false + internal_password_disabled = true + } + ` + + id := testutil.RandomInt() + name := fmt.Sprintf("foobar-%d", id) + fqrn := fmt.Sprintf("artifactory_unmanaged_user.%s", name) + username := fmt.Sprintf("dummy_user%d", id) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, + CheckDestroy: testAccCheckUserDestroy(fqrn), + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(config, name, username, id), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(fqrn, "name", username), + resource.TestCheckResourceAttr(fqrn, "email", fmt.Sprintf("dummy_user%d@a.com", id)), + resource.TestCheckResourceAttr(fqrn, "profile_updatable", "true"), + resource.TestCheckResourceAttr(fqrn, "internal_password_disabled", "true"), + resource.TestCheckResourceAttr(fqrn, "password", "Password!123"), + resource.TestCheckResourceAttr(fqrn, "groups.#", "0"), + ), + }, + { + Config: fmt.Sprintf(nameChangedConfig, name, id), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(fqrn, plancheck.ResourceActionDestroyBeforeCreate), + }, + }, + }, + }, + }) +} + func TestAccUnmanagedUser_full(t *testing.T) { id, fqrn, resourceName := testutil.MkNames("test-user-", "artifactory_unmanaged_user") _, _, groupName1 := testutil.MkNames("test-group-", "artifactory_group") diff --git a/pkg/artifactory/resource/user/resource_artifactory_user_test.go b/pkg/artifactory/resource/user/resource_artifactory_user_test.go index 6c69089c3..3855f144b 100644 --- a/pkg/artifactory/resource/user/resource_artifactory_user_test.go +++ b/pkg/artifactory/resource/user/resource_artifactory_user_test.go @@ -8,6 +8,7 @@ import ( "github.com/go-resty/resty/v2" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/plancheck" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/jfrog/terraform-provider-artifactory/v10/pkg/acctest" "github.com/jfrog/terraform-provider-artifactory/v10/pkg/artifactory/resource/user" @@ -51,13 +52,13 @@ func TestAccUser_UpgradeFromSDKv2(t *testing.T) { resource.TestCheckResourceAttr(fqrn, "internal_password_disabled", "false"), resource.TestCheckNoResourceAttr(fqrn, "groups"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, Config: userNoGroups, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, }) @@ -98,13 +99,13 @@ func TestAccUser_UpgradeFrom10_7_0(t *testing.T) { resource.TestCheckResourceAttr(fqrn, "internal_password_disabled", "false"), resource.TestCheckNoResourceAttr(fqrn, "groups"), ), - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, { ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, Config: userNoGroups, PlanOnly: true, - ConfigPlanChecks: acctest.ConfigPlanChecks, + ConfigPlanChecks: testutil.ConfigPlanChecks, }, }, }) @@ -484,6 +485,61 @@ func testAccUserInvalidName(username, errorRegex string) func(t *testing.T) { } } +func TestAccUser_name_change(t *testing.T) { + const config = ` + resource "artifactory_user" "%s" { + name = "%s" + email = "dummy%d@a.com" + password = "Passw0rd!" + admin = true + profile_updatable = true + disable_ui_access = false + internal_password_disabled = false + } + ` + const nameChangedConfig = ` + resource "artifactory_user" "%s" { + name = "foobar" + email = "dummy%d@a.com" + password = "Passw0rd!" + admin = true + profile_updatable = true + disable_ui_access = false + internal_password_disabled = false + } + ` + id, fqrn, name := testutil.MkNames("foobar-", "artifactory_user") + username := fmt.Sprintf("dummy_user-@%d.", id) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, + CheckDestroy: testAccCheckUserDestroy(fqrn), + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(config, name, username, id), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(fqrn, "name", username), + resource.TestCheckResourceAttr(fqrn, "email", fmt.Sprintf("dummy%d@a.com", id)), + resource.TestCheckResourceAttr(fqrn, "admin", "true"), + resource.TestCheckResourceAttr(fqrn, "profile_updatable", "true"), + resource.TestCheckResourceAttr(fqrn, "disable_ui_access", "false"), + resource.TestCheckResourceAttr(fqrn, "internal_password_disabled", "false"), + resource.TestCheckResourceAttr(fqrn, "groups.#", "0"), + ), + }, + { + Config: fmt.Sprintf(nameChangedConfig, name, id), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction(fqrn, plancheck.ResourceActionDestroyBeforeCreate), + }, + }, + }, + }, + }) +} + func TestAccUser_all_attributes(t *testing.T) { const userFull = ` resource "artifactory_user" "%s" { diff --git a/pkg/artifactory/resource/user/user.go b/pkg/artifactory/resource/user/user.go index b2ac05f96..ff8ec392e 100644 --- a/pkg/artifactory/resource/user/user.go +++ b/pkg/artifactory/resource/user/user.go @@ -133,6 +133,9 @@ var baseUserSchemaFramework = map[string]schema.Attribute{ "may contain lowercase letters, numbers and symbols: '.-_@'", ), }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, }, "email": schema.StringAttribute{ MarkdownDescription: "Email for user.",