-
Notifications
You must be signed in to change notification settings - Fork 626
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add challenge and js_challenge rate-limit modes #172
Add challenge and js_challenge rate-limit modes #172
Conversation
}, | ||
|
||
"timeout": { | ||
Type: schema.TypeInt, | ||
Required: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As this is now optional based on the mode, we probably want to add a check in the Create
/Update
that if the mode is simulate or ban, we check the value is defined to prevent people scratching their heads with unintended behaviour.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I completely agree. The Cloudflare API does give reasonable error messages around this though it should really be caught by the provider before the API is called.
I'm just working on it at the moment, though this is the first time I've written any Go so you may have to forgive my non-idiomatic code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After grappling with attempting to insert validation into expandRateLimitAction
, I've realised that this won't behave quite as expected. I've attempted to implement a ValidateFunc
into the action
section of the schema itself (where I'll have access to both mode
and timeout
), but it appears that this is not supported on lists or sets at this point in time.
I'd appreciate any pointers as to how to proceed with this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... but it appears that this is not supported on lists or sets at this point in time.
Yep, the ValidateFunc
is only supported on primitive types which throws it out a bit.
I'd appreciate any pointers as to how to proceed with this.
Sure, I think this might do the job. You were on the right track with using expandRateLimitAction
as it's used in both the Create
and Update
. I haven't thoroughly vetted this though.
diff --git a/cloudflare/resource_cloudflare_rate_limit.go b/cloudflare/resource_cloudflare_rate_limit.go
index e67f1a4..dd0f170 100644
--- a/cloudflare/resource_cloudflare_rate_limit.go
+++ b/cloudflare/resource_cloudflare_rate_limit.go
@@ -197,11 +197,15 @@ func resourceCloudflareRateLimit() *schema.Resource {
func resourceCloudflareRateLimitCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*cloudflare.API)
+ rateLimitAction, err := expandRateLimitAction(d)
+ if err != nil {
+ return errors.Wrap(err, "error expanding rate limit action")
+ }
newRateLimit := cloudflare.RateLimit{
Threshold: d.Get("threshold").(int),
Period: d.Get("period").(int),
- Action: expandRateLimitAction(d),
+ Action: rateLimitAction,
}
newRateLimitMatch, err := expandRateLimitTrafficMatcher(d)
@@ -255,11 +259,15 @@ func resourceCloudflareRateLimitUpdate(d *schema.ResourceData, meta interface{})
client := meta.(*cloudflare.API)
zoneId := d.Get("zone_id").(string)
rateLimitId := d.Id()
+ rateLimitAction, err := expandRateLimitAction(d)
+ if err != nil {
+ return errors.Wrap(err, "error expanding rate limit action")
+ }
updatedRateLimit := cloudflare.RateLimit{
Threshold: d.Get("threshold").(int),
Period: d.Get("period").(int),
- Action: expandRateLimitAction(d),
+ Action: rateLimitAction,
}
newRateLimitMatch, err := expandRateLimitTrafficMatcher(d)
@@ -341,13 +349,21 @@ func expandRateLimitTrafficMatcher(d *schema.ResourceData) (matcher cloudflare.R
return
}
-func expandRateLimitAction(d *schema.ResourceData) cloudflare.RateLimitAction {
+func expandRateLimitAction(d *schema.ResourceData) (cloudflare.RateLimitAction, error) {
// dont need to guard for array length because MinItems is set **and** action is required
tfAction := d.Get("action").([]interface{})[0].(map[string]interface{})
+ mode := tfAction["mode"].(string)
+ timeout := tfAction["timeout"].(int)
+
+ if mode == "simulate" || mode == "ban" {
+ if timeout == 0 {
+ return cloudflare.RateLimitAction{}, fmt.Errorf("rate limit timeout must be set if the 'mode' is simulate or ban")
+ }
+ }
action := cloudflare.RateLimitAction{
- Mode: tfAction["mode"].(string),
- Timeout: tfAction["timeout"].(int),
+ Mode: mode,
+ Timeout: timeout,
}
if _, ok := tfAction["response"]; ok && len(tfAction["response"].([]interface{})) > 0 {
@@ -359,7 +375,7 @@ func expandRateLimitAction(d *schema.ResourceData) cloudflare.RateLimitAction {
Body: tfActionResponse["body"].(string),
}
}
- return action
+ return action, nil
}
func expandRateLimitCorrelate(d *schema.ResourceData) (correlate cloudflare.RateLimitCorrelate, err error) {
Do you want to try this and let me know how you go?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's absolutely brilliant, thanks for your help. I'd used fmt.Errorf
to raise errors, but hadn't wrapped them with errors.Wrap
. This now raises errors correctly.
I expanded the logic to throw an error when timeout values are provided for challenge
and js_challenge
modes as the Cloudflare API won't accept them.
The previous commit was just my current work in progress, unfortunately it didn't error during the I'm just in the process of applying the diff above and testing it. |
… to challenge and js_challenge modes
@jdarley is this ready for another review? |
I think it is @jacobbednarz. I've tested it manually by attempting to create challenge responses with a timeout and block/simulate without a timeout. I've introduced a couple of acceptance tests which I think will test this behaviour, though I've not yet sorted an environment to run the full suite of acceptance tests against. |
period = 1 | ||
action { | ||
mode = "challenge" | ||
timeoute = 60 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
timeoute = 60 | |
timeout = 60 |
I know they weren't all your changes however the diff --git a/cloudflare/resource_cloudflare_rate_limit_test.go b/cloudflare/resource_cloudflare_rate_limit_test.go
index 1a1ecbcad21e86c058420a5c9fdfb355064838b9..203142bb41028dc934a9501e265b88a1dd8a5d40 100644
--- a/cloudflare/resource_cloudflare_rate_limit_test.go
+++ b/cloudflare/resource_cloudflare_rate_limit_test.go
@@ -326,7 +326,7 @@ func testAccCheckCloudflareRateLimitConfigBasic(zone, id string) string {
resource "cloudflare_rate_limit" "%[1]s" {
zone = "%[2]s"
threshold = 1000
- period = 1
+ period = 10
action {
mode = "simulate"
timeout = 86400
@@ -339,7 +339,7 @@ func testAccCheckCloudflareRateLimitConfigMatchingUrl(zone, id string) string {
resource "cloudflare_rate_limit" "%[1]s" {
zone = "%[2]s"
threshold = 1000
- period = 1
+ period = 10
match {
request {
url_pattern = "%[2]s/tfacc-url-%[1]s"
@@ -357,7 +357,7 @@ func testAccCheckCloudflareRateLimitConfigFullySpecified(zone, id string) string
resource "cloudflare_rate_limit" "%[1]s" {
zone = "%[2]s"
threshold = 2000
- period = 2
+ period = 10
match {
request {
url_pattern = "%[2]s/tfacc-full-%[1]s"
@@ -391,7 +391,7 @@ func testAccCheckCloudflareRateLimitChallengeConfigBasic(zone, id string) string
resource "cloudflare_rate_limit" "%[1]s" {
zone = "%[2]s"
threshold = 1000
- period = 1
+ period = 10
action {
mode = "challenge"
}
@@ -403,7 +403,7 @@ func testAccCheckCloudflareRateLimitConfigWithoutTimeout(zone, id string) string
resource "cloudflare_rate_limit" "%[1]s" {
zone = "%[2]s"
threshold = 1000
- period = 1
+ period = 10
action {
mode = "simulate"
}
@@ -415,7 +415,7 @@ func testAccCheckCloudflareRateLimitChallengeConfigWithTimeout(zone, id string)
resource "cloudflare_rate_limit" "%[1]s" {
zone = "%[2]s"
threshold = 1000
- period = 1
+ period = 10
action {
mode = "challenge"
timeoute = 60 |
Very close @jdarley! Once we address the
|
Apologies for not getting this sorted sooner @jacobbednarz - I've had a couple of weeks completely away from the screen. Hopefully this last commit will get it over the line! |
No sweat @jdarley. Glad to hear you're taking time away from the screens 😄 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🚢
Thanks @jdarley! |
Minor update to add
challenge
andjs_challenge
support tocloudflare_rate_limit
resource.This has been manually tested and I can confirm it will create a rate limit with a
challenge
orjs_challenge
action as expected.This PR related to issue 171