Content-Length: 20095 | pFad | http://github.com/coder/terraform-provider-coder/pull/422.patch

thub.com From c9a632168bd1d89096a69e5d8f070ae4fd71c0bc Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Mon, 21 Jul 2025 16:46:31 +0000 Subject: [PATCH 1/6] feat: add icon and description fields to workspace preset --- docs/data-sources/workspace_preset.md | 2 ++ integration/integration_test.go | 2 ++ integration/test-data-source/main.tf | 8 +++-- provider/workspace_preset.go | 32 +++++++++++++++-- provider/workspace_preset_test.go | 49 +++++++++++++++++++++++++++ 5 files changed, 88 insertions(+), 5 deletions(-) diff --git a/docs/data-sources/workspace_preset.md b/docs/data-sources/workspace_preset.md index 69057403..d6209659 100644 --- a/docs/data-sources/workspace_preset.md +++ b/docs/data-sources/workspace_preset.md @@ -49,6 +49,8 @@ data "coder_workspace_preset" "standard" { ### Optional - `default` (Boolean) Whether this preset should be selected by default when creating a workspace. Only one preset per template can be marked as default. +- `description` (String) Describe what this preset does. +- `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/"`. - `parameters` (Map of String) Workspace parameters that will be set by the workspace preset. For simple templates that only need prebuilds, you may define a preset with zero parameters. Because workspace parameters may change between Coder template versions, preset parameters are allowed to define values for parameters that do not exist in the current template version. - `prebuilds` (Block Set, Max: 1) Configuration for prebuilt workspaces associated with this preset. Coder will maintain a pool of standby workspaces based on this configuration. When a user creates a workspace using this preset, they are assigned a prebuilt workspace instead of waiting for a new one to build. See prebuilt workspace documentation [here](https://coder.com/docs/admin/templates/extending-templates/prebuilt-workspaces.md) (see [below for nested schema](#nestedblock--prebuilds)) diff --git a/integration/integration_test.go b/integration/integration_test.go index ec0b5e4f..423447c9 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -93,6 +93,8 @@ func TestIntegration(t *testing.T) { "workspace_parameter.value": `param value`, "workspace_parameter.icon": `param icon`, "workspace_preset.name": `preset`, + "workspace_preset.description": `preset description`, + "workspace_preset.icon": `preset icon`, "workspace_preset.default": `true`, "workspace_preset.parameters.param": `preset param value`, "workspace_preset.prebuilds.instances": `1`, diff --git a/integration/test-data-source/main.tf b/integration/test-data-source/main.tf index 5d312b1a..cc4802d3 100644 --- a/integration/test-data-source/main.tf +++ b/integration/test-data-source/main.tf @@ -20,8 +20,10 @@ data "coder_parameter" "param" { icon = "param icon" } data "coder_workspace_preset" "preset" { - name = "preset" - default = true + name = "preset" + description = "preset description" + icon = "preset icon" + default = true parameters = { (data.coder_parameter.param.name) = "preset param value" } @@ -65,6 +67,8 @@ locals { "workspace_parameter.value" : data.coder_parameter.param.value, "workspace_parameter.icon" : data.coder_parameter.param.icon, "workspace_preset.name" : data.coder_workspace_preset.preset.name, + "workspace_preset.description" : data.coder_workspace_preset.preset.description, + "workspace_preset.icon" : data.coder_workspace_preset.preset.icon, "workspace_preset.default" : tostring(data.coder_workspace_preset.preset.default), "workspace_preset.parameters.param" : data.coder_workspace_preset.preset.parameters.param, "workspace_preset.prebuilds.instances" : tostring(one(data.coder_workspace_preset.preset.prebuilds).instances), diff --git a/provider/workspace_preset.go b/provider/workspace_preset.go index 1d7576e9..586b1fa9 100644 --- a/provider/workspace_preset.go +++ b/provider/workspace_preset.go @@ -3,6 +3,7 @@ package provider import ( "context" "fmt" + "net/url" "strings" "time" @@ -18,9 +19,11 @@ import ( var PrebuildsCRONParser = rbcron.NewParser(rbcron.Minute | rbcron.Hour | rbcron.Dom | rbcron.Month | rbcron.Dow) type WorkspacePreset struct { - Name string `mapstructure:"name"` - Default bool `mapstructure:"default"` - Parameters map[string]string `mapstructure:"parameters"` + Name string `mapstructure:"name"` + Description string `mapstructure:"description"` + Icon string `mapstructure:"icon"` + Default bool `mapstructure:"default"` + Parameters map[string]string `mapstructure:"parameters"` // There should always be only one prebuild block, but Terraform's type system // still parses them as a slice, so we need to handle it as such. We could use // an anonymous type and rd.Get to avoid a slice here, but that would not be possible @@ -93,6 +96,29 @@ func workspacePresetDataSource() *schema.Resource { Required: true, ValidateFunc: validation.StringIsNotEmpty, }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Describe what this preset does.", + }, + "icon": { + Type: schema.TypeString, + Description: "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/\"`.", + ForceNew: true, + Optional: true, + ValidateFunc: func(value interface{}, label string) ([]string, []error) { + val, ok := value.(string) + if !ok { + return nil, []error{fmt.Errorf("expected %q to be a string", label)} + } + if _, err := url.Parse(val); err != nil { + return nil, []error{err} + } + return nil, nil + }, + }, "default": { Type: schema.TypeBool, Description: "Whether this preset should be selected by default when creating a workspace. Only one preset per template can be marked as default.", diff --git a/provider/workspace_preset_test.go b/provider/workspace_preset_test.go index 073193c6..9613bb39 100644 --- a/provider/workspace_preset_test.go +++ b/provider/workspace_preset_test.go @@ -23,6 +23,11 @@ func TestWorkspacePreset(t *testing.T) { Config: ` data "coder_workspace_preset" "preset_1" { name = "preset_1" + description = <<-EOT + # Select the machine image + See the [registry](https://container.registry.blah/namespace) for options. + EOT + icon = "/icon/region.svg" parameters = { "region" = "us-east1-a" } @@ -34,6 +39,8 @@ func TestWorkspacePreset(t *testing.T) { require.NotNil(t, resource) attrs := resource.Primary.Attributes require.Equal(t, attrs["name"], "preset_1") + require.Equal(t, attrs["description"], "# Select the machine image\nSee the [registry](https://container.registry.blah/namespace) for options.\n") + require.Equal(t, attrs["icon"], "/icon/region.svg") require.Equal(t, attrs["parameters.region"], "us-east1-a") return nil }, @@ -76,6 +83,48 @@ func TestWorkspacePreset(t *testing.T) { // So we test it here to make sure we don't regress. ExpectError: regexp.MustCompile("Incorrect attribute value type"), }, + { + Name: "Description field is empty", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "preset_1" + description = "" + parameters = { + "region" = "us-east1-a" + } + }`, + // This validation is done by Terraform, but it could still break if we misconfigure the schema. + // So we test it here to make sure we don't regress. + ExpectError: nil, + }, + { + Name: "Icon field is empty", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "preset_1" + icon = "" + parameters = { + "region" = "us-east1-a" + } + }`, + // This validation is done by Terraform, but it could still break if we misconfigure the schema. + // So we test it here to make sure we don't regress. + ExpectError: nil, + }, + { + Name: "Icon field is an invalid URL", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "preset_1" + icon = "/icon%.svg" + parameters = { + "region" = "us-east1-a" + } + }`, + // This validation is done by Terraform, but it could still break if we misconfigure the schema. + // So we test it here to make sure we don't regress. + ExpectError: regexp.MustCompile("invalid URL escape"), + }, { Name: "Parameters field is not provided", Config: ` From fac00c722f4bef302a115c1f2763a14e6274d167 Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Tue, 22 Jul 2025 12:21:56 +0000 Subject: [PATCH 2/6] chore: update preset.icon to use ValidateURL --- provider/workspace_preset.go | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/provider/workspace_preset.go b/provider/workspace_preset.go index 586b1fa9..302e42c1 100644 --- a/provider/workspace_preset.go +++ b/provider/workspace_preset.go @@ -3,7 +3,6 @@ package provider import ( "context" "fmt" - "net/url" "strings" "time" @@ -106,18 +105,9 @@ func workspacePresetDataSource() *schema.Resource { Description: "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/\"`.", - ForceNew: true, - Optional: true, - ValidateFunc: func(value interface{}, label string) ([]string, []error) { - val, ok := value.(string) - if !ok { - return nil, []error{fmt.Errorf("expected %q to be a string", label)} - } - if _, err := url.Parse(val); err != nil { - return nil, []error{err} - } - return nil, nil - }, + ForceNew: true, + Optional: true, + ValidateFunc: helpers.ValidateURL, }, "default": { Type: schema.TypeBool, From d2efd30b80e48b7672da75be6618f24fc17f28b4 Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Tue, 22 Jul 2025 16:05:31 +0000 Subject: [PATCH 3/6] docs: add description and icon to preset examples --- docs/data-sources/workspace_preset.md | 4 ++++ examples/data-sources/coder_workspace_preset/data-source.tf | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/docs/data-sources/workspace_preset.md b/docs/data-sources/workspace_preset.md index d6209659..bf1e3140 100644 --- a/docs/data-sources/workspace_preset.md +++ b/docs/data-sources/workspace_preset.md @@ -22,6 +22,8 @@ provider "coder" {} # parameters like the ones used below. data "coder_workspace_preset" "example" { name = "example" + description = "Example description of what this preset does." + icon = "/icon/example.svg" parameters = { (data.coder_parameter.example.name) = "us-central1-a" (data.coder_parameter.ami.name) = "ami-xxxxxxxx" @@ -31,6 +33,8 @@ data "coder_workspace_preset" "example" { # Example of a default preset that will be pre-selected for users data "coder_workspace_preset" "standard" { name = "Standard" + description = "A workspace preset with medium compute in the US West region." + icon = "/icon/standard.svg" default = true parameters = { (data.coder_parameter.instance_type.name) = "t3.medium" diff --git a/examples/data-sources/coder_workspace_preset/data-source.tf b/examples/data-sources/coder_workspace_preset/data-source.tf index 3c245f7a..787c1dfe 100644 --- a/examples/data-sources/coder_workspace_preset/data-source.tf +++ b/examples/data-sources/coder_workspace_preset/data-source.tf @@ -7,6 +7,8 @@ provider "coder" {} # parameters like the ones used below. data "coder_workspace_preset" "example" { name = "example" + description = "Example description of what this preset does." + icon = "/icon/example.svg" parameters = { (data.coder_parameter.example.name) = "us-central1-a" (data.coder_parameter.ami.name) = "ami-xxxxxxxx" @@ -16,6 +18,8 @@ data "coder_workspace_preset" "example" { # Example of a default preset that will be pre-selected for users data "coder_workspace_preset" "standard" { name = "Standard" + description = "A workspace preset with medium compute in the US West region." + icon = "/icon/standard.svg" default = true parameters = { (data.coder_parameter.instance_type.name) = "t3.medium" From 6c221509dfdc38125ad32ab3a4c43840219a137a Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Tue, 22 Jul 2025 16:07:08 +0000 Subject: [PATCH 4/6] chore: run make fmt --- .../data-sources/coder_workspace_preset/data-source.tf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/data-sources/coder_workspace_preset/data-source.tf b/examples/data-sources/coder_workspace_preset/data-source.tf index 787c1dfe..89150761 100644 --- a/examples/data-sources/coder_workspace_preset/data-source.tf +++ b/examples/data-sources/coder_workspace_preset/data-source.tf @@ -6,9 +6,9 @@ provider "coder" {} # See the coder_parameter data source's documentation for examples of how to define # parameters like the ones used below. data "coder_workspace_preset" "example" { - name = "example" + name = "example" description = "Example description of what this preset does." - icon = "/icon/example.svg" + icon = "/icon/example.svg" parameters = { (data.coder_parameter.example.name) = "us-central1-a" (data.coder_parameter.ami.name) = "ami-xxxxxxxx" @@ -17,10 +17,10 @@ data "coder_workspace_preset" "example" { # Example of a default preset that will be pre-selected for users data "coder_workspace_preset" "standard" { - name = "Standard" + name = "Standard" description = "A workspace preset with medium compute in the US West region." icon = "/icon/standard.svg" - default = true + default = true parameters = { (data.coder_parameter.instance_type.name) = "t3.medium" (data.coder_parameter.region.name) = "us-west-2" From 2a17ccce5fa0c9cc39f02373e84c4f6a1ef31554 Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Tue, 22 Jul 2025 16:22:18 +0000 Subject: [PATCH 5/6] chore: run make gen --- docs/data-sources/workspace_preset.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/data-sources/workspace_preset.md b/docs/data-sources/workspace_preset.md index bf1e3140..e7de98e4 100644 --- a/docs/data-sources/workspace_preset.md +++ b/docs/data-sources/workspace_preset.md @@ -21,9 +21,9 @@ provider "coder" {} # See the coder_parameter data source's documentation for examples of how to define # parameters like the ones used below. data "coder_workspace_preset" "example" { - name = "example" + name = "example" description = "Example description of what this preset does." - icon = "/icon/example.svg" + icon = "/icon/example.svg" parameters = { (data.coder_parameter.example.name) = "us-central1-a" (data.coder_parameter.ami.name) = "ami-xxxxxxxx" @@ -32,10 +32,10 @@ data "coder_workspace_preset" "example" { # Example of a default preset that will be pre-selected for users data "coder_workspace_preset" "standard" { - name = "Standard" + name = "Standard" description = "A workspace preset with medium compute in the US West region." icon = "/icon/standard.svg" - default = true + default = true parameters = { (data.coder_parameter.instance_type.name) = "t3.medium" (data.coder_parameter.region.name) = "us-west-2" From 23765b081f40e8843c7746b82c3cf29dd6dfaa28 Mon Sep 17 00:00:00 2001 From: Susana Ferreira Date: Tue, 22 Jul 2025 17:05:26 +0000 Subject: [PATCH 6/6] chore: add size limit to preset icon and description --- provider/workspace_preset.go | 16 ++++++++++------ provider/workspace_preset_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/provider/workspace_preset.go b/provider/workspace_preset.go index 302e42c1..393c7b7f 100644 --- a/provider/workspace_preset.go +++ b/provider/workspace_preset.go @@ -96,18 +96,22 @@ func workspacePresetDataSource() *schema.Resource { ValidateFunc: validation.StringIsNotEmpty, }, "description": { - Type: schema.TypeString, - Optional: true, - Description: "Describe what this preset does.", + Type: schema.TypeString, + Optional: true, + Description: "Describe what this preset does.", + ValidateFunc: validation.StringLenBetween(0, 128), }, "icon": { Type: schema.TypeString, Description: "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/\"`.", - ForceNew: true, - Optional: true, - ValidateFunc: helpers.ValidateURL, + ForceNew: true, + Optional: true, + ValidateFunc: validation.All( + helpers.ValidateURL, + validation.StringLenBetween(0, 256), + ), }, "default": { Type: schema.TypeBool, diff --git a/provider/workspace_preset_test.go b/provider/workspace_preset_test.go index 9613bb39..d10b8126 100644 --- a/provider/workspace_preset_test.go +++ b/provider/workspace_preset_test.go @@ -97,6 +97,20 @@ func TestWorkspacePreset(t *testing.T) { // So we test it here to make sure we don't regress. ExpectError: nil, }, + { + Name: "Description field exceeds maximum supported length (128 characters)", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "preset_1" + description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vehicula leo sit amet mi laoreet, sed ornare velit tincidunt. Proin gravida lacinia blandit." + parameters = { + "region" = "us-east1-a" + } + }`, + // This validation is done by Terraform, but it could still break if we misconfigure the schema. + // So we test it here to make sure we don't regress. + ExpectError: regexp.MustCompile(`expected length of description to be in the range \(0 - 128\)`), + }, { Name: "Icon field is empty", Config: ` @@ -125,6 +139,20 @@ func TestWorkspacePreset(t *testing.T) { // So we test it here to make sure we don't regress. ExpectError: regexp.MustCompile("invalid URL escape"), }, + { + Name: "Icon field exceeds maximum supported length (256 characters)", + Config: ` + data "coder_workspace_preset" "preset_1" { + name = "preset_1" + icon = "https://example.com/path/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.svg" + parameters = { + "region" = "us-east1-a" + } + }`, + // This validation is done by Terraform, but it could still break if we misconfigure the schema. + // So we test it here to make sure we don't regress. + ExpectError: regexp.MustCompile(`expected length of icon to be in the range \(0 - 256\)`), + }, { Name: "Parameters field is not provided", Config: `








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/coder/terraform-provider-coder/pull/422.patch

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy