Skip to content

Commit 56ccdeb

Browse files
Merge pull request #5899 from 1000hz/cina/workers-script-updates
Updates to `cloudflare_workers_script`
2 parents 9bd4f74 + 2602dba commit 56ccdeb

File tree

7 files changed

+101
-38
lines changed

7 files changed

+101
-38
lines changed

internal/services/workers_script/custom.go

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,6 @@ func (v contentSHA256Validator) ValidateString(ctx context.Context, req validato
128128
hasContentFile = true
129129
}
130130

131-
if !hasContent && !hasContentFile {
132-
resp.Diagnostics.AddError("Missing required attributes", "One of `content` or `content_file` is required")
133-
return
134-
}
135-
136131
var actualHash string
137132
var err error
138133

@@ -184,15 +179,15 @@ func ValidateContentSHA256() validator.String {
184179

185180
func UpdateSecretTextsFromState[T any](
186181
ctx context.Context,
187-
refreshed customfield.NestedObjectSet[T],
188-
state customfield.NestedObjectSet[T],
189-
) (customfield.NestedObjectSet[T], diag.Diagnostics) {
182+
refreshed customfield.NestedObjectList[T],
183+
state customfield.NestedObjectList[T],
184+
) (customfield.NestedObjectList[T], diag.Diagnostics) {
190185
var diags diag.Diagnostics
191186

192187
refreshedElems := refreshed.Elements()
193188
stateElems := state.Elements()
194189

195-
updatedElems := make([]attr.Value, len(refreshedElems))
190+
updatedElems := make([]attr.Value, 0, len(refreshedElems))
196191

197192
elemType := refreshed.ElementType(ctx)
198193

@@ -204,10 +199,10 @@ func UpdateSecretTextsFromState[T any](
204199

205200
attrTypes := objType.AttributeTypes()
206201

207-
for i, val := range refreshedElems {
202+
for _, val := range refreshedElems {
208203
refreshedObj, ok := val.(basetypes.ObjectValue)
209204
if !ok {
210-
updatedElems[i] = val
205+
updatedElems = append(updatedElems, val)
211206
continue
212207
}
213208

@@ -216,18 +211,19 @@ func UpdateSecretTextsFromState[T any](
216211
nameAttr := refreshedAttrs["name"]
217212

218213
if typeAttr.IsNull() || nameAttr.IsNull() {
219-
updatedElems[i] = val
214+
updatedElems = append(updatedElems, val)
220215
continue
221216
}
222217

223218
if typeAttr.(types.String).ValueString() != "secret_text" {
224-
updatedElems[i] = val
219+
updatedElems = append(updatedElems, val)
225220
continue
226221
}
227222

228223
name := nameAttr.(types.String).ValueString()
229224

230225
var originalText attr.Value
226+
var foundInState bool
231227
for _, stateVal := range stateElems {
232228
stateObj, ok := stateVal.(basetypes.ObjectValue)
233229
if !ok {
@@ -237,10 +233,15 @@ func UpdateSecretTextsFromState[T any](
237233
if stateAttrs["type"].(types.String).ValueString() == "secret_text" &&
238234
stateAttrs["name"].(types.String).ValueString() == name {
239235
originalText = stateAttrs["text"]
236+
foundInState = true
240237
break
241238
}
242239
}
243240

241+
if !foundInState {
242+
continue
243+
}
244+
244245
if originalText != nil && !originalText.IsNull() && !originalText.IsUnknown() {
245246
refreshedAttrs["text"] = originalText
246247

@@ -249,14 +250,14 @@ func UpdateSecretTextsFromState[T any](
249250
refreshedObj = newObj
250251
}
251252

252-
updatedElems[i] = refreshedObj
253+
updatedElems = append(updatedElems, refreshedObj)
253254
}
254255

255-
setValue, d := types.SetValue(refreshed.ElementType(ctx), updatedElems)
256+
value, d := types.ListValue(refreshed.ElementType(ctx), updatedElems)
256257
diags.Append(d...)
257258

258-
return customfield.NestedObjectSet[T]{
259-
SetValue: setValue,
259+
return customfield.NestedObjectList[T]{
260+
ListValue: value,
260261
}, diags
261262
}
262263

internal/services/workers_script/model.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -89,18 +89,18 @@ func (r WorkersScriptModel) MarshalMultipart() (data []byte, formDataContentType
8989
}
9090

9191
type WorkersScriptMetadataModel struct {
92-
Assets *WorkersScriptMetadataAssetsModel `tfsdk:"assets" json:"assets,optional"`
93-
Bindings customfield.NestedObjectSet[WorkersScriptMetadataBindingsModel] `tfsdk:"bindings" json:"bindings,computed_optional"`
94-
BodyPart types.String `tfsdk:"body_part" json:"body_part,optional"`
95-
CompatibilityDate types.String `tfsdk:"compatibility_date" json:"compatibility_date,computed_optional"`
96-
CompatibilityFlags customfield.Set[types.String] `tfsdk:"compatibility_flags" json:"compatibility_flags,computed_optional"`
97-
KeepAssets types.Bool `tfsdk:"keep_assets" json:"keep_assets,optional"`
98-
KeepBindings *[]types.String `tfsdk:"keep_bindings" json:"keep_bindings,optional"`
99-
Logpush types.Bool `tfsdk:"logpush" json:"logpush,computed_optional"`
100-
MainModule types.String `tfsdk:"main_module" json:"main_module,optional"`
101-
Migrations customfield.NestedObject[WorkersScriptMetadataMigrationsModel] `tfsdk:"migrations" json:"migrations,optional"`
102-
Observability *WorkersScriptMetadataObservabilityModel `tfsdk:"observability" json:"observability,optional"`
103-
Placement customfield.NestedObject[WorkersScriptMetadataPlacementModel] `tfsdk:"placement" json:"placement,computed_optional"`
92+
Assets *WorkersScriptMetadataAssetsModel `tfsdk:"assets" json:"assets,optional"`
93+
Bindings customfield.NestedObjectList[WorkersScriptMetadataBindingsModel] `tfsdk:"bindings" json:"bindings,computed_optional"`
94+
BodyPart types.String `tfsdk:"body_part" json:"body_part,optional"`
95+
CompatibilityDate types.String `tfsdk:"compatibility_date" json:"compatibility_date,computed_optional"`
96+
CompatibilityFlags customfield.Set[types.String] `tfsdk:"compatibility_flags" json:"compatibility_flags,computed_optional"`
97+
KeepAssets types.Bool `tfsdk:"keep_assets" json:"keep_assets,optional"`
98+
KeepBindings *[]types.String `tfsdk:"keep_bindings" json:"keep_bindings,optional"`
99+
Logpush types.Bool `tfsdk:"logpush" json:"logpush,computed_optional"`
100+
MainModule types.String `tfsdk:"main_module" json:"main_module,optional"`
101+
Migrations customfield.NestedObject[WorkersScriptMetadataMigrationsModel] `tfsdk:"migrations" json:"migrations,optional"`
102+
Observability *WorkersScriptMetadataObservabilityModel `tfsdk:"observability" json:"observability,optional"`
103+
Placement customfield.NestedObject[WorkersScriptMetadataPlacementModel] `tfsdk:"placement" json:"placement,computed_optional"`
104104
// Tags *[]types.String `tfsdk:"tags" json:"tags,optional"`
105105
TailConsumers customfield.NestedObjectSet[WorkersScriptMetadataTailConsumersModel] `tfsdk:"tail_consumers" json:"tail_consumers,computed_optional"`
106106
UsageModel types.String `tfsdk:"usage_model" json:"usage_model,computed_optional"`

internal/services/workers_script/resource.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/cloudflare/terraform-provider-cloudflare/internal/importpath"
2020
"github.com/cloudflare/terraform-provider-cloudflare/internal/logging"
2121
"github.com/hashicorp/terraform-plugin-framework/diag"
22+
"github.com/hashicorp/terraform-plugin-framework/path"
2223
"github.com/hashicorp/terraform-plugin-framework/resource"
2324
"github.com/hashicorp/terraform-plugin-framework/types"
2425
"github.com/jinzhu/copier"
@@ -65,6 +66,7 @@ func (r *WorkersScriptResource) Create(ctx context.Context, req resource.CreateR
6566
var data *WorkersScriptModel
6667

6768
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
69+
resp.Diagnostics.Append(req.Config.GetAttribute(ctx, path.Root("migrations"), &data.Migrations)...)
6870

6971
if resp.Diagnostics.HasError() {
7072
return
@@ -126,6 +128,7 @@ func (r *WorkersScriptResource) Update(ctx context.Context, req resource.UpdateR
126128
var data *WorkersScriptModel
127129

128130
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
131+
resp.Diagnostics.Append(req.Config.GetAttribute(ctx, path.Root("migrations"), &data.Migrations)...)
129132

130133
if resp.Diagnostics.HasError() {
131134
return

internal/services/workers_script/resource_test.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ func TestAccCloudflareWorkerScript_ModuleUpload(t *testing.T) {
150150
ImportStateIdPrefix: fmt.Sprintf("%s/", accountID),
151151
ImportState: true,
152152
ImportStateVerify: true,
153-
ImportStateVerifyIgnore: []string{"bindings.2.text", "main_module", "startup_time_ms"},
153+
ImportStateVerifyIgnore: []string{"bindings.2", "bindings.#", "main_module", "startup_time_ms"},
154154
},
155155
},
156156
})
@@ -339,6 +339,38 @@ func TestAccCloudflareWorkerScript_PythonWorker(t *testing.T) {
339339
})
340340
}
341341

342+
func TestAccCloudflareWorkerScript_ModuleWithDurableObject(t *testing.T) {
343+
t.Parallel()
344+
345+
rnd := utils.GenerateRandomResourceName()
346+
name := "cloudflare_workers_script." + rnd
347+
accountID := os.Getenv("CLOUDFLARE_ACCOUNT_ID")
348+
349+
resource.Test(t, resource.TestCase{
350+
PreCheck: func() {
351+
acctest.TestAccPreCheck(t)
352+
acctest.TestAccPreCheck_AccountID(t)
353+
},
354+
ProtoV6ProviderFactories: acctest.TestAccProtoV6ProviderFactories,
355+
Steps: []resource.TestStep{
356+
{
357+
Config: acctest.LoadTestCase("module_with_durable_object.tf", rnd, accountID),
358+
ConfigStateChecks: []statecheck.StateCheck{
359+
statecheck.ExpectKnownValue(name, tfjsonpath.New("script_name"), knownvalue.StringExact(rnd)),
360+
statecheck.ExpectKnownValue(name, tfjsonpath.New("main_module"), knownvalue.StringExact("worker.js")),
361+
},
362+
},
363+
{
364+
ResourceName: name,
365+
ImportStateIdPrefix: fmt.Sprintf("%s/", accountID),
366+
ImportState: true,
367+
ImportStateVerify: true,
368+
ImportStateVerifyIgnore: []string{"bindings.0.namespace_id", "has_modules", "main_module", "startup_time_ms"},
369+
},
370+
},
371+
})
372+
}
373+
342374
func testAccCheckCloudflareWorkerScriptConfigServiceWorkerInitial(rnd, accountID string) string {
343375
return acctest.LoadTestCase("service_worker_initial.tf", rnd, scriptContent1, accountID)
344376
}

internal/services/workers_script/schema.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes"
1313
"github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
1414
"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
15+
"github.com/hashicorp/terraform-plugin-framework-validators/resourcevalidator"
1516
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
1617
"github.com/hashicorp/terraform-plugin-framework/path"
1718
"github.com/hashicorp/terraform-plugin-framework/resource"
@@ -145,11 +146,11 @@ func ResourceSchema(ctx context.Context) schema.Schema {
145146
},
146147
},
147148
},
148-
"bindings": schema.SetNestedAttribute{
149+
"bindings": schema.ListNestedAttribute{
149150
Description: "List of bindings attached to a Worker. You can find more about bindings on our docs: https://developers.cloudflare.com/workers/configuration/multipart-upload-metadata/#bindings.",
150151
Computed: true,
151152
Optional: true,
152-
CustomType: customfield.NewNestedObjectSetType[WorkersScriptMetadataBindingsModel](ctx),
153+
CustomType: customfield.NewNestedObjectListType[WorkersScriptMetadataBindingsModel](ctx),
153154
NestedObject: schema.NestedAttributeObject{
154155
Attributes: map[string]schema.Attribute{
155156
"name": schema.StringAttribute{
@@ -650,5 +651,10 @@ func (r *WorkersScriptResource) Schema(ctx context.Context, req resource.SchemaR
650651
}
651652

652653
func (r *WorkersScriptResource) ConfigValidators(_ context.Context) []resource.ConfigValidator {
653-
return []resource.ConfigValidator{}
654+
return []resource.ConfigValidator{
655+
resourcevalidator.ExactlyOneOf(
656+
path.MatchRoot("content"),
657+
path.MatchRoot("content_file"),
658+
),
659+
}
654660
}

internal/services/workers_script/testdata/module.tf

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ resource "cloudflare_workers_script" "%[1]s" {
2828
type = "kv_namespace"
2929
namespace_id = cloudflare_workers_kv_namespace.%[1]s.id
3030
},
31-
{
32-
name = "SECRET"
33-
type = "secret_text"
34-
text = "shhh!!"
35-
},
3631
{
3732
name = "MY_QUEUE"
3833
type = "queue"
3934
queue_name = cloudflare_queue.%[1]s.queue_name
35+
},
36+
{
37+
name = "SECRET"
38+
type = "secret_text"
39+
text = "shhh!!"
4040
}
4141
]
4242
observability = {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
resource "cloudflare_workers_script" "%[1]s" {
2+
account_id = "%[2]s"
3+
script_name = "%[1]s"
4+
content = <<-EOT
5+
import {DurableObject} from "cloudflare:workers"
6+
export class MyDurableObject extends DurableObject {}
7+
export default { fetch() {return new Response()} }
8+
EOT
9+
main_module = "worker.js"
10+
migrations = {
11+
new_tag = "v1"
12+
new_sqlite_classes = ["MyDurableObject"]
13+
}
14+
bindings = [
15+
{
16+
name = "MY_DO"
17+
type = "durable_object_namespace"
18+
class_name = "MyDurableObject"
19+
}
20+
]
21+
}

0 commit comments

Comments
 (0)