Skip to content

Commit

Permalink
aws-cognito-user-pool: fix empty string_attribute_constraints on user…
Browse files Browse the repository at this point in the history
…_pool

Fixing bug when empty string_attribute_constraints on user_pool attribute creates no-op update that results in a failure when applied

Rebase for [PR][1]

Closes hashicorp#20276
Closes hashicorp#37687

[1]: hashicorp#20386
  • Loading branch information
kuzaxak committed Aug 31, 2024
1 parent 6efc447 commit 61cdc4e
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 5 deletions.
2 changes: 2 additions & 0 deletions internal/acctest/consts_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 53 additions & 1 deletion internal/service/cognitoidp/user_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package cognitoidp

import (
"bytes"
"context"
"fmt"
"log"
Expand All @@ -20,6 +21,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/create"
"github.com/hashicorp/terraform-provider-aws/internal/enum"
"github.com/hashicorp/terraform-provider-aws/internal/errs"
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
Expand Down Expand Up @@ -421,6 +423,7 @@ func resourceUserPool() *schema.Resource {
Optional: true,
MinItems: 1,
MaxItems: 50,
Set: resourceUserPoolSchemaHash,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"attribute_data_type": {
Expand Down Expand Up @@ -645,6 +648,51 @@ func resourceUserPool() *schema.Resource {
}
}

func resourceUserPoolSchemaHash(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
buf.WriteString(fmt.Sprintf("%s-", m["attribute_data_type"].(string)))
buf.WriteString(fmt.Sprintf("%t-", m["developer_only_attribute"].(bool)))
buf.WriteString(fmt.Sprintf("%t-", m["mutable"].(bool)))
buf.WriteString(fmt.Sprintf("%t-", m["required"].(bool)))

if v, ok := m["string_attribute_constraints"]; ok {
data := v.([]interface{})

if len(data) > 0 {
buf.WriteString("string_attribute_constraints-")
m, _ := data[0].(map[string]interface{})
if l, ok := m["min_length"]; ok && l.(string) != "" {
buf.WriteString(fmt.Sprintf("%s-", l.(string)))
}

if l, ok := m["max_length"]; ok && l.(string) != "" {
buf.WriteString(fmt.Sprintf("%s-", l.(string)))
}
}
}

if v, ok := m["number_attribute_constraints"]; ok {
data := v.([]interface{})

if len(data) > 0 {
buf.WriteString("number_attribute_constraints-")
m, _ := data[0].(map[string]interface{})

if l, ok := m["min_value"]; ok && l.(string) != "" {
buf.WriteString(fmt.Sprintf("%s-", l.(string)))
}

if l, ok := m["max_value"]; ok && l.(string) != "" {
buf.WriteString(fmt.Sprintf("%s-", l.(string)))
}
}
}

return create.StringHashcode(buf.String())
}

func resourceUserPoolCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).CognitoIDPClient(ctx)
Expand Down Expand Up @@ -1692,7 +1740,11 @@ func expandSchemaAttributeTypes(tfList []interface{}) []awstypes.SchemaAttribute
sact.MinLength = aws.String(v.(string))
}

apiObject.StringAttributeConstraints = sact
if sact.MinLength == nil && sact.MaxLength == nil {
apiObject.StringAttributeConstraints = nil
} else {
apiObject.StringAttributeConstraints = sact
}
}
}
}
Expand Down
62 changes: 58 additions & 4 deletions internal/service/cognitoidp/user_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1434,7 +1434,7 @@ func TestAccCognitoIDPUserPool_schemaAttributes(t *testing.T) {
Config: testAccUserPoolConfig_schemaAttributes(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckUserPoolExists(ctx, resourceName, &pool1),
resource.TestCheckResourceAttr(resourceName, "schema.#", acctest.Ct2),
resource.TestCheckResourceAttr(resourceName, "schema.#", acctest.Ct4),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "schema.*", map[string]string{
"attribute_data_type": "String",
"developer_only_attribute": acctest.CtFalse,
Expand All @@ -1443,9 +1443,27 @@ func TestAccCognitoIDPUserPool_schemaAttributes(t *testing.T) {
"number_attribute_constraints.#": acctest.Ct0,
"required": acctest.CtTrue,
"string_attribute_constraints.#": acctest.Ct1,
"string_attribute_constraints.0.min_length": "5",
"string_attribute_constraints.0.min_length": acctest.Ct5,
"string_attribute_constraints.0.max_length": acctest.Ct10,
}),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "schema.*", map[string]string{
"attribute_data_type": "String",
"developer_only_attribute": acctest.CtFalse,
"mutable": acctest.CtTrue,
"name": "strattr",
"required": acctest.CtFalse,
"number_attribute_constraints.#": acctest.Ct0,
"string_attribute_constraints.#": acctest.Ct1,
}),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "schema.*", map[string]string{
"attribute_data_type": "Number",
"developer_only_attribute": acctest.CtFalse,
"mutable": acctest.CtTrue,
"name": "numattr",
"required": acctest.CtFalse,
"number_attribute_constraints.#": acctest.Ct1,
"string_attribute_constraints.#": acctest.Ct0,
}),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "schema.*", map[string]string{
"attribute_data_type": "Boolean",
"developer_only_attribute": acctest.CtTrue,
Expand All @@ -1471,7 +1489,7 @@ func TestAccCognitoIDPUserPool_schemaAttributes(t *testing.T) {
"number_attribute_constraints.#": acctest.Ct0,
"required": acctest.CtTrue,
"string_attribute_constraints.#": acctest.Ct1,
"string_attribute_constraints.0.min_length": "5",
"string_attribute_constraints.0.min_length": acctest.Ct5,
"string_attribute_constraints.0.max_length": acctest.Ct10,
}),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "schema.*", map[string]string{
Expand All @@ -1490,7 +1508,7 @@ func TestAccCognitoIDPUserPool_schemaAttributes(t *testing.T) {
names.AttrName: "mynondevnumber",
"number_attribute_constraints.#": acctest.Ct1,
"number_attribute_constraints.0.min_value": acctest.Ct2,
"number_attribute_constraints.0.max_value": "6",
"number_attribute_constraints.0.max_value": acctest.Ct6,
"required": acctest.CtFalse,
"string_attribute_constraints.#": acctest.Ct0,
}),
Expand Down Expand Up @@ -2732,6 +2750,24 @@ resource "aws_cognito_user_pool" "test" {
}
}
schema {
attribute_data_type = "String"
developer_only_attribute = false
mutable = true
name = "strattr"
required = false
string_attribute_constraints {}
}
schema {
attribute_data_type = "Number"
developer_only_attribute = false
mutable = true
name = "numattr"
required = false
number_attribute_constraints {}
}
schema {
attribute_data_type = "Boolean"
developer_only_attribute = true
Expand Down Expand Up @@ -2761,6 +2797,24 @@ resource "aws_cognito_user_pool" "test" {
}
}
schema {
attribute_data_type = "String"
developer_only_attribute = false
mutable = true
name = "strattr"
required = false
string_attribute_constraints {}
}
schema {
attribute_data_type = "Number"
developer_only_attribute = false
mutable = true
name = "numattr"
required = false
number_attribute_constraints {}
}
schema {
attribute_data_type = "Boolean"
developer_only_attribute = true
Expand Down

0 comments on commit 61cdc4e

Please sign in to comment.