Skip to content

Commit f80a755

Browse files
authored
Merge pull request #546 from cloudflare/allow-empty-rewrite-rules-to-generate
cmd/generate: Handle rewriting `uri.query.value` to empty strings
2 parents b74032f + 2f54c1a commit f80a755

File tree

15 files changed

+177
-18
lines changed

15 files changed

+177
-18
lines changed

internal/app/cf-terraforming/cmd/generate.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,12 +1119,12 @@ func generateResources() func(cmd *cobra.Command, args []string) {
11191119
continue
11201120
}
11211121
if attrName == "account_id" && accountID != "" {
1122-
writeAttrLine(attrName, accountID, resource)
1122+
writeAttrLine(attrName, accountID, "", resource)
11231123
continue
11241124
}
11251125

11261126
if attrName == "zone_id" && zoneID != "" && accountID == "" {
1127-
writeAttrLine(attrName, zoneID, resource)
1127+
writeAttrLine(attrName, zoneID, "", resource)
11281128
continue
11291129
}
11301130

@@ -1133,15 +1133,15 @@ func generateResources() func(cmd *cobra.Command, args []string) {
11331133
case ty.IsPrimitiveType():
11341134
switch ty {
11351135
case cty.String, cty.Bool, cty.Number:
1136-
writeAttrLine(attrName, structData[attrName], resource)
1136+
writeAttrLine(attrName, structData[attrName], "", resource)
11371137
delete(structData, attrName)
11381138
default:
11391139
log.Debugf("unexpected primitive type %q", ty.FriendlyName())
11401140
}
11411141
case ty.IsCollectionType():
11421142
switch {
11431143
case ty.IsListType(), ty.IsSetType(), ty.IsMapType():
1144-
writeAttrLine(attrName, structData[attrName], resource)
1144+
writeAttrLine(attrName, structData[attrName], "", resource)
11451145
delete(structData, attrName)
11461146
default:
11471147
log.Debugf("unexpected collection type %q", ty.FriendlyName())

internal/app/cf-terraforming/cmd/generate_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func TestGenerate_writeAttrLine(t *testing.T) {
7171
for name, tc := range tests {
7272
f := hclwrite.NewEmptyFile()
7373
t.Run(name, func(t *testing.T) {
74-
writeAttrLine(tc.key, tc.value, f.Body())
74+
writeAttrLine(tc.key, tc.value, "", f.Body())
7575
assert.Equal(t, tc.want, string(f.Bytes()))
7676
})
7777
}
@@ -136,6 +136,7 @@ func TestResourceGeneration(t *testing.T) {
136136
"cloudflare ruleset (no configuration)": {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_no_configuration"},
137137
"cloudflare ruleset (override remapping = disabled)": {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_override_remapping_disabled"},
138138
"cloudflare ruleset (override remapping = enabled)": {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_override_remapping_enabled"},
139+
"cloudflare ruleset (rewrite to empty query string)": {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone_rewrite_to_empty_query_parameter"},
139140
"cloudflare ruleset": {identiferType: "zone", resourceType: "cloudflare_ruleset", testdataFilename: "cloudflare_ruleset_zone"},
140141
"cloudflare spectrum application": {identiferType: "zone", resourceType: "cloudflare_spectrum_application", testdataFilename: "cloudflare_spectrum_application"},
141142
"cloudflare tunnel": {identiferType: "account", resourceType: "cloudflare_tunnel", testdataFilename: "cloudflare_tunnel"},

internal/app/cf-terraforming/cmd/util.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,15 +210,15 @@ func processBlocks(schemaBlock *tfjson.SchemaBlock, structData map[string]interf
210210
continue
211211
}
212212
if _, ok := schemaBlock.Attributes[block]; ok && (schemaBlock.Attributes[block].Optional || schemaBlock.Attributes[block].Required) {
213-
writeAttrLine(block, structData[block], parent)
213+
writeAttrLine(block, structData[block], parentBlock, parent)
214214
}
215215
}
216216
}
217217
}
218218

219219
// writeAttrLine outputs a line of HCL configuration with a configurable depth
220220
// for known types.
221-
func writeAttrLine(key string, value interface{}, body *hclwrite.Body) {
221+
func writeAttrLine(key string, value interface{}, parentName string, body *hclwrite.Body) {
222222
switch values := value.(type) {
223223
case []map[string]interface{}:
224224
var childCty []cty.Value
@@ -268,15 +268,15 @@ func writeAttrLine(key string, value interface{}, body *hclwrite.Body) {
268268
}
269269
}
270270
if len(stringItems) > 0 {
271-
writeAttrLine(key, stringItems, body)
271+
writeAttrLine(key, stringItems, parentName, body)
272272
}
273273

274274
if len(intItems) > 0 {
275-
writeAttrLine(key, intItems, body)
275+
writeAttrLine(key, intItems, parentName, body)
276276
}
277277

278278
if len(interfaceItems) > 0 {
279-
writeAttrLine(key, interfaceItems, body)
279+
writeAttrLine(key, interfaceItems, parentName, body)
280280
}
281281
case []int:
282282
var vals []cty.Value
@@ -295,6 +295,10 @@ func writeAttrLine(key string, value interface{}, body *hclwrite.Body) {
295295
body.SetAttributeValue(key, cty.ListVal(vals))
296296
}
297297
case string:
298+
if parentName == "query" && key == "value" && value == "" {
299+
body.SetAttributeValue(key, cty.StringVal(""))
300+
}
301+
298302
if value != "" {
299303
body.SetAttributeValue(key, cty.StringVal(value.(string)))
300304
}

testdata/cloudflare/cloudflare_ruleset_zone_http_request_late_transform.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ interactions:
6767
},
6868
"example-http-header-3": {
6969
"operation": "set",
70-
"value": "space-header",
7170
"expression": "(ip.geoip.continent eq \"pluto\")"
7271
}
7372
},
@@ -91,8 +90,7 @@ interactions:
9190
"headers": {
9291
"example-http-static-header-1": {
9392
"operation": "set",
94-
"value": "my-http-header-1",
95-
"expression": "(ip.geoip.continent eq \"T1\")"
93+
"value": "my-http-header-1"
9694
}
9795
}
9896
},
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
---
2+
version: 1
3+
interactions:
4+
- request:
5+
body: ""
6+
form: {}
7+
headers:
8+
Content-Type:
9+
- application/json
10+
url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets
11+
method: GET
12+
response:
13+
body: |
14+
{
15+
"result": [
16+
{
17+
"id": "c0e45d27315a4fa2bf62ffa2312f935b",
18+
"name": "default",
19+
"description": "",
20+
"kind": "zone",
21+
"version": "5",
22+
"last_updated": "2023-02-16T00:26:08.978517Z",
23+
"phase": "http_request_transform"
24+
}
25+
],
26+
"success": true,
27+
"errors": [],
28+
"messages": []
29+
}
30+
31+
headers:
32+
Content-Type:
33+
- application/json
34+
Vary:
35+
- Accept-Encoding
36+
status: 200 OK
37+
code: 200
38+
duration: ""
39+
- request:
40+
body: ""
41+
form: {}
42+
headers:
43+
Content-Type:
44+
- application/json
45+
url: https://api.cloudflare.com/client/v4/zones/0da42c8d2132a9ddaf714f9e7c920711/rulesets/c0e45d27315a4fa2bf62ffa2312f935b
46+
method: GET
47+
response:
48+
body: |
49+
{
50+
"result": {
51+
"id": "c0e45d27315a4fa2bf62ffa2312f935b",
52+
"name": "default",
53+
"description": "",
54+
"kind": "zone",
55+
"version": "5",
56+
"rules": [
57+
{
58+
"id": "1fb6a3117e864d46bcda192d14a1e1dc",
59+
"version": "5",
60+
"action": "rewrite",
61+
"expression": "true",
62+
"description": "rewrite with no query string",
63+
"last_updated": "2023-02-16T00:26:08.978517Z",
64+
"ref": "1fb6a3117e864d46bcda192d14a1e1dc",
65+
"enabled": true,
66+
"action_parameters": {
67+
"uri": {
68+
"query": {
69+
"value": ""
70+
}
71+
}
72+
}
73+
}
74+
],
75+
"last_updated": "2023-02-16T00:26:08.978517Z",
76+
"phase": "http_request_transform"
77+
},
78+
"success": true,
79+
"errors": [],
80+
"messages": []
81+
}
82+
headers:
83+
Content-Type:
84+
- application/json
85+
Vary:
86+
- Accept-Encoding
87+
status: 200 OK
88+
code: 200
89+
duration: ""

testdata/terraform/cloudflare_ruleset_http_request_cache_settings/test.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ resource "cloudflare_ruleset" "terraform_managed_resource" {
5454
description = "test cache rule"
5555
enabled = false
5656
expression = "(http.host eq \"example.com\")"
57+
id = "0f24aab3002347a9a4ac01520e6893d0"
5758
last_updated = "2022-09-28T17:21:21.510301Z"
59+
ref = "0f24aab3002347a9a4ac01520e6893d0"
60+
version = "3"
5861
}
5962
rules {
6063
action = "set_cache_settings"
@@ -68,6 +71,9 @@ resource "cloudflare_ruleset" "terraform_managed_resource" {
6871
description = "/status/202"
6972
enabled = true
7073
expression = "(http.host eq \"example.com\")"
74+
id = "e5f1bd1386b4464aa8d726ba1e0d51ad"
7175
last_updated = "2022-09-21T16:36:00.999083Z"
76+
ref = "e5f1bd1386b4464aa8d726ba1e0d51ad"
77+
version = "2"
7278
}
7379
}

testdata/terraform/cloudflare_ruleset_zone/test.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ resource "cloudflare_ruleset" "terraform_managed_resource" {
1717
}
1818
enabled = true
1919
expression = "true"
20+
id = "0789dc4343054d1e981f8c44bedc6fbd"
2021
last_updated = "2021-08-19T23:41:34.985519Z"
22+
ref = "0789dc4343054d1e981f8c44bedc6fbd"
23+
version = "1"
2124
}
2225
}

testdata/terraform/cloudflare_ruleset_zone_ddos_l7/test.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ resource "cloudflare_ruleset" "terraform_managed_resource" {
1515
description = "zone"
1616
enabled = true
1717
expression = "true"
18+
id = "c6893ad10fb344e9b8be3c0c3575adc9"
1819
last_updated = "2021-08-30T02:38:50.39057Z"
20+
ref = "c6893ad10fb344e9b8be3c0c3575adc9"
21+
version = "1"
1922
}
2023
}

testdata/terraform/cloudflare_ruleset_zone_http_log_custom_fields/test.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ resource "cloudflare_ruleset" "terraform_managed_resource" {
1313
description = "zone"
1414
enabled = true
1515
expression = "true"
16+
id = "17a0d1e23a3444ccbd5e58fc7793649a"
1617
last_updated = "2022-07-22T12:34:45.479429Z"
18+
ref = "17a0d1e23a3444ccbd5e58fc7793649a"
19+
version = "1"
1720
}
1821
}

testdata/terraform/cloudflare_ruleset_zone_http_ratelimit/test.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@ resource "cloudflare_ruleset" "terraform_managed_resource" {
88
description = "fwewe"
99
enabled = false
1010
expression = "(http.cookie eq \"namwe=value\")"
11+
id = "549e64153ff14d2cb5a5ef88c1f5bdbc"
1112
last_updated = "2021-08-29T21:59:21.447624Z"
1213
ratelimit {
1314
characteristics = ["ip.src", "cf.colo.id"]
1415
mitigation_timeout = 30
1516
period = 60
1617
requests_per_period = 100
1718
}
19+
ref = "549e64153ff14d2cb5a5ef88c1f5bdbc"
20+
version = "1"
1821
}
1922
}

testdata/terraform/cloudflare_ruleset_zone_http_request_firewall_custom/test.tf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,32 @@ resource "cloudflare_ruleset" "terraform_managed_resource" {
1313
description = "test.example.com"
1414
enabled = true
1515
expression = "(http.host eq \"test.example.com\")"
16+
id = "88dcb30401e348ba9e1352c2598f2a4c"
1617
last_updated = "2022-11-24T14:24:14.756247Z"
1718
logging {
1819
enabled = true
1920
}
21+
ref = "88dcb30401e348ba9e1352c2598f2a4c"
22+
version = "2"
2023
}
2124
rules {
2225
action = "challenge"
2326
description = "customRule-test"
2427
enabled = true
2528
expression = "(cf.bot_management.score eq 50 and cf.bot_management.static_resource)"
29+
id = "b3cc5e4cc6604f9d90a6a106df867760"
2630
last_updated = "2022-11-07T19:03:05.198191Z"
31+
ref = "b3cc5e4cc6604f9d90a6a106df867760"
32+
version = "29"
2733
}
2834
rules {
2935
action = "log"
3036
description = "AWAF ML"
3137
enabled = false
3238
expression = "(cf.waf.score le 20)"
39+
id = "1ecf73bdf7bd4227969a734412b13ad1"
3340
last_updated = "2022-12-09T16:53:19.003821Z"
41+
ref = "1ecf73bdf7bd4227969a734412b13ad1"
42+
version = "7"
3443
}
3544
}

testdata/terraform/cloudflare_ruleset_zone_http_request_late_transform/test.tf

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ resource "cloudflare_ruleset" "terraform_managed_resource" {
1818
expression = "(ip.geoip.continent eq \"pluto\")"
1919
name = "example-http-header-3"
2020
operation = "set"
21-
value = "space-header"
2221
}
2322
uri {
2423
path {
@@ -29,22 +28,27 @@ resource "cloudflare_ruleset" "terraform_managed_resource" {
2928
description = "test transform"
3029
enabled = true
3130
expression = "(http.request.uri.path eq \"example.com\")"
31+
id = "e5b61605d6cf4ce08f729c17d42d76ef"
3232
last_updated = "2022-02-07T16:58:54.317608Z"
33+
ref = "e5b61605d6cf4ce08f729c17d42d76ef"
34+
version = "1"
3335
}
3436
rules {
3537
action = "rewrite"
3638
action_parameters {
3739
headers {
38-
expression = "(ip.geoip.continent eq \"T1\")"
39-
name = "example-http-static-header-1"
40-
operation = "set"
41-
value = "my-http-header-1"
40+
name = "example-http-static-header-1"
41+
operation = "set"
42+
value = "my-http-header-1"
4243
}
4344
}
4445
description = "test transform set"
4546
enabled = true
4647
expression = "(http.request.uri.path eq \"example.com\")"
48+
id = "8ec764cf386940c89dd83dbab7bb4c16"
4749
last_updated = "2022-02-07T16:58:54.317608Z"
50+
ref = "8ec764cf386940c89dd83dbab7bb4c16"
51+
version = "1"
4852
}
4953
rules {
5054
action = "rewrite"
@@ -58,6 +62,9 @@ resource "cloudflare_ruleset" "terraform_managed_resource" {
5862
description = "test uri rewrite set"
5963
enabled = false
6064
expression = "(http.request.uri.path eq \"pumpkin.com\")"
65+
id = "d0f1b4fdb4234adf9c6de9b614424836"
6166
last_updated = "2022-05-07T16:58:54.317608Z"
67+
ref = "d0f1b4fdb4234adf9c6de9b614424836"
68+
version = "1"
6269
}
6370
}

testdata/terraform/cloudflare_ruleset_zone_http_request_sanitize/test.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ resource "cloudflare_ruleset" "terraform_managed_resource" {
1717
}
1818
enabled = true
1919
expression = "true"
20+
id = "0789dc4343054d1e981f8c44bedc6fbd"
2021
last_updated = "2021-08-19T23:41:34.985519Z"
22+
ref = "0789dc4343054d1e981f8c44bedc6fbd"
23+
version = "1"
2124
}
2225
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
terraform {
2+
required_providers {
3+
cloudflare = {
4+
source = "cloudflare/cloudflare"
5+
}
6+
}
7+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
resource "cloudflare_ruleset" "terraform_managed_resource" {
2+
kind = "zone"
3+
name = "default"
4+
phase = "http_request_transform"
5+
zone_id = "0da42c8d2132a9ddaf714f9e7c920711"
6+
rules {
7+
action = "rewrite"
8+
action_parameters {
9+
uri {
10+
query {
11+
value = ""
12+
}
13+
}
14+
}
15+
description = "rewrite with no query string"
16+
enabled = true
17+
expression = "true"
18+
id = "1fb6a3117e864d46bcda192d14a1e1dc"
19+
last_updated = "2023-02-16T00:26:08.978517Z"
20+
ref = "1fb6a3117e864d46bcda192d14a1e1dc"
21+
version = "5"
22+
}
23+
}

0 commit comments

Comments
 (0)