From f8b70a696042eaa540f2ce4970941e0419ad9910 Mon Sep 17 00:00:00 2001 From: The Magician Date: Fri, 6 Dec 2024 11:54:01 -0800 Subject: [PATCH] Fixed recaptcha_options permadiff causing rules being recreated (#12458) (#20617) [upstream:b0b7f57d696854f3025089d6866a2c8a385c5536] Signed-off-by: Modular Magician --- .changelog/12458.txt | 3 ++ .../resource_compute_security_policy.go | 54 ++++++++++++------- 2 files changed, 37 insertions(+), 20 deletions(-) create mode 100644 .changelog/12458.txt diff --git a/.changelog/12458.txt b/.changelog/12458.txt new file mode 100644 index 00000000000..a0b79d03306 --- /dev/null +++ b/.changelog/12458.txt @@ -0,0 +1,3 @@ +```release-note:bug +compute: fixed permadiff on the `recaptcha_options` field for `google_compute_security_policy` resource +``` \ No newline at end of file diff --git a/google/services/compute/resource_compute_security_policy.go b/google/services/compute/resource_compute_security_policy.go index b66ca41d26a..b16d61bba27 100644 --- a/google/services/compute/resource_compute_security_policy.go +++ b/google/services/compute/resource_compute_security_policy.go @@ -22,6 +22,26 @@ import ( "google.golang.org/api/compute/v1" ) +func verifyRulePriorityCompareEmptyValues(d *schema.ResourceData, rulePriority int, schemaKey string) bool { + if schemaRules, ok := d.GetOk("rule"); ok { + for _, itemRaw := range schemaRules.(*schema.Set).List() { + if itemRaw == nil { + continue + } + item := itemRaw.(map[string]interface{}) + + schemaPriority := item["priority"].(int) + if rulePriority == schemaPriority { + if tpgresource.IsEmptyValue(reflect.ValueOf(item[schemaKey])) { + return true + } + break + } + } + } + return false +} + // IsEmptyValue does not consider a empty PreconfiguredWafConfig object as empty so we check it's nested values func preconfiguredWafConfigIsEmptyValue(config *compute.SecurityPolicyRulePreconfiguredWafConfig) bool { if tpgresource.IsEmptyValue(reflect.ValueOf(config.Exclusions)) && @@ -1155,7 +1175,7 @@ func flattenSecurityPolicyRules(rules []*compute.SecurityPolicyRule, d *schema.R "priority": rule.Priority, "action": rule.Action, "preview": rule.Preview, - "match": flattenMatch(rule.Match), + "match": flattenMatch(rule.Match, d, int(rule.Priority)), "preconfigured_waf_config": flattenPreconfiguredWafConfig(rule.PreconfiguredWafConfig, d, int(rule.Priority)), "rate_limit_options": flattenSecurityPolicyRuleRateLimitOptions(rule.RateLimitOptions), "redirect_options": flattenSecurityPolicyRedirectOptions(rule.RedirectOptions), @@ -1166,7 +1186,7 @@ func flattenSecurityPolicyRules(rules []*compute.SecurityPolicyRule, d *schema.R return rulesSchema } -func flattenMatch(match *compute.SecurityPolicyRuleMatcher) []map[string]interface{} { +func flattenMatch(match *compute.SecurityPolicyRuleMatcher, d *schema.ResourceData, rulePriority int) []map[string]interface{} { if match == nil { return nil } @@ -1175,7 +1195,7 @@ func flattenMatch(match *compute.SecurityPolicyRuleMatcher) []map[string]interfa "versioned_expr": match.VersionedExpr, "config": flattenMatchConfig(match.Config), "expr": flattenMatchExpr(match), - "expr_options": flattenMatchExprOptions(match.ExprOptions), + "expr_options": flattenMatchExprOptions(match.ExprOptions, d, rulePriority), } return []map[string]interface{}{data} @@ -1193,11 +1213,18 @@ func flattenMatchConfig(conf *compute.SecurityPolicyRuleMatcherConfig) []map[str return []map[string]interface{}{data} } -func flattenMatchExprOptions(exprOptions *compute.SecurityPolicyRuleMatcherExprOptions) []map[string]interface{} { +func flattenMatchExprOptions(exprOptions *compute.SecurityPolicyRuleMatcherExprOptions, d *schema.ResourceData, rulePriority int) []map[string]interface{} { if exprOptions == nil { return nil } + // We check if the API is returning a empty non-null value then we find the current value for this field in the rule config and check if its empty + if (tpgresource.IsEmptyValue(reflect.ValueOf(exprOptions.RecaptchaOptions.ActionTokenSiteKeys)) && + tpgresource.IsEmptyValue(reflect.ValueOf(exprOptions.RecaptchaOptions.SessionTokenSiteKeys))) && + verifyRulePriorityCompareEmptyValues(d, rulePriority, "recaptcha_options") { + return nil + } + data := map[string]interface{}{ "recaptcha_options": flattenMatchExprOptionsRecaptchaOptions(exprOptions.RecaptchaOptions), } @@ -1239,22 +1266,9 @@ func flattenPreconfiguredWafConfig(config *compute.SecurityPolicyRulePreconfigur return nil } - // We find the current value for this field in the config and check if its empty, then check if the API is returning a empty non-null value - if schemaRules, ok := d.GetOk("rule"); ok { - for _, itemRaw := range schemaRules.(*schema.Set).List() { - if itemRaw == nil { - continue - } - item := itemRaw.(map[string]interface{}) - - schemaPriority := item["priority"].(int) - if rulePriority == schemaPriority { - if preconfiguredWafConfigIsEmptyValue(config) && tpgresource.IsEmptyValue(reflect.ValueOf(item["preconfigured_waf_config"])) { - return nil - } - break - } - } + // We check if the API is returning a empty non-null value then we find the current value for this field in the rule config and check if its empty + if preconfiguredWafConfigIsEmptyValue(config) && verifyRulePriorityCompareEmptyValues(d, rulePriority, "preconfigured_waf_config") { + return nil } data := map[string]interface{}{