Skip to content

Commit e17bb26

Browse files
authored
Including #28726
* Initial Check-In... * Fix lint error... * Update test case names... * Mostly working now, need to fix one test... * Fix lint error... * Add test cases and CustomizeDiffShim... * Add custom_rule definition to jsChallengePolicyStandardSku test case... * Fix error return value... * Slightly tweak documentation and expose a CustomizeDiffShim for JSChallenge policy validation... * Add test case for invalid JSChallenge Policy... * Update tests... * Update documentation... * Format documentation... * Address PR comments...
1 parent 0996bec commit e17bb26

6 files changed

+601
-136
lines changed

internal/services/cdn/cdn_frontdoor_firewall_policy_data_source_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ func TestAccCdnFrontDoorFirewallPolicyDataSource_basic(t *testing.T) {
2828
})
2929
}
3030

31-
func TestAccCdnFrontDoorFirewallPolicyDataSourceJsChallenge_basic(t *testing.T) {
31+
func TestAccCdnFrontDoorFirewallPolicyDataSource_jsChallengeBasic(t *testing.T) {
3232
data := acceptance.BuildTestData(t, "data.azurerm_cdn_frontdoor_firewall_policy", "test")
3333
d := CdnFrontDoorFirewallPolicyDataSource{}
3434

3535
data.DataSourceTest(t, []acceptance.TestStep{
3636
{
37-
Config: d.basicJsChallenge(data),
37+
Config: d.jsChallengePolicyBasic(data),
3838
Check: acceptance.ComposeTestCheckFunc(
3939
check.That(data.ResourceName).Key("redirect_url").MatchesOtherKey(check.That("azurerm_cdn_frontdoor_firewall_policy.test").Key("redirect_url")),
4040
check.That(data.ResourceName).Key("js_challenge_cookie_expiration_in_minutes").HasValue("45"),
@@ -54,13 +54,13 @@ data "azurerm_cdn_frontdoor_firewall_policy" "test" {
5454
`, CdnFrontDoorFirewallPolicyResource{}.basic(data))
5555
}
5656

57-
func (CdnFrontDoorFirewallPolicyDataSource) basicJsChallenge(data acceptance.TestData) string {
57+
func (CdnFrontDoorFirewallPolicyDataSource) jsChallengePolicyBasic(data acceptance.TestData) string {
5858
return fmt.Sprintf(`
5959
%s
6060
6161
data "azurerm_cdn_frontdoor_firewall_policy" "test" {
6262
name = azurerm_cdn_frontdoor_firewall_policy.test.name
6363
resource_group_name = azurerm_resource_group.test.name
6464
}
65-
`, CdnFrontDoorFirewallPolicyResource{}.basicJsChallenge(data))
65+
`, CdnFrontDoorFirewallPolicyResource{}.jSChallengePolicyBasic(data))
6666
}

internal/services/cdn/cdn_frontdoor_firewall_policy_resource.go

Lines changed: 98 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package cdn
55

66
import (
7+
"context"
78
"fmt"
89
"strconv"
910
"strings"
@@ -79,11 +80,12 @@ func resourceCdnFrontDoorFirewallPolicy() *pluginsdk.Resource {
7980
},
8081

8182
// NOTE: Through local testing, the new API js challenge expiration is always
82-
// enabled no matter what and cannot be disabled...
83+
// enabled no matter what and cannot be disabled for Premium_AzureFrontDoor
84+
// and is not supported in Standard_AzureFrontDoor...
8385
"js_challenge_cookie_expiration_in_minutes": {
8486
Type: pluginsdk.TypeInt,
8587
Optional: true,
86-
Default: 30,
88+
Computed: true,
8789
ValidateFunc: validation.IntBetween(5, 1440),
8890
},
8991

@@ -458,6 +460,61 @@ func resourceCdnFrontDoorFirewallPolicy() *pluginsdk.Resource {
458460

459461
"tags": commonschema.Tags(),
460462
},
463+
464+
CustomizeDiff: pluginsdk.CustomDiffWithAll(
465+
// Verify that they are not downgrading the service from Premium SKU -> Standard SKU...
466+
pluginsdk.CustomizeDiffShim(func(ctx context.Context, diff *pluginsdk.ResourceDiff, v interface{}) error {
467+
oSku, nSku := diff.GetChange("sku_name")
468+
469+
if oSku != "" {
470+
if oSku.(string) == string(waf.SkuNamePremiumAzureFrontDoor) && nSku.(string) == string(waf.SkuNameStandardAzureFrontDoor) {
471+
return fmt.Errorf("downgrading from the %q sku to the %q sku is not supported, got %q", waf.SkuNamePremiumAzureFrontDoor, waf.SkuNameStandardAzureFrontDoor, nSku.(string))
472+
}
473+
}
474+
475+
return nil
476+
}),
477+
478+
// Verify that the Standard SKU is not setting the JSChallenge policy...
479+
pluginsdk.CustomizeDiffShim(func(ctx context.Context, diff *pluginsdk.ResourceDiff, v interface{}) error {
480+
sku := diff.Get("sku_name").(string)
481+
policyInMinutes := diff.Get("js_challenge_cookie_expiration_in_minutes").(int)
482+
483+
if sku == string(waf.SkuNameStandardAzureFrontDoor) && policyInMinutes > 0 {
484+
return fmt.Errorf("the 'js_challenge_cookie_expiration_in_minutes' field is only supported with the %q sku, got %q", waf.SkuNamePremiumAzureFrontDoor, sku)
485+
}
486+
487+
return nil
488+
}),
489+
490+
// Verify that the Standard SKU is not using managed rules...
491+
pluginsdk.CustomizeDiffShim(func(ctx context.Context, diff *pluginsdk.ResourceDiff, v interface{}) error {
492+
sku := diff.Get("sku_name").(string)
493+
managedRules := diff.Get("managed_rule").([]interface{})
494+
495+
if sku == string(waf.SkuNameStandardAzureFrontDoor) && len(managedRules) > 0 {
496+
return fmt.Errorf("the 'managed_rule' code block is only supported with the %q sku, got %q", waf.SkuNamePremiumAzureFrontDoor, sku)
497+
}
498+
499+
return nil
500+
}),
501+
502+
// Verify that the Standard SKU is not using the JSChallenge Action type for custom rules...
503+
pluginsdk.CustomizeDiffShim(func(ctx context.Context, diff *pluginsdk.ResourceDiff, v interface{}) error {
504+
sku := diff.Get("sku_name").(string)
505+
customRules := expandCdnFrontDoorFirewallCustomRules(diff.Get("custom_rule").([]interface{}))
506+
507+
if sku == string(waf.SkuNameStandardAzureFrontDoor) && customRules != nil {
508+
for _, v := range *customRules.Rules {
509+
if v.Action == waf.ActionTypeJSChallenge {
510+
return fmt.Errorf("'custom_rule' blocks with the 'action' type of 'JSChallenge' are only supported for the %q sku, got action: %q (custom_rule.name: %q, sku_name: %q)", waf.SkuNamePremiumAzureFrontDoor, waf.ActionTypeJSChallenge, *v.Name, sku)
511+
}
512+
}
513+
}
514+
515+
return nil
516+
}),
517+
),
461518
}
462519
}
463520

@@ -498,7 +555,6 @@ func resourceCdnFrontDoorFirewallPolicyCreate(d *pluginsdk.ResourceData, meta in
498555
sku := d.Get("sku_name").(string)
499556
mode := waf.PolicyMode(d.Get("mode").(string))
500557
redirectUrl := d.Get("redirect_url").(string)
501-
jsChallengeExpirationInMinutes := int64(d.Get("js_challenge_cookie_expiration_in_minutes").(int))
502558
customBlockResponseStatusCode := d.Get("custom_block_response_status_code").(int)
503559
customBlockResponseBody := d.Get("custom_block_response_body").(string)
504560
customRules := d.Get("custom_rule").([]interface{})
@@ -518,16 +574,29 @@ func resourceCdnFrontDoorFirewallPolicyCreate(d *pluginsdk.ResourceData, meta in
518574
},
519575
Properties: &waf.WebApplicationFirewallPolicyProperties{
520576
PolicySettings: &waf.PolicySettings{
521-
EnabledState: pointer.To(enabled),
522-
Mode: pointer.To(mode),
523-
RequestBodyCheck: pointer.To(requestBodyCheck),
524-
JavascriptChallengeExpirationInMinutes: pointer.To(jsChallengeExpirationInMinutes),
577+
EnabledState: pointer.To(enabled),
578+
Mode: pointer.To(mode),
579+
RequestBodyCheck: pointer.To(requestBodyCheck),
525580
},
526581
CustomRules: expandCdnFrontDoorFirewallCustomRules(customRules),
527582
},
528583
Tags: tags.Expand(d.Get("tags").(map[string]interface{})),
529584
}
530585

586+
// NOTE: JS Challenge Expiration policy is enabled by default on Premium SKU's with a default of
587+
// 30 minutes, if it is not in the config set the default and include it in the policy settings
588+
// payload block...
589+
if sku == string(waf.SkuNamePremiumAzureFrontDoor) {
590+
// Set the Default value...
591+
jsChallengeExpirationInMinutes := 30
592+
593+
if v, ok := d.GetOk("js_challenge_cookie_expiration_in_minutes"); ok {
594+
jsChallengeExpirationInMinutes = v.(int)
595+
}
596+
597+
payload.Properties.PolicySettings.JavascriptChallengeExpirationInMinutes = pointer.FromInt64(int64(jsChallengeExpirationInMinutes))
598+
}
599+
531600
if managedRules != nil {
532601
payload.Properties.ManagedRules = managedRules
533602
}
@@ -592,10 +661,22 @@ func resourceCdnFrontDoorFirewallPolicyUpdate(d *pluginsdk.ResourceData, meta in
592661
}
593662

594663
props.PolicySettings = &waf.PolicySettings{
595-
EnabledState: pointer.To(enabled),
596-
Mode: pointer.To(waf.PolicyMode(d.Get("mode").(string))),
597-
RequestBodyCheck: pointer.To(requestBodyCheck),
598-
JavascriptChallengeExpirationInMinutes: pointer.To(int64(d.Get("js_challenge_cookie_expiration_in_minutes").(int))),
664+
EnabledState: pointer.To(enabled),
665+
Mode: pointer.To(waf.PolicyMode(d.Get("mode").(string))),
666+
RequestBodyCheck: pointer.To(requestBodyCheck),
667+
}
668+
669+
// NOTE: js_challenge_cookie_expiration_in_minutes is only valid for
670+
// Premium_AzureFrontDoor skus...
671+
if model.Sku != nil && *model.Sku.Name == waf.SkuNamePremiumAzureFrontDoor {
672+
// Set the Default value...
673+
jsChallengeExpirationInMinutes := 30
674+
675+
if v, ok := d.GetOk("js_challenge_cookie_expiration_in_minutes"); ok {
676+
jsChallengeExpirationInMinutes = v.(int)
677+
}
678+
679+
props.PolicySettings.JavascriptChallengeExpirationInMinutes = pointer.FromInt64(int64(jsChallengeExpirationInMinutes))
599680
}
600681

601682
if redirectUrl := d.Get("redirect_url").(string); redirectUrl != "" {
@@ -691,7 +772,12 @@ func resourceCdnFrontDoorFirewallPolicyRead(d *pluginsdk.ResourceData, meta inte
691772
d.Set("redirect_url", policy.RedirectURL)
692773
d.Set("custom_block_response_status_code", int(pointer.From(policy.CustomBlockResponseStatusCode)))
693774
d.Set("custom_block_response_body", policy.CustomBlockResponseBody)
694-
d.Set("js_challenge_cookie_expiration_in_minutes", int(pointer.From(policy.JavascriptChallengeExpirationInMinutes)))
775+
776+
// NOTE: js_challenge_cookie_expiration_in_minutes is only returned
777+
// for Premium_AzureFrontDoor skus, else it will be 'nil'...
778+
if policy.JavascriptChallengeExpirationInMinutes != nil {
779+
d.Set("js_challenge_cookie_expiration_in_minutes", int(pointer.From(policy.JavascriptChallengeExpirationInMinutes)))
780+
}
695781
}
696782
}
697783

0 commit comments

Comments
 (0)