Skip to content

Commit

Permalink
Merge pull request #304 from hashicorp/bendbennett/issues-302
Browse files Browse the repository at this point in the history
Fix upgrade v2.2.1 -> v3.4.0 forces replacement
  • Loading branch information
bendbennett committed Sep 2, 2022
2 parents fae7ea6 + 5b5e6b8 commit d4872da
Show file tree
Hide file tree
Showing 6 changed files with 258 additions and 0 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
18 changes: 18 additions & 0 deletions internal/provider/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
2 changes: 2 additions & 0 deletions internal/provider/resource_password.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
156 changes: 156 additions & 0 deletions internal/provider/resource_password_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"regexp"
"runtime"
"testing"

"github.com/google/go-cmp/cmp"
Expand Down Expand Up @@ -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{
Expand Down
1 change: 1 addition & 0 deletions internal/provider/resource_string.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
74 changes: 74 additions & 0 deletions internal/provider/resource_string_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down

0 comments on commit d4872da

Please sign in to comment.