Skip to content

Commit 6cca175

Browse files
committed
Update complex constraints to allow interpolation
1 parent f1ca622 commit 6cca175

File tree

2 files changed

+77
-13
lines changed

2 files changed

+77
-13
lines changed

internal/schema/0.12/provisioners.go

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,11 @@ var LocalExecProvisioner = &schema.BodySchema{
8282
},
8383
"interpreter": {
8484
IsOptional: true,
85-
Constraint: schema.List{
86-
Elem: schema.AnyExpression{OfType: cty.String},
85+
Constraint: schema.OneOf{
86+
schema.AnyExpression{OfType: cty.List(cty.String), SkipLiteralComplexTypes: true},
87+
schema.List{
88+
Elem: schema.AnyExpression{OfType: cty.String},
89+
},
8790
},
8891
Description: lang.Markdown("If provided, this is a list of interpreter arguments used to execute " +
8992
"the command. The first argument is the interpreter itself. It can be provided as a relative " +
@@ -117,8 +120,11 @@ var RemoteExecProvisioner = &schema.BodySchema{
117120
Attributes: map[string]*schema.AttributeSchema{
118121
"inline": {
119122
IsOptional: true,
120-
Constraint: schema.List{
121-
Elem: schema.AnyExpression{OfType: cty.String},
123+
Constraint: schema.OneOf{
124+
schema.AnyExpression{OfType: cty.List(cty.String), SkipLiteralComplexTypes: true},
125+
schema.List{
126+
Elem: schema.AnyExpression{OfType: cty.String},
127+
},
122128
},
123129
Description: lang.Markdown("A list of command strings. They are executed in the order they are provided." +
124130
" This cannot be provided with `script` or `scripts`."),
@@ -131,8 +137,11 @@ var RemoteExecProvisioner = &schema.BodySchema{
131137
},
132138
"scripts": {
133139
IsOptional: true,
134-
Constraint: schema.List{
135-
Elem: schema.AnyExpression{OfType: cty.String},
140+
Constraint: schema.OneOf{
141+
schema.AnyExpression{OfType: cty.List(cty.String), SkipLiteralComplexTypes: true},
142+
schema.List{
143+
Elem: schema.AnyExpression{OfType: cty.String},
144+
},
136145
},
137146
Description: lang.Markdown("A list of paths (relative or absolute) to local scripts that will be copied " +
138147
"to the remote resource and then executed. They are executed in the order they are provided." +

schema/convert_json.go

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,27 +195,47 @@ func exprConstraintFromSchemaAttribute(attr *tfjson.SchemaAttribute) schema.Cons
195195
return convertAttributeTypeToConstraint(attr.AttributeType)
196196
}
197197
if attr.AttributeNestedType != nil {
198+
var attrType cty.Type
199+
var cons schema.Constraint
200+
201+
objType := convertJsonAttributesToCtyObject(attr.AttributeNestedType.Attributes)
202+
objectCons := convertJsonAttributesToObjectConstraint(attr.AttributeNestedType.Attributes)
203+
198204
switch attr.AttributeNestedType.NestingMode {
199205
case tfjson.SchemaNestingModeSingle:
200-
return convertJsonAttributesToObjectConstraint(attr.AttributeNestedType.Attributes)
206+
attrType = objType
207+
cons = objectCons
201208
case tfjson.SchemaNestingModeList:
202-
return schema.List{
203-
Elem: convertJsonAttributesToObjectConstraint(attr.AttributeNestedType.Attributes),
209+
attrType = cty.List(objType)
210+
cons = schema.List{
211+
Elem: objectCons,
204212
MinItems: attr.AttributeNestedType.MinItems,
205213
MaxItems: attr.AttributeNestedType.MaxItems,
206214
}
207215
case tfjson.SchemaNestingModeSet:
208-
return schema.Set{
209-
Elem: convertJsonAttributesToObjectConstraint(attr.AttributeNestedType.Attributes),
216+
attrType = cty.Set(objType)
217+
cons = schema.Set{
218+
Elem: objectCons,
210219
MinItems: attr.AttributeNestedType.MinItems,
211220
MaxItems: attr.AttributeNestedType.MaxItems,
212221
}
213222
case tfjson.SchemaNestingModeMap:
214-
return schema.Map{
215-
Elem: convertJsonAttributesToObjectConstraint(attr.AttributeNestedType.Attributes),
223+
attrType = cty.Map(objType)
224+
cons = schema.Map{
225+
Elem: objectCons,
216226
MinItems: attr.AttributeNestedType.MinItems,
217227
MaxItems: attr.AttributeNestedType.MaxItems,
218228
}
229+
default:
230+
return nil
231+
}
232+
233+
return schema.OneOf{
234+
schema.AnyExpression{
235+
OfType: attrType,
236+
SkipLiteralComplexTypes: true,
237+
},
238+
cons,
219239
}
220240
}
221241
return nil
@@ -300,6 +320,41 @@ func convertJsonAttributesToObjectConstraint(attrs map[string]*tfjson.SchemaAttr
300320
}
301321
}
302322

323+
func convertJsonAttributesToCtyObject(attrs map[string]*tfjson.SchemaAttribute) cty.Type {
324+
optional := make([]string, 0)
325+
attributes := make(map[string]cty.Type, 0)
326+
327+
for name, attr := range attrs {
328+
attributes[name] = convertJsonAttributeToCtyType(attr)
329+
if attr.Optional {
330+
optional = append(optional, name)
331+
}
332+
}
333+
334+
return cty.ObjectWithOptionalAttrs(attributes, optional)
335+
}
336+
337+
func convertJsonAttributeToCtyType(attr *tfjson.SchemaAttribute) cty.Type {
338+
if attr.AttributeType != cty.NilType {
339+
return attr.AttributeType
340+
}
341+
if attr.AttributeNestedType != nil {
342+
objType := convertJsonAttributesToCtyObject(attr.AttributeNestedType.Attributes)
343+
344+
switch attr.AttributeNestedType.NestingMode {
345+
case tfjson.SchemaNestingModeSingle:
346+
return objType
347+
case tfjson.SchemaNestingModeList:
348+
return cty.List(objType)
349+
case tfjson.SchemaNestingModeSet:
350+
return cty.Set(objType)
351+
case tfjson.SchemaNestingModeMap:
352+
return cty.Map(objType)
353+
}
354+
}
355+
return cty.NilType
356+
}
357+
303358
func markupContent(value string, kind tfjson.SchemaDescriptionKind) lang.MarkupContent {
304359
if value == "" {
305360
return lang.MarkupContent{}

0 commit comments

Comments
 (0)