Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
217 commits
Select commit Hold shift + click to select a range
1730fa2
chore: skip mtls migration test (#6207)
vaishakdinesh Sep 17, 2025
dca249e
fix: workers script migration (#6210)
tamas-jozsa Sep 17, 2025
489795d
chore: run migration tests with sweepers (#6209)
tamas-jozsa Sep 17, 2025
002316c
chore(api): update composite API spec
stainless-app[bot] Sep 17, 2025
78c33ff
fix: case-insensitive location handling for R2 bucket resources (#6026)
pvail-cf Sep 17, 2025
da6a341
chore(api): update composite API spec
stainless-app[bot] Sep 18, 2025
c6be1c6
feat(api): api update
stainless-app[bot] Sep 17, 2025
267dfc2
chore(test): use no-grit by default when running migration tests (#6214)
musa-cf Sep 18, 2025
42a83d1
fix(migrate): page rules status defaults (#6212)
vaishakdinesh Sep 18, 2025
be571d8
fix(migrate): concatenate static and dynamic rules blocks (#6215)
musa-cf Sep 18, 2025
cea98f8
fix(migrate): zt access app default type (#6218)
vaishakdinesh Sep 18, 2025
5babbb1
fix(r2_bucket): case-insensitive location comparison and preserve st…
pvail-cf Sep 18, 2025
b50ee7c
chore(migrate): remove debug statements from migration tool (#6223)
musa-cf Sep 19, 2025
2df6eb1
fix: resolve provider schema validation errors and R2 bucket test fai…
tamas-jozsa Sep 19, 2025
5351c6a
fix: resolve zero trust test failures from computed attribute refresh…
tamas-jozsa Sep 19, 2025
ed096e0
feat(api): api update
stainless-app[bot] Sep 19, 2025
c889ef1
feat(api): api update
stainless-app[bot] Sep 17, 2025
41bce47
codegen metadata
stainless-app[bot] Sep 17, 2025
cf204ba
codegen metadata
stainless-app[bot] Sep 17, 2025
9bf7419
codegen metadata
stainless-app[bot] Sep 17, 2025
b4ef8fc
codegen metadata
stainless-app[bot] Sep 17, 2025
c0edeab
codegen metadata
stainless-app[bot] Sep 17, 2025
bb1efac
codegen metadata
stainless-app[bot] Sep 17, 2025
e4a44a8
chore(api): update composite API spec
stainless-app[bot] Sep 17, 2025
eca0889
codegen metadata
stainless-app[bot] Sep 17, 2025
14d8b06
codegen metadata
stainless-app[bot] Sep 17, 2025
845546d
codegen metadata
stainless-app[bot] Sep 17, 2025
65019de
codegen metadata
stainless-app[bot] Sep 17, 2025
c9139d7
codegen metadata
stainless-app[bot] Sep 17, 2025
d9fd0ff
codegen metadata
stainless-app[bot] Sep 17, 2025
5bd01e1
codegen metadata
stainless-app[bot] Sep 17, 2025
f1164d2
chore(api): update composite API spec
stainless-app[bot] Sep 17, 2025
ac09de9
feat: Merge branch 'vaishak/update-version' into 'main'
stainless-app[bot] Sep 17, 2025
f52687d
chore(api): update composite API spec
stainless-app[bot] Sep 17, 2025
3a87235
codegen metadata
stainless-app[bot] Sep 17, 2025
1866719
codegen metadata
stainless-app[bot] Sep 17, 2025
5fe113d
chore(internal): codegen related update
stainless-app[bot] Sep 18, 2025
b5f2c46
chore(api): update composite API spec
stainless-app[bot] Sep 18, 2025
3fd9175
chore(api): update composite API spec
stainless-app[bot] Sep 18, 2025
993307f
codegen metadata
stainless-app[bot] Sep 18, 2025
62dd485
codegen metadata
stainless-app[bot] Sep 18, 2025
133bb02
chore(api): update composite API spec
stainless-app[bot] Sep 18, 2025
bdcf432
codegen metadata
stainless-app[bot] Sep 18, 2025
e52ffb1
chore(api): update composite API spec
stainless-app[bot] Sep 18, 2025
5c2d985
chore(api): update composite API spec
stainless-app[bot] Sep 18, 2025
7636b30
chore(api): update composite API spec
stainless-app[bot] Sep 18, 2025
8507e54
codegen metadata
stainless-app[bot] Sep 18, 2025
7533c05
feat: Merge branch 'mpeterson/IAC-224-workflow' into 'main'
stainless-app[bot] Sep 18, 2025
3ccb727
chore: ensure `tfplugindocs` always use `/var/tmp` for compilation on…
stainless-app[bot] Sep 19, 2025
8af9395
codegen metadata
stainless-app[bot] Sep 18, 2025
3a74bdd
chore(internal): codegen related update
stainless-app[bot] Sep 18, 2025
37c5da3
codegen metadata
stainless-app[bot] Sep 18, 2025
fdb5109
codegen metadata
stainless-app[bot] Sep 18, 2025
c800edc
chore(internal): codegen related update
stainless-app[bot] Sep 18, 2025
175f4f5
feat: Merge branch 'dianatran/SECENG-8771' into 'main'
stainless-app[bot] Sep 19, 2025
09032bc
codegen metadata
stainless-app[bot] Sep 19, 2025
04236ca
chore(api): update composite API spec
stainless-app[bot] Sep 19, 2025
c2967fb
codegen metadata
stainless-app[bot] Sep 19, 2025
902de47
codegen metadata
stainless-app[bot] Sep 19, 2025
e8c69b1
codegen metadata
stainless-app[bot] Sep 19, 2025
6345ba4
codegen metadata
stainless-app[bot] Sep 19, 2025
4a181d7
chore(internal): codegen related update
stainless-app[bot] Sep 19, 2025
2ffd2e0
codegen metadata
stainless-app[bot] Sep 19, 2025
6e86fb5
codegen metadata
stainless-app[bot] Sep 19, 2025
8bbc5e0
codegen metadata
stainless-app[bot] Sep 19, 2025
4acb7ab
chore(api): update composite API spec
stainless-app[bot] Sep 19, 2025
44f11c3
chore: do not install brew dependencies in ./scripts/bootstrap by def…
stainless-app[bot] Sep 19, 2025
296e92c
codegen metadata
stainless-app[bot] Sep 19, 2025
1f20a56
chore(internal): codegen related update
stainless-app[bot] Sep 19, 2025
97579b5
codegen metadata
stainless-app[bot] Sep 19, 2025
04c89cb
chore(api): update composite API spec
stainless-app[bot] Sep 19, 2025
0ff7a11
chore(api): update composite API spec
stainless-app[bot] Sep 19, 2025
ced7790
chore(api): update composite API spec
stainless-app[bot] Sep 22, 2025
04aeebf
codegen metadata
stainless-app[bot] Sep 22, 2025
6ed7774
codegen metadata
stainless-app[bot] Sep 22, 2025
2978db8
chore(api): update composite API spec
stainless-app[bot] Sep 22, 2025
26e251c
codegen metadata
stainless-app[bot] Sep 22, 2025
27f2715
codegen metadata
stainless-app[bot] Sep 22, 2025
2b78333
fix: resolve compilation errors in zero_trust_access_application and …
tamas-jozsa Sep 22, 2025
c0fb2a4
chore(api): update composite API spec
stainless-app[bot] Sep 22, 2025
efebe55
chore(api): update composite API spec
stainless-app[bot] Sep 22, 2025
fcb14b6
chore(api): update composite API spec
stainless-app[bot] Sep 22, 2025
81d79a5
chore(api): update composite API spec
stainless-app[bot] Sep 22, 2025
63556d3
codegen metadata
stainless-app[bot] Sep 22, 2025
1b23a2e
codegen metadata
stainless-app[bot] Sep 22, 2025
7fb69e9
chore(internal): codegen related update
stainless-app[bot] Sep 22, 2025
ceb2a7b
codegen metadata
stainless-app[bot] Sep 22, 2025
d6a6cca
codegen metadata
stainless-app[bot] Sep 22, 2025
68f3a2b
codegen metadata
stainless-app[bot] Sep 22, 2025
0fac3c3
codegen metadata
stainless-app[bot] Sep 22, 2025
7139af1
chore(api): update composite API spec
stainless-app[bot] Sep 22, 2025
1ac2c1e
chore: improve example values
stainless-app[bot] Sep 22, 2025
5b65453
codegen metadata
stainless-app[bot] Sep 22, 2025
205b46c
codegen metadata
stainless-app[bot] Sep 22, 2025
ced0009
codegen metadata
stainless-app[bot] Sep 22, 2025
fc1f691
chore(api): update composite API spec
stainless-app[bot] Sep 22, 2025
43a63bd
codegen metadata
stainless-app[bot] Sep 22, 2025
771092e
codegen metadata
stainless-app[bot] Sep 22, 2025
a5ce060
add comprehensive tests for regional tiered cache resource (#6213)
zaidoon1 Sep 23, 2025
57a183e
Modernize & Improve Acceptance tests for workers_kv and custom_namesp…
tamas-jozsa Sep 23, 2025
f7a4176
Fix acceptance test failures in workers_script, worker_version, and …
tamas-jozsa Sep 23, 2025
7fe36e5
chore: add easy sweeper script (#6220)
tamas-jozsa Sep 23, 2025
5433d6b
chore: run workers_kv and regional_hostname tests in CI (#6240)
tamas-jozsa Sep 23, 2025
052cab8
fix: resolve compilation and schema parity errors across multiple ser…
tamas-jozsa Sep 23, 2025
4a2cbdb
fix: Fix zero trust access application acceptance tests (#6243)
tamas-jozsa Sep 23, 2025
b819769
Revert "fix: Fix zero trust access application acceptance tests" (#6245)
tamas-jozsa Sep 23, 2025
5730318
don't treat `bindings.*.version_id` as Computed and remove default va…
1000hz Sep 24, 2025
0ff8a4d
Remove created_at, updated_at, app_count (#6250)
ajholland Sep 24, 2025
c9f72ef
Remove created_at, updated_at from saas app (#6253)
ajholland Sep 24, 2025
50168e5
feat: add `assets.directory` attribute for handling assets uploads in…
1000hz Sep 24, 2025
d70cdd1
feat: modernize and fix cloudflare_zone_dnssec tests with comprehensi…
tamas-jozsa Sep 24, 2025
88c6071
Add validation tests for cloudflare_workflow resource (#6236)
maxwellpeterson Sep 24, 2025
b177cc0
fix(ruleset): allow rewrite rules to set an empty URL query string (#…
zakcutner Sep 24, 2025
9f44166
Rex/acceptance tests (#6248)
rexscaria Sep 25, 2025
6d2746c
feat: add comprehensive test coverage for cloudflare_zero_trust_list …
tamas-jozsa Sep 25, 2025
79e891e
feat: modernize and expand cloudflare_zero_trust_access_service_token…
tamas-jozsa Sep 25, 2025
2c4a1e3
feat: Modernize and expand test coverage for zero_trust_tunnel_cloudf…
tamas-jozsa Sep 26, 2025
6666597
feat: Modernize and expand test coverage for zero_trust_device_postur…
tamas-jozsa Sep 29, 2025
f53129a
tests: add acceptance tests for r2_managed_domain and r2_bucket_cors …
Carolx715 Sep 29, 2025
cd7af0a
chore(zero_trust_dex_test): Updated acceptance tests (#6183)
nevins-cf Sep 29, 2025
1477df8
feat: add missing services to CI test runner (#6271)
tamas-jozsa Sep 29, 2025
9ad5fc1
feat: modernize and expand test coverage for zero_trust_gateway_polic…
tamas-jozsa Sep 29, 2025
0b6b710
chore(api): update composite API spec
stainless-app[bot] Sep 29, 2025
b9b674c
chore(api): update composite API spec
stainless-app[bot] Sep 23, 2025
516b468
chore(api): update composite API spec
stainless-app[bot] Sep 23, 2025
64ff1f0
chore(api): update composite API spec
stainless-app[bot] Sep 23, 2025
442e6a4
codegen metadata
stainless-app[bot] Sep 23, 2025
14e2f65
codegen metadata
stainless-app[bot] Sep 23, 2025
82c913f
chore(api): update composite API spec
stainless-app[bot] Sep 23, 2025
0e5d493
codegen metadata
stainless-app[bot] Sep 23, 2025
3f85aee
codegen metadata
stainless-app[bot] Sep 23, 2025
e4c0f73
chore(api): update composite API spec
stainless-app[bot] Sep 23, 2025
d29ed40
codegen metadata
stainless-app[bot] Sep 23, 2025
906e13c
codegen metadata
stainless-app[bot] Sep 23, 2025
e4b3a36
chore(api): update composite API spec
stainless-app[bot] Sep 23, 2025
577079e
codegen metadata
stainless-app[bot] Sep 23, 2025
125870b
chore(api): update composite API spec
stainless-app[bot] Sep 23, 2025
f720dde
chore(api): update composite API spec
stainless-app[bot] Sep 23, 2025
faba42b
codegen metadata
stainless-app[bot] Sep 23, 2025
8ea71d6
codegen metadata
stainless-app[bot] Sep 23, 2025
7205a51
codegen metadata
stainless-app[bot] Sep 23, 2025
e8e7241
chore(api): update composite API spec
stainless-app[bot] Sep 23, 2025
970c75a
codegen metadata
stainless-app[bot] Sep 23, 2025
2424405
codegen metadata
stainless-app[bot] Sep 23, 2025
7a197a8
codegen metadata
stainless-app[bot] Sep 23, 2025
afd5c1e
codegen metadata
stainless-app[bot] Sep 23, 2025
226cce5
chore(api): update composite API spec
stainless-app[bot] Sep 23, 2025
588475d
codegen metadata
stainless-app[bot] Sep 23, 2025
8e01c81
codegen metadata
stainless-app[bot] Sep 23, 2025
270f556
chore(api): update composite API spec
stainless-app[bot] Sep 23, 2025
86e8862
chore(api): update composite API spec
stainless-app[bot] Sep 23, 2025
f96417c
chore(api): update composite API spec
stainless-app[bot] Sep 23, 2025
00bb6e6
chore(api): update composite API spec
stainless-app[bot] Sep 23, 2025
7310778
chore(internal): codegen related update
stainless-app[bot] Sep 23, 2025
8fabca3
chore(api): update composite API spec
stainless-app[bot] Sep 23, 2025
a50d130
chore(api): update composite API spec
stainless-app[bot] Sep 24, 2025
0df0b82
chore(api): update composite API spec
stainless-app[bot] Sep 29, 2025
b14a809
codegen metadata
stainless-app[bot] Sep 24, 2025
b02b92c
chore(internal): codegen related update
stainless-app[bot] Sep 30, 2025
7c43df9
chore(api): update composite API spec
stainless-app[bot] Sep 24, 2025
ca18700
chore(api): update composite API spec
stainless-app[bot] Sep 30, 2025
5a3b647
codegen metadata
stainless-app[bot] Sep 24, 2025
9fa7201
codegen metadata
stainless-app[bot] Sep 24, 2025
2a0c724
chore(api): update composite API spec
stainless-app[bot] Sep 24, 2025
a2fa388
codegen metadata
stainless-app[bot] Sep 24, 2025
d15f035
chore(api): update composite API spec
stainless-app[bot] Sep 24, 2025
3fe6bda
codegen metadata
stainless-app[bot] Sep 24, 2025
7839869
chore(api): update composite API spec
stainless-app[bot] Sep 24, 2025
9663d30
chore(api): update composite API spec
stainless-app[bot] Sep 24, 2025
91dd46e
codegen metadata
stainless-app[bot] Sep 25, 2025
2e822a9
chore(internal): codegen related update
stainless-app[bot] Sep 25, 2025
007bdbc
feat: docs(iam): Adding new self-service SSO APIs
stainless-app[bot] Sep 25, 2025
f965e4c
chore(api): update composite API spec
stainless-app[bot] Sep 25, 2025
02f821d
chore(api): update composite API spec
stainless-app[bot] Sep 25, 2025
2db7987
codegen metadata
stainless-app[bot] Sep 25, 2025
9a106e3
fix: bugfix for setting JSON keys with special characters
stainless-app[bot] Sep 25, 2025
f67fbd5
feat: docs(iam): Changing SSO update from put to patch
stainless-app[bot] Sep 25, 2025
63871c7
codegen metadata
stainless-app[bot] Sep 25, 2025
a2ec386
codegen metadata
stainless-app[bot] Sep 25, 2025
ebc4649
codegen metadata
stainless-app[bot] Sep 25, 2025
2416723
chore(internal): codegen related update
stainless-app[bot] Sep 25, 2025
d98c4cc
chore(api): update composite API spec
stainless-app[bot] Sep 26, 2025
1b987a0
chore(api): update composite API spec
stainless-app[bot] Sep 26, 2025
cbf8d12
chore(api): update composite API spec
stainless-app[bot] Sep 26, 2025
d22865a
chore(api): update composite API spec
stainless-app[bot] Sep 26, 2025
d140041
chore(api): update composite API spec
stainless-app[bot] Sep 26, 2025
e9b678b
chore(internal): codegen related update
stainless-app[bot] Sep 26, 2025
4a73956
codegen metadata
stainless-app[bot] Sep 26, 2025
5dbc8ba
codegen metadata
stainless-app[bot] Sep 26, 2025
b75aafd
chore(api): update composite API spec
stainless-app[bot] Sep 26, 2025
195dbf4
chore(mcp): allow pointing `docs_search` tool at other URLs
stainless-app[bot] Sep 26, 2025
ed48ae9
codegen metadata
stainless-app[bot] Sep 26, 2025
9935a7e
codegen metadata
stainless-app[bot] Sep 26, 2025
95603f6
chore(internal): codegen related update
stainless-app[bot] Sep 26, 2025
ee08de7
chore(api): update composite API spec
stainless-app[bot] Sep 26, 2025
07b0b65
codegen metadata
stainless-app[bot] Sep 26, 2025
510c380
codegen metadata
stainless-app[bot] Sep 26, 2025
ed99054
chore(internal): codegen related update
stainless-app[bot] Sep 26, 2025
e5c0d2e
codegen metadata
stainless-app[bot] Sep 26, 2025
5278c20
codegen metadata
stainless-app[bot] Sep 26, 2025
e88cb76
codegen metadata
stainless-app[bot] Sep 26, 2025
8d68abc
chore(internal): codegen related update
stainless-app[bot] Sep 26, 2025
e1faeb8
feat: added capability for `dynamicvalidator` to do arbitrary semanti…
stainless-app[bot] Sep 29, 2025
1a71265
feat: fix(api): RAG-286: Add to_markdown subresource to AI resource
stainless-app[bot] Sep 29, 2025
75d8d6b
feat: chore(zero_trust_access_application): fix config for disabling …
stainless-app[bot] Sep 30, 2025
290fbad
chore(internal): codegen related update
stainless-app[bot] Sep 30, 2025
70abffa
fix(list_item): source url validation (#6226)
broswen Sep 30, 2025
07ccc50
feat: fix(ai): rename duplicate parameter in the to_markdown subresource
stainless-app[bot] Sep 30, 2025
3457590
chore(internal): codegen related update
stainless-app[bot] Sep 30, 2025
2224d8a
fix(build): fix broken builds on 'next' (#6280)
musa-cf Oct 1, 2025
ebdbece
feat: modernize and improve cloudflare_pages_project test coverage (#…
tamas-jozsa Oct 1, 2025
b4829e2
TUN-9814: Update virtual network resource (#6270)
lmpn Oct 1, 2025
7c8a8ee
TUN-9813: Update cloudflared config resource (#6272)
lmpn Oct 1, 2025
2ed457a
feat: sweepers for workers_kv and zero_trust_list (#6281)
tamas-jozsa Oct 1, 2025
c0a9e89
fix: fix acceptance tests in CI (#6286)
tamas-jozsa Oct 1, 2025
502612c
DRAFT: give clear error messages on gateway policy drift
Oct 2, 2025
e35b33c
GENERIC + COLOR
Oct 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 0 additions & 4 deletions .github/workflows/acceptance-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,13 @@ jobs:
run: ./scripts/run-ci-tests magic acceptance
env:
TF_ACC: 1
NO_GRIT: true
continue-on-error: true

- name: Run Magic Migration Tests
id: magic_migration_tests
run: ./scripts/run-ci-tests magic migration
env:
TF_ACC: 1
NO_GRIT: true
continue-on-error: true

######## Everything Else ########
Expand All @@ -78,15 +76,13 @@ jobs:
run: ./scripts/run-ci-tests default acceptance
env:
TF_ACC: 1
NO_GRIT: true
continue-on-error: true

- name: Run Default Migration Tests
id: default_migration_tests
run: ./scripts/run-ci-tests default migration
env:
TF_ACC: 1
NO_GRIT: true
continue-on-error: true

- name: Check Test Status
Expand Down
8 changes: 4 additions & 4 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 1809
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-77d61495fecd0d26b9adff1af0ab3510b06a3cc2c6781b9a40aabcad2f10588a.yml
openapi_spec_hash: 95dee3be411dda77306a41dc7d49eb35
config_hash: ac04197a992afb1d8c3b416fc46e8c8e
configured_endpoints: 1822
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-ca8fbfa82d19dca400ec61b8c93392de1acd157860e435419f9a5e9ec8c586e0.yml
openapi_spec_hash: 77d55c70bc3824ac61bd056e2319ee18
config_hash: 107e0f1f8a98b007260b319226b88b3c
37 changes: 29 additions & 8 deletions cmd/migrate/access_application.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,24 @@ func isAccessApplicationResource(block *hclwrite.Block) bool {
// Phase 3 - Remove unsupported attributes and convert blocks to attributes:
// Before: domain_type = "public" (removed - not supported in v5)
// Before: destinations { ... } (converted from blocks to list attribute)
//
// Phase 4 - Add default type if missing:
// Before: (no type attribute)
// After: type = "self_hosted"
func transformAccessApplicationBlock(block *hclwrite.Block, diags ast.Diagnostics) {
// STEP 1: Auto-populate policies from collected access_policy mappings
// STEP 1: Add default type attribute if missing (v4 defaulted to "self_hosted")
addDefaultTypeAttribute(block)

// STEP 2: Auto-populate policies from collected access_policy mappings
injectCollectedPolicies(block, diags)
// STEP 2: Remove unsupported attributes

// STEP 3: Remove unsupported attributes
removeUnsupportedAttributes(block)
// STEP 3: Convert destinations blocks to list attribute

// STEP 4: Convert destinations blocks to list attribute
convertDestinationsBlocksToAttribute(block, diags)
// STEP 4: Transform existing attribute formats

// STEP 5: Transform existing attribute formats
transforms := map[string]ast.ExprTransformer{
"policies": transformPoliciesAttribute,
"allowed_idps": transformSetToListAttribute,
Expand All @@ -53,6 +60,20 @@ func transformAccessApplicationBlock(block *hclwrite.Block, diags ast.Diagnostic
ast.ApplyTransformToAttributes(ast.Block{Block: block}, transforms, diags)
}

// addDefaultTypeAttribute adds type = "self_hosted" if the type attribute is missing
// This is needed because v4 had a default value of "self_hosted" for the type attribute,
// but v5 requires it to be explicitly set
func addDefaultTypeAttribute(block *hclwrite.Block) {
body := block.Body()

// Check if type attribute exists
typeAttr := body.GetAttribute("type")
if typeAttr == nil {
// Add default type = "self_hosted" as this was the v4 default
body.SetAttributeValue("type", cty.StringVal("self_hosted"))
}
}

// transformPoliciesAttribute transforms a policies list from strings/references to objects
//
// Example transformations:
Expand Down Expand Up @@ -333,6 +354,6 @@ func convertDestinationBlockToObject(block *hclwrite.Block) string {

// Sort for consistent output
sort.Strings(attrStrings)

return fmt.Sprintf("{\n%s\n }", strings.Join(attrStrings, "\n"))
}
31 changes: 15 additions & 16 deletions cmd/migrate/access_application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ func TestAccessApplicationPoliciesTransformation(t *testing.T) {
account_id = "abc123"
name = "Test App"
domain = "test.example.com"

policies = [
{ id = cloudflare_zero_trust_access_policy.allow.id },
{ id = cloudflare_zero_trust_access_policy.deny.id }
]

policies = [{ id = cloudflare_zero_trust_access_policy.allow.id }, { id = cloudflare_zero_trust_access_policy.deny.id }]
type = "self_hosted"
}`},
},
{
Expand All @@ -42,8 +40,9 @@ func TestAccessApplicationPoliciesTransformation(t *testing.T) {
account_id = "abc123"
name = "Test App"
domain = "test.example.com"

policies = [{ id = "policy-id-1" }, { id = "policy-id-2" }]
type = "self_hosted"
}`},
},
{
Expand All @@ -63,12 +62,9 @@ func TestAccessApplicationPoliciesTransformation(t *testing.T) {
account_id = "abc123"
name = "Test App"
domain = "test.example.com"

policies = [
{ id = cloudflare_zero_trust_access_policy.allow.id },
{ id = "literal-policy-id" },
{ id = cloudflare_zero_trust_access_policy.deny.id }
]

policies = [{ id = cloudflare_zero_trust_access_policy.allow.id }, { id = "literal-policy-id" }, { id = cloudflare_zero_trust_access_policy.deny.id }]
type = "self_hosted"
}`},
},
{
Expand All @@ -86,12 +82,13 @@ func TestAccessApplicationPoliciesTransformation(t *testing.T) {
account_id = "abc123"
name = "Test App"
domain = "test.example.com"

policies = [ { id = cloudflare_zero_trust_access_policy.old_style.id } ]

policies = [{ id = cloudflare_zero_trust_access_policy.old_style.id }]
type = "self_hosted"
}`},
},
{
Name: "no policies attribute",
Name: "no policies attribute but add default type",
Config: `resource "cloudflare_zero_trust_access_application" "test" {
account_id = "abc123"
name = "Test App"
Expand All @@ -101,6 +98,7 @@ func TestAccessApplicationPoliciesTransformation(t *testing.T) {
account_id = "abc123"
name = "Test App"
domain = "test.example.com"
type = "self_hosted"
}`},
},
}
Expand Down Expand Up @@ -424,7 +422,7 @@ func TestAccessApplicationSkipAppLauncherLoginPageRemoval(t *testing.T) {
}`},
},
{
Name: "remove skip_app_launcher_login_page when no type attribute",
Name: "remove skip_app_launcher_login_page when no type attribute and add default type",
Config: `resource "cloudflare_zero_trust_access_application" "test" {
account_id = "abc123"
name = "Test App"
Expand All @@ -435,6 +433,7 @@ func TestAccessApplicationSkipAppLauncherLoginPageRemoval(t *testing.T) {
account_id = "abc123"
name = "Test App"
domain = "test.example.com"
type = "self_hosted"
}`},
},
{
Expand Down
141 changes: 108 additions & 33 deletions cmd/migrate/cloudflare_ruleset_hcl.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,29 @@ func transformCloudflareRulesetBlock(block *hclwrite.Block, diags ast.Diagnostic
// transformDynamicRulesBlocks converts dynamic "rules" blocks to for expressions
// V4: dynamic "rules" { for_each = local.rule_configs; content { ... } }
// V5: rules = [for rule in local.rule_configs : { ... }]
// When mixed with static rules blocks (already converted to list), use concat()
func transformDynamicRulesBlocks(block *hclwrite.Block, diags ast.Diagnostics) {
body := block.Body()
dynamicRulesBlocks := []*hclwrite.Block{}

// Check if there's already a rules attribute (from converted static blocks)
existingRulesAttr := body.GetAttribute("rules")

// Find all dynamic blocks with label "rules"
for _, childBlock := range body.Blocks() {
if childBlock.Type() == "dynamic" && len(childBlock.Labels()) > 0 && childBlock.Labels()[0] == "rules" {
dynamicRulesBlocks = append(dynamicRulesBlocks, childBlock)
}
}

// If no dynamic blocks, nothing to do
if len(dynamicRulesBlocks) == 0 {
return
}

// Collect all dynamic block expressions
var dynamicExpressions []hclwrite.Tokens

// Process each dynamic rules block
for _, dynBlock := range dynamicRulesBlocks {
// Extract the for_each expression
Expand Down Expand Up @@ -138,37 +150,8 @@ func transformDynamicRulesBlocks(block *hclwrite.Block, diags ast.Diagnostics) {
// Handle nested blocks within content (e.g., action_parameters, ratelimit, etc.)
// These need to be converted to attribute format as well
for _, nestedBlock := range contentBlock.Body().Blocks() {
blockType := nestedBlock.Type()

// Add the block as an attribute with object value
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenIdent, Bytes: []byte(" " + blockType)})
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenEqual, Bytes: []byte(" = ")})
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenOBrace, Bytes: []byte("{")})
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")})

// Process nested block attributes
nestedAttrs := nestedBlock.Body().Attributes()
nestedAttrNames := make([]string, 0, len(nestedAttrs))
for name := range nestedAttrs {
nestedAttrNames = append(nestedAttrNames, name)
}
sort.Strings(nestedAttrNames)

for _, name := range nestedAttrNames {
attr := nestedAttrs[name]
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenIdent, Bytes: []byte(" " + name)})
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenEqual, Bytes: []byte(" = ")})

attrTokens := attr.Expr().BuildTokens(nil)
processedTokens := replaceRulesIteratorReferences(attrTokens, iteratorName)
tokens = append(tokens, processedTokens...)

tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")})
}

// Close the nested object
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenIdent, Bytes: []byte(" }")})
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")})
blockTokens := convertBlockToAttributeTokens(nestedBlock, iteratorName, 2)
tokens = append(tokens, blockTokens...)
}

// Close object
Expand All @@ -180,9 +163,101 @@ func transformDynamicRulesBlocks(block *hclwrite.Block, diags ast.Diagnostics) {
// Remove the dynamic block
body.RemoveBlock(dynBlock)

// Add the new attribute with the for expression
body.SetAttributeRaw("rules", tokens)
// Store the dynamic expression for later combination
dynamicExpressions = append(dynamicExpressions, tokens)
}

// Now combine all expressions
if len(dynamicExpressions) == 0 {
return
}

// Build the final rules expression
var finalTokens hclwrite.Tokens

// If we have existing rules (from static blocks), use concat()
if existingRulesAttr != nil {
// Start with concat(
finalTokens = append(finalTokens, &hclwrite.Token{Type: hclsyntax.TokenIdent, Bytes: []byte("concat")})
finalTokens = append(finalTokens, &hclwrite.Token{Type: hclsyntax.TokenOParen, Bytes: []byte("(")})

// Add existing rules expression
finalTokens = append(finalTokens, existingRulesAttr.Expr().BuildTokens(nil)...)

// Add each dynamic expression
for _, dynTokens := range dynamicExpressions {
finalTokens = append(finalTokens, &hclwrite.Token{Type: hclsyntax.TokenComma, Bytes: []byte(", ")})
finalTokens = append(finalTokens, dynTokens...)
}

// Close concat
finalTokens = append(finalTokens, &hclwrite.Token{Type: hclsyntax.TokenCParen, Bytes: []byte(")")})
} else if len(dynamicExpressions) == 1 {
// Just one dynamic expression, use it directly
finalTokens = dynamicExpressions[0]
} else {
// Multiple dynamic expressions without static rules, use concat()
finalTokens = append(finalTokens, &hclwrite.Token{Type: hclsyntax.TokenIdent, Bytes: []byte("concat")})
finalTokens = append(finalTokens, &hclwrite.Token{Type: hclsyntax.TokenOParen, Bytes: []byte("(")})

for i, dynTokens := range dynamicExpressions {
if i > 0 {
finalTokens = append(finalTokens, &hclwrite.Token{Type: hclsyntax.TokenComma, Bytes: []byte(", ")})
}
finalTokens = append(finalTokens, dynTokens...)
}

finalTokens = append(finalTokens, &hclwrite.Token{Type: hclsyntax.TokenCParen, Bytes: []byte(")")})
}

// Set the final rules attribute
body.SetAttributeRaw("rules", finalTokens)
}

// convertBlockToAttributeTokens recursively converts a block and all its nested blocks to attribute format
func convertBlockToAttributeTokens(block *hclwrite.Block, iteratorName string, indentLevel int) hclwrite.Tokens {
var tokens hclwrite.Tokens
indent := strings.Repeat(" ", indentLevel)

blockType := block.Type()

// Add the block as an attribute with object value
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenIdent, Bytes: []byte(indent + blockType)})
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenEqual, Bytes: []byte(" = ")})
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenOBrace, Bytes: []byte("{")})
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")})

// Process attributes
attrs := block.Body().Attributes()
attrNames := make([]string, 0, len(attrs))
for name := range attrs {
attrNames = append(attrNames, name)
}
sort.Strings(attrNames)

for _, name := range attrNames {
attr := attrs[name]
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenIdent, Bytes: []byte(indent + " " + name)})
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenEqual, Bytes: []byte(" = ")})

attrTokens := attr.Expr().BuildTokens(nil)
processedTokens := replaceRulesIteratorReferences(attrTokens, iteratorName)
tokens = append(tokens, processedTokens...)

tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")})
}

// Recursively process nested blocks
for _, nestedBlock := range block.Body().Blocks() {
nestedTokens := convertBlockToAttributeTokens(nestedBlock, iteratorName, indentLevel+1)
tokens = append(tokens, nestedTokens...)
}

// Close the object
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenIdent, Bytes: []byte(indent + "}")})
tokens = append(tokens, &hclwrite.Token{Type: hclsyntax.TokenNewline, Bytes: []byte("\n")})

return tokens
}

// replaceRulesIteratorReferences replaces iterator.value references with just iterator
Expand Down
Loading