Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 195 additions & 2 deletions internal/services/cdn/cdn_frontdoor_firewall_policy_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,57 @@ func resourceCdnFrontDoorFirewallPolicy() *pluginsdk.Resource {
},
},

"log_scrubbing": {
Type: pluginsdk.TypeList,
MaxItems: 1,
Optional: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"enabled": {
Type: pluginsdk.TypeBool,
Optional: true,
Default: true,
},

"scrubbing_rule": {
Type: pluginsdk.TypeList,
MaxItems: 100,
Required: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"enabled": {
Type: pluginsdk.TypeBool,
Optional: true,
Default: true,
},

"match_variable": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice(waf.PossibleValuesForScrubbingRuleEntryMatchVariable(),
false),
},

"operator": {
Type: pluginsdk.TypeString,
Optional: true,
Default: string(waf.ScrubbingRuleEntryMatchOperatorEquals),
ValidateFunc: validation.StringInSlice(waf.PossibleValuesForScrubbingRuleEntryMatchOperator(),
false),
},

"selector": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: validation.StringIsNotEmpty,
},
},
},
},
},
},
},

"frontend_endpoint_ids": {
Type: pluginsdk.TypeList,
Computed: true,
Expand Down Expand Up @@ -514,6 +565,17 @@ func resourceCdnFrontDoorFirewallPolicy() *pluginsdk.Resource {

return nil
}),

// Verify that the scrubbing_rule's are valid...
pluginsdk.CustomizeDiffShim(func(ctx context.Context, diff *pluginsdk.ResourceDiff, v interface{}) error {
if v, ok := diff.GetOk("log_scrubbing"); ok {
_, err := expandCdnFrontDoorFirewallLogScrubbingPolicy(v.([]interface{}))
if err != nil {
return err
}
}
return nil
}),
),
}
}
Expand Down Expand Up @@ -558,9 +620,15 @@ func resourceCdnFrontDoorFirewallPolicyCreate(d *pluginsdk.ResourceData, meta in
customBlockResponseStatusCode := d.Get("custom_block_response_status_code").(int)
customBlockResponseBody := d.Get("custom_block_response_body").(string)
customRules := d.Get("custom_rule").([]interface{})

managedRules, err := expandCdnFrontDoorFirewallManagedRules(d.Get("managed_rule").([]interface{}))
if err != nil {
return fmt.Errorf("expanding managed_rule: %+v", err)
return fmt.Errorf("expanding 'managed_rule': %+v", err)
}

logScrubbingRules, err := expandCdnFrontDoorFirewallLogScrubbingPolicy(d.Get("log_scrubbing").([]interface{}))
if err != nil {
return fmt.Errorf("expanding 'log_scrubbing': %+v", err)
}

if sku != string(waf.SkuNamePremiumAzureFrontDoor) && managedRules != nil {
Expand Down Expand Up @@ -613,6 +681,10 @@ func resourceCdnFrontDoorFirewallPolicyCreate(d *pluginsdk.ResourceData, meta in
payload.Properties.PolicySettings.CustomBlockResponseStatusCode = pointer.To(int64(customBlockResponseStatusCode))
}

if logScrubbingRules != nil {
payload.Properties.PolicySettings.LogScrubbing = logScrubbingRules
}

err = client.PoliciesCreateOrUpdateThenPoll(ctx, id, payload)
if err != nil {
return fmt.Errorf("creating %s: %+v", id, err)
Expand Down Expand Up @@ -649,7 +721,7 @@ func resourceCdnFrontDoorFirewallPolicyUpdate(d *pluginsdk.ResourceData, meta in

props := *model.Properties

if d.HasChanges("custom_block_response_body", "custom_block_response_status_code", "enabled", "mode", "redirect_url", "request_body_check_enabled", "js_challenge_cookie_expiration_in_minutes") {
if d.HasChanges("custom_block_response_body", "custom_block_response_status_code", "enabled", "mode", "redirect_url", "request_body_check_enabled", "js_challenge_cookie_expiration_in_minutes", "log_scrubbing") {
enabled := waf.PolicyEnabledStateDisabled
if d.Get("enabled").(bool) {
enabled = waf.PolicyEnabledStateEnabled
Expand Down Expand Up @@ -715,6 +787,17 @@ func resourceCdnFrontDoorFirewallPolicyUpdate(d *pluginsdk.ResourceData, meta in
}
}

if d.HasChange("log_scrubbing") {
logScrubbingPolicy, err := expandCdnFrontDoorFirewallLogScrubbingPolicy(d.Get("log_scrubbing").([]interface{}))
if err != nil {
return err
}

if logScrubbingPolicy != nil {
props.PolicySettings.LogScrubbing = logScrubbingPolicy
}
}

if d.HasChange("tags") {
model.Tags = tags.Expand(d.Get("tags").(map[string]interface{}))
}
Expand Down Expand Up @@ -778,6 +861,10 @@ func resourceCdnFrontDoorFirewallPolicyRead(d *pluginsdk.ResourceData, meta inte
if policy.JavascriptChallengeExpirationInMinutes != nil {
d.Set("js_challenge_cookie_expiration_in_minutes", int(pointer.From(policy.JavascriptChallengeExpirationInMinutes)))
}

if err := d.Set("log_scrubbing", flattenCdnFrontDoorFirewallLogScrubbingPolicy(policy.LogScrubbing)); err != nil {
return fmt.Errorf("flattening 'log_scrubbing': %+v", err)
}
}
}

Expand Down Expand Up @@ -1041,6 +1128,80 @@ func expandCdnFrontDoorFirewallRuleOverride(input []interface{}, versionRaw stri
return &result, nil
}

func expandCdnFrontDoorFirewallLogScrubbingPolicy(input []interface{}) (*waf.PolicySettingsLogScrubbing, error) {
if len(input) == 0 {
return nil, nil
}

inputRaw := input[0].(map[string]interface{})

policyEnabled := waf.WebApplicationFirewallScrubbingStateDisabled
if inputRaw["enabled"].(bool) {
policyEnabled = waf.WebApplicationFirewallScrubbingStateEnabled
}

scrubbingRules, err := expandCdnFrontDoorFirewallScrubbingRules(inputRaw["scrubbing_rule"].([]interface{}))
if err != nil {
return nil, err
}

return &waf.PolicySettingsLogScrubbing{
State: pointer.To(policyEnabled),
ScrubbingRules: scrubbingRules,
}, nil
}

func expandCdnFrontDoorFirewallScrubbingRules(input []interface{}) (*[]waf.WebApplicationFirewallScrubbingRules, error) {
if len(input) == 0 {
return nil, nil
}

scrubbingRules := make([]waf.WebApplicationFirewallScrubbingRules, 0)

for _, rule := range input {
v := rule.(map[string]interface{})
var item waf.WebApplicationFirewallScrubbingRules

enalbed := waf.ScrubbingRuleEntryStateDisabled
if value := v["enabled"].(bool); value {
enalbed = waf.ScrubbingRuleEntryStateEnabled
}

item.State = pointer.To(enalbed)
item.MatchVariable = waf.ScrubbingRuleEntryMatchVariable(v["match_variable"].(string))
item.SelectorMatchOperator = waf.ScrubbingRuleEntryMatchOperator(v["operator"].(string))

if selector, ok := v["selector"]; ok {
item.Selector = pointer.To(selector.(string))
}

// NOTE: Validate the rules configuration...
switch {
case item.MatchVariable == waf.ScrubbingRuleEntryMatchVariableRequestIPAddress || item.MatchVariable == waf.ScrubbingRuleEntryMatchVariableRequestUri:
// NOTE: 'RequestIPAddress' and 'RequestUri' 'match_variable's can only use the 'EqualsAny' 'operator'...
if item.SelectorMatchOperator != waf.ScrubbingRuleEntryMatchOperatorEqualsAny {
return nil, fmt.Errorf("the %q 'match_variable' must use the %q 'operator', got %q", item.MatchVariable, waf.ScrubbingRuleEntryMatchOperatorEqualsAny, item.SelectorMatchOperator)
}

case item.SelectorMatchOperator == waf.ScrubbingRuleEntryMatchOperatorEquals:
// NOTE: If the 'operator' is set to 'Equals' the 'selector' cannot be 'nil'...
if pointer.From(item.Selector) == "" {
return nil, fmt.Errorf("the 'selector' field must be set when the %q 'operator' is used, got %q", waf.ScrubbingRuleEntryMatchOperatorEquals, "nil")
}

case item.SelectorMatchOperator == waf.ScrubbingRuleEntryMatchOperatorEqualsAny:
// NOTE: If the 'operator' is set to 'EqualsAny' the 'selector' must be 'nil'...
if pointer.From(item.Selector) != "" {
return nil, fmt.Errorf("the 'selector' field cannot be set when the %q 'operator' is used, got %q", waf.ScrubbingRuleEntryMatchOperatorEqualsAny, *item.Selector)
}
}

scrubbingRules = append(scrubbingRules, item)
}

return pointer.To(scrubbingRules), nil
}

func flattenCdnFrontDoorFirewallCustomRules(input *waf.CustomRuleList) []interface{} {
if input == nil || input.Rules == nil {
return []interface{}{}
Expand Down Expand Up @@ -1204,3 +1365,35 @@ func flattenCdnFrontDoorFirewallRules(input *[]waf.ManagedRuleOverride) []interf

return results
}

func flattenCdnFrontDoorFirewallLogScrubbingPolicy(input *waf.PolicySettingsLogScrubbing) []interface{} {
if input == nil {
return make([]interface{}, 0)
}

result := make(map[string]interface{})
result["enabled"] = pointer.From(input.State) == waf.WebApplicationFirewallScrubbingStateEnabled
result["scrubbing_rule"] = flattenCdnFrontDoorFirewallLogScrubbingRules(input.ScrubbingRules)

return []interface{}{result}
}

func flattenCdnFrontDoorFirewallLogScrubbingRules(scrubbingRules *[]waf.WebApplicationFirewallScrubbingRules) interface{} {
result := make([]interface{}, 0)

if scrubbingRules == nil || len(*scrubbingRules) == 0 {
return result
}

for _, scrubbingRule := range *scrubbingRules {
item := map[string]interface{}{}
item["enabled"] = pointer.From(scrubbingRule.State) == waf.ScrubbingRuleEntryStateEnabled
item["match_variable"] = scrubbingRule.MatchVariable
item["operator"] = scrubbingRule.SelectorMatchOperator
item["selector"] = pointer.From(scrubbingRule.Selector)

result = append(result, item)
}

return result
}
Loading
Loading