55 "fmt"
66 "net/url"
77 "os"
8+ "regexp"
89 "strconv"
910
1011 "github.com/google/uuid"
@@ -37,6 +38,49 @@ func parameterDataSource() *schema.Resource {
3738 }
3839 rd .Set ("value" , value )
3940
41+ rawValidation , exists := rd .GetOk ("validation" )
42+ var (
43+ validationRegex string
44+ validationMin int
45+ validationMax int
46+ )
47+ if exists {
48+ validationArray , valid := rawValidation .([]interface {})
49+ if ! valid {
50+ return diag .Errorf ("validation is of wrong type %T" , rawValidation )
51+ }
52+ validation , valid := validationArray [0 ].(map [string ]interface {})
53+ if ! valid {
54+ return diag .Errorf ("validation is of wrong type %T" , validation )
55+ }
56+ rawRegex , ok := validation ["regex" ]
57+ if ok {
58+ validationRegex , ok = rawRegex .(string )
59+ if ! ok {
60+ return diag .Errorf ("validation regex is of wrong type %T" , rawRegex )
61+ }
62+ }
63+ rawMin , ok := validation ["min" ]
64+ if ok {
65+ validationMin , ok = rawMin .(int )
66+ if ! ok {
67+ return diag .Errorf ("validation min is wrong type %T" , rawMin )
68+ }
69+ }
70+ rawMax , ok := validation ["max" ]
71+ if ok {
72+ validationMax , ok = rawMax .(int )
73+ if ! ok {
74+ return diag .Errorf ("validation max is wrong type %T" , rawMax )
75+ }
76+ }
77+ }
78+
79+ err := ValueValidatesType (typ , value , validationRegex , validationMin , validationMax )
80+ if err != nil {
81+ return diag .FromErr (err )
82+ }
83+
4084 rawOptions , exists := rd .GetOk ("option" )
4185 if exists {
4286 rawArrayOptions , valid := rawOptions .([]interface {})
@@ -91,28 +135,30 @@ func parameterDataSource() *schema.Resource {
91135 "value" : {
92136 Type : schema .TypeString ,
93137 Computed : true ,
94- Description : "The output value of a parameter." ,
138+ Description : "The output value of the parameter." ,
95139 },
96140 "name" : {
97141 Type : schema .TypeString ,
98142 Required : true ,
99- Description : "The name of the parameter as it appears in the interface. If this is changed, the parameter will need to be re-updated by developers ." ,
143+ Description : "The name of the parameter as it will appear in the interface. If this is changed, developers will be re-prompted for a new value ." ,
100144 },
101145 "description" : {
102146 Type : schema .TypeString ,
103147 Optional : true ,
104- Description : "Explain what the parameter does." ,
148+ Description : "Describe what this parameter does." ,
105149 },
106150 "type" : {
107151 Type : schema .TypeString ,
108152 Default : "string" ,
109153 Optional : true ,
110154 ValidateFunc : validation .StringInSlice ([]string {"number" , "string" , "bool" }, false ),
155+ Description : `The type of this parameter. Must be one of: "number", "string", or "bool".` ,
111156 },
112157 "immutable" : {
113158 Type : schema .TypeBool ,
114159 Optional : true ,
115- Description : "Whether the value can be changed after it's set initially." ,
160+ Default : true ,
161+ Description : "Whether this value can be changed after workspace creation. This can be destructive for values like region, so use with caution!" ,
116162 },
117163 "default" : {
118164 Type : schema .TypeString ,
@@ -136,11 +182,12 @@ func parameterDataSource() *schema.Resource {
136182 },
137183 },
138184 "option" : {
139- Type : schema .TypeList ,
140- Description : "Each \" option\" block defines a single displayable value for a user to select." ,
141- ForceNew : true ,
142- Optional : true ,
143- MaxItems : 64 ,
185+ Type : schema .TypeList ,
186+ Description : "Each \" option\" block defines a value for a user to select from." ,
187+ ForceNew : true ,
188+ Optional : true ,
189+ MaxItems : 64 ,
190+ ConflictsWith : []string {"validation" },
144191 Elem : & schema.Resource {
145192 Schema : map [string ]* schema.Schema {
146193 "name" : {
@@ -151,13 +198,13 @@ func parameterDataSource() *schema.Resource {
151198 },
152199 "description" : {
153200 Type : schema .TypeString ,
154- Description : "Add a description to select this item ." ,
201+ Description : "Describe what selecting this value does ." ,
155202 ForceNew : true ,
156203 Optional : true ,
157204 },
158205 "value" : {
159206 Type : schema .TypeString ,
160- Description : "The value of this option." ,
207+ Description : "The value of this option set on the parameter if selected ." ,
161208 ForceNew : true ,
162209 Required : true ,
163210 },
@@ -180,26 +227,31 @@ func parameterDataSource() *schema.Resource {
180227 },
181228 },
182229 "validation" : {
183- Type : schema .TypeSet ,
184- MaxItems : 1 ,
185- Optional : true ,
230+ Type : schema .TypeList ,
231+ MaxItems : 1 ,
232+ Optional : true ,
233+ Description : "Validate the input of a parameter." ,
234+ ConflictsWith : []string {"option" },
186235 Elem : & schema.Resource {
187236 Schema : map [string ]* schema.Schema {
188237 "min" : {
189- Type : schema .TypeInt ,
190- Optional : true ,
191- Default : 0 ,
192- Description : "The minimum for a number to be." ,
238+ Type : schema .TypeInt ,
239+ Optional : true ,
240+ Default : 0 ,
241+ Description : "The minimum of a number parameter." ,
242+ RequiredWith : []string {"validation.0.max" },
193243 },
194244 "max" : {
195- Type : schema .TypeInt ,
196- Optional : true ,
197- Description : "The maximum for a number to be." ,
245+ Type : schema .TypeInt ,
246+ Optional : true ,
247+ Description : "The maximum of a number parameter." ,
248+ RequiredWith : []string {"validation.0.min" },
198249 },
199250 "regex" : {
200- Type : schema .TypeString ,
201- ExactlyOneOf : []string {"min" , "max" },
202- Optional : true ,
251+ Type : schema .TypeString ,
252+ ConflictsWith : []string {"validation.0.min" , "validation.0.max" },
253+ Description : "A regex for the input parameter to match against." ,
254+ Optional : true ,
203255 },
204256 },
205257 },
@@ -227,3 +279,45 @@ func valueIsType(typ, value string) diag.Diagnostics {
227279 }
228280 return nil
229281}
282+
283+ func ValueValidatesType (typ , value , regex string , min , max int ) error {
284+ if typ != "number" {
285+ if min != 0 {
286+ return fmt .Errorf ("a min cannot be specified for a %s type" , typ )
287+ }
288+ if max != 0 {
289+ return fmt .Errorf ("a max cannot be specified for a %s type" , typ )
290+ }
291+ }
292+ if typ != "string" && regex != "" {
293+ return fmt .Errorf ("a regex cannot be specified for a %s type" , typ )
294+ }
295+ switch typ {
296+ case "bool" :
297+ return nil
298+ case "string" :
299+ if regex == "" {
300+ return nil
301+ }
302+ regex , err := regexp .Compile (regex )
303+ if err != nil {
304+ return fmt .Errorf ("compile regex %q: %s" , regex , err )
305+ }
306+ matched := regex .MatchString (value )
307+ if ! matched {
308+ return fmt .Errorf ("value %q does not match %q" , value , regex )
309+ }
310+ case "number" :
311+ num , err := strconv .Atoi (value )
312+ if err != nil {
313+ return fmt .Errorf ("parse value %s as int: %s" , value , err )
314+ }
315+ if num < min {
316+ return fmt .Errorf ("provided value %d is less than the minimum %d" , num , min )
317+ }
318+ if num > max {
319+ return fmt .Errorf ("provided value %d is more than the maximum %d" , num , max )
320+ }
321+ }
322+ return nil
323+ }
0 commit comments