objects vs maps in nested object types
When using NestedMap objects, unify the codepath for both maps and objects as they may be interchangeable.
This commit is contained in:
parent
7ca6be8285
commit
903797084a
|
@ -368,71 +368,46 @@ func assertPlannedObjectValid(schema *configschema.Object, prior, config, planne
|
|||
|
||||
case configschema.NestingMap:
|
||||
// A NestingMap might either be a map or an object, depending on
|
||||
// whether there are dynamically-typed attributes inside, but
|
||||
// that's decided statically and so all values will have the same
|
||||
// kind.
|
||||
if planned.Type().IsObjectType() {
|
||||
plannedAtys := planned.Type().AttributeTypes()
|
||||
configAtys := config.Type().AttributeTypes()
|
||||
for k := range plannedAtys {
|
||||
if _, ok := configAtys[k]; !ok {
|
||||
errs = append(errs, path.NewErrorf("block key %q from plan is not present in config", k))
|
||||
continue
|
||||
}
|
||||
path := append(path, cty.GetAttrStep{Name: k})
|
||||
// whether there are dynamically-typed attributes inside, so we will
|
||||
// break these down to maps to handle them both in the same manner.
|
||||
plannedVals := map[string]cty.Value{}
|
||||
configVals := map[string]cty.Value{}
|
||||
priorVals := map[string]cty.Value{}
|
||||
|
||||
plannedEV := planned.GetAttr(k)
|
||||
if !plannedEV.IsKnown() {
|
||||
errs = append(errs, path.NewErrorf("element representing nested block must not be unknown itself; set nested attribute values to unknown instead"))
|
||||
continue
|
||||
}
|
||||
configEV := config.GetAttr(k)
|
||||
priorEV := cty.NullVal(schema.ImpliedType())
|
||||
if !prior.IsNull() && prior.Type().HasAttribute(k) {
|
||||
priorEV = prior.GetAttr(k)
|
||||
}
|
||||
moreErrs := assertPlannedAttrsValid(schema.Attributes, priorEV, configEV, plannedEV, path)
|
||||
errs = append(errs, moreErrs...)
|
||||
if !planned.IsNull() {
|
||||
plannedVals = planned.AsValueMap()
|
||||
}
|
||||
if !config.IsNull() {
|
||||
configVals = config.AsValueMap()
|
||||
}
|
||||
if !prior.IsNull() {
|
||||
priorVals = prior.AsValueMap()
|
||||
}
|
||||
|
||||
for k, plannedEV := range plannedVals {
|
||||
configEV, ok := configVals[k]
|
||||
if !ok {
|
||||
errs = append(errs, path.NewErrorf("block key %q from plan is not present in config", k))
|
||||
continue
|
||||
}
|
||||
for k := range configAtys {
|
||||
if _, ok := plannedAtys[k]; !ok {
|
||||
errs = append(errs, path.NewErrorf("block key %q from config is not present in plan", k))
|
||||
continue
|
||||
}
|
||||
path := append(path, cty.GetAttrStep{Name: k})
|
||||
|
||||
if !plannedEV.IsKnown() {
|
||||
errs = append(errs, path.NewErrorf("element representing nested block must not be unknown itself; set nested attribute values to unknown instead"))
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
plannedL := planned.LengthInt()
|
||||
configL := config.LengthInt()
|
||||
if plannedL != configL {
|
||||
errs = append(errs, path.NewErrorf("block count in plan (%d) disagrees with count in config (%d)", plannedL, configL))
|
||||
return errs
|
||||
|
||||
priorEV, ok := priorVals[k]
|
||||
if !ok {
|
||||
priorEV = cty.NullVal(schema.ImpliedType())
|
||||
}
|
||||
for it := planned.ElementIterator(); it.Next(); {
|
||||
idx, plannedEV := it.Element()
|
||||
path := append(path, cty.IndexStep{Key: idx})
|
||||
if !plannedEV.IsKnown() {
|
||||
errs = append(errs, path.NewErrorf("element representing nested block must not be unknown itself; set nested attribute values to unknown instead"))
|
||||
continue
|
||||
}
|
||||
k := idx.AsString()
|
||||
if !config.HasIndex(idx).True() {
|
||||
errs = append(errs, path.NewErrorf("block key %q from plan is not present in config", k))
|
||||
continue
|
||||
}
|
||||
configEV := config.Index(idx)
|
||||
priorEV := cty.NullVal(schema.ImpliedType())
|
||||
if !prior.IsNull() && prior.HasIndex(idx).True() {
|
||||
priorEV = prior.Index(idx)
|
||||
}
|
||||
moreErrs := assertPlannedAttrsValid(schema.Attributes, priorEV, configEV, plannedEV, path)
|
||||
errs = append(errs, moreErrs...)
|
||||
}
|
||||
for it := config.ElementIterator(); it.Next(); {
|
||||
idx, _ := it.Element()
|
||||
if !planned.HasIndex(idx).True() {
|
||||
errs = append(errs, path.NewErrorf("block key %q from config is not present in plan", idx.AsString()))
|
||||
continue
|
||||
}
|
||||
moreErrs := assertPlannedAttrsValid(schema.Attributes, priorEV, configEV, plannedEV, path)
|
||||
errs = append(errs, moreErrs...)
|
||||
}
|
||||
for k := range configVals {
|
||||
if _, ok := plannedVals[k]; !ok {
|
||||
errs = append(errs, path.NewErrorf("block key %q from config is not present in plan", k))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1307,7 +1307,7 @@ func TestAssertPlanValid(t *testing.T) {
|
|||
"name": cty.NullVal(cty.String),
|
||||
}),
|
||||
}),
|
||||
"map_as_obj": cty.ObjectVal(map[string]cty.Value{
|
||||
"map_as_obj": cty.MapVal(map[string]cty.Value{
|
||||
"one": cty.ObjectVal(map[string]cty.Value{
|
||||
"name": cty.NullVal(cty.DynamicPseudoType),
|
||||
}),
|
||||
|
|
Loading…
Reference in New Issue