Skip to content

Commit 9f5fa2a

Browse files
authored
Merge pull request #22530 from hashicorp/jbardin/validations
MinItems and MaxItems validations
2 parents 723fef6 + 13e2e10 commit 9f5fa2a

4 files changed

Lines changed: 10 additions & 20 deletions

File tree

configs/configschema/coerce_value.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ import (
88
)
99

1010
// CoerceValue attempts to force the given value to conform to the type
11-
// implied by the receiever, while also applying the same validation and
12-
// transformation rules that would be applied by the decoder specification
13-
// returned by method DecoderSpec.
11+
// implied by the receiever.
1412
//
1513
// This is useful in situations where a configuration must be derived from
1614
// an already-decoded value. It is always better to decode directly from
@@ -83,16 +81,8 @@ func (b *Block) coerceValue(in cty.Value, path cty.Path) (cty.Value, error) {
8381
if err != nil {
8482
return cty.UnknownVal(b.ImpliedType()), err
8583
}
86-
case blockS.MinItems != 1 && blockS.MaxItems != 1:
87-
if blockS.Nesting == NestingGroup {
88-
attrs[typeName] = blockS.EmptyValue()
89-
} else {
90-
attrs[typeName] = cty.NullVal(blockS.ImpliedType())
91-
}
9284
default:
93-
// We use the word "attribute" here because we're talking about
94-
// the cty sense of that word rather than the HCL sense.
95-
return cty.UnknownVal(b.ImpliedType()), path.NewErrorf("attribute %q is required", typeName)
85+
attrs[typeName] = blockS.EmptyValue()
9686
}
9787

9888
case NestingList:

configs/configschema/coerce_value_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,10 @@ func TestCoerceValue(t *testing.T) {
288288
},
289289
},
290290
cty.EmptyObjectVal,
291-
cty.DynamicVal,
292-
`attribute "foo" is required`,
291+
cty.ObjectVal(map[string]cty.Value{
292+
"foo": cty.NullVal(cty.EmptyObject),
293+
}),
294+
``,
293295
},
294296
"unknown nested list": {
295297
&Block{

configs/configschema/decoder_spec.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ func (b *Block) DecoderSpec() hcldec.Spec {
3535

3636
// We can only validate 0 or 1 for MinItems, because a dynamic block
3737
// may satisfy any number of min items while only having a single
38-
// block in the config.
38+
// block in the config. We cannot validate MaxItems because a
39+
// configuration may have any number of dynamic blocks
3940
minItems := 0
4041
if blockS.MinItems > 1 {
4142
minItems = 1
@@ -46,7 +47,7 @@ func (b *Block) DecoderSpec() hcldec.Spec {
4647
ret[name] = &hcldec.BlockSpec{
4748
TypeName: name,
4849
Nested: childSpec,
49-
Required: blockS.MinItems == 1 && blockS.MaxItems >= 1,
50+
Required: blockS.MinItems == 1,
5051
}
5152
if blockS.Nesting == NestingGroup {
5253
ret[name] = &hcldec.DefaultSpec{
@@ -66,14 +67,12 @@ func (b *Block) DecoderSpec() hcldec.Spec {
6667
TypeName: name,
6768
Nested: childSpec,
6869
MinItems: minItems,
69-
MaxItems: blockS.MaxItems,
7070
}
7171
} else {
7272
ret[name] = &hcldec.BlockListSpec{
7373
TypeName: name,
7474
Nested: childSpec,
7575
MinItems: minItems,
76-
MaxItems: blockS.MaxItems,
7776
}
7877
}
7978
case NestingSet:
@@ -86,7 +85,6 @@ func (b *Block) DecoderSpec() hcldec.Spec {
8685
TypeName: name,
8786
Nested: childSpec,
8887
MinItems: minItems,
89-
MaxItems: blockS.MaxItems,
9088
}
9189
case NestingMap:
9290
// We prefer to use a list where possible, since it makes our

configs/configschema/decoder_spec_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ func TestBlockDecoderSpec(t *testing.T) {
354354
cty.EmptyObjectVal,
355355
}),
356356
}),
357-
1, // too many "foo" blocks
357+
0, // max items cannot be validated during decode
358358
},
359359
// dynamic blocks may fulfill MinItems, but there is only one block to
360360
// decode.

0 commit comments

Comments
 (0)