From 15f99bcf0cb34ed203da3d9001a4841f78c554aa Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 5 Jul 2023 17:05:47 +0200 Subject: [PATCH 1/3] feat: support ephemeral parameters --- docs/data-sources/parameter.md | 1 + .../resources/coder_parameter/resource.tf | 6 +- provider/parameter.go | 16 +- provider/parameter_test.go | 583 +++++++++--------- 4 files changed, 317 insertions(+), 289 deletions(-) diff --git a/docs/data-sources/parameter.md b/docs/data-sources/parameter.md index 180a7d7b..b44b6f3f 100644 --- a/docs/data-sources/parameter.md +++ b/docs/data-sources/parameter.md @@ -24,6 +24,7 @@ Use this data source to configure editable options for workspaces. - `default` (String) A default value for the parameter. - `description` (String) Describe what this parameter does. - `display_name` (String) The displayed name of the parameter as it will appear in the interface. +- `ephemeral` (Boolean) The presence of the ephemeral dictates whether the parameter value will be preserved between consecutive workspace builds. - `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. - `legacy_variable` (String, Deprecated) Reference to the Terraform variable. Coder will use it to lookup the default value. - `legacy_variable_name` (String, Deprecated) Name of the legacy Terraform variable. Coder will use it to lookup the variable value. diff --git a/examples/resources/coder_parameter/resource.tf b/examples/resources/coder_parameter/resource.tf index 15b747c4..ca2f9ec4 100644 --- a/examples/resources/coder_parameter/resource.tf +++ b/examples/resources/coder_parameter/resource.tf @@ -74,8 +74,10 @@ data "coder_parameter" "cat_lives" { } data "coder_parameter" "fairy_tale" { - name = "Fairy Tale" - type = "string" + name = "Fairy Tale" + type = "string" + mutable = true + ephemeral = true } data "coder_parameter" "users" { diff --git a/provider/parameter.go b/provider/parameter.go index e8cfd4c6..2b2293a0 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -56,8 +56,8 @@ type Parameter struct { Option []Option Validation []Validation Optional bool - - Order int + Order int + Ephemeral bool LegacyVariableName string `mapstructure:"legacy_variable_name"` LegacyVariable string `mapstructure:"legacy_variable"` @@ -93,6 +93,7 @@ func parameterDataSource() *schema.Resource { Validation interface{} Optional interface{} Order interface{} + Ephemeral interface{} LegacyVariableName interface{} LegacyVariable interface{} @@ -126,6 +127,7 @@ func parameterDataSource() *schema.Resource { return val }(), Order: rd.Get("order"), + Ephemeral: rd.Get("ephemeral"), LegacyVariableName: rd.Get("legacy_variable_name"), LegacyVariable: rd.Get("legacy_variable"), }, ¶meter) @@ -146,6 +148,10 @@ func parameterDataSource() *schema.Resource { } rd.Set("value", value) + if !parameter.Mutable && parameter.Ephemeral { + return diag.Errorf("parameter can't be immutable and ephemeral") + } + if len(parameter.Validation) == 1 { validation := ¶meter.Validation[0] err = validation.Valid(parameter.Type, value) @@ -340,6 +346,12 @@ func parameterDataSource() *schema.Resource { Optional: true, Description: "The order determines the position of a template parameter in the UI/CLI presentation. The lowest order is shown first and parameters with equal order are sorted by name (ascending order).", }, + "ephemeral": { + Type: schema.TypeBool, + Default: false, + Optional: true, + Description: "The presence of the ephemeral dictates whether the parameter value will be preserved between consecutive workspace builds.", + }, "legacy_variable_name": { Type: schema.TypeString, Optional: true, diff --git a/provider/parameter_test.go b/provider/parameter_test.go index f591eeff..92d23072 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -21,31 +21,32 @@ func TestParameter(t *testing.T) { }{{ Name: "FieldsExist", Config: ` - data "coder_parameter" "region" { - name = "region" - display_name = "Region" - type = "string" - description = <<-EOT - # Select the machine image - See the [registry](https://container.registry.blah/namespace) for options. - EOT - mutable = true - icon = "/icon/region.svg" - option { - name = "US Central" - value = "us-central1-a" - icon = "/icon/central.svg" - description = "Select for central!" - } - option { - name = "US East" - value = "us-east1-a" - icon = "/icon/east.svg" - description = "Select for east!" - } - order = 5 - } - `, + data "coder_parameter" "region" { + name = "region" + display_name = "Region" + type = "string" + description = <<-EOT + # Select the machine image + See the [registry](https://container.registry.blah/namespace) for options. + EOT + mutable = true + icon = "/icon/region.svg" + option { + name = "US Central" + value = "us-central1-a" + icon = "/icon/central.svg" + description = "Select for central!" + } + option { + name = "US East" + value = "us-east1-a" + icon = "/icon/east.svg" + description = "Select for east!" + } + order = 5 + ephemeral = true + } + `, Check: func(state *terraform.ResourceState) { attrs := state.Primary.Attributes for key, value := range map[string]interface{}{ @@ -64,6 +65,7 @@ func TestParameter(t *testing.T) { "option.1.icon": "/icon/east.svg", "option.1.description": "Select for east!", "order": "5", + "ephemeral": "true", } { require.Equal(t, value, attrs[key]) } @@ -71,46 +73,46 @@ func TestParameter(t *testing.T) { }, { Name: "ValidationWithOptions", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - option { - name = "1" - value = "1" - } - validation { - regex = "1" - error = "Not 1" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + option { + name = "1" + value = "1" + } + validation { + regex = "1" + error = "Not 1" + } + } + `, ExpectError: regexp.MustCompile("conflicts with option"), }, { Name: "ValidationRegexMissingError", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - default = "hello" - validation { - regex = "hello" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "string" + default = "hello" + validation { + regex = "hello" + } + } + `, ExpectError: regexp.MustCompile("an error must be specified"), }, { Name: "NumberValidation", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 2 - validation { - min = 1 - max = 5 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 2 + validation { + min = 1 + max = 5 + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -128,57 +130,57 @@ func TestParameter(t *testing.T) { }, { Name: "DefaultNotNumber", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = true - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = true + } + `, ExpectError: regexp.MustCompile("is not a number"), }, { Name: "DefaultNotBool", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "bool" - default = 5 - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "bool" + default = 5 + } + `, ExpectError: regexp.MustCompile("is not a bool"), }, { Name: "OptionNotBool", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "bool" - option { - value = 1 - name = 1 - } - option { - value = 2 - name = 2 - } - }`, + data "coder_parameter" "region" { + name = "Region" + type = "bool" + option { + value = 1 + name = 1 + } + option { + value = 2 + name = 2 + } + }`, ExpectError: regexp.MustCompile("\"2\" is not a bool"), }, { Name: "MultipleOptions", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - option { - name = "1" - value = "1" - icon = "/icon/code.svg" - description = "Something!" - } - option { - name = "2" - value = "2" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "string" + option { + name = "1" + value = "1" + icon = "/icon/code.svg" + description = "Something!" + } + option { + name = "2" + value = "2" + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -194,22 +196,22 @@ func TestParameter(t *testing.T) { }, { Name: "ValidDefaultWithOptions", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - default = "2" - option { - name = "1" - value = "1" - icon = "/icon/code.svg" - description = "Something!" - } - option { - name = "2" - value = "2" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "string" + default = "2" + option { + name = "1" + value = "1" + icon = "/icon/code.svg" + description = "Something!" + } + option { + name = "2" + value = "2" + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -225,72 +227,72 @@ func TestParameter(t *testing.T) { }, { Name: "InvalidDefaultWithOption", Config: ` - data "coder_parameter" "region" { - name = "Region" - default = "hi" - option { - name = "1" - value = "1" - } - option { - name = "2" - value = "2" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + default = "hi" + option { + name = "1" + value = "1" + } + option { + name = "2" + value = "2" + } + } + `, ExpectError: regexp.MustCompile("must be defined as one of options"), }, { Name: "SingleOption", Config: ` - data "coder_parameter" "region" { - name = "Region" - option { - name = "1" - value = "1" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + option { + name = "1" + value = "1" + } + } + `, }, { Name: "DuplicateOptionName", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - option { - name = "1" - value = "1" - } - option { - name = "1" - value = "2" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "string" + option { + name = "1" + value = "1" + } + option { + name = "1" + value = "2" + } + } + `, ExpectError: regexp.MustCompile("cannot have the same name"), }, { Name: "DuplicateOptionValue", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - option { - name = "1" - value = "1" - } - option { - name = "2" - value = "1" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "string" + option { + name = "1" + value = "1" + } + option { + name = "2" + value = "1" + } + } + `, ExpectError: regexp.MustCompile("cannot have the same value"), }, { Name: "RequiredParameterNoDefault", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - }`, + data "coder_parameter" "region" { + name = "Region" + type = "string" + }`, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -303,11 +305,11 @@ func TestParameter(t *testing.T) { }, { Name: "RequiredParameterDefaultNull", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - default = null - }`, + data "coder_parameter" "region" { + name = "Region" + type = "string" + default = null + }`, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -320,11 +322,11 @@ func TestParameter(t *testing.T) { }, { Name: "OptionalParameterDefaultEmpty", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - default = "" - }`, + data "coder_parameter" "region" { + name = "Region" + type = "string" + default = "" + }`, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -337,11 +339,11 @@ func TestParameter(t *testing.T) { }, { Name: "OptionalParameterDefaultNotEmpty", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - default = "us-east-1" - }`, + data "coder_parameter" "region" { + name = "Region" + type = "string" + default = "us-east-1" + }`, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -354,18 +356,18 @@ func TestParameter(t *testing.T) { }, { Name: "LegacyVariable", Config: ` -variable "old_region" { - type = string - default = "fake-region" # for testing purposes, no need to set via env TF_... -} + variable "old_region" { + type = string + default = "fake-region" # for testing purposes, no need to set via env TF_... + } -data "coder_parameter" "region" { - name = "Region" - type = "string" - default = "will-be-ignored" - legacy_variable_name = "old_region" - legacy_variable = var.old_region -}`, + data "coder_parameter" "region" { + name = "Region" + type = "string" + default = "will-be-ignored" + legacy_variable_name = "old_region" + legacy_variable = var.old_region + }`, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -380,11 +382,11 @@ data "coder_parameter" "region" { }, { Name: "ListOfStrings", Config: ` -data "coder_parameter" "region" { - name = "Region" - type = "list(string)" - default = jsonencode(["us-east-1", "eu-west-1", "ap-northeast-1"]) -}`, + data "coder_parameter" "region" { + name = "Region" + type = "list(string)" + default = jsonencode(["us-east-1", "eu-west-1", "ap-northeast-1"]) + }`, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -399,18 +401,18 @@ data "coder_parameter" "region" { }, { Name: "ListOfStringsButMigrated", Config: ` -variable "old_region" { - type = list(string) - default = ["us-west-1a"] # for testing purposes, no need to set via env TF_... -} + variable "old_region" { + type = list(string) + default = ["us-west-1a"] # for testing purposes, no need to set via env TF_... + } -data "coder_parameter" "region" { - name = "Region" - type = "list(string)" - default = "[\"us-east-1\", \"eu-west-1\", \"ap-northeast-1\"]" - legacy_variable_name = "old_region" - legacy_variable = jsonencode(var.old_region) -}`, + data "coder_parameter" "region" { + name = "Region" + type = "list(string)" + default = "[\"us-east-1\", \"eu-west-1\", \"ap-northeast-1\"]" + legacy_variable_name = "old_region" + legacy_variable = jsonencode(var.old_region) + }`, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -425,15 +427,15 @@ data "coder_parameter" "region" { }, { Name: "NumberValidation_Max", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 2 - validation { - max = 9 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 2 + validation { + max = 9 + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -450,15 +452,15 @@ data "coder_parameter" "region" { }, { Name: "NumberValidation_MaxZero", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = -1 - validation { - max = 0 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = -1 + validation { + max = 0 + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -475,15 +477,15 @@ data "coder_parameter" "region" { }, { Name: "NumberValidation_Min", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 2 - validation { - min = 1 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 2 + validation { + min = 1 + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -500,15 +502,15 @@ data "coder_parameter" "region" { }, { Name: "NumberValidation_MinZero", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 2 - validation { - min = 0 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 2 + validation { + min = 0 + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -525,16 +527,16 @@ data "coder_parameter" "region" { }, { Name: "NumberValidation_MinMaxZero", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 0 - validation { - max = 0 - min = 0 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 0 + validation { + max = 0 + min = 0 + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -552,56 +554,67 @@ data "coder_parameter" "region" { }, { Name: "NumberValidation_LesserThanMin", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 5 - validation { - min = 7 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 5 + validation { + min = 7 + } + } + `, ExpectError: regexp.MustCompile("is less than the minimum"), }, { Name: "NumberValidation_GreaterThanMin", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 5 - validation { - max = 3 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 5 + validation { + max = 3 + } + } + `, ExpectError: regexp.MustCompile("is more than the maximum"), }, { Name: "NumberValidation_NotInRange", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 8 - validation { - min = 3 - max = 5 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 8 + validation { + min = 3 + max = 5 + } + } + `, ExpectError: regexp.MustCompile("is more than the maximum"), }, { Name: "NumberValidation_BoolWithMin", + Config: ` + data "coder_parameter" "region" { + name = "Region" + type = "bool" + default = true + validation { + min = 7 + } + } + `, + ExpectError: regexp.MustCompile("a min cannot be specified for a bool type"), + }, { + Name: "ImmutableEphemeralError", Config: ` data "coder_parameter" "region" { name = "Region" - type = "bool" - default = true - validation { - min = 7 - } + type = "string" + mutable = false + ephemeral = true } `, - ExpectError: regexp.MustCompile("a min cannot be specified for a bool type"), + ExpectError: regexp.MustCompile("parameter can't be immutable and ephemeral"), }} { tc := tc t.Run(tc.Name, func(t *testing.T) { From 751d3e035c6b128dd38d42c3c9b94d5d10ea9ba8 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Wed, 5 Jul 2023 17:16:48 +0200 Subject: [PATCH 2/3] fmt --- provider/parameter_test.go | 578 ++++++++++++++++++------------------- 1 file changed, 289 insertions(+), 289 deletions(-) diff --git a/provider/parameter_test.go b/provider/parameter_test.go index 92d23072..78075c18 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -21,32 +21,32 @@ func TestParameter(t *testing.T) { }{{ Name: "FieldsExist", Config: ` - data "coder_parameter" "region" { - name = "region" - display_name = "Region" - type = "string" - description = <<-EOT - # Select the machine image - See the [registry](https://container.registry.blah/namespace) for options. - EOT - mutable = true - icon = "/icon/region.svg" - option { - name = "US Central" - value = "us-central1-a" - icon = "/icon/central.svg" - description = "Select for central!" - } - option { - name = "US East" - value = "us-east1-a" - icon = "/icon/east.svg" - description = "Select for east!" - } - order = 5 - ephemeral = true - } - `, + data "coder_parameter" "region" { + name = "region" + display_name = "Region" + type = "string" + description = <<-EOT + # Select the machine image + See the [registry](https://container.registry.blah/namespace) for options. + EOT + mutable = true + icon = "/icon/region.svg" + option { + name = "US Central" + value = "us-central1-a" + icon = "/icon/central.svg" + description = "Select for central!" + } + option { + name = "US East" + value = "us-east1-a" + icon = "/icon/east.svg" + description = "Select for east!" + } + order = 5 + ephemeral = true + } + `, Check: func(state *terraform.ResourceState) { attrs := state.Primary.Attributes for key, value := range map[string]interface{}{ @@ -73,46 +73,46 @@ func TestParameter(t *testing.T) { }, { Name: "ValidationWithOptions", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - option { - name = "1" - value = "1" - } - validation { - regex = "1" - error = "Not 1" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + option { + name = "1" + value = "1" + } + validation { + regex = "1" + error = "Not 1" + } + } + `, ExpectError: regexp.MustCompile("conflicts with option"), }, { Name: "ValidationRegexMissingError", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - default = "hello" - validation { - regex = "hello" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "string" + default = "hello" + validation { + regex = "hello" + } + } + `, ExpectError: regexp.MustCompile("an error must be specified"), }, { Name: "NumberValidation", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 2 - validation { - min = 1 - max = 5 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 2 + validation { + min = 1 + max = 5 + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -130,57 +130,57 @@ func TestParameter(t *testing.T) { }, { Name: "DefaultNotNumber", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = true - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = true + } + `, ExpectError: regexp.MustCompile("is not a number"), }, { Name: "DefaultNotBool", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "bool" - default = 5 - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "bool" + default = 5 + } + `, ExpectError: regexp.MustCompile("is not a bool"), }, { Name: "OptionNotBool", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "bool" - option { - value = 1 - name = 1 - } - option { - value = 2 - name = 2 - } - }`, + data "coder_parameter" "region" { + name = "Region" + type = "bool" + option { + value = 1 + name = 1 + } + option { + value = 2 + name = 2 + } + }`, ExpectError: regexp.MustCompile("\"2\" is not a bool"), }, { Name: "MultipleOptions", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - option { - name = "1" - value = "1" - icon = "/icon/code.svg" - description = "Something!" - } - option { - name = "2" - value = "2" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "string" + option { + name = "1" + value = "1" + icon = "/icon/code.svg" + description = "Something!" + } + option { + name = "2" + value = "2" + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -196,22 +196,22 @@ func TestParameter(t *testing.T) { }, { Name: "ValidDefaultWithOptions", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - default = "2" - option { - name = "1" - value = "1" - icon = "/icon/code.svg" - description = "Something!" - } - option { - name = "2" - value = "2" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "string" + default = "2" + option { + name = "1" + value = "1" + icon = "/icon/code.svg" + description = "Something!" + } + option { + name = "2" + value = "2" + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -227,72 +227,72 @@ func TestParameter(t *testing.T) { }, { Name: "InvalidDefaultWithOption", Config: ` - data "coder_parameter" "region" { - name = "Region" - default = "hi" - option { - name = "1" - value = "1" - } - option { - name = "2" - value = "2" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + default = "hi" + option { + name = "1" + value = "1" + } + option { + name = "2" + value = "2" + } + } + `, ExpectError: regexp.MustCompile("must be defined as one of options"), }, { Name: "SingleOption", Config: ` - data "coder_parameter" "region" { - name = "Region" - option { - name = "1" - value = "1" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + option { + name = "1" + value = "1" + } + } + `, }, { Name: "DuplicateOptionName", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - option { - name = "1" - value = "1" - } - option { - name = "1" - value = "2" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "string" + option { + name = "1" + value = "1" + } + option { + name = "1" + value = "2" + } + } + `, ExpectError: regexp.MustCompile("cannot have the same name"), }, { Name: "DuplicateOptionValue", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - option { - name = "1" - value = "1" - } - option { - name = "2" - value = "1" - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "string" + option { + name = "1" + value = "1" + } + option { + name = "2" + value = "1" + } + } + `, ExpectError: regexp.MustCompile("cannot have the same value"), }, { Name: "RequiredParameterNoDefault", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - }`, + data "coder_parameter" "region" { + name = "Region" + type = "string" + }`, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -305,11 +305,11 @@ func TestParameter(t *testing.T) { }, { Name: "RequiredParameterDefaultNull", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - default = null - }`, + data "coder_parameter" "region" { + name = "Region" + type = "string" + default = null + }`, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -322,11 +322,11 @@ func TestParameter(t *testing.T) { }, { Name: "OptionalParameterDefaultEmpty", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - default = "" - }`, + data "coder_parameter" "region" { + name = "Region" + type = "string" + default = "" + }`, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -339,11 +339,11 @@ func TestParameter(t *testing.T) { }, { Name: "OptionalParameterDefaultNotEmpty", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "string" - default = "us-east-1" - }`, + data "coder_parameter" "region" { + name = "Region" + type = "string" + default = "us-east-1" + }`, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -356,18 +356,18 @@ func TestParameter(t *testing.T) { }, { Name: "LegacyVariable", Config: ` - variable "old_region" { - type = string - default = "fake-region" # for testing purposes, no need to set via env TF_... - } +variable "old_region" { + type = string + default = "fake-region" # for testing purposes, no need to set via env TF_... +} - data "coder_parameter" "region" { - name = "Region" - type = "string" - default = "will-be-ignored" - legacy_variable_name = "old_region" - legacy_variable = var.old_region - }`, +data "coder_parameter" "region" { + name = "Region" + type = "string" + default = "will-be-ignored" + legacy_variable_name = "old_region" + legacy_variable = var.old_region +}`, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -382,11 +382,11 @@ func TestParameter(t *testing.T) { }, { Name: "ListOfStrings", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "list(string)" - default = jsonencode(["us-east-1", "eu-west-1", "ap-northeast-1"]) - }`, +data "coder_parameter" "region" { + name = "Region" + type = "list(string)" + default = jsonencode(["us-east-1", "eu-west-1", "ap-northeast-1"]) +}`, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -401,18 +401,18 @@ func TestParameter(t *testing.T) { }, { Name: "ListOfStringsButMigrated", Config: ` - variable "old_region" { - type = list(string) - default = ["us-west-1a"] # for testing purposes, no need to set via env TF_... - } +variable "old_region" { + type = list(string) + default = ["us-west-1a"] # for testing purposes, no need to set via env TF_... +} - data "coder_parameter" "region" { - name = "Region" - type = "list(string)" - default = "[\"us-east-1\", \"eu-west-1\", \"ap-northeast-1\"]" - legacy_variable_name = "old_region" - legacy_variable = jsonencode(var.old_region) - }`, +data "coder_parameter" "region" { + name = "Region" + type = "list(string)" + default = "[\"us-east-1\", \"eu-west-1\", \"ap-northeast-1\"]" + legacy_variable_name = "old_region" + legacy_variable = jsonencode(var.old_region) +}`, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -427,15 +427,15 @@ func TestParameter(t *testing.T) { }, { Name: "NumberValidation_Max", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 2 - validation { - max = 9 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 2 + validation { + max = 9 + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -452,15 +452,15 @@ func TestParameter(t *testing.T) { }, { Name: "NumberValidation_MaxZero", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = -1 - validation { - max = 0 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = -1 + validation { + max = 0 + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -477,15 +477,15 @@ func TestParameter(t *testing.T) { }, { Name: "NumberValidation_Min", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 2 - validation { - min = 1 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 2 + validation { + min = 1 + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -502,15 +502,15 @@ func TestParameter(t *testing.T) { }, { Name: "NumberValidation_MinZero", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 2 - validation { - min = 0 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 2 + validation { + min = 0 + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -527,16 +527,16 @@ func TestParameter(t *testing.T) { }, { Name: "NumberValidation_MinMaxZero", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 0 - validation { - max = 0 - min = 0 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 0 + validation { + max = 0 + min = 0 + } + } + `, Check: func(state *terraform.ResourceState) { for key, expected := range map[string]string{ "name": "Region", @@ -554,55 +554,55 @@ func TestParameter(t *testing.T) { }, { Name: "NumberValidation_LesserThanMin", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 5 - validation { - min = 7 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 5 + validation { + min = 7 + } + } + `, ExpectError: regexp.MustCompile("is less than the minimum"), }, { Name: "NumberValidation_GreaterThanMin", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 5 - validation { - max = 3 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 5 + validation { + max = 3 + } + } + `, ExpectError: regexp.MustCompile("is more than the maximum"), }, { Name: "NumberValidation_NotInRange", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "number" - default = 8 - validation { - min = 3 - max = 5 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "number" + default = 8 + validation { + min = 3 + max = 5 + } + } + `, ExpectError: regexp.MustCompile("is more than the maximum"), }, { Name: "NumberValidation_BoolWithMin", Config: ` - data "coder_parameter" "region" { - name = "Region" - type = "bool" - default = true - validation { - min = 7 - } - } - `, + data "coder_parameter" "region" { + name = "Region" + type = "bool" + default = true + validation { + min = 7 + } + } + `, ExpectError: regexp.MustCompile("a min cannot be specified for a bool type"), }, { Name: "ImmutableEphemeralError", From e78c34f02b81a812fc288f3a8978040bb6e61acb Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Thu, 6 Jul 2023 10:27:03 +0200 Subject: [PATCH 3/3] Desc --- docs/data-sources/parameter.md | 2 +- provider/parameter.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/data-sources/parameter.md b/docs/data-sources/parameter.md index b44b6f3f..100c4f91 100644 --- a/docs/data-sources/parameter.md +++ b/docs/data-sources/parameter.md @@ -24,7 +24,7 @@ Use this data source to configure editable options for workspaces. - `default` (String) A default value for the parameter. - `description` (String) Describe what this parameter does. - `display_name` (String) The displayed name of the parameter as it will appear in the interface. -- `ephemeral` (Boolean) The presence of the ephemeral dictates whether the parameter value will be preserved between consecutive workspace builds. +- `ephemeral` (Boolean) The value of an ephemeral parameter will not be preserved between consecutive workspace builds. - `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icon. Use a built-in icon with `data.coder_workspace.me.access_url + "/icon/"`. - `legacy_variable` (String, Deprecated) Reference to the Terraform variable. Coder will use it to lookup the default value. - `legacy_variable_name` (String, Deprecated) Name of the legacy Terraform variable. Coder will use it to lookup the variable value. diff --git a/provider/parameter.go b/provider/parameter.go index 2b2293a0..da09720a 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -350,7 +350,7 @@ func parameterDataSource() *schema.Resource { Type: schema.TypeBool, Default: false, Optional: true, - Description: "The presence of the ephemeral dictates whether the parameter value will be preserved between consecutive workspace builds.", + Description: "The value of an ephemeral parameter will not be preserved between consecutive workspace builds.", }, "legacy_variable_name": { Type: schema.TypeString,