Merge branch 'fix-field-reader-setsubkeys-computed' of https://github.com/vancluever/terraform into vancluever-fix-field-reader-setsubkeys-computed
This commit is contained in:
commit
f2fcf1494a
|
@ -270,12 +270,30 @@ func (r *ConfigFieldReader) hasComputedSubKeys(key string, schema *Schema) bool
|
|||
switch t := schema.Elem.(type) {
|
||||
case *Resource:
|
||||
for k, schema := range t.Schema {
|
||||
if r.Config.IsComputed(prefix + k) {
|
||||
addr := prefix + k
|
||||
if r.Config.IsComputed(addr) {
|
||||
return true
|
||||
}
|
||||
|
||||
if r.hasComputedSubKeys(prefix+k, schema) {
|
||||
return true
|
||||
// We need to loop into sets and lists to ensure we pass the correct
|
||||
// address to the raw config - otherwise for sets we get something like
|
||||
// set.0.set.item instead of set.0.set.0.item, which renders an
|
||||
// inaccurate result.
|
||||
if schema.Type == TypeSet || schema.Type == TypeList {
|
||||
raw, err := readListField(&nestedConfigFieldReader{r}, strings.Split(addr, "."), schema)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("readListField failed when field was supposed to be list-like: %v", err))
|
||||
}
|
||||
// Just range into the address space here, we don't need the value.
|
||||
for i := range raw.Value.([]interface{}) {
|
||||
if r.hasComputedSubKeys(addr+"."+strconv.Itoa(i), schema) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if r.hasComputedSubKeys(addr, schema) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3267,6 +3267,159 @@ func TestSchemaMap_DiffSuppress(t *testing.T) {
|
|||
|
||||
Err: false,
|
||||
},
|
||||
|
||||
"Complex structure with set of computed string should mark root set as computed": {
|
||||
Schema: map[string]*Schema{
|
||||
"outer": &Schema{
|
||||
Type: TypeSet,
|
||||
Optional: true,
|
||||
Elem: &Resource{
|
||||
Schema: map[string]*Schema{
|
||||
"outer_str": &Schema{
|
||||
Type: TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"inner": &Schema{
|
||||
Type: TypeSet,
|
||||
Optional: true,
|
||||
Elem: &Resource{
|
||||
Schema: map[string]*Schema{
|
||||
"inner_str": &Schema{
|
||||
Type: TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
Set: func(v interface{}) int {
|
||||
return 2
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Set: func(v interface{}) int {
|
||||
return 1
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
State: nil,
|
||||
|
||||
Config: map[string]interface{}{
|
||||
"outer": []map[string]interface{}{
|
||||
map[string]interface{}{
|
||||
"outer_str": "foo",
|
||||
"inner": []map[string]interface{}{
|
||||
map[string]interface{}{
|
||||
"inner_str": "${var.bar}",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
ConfigVariables: map[string]ast.Variable{
|
||||
"var.bar": interfaceToVariableSwallowError(config.UnknownVariableValue),
|
||||
},
|
||||
|
||||
ExpectedDiff: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"outer.#": &terraform.ResourceAttrDiff{
|
||||
Old: "0",
|
||||
New: "1",
|
||||
},
|
||||
"outer.~1.outer_str": &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "foo",
|
||||
},
|
||||
"outer.~1.inner.#": &terraform.ResourceAttrDiff{
|
||||
Old: "0",
|
||||
New: "1",
|
||||
},
|
||||
"outer.~1.inner.~2.inner_str": &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "${var.bar}",
|
||||
NewComputed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Err: false,
|
||||
},
|
||||
|
||||
"Complex structure with complex list of computed string should mark root set as computed": {
|
||||
Schema: map[string]*Schema{
|
||||
"outer": &Schema{
|
||||
Type: TypeSet,
|
||||
Optional: true,
|
||||
Elem: &Resource{
|
||||
Schema: map[string]*Schema{
|
||||
"outer_str": &Schema{
|
||||
Type: TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"inner": &Schema{
|
||||
Type: TypeList,
|
||||
Optional: true,
|
||||
Elem: &Resource{
|
||||
Schema: map[string]*Schema{
|
||||
"inner_str": &Schema{
|
||||
Type: TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Set: func(v interface{}) int {
|
||||
return 1
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
State: nil,
|
||||
|
||||
Config: map[string]interface{}{
|
||||
"outer": []map[string]interface{}{
|
||||
map[string]interface{}{
|
||||
"outer_str": "foo",
|
||||
"inner": []map[string]interface{}{
|
||||
map[string]interface{}{
|
||||
"inner_str": "${var.bar}",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
ConfigVariables: map[string]ast.Variable{
|
||||
"var.bar": interfaceToVariableSwallowError(config.UnknownVariableValue),
|
||||
},
|
||||
|
||||
ExpectedDiff: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"outer.#": &terraform.ResourceAttrDiff{
|
||||
Old: "0",
|
||||
New: "1",
|
||||
},
|
||||
"outer.~1.outer_str": &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "foo",
|
||||
},
|
||||
"outer.~1.inner.#": &terraform.ResourceAttrDiff{
|
||||
Old: "0",
|
||||
New: "1",
|
||||
},
|
||||
"outer.~1.inner.0.inner_str": &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "${var.bar}",
|
||||
NewComputed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Err: false,
|
||||
},
|
||||
}
|
||||
|
||||
for tn, tc := range cases {
|
||||
|
|
Loading…
Reference in New Issue