Merge pull request #37923 from hashicorp/jbardin/nesting-group-schema-fixes

fix handling of NestingGroup in the configschema package
pull/37941/head
James Bardin 3 months ago committed by GitHub
commit 6ed7151b2c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -73,6 +73,14 @@ func (b *Block) coerceValue(in cty.Value, path cty.Path) (cty.Value, error) {
return cty.UnknownVal(impliedType), path.NewErrorf("attribute %q has none of required, optional, or computed set", name)
}
// check for NestingGroup which cannot be null
if attrS.NestedType != nil && attrS.NestedType.Nesting == NestingGroup && val.IsNull() {
// we can cheat here and use EmptyValue to get a "zero" value
// object, and expect the conversion to turn out the correct final
// object type
val = cty.EmptyObjectVal
}
val, err := convert.Convert(val, attrConvType)
if err != nil {
return cty.UnknownVal(impliedType), append(path, cty.GetAttrStep{Name: name}).NewError(err)

@ -616,6 +616,54 @@ func TestCoerceValue(t *testing.T) {
}),
``,
},
"nested type nulls": {
// handle NestedTypes with null
&Block{
Attributes: map[string]*Attribute{
"foo": {
NestedType: &Object{
Nesting: NestingSingle,
Attributes: map[string]*Attribute{
"bar": {Type: cty.DynamicPseudoType, Optional: true},
"baz": {Type: cty.DynamicPseudoType, Optional: true},
},
},
Optional: true,
},
"fob": {
NestedType: &Object{
Nesting: NestingGroup,
Attributes: map[string]*Attribute{
"bar": {Type: cty.DynamicPseudoType, Optional: true},
"baz": {Type: cty.DynamicPseudoType, Computed: true},
},
},
Optional: true,
},
},
},
cty.ObjectVal(map[string]cty.Value{
"foo": cty.ObjectVal(map[string]cty.Value{
"bar": cty.StringVal("test"),
"baz": cty.NullVal(cty.Number),
}),
"fob": cty.ObjectVal(map[string]cty.Value{
"bar": cty.NullVal(cty.String),
"baz": cty.NullVal(cty.Number),
}),
}),
cty.ObjectVal(map[string]cty.Value{
"foo": cty.ObjectVal(map[string]cty.Value{
"bar": cty.StringVal("test"),
"baz": cty.NullVal(cty.Number),
}),
"fob": cty.ObjectVal(map[string]cty.Value{
"bar": cty.NullVal(cty.String),
"baz": cty.NullVal(cty.Number),
}),
}),
``,
},
}
for name, test := range tests {
@ -633,7 +681,6 @@ func TestCoerceValue(t *testing.T) {
}
return
}
if !gotValue.RawEquals(test.WantValue) {
t.Errorf("wrong result\ninput: %#v\ngot: %#v\nwant: %#v", test.Input, gotValue, test.WantValue)
}

@ -138,8 +138,9 @@ func (o *Object) specType() cty.Type {
} else {
ret = cty.Object(attrTys)
}
switch o.Nesting {
case NestingSingle:
case NestingSingle, NestingGroup:
return ret
case NestingList:
return cty.List(ret)

@ -316,6 +316,25 @@ func TestObjectImpliedType(t *testing.T) {
},
),
},
"nesting-group-attributes": {
&Object{
Nesting: NestingGroup,
Attributes: map[string]*Attribute{
"optional": {Type: cty.String, Optional: true},
"required": {Type: cty.Number, Required: true},
"computed": {Type: cty.List(cty.Bool), Computed: true},
"optional_computed": {Type: cty.Map(cty.Bool), Optional: true, Computed: true},
},
},
cty.Object(
map[string]cty.Type{
"optional": cty.String,
"required": cty.Number,
"computed": cty.List(cty.Bool),
"optional_computed": cty.Map(cty.Bool),
},
),
},
"nested attributes": {
&Object{
Nesting: NestingSingle,

Loading…
Cancel
Save