Added supported for ConflictsWith for fields within lists/sets

This commit is contained in:
Brandon Tosch 2017-03-17 19:35:53 -07:00
parent 4294754456
commit 7703d6c595
2 changed files with 48 additions and 3 deletions

View File

@ -1164,16 +1164,35 @@ func (m schemaMap) validateConflictingAttributes(
return nil
}
for _, conflicting_key := range schema.ConflictsWith {
if value, ok := c.Get(conflicting_key); ok {
for _, conflictingKey := range schema.ConflictsWith {
resolvedConflictingKey := resolveConflictingKey(k, conflictingKey)
if value, ok := c.Get(resolvedConflictingKey); ok {
return fmt.Errorf(
"%q: conflicts with %s (%#v)", k, conflicting_key, value)
"%q: conflicts with %s (%#v)", k, resolvedConflictingKey, value)
}
}
return nil
}
//The key we are validating for (k) contains the index for the current list/set item
//Example: list.2.field
//The conflicting key does not contain the index so we must resolve it and add it to the conflicting key
//Example: list.conflictingField needs to become list.2.conflictingField
func resolveConflictingKey(k string, conflictingKey string) string {
if conflictingFieldIndex := strings.LastIndex(conflictingKey, "."); conflictingFieldIndex != -1 {
if parentName := conflictingKey[:conflictingFieldIndex+1]; parentName != "" {
if strings.HasPrefix(strings.ToLower(k), strings.ToLower(parentName)) {
conflictingFieldName := conflictingKey[conflictingFieldIndex+1:]
fieldIndex := strings.LastIndex(k, ".")
return k[:fieldIndex+1] + conflictingFieldName
}
}
}
return conflictingKey
}
func (m schemaMap) validateList(
k string,
raw interface{},

View File

@ -14,6 +14,7 @@ import (
"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/terraform"
"strings"
)
func TestEnvDefaultFunc(t *testing.T) {
@ -5018,6 +5019,31 @@ func TestSchemaSet_ValidateMinItems(t *testing.T) {
}
}
func TestSchema_ResolveConflictingKey(t *testing.T) {
cases := []struct {
Key string
ConflictingKey string
ExpectedResolvedKey string
}{
{"Field", "ConflictField", "ConflictField"},
{"Nested.Field", "Nested.ConflictField", "Nested.ConflictField"},
{"Double.Nested.Field", "Double.Nested.ConflictField", "Double.Nested.ConflictField"},
{"List.0.Field", "List.ConflictingField", "List.0.ConflictingField"},
{"Nested.List.0.Field", "Nested.List.ConflictingField", "Nested.List.0.ConflictingField"},
{"Field", ".G.I.G.O.", ".G.I.G.O."},
{"Field", ".", "."},
{"Field", "", ""},
}
for i, tc := range cases {
actualResolvedKey := resolveConflictingKey(tc.Key, tc.ConflictingKey)
if !strings.EqualFold(actualResolvedKey, tc.ExpectedResolvedKey) {
t.Errorf("%d: expected: %s actual: %s", i, tc.ExpectedResolvedKey, actualResolvedKey)
}
}
}
// errorSort implements sort.Interface to sort errors by their error message
type errorSort []error