Skip to content

Commit

Permalink
Merge pull request hashicorp#3913 from terraform-providers/f-waf-rege…
Browse files Browse the repository at this point in the history
…x-pattern-set

New Resource: aws_waf_regex_pattern_set
  • Loading branch information
radeksimko authored Mar 27, 2018
2 parents 4c4a6a4 + 98dae17 commit e6b0b62
Show file tree
Hide file tree
Showing 6 changed files with 447 additions and 0 deletions.
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ func Provider() terraform.ResourceProvider {
"aws_waf_ipset": resourceAwsWafIPSet(),
"aws_waf_rule": resourceAwsWafRule(),
"aws_waf_rate_based_rule": resourceAwsWafRateBasedRule(),
"aws_waf_regex_pattern_set": resourceAwsWafRegexPatternSet(),
"aws_waf_size_constraint_set": resourceAwsWafSizeConstraintSet(),
"aws_waf_web_acl": resourceAwsWafWebAcl(),
"aws_waf_xss_match_set": resourceAwsWafXssMatchSet(),
Expand Down
144 changes: 144 additions & 0 deletions aws/resource_aws_waf_regex_pattern_set.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package aws

import (
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/waf"
"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsWafRegexPatternSet() *schema.Resource {
return &schema.Resource{
Create: resourceAwsWafRegexPatternSetCreate,
Read: resourceAwsWafRegexPatternSetRead,
Update: resourceAwsWafRegexPatternSetUpdate,
Delete: resourceAwsWafRegexPatternSetDelete,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"regex_pattern_strings": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
}
}

func resourceAwsWafRegexPatternSetCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).wafconn

log.Printf("[INFO] Creating WAF Regex Pattern Set: %s", d.Get("name").(string))

wr := newWafRetryer(conn, "global")
out, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
params := &waf.CreateRegexPatternSetInput{
ChangeToken: token,
Name: aws.String(d.Get("name").(string)),
}
return conn.CreateRegexPatternSet(params)
})
if err != nil {
return fmt.Errorf("Failed creating WAF Regex Pattern Set: %s", err)
}
resp := out.(*waf.CreateRegexPatternSetOutput)

d.SetId(*resp.RegexPatternSet.RegexPatternSetId)

return resourceAwsWafRegexPatternSetUpdate(d, meta)
}

func resourceAwsWafRegexPatternSetRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).wafconn
log.Printf("[INFO] Reading WAF Regex Pattern Set: %s", d.Get("name").(string))
params := &waf.GetRegexPatternSetInput{
RegexPatternSetId: aws.String(d.Id()),
}

resp, err := conn.GetRegexPatternSet(params)
if err != nil {
// TODO: Replace with a constant once available
// See https://github.com/aws/aws-sdk-go/issues/1856
if isAWSErr(err, "WAFNonexistentItemException", "") {
log.Printf("[WARN] WAF Regex Pattern Set (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

return err
}

d.Set("name", resp.RegexPatternSet.Name)
d.Set("regex_pattern_strings", aws.StringValueSlice(resp.RegexPatternSet.RegexPatternStrings))

return nil
}

func resourceAwsWafRegexPatternSetUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).wafconn

log.Printf("[INFO] Updating WAF Regex Pattern Set: %s", d.Get("name").(string))

if d.HasChange("regex_pattern_strings") {
o, n := d.GetChange("regex_pattern_strings")
oldPatterns, newPatterns := o.(*schema.Set).List(), n.(*schema.Set).List()
err := updateWafRegexPatternSetPatternStrings(d.Id(), oldPatterns, newPatterns, conn)
if err != nil {
return fmt.Errorf("Failed updating WAF Regex Pattern Set: %s", err)
}
}

return resourceAwsWafRegexPatternSetRead(d, meta)
}

func resourceAwsWafRegexPatternSetDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).wafconn

oldPatterns := d.Get("regex_pattern_strings").(*schema.Set).List()
if len(oldPatterns) > 0 {
noPatterns := []interface{}{}
err := updateWafRegexPatternSetPatternStrings(d.Id(), oldPatterns, noPatterns, conn)
if err != nil {
return fmt.Errorf("Error updating WAF Regex Pattern Set: %s", err)
}
}

wr := newWafRetryer(conn, "global")
_, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
req := &waf.DeleteRegexPatternSetInput{
ChangeToken: token,
RegexPatternSetId: aws.String(d.Id()),
}
log.Printf("[INFO] Deleting WAF Regex Pattern Set: %s", req)
return conn.DeleteRegexPatternSet(req)
})
if err != nil {
return fmt.Errorf("Failed deleting WAF Regex Pattern Set: %s", err)
}

return nil
}

func updateWafRegexPatternSetPatternStrings(id string, oldPatterns, newPatterns []interface{}, conn *waf.WAF) error {
wr := newWafRetryer(conn, "global")
_, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
req := &waf.UpdateRegexPatternSetInput{
ChangeToken: token,
RegexPatternSetId: aws.String(id),
Updates: diffWafRegexPatternSetPatternStrings(oldPatterns, newPatterns),
}

return conn.UpdateRegexPatternSet(req)
})
if err != nil {
return fmt.Errorf("Failed updating WAF Regex Pattern Set: %s", err)
}

return nil
}
231 changes: 231 additions & 0 deletions aws/resource_aws_waf_regex_pattern_set_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
package aws

import (
"fmt"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/waf"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSWafRegexPatternSet_basic(t *testing.T) {
var v waf.RegexPatternSet
patternSetName := fmt.Sprintf("tfacc-%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSWafRegexPatternSetDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSWafRegexPatternSetConfig(patternSetName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSWafRegexPatternSetExists("aws_waf_regex_pattern_set.test", &v),
resource.TestCheckResourceAttr("aws_waf_regex_pattern_set.test", "name", patternSetName),
resource.TestCheckResourceAttr("aws_waf_regex_pattern_set.test", "regex_pattern_strings.#", "2"),
resource.TestCheckResourceAttr("aws_waf_regex_pattern_set.test", "regex_pattern_strings.2848565413", "one"),
resource.TestCheckResourceAttr("aws_waf_regex_pattern_set.test", "regex_pattern_strings.3351840846", "two"),
),
},
},
})
}

func TestAccAWSWafRegexPatternSet_changePatterns(t *testing.T) {
var before, after waf.RegexPatternSet
patternSetName := fmt.Sprintf("tfacc-%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSWafRegexPatternSetDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSWafRegexPatternSetConfig(patternSetName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckAWSWafRegexPatternSetExists("aws_waf_regex_pattern_set.test", &before),
resource.TestCheckResourceAttr("aws_waf_regex_pattern_set.test", "name", patternSetName),
resource.TestCheckResourceAttr("aws_waf_regex_pattern_set.test", "regex_pattern_strings.#", "2"),
resource.TestCheckResourceAttr("aws_waf_regex_pattern_set.test", "regex_pattern_strings.2848565413", "one"),
resource.TestCheckResourceAttr("aws_waf_regex_pattern_set.test", "regex_pattern_strings.3351840846", "two"),
),
},
{
Config: testAccAWSWafRegexPatternSetConfig_changePatterns(patternSetName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckAWSWafRegexPatternSetExists("aws_waf_regex_pattern_set.test", &after),
resource.TestCheckResourceAttr("aws_waf_regex_pattern_set.test", "name", patternSetName),
resource.TestCheckResourceAttr("aws_waf_regex_pattern_set.test", "regex_pattern_strings.#", "3"),
resource.TestCheckResourceAttr("aws_waf_regex_pattern_set.test", "regex_pattern_strings.3351840846", "two"),
resource.TestCheckResourceAttr("aws_waf_regex_pattern_set.test", "regex_pattern_strings.2929247714", "three"),
resource.TestCheckResourceAttr("aws_waf_regex_pattern_set.test", "regex_pattern_strings.1294846542", "four"),
),
},
},
})
}

func TestAccAWSWafRegexPatternSet_noPatterns(t *testing.T) {
var patternSet waf.RegexPatternSet
patternSetName := fmt.Sprintf("tfacc-%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSWafRegexPatternSetDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSWafRegexPatternSetConfig_noPatterns(patternSetName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckAWSWafRegexPatternSetExists("aws_waf_regex_pattern_set.test", &patternSet),
resource.TestCheckResourceAttr("aws_waf_regex_pattern_set.test", "name", patternSetName),
resource.TestCheckResourceAttr("aws_waf_regex_pattern_set.test", "regex_pattern_strings.#", "0"),
),
},
},
})
}

func TestAccAWSWafRegexPatternSet_disappears(t *testing.T) {
var v waf.RegexPatternSet
patternSetName := fmt.Sprintf("tfacc-%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSWafRegexPatternSetDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSWafRegexPatternSetConfig(patternSetName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSWafRegexPatternSetExists("aws_waf_regex_pattern_set.test", &v),
testAccCheckAWSWafRegexPatternSetDisappears(&v),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func testAccCheckAWSWafRegexPatternSetDisappears(set *waf.RegexPatternSet) resource.TestCheckFunc {
return func(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).wafconn

wr := newWafRetryer(conn, "global")
_, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
req := &waf.UpdateRegexPatternSetInput{
ChangeToken: token,
RegexPatternSetId: set.RegexPatternSetId,
}

for _, pattern := range set.RegexPatternStrings {
update := &waf.RegexPatternSetUpdate{
Action: aws.String("DELETE"),
RegexPatternString: pattern,
}
req.Updates = append(req.Updates, update)
}

return conn.UpdateRegexPatternSet(req)
})
if err != nil {
return fmt.Errorf("Failed updating WAF Regex Pattern Set: %s", err)
}

_, err = wr.RetryWithToken(func(token *string) (interface{}, error) {
opts := &waf.DeleteRegexPatternSetInput{
ChangeToken: token,
RegexPatternSetId: set.RegexPatternSetId,
}
return conn.DeleteRegexPatternSet(opts)
})
if err != nil {
return fmt.Errorf("Failed deleting WAF Regex Pattern Set: %s", err)
}

return nil
}
}

func testAccCheckAWSWafRegexPatternSetExists(n string, v *waf.RegexPatternSet) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("No WAF Regex Pattern Set ID is set")
}

conn := testAccProvider.Meta().(*AWSClient).wafconn
resp, err := conn.GetRegexPatternSet(&waf.GetRegexPatternSetInput{
RegexPatternSetId: aws.String(rs.Primary.ID),
})

if err != nil {
return err
}

if *resp.RegexPatternSet.RegexPatternSetId == rs.Primary.ID {
*v = *resp.RegexPatternSet
return nil
}

return fmt.Errorf("WAF Regex Pattern Set (%s) not found", rs.Primary.ID)
}
}

func testAccCheckAWSWafRegexPatternSetDestroy(s *terraform.State) error {
for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_waf_regex_pattern_set" {
continue
}

conn := testAccProvider.Meta().(*AWSClient).wafconn
resp, err := conn.GetRegexPatternSet(&waf.GetRegexPatternSetInput{
RegexPatternSetId: aws.String(rs.Primary.ID),
})

if err == nil {
if *resp.RegexPatternSet.RegexPatternSetId == rs.Primary.ID {
return fmt.Errorf("WAF Regex Pattern Set %s still exists", rs.Primary.ID)
}
}

// Return nil if the Regex Pattern Set is already destroyed
if isAWSErr(err, "WAFNonexistentItemException", "") {
return nil
}

return err
}

return nil
}

func testAccAWSWafRegexPatternSetConfig(name string) string {
return fmt.Sprintf(`
resource "aws_waf_regex_pattern_set" "test" {
name = "%s"
regex_pattern_strings = ["one", "two"]
}`, name)
}

func testAccAWSWafRegexPatternSetConfig_changePatterns(name string) string {
return fmt.Sprintf(`
resource "aws_waf_regex_pattern_set" "test" {
name = "%s"
regex_pattern_strings = ["two", "three", "four"]
}`, name)
}

func testAccAWSWafRegexPatternSetConfig_noPatterns(name string) string {
return fmt.Sprintf(`
resource "aws_waf_regex_pattern_set" "test" {
name = "%s"
}`, name)
}
Loading

0 comments on commit e6b0b62

Please sign in to comment.