@@ -12,120 +12,105 @@ import (
1212 "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1313 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1414 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
15+ "github.com/mitchellh/mapstructure"
1516)
1617
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+
1743func parameterDataSource () * schema.Resource {
1844 return & schema.Resource {
1945 Description : "Use this data source to configure editable options for workspaces." ,
2046 ReadContext : func (ctx context.Context , rd * schema.ResourceData , i interface {}) diag.Diagnostics {
2147 rd .SetId (uuid .NewString ())
2248
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+ }
2574 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 )
3077 if err != nil {
3178 return err
3279 }
33- value = defaultValue
80+ value = parameter . Default
3481 }
35- envValue , ok := os .LookupEnv (fmt .Sprintf ("CODER_PARAMETER_%s" , name ))
82+ envValue , ok := os .LookupEnv (fmt .Sprintf ("CODER_PARAMETER_%s" , parameter . Name ))
3683 if ok {
3784 value = envValue
3885 }
3986 rd .Set ("value" , value )
4087
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 )
7693 }
7794 }
7895
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 ]
106101 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 )
108103 }
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 ]
119105 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 )
121107 }
122- err := valueIsType (typ , value )
108+ err := valueIsType (parameter . Type , option . Value )
123109 if err != nil {
124110 return err
125111 }
126-
127- optionValues [value ] = nil
128- optionDisplayNames [displayName ] = nil
112+ values [option .Value ] = nil
113+ names [option .Name ] = nil
129114 }
130115 }
131116
@@ -280,26 +265,26 @@ func valueIsType(typ, value string) diag.Diagnostics {
280265 return nil
281266}
282267
283- func ValueValidatesType ( typ , value , regex string , min , max int ) error {
268+ func ( v * Validation ) Valid ( typ , value string ) error {
284269 if typ != "number" {
285- if min != 0 {
270+ if v . Min != 0 {
286271 return fmt .Errorf ("a min cannot be specified for a %s type" , typ )
287272 }
288- if max != 0 {
273+ if v . Max != 0 {
289274 return fmt .Errorf ("a max cannot be specified for a %s type" , typ )
290275 }
291276 }
292- if typ != "string" && regex != "" {
277+ if typ != "string" && v . Regex != "" {
293278 return fmt .Errorf ("a regex cannot be specified for a %s type" , typ )
294279 }
295280 switch typ {
296281 case "bool" :
297282 return nil
298283 case "string" :
299- if regex == "" {
284+ if v . Regex == "" {
300285 return nil
301286 }
302- regex , err := regexp .Compile (regex )
287+ regex , err := regexp .Compile (v . Regex )
303288 if err != nil {
304289 return fmt .Errorf ("compile regex %q: %s" , regex , err )
305290 }
@@ -312,11 +297,11 @@ func ValueValidatesType(typ, value, regex string, min, max int) error {
312297 if err != nil {
313298 return fmt .Errorf ("parse value %s as int: %s" , value , err )
314299 }
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 )
317302 }
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 )
320305 }
321306 }
322307 return nil
0 commit comments