@@ -12,120 +12,105 @@ import (
12
12
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
13
13
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
14
14
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
15
+ "github.com/mitchellh/mapstructure"
15
16
)
16
17
18
+ type Option struct {
19
+ Name string
20
+ Description string
21
+ Value string
22
+ Icon string
23
+ }
24
+
25
+ type Validation struct {
26
+ Min int
27
+ Max int
28
+ Regex string
29
+ }
30
+
31
+ type Parameter struct {
32
+ Value string
33
+ Name string
34
+ Description string
35
+ Type string
36
+ Immutable bool
37
+ Default string
38
+ Icon string
39
+ Option []Option
40
+ Validation []Validation
41
+ }
42
+
17
43
func parameterDataSource () * schema.Resource {
18
44
return & schema.Resource {
19
45
Description : "Use this data source to configure editable options for workspaces." ,
20
46
ReadContext : func (ctx context.Context , rd * schema.ResourceData , i interface {}) diag.Diagnostics {
21
47
rd .SetId (uuid .NewString ())
22
48
23
- name := rd .Get ("name" ).(string )
24
- typ := rd .Get ("type" ).(string )
49
+ var parameter Parameter
50
+ err := mapstructure .Decode (struct {
51
+ Value interface {}
52
+ Name interface {}
53
+ Description interface {}
54
+ Type interface {}
55
+ Immutable interface {}
56
+ Default interface {}
57
+ Icon interface {}
58
+ Option interface {}
59
+ Validation interface {}
60
+ }{
61
+ Value : rd .Get ("value" ),
62
+ Name : rd .Get ("name" ),
63
+ Description : rd .Get ("description" ),
64
+ Type : rd .Get ("type" ),
65
+ Immutable : rd .Get ("immutable" ),
66
+ Default : rd .Get ("default" ),
67
+ Icon : rd .Get ("icon" ),
68
+ Option : rd .Get ("option" ),
69
+ Validation : rd .Get ("validation" ),
70
+ }, & parameter )
71
+ if err != nil {
72
+ return diag .Errorf ("decode parameter: %s" , err )
73
+ }
25
74
var value string
26
- rawDefaultValue , ok := rd .GetOk ("default" )
27
- if ok {
28
- defaultValue := rawDefaultValue .(string )
29
- err := valueIsType (typ , defaultValue )
75
+ if parameter .Default != "" {
76
+ err := valueIsType (parameter .Type , parameter .Default )
30
77
if err != nil {
31
78
return err
32
79
}
33
- value = defaultValue
80
+ value = parameter . Default
34
81
}
35
- envValue , ok := os .LookupEnv (fmt .Sprintf ("CODER_PARAMETER_%s" , name ))
82
+ envValue , ok := os .LookupEnv (fmt .Sprintf ("CODER_PARAMETER_%s" , parameter . Name ))
36
83
if ok {
37
84
value = envValue
38
85
}
39
86
rd .Set ("value" , value )
40
87
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
- }
88
+ if len (parameter .Validation ) == 1 {
89
+ validation := & parameter .Validation [0 ]
90
+ err = validation .Valid (parameter .Type , value )
91
+ if err != nil {
92
+ return diag .FromErr (err )
76
93
}
77
94
}
78
95
79
- err := ValueValidatesType (typ , value , validationRegex , validationMin , validationMax )
80
- if err != nil {
81
- return diag .FromErr (err )
82
- }
83
-
84
- rawOptions , exists := rd .GetOk ("option" )
85
- if exists {
86
- rawArrayOptions , valid := rawOptions .([]interface {})
87
- if ! valid {
88
- return diag .Errorf ("options is of wrong type %T" , rawArrayOptions )
89
- }
90
- optionDisplayNames := map [string ]interface {}{}
91
- optionValues := map [string ]interface {}{}
92
- for _ , rawOption := range rawArrayOptions {
93
- option , valid := rawOption .(map [string ]interface {})
94
- if ! valid {
95
- return diag .Errorf ("option is of wrong type %T" , rawOption )
96
- }
97
- rawName , ok := option ["name" ]
98
- if ! ok {
99
- return diag .Errorf ("no name for %+v" , option )
100
- }
101
- displayName , ok := rawName .(string )
102
- if ! ok {
103
- return diag .Errorf ("display name is of wrong type %T" , displayName )
104
- }
105
- _ , exists := optionDisplayNames [displayName ]
96
+ if len (parameter .Option ) > 0 {
97
+ names := map [string ]interface {}{}
98
+ values := map [string ]interface {}{}
99
+ for _ , option := range parameter .Option {
100
+ _ , exists := names [option .Name ]
106
101
if exists {
107
- return diag .Errorf ("multiple options cannot have the same display name %q" , displayName )
102
+ return diag .Errorf ("multiple options cannot have the same name %q" , option . Name )
108
103
}
109
-
110
- rawValue , ok := option ["value" ]
111
- if ! ok {
112
- return diag .Errorf ("no value for %+v\n " , option )
113
- }
114
- value , ok := rawValue .(string )
115
- if ! ok {
116
- return diag .Errorf ("" )
117
- }
118
- _ , exists = optionValues [value ]
104
+ _ , exists = values [option .Value ]
119
105
if exists {
120
- return diag .Errorf ("multiple options cannot have the same value %q" , value )
106
+ return diag .Errorf ("multiple options cannot have the same value %q" , option . Value )
121
107
}
122
- err := valueIsType (typ , value )
108
+ err := valueIsType (parameter . Type , option . Value )
123
109
if err != nil {
124
110
return err
125
111
}
126
-
127
- optionValues [value ] = nil
128
- optionDisplayNames [displayName ] = nil
112
+ values [option .Value ] = nil
113
+ names [option .Name ] = nil
129
114
}
130
115
}
131
116
@@ -280,26 +265,26 @@ func valueIsType(typ, value string) diag.Diagnostics {
280
265
return nil
281
266
}
282
267
283
- func ValueValidatesType ( typ , value , regex string , min , max int ) error {
268
+ func ( v * Validation ) Valid ( typ , value string ) error {
284
269
if typ != "number" {
285
- if min != 0 {
270
+ if v . Min != 0 {
286
271
return fmt .Errorf ("a min cannot be specified for a %s type" , typ )
287
272
}
288
- if max != 0 {
273
+ if v . Max != 0 {
289
274
return fmt .Errorf ("a max cannot be specified for a %s type" , typ )
290
275
}
291
276
}
292
- if typ != "string" && regex != "" {
277
+ if typ != "string" && v . Regex != "" {
293
278
return fmt .Errorf ("a regex cannot be specified for a %s type" , typ )
294
279
}
295
280
switch typ {
296
281
case "bool" :
297
282
return nil
298
283
case "string" :
299
- if regex == "" {
284
+ if v . Regex == "" {
300
285
return nil
301
286
}
302
- regex , err := regexp .Compile (regex )
287
+ regex , err := regexp .Compile (v . Regex )
303
288
if err != nil {
304
289
return fmt .Errorf ("compile regex %q: %s" , regex , err )
305
290
}
@@ -312,11 +297,11 @@ func ValueValidatesType(typ, value, regex string, min, max int) error {
312
297
if err != nil {
313
298
return fmt .Errorf ("parse value %s as int: %s" , value , err )
314
299
}
315
- if num < min {
316
- return fmt .Errorf ("provided value %d is less than the minimum %d" , num , min )
300
+ if num < v . Min {
301
+ return fmt .Errorf ("provided value %d is less than the minimum %d" , num , v . Min )
317
302
}
318
- if num > max {
319
- return fmt .Errorf ("provided value %d is more than the maximum %d" , num , max )
303
+ if num > v . Max {
304
+ return fmt .Errorf ("provided value %d is more than the maximum %d" , num , v . Max )
320
305
}
321
306
}
322
307
return nil
0 commit comments