diff --git a/CHANGELOG.md b/CHANGELOG.md index e4668ee7..e407c882 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 3.4.2 (unreleased) + +BUG FIXES: + +* resource/random_password: During upgrade state, ensure `min_upper` is populated ([304](https://github.com/hashicorp/terraform-provider-random/pull/304)). +* resource/random_string: During upgrade state, ensure `min_upper` is populated ([304](https://github.com/hashicorp/terraform-provider-random/pull/304)). + ## 3.4.1 (August 31, 2022) BUG FIXES: diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go index 2c9c4302..579db5c4 100644 --- a/internal/provider/provider_test.go +++ b/internal/provider/provider_test.go @@ -13,6 +13,24 @@ func protoV5ProviderFactories() map[string]func() (tfprotov5.ProviderServer, err } } +func providerVersion221() map[string]resource.ExternalProvider { + return map[string]resource.ExternalProvider{ + "random": { + VersionConstraint: "2.2.1", + Source: "hashicorp/random", + }, + } +} + +func providerVersion320() map[string]resource.ExternalProvider { + return map[string]resource.ExternalProvider{ + "random": { + VersionConstraint: "3.2.0", + Source: "hashicorp/random", + }, + } +} + func providerVersion332() map[string]resource.ExternalProvider { return map[string]resource.ExternalProvider{ "random": { diff --git a/internal/provider/resource_password.go b/internal/provider/resource_password.go index ada43b33..2d205ae9 100644 --- a/internal/provider/resource_password.go +++ b/internal/provider/resource_password.go @@ -193,6 +193,7 @@ func upgradePasswordStateV0toV2(ctx context.Context, req resource.UpgradeStateRe Number: passwordDataV0.Number, Numeric: passwordDataV0.Number, MinNumeric: passwordDataV0.MinNumeric, + MinUpper: passwordDataV0.MinUpper, MinLower: passwordDataV0.MinLower, MinSpecial: passwordDataV0.MinSpecial, OverrideSpecial: passwordDataV0.OverrideSpecial, @@ -246,6 +247,7 @@ func upgradePasswordStateV1toV2(ctx context.Context, req resource.UpgradeStateRe Number: passwordDataV1.Number, Numeric: passwordDataV1.Number, MinNumeric: passwordDataV1.MinNumeric, + MinUpper: passwordDataV1.MinUpper, MinLower: passwordDataV1.MinLower, MinSpecial: passwordDataV1.MinSpecial, OverrideSpecial: passwordDataV1.OverrideSpecial, diff --git a/internal/provider/resource_password_test.go b/internal/provider/resource_password_test.go index 94235229..2445c963 100644 --- a/internal/provider/resource_password_test.go +++ b/internal/provider/resource_password_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "regexp" + "runtime" "testing" "github.com/google/go-cmp/cmp" @@ -506,6 +507,161 @@ func TestAccResourcePassword_Min(t *testing.T) { }) } +// TestAccResourcePassword_UpgradeFromVersion2_2_1 verifies behaviour when upgrading state from schema V0 to V2. +func TestAccResourcePassword_UpgradeFromVersion2_2_1(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { + t.Skip("This test requires darwin/amd64 to download the old provider version. Setting TF_ACC_TERRAFORM_PATH to darwin/amd64 compatible Terraform binary can be used as a workaround.") + } + }, + Steps: []resource.TestStep{ + { + ExternalProviders: providerVersion221(), + Config: `resource "random_password" "min" { + length = 12 + override_special = "!#@" + min_lower = 2 + min_upper = 3 + min_special = 1 + min_numeric = 4 + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_password.min", "result", testCheckLen(12)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([a-z].*){2,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([A-Z].*){3,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([0-9].*){4,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([!#@])`)), + resource.TestCheckResourceAttr("random_password.min", "special", "true"), + resource.TestCheckResourceAttr("random_password.min", "upper", "true"), + resource.TestCheckResourceAttr("random_password.min", "lower", "true"), + resource.TestCheckResourceAttr("random_password.min", "number", "true"), + resource.TestCheckResourceAttr("random_password.min", "min_special", "1"), + resource.TestCheckResourceAttr("random_password.min", "min_upper", "3"), + resource.TestCheckResourceAttr("random_password.min", "min_lower", "2"), + resource.TestCheckResourceAttr("random_password.min", "min_numeric", "4"), + ), + }, + { + ProtoV5ProviderFactories: protoV5ProviderFactories(), + Config: `resource "random_password" "min" { + length = 12 + override_special = "!#@" + min_lower = 2 + min_upper = 3 + min_special = 1 + min_numeric = 4 + }`, + PlanOnly: true, + }, + { + ProtoV5ProviderFactories: protoV5ProviderFactories(), + Config: `resource "random_password" "min" { + length = 12 + override_special = "!#@" + min_lower = 2 + min_upper = 3 + min_special = 1 + min_numeric = 4 + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_password.min", "result", testCheckLen(12)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([a-z].*){2,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([A-Z].*){3,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([0-9].*){4,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([!#@])`)), + resource.TestCheckResourceAttr("random_password.min", "special", "true"), + resource.TestCheckResourceAttr("random_password.min", "upper", "true"), + resource.TestCheckResourceAttr("random_password.min", "lower", "true"), + resource.TestCheckResourceAttr("random_password.min", "number", "true"), + resource.TestCheckResourceAttr("random_password.min", "numeric", "true"), + resource.TestCheckResourceAttr("random_password.min", "min_special", "1"), + resource.TestCheckResourceAttr("random_password.min", "min_upper", "3"), + resource.TestCheckResourceAttr("random_password.min", "min_lower", "2"), + resource.TestCheckResourceAttr("random_password.min", "min_numeric", "4"), + resource.TestCheckResourceAttrSet("random_password.min", "bcrypt_hash"), + ), + }, + }, + }) +} + +// TestAccResourcePassword_UpgradeFromVersion3_2_0 verifies behaviour when upgrading state from schema V1 to V2. +func TestAccResourcePassword_UpgradeFromVersion3_2_0(t *testing.T) { + resource.Test(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + ExternalProviders: providerVersion320(), + Config: `resource "random_password" "min" { + length = 12 + override_special = "!#@" + min_lower = 2 + min_upper = 3 + min_special = 1 + min_numeric = 4 + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_password.min", "result", testCheckLen(12)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([a-z].*){2,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([A-Z].*){3,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([0-9].*){4,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([!#@])`)), + resource.TestCheckResourceAttr("random_password.min", "special", "true"), + resource.TestCheckResourceAttr("random_password.min", "upper", "true"), + resource.TestCheckResourceAttr("random_password.min", "lower", "true"), + resource.TestCheckResourceAttr("random_password.min", "number", "true"), + resource.TestCheckResourceAttr("random_password.min", "min_special", "1"), + resource.TestCheckResourceAttr("random_password.min", "min_upper", "3"), + resource.TestCheckResourceAttr("random_password.min", "min_lower", "2"), + resource.TestCheckResourceAttr("random_password.min", "min_numeric", "4"), + resource.TestCheckResourceAttrSet("random_password.min", "bcrypt_hash"), + ), + }, + { + ProtoV5ProviderFactories: protoV5ProviderFactories(), + Config: `resource "random_password" "min" { + length = 12 + override_special = "!#@" + min_lower = 2 + min_upper = 3 + min_special = 1 + min_numeric = 4 + }`, + PlanOnly: true, + }, + { + ProtoV5ProviderFactories: protoV5ProviderFactories(), + Config: `resource "random_password" "min" { + length = 12 + override_special = "!#@" + min_lower = 2 + min_upper = 3 + min_special = 1 + min_numeric = 4 + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_password.min", "result", testCheckLen(12)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([a-z].*){2,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([A-Z].*){3,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([0-9].*){4,}`)), + resource.TestMatchResourceAttr("random_password.min", "result", regexp.MustCompile(`([!#@])`)), + resource.TestCheckResourceAttr("random_password.min", "special", "true"), + resource.TestCheckResourceAttr("random_password.min", "upper", "true"), + resource.TestCheckResourceAttr("random_password.min", "lower", "true"), + resource.TestCheckResourceAttr("random_password.min", "number", "true"), + resource.TestCheckResourceAttr("random_password.min", "numeric", "true"), + resource.TestCheckResourceAttr("random_password.min", "min_special", "1"), + resource.TestCheckResourceAttr("random_password.min", "min_upper", "3"), + resource.TestCheckResourceAttr("random_password.min", "min_lower", "2"), + resource.TestCheckResourceAttr("random_password.min", "min_numeric", "4"), + resource.TestCheckResourceAttrSet("random_password.min", "bcrypt_hash"), + ), + }, + }, + }) +} + +// TestAccResourcePassword_UpgradeFromVersion3_3_2 verifies behaviour when upgrading from SDKv2 to the Framework. func TestAccResourcePassword_UpgradeFromVersion3_3_2(t *testing.T) { resource.Test(t, resource.TestCase{ Steps: []resource.TestStep{ diff --git a/internal/provider/resource_string.go b/internal/provider/resource_string.go index 320b3c04..cf0d1566 100644 --- a/internal/provider/resource_string.go +++ b/internal/provider/resource_string.go @@ -490,6 +490,7 @@ func upgradeStringStateV1toV2(ctx context.Context, req resource.UpgradeStateRequ Number: stringDataV1.Number, Numeric: stringDataV1.Number, MinNumeric: stringDataV1.MinNumeric, + MinUpper: stringDataV1.MinUpper, MinLower: stringDataV1.MinLower, MinSpecial: stringDataV1.MinSpecial, OverrideSpecial: stringDataV1.OverrideSpecial, diff --git a/internal/provider/resource_string_test.go b/internal/provider/resource_string_test.go index a6b737d2..ec39fe55 100644 --- a/internal/provider/resource_string_test.go +++ b/internal/provider/resource_string_test.go @@ -300,6 +300,80 @@ func TestAccResourceString_LengthErrors(t *testing.T) { }) } +// TestAccResourceString_UpgradeFromVersion3_2_0 verifies behaviour when upgrading state from schema V1 to V2. +func TestAccResourceString_UpgradeFromVersion3_2_0(t *testing.T) { + resource.Test(t, resource.TestCase{ + Steps: []resource.TestStep{ + { + ExternalProviders: providerVersion320(), + Config: `resource "random_string" "min" { + length = 12 + override_special = "!#@" + min_lower = 2 + min_upper = 3 + min_special = 1 + min_numeric = 4 + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_string.min", "result", testCheckLen(12)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([a-z].*){2,}`)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([A-Z].*){3,}`)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([0-9].*){4,}`)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([!#@])`)), + resource.TestCheckResourceAttr("random_string.min", "special", "true"), + resource.TestCheckResourceAttr("random_string.min", "upper", "true"), + resource.TestCheckResourceAttr("random_string.min", "lower", "true"), + resource.TestCheckResourceAttr("random_string.min", "number", "true"), + resource.TestCheckResourceAttr("random_string.min", "min_special", "1"), + resource.TestCheckResourceAttr("random_string.min", "min_upper", "3"), + resource.TestCheckResourceAttr("random_string.min", "min_lower", "2"), + resource.TestCheckResourceAttr("random_string.min", "min_numeric", "4"), + ), + }, + { + ProtoV5ProviderFactories: protoV5ProviderFactories(), + Config: `resource "random_string" "min" { + length = 12 + override_special = "!#@" + min_lower = 2 + min_upper = 3 + min_special = 1 + min_numeric = 4 + }`, + PlanOnly: true, + }, + { + ProtoV5ProviderFactories: protoV5ProviderFactories(), + Config: `resource "random_string" "min" { + length = 12 + override_special = "!#@" + min_lower = 2 + min_upper = 3 + min_special = 1 + min_numeric = 4 + }`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrWith("random_string.min", "result", testCheckLen(12)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([a-z].*){2,}`)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([A-Z].*){3,}`)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([0-9].*){4,}`)), + resource.TestMatchResourceAttr("random_string.min", "result", regexp.MustCompile(`([!#@])`)), + resource.TestCheckResourceAttr("random_string.min", "special", "true"), + resource.TestCheckResourceAttr("random_string.min", "upper", "true"), + resource.TestCheckResourceAttr("random_string.min", "lower", "true"), + resource.TestCheckResourceAttr("random_string.min", "number", "true"), + resource.TestCheckResourceAttr("random_string.min", "numeric", "true"), + resource.TestCheckResourceAttr("random_string.min", "min_special", "1"), + resource.TestCheckResourceAttr("random_string.min", "min_upper", "3"), + resource.TestCheckResourceAttr("random_string.min", "min_lower", "2"), + resource.TestCheckResourceAttr("random_string.min", "min_numeric", "4"), + ), + }, + }, + }) +} + +// TestAccResourceString_UpgradeFromVersion3_3_2 verifies behaviour when upgrading from SDKv2 to the Framework. func TestAccResourceString_UpgradeFromVersion3_3_2(t *testing.T) { resource.Test(t, resource.TestCase{ Steps: []resource.TestStep{