From 22c75cb1fb8536d80375d35c4e5992fc54425630 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Wed, 18 Mar 2020 12:45:47 -0400 Subject: [PATCH 1/3] tests/helper/schema: Add unit testing covering existing behavior of ConflictsWith and list index/map key syntax Reference: https://github.com/hashicorp/terraform-plugin-sdk/issues/71 Reference: https://github.com/bflad/tfproviderlint/issues/104 The `TestSchemaMap_InternalValidate` tests also include TODOs for potential schema validation improvements. --- helper/schema/schema_test.go | 633 +++++++++++++++++++++++++++++++++++ 1 file changed, 633 insertions(+) diff --git a/helper/schema/schema_test.go b/helper/schema/schema_test.go index 1f9f773ec4..35f3ca90e2 100644 --- a/helper/schema/schema_test.go +++ b/helper/schema/schema_test.go @@ -3307,6 +3307,244 @@ func TestSchemaMap_InternalValidate(t *testing.T) { true, }, + "ConflictsWith list index syntax with self reference": { + map[string]*Schema{ + "config_block_attr": &Schema{ + Type: TypeList, + Optional: true, + Elem: &Resource{ + Schema: map[string]*Schema{ + "nested_attr": &Schema{ + Type: TypeString, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.nested_attr"}, + }, + }, + }, + }, + }, + false, // TODO: This should return an error as it will always error during runtime + }, + + "ConflictsWith list index syntax with list configuration block existing attribute": { + map[string]*Schema{ + "config_block_attr": &Schema{ + Type: TypeList, + Optional: true, + Elem: &Resource{ + Schema: map[string]*Schema{ + "nested_attr": &Schema{ + Type: TypeString, + Optional: true, + }, + }, + }, + }, + "test": &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.nested_attr"}, + }, + }, + false, + }, + + "ConflictsWith list index syntax with list configuration block missing attribute": { + map[string]*Schema{ + "config_block_attr": &Schema{ + Type: TypeList, + Optional: true, + Elem: &Resource{ + Schema: map[string]*Schema{ + "nested_attr": &Schema{ + Type: TypeString, + Optional: true, + }, + }, + }, + }, + "test": &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.missing_attr"}, + }, + }, + true, + }, + + "ConflictsWith list index syntax with set configuration block existing attribute": { + map[string]*Schema{ + "config_block_attr": &Schema{ + Type: TypeSet, + Optional: true, + Elem: &Resource{ + Schema: map[string]*Schema{ + "nested_attr": &Schema{ + Type: TypeString, + Optional: true, + }, + }, + }, + }, + "test": &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.nested_attr"}, + }, + }, + false, // TODO: This should return an error as sets cannot be indexed + }, + + "ConflictsWith list index syntax with set configuration block missing attribute": { + map[string]*Schema{ + "config_block_attr": &Schema{ + Type: TypeSet, + Optional: true, + Elem: &Resource{ + Schema: map[string]*Schema{ + "nested_attr": &Schema{ + Type: TypeString, + Optional: true, + }, + }, + }, + }, + "test": &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.missing_attr"}, + }, + }, + true, + }, + + "ConflictsWith map key syntax with list configuration block existing attribute": { + map[string]*Schema{ + "config_block_attr": &Schema{ + Type: TypeList, + Optional: true, + Elem: &Resource{ + Schema: map[string]*Schema{ + "nested_attr": &Schema{ + Type: TypeString, + Optional: true, + }, + }, + }, + }, + "test": &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.nested_attr"}, + }, + }, + false, // TODO: This should return an error as validateConflictingAttributes will never error + }, + + "ConflictsWith map key syntax with list configuration block self reference": { + map[string]*Schema{ + "config_block_attr": &Schema{ + Type: TypeList, + Optional: true, + Elem: &Resource{ + Schema: map[string]*Schema{ + "nested_attr": &Schema{ + Type: TypeString, + Optional: true, + ConflictsWith: []string{"config_block_attr.nested_attr"}, + }, + }, + }, + }, + }, + false, // TODO: This should return an error as validateConflictingAttributes will never error + }, + + "ConflictsWith map key syntax with set configuration block existing attribute": { + map[string]*Schema{ + "config_block_attr": &Schema{ + Type: TypeSet, + Optional: true, + Elem: &Resource{ + Schema: map[string]*Schema{ + "nested_attr": &Schema{ + Type: TypeString, + Optional: true, + }, + }, + }, + }, + "test": &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.nested_attr"}, + }, + }, + false, // TODO: This should return an error as validateConflictingAttributes will never error and sets cannot be indexed + }, + + "ConflictsWith map key syntax with set configuration block self reference": { + map[string]*Schema{ + "config_block_attr": &Schema{ + Type: TypeSet, + Optional: true, + Elem: &Resource{ + Schema: map[string]*Schema{ + "nested_attr": &Schema{ + Type: TypeString, + Optional: true, + ConflictsWith: []string{"config_block_attr.nested_attr"}, + }, + }, + }, + }, + }, + false, // TODO: This should return an error as validateConflictingAttributes will never error and sets cannot be indexed + }, + + "ConflictsWith map key syntax with map attribute": { + map[string]*Schema{ + "map_attr": &Schema{ + Type: TypeMap, + Optional: true, + Elem: &Schema{Type: TypeString}, + }, + "test": &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"map_attr.some_key"}, + }, + }, + true, + }, + + "ConflictsWith string syntax with map attribute": { + map[string]*Schema{ + "map_attr": &Schema{ + Type: TypeMap, + Optional: true, + Elem: &Schema{Type: TypeString}, + }, + "test": &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"map_attr"}, + }, + }, + false, + }, + + "ConflictsWith string syntax with self reference": { + map[string]*Schema{ + "test": &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"test"}, + }, + }, + false, // TODO: This should return an error as it will always error during runtime + }, + "Sub-resource invalid": { map[string]*Schema{ "foo": { @@ -5402,6 +5640,401 @@ func TestSchemaMapDeepCopy(t *testing.T) { } } +func TestValidateConflictingAttributes(t *testing.T) { + cases := map[string]struct { + Key string + Schema *Schema + Config map[string]interface{} + Err bool + }{ + "root attribute self conflicting": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"self"}, + }, + Config: map[string]interface{}{ + "self": true, + }, + Err: true, + }, + + "root attribute conflicting unconfigured self unconfigured": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"root_attr"}, + }, + Config: map[string]interface{}{}, + Err: false, + }, + + "root attribute conflicting unconfigured self unknown": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"root_attr"}, + }, + Config: map[string]interface{}{ + "self": hcl2shim.UnknownVariableValue, + }, + Err: false, + }, + + "root attribute conflicting unconfigured self known": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"root_attr"}, + }, + Config: map[string]interface{}{ + "self": true, + }, + Err: false, + }, + + "root attribute conflicting unknown self unconfigured": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"root_attr"}, + }, + Config: map[string]interface{}{ + "root_attr": hcl2shim.UnknownVariableValue, + }, + Err: false, + }, + + "root attribute conflicting unknown self unknown": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"root_attr"}, + }, + Config: map[string]interface{}{ + "root_attr": hcl2shim.UnknownVariableValue, + "self": hcl2shim.UnknownVariableValue, + }, + Err: false, + }, + + "root attribute conflicting unknown self known": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"root_attr"}, + }, + Config: map[string]interface{}{ + "root_attr": hcl2shim.UnknownVariableValue, + "self": true, + }, + Err: false, + }, + + "root attribute conflicting known self unconfigured": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"root_attr"}, + }, + Config: map[string]interface{}{ + "root_attr": true, + }, + Err: true, + }, + + "root attribute conflicting known self unknown": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"root_attr"}, + }, + Config: map[string]interface{}{ + "root_attr": true, + "self": hcl2shim.UnknownVariableValue, + }, + Err: true, + }, + + "root attribute conflicting known self known": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"root_attr"}, + }, + Config: map[string]interface{}{ + "root_attr": true, + "self": true, + }, + Err: true, + }, + + "configuration block attribute list index syntax self conflicting": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.self"}, + }, + Config: map[string]interface{}{ + "config_block_attr": []interface{}{ + map[string]interface{}{ + "self": true, + }, + }, + }, + Err: true, + }, + + "configuration block attribute list index syntax conflicting unconfigured self unconfigured": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.nested_attr"}, + }, + Config: map[string]interface{}{}, + Err: false, + }, + + "configuration block attribute list index syntax conflicting unconfigured self unknown": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.nested_attr"}, + }, + Config: map[string]interface{}{ + "config_block_attr": []interface{}{ + map[string]interface{}{ + "self": hcl2shim.UnknownVariableValue, + }, + }, + }, + Err: false, + }, + + "configuration block attribute list index syntax conflicting unconfigured self known": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.nested_attr"}, + }, + Config: map[string]interface{}{ + "config_block_attr": []interface{}{ + map[string]interface{}{ + "self": true, + }, + }, + }, + Err: false, + }, + + "configuration block attribute list index syntax conflicting unknown self unconfigured": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.nested_attr"}, + }, + Config: map[string]interface{}{ + "config_block_attr": []interface{}{ + map[string]interface{}{ + "nested_attr": hcl2shim.UnknownVariableValue, + }, + }, + }, + Err: false, + }, + + "configuration block attribute list index syntax conflicting unknown self unknown": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.nested_attr"}, + }, + Config: map[string]interface{}{ + "config_block_attr": []interface{}{ + map[string]interface{}{ + "nested_attr": hcl2shim.UnknownVariableValue, + "self": hcl2shim.UnknownVariableValue, + }, + }, + }, + Err: false, + }, + + "configuration block attribute list index syntax conflicting unknown self known": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.nested_attr"}, + }, + Config: map[string]interface{}{ + "config_block_attr": []interface{}{ + map[string]interface{}{ + "nested_attr": hcl2shim.UnknownVariableValue, + "self": true, + }, + }, + }, + Err: false, + }, + + "configuration block attribute list index syntax conflicting known self unconfigured": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.nested_attr"}, + }, + Config: map[string]interface{}{ + "config_block_attr": []interface{}{ + map[string]interface{}{ + "nested_attr": true, + }, + }, + }, + Err: true, + }, + + "configuration block attribute list index syntax conflicting known self unknown": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.nested_attr"}, + }, + Config: map[string]interface{}{ + "config_block_attr": []interface{}{ + map[string]interface{}{ + "nested_attr": true, + "self": hcl2shim.UnknownVariableValue, + }, + }, + }, + Err: true, + }, + + "configuration block attribute list index syntax conflicting known self known": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.nested_attr"}, + }, + Config: map[string]interface{}{ + "config_block_attr": []interface{}{ + map[string]interface{}{ + "nested_attr": true, + "self": true, + }, + }, + }, + Err: true, + }, + + "configuration block attribute map key syntax self conflicting": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.self"}, + }, + Config: map[string]interface{}{ + "config_block_attr": []interface{}{ + map[string]interface{}{ + "self": true, + }, + }, + }, + Err: false, + }, + + "configuration block attribute map key syntax conflicting known self unconfigured": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.nested_attr"}, + }, + Config: map[string]interface{}{ + "config_block_attr": []interface{}{ + map[string]interface{}{ + "nested_attr": true, + }, + }, + }, + Err: false, + }, + + "configuration block attribute map key syntax conflicting known self unknown": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.nested_attr"}, + }, + Config: map[string]interface{}{ + "config_block_attr": []interface{}{ + map[string]interface{}{ + "nested_attr": true, + "self": hcl2shim.UnknownVariableValue, + }, + }, + }, + Err: false, + }, + + "configuration block attribute map key syntax conflicting known self known": { + Key: "self", + Schema: &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.nested_attr"}, + }, + Config: map[string]interface{}{ + "config_block_attr": []interface{}{ + map[string]interface{}{ + "nested_attr": true, + "self": true, + }, + }, + }, + Err: false, + }, + } + + for tn, tc := range cases { + t.Run(tn, func(t *testing.T) { + c := terraform.NewResourceConfigRaw(tc.Config) + + err := validateConflictingAttributes(tc.Key, tc.Schema, c) + if err == nil && tc.Err { + t.Fatalf("expected error") + } + + if err != nil && !tc.Err { + t.Fatalf("didn't expect error, got error: %+v", err) + } + }) + } + +} + func TestValidateExactlyOneOfAttributes(t *testing.T) { cases := map[string]struct { Key string From 50320651b6167866186f9a0458d2fe8b3cc184c4 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Wed, 18 Mar 2020 23:30:09 -0400 Subject: [PATCH 2/3] helper/schema: Additional validation for schema attribute references Reference: https://github.com/hashicorp/terraform-plugin-sdk/issues/71 --- helper/schema/schema.go | 36 ++++++++++++++++++++++++++-------- helper/schema/schema_test.go | 38 +++++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/helper/schema/schema.go b/helper/schema/schema.go index 331c524582..daf598d1e0 100644 --- a/helper/schema/schema.go +++ b/helper/schema/schema.go @@ -683,21 +683,21 @@ func (m schemaMap) internalValidate(topSchemaMap schemaMap, attrsOnly bool) erro } if len(v.ConflictsWith) > 0 { - err := checkKeysAgainstSchemaFlags(k, v.ConflictsWith, topSchemaMap) + err := checkKeysAgainstSchemaFlags(k, v.ConflictsWith, topSchemaMap, v) if err != nil { return fmt.Errorf("ConflictsWith: %+v", err) } } if len(v.ExactlyOneOf) > 0 { - err := checkKeysAgainstSchemaFlags(k, v.ExactlyOneOf, topSchemaMap) + err := checkKeysAgainstSchemaFlags(k, v.ExactlyOneOf, topSchemaMap, v) if err != nil { return fmt.Errorf("ExactlyOneOf: %+v", err) } } if len(v.AtLeastOneOf) > 0 { - err := checkKeysAgainstSchemaFlags(k, v.AtLeastOneOf, topSchemaMap) + err := checkKeysAgainstSchemaFlags(k, v.AtLeastOneOf, topSchemaMap, v) if err != nil { return fmt.Errorf("AtLeastOneOf: %+v", err) } @@ -809,14 +809,20 @@ func (m schemaMap) internalValidate(topSchemaMap schemaMap, attrsOnly bool) erro return nil } -func checkKeysAgainstSchemaFlags(k string, keys []string, topSchemaMap schemaMap) error { +func checkKeysAgainstSchemaFlags(k string, keys []string, topSchemaMap schemaMap, self *Schema) error { for _, key := range keys { parts := strings.Split(key, ".") sm := topSchemaMap var target *Schema for _, part := range parts { - // Skip index fields - if _, err := strconv.Atoi(part); err == nil { + // Skip index fields if 0 + partInt, err := strconv.Atoi(part) + + if err == nil { + if partInt != 0 { + return fmt.Errorf("%s configuration block reference (%s) can only use the .0. index for TypeList and MaxItems: 1 configuration blocks", k, key) + } + continue } @@ -825,13 +831,27 @@ func checkKeysAgainstSchemaFlags(k string, keys []string, topSchemaMap schemaMap return fmt.Errorf("%s references unknown attribute (%s) at part (%s)", k, key, part) } - if subResource, ok := target.Elem.(*Resource); ok { - sm = schemaMap(subResource.Schema) + subResource, ok := target.Elem.(*Resource) + + if !ok { + continue + } + + if target.Type == TypeSet || target.MaxItems != 1 { + return fmt.Errorf("%s configuration block reference (%s) can only be used with TypeList and MaxItems: 1 configuration blocks", k, key) } + + sm = schemaMap(subResource.Schema) } + if target == nil { return fmt.Errorf("%s cannot find target attribute (%s), sm: %#v", k, key, sm) } + + if target == self { + return fmt.Errorf("%s cannot reference self (%s)", k, key) + } + if target.Required { return fmt.Errorf("%s cannot contain Required attribute (%s)", k, key) } diff --git a/helper/schema/schema_test.go b/helper/schema/schema_test.go index 35f3ca90e2..faf5c37ebc 100644 --- a/helper/schema/schema_test.go +++ b/helper/schema/schema_test.go @@ -3323,7 +3323,7 @@ func TestSchemaMap_InternalValidate(t *testing.T) { }, }, }, - false, // TODO: This should return an error as it will always error during runtime + true, }, "ConflictsWith list index syntax with list configuration block existing attribute": { @@ -3331,6 +3331,7 @@ func TestSchemaMap_InternalValidate(t *testing.T) { "config_block_attr": &Schema{ Type: TypeList, Optional: true, + MaxItems: 1, Elem: &Resource{ Schema: map[string]*Schema{ "nested_attr": &Schema{ @@ -3372,6 +3373,29 @@ func TestSchemaMap_InternalValidate(t *testing.T) { true, }, + "ConflictsWith list index syntax with list configuration block missing MaxItems": { + map[string]*Schema{ + "config_block_attr": &Schema{ + Type: TypeList, + Optional: true, + Elem: &Resource{ + Schema: map[string]*Schema{ + "nested_attr": &Schema{ + Type: TypeString, + Optional: true, + }, + }, + }, + }, + "test": &Schema{ + Type: TypeBool, + Optional: true, + ConflictsWith: []string{"config_block_attr.0.missing_attr"}, + }, + }, + true, + }, + "ConflictsWith list index syntax with set configuration block existing attribute": { map[string]*Schema{ "config_block_attr": &Schema{ @@ -3392,7 +3416,7 @@ func TestSchemaMap_InternalValidate(t *testing.T) { ConflictsWith: []string{"config_block_attr.0.nested_attr"}, }, }, - false, // TODO: This should return an error as sets cannot be indexed + true, }, "ConflictsWith list index syntax with set configuration block missing attribute": { @@ -3438,7 +3462,7 @@ func TestSchemaMap_InternalValidate(t *testing.T) { ConflictsWith: []string{"config_block_attr.nested_attr"}, }, }, - false, // TODO: This should return an error as validateConflictingAttributes will never error + true, }, "ConflictsWith map key syntax with list configuration block self reference": { @@ -3457,7 +3481,7 @@ func TestSchemaMap_InternalValidate(t *testing.T) { }, }, }, - false, // TODO: This should return an error as validateConflictingAttributes will never error + true, }, "ConflictsWith map key syntax with set configuration block existing attribute": { @@ -3480,7 +3504,7 @@ func TestSchemaMap_InternalValidate(t *testing.T) { ConflictsWith: []string{"config_block_attr.nested_attr"}, }, }, - false, // TODO: This should return an error as validateConflictingAttributes will never error and sets cannot be indexed + true, }, "ConflictsWith map key syntax with set configuration block self reference": { @@ -3499,7 +3523,7 @@ func TestSchemaMap_InternalValidate(t *testing.T) { }, }, }, - false, // TODO: This should return an error as validateConflictingAttributes will never error and sets cannot be indexed + true, }, "ConflictsWith map key syntax with map attribute": { @@ -3542,7 +3566,7 @@ func TestSchemaMap_InternalValidate(t *testing.T) { ConflictsWith: []string{"test"}, }, }, - false, // TODO: This should return an error as it will always error during runtime + true, }, "Sub-resource invalid": { From 747ebff070b278d242c12bca76f548051e42a75a Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Wed, 18 Mar 2020 23:40:58 -0400 Subject: [PATCH 3/3] tests/helper/schema: gofmt -s -w --- helper/schema/schema_test.go | 64 ++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/helper/schema/schema_test.go b/helper/schema/schema_test.go index faf5c37ebc..5bb8ff48a5 100644 --- a/helper/schema/schema_test.go +++ b/helper/schema/schema_test.go @@ -3309,12 +3309,12 @@ func TestSchemaMap_InternalValidate(t *testing.T) { "ConflictsWith list index syntax with self reference": { map[string]*Schema{ - "config_block_attr": &Schema{ + "config_block_attr": { Type: TypeList, Optional: true, Elem: &Resource{ Schema: map[string]*Schema{ - "nested_attr": &Schema{ + "nested_attr": { Type: TypeString, Optional: true, ConflictsWith: []string{"config_block_attr.0.nested_attr"}, @@ -3328,20 +3328,20 @@ func TestSchemaMap_InternalValidate(t *testing.T) { "ConflictsWith list index syntax with list configuration block existing attribute": { map[string]*Schema{ - "config_block_attr": &Schema{ + "config_block_attr": { Type: TypeList, Optional: true, MaxItems: 1, Elem: &Resource{ Schema: map[string]*Schema{ - "nested_attr": &Schema{ + "nested_attr": { Type: TypeString, Optional: true, }, }, }, }, - "test": &Schema{ + "test": { Type: TypeBool, Optional: true, ConflictsWith: []string{"config_block_attr.0.nested_attr"}, @@ -3352,19 +3352,19 @@ func TestSchemaMap_InternalValidate(t *testing.T) { "ConflictsWith list index syntax with list configuration block missing attribute": { map[string]*Schema{ - "config_block_attr": &Schema{ + "config_block_attr": { Type: TypeList, Optional: true, Elem: &Resource{ Schema: map[string]*Schema{ - "nested_attr": &Schema{ + "nested_attr": { Type: TypeString, Optional: true, }, }, }, }, - "test": &Schema{ + "test": { Type: TypeBool, Optional: true, ConflictsWith: []string{"config_block_attr.0.missing_attr"}, @@ -3375,19 +3375,19 @@ func TestSchemaMap_InternalValidate(t *testing.T) { "ConflictsWith list index syntax with list configuration block missing MaxItems": { map[string]*Schema{ - "config_block_attr": &Schema{ + "config_block_attr": { Type: TypeList, Optional: true, Elem: &Resource{ Schema: map[string]*Schema{ - "nested_attr": &Schema{ + "nested_attr": { Type: TypeString, Optional: true, }, }, }, }, - "test": &Schema{ + "test": { Type: TypeBool, Optional: true, ConflictsWith: []string{"config_block_attr.0.missing_attr"}, @@ -3398,19 +3398,19 @@ func TestSchemaMap_InternalValidate(t *testing.T) { "ConflictsWith list index syntax with set configuration block existing attribute": { map[string]*Schema{ - "config_block_attr": &Schema{ + "config_block_attr": { Type: TypeSet, Optional: true, Elem: &Resource{ Schema: map[string]*Schema{ - "nested_attr": &Schema{ + "nested_attr": { Type: TypeString, Optional: true, }, }, }, }, - "test": &Schema{ + "test": { Type: TypeBool, Optional: true, ConflictsWith: []string{"config_block_attr.0.nested_attr"}, @@ -3421,19 +3421,19 @@ func TestSchemaMap_InternalValidate(t *testing.T) { "ConflictsWith list index syntax with set configuration block missing attribute": { map[string]*Schema{ - "config_block_attr": &Schema{ + "config_block_attr": { Type: TypeSet, Optional: true, Elem: &Resource{ Schema: map[string]*Schema{ - "nested_attr": &Schema{ + "nested_attr": { Type: TypeString, Optional: true, }, }, }, }, - "test": &Schema{ + "test": { Type: TypeBool, Optional: true, ConflictsWith: []string{"config_block_attr.0.missing_attr"}, @@ -3444,19 +3444,19 @@ func TestSchemaMap_InternalValidate(t *testing.T) { "ConflictsWith map key syntax with list configuration block existing attribute": { map[string]*Schema{ - "config_block_attr": &Schema{ + "config_block_attr": { Type: TypeList, Optional: true, Elem: &Resource{ Schema: map[string]*Schema{ - "nested_attr": &Schema{ + "nested_attr": { Type: TypeString, Optional: true, }, }, }, }, - "test": &Schema{ + "test": { Type: TypeBool, Optional: true, ConflictsWith: []string{"config_block_attr.nested_attr"}, @@ -3467,12 +3467,12 @@ func TestSchemaMap_InternalValidate(t *testing.T) { "ConflictsWith map key syntax with list configuration block self reference": { map[string]*Schema{ - "config_block_attr": &Schema{ + "config_block_attr": { Type: TypeList, Optional: true, Elem: &Resource{ Schema: map[string]*Schema{ - "nested_attr": &Schema{ + "nested_attr": { Type: TypeString, Optional: true, ConflictsWith: []string{"config_block_attr.nested_attr"}, @@ -3486,19 +3486,19 @@ func TestSchemaMap_InternalValidate(t *testing.T) { "ConflictsWith map key syntax with set configuration block existing attribute": { map[string]*Schema{ - "config_block_attr": &Schema{ + "config_block_attr": { Type: TypeSet, Optional: true, Elem: &Resource{ Schema: map[string]*Schema{ - "nested_attr": &Schema{ + "nested_attr": { Type: TypeString, Optional: true, }, }, }, }, - "test": &Schema{ + "test": { Type: TypeBool, Optional: true, ConflictsWith: []string{"config_block_attr.nested_attr"}, @@ -3509,12 +3509,12 @@ func TestSchemaMap_InternalValidate(t *testing.T) { "ConflictsWith map key syntax with set configuration block self reference": { map[string]*Schema{ - "config_block_attr": &Schema{ + "config_block_attr": { Type: TypeSet, Optional: true, Elem: &Resource{ Schema: map[string]*Schema{ - "nested_attr": &Schema{ + "nested_attr": { Type: TypeString, Optional: true, ConflictsWith: []string{"config_block_attr.nested_attr"}, @@ -3528,12 +3528,12 @@ func TestSchemaMap_InternalValidate(t *testing.T) { "ConflictsWith map key syntax with map attribute": { map[string]*Schema{ - "map_attr": &Schema{ + "map_attr": { Type: TypeMap, Optional: true, Elem: &Schema{Type: TypeString}, }, - "test": &Schema{ + "test": { Type: TypeBool, Optional: true, ConflictsWith: []string{"map_attr.some_key"}, @@ -3544,12 +3544,12 @@ func TestSchemaMap_InternalValidate(t *testing.T) { "ConflictsWith string syntax with map attribute": { map[string]*Schema{ - "map_attr": &Schema{ + "map_attr": { Type: TypeMap, Optional: true, Elem: &Schema{Type: TypeString}, }, - "test": &Schema{ + "test": { Type: TypeBool, Optional: true, ConflictsWith: []string{"map_attr"}, @@ -3560,7 +3560,7 @@ func TestSchemaMap_InternalValidate(t *testing.T) { "ConflictsWith string syntax with self reference": { map[string]*Schema{ - "test": &Schema{ + "test": { Type: TypeBool, Optional: true, ConflictsWith: []string{"test"},