Merge pull request #29563 from hashicorp/jbardin/optional-computed-nested-objects

remove incorrect computed check
This commit is contained in:
James Bardin 2021-09-10 15:47:03 -04:00 committed by GitHub
commit 16e8bf028a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 185 additions and 14 deletions

View File

@ -286,11 +286,6 @@ func assertPlannedValueValid(attrS *configschema.Attribute, priorV, configV, pla
}
return errs
}
} else {
if attrS.Computed {
errs = append(errs, path.NewErrorf("configuration present for computed attribute"))
return errs
}
}
// If this attribute has a NestedType, validate the nested object

View File

@ -1387,6 +1387,7 @@ func TestAssertPlanValid(t *testing.T) {
},
},
},
Optional: true,
Computed: true,
},
"single": {
@ -1423,9 +1424,11 @@ func TestAssertPlanValid(t *testing.T) {
"list": cty.NullVal(cty.List(cty.Object(map[string]cty.Type{
"name": cty.String,
}))),
"set": cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{
"name": cty.String,
}))),
"set": cty.SetVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"name": cty.StringVal("from_config"),
}),
}),
"single": cty.NullVal(cty.Object(map[string]cty.Type{
"name": cty.String,
})),
@ -1437,14 +1440,14 @@ func TestAssertPlanValid(t *testing.T) {
})),
}),
"list": cty.ListVal([]cty.Value{
cty.UnknownVal(cty.Object(map[string]cty.Type{
"name": cty.String,
})),
cty.ObjectVal(map[string]cty.Value{
"name": cty.StringVal("computed"),
}),
}),
"set": cty.SetVal([]cty.Value{
cty.UnknownVal(cty.Object(map[string]cty.Type{
"name": cty.String,
})),
cty.ObjectVal(map[string]cty.Value{
"name": cty.StringVal("from_config"),
}),
}),
"single": cty.UnknownVal(cty.Object(map[string]cty.Type{
"name": cty.String,
@ -1452,6 +1455,179 @@ func TestAssertPlanValid(t *testing.T) {
}),
nil,
},
"optional computed within nested objects": {
&configschema.Block{
Attributes: map[string]*configschema.Attribute{
"map": {
NestedType: &configschema.Object{
Nesting: configschema.NestingMap,
Attributes: map[string]*configschema.Attribute{
"name": {
Type: cty.String,
Computed: true,
},
},
},
},
// When an object has dynamic attrs, the map may be
// handled as an object.
"map_as_obj": {
NestedType: &configschema.Object{
Nesting: configschema.NestingMap,
Attributes: map[string]*configschema.Attribute{
"name": {
Type: cty.String,
Optional: true,
Computed: true,
},
},
},
},
"list": {
NestedType: &configschema.Object{
Nesting: configschema.NestingList,
Attributes: map[string]*configschema.Attribute{
"name": {
Type: cty.String,
Optional: true,
Computed: true,
},
},
},
},
"set": {
NestedType: &configschema.Object{
Nesting: configschema.NestingSet,
Attributes: map[string]*configschema.Attribute{
"name": {
Type: cty.String,
Optional: true,
Computed: true,
},
},
},
},
"single": {
NestedType: &configschema.Object{
Nesting: configschema.NestingSingle,
Attributes: map[string]*configschema.Attribute{
"name": {
Type: cty.DynamicPseudoType,
Optional: true,
Computed: true,
},
},
},
},
},
},
cty.NullVal(cty.Object(map[string]cty.Type{
"map": cty.Map(cty.Object(map[string]cty.Type{
"name": cty.String,
})),
"map_as_obj": cty.Map(cty.Object(map[string]cty.Type{
"name": cty.DynamicPseudoType,
})),
"list": cty.List(cty.Object(map[string]cty.Type{
"name": cty.String,
})),
"set": cty.Set(cty.Object(map[string]cty.Type{
"name": cty.String,
})),
"single": cty.Object(map[string]cty.Type{
"name": cty.String,
}),
})),
cty.ObjectVal(map[string]cty.Value{
"map": cty.MapVal(map[string]cty.Value{
"one": cty.ObjectVal(map[string]cty.Value{
"name": cty.StringVal("from_config"),
}),
}),
"map_as_obj": cty.MapVal(map[string]cty.Value{
"one": cty.ObjectVal(map[string]cty.Value{
"name": cty.NullVal(cty.DynamicPseudoType),
}),
}),
"list": cty.ListVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"name": cty.NullVal(cty.String),
}),
}),
"set": cty.SetVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"name": cty.NullVal(cty.String),
}),
}),
"single": cty.ObjectVal(map[string]cty.Value{
"name": cty.StringVal("from_config"),
}),
}),
cty.ObjectVal(map[string]cty.Value{
"map": cty.MapVal(map[string]cty.Value{
"one": cty.ObjectVal(map[string]cty.Value{
"name": cty.StringVal("from_config"),
}),
}),
"map_as_obj": cty.ObjectVal(map[string]cty.Value{
"one": cty.ObjectVal(map[string]cty.Value{
"name": cty.StringVal("computed"),
}),
}),
"list": cty.ListVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"name": cty.StringVal("computed"),
}),
}),
"set": cty.SetVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"name": cty.NullVal(cty.String),
}),
}),
"single": cty.ObjectVal(map[string]cty.Value{
"name": cty.StringVal("from_config"),
}),
}),
nil,
},
"cannot replace config nested attr": {
&configschema.Block{
Attributes: map[string]*configschema.Attribute{
"map": {
NestedType: &configschema.Object{
Nesting: configschema.NestingMap,
Attributes: map[string]*configschema.Attribute{
"name": {
Type: cty.String,
Computed: true,
Optional: true,
},
},
},
},
},
},
cty.NullVal(cty.Object(map[string]cty.Type{
"map": cty.Map(cty.Object(map[string]cty.Type{
"name": cty.String,
})),
})),
cty.ObjectVal(map[string]cty.Value{
"map": cty.MapVal(map[string]cty.Value{
"one": cty.ObjectVal(map[string]cty.Value{
"name": cty.StringVal("from_config"),
}),
}),
}),
cty.ObjectVal(map[string]cty.Value{
"map": cty.MapVal(map[string]cty.Value{
"one": cty.ObjectVal(map[string]cty.Value{
"name": cty.StringVal("from_provider"),
}),
}),
}),
[]string{`.map.one.name: planned value cty.StringVal("from_provider") does not match config value cty.StringVal("from_config")`},
},
}
for name, test := range tests {