Skip to content

Commit

Permalink
Merge pull request #34319 from hashicorp/b-ExpandFrameworkStringValue…
Browse files Browse the repository at this point in the history
…Map-crash

Fix `Value Conversion Error` panics for Plugin Framework resources when `null` tag values are specified
  • Loading branch information
ewbankkit authored Nov 9, 2023
2 parents ec5d398 + 3b830ec commit 6ef42d2
Show file tree
Hide file tree
Showing 10 changed files with 244 additions and 195 deletions.
3 changes: 3 additions & 0 deletions .changelog/34319.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
provider: Fix `Value Conversion Error` panic for certain resources when `null` tag values are specified
```
10 changes: 10 additions & 0 deletions internal/framework/flex/map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ func TestExpandFrameworkStringMap(t *testing.T) {
}),
expected: nil,
},
"null element": {
input: types.MapValueMust(types.StringType, map[string]attr.Value{
"one": types.StringValue("GET"),
"two": types.StringNull(),
}),
expected: map[string]*string{
"one": aws.String("GET"),
"two": nil,
},
},
}

for name, test := range tests {
Expand Down
7 changes: 3 additions & 4 deletions internal/service/appconfig/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,10 @@ func resourceApplicationDelete(ctx context.Context, d *schema.ResourceData, meta
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).AppConfigConn(ctx)

input := &appconfig.DeleteApplicationInput{
log.Printf("[INFO] Deleting AppConfig Application: %s", d.Id())
_, err := conn.DeleteApplicationWithContext(ctx, &appconfig.DeleteApplicationInput{
ApplicationId: aws.String(d.Id()),
}

_, err := conn.DeleteApplicationWithContext(ctx, input)
})

if tfawserr.ErrCodeEquals(err, appconfig.ErrCodeResourceNotFoundException) {
return diags
Expand Down
10 changes: 4 additions & 6 deletions internal/service/appconfig/configuration_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,17 +256,15 @@ func resourceConfigurationProfileDelete(ctx context.Context, d *schema.ResourceD
conn := meta.(*conns.AWSClient).AppConfigConn(ctx)

confProfID, appID, err := ConfigurationProfileParseID(d.Id())

if err != nil {
return sdkdiag.AppendErrorf(diags, "deleting AppConfig Configuration Profile (%s): %s", d.Id(), err)
return sdkdiag.AppendFromErr(diags, err)
}

input := &appconfig.DeleteConfigurationProfileInput{
log.Printf("[INFO] Deleting AppConfig Configuration Profile: %s", d.Id())
_, err = conn.DeleteConfigurationProfileWithContext(ctx, &appconfig.DeleteConfigurationProfileInput{
ApplicationId: aws.String(appID),
ConfigurationProfileId: aws.String(confProfID),
}

_, err = conn.DeleteConfigurationProfileWithContext(ctx, input)
})

if tfawserr.ErrCodeEquals(err, appconfig.ErrCodeResourceNotFoundException) {
return diags
Expand Down
7 changes: 3 additions & 4 deletions internal/service/appconfig/deployment_strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,10 @@ func resourceDeploymentStrategyDelete(ctx context.Context, d *schema.ResourceDat
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).AppConfigConn(ctx)

input := &appconfig.DeleteDeploymentStrategyInput{
log.Printf("[INFO] Deleting AppConfig Deployment Strategy: %s", d.Id())
_, err := conn.DeleteDeploymentStrategyWithContext(ctx, &appconfig.DeleteDeploymentStrategyInput{
DeploymentStrategyId: aws.String(d.Id()),
}

_, err := conn.DeleteDeploymentStrategyWithContext(ctx, input)
})

if tfawserr.ErrCodeEquals(err, appconfig.ErrCodeResourceNotFoundException) {
return diags
Expand Down
73 changes: 52 additions & 21 deletions internal/service/appconfig/environment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,35 @@ func TestAccAppConfigEnvironment_tags(t *testing.T) {
})
}

func TestAccAppConfigEnvironment_tagsWithNullValue(t *testing.T) {
ctx := acctest.Context(t)
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_appconfig_environment.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, appconfig.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckEnvironmentDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccEnvironmentConfig_tagsWithNullValue(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckEnvironmentExists(ctx, resourceName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "2"),
resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"),
resource.TestCheckNoResourceAttr(resourceName, "tags.key2"),
),
// ~ tags = {
// ~ "key2" = "" -> null
// # (1 unchanged element hidden)
// }
ExpectNonEmptyPlan: true,
},
},
})
}

func TestAccAppConfigEnvironment_frameworkMigration_basic(t *testing.T) {
ctx := acctest.Context(t)
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
Expand Down Expand Up @@ -440,32 +469,26 @@ func testAccCheckEnvironmentExists(ctx context.Context, resourceName string) res
}

func testAccEnvironmentConfig_basic(rName string) string {
return acctest.ConfigCompose(
testAccApplicationConfig_name(rName),
fmt.Sprintf(`
return acctest.ConfigCompose(testAccApplicationConfig_name(rName), fmt.Sprintf(`
resource "aws_appconfig_environment" "test" {
name = %q
name = %[1]q
application_id = aws_appconfig_application.test.id
}
`, rName))
}

func testAccEnvironmentConfig_description(rName, description string) string {
return acctest.ConfigCompose(
testAccApplicationConfig_name(rName),
fmt.Sprintf(`
return acctest.ConfigCompose(testAccApplicationConfig_name(rName), fmt.Sprintf(`
resource "aws_appconfig_environment" "test" {
name = %q
description = %q
name = %[1]q
description = %[2]q
application_id = aws_appconfig_application.test.id
}
`, rName, description))
}

func testAccEnvironmentConfig_monitors(rName string, count int) string {
return acctest.ConfigCompose(
testAccApplicationConfig_name(rName),
fmt.Sprintf(`
return acctest.ConfigCompose(testAccApplicationConfig_name(rName), fmt.Sprintf(`
data "aws_partition" "current" {}
resource "aws_iam_role" "test" {
Expand Down Expand Up @@ -541,9 +564,7 @@ resource "aws_appconfig_environment" "test" {
}

func testAccEnvironmentConfig_multiple(rName string) string {
return acctest.ConfigCompose(
testAccApplicationConfig_name(rName),
fmt.Sprintf(`
return acctest.ConfigCompose(testAccApplicationConfig_name(rName), fmt.Sprintf(`
resource "aws_appconfig_environment" "test" {
name = %[1]q
application_id = aws_appconfig_application.test.id
Expand All @@ -557,9 +578,7 @@ resource "aws_appconfig_environment" "test2" {
}

func testAccEnvironmentConfig_tags1(rName, tagKey1, tagValue1 string) string {
return acctest.ConfigCompose(
testAccApplicationConfig_name(rName),
fmt.Sprintf(`
return acctest.ConfigCompose(testAccApplicationConfig_name(rName), fmt.Sprintf(`
resource "aws_appconfig_environment" "test" {
name = %[1]q
application_id = aws_appconfig_application.test.id
Expand All @@ -572,9 +591,7 @@ resource "aws_appconfig_environment" "test" {
}

func testAccEnvironmentConfig_tags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string {
return acctest.ConfigCompose(
testAccApplicationConfig_name(rName),
fmt.Sprintf(`
return acctest.ConfigCompose(testAccApplicationConfig_name(rName), fmt.Sprintf(`
resource "aws_appconfig_environment" "test" {
name = %[1]q
application_id = aws_appconfig_application.test.id
Expand All @@ -586,3 +603,17 @@ resource "aws_appconfig_environment" "test" {
}
`, rName, tagKey1, tagValue1, tagKey2, tagValue2))
}

func testAccEnvironmentConfig_tagsWithNullValue(rName string) string {
return acctest.ConfigCompose(testAccApplicationConfig_name(rName), fmt.Sprintf(`
resource "aws_appconfig_environment" "test" {
name = %[1]q
application_id = aws_appconfig_application.test.id
tags = {
key1 = "value1"
key2 = null
}
}
`, rName))
}
2 changes: 2 additions & 0 deletions internal/service/appconfig/extension_association.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package appconfig
import (
"context"
"errors"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/appconfig"
Expand Down Expand Up @@ -144,6 +145,7 @@ func resourceExtensionAssociationUpdate(ctx context.Context, d *schema.ResourceD
func resourceExtensionAssociationDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).AppConfigConn(ctx)

log.Printf("[INFO] Deleting AppConfig Hosted Extension Association: %s", d.Id())
_, err := conn.DeleteExtensionAssociationWithContext(ctx, &appconfig.DeleteExtensionAssociationInput{
ExtensionAssociationId: aws.String(d.Id()),
})
Expand Down
10 changes: 4 additions & 6 deletions internal/service/appconfig/hosted_configuration_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,18 +161,16 @@ func resourceHostedConfigurationVersionDelete(ctx context.Context, d *schema.Res
conn := meta.(*conns.AWSClient).AppConfigConn(ctx)

appID, confProfID, versionNumber, err := HostedConfigurationVersionParseID(d.Id())

if err != nil {
return sdkdiag.AppendErrorf(diags, "deleting Appconfig Hosted Configuration Version (%s): %s", d.Id(), err)
return sdkdiag.AppendFromErr(diags, err)
}

input := &appconfig.DeleteHostedConfigurationVersionInput{
log.Printf("[INFO] Deleting AppConfig Hosted Configuration Version: %s", d.Id())
_, err = conn.DeleteHostedConfigurationVersionWithContext(ctx, &appconfig.DeleteHostedConfigurationVersionInput{
ApplicationId: aws.String(appID),
ConfigurationProfileId: aws.String(confProfID),
VersionNumber: aws.Int64(int64(versionNumber)),
}

_, err = conn.DeleteHostedConfigurationVersionWithContext(ctx, input)
})

if tfawserr.ErrCodeEquals(err, appconfig.ErrCodeResourceNotFoundException) {
return diags
Expand Down
Loading

0 comments on commit 6ef42d2

Please sign in to comment.