Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit50ed1c1

Browse files
authored
feat: exposeis_prebuild_claim attribute (#396)
* feat: expose is_prebuild_claim attributeSigned-off-by: Danny Kopping <dannykopping@gmail.com>* fix: string comparison hardeningSigned-off-by: Danny Kopping <dannykopping@gmail.com>---------Signed-off-by: Danny Kopping <dannykopping@gmail.com>
1 parent4126ff4 commit50ed1c1

File tree

3 files changed

+164
-1
lines changed

3 files changed

+164
-1
lines changed

‎docs/data-sources/workspace.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ resource "docker_container" "workspace" {
7070
-`access_url` (String) The access URL of the Coder deployment provisioning this workspace.
7171
-`id` (String) UUID of the workspace.
7272
-`is_prebuild` (Boolean) Similar to`prebuild_count`, but a boolean value instead of a count. This is set to true if the workspace is a currently unassigned prebuild. Once the workspace is assigned, this value will be false.
73+
-`is_prebuild_claim` (Boolean) Indicates whether a prebuilt workspace has just been claimed and this is the first`apply` after that occurrence.
7374
-`name` (String) Name of the workspace.
7475
-`prebuild_count` (Number) A computed count, equal to 1 if the workspace is a currently unassigned prebuild. Use this to conditionally act on the status of a prebuild. Actions that do not require user identity can be taken when this value is set to 1. Actions that should only be taken once the workspace has been assigned to a user may be taken when this value is set to 0.
7576
-`start_count` (Number) A computed count based on`transition` state. If`start`, count will equal 1.

‎provider/workspace.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"reflect"
66
"strconv"
7+
"strings"
78

89
"github.com/google/uuid"
910
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -30,10 +31,23 @@ func workspaceDataSource() *schema.Resource {
3031
ifisPrebuiltWorkspace() {
3132
_=rd.Set("prebuild_count",1)
3233
_=rd.Set("is_prebuild",true)
34+
35+
// A claim can only take place AFTER a prebuild, so it's not logically consistent to have this set to any other value.
36+
_=rd.Set("is_prebuild_claim",false)
3337
}else {
3438
_=rd.Set("prebuild_count",0)
3539
_=rd.Set("is_prebuild",false)
3640
}
41+
ifisPrebuiltWorkspaceClaim() {
42+
// Indicate that a prebuild claim has taken place.
43+
_=rd.Set("is_prebuild_claim",true)
44+
45+
// A claim can only take place AFTER a prebuild, so it's not logically consistent to have these set to any other values.
46+
_=rd.Set("prebuild_count",0)
47+
_=rd.Set("is_prebuild",false)
48+
}else {
49+
_=rd.Set("is_prebuild_claim",false)
50+
}
3751

3852
name:=helpers.OptionalEnvOrDefault("CODER_WORKSPACE_NAME","default")
3953
rd.Set("name",name)
@@ -116,6 +130,11 @@ func workspaceDataSource() *schema.Resource {
116130
Computed:true,
117131
Description:"Similar to `prebuild_count`, but a boolean value instead of a count. This is set to true if the workspace is a currently unassigned prebuild. Once the workspace is assigned, this value will be false.",
118132
},
133+
"is_prebuild_claim": {
134+
Type:schema.TypeBool,
135+
Computed:true,
136+
Description:"Indicates whether a prebuilt workspace has just been claimed and this is the first `apply` after that occurrence.",
137+
},
119138
"name": {
120139
Type:schema.TypeString,
121140
Computed:true,
@@ -142,7 +161,12 @@ func workspaceDataSource() *schema.Resource {
142161

143162
// isPrebuiltWorkspace returns true if the workspace is an unclaimed prebuilt workspace.
144163
funcisPrebuiltWorkspace()bool {
145-
returnhelpers.OptionalEnv(IsPrebuildEnvironmentVariable())=="true"
164+
returnstrings.EqualFold(helpers.OptionalEnv(IsPrebuildEnvironmentVariable()),"true")
165+
}
166+
167+
// isPrebuiltWorkspaceClaim returns true if the workspace is a prebuilt workspace which has just been claimed.
168+
funcisPrebuiltWorkspaceClaim()bool {
169+
returnstrings.EqualFold(helpers.OptionalEnv(IsPrebuildClaimEnvironmentVariable()),"true")
146170
}
147171

148172
// IsPrebuildEnvironmentVariable returns the name of the environment variable that
@@ -161,3 +185,21 @@ func isPrebuiltWorkspace() bool {
161185
funcIsPrebuildEnvironmentVariable()string {
162186
return"CODER_WORKSPACE_IS_PREBUILD"
163187
}
188+
189+
// IsPrebuildClaimEnvironmentVariable returns the name of the environment variable that
190+
// indicates whether the workspace is a prebuilt workspace which has just been claimed, and this is the first Terraform
191+
// apply after that occurrence.
192+
//
193+
// Knowing whether the workspace is a claimed prebuilt workspace allows template
194+
// authors to conditionally execute code in the template based on whether the workspace
195+
// has been assigned to a user or not. This allows identity specific configuration to
196+
// be applied only after the workspace is claimed, while the rest of the workspace can
197+
// be pre-configured.
198+
//
199+
// The value of this environment variable should be set to "true" if the workspace is prebuilt
200+
// and it has just been claimed by a user. Any other values, including "false"
201+
// and "" will be interpreted to mean that the workspace is not prebuilt, or was
202+
// prebuilt but has not been claimed by a user.
203+
funcIsPrebuildClaimEnvironmentVariable()string {
204+
return"CODER_WORKSPACE_IS_PREBUILD_CLAIM"
205+
}

‎provider/workspace_test.go

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"regexp"
55
"testing"
66

7+
"github.com/coder/terraform-provider-coder/v2/provider"
78
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
89
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
910
"github.com/stretchr/testify/assert"
@@ -102,3 +103,122 @@ func TestWorkspace_MissingTemplateName(t *testing.T) {
102103
}},
103104
})
104105
}
106+
107+
// TestWorkspace_PrebuildEnv validates that our handling of input environment variables is correct.
108+
funcTestWorkspace_PrebuildEnv(t*testing.T) {
109+
cases:= []struct {
110+
namestring
111+
envsmap[string]string
112+
checkfunc(state*terraform.State,resource*terraform.ResourceState)error
113+
}{
114+
{
115+
name:"unused",
116+
envs:map[string]string{},
117+
check:func(state*terraform.State,resource*terraform.ResourceState)error {
118+
attribs:=resource.Primary.Attributes
119+
assert.Equal(t,"false",attribs["is_prebuild"])
120+
assert.Equal(t,"0",attribs["prebuild_count"])
121+
assert.Equal(t,"false",attribs["is_prebuild_claim"])
122+
returnnil
123+
},
124+
},
125+
{
126+
name:"prebuild=true",
127+
envs:map[string]string{
128+
provider.IsPrebuildEnvironmentVariable():"true",
129+
},
130+
check:func(state*terraform.State,resource*terraform.ResourceState)error {
131+
attribs:=resource.Primary.Attributes
132+
assert.Equal(t,"true",attribs["is_prebuild"])
133+
assert.Equal(t,"1",attribs["prebuild_count"])
134+
assert.Equal(t,"false",attribs["is_prebuild_claim"])
135+
returnnil
136+
},
137+
},
138+
{
139+
name:"prebuild=false",
140+
envs:map[string]string{
141+
provider.IsPrebuildEnvironmentVariable():"false",
142+
},
143+
check:func(state*terraform.State,resource*terraform.ResourceState)error {
144+
attribs:=resource.Primary.Attributes
145+
assert.Equal(t,"false",attribs["is_prebuild"])
146+
assert.Equal(t,"0",attribs["prebuild_count"])
147+
assert.Equal(t,"false",attribs["is_prebuild_claim"])
148+
returnnil
149+
},
150+
},
151+
{
152+
name:"prebuild_claim=true",
153+
envs:map[string]string{
154+
provider.IsPrebuildClaimEnvironmentVariable():"true",
155+
},
156+
check:func(state*terraform.State,resource*terraform.ResourceState)error {
157+
attribs:=resource.Primary.Attributes
158+
assert.Equal(t,"false",attribs["is_prebuild"])
159+
assert.Equal(t,"0",attribs["prebuild_count"])
160+
assert.Equal(t,"true",attribs["is_prebuild_claim"])
161+
returnnil
162+
},
163+
},
164+
{
165+
name:"prebuild_claim=false",
166+
envs:map[string]string{
167+
provider.IsPrebuildClaimEnvironmentVariable():"false",
168+
},
169+
check:func(state*terraform.State,resource*terraform.ResourceState)error {
170+
attribs:=resource.Primary.Attributes
171+
assert.Equal(t,"false",attribs["is_prebuild"])
172+
assert.Equal(t,"0",attribs["prebuild_count"])
173+
assert.Equal(t,"false",attribs["is_prebuild_claim"])
174+
returnnil
175+
},
176+
},
177+
{
178+
// Should not ever happen, but let's ensure our defensive check is activated. We can't ever have both flags
179+
// being true.
180+
name:"prebuild=true,prebuild_claim=true",
181+
envs:map[string]string{
182+
provider.IsPrebuildEnvironmentVariable():"true",
183+
provider.IsPrebuildClaimEnvironmentVariable():"true",
184+
},
185+
check:func(state*terraform.State,resource*terraform.ResourceState)error {
186+
attribs:=resource.Primary.Attributes
187+
assert.Equal(t,"false",attribs["is_prebuild"])
188+
assert.Equal(t,"0",attribs["prebuild_count"])
189+
assert.Equal(t,"true",attribs["is_prebuild_claim"])
190+
returnnil
191+
},
192+
},
193+
}
194+
195+
for_,tc:=rangecases {
196+
t.Run(tc.name,func(t*testing.T) {
197+
fork,v:=rangetc.envs {
198+
t.Setenv(k,v)
199+
}
200+
201+
resource.Test(t, resource.TestCase{
202+
ProviderFactories:coderFactory(),
203+
IsUnitTest:true,
204+
Steps: []resource.TestStep{{
205+
Config:`
206+
provider "coder" {
207+
url = "https://example.com:8080"
208+
}
209+
data "coder_workspace" "me" {
210+
}`,
211+
Check:func(state*terraform.State)error {
212+
// Baseline checks
213+
require.Len(t,state.Modules,1)
214+
require.Len(t,state.Modules[0].Resources,1)
215+
resource:=state.Modules[0].Resources["data.coder_workspace.me"]
216+
require.NotNil(t,resource)
217+
218+
returntc.check(state,resource)
219+
},
220+
}},
221+
})
222+
})
223+
}
224+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp