@@ -223,9 +223,13 @@ type Schema struct {
223223 //
224224 // AtLeastOneOf is a set of schema keys that, when set, at least one of
225225 // the keys in that list must be specified.
226+ //
227+ // AllOf is a set of schema keys that must be set simultaneously. This
228+ // setting conflicts with ExactlyOneOf or AtLeastOneOf
226229 ConflictsWith []string
227230 ExactlyOneOf []string
228231 AtLeastOneOf []string
232+ AllOf []string
229233
230234 // When Deprecated is set, this attribute is deprecated.
231235 //
@@ -773,6 +777,16 @@ func (m schemaMap) internalValidate(topSchemaMap schemaMap, attrsOnly bool) erro
773777 }
774778 }
775779
780+ if len (v .AllOf ) > 0 {
781+ if len (v .ExactlyOneOf ) > 0 || len (v .AtLeastOneOf ) > 0 {
782+ return fmt .Errorf ("AllOf cannot be used simultaneously with ExactlyOneOf or AtLeastOneOf" )
783+ }
784+ err := checkKeysAgainstSchemaFlags (k , v .AllOf , topSchemaMap )
785+ if err != nil {
786+ return fmt .Errorf ("AllOf: %+v" , err )
787+ }
788+ }
789+
776790 if len (v .ExactlyOneOf ) > 0 {
777791 err := checkKeysAgainstSchemaFlags (k , v .ExactlyOneOf , topSchemaMap )
778792 if err != nil {
@@ -1390,22 +1404,27 @@ func (m schemaMap) validate(
13901404 ok = raw != nil
13911405 }
13921406
1393- err := validateExactlyOneAttribute (k , schema , c )
1407+ if ! ok {
1408+ if schema .Required {
1409+ return nil , []error {fmt .Errorf (
1410+ "%q: required field is not set" , k )}
1411+ }
1412+ return nil , nil
1413+ }
1414+
1415+ err := validateAllOfAttribute (k , schema , c )
13941416 if err != nil {
13951417 return nil , []error {err }
13961418 }
13971419
1398- err = validateAtLeastOneAttribute (k , schema , c )
1420+ err = validateExactlyOneAttribute (k , schema , c )
13991421 if err != nil {
14001422 return nil , []error {err }
14011423 }
14021424
1403- if ! ok {
1404- if schema .Required {
1405- return nil , []error {fmt .Errorf (
1406- "%q: required field is not set" , k )}
1407- }
1408- return nil , nil
1425+ err = validateAtLeastOneAttribute (k , schema , c )
1426+ if err != nil {
1427+ return nil , []error {err }
14091428 }
14101429
14111430 if ! schema .Required && ! schema .Optional {
@@ -1494,6 +1513,27 @@ func removeDuplicates(elements []string) []string {
14941513 return result
14951514}
14961515
1516+ func validateAllOfAttribute (
1517+ k string ,
1518+ schema * Schema ,
1519+ c * terraform.ResourceConfig ) error {
1520+
1521+ if len (schema .AllOf ) == 0 {
1522+ return nil
1523+ }
1524+
1525+ allKeys := removeDuplicates (append (schema .AllOf , k ))
1526+ sort .Strings (allKeys )
1527+
1528+ for _ , allOfKey := range allKeys {
1529+ if _ , ok := c .Get (allOfKey ); ! ok {
1530+ return fmt .Errorf ("%q: all of `%s` must be specified" , k , strings .Join (allKeys , "," ))
1531+ }
1532+ }
1533+
1534+ return nil
1535+ }
1536+
14971537func validateExactlyOneAttribute (
14981538 k string ,
14991539 schema * Schema ,
0 commit comments