Skip to content

Commit fd34f82

Browse files
committed
feat: add cache_invalidation parameter to prebuild resource
1 parent 7489953 commit fd34f82

File tree

5 files changed

+105
-6
lines changed

5 files changed

+105
-6
lines changed

docs/data-sources/workspace_preset.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,14 @@ data "coder_workspace_preset" "example" {
5151
Required:
5252

5353
- `instances` (Number) The number of workspaces to keep in reserve for this preset.
54+
55+
Optional:
56+
57+
- `cache_invalidation` (Block Set, Max: 1) Configuration block that defines TTL (time-to-live) behavior for prebuilds. Use this to automatically invalidate and delete prebuilds after a certain period, ensuring they stay up-to-date. (see [below for nested schema](#nestedblock--prebuilds--cache_invalidation))
58+
59+
<a id="nestedblock--prebuilds--cache_invalidation"></a>
60+
### Nested Schema for `prebuilds.cache_invalidation`
61+
62+
Required:
63+
64+
- `invalidate_after_secs` (Number) Time in seconds after which an unclaimed prebuild is considered expired and eligible for cleanup.

integration/integration_test.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,12 @@ func TestIntegration(t *testing.T) {
9090
// TODO (sasswart): the cli doesn't support presets yet.
9191
// once it does, the value for workspace_parameter.value
9292
// will be the preset value.
93-
"workspace_parameter.value": `param value`,
94-
"workspace_parameter.icon": `param icon`,
95-
"workspace_preset.name": `preset`,
96-
"workspace_preset.parameters.param": `preset param value`,
97-
"workspace_preset.prebuilds.instances": `1`,
93+
"workspace_parameter.value": `param value`,
94+
"workspace_parameter.icon": `param icon`,
95+
"workspace_preset.name": `preset`,
96+
"workspace_preset.parameters.param": `preset param value`,
97+
"workspace_preset.prebuilds.instances": `1`,
98+
"workspace_preset.prebuilds.cache_invalidation.invalidate_after_secs": `86400`,
9899
},
99100
},
100101
{

integration/test-data-source/main.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ data "coder_workspace_preset" "preset" {
2727

2828
prebuilds {
2929
instances = 1
30+
cache_invalidation = {
31+
invalidate_after_secs = 86400
32+
}
3033
}
3134
}
3235

@@ -52,6 +55,7 @@ locals {
5255
"workspace_preset.name" : data.coder_workspace_preset.preset.name,
5356
"workspace_preset.parameters.param" : data.coder_workspace_preset.preset.parameters.param,
5457
"workspace_preset.prebuilds.instances" : tostring(one(data.coder_workspace_preset.preset.prebuilds).instances),
58+
"workspace_preset.prebuilds.cache_invalidation.invalidate_after_secs" : tostring(one(data.coder_workspace_preset.preset.prebuilds.cache_invalidation).invalidate_after_secs),
5559
}
5660
}
5761

provider/workspace_preset.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@ type WorkspacePreset struct {
2121
}
2222

2323
type WorkspacePrebuild struct {
24-
Instances int `mapstructure:"instances"`
24+
Instances int `mapstructure:"instances"`
25+
CacheInvalidation []CacheInvalidation `mapstructure:"cache_invalidation"`
26+
}
27+
28+
type CacheInvalidation struct {
29+
InvalidateAfterSecs int `mapstructure:"invalidate_after_secs"`
2530
}
2631

2732
func workspacePresetDataSource() *schema.Resource {
@@ -81,6 +86,24 @@ func workspacePresetDataSource() *schema.Resource {
8186
ForceNew: true,
8287
ValidateFunc: validation.IntAtLeast(0),
8388
},
89+
"cache_invalidation": {
90+
Type: schema.TypeSet,
91+
Description: "Configuration block that defines TTL (time-to-live) behavior for prebuilds. Use this to automatically invalidate and delete prebuilds after a certain period, ensuring they stay up-to-date.",
92+
Optional: true,
93+
MaxItems: 1,
94+
Elem: &schema.Resource{
95+
Schema: map[string]*schema.Schema{
96+
"invalidate_after_secs": {
97+
Type: schema.TypeInt,
98+
Description: "Time in seconds after which an unclaimed prebuild is considered expired and eligible for cleanup.",
99+
Required: true,
100+
ForceNew: true,
101+
//Default: 86400, // TODO: Should we add a default value?
102+
ValidateFunc: validation.IntAtLeast(0),
103+
},
104+
},
105+
},
106+
},
84107
},
85108
},
86109
},

provider/workspace_preset_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,66 @@ func TestWorkspacePreset(t *testing.T) {
144144
return nil
145145
},
146146
},
147+
{
148+
Name: "Prebuilds is set with a cache_invalidation field without its required fields",
149+
Config: `
150+
data "coder_workspace_preset" "preset_1" {
151+
name = "preset_1"
152+
parameters = {
153+
"region" = "us-east1-a"
154+
}
155+
prebuilds {
156+
instances = 1
157+
cache_invalidation {}
158+
}
159+
}`,
160+
ExpectError: regexp.MustCompile("The argument \"invalidate_after_secs\" is required, but no definition was found."),
161+
},
162+
{
163+
Name: "Prebuilds is set with a cache_invalidation field with its required fields",
164+
Config: `
165+
data "coder_workspace_preset" "preset_1" {
166+
name = "preset_1"
167+
parameters = {
168+
"region" = "us-east1-a"
169+
}
170+
prebuilds {
171+
instances = 1
172+
cache_invalidation {
173+
invalidate_after_secs = 86400
174+
}
175+
}
176+
}`,
177+
ExpectError: nil,
178+
Check: func(state *terraform.State) error {
179+
require.Len(t, state.Modules, 1)
180+
require.Len(t, state.Modules[0].Resources, 1)
181+
resource := state.Modules[0].Resources["data.coder_workspace_preset.preset_1"]
182+
require.NotNil(t, resource)
183+
attrs := resource.Primary.Attributes
184+
require.Equal(t, attrs["name"], "preset_1")
185+
require.Equal(t, attrs["prebuilds.0.cache_invalidation.0.invalidate_after_secs"], "86400")
186+
return nil
187+
},
188+
},
189+
{
190+
Name: "Prebuilds is set with a cache_invalidation field with its required fields and an unexpected argument",
191+
Config: `
192+
data "coder_workspace_preset" "preset_1" {
193+
name = "preset_1"
194+
parameters = {
195+
"region" = "us-east1-a"
196+
}
197+
prebuilds {
198+
instances = 1
199+
cache_invalidation {
200+
invalidate_after_secs = 86400
201+
invalid_argument = "test"
202+
}
203+
}
204+
}`,
205+
ExpectError: regexp.MustCompile("An argument named \"invalid_argument\" is not expected here."),
206+
},
147207
}
148208

149209
for _, testcase := range testcases {

0 commit comments

Comments
 (0)