@@ -192,9 +192,13 @@ type Schema struct {
192192 //
193193 // AtLeastOneOf is a set of schema keys that, when set, at least one of
194194 // the keys in that list must be specified.
195+ //
196+ // AllOf is a set of schema keys that must be set simultaneously. This
197+ // setting conflicts with ExactlyOneOf or AtLeastOneOf
195198 ConflictsWith []string
196199 ExactlyOneOf []string
197200 AtLeastOneOf []string
201+ AllOf []string
198202
199203 // When Deprecated is set, this attribute is deprecated.
200204 //
@@ -689,6 +693,16 @@ func (m schemaMap) internalValidate(topSchemaMap schemaMap, attrsOnly bool) erro
689693 }
690694 }
691695
696+ if len (v .AllOf ) > 0 {
697+ if len (v .ExactlyOneOf ) > 0 || len (v .AtLeastOneOf ) > 0 {
698+ return fmt .Errorf ("AllOf cannot be used simultaneously with ExactlyOneOf or AtLeastOneOf" )
699+ }
700+ err := checkKeysAgainstSchemaFlags (k , v .AllOf , topSchemaMap )
701+ if err != nil {
702+ return fmt .Errorf ("AllOf: %+v" , err )
703+ }
704+ }
705+
692706 if len (v .ExactlyOneOf ) > 0 {
693707 err := checkKeysAgainstSchemaFlags (k , v .ExactlyOneOf , topSchemaMap )
694708 if err != nil {
@@ -1335,22 +1349,27 @@ func (m schemaMap) validate(
13351349 ok = raw != nil
13361350 }
13371351
1338- err := validateExactlyOneAttribute (k , schema , c )
1352+ if ! ok {
1353+ if schema .Required {
1354+ return nil , []error {fmt .Errorf (
1355+ "%q: required field is not set" , k )}
1356+ }
1357+ return nil , nil
1358+ }
1359+
1360+ err := validateAllOfAttribute (k , schema , c )
13391361 if err != nil {
13401362 return nil , []error {err }
13411363 }
13421364
1343- err = validateAtLeastOneAttribute (k , schema , c )
1365+ err = validateExactlyOneAttribute (k , schema , c )
13441366 if err != nil {
13451367 return nil , []error {err }
13461368 }
13471369
1348- if ! ok {
1349- if schema .Required {
1350- return nil , []error {fmt .Errorf (
1351- "%q: required field is not set" , k )}
1352- }
1353- return nil , nil
1370+ err = validateAtLeastOneAttribute (k , schema , c )
1371+ if err != nil {
1372+ return nil , []error {err }
13541373 }
13551374
13561375 if ! schema .Required && ! schema .Optional {
@@ -1439,6 +1458,27 @@ func removeDuplicates(elements []string) []string {
14391458 return result
14401459}
14411460
1461+ func validateAllOfAttribute (
1462+ k string ,
1463+ schema * Schema ,
1464+ c * terraform.ResourceConfig ) error {
1465+
1466+ if len (schema .AllOf ) == 0 {
1467+ return nil
1468+ }
1469+
1470+ allKeys := removeDuplicates (append (schema .AllOf , k ))
1471+ sort .Strings (allKeys )
1472+
1473+ for _ , allOfKey := range allKeys {
1474+ if _ , ok := c .Get (allOfKey ); ! ok {
1475+ return fmt .Errorf ("%q: all of `%s` must be specified" , k , strings .Join (allKeys , "," ))
1476+ }
1477+ }
1478+
1479+ return nil
1480+ }
1481+
14421482func validateExactlyOneAttribute (
14431483 k string ,
14441484 schema * Schema ,
0 commit comments