Skip to content
This repository has been archived by the owner on Jan 13, 2023. It is now read-only.

Commit

Permalink
resources: WAF: handles properly when the target has been deleted on …
Browse files Browse the repository at this point in the history
…Cloudflare's side

In the previous situation, when the target had been deleted, the Read
accion would fail and return an error. However, this would be expected
that when this happen, the object should be considered as not existing
anymore and the process should continue.  This thus fixes that and makes
sure that we avoid erroring out when a WAF Rule, Group or Package has
been deleted on Cloudflare's side.
  • Loading branch information
XaF committed Mar 13, 2020
1 parent a529403 commit 6bdc868
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 3 deletions.
9 changes: 8 additions & 1 deletion cloudflare/resource_cloudflare_waf_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,14 @@ func resourceCloudflareWAFGroupRead(d *schema.ResourceData, meta interface{}) er

group, err := client.WAFGroup(zoneID, packageID, groupID)
if err != nil {
return (err)
// 1002 is the 'Invalid or missing WAF Package ID' error
// 1003 is the 'Invalid or missing WAF Rule Set ID' error
if cloudflareErrorIsOneOfCodes(err, []int{1002, 1003}) {
d.SetId("")
return nil
}

return err
}

// Only need to set mode as that is the only attribute that could have changed
Expand Down
8 changes: 7 additions & 1 deletion cloudflare/resource_cloudflare_waf_package.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,13 @@ func resourceCloudflareWAFPackageRead(d *schema.ResourceData, meta interface{})

pkg, err := client.WAFPackage(zoneID, packageID)
if err != nil {
return (err)
// 1002 is the 'Invalid or missing WAF Package ID' error
if cloudflareErrorIsCode(err, 1002) {
d.SetId("")
return nil
}

return err
}

d.Set("sensitivity", pkg.Sensitivity)
Expand Down
9 changes: 8 additions & 1 deletion cloudflare/resource_cloudflare_waf_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,14 @@ func resourceCloudflareWAFRuleRead(d *schema.ResourceData, meta interface{}) err

rule, err := client.WAFRule(zoneID, packageID, ruleID)
if err != nil {
return (err)
// 1002 is the 'Invalid or missing WAF Package ID' error
// 1004 is the 'Invalid or missing WAF Rule ID' error
if cloudflareErrorIsOneOfCodes(err, []int{1002, 1004}) {
d.SetId("")
return nil
}

return err
}

// Only need to set mode as that is the only attribute that could have changed
Expand Down
46 changes: 46 additions & 0 deletions cloudflare/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ package cloudflare

import (
"crypto/md5"
"encoding/json"
"fmt"
"log"
"regexp"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
errors "github.com/pkg/errors"
)

func expandInterfaceToStringList(list interface{}) []string {
Expand Down Expand Up @@ -62,3 +67,44 @@ func contains(slice []string, item string) bool {
_, ok := set[item]
return ok
}

type CloudflareAPIError struct {
Code int `json:"code"`
Message string `json:"message"`
}

type CloudflareAPIErrorResponse struct {
Errors []CloudflareAPIError `json:"errors"`
}

func cloudflareErrorIsCode(err error, code int) bool {
return cloudflareErrorIsOneOfCodes(err, []int{code})
}

func cloudflareErrorIsOneOfCodes(err error, codes []int) bool {
errorMsg := errors.Cause(err).Error()

// We will parse the error message only if it's an error 400, in which
// case we need to verify the kind of error.
r := regexp.MustCompile(`^HTTP status 400: content "(.*)"$`)
submatchs := r.FindStringSubmatch(errorMsg)
if submatchs != nil {
jsonData := strings.Replace(submatchs[1], "\\\"", "\"", -1)
log.Printf("[DEBUG][cloudflareErrorIsCode] error matching status 400, content: %#v", jsonData)

var cfer CloudflareAPIErrorResponse
unmarshalErr := json.Unmarshal([]byte(jsonData), &cfer)

// We check that there is only one error and that its code
// matches what we expected
if unmarshalErr == nil && len(cfer.Errors) == 1 {
for _, code := range codes {
if cfer.Errors[0].Code == code {
return true
}
}
}
}

return false
}

0 comments on commit 6bdc868

Please sign in to comment.