@@ -12,10 +12,12 @@ import (
12
12
"strconv"
13
13
14
14
"github.com/google/uuid"
15
+ "github.com/hashicorp/go-cty/cty"
15
16
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
16
17
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
17
18
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
18
19
"github.com/mitchellh/mapstructure"
20
+ "golang.org/x/xerrors"
19
21
)
20
22
21
23
type Option struct {
@@ -26,8 +28,8 @@ type Option struct {
26
28
}
27
29
28
30
type Validation struct {
29
- Min int
30
- Max int
31
+ Min * int
32
+ Max * int
31
33
Monotonic string
32
34
33
35
Regex string
@@ -62,8 +64,18 @@ func parameterDataSource() *schema.Resource {
62
64
ReadContext : func (ctx context.Context , rd * schema.ResourceData , i interface {}) diag.Diagnostics {
63
65
rd .SetId (uuid .NewString ())
64
66
67
+ fixedValidation , err := fixValidationResourceData (rd .GetRawConfig (), rd .Get ("validation" ))
68
+ if err != nil {
69
+ return diag .FromErr (err )
70
+ }
71
+
72
+ err = rd .Set ("validation" , fixedValidation )
73
+ if err != nil {
74
+ return diag .FromErr (err )
75
+ }
76
+
65
77
var parameter Parameter
66
- err : = mapstructure .Decode (struct {
78
+ err = mapstructure .Decode (struct {
67
79
Value interface {}
68
80
Name interface {}
69
81
DisplayName interface {}
@@ -98,7 +110,7 @@ func parameterDataSource() *schema.Resource {
98
110
}(),
99
111
Icon : rd .Get ("icon" ),
100
112
Option : rd .Get ("option" ),
101
- Validation : rd . Get ( "validation" ) ,
113
+ Validation : fixedValidation ,
102
114
Optional : func () bool {
103
115
// This hack allows for checking if the "default" field is present in the .tf file.
104
116
// If "default" is missing or is "null", then it means that this field is required,
@@ -272,17 +284,14 @@ func parameterDataSource() *schema.Resource {
272
284
Elem : & schema.Resource {
273
285
Schema : map [string ]* schema.Schema {
274
286
"min" : {
275
- Type : schema .TypeInt ,
276
- Optional : true ,
277
- Default : 0 ,
278
- Description : "The minimum of a number parameter." ,
279
- RequiredWith : []string {"validation.0.max" },
287
+ Type : schema .TypeInt ,
288
+ Optional : true ,
289
+ Description : "The minimum of a number parameter." ,
280
290
},
281
291
"max" : {
282
- Type : schema .TypeInt ,
283
- Optional : true ,
284
- Description : "The maximum of a number parameter." ,
285
- RequiredWith : []string {"validation.0.min" },
292
+ Type : schema .TypeInt ,
293
+ Optional : true ,
294
+ Description : "The maximum of a number parameter." ,
286
295
},
287
296
"monotonic" : {
288
297
Type : schema .TypeString ,
@@ -325,6 +334,45 @@ func parameterDataSource() *schema.Resource {
325
334
}
326
335
}
327
336
337
+ func fixValidationResourceData (rawConfig cty.Value , validation interface {}) (interface {}, error ) {
338
+ // Read validation from raw config
339
+ rawValidation , ok := rawConfig .AsValueMap ()["validation" ]
340
+ if ! ok {
341
+ return validation , nil // no validation rules, nothing to fix
342
+ }
343
+
344
+ rawValidationArr := rawValidation .AsValueSlice ()
345
+ if len (rawValidationArr ) == 0 {
346
+ return validation , nil // no validation rules, nothing to fix
347
+ }
348
+
349
+ rawValidationRule := rawValidationArr [0 ].AsValueMap ()
350
+
351
+ // Load validation from resource data
352
+ vArr , ok := validation .([]interface {})
353
+ if ! ok {
354
+ return nil , xerrors .New ("validation should be an array" )
355
+ }
356
+
357
+ if len (vArr ) == 0 {
358
+ return validation , nil // no validation rules, nothing to fix
359
+ }
360
+
361
+ validationRule , ok := vArr [0 ].(map [string ]interface {})
362
+ if ! ok {
363
+ return nil , xerrors .New ("validation rule should be a map" )
364
+ }
365
+
366
+ // Fix the resource data
367
+ if rawValidationRule ["min" ].IsNull () {
368
+ validationRule ["min" ] = nil
369
+ }
370
+ if rawValidationRule ["max" ].IsNull () {
371
+ validationRule ["max" ] = nil
372
+ }
373
+ return vArr , nil
374
+ }
375
+
328
376
func valueIsType (typ , value string ) diag.Diagnostics {
329
377
switch typ {
330
378
case "number" :
@@ -353,10 +401,10 @@ func valueIsType(typ, value string) diag.Diagnostics {
353
401
354
402
func (v * Validation ) Valid (typ , value string ) error {
355
403
if typ != "number" {
356
- if v .Min != 0 {
404
+ if v .Min != nil {
357
405
return fmt .Errorf ("a min cannot be specified for a %s type" , typ )
358
406
}
359
- if v .Max != 0 {
407
+ if v .Max != nil {
360
408
return fmt .Errorf ("a max cannot be specified for a %s type" , typ )
361
409
}
362
410
}
@@ -389,10 +437,10 @@ func (v *Validation) Valid(typ, value string) error {
389
437
if err != nil {
390
438
return fmt .Errorf ("value %q is not a number" , value )
391
439
}
392
- if num < v .Min {
440
+ if v . Min != nil && num < * v .Min {
393
441
return fmt .Errorf ("value %d is less than the minimum %d" , num , v .Min )
394
442
}
395
- if num > v .Max {
443
+ if v . Max != nil && num > * v .Max {
396
444
return fmt .Errorf ("value %d is more than the maximum %d" , num , v .Max )
397
445
}
398
446
if v .Monotonic != "" && v .Monotonic != ValidationMonotonicIncreasing && v .Monotonic != ValidationMonotonicDecreasing {
0 commit comments