@@ -12,10 +12,12 @@ import (
1212 "strconv"
1313
1414 "github.com/google/uuid"
15+ "github.com/hashicorp/go-cty/cty"
1516 "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1617 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1718 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1819 "github.com/mitchellh/mapstructure"
20+ "golang.org/x/xerrors"
1921)
2022
2123type Option struct {
@@ -26,8 +28,8 @@ type Option struct {
2628}
2729
2830type Validation struct {
29- Min int
30- Max int
31+ Min * int
32+ Max * int
3133 Monotonic string
3234
3335 Regex string
@@ -62,8 +64,18 @@ func parameterDataSource() *schema.Resource {
6264 ReadContext : func (ctx context.Context , rd * schema.ResourceData , i interface {}) diag.Diagnostics {
6365 rd .SetId (uuid .NewString ())
6466
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+
6577 var parameter Parameter
66- err : = mapstructure .Decode (struct {
78+ err = mapstructure .Decode (struct {
6779 Value interface {}
6880 Name interface {}
6981 DisplayName interface {}
@@ -98,7 +110,7 @@ func parameterDataSource() *schema.Resource {
98110 }(),
99111 Icon : rd .Get ("icon" ),
100112 Option : rd .Get ("option" ),
101- Validation : rd . Get ( "validation" ) ,
113+ Validation : fixedValidation ,
102114 Optional : func () bool {
103115 // This hack allows for checking if the "default" field is present in the .tf file.
104116 // If "default" is missing or is "null", then it means that this field is required,
@@ -272,17 +284,14 @@ func parameterDataSource() *schema.Resource {
272284 Elem : & schema.Resource {
273285 Schema : map [string ]* schema.Schema {
274286 "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." ,
280290 },
281291 "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." ,
286295 },
287296 "monotonic" : {
288297 Type : schema .TypeString ,
@@ -325,6 +334,45 @@ func parameterDataSource() *schema.Resource {
325334 }
326335}
327336
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+
328376func valueIsType (typ , value string ) diag.Diagnostics {
329377 switch typ {
330378 case "number" :
@@ -353,10 +401,10 @@ func valueIsType(typ, value string) diag.Diagnostics {
353401
354402func (v * Validation ) Valid (typ , value string ) error {
355403 if typ != "number" {
356- if v .Min != 0 {
404+ if v .Min != nil {
357405 return fmt .Errorf ("a min cannot be specified for a %s type" , typ )
358406 }
359- if v .Max != 0 {
407+ if v .Max != nil {
360408 return fmt .Errorf ("a max cannot be specified for a %s type" , typ )
361409 }
362410 }
@@ -389,10 +437,10 @@ func (v *Validation) Valid(typ, value string) error {
389437 if err != nil {
390438 return fmt .Errorf ("value %q is not a number" , value )
391439 }
392- if num < v .Min {
440+ if v . Min != nil && num < * v .Min {
393441 return fmt .Errorf ("value %d is less than the minimum %d" , num , v .Min )
394442 }
395- if num > v .Max {
443+ if v . Max != nil && num > * v .Max {
396444 return fmt .Errorf ("value %d is more than the maximum %d" , num , v .Max )
397445 }
398446 if v .Monotonic != "" && v .Monotonic != ValidationMonotonicIncreasing && v .Monotonic != ValidationMonotonicDecreasing {
0 commit comments