5
5
"fmt"
6
6
"net/url"
7
7
"os"
8
+ "regexp"
8
9
"strconv"
9
10
10
11
"github.com/google/uuid"
@@ -37,6 +38,49 @@ func parameterDataSource() *schema.Resource {
37
38
}
38
39
rd .Set ("value" , value )
39
40
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
+
40
84
rawOptions , exists := rd .GetOk ("option" )
41
85
if exists {
42
86
rawArrayOptions , valid := rawOptions .([]interface {})
@@ -91,28 +135,30 @@ func parameterDataSource() *schema.Resource {
91
135
"value" : {
92
136
Type : schema .TypeString ,
93
137
Computed : true ,
94
- Description : "The output value of a parameter." ,
138
+ Description : "The output value of the parameter." ,
95
139
},
96
140
"name" : {
97
141
Type : schema .TypeString ,
98
142
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 ." ,
100
144
},
101
145
"description" : {
102
146
Type : schema .TypeString ,
103
147
Optional : true ,
104
- Description : "Explain what the parameter does." ,
148
+ Description : "Describe what this parameter does." ,
105
149
},
106
150
"type" : {
107
151
Type : schema .TypeString ,
108
152
Default : "string" ,
109
153
Optional : true ,
110
154
ValidateFunc : validation .StringInSlice ([]string {"number" , "string" , "bool" }, false ),
155
+ Description : `The type of this parameter. Must be one of: "number", "string", or "bool".` ,
111
156
},
112
157
"immutable" : {
113
158
Type : schema .TypeBool ,
114
159
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!" ,
116
162
},
117
163
"default" : {
118
164
Type : schema .TypeString ,
@@ -136,11 +182,12 @@ func parameterDataSource() *schema.Resource {
136
182
},
137
183
},
138
184
"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" },
144
191
Elem : & schema.Resource {
145
192
Schema : map [string ]* schema.Schema {
146
193
"name" : {
@@ -151,13 +198,13 @@ func parameterDataSource() *schema.Resource {
151
198
},
152
199
"description" : {
153
200
Type : schema .TypeString ,
154
- Description : "Add a description to select this item ." ,
201
+ Description : "Describe what selecting this value does ." ,
155
202
ForceNew : true ,
156
203
Optional : true ,
157
204
},
158
205
"value" : {
159
206
Type : schema .TypeString ,
160
- Description : "The value of this option." ,
207
+ Description : "The value of this option set on the parameter if selected ." ,
161
208
ForceNew : true ,
162
209
Required : true ,
163
210
},
@@ -180,26 +227,31 @@ func parameterDataSource() *schema.Resource {
180
227
},
181
228
},
182
229
"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" },
186
235
Elem : & schema.Resource {
187
236
Schema : map [string ]* schema.Schema {
188
237
"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" },
193
243
},
194
244
"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" },
198
249
},
199
250
"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 ,
203
255
},
204
256
},
205
257
},
@@ -227,3 +279,45 @@ func valueIsType(typ, value string) diag.Diagnostics {
227
279
}
228
280
return nil
229
281
}
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