Skip to content

Commit 23a23a2

Browse files
authored
feat: support list(string) as coder_parameter (#111)
* feat: support list(string) as coder_parameter * fmt * jsonencode
1 parent 9bcdcd6 commit 23a23a2

File tree

4 files changed

+61
-4
lines changed

4 files changed

+61
-4
lines changed

docs/data-sources/parameter.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Use this data source to configure editable options for workspaces.
2828
- `legacy_variable_name` (String) Name of the legacy Terraform variable. Coder will use it to lookup the variable value.
2929
- `mutable` (Boolean) Whether this value can be changed after workspace creation. This can be destructive for values like region, so use with caution!
3030
- `option` (Block List, Max: 64) Each "option" block defines a value for a user to select from. (see [below for nested schema](#nestedblock--option))
31-
- `type` (String) The type of this parameter. Must be one of: "number", "string", or "bool".
31+
- `type` (String) The type of this parameter. Must be one of: "number", "string", "bool", or "list(string)".
3232
- `validation` (Block List, Max: 1) Validate the input of a parameter. (see [below for nested schema](#nestedblock--validation))
3333

3434
### Read-Only

examples/resources/coder_parameter/resource.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,10 @@ data "coder_parameter" "cat_lives" {
7474
data "coder_parameter" "fairy_tale" {
7575
name = "Fairy Tale"
7676
type = "string"
77+
}
78+
79+
data "coder_parameter" "users" {
80+
name = "System users"
81+
type = "list(string)"
82+
default = jsonencode(["root", "user1", "user2"])
7783
}

provider/parameter.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"crypto/sha256"
66
"encoding/hex"
7+
"encoding/json"
78
"fmt"
89
"net/url"
910
"os"
@@ -180,8 +181,8 @@ func parameterDataSource() *schema.Resource {
180181
Type: schema.TypeString,
181182
Default: "string",
182183
Optional: true,
183-
ValidateFunc: validation.StringInSlice([]string{"number", "string", "bool"}, false),
184-
Description: `The type of this parameter. Must be one of: "number", "string", or "bool".`,
184+
ValidateFunc: validation.StringInSlice([]string{"number", "string", "bool", "list(string)"}, false),
185+
Description: `The type of this parameter. Must be one of: "number", "string", "bool", or "list(string)".`,
185186
},
186187
"mutable": {
187188
Type: schema.TypeBool,
@@ -328,6 +329,12 @@ func valueIsType(typ, value string) diag.Diagnostics {
328329
if err != nil {
329330
return diag.Errorf("%q is not a bool", value)
330331
}
332+
case "list(string)":
333+
var items []string
334+
err := json.Unmarshal([]byte(value), &items)
335+
if err != nil {
336+
return diag.Errorf("%q is not an array of strings", value)
337+
}
331338
case "string":
332339
// Anything is a string!
333340
default:

provider/parameter_test.go

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,51 @@ data "coder_parameter" "region" {
359359
require.Equal(t, expected, state.Primary.Attributes[key])
360360
}
361361
},
362+
}, {
363+
Name: "ListOfStrings",
364+
Config: `
365+
data "coder_parameter" "region" {
366+
name = "Region"
367+
type = "list(string)"
368+
default = jsonencode(["us-east-1", "eu-west-1", "ap-northeast-1"])
369+
}`,
370+
Check: func(state *terraform.ResourceState) {
371+
for key, expected := range map[string]string{
372+
"name": "Region",
373+
"type": "list(string)",
374+
"default": `["us-east-1","eu-west-1","ap-northeast-1"]`,
375+
} {
376+
attributeValue, ok := state.Primary.Attributes[key]
377+
require.True(t, ok, "attribute %q is expected", key)
378+
require.Equal(t, expected, attributeValue)
379+
}
380+
},
381+
}, {
382+
Name: "ListOfStringsButMigrated",
383+
Config: `
384+
variable "old_region" {
385+
type = list(string)
386+
default = ["us-west-1a"] # for testing purposes, no need to set via env TF_...
387+
}
388+
389+
data "coder_parameter" "region" {
390+
name = "Region"
391+
type = "list(string)"
392+
default = "[\"us-east-1\", \"eu-west-1\", \"ap-northeast-1\"]"
393+
legacy_variable_name = "old_region"
394+
legacy_variable = jsonencode(var.old_region)
395+
}`,
396+
Check: func(state *terraform.ResourceState) {
397+
for key, expected := range map[string]string{
398+
"name": "Region",
399+
"type": "list(string)",
400+
"default": `["us-west-1a"]`,
401+
} {
402+
attributeValue, ok := state.Primary.Attributes[key]
403+
require.True(t, ok, "attribute %q is expected", key)
404+
require.Equal(t, expected, attributeValue)
405+
}
406+
},
362407
}} {
363408
tc := tc
364409
t.Run(tc.Name, func(t *testing.T) {
@@ -376,7 +421,6 @@ data "coder_parameter" "region" {
376421
require.Len(t, state.Modules[0].Resources, 1)
377422
param := state.Modules[0].Resources["data.coder_parameter.region"]
378423
require.NotNil(t, param)
379-
t.Logf("parameter attributes: %#v", param.Primary.Attributes)
380424
if tc.Check != nil {
381425
tc.Check(param)
382426
}

0 commit comments

Comments
 (0)