provider/aws: AWS WAF Regional IPSet + ByteMatchSet support (#13705)
* provider/aws: AWS WAF Regional ByteMatchSet support * providor/aws: AWS WAF Regional IPSet support * fix typo * Nested ByteMatchTuples of WAF Regional support * fix name byte_match_tuple singular WAF Regional * update wafregional_byte_match_set doc * fix wafregional ipset to look descriptor * Add wafregional_byte_match_set test * fix wafregional_ipset_descriptor to be singular * fix newWafRegionalRetryer to receive region * fix updateSetWR argument * fix wafregional_ipset_descriptor doc * Separate out logic into flatteners * Fix failing test
This commit is contained in:
parent
5367f2607e
commit
3b14fc90d9
|
@ -66,6 +66,7 @@ import (
|
||||||
"github.com/aws/aws-sdk-go/service/ssm"
|
"github.com/aws/aws-sdk-go/service/ssm"
|
||||||
"github.com/aws/aws-sdk-go/service/sts"
|
"github.com/aws/aws-sdk-go/service/sts"
|
||||||
"github.com/aws/aws-sdk-go/service/waf"
|
"github.com/aws/aws-sdk-go/service/waf"
|
||||||
|
"github.com/aws/aws-sdk-go/service/wafregional"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
"github.com/hashicorp/errwrap"
|
"github.com/hashicorp/errwrap"
|
||||||
"github.com/hashicorp/go-cleanhttp"
|
"github.com/hashicorp/go-cleanhttp"
|
||||||
|
@ -172,6 +173,7 @@ type AWSClient struct {
|
||||||
sfnconn *sfn.SFN
|
sfnconn *sfn.SFN
|
||||||
ssmconn *ssm.SSM
|
ssmconn *ssm.SSM
|
||||||
wafconn *waf.WAF
|
wafconn *waf.WAF
|
||||||
|
wafregionalconn *wafregional.WAFRegional
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *AWSClient) S3() *s3.S3 {
|
func (c *AWSClient) S3() *s3.S3 {
|
||||||
|
@ -379,6 +381,7 @@ func (c *Config) Client() (interface{}, error) {
|
||||||
client.sqsconn = sqs.New(awsSqsSess)
|
client.sqsconn = sqs.New(awsSqsSess)
|
||||||
client.ssmconn = ssm.New(sess)
|
client.ssmconn = ssm.New(sess)
|
||||||
client.wafconn = waf.New(sess)
|
client.wafconn = waf.New(sess)
|
||||||
|
client.wafregionalconn = wafregional.New(sess)
|
||||||
|
|
||||||
return &client, nil
|
return &client, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -457,6 +457,8 @@ func Provider() terraform.ResourceProvider {
|
||||||
"aws_waf_web_acl": resourceAwsWafWebAcl(),
|
"aws_waf_web_acl": resourceAwsWafWebAcl(),
|
||||||
"aws_waf_xss_match_set": resourceAwsWafXssMatchSet(),
|
"aws_waf_xss_match_set": resourceAwsWafXssMatchSet(),
|
||||||
"aws_waf_sql_injection_match_set": resourceAwsWafSqlInjectionMatchSet(),
|
"aws_waf_sql_injection_match_set": resourceAwsWafSqlInjectionMatchSet(),
|
||||||
|
"aws_wafregional_byte_match_set": resourceAwsWafRegionalByteMatchSet(),
|
||||||
|
"aws_wafregional_ipset": resourceAwsWafRegionalIPSet(),
|
||||||
},
|
},
|
||||||
ConfigureFunc: providerConfigure,
|
ConfigureFunc: providerConfigure,
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,266 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/service/waf"
|
||||||
|
"github.com/aws/aws-sdk-go/service/wafregional"
|
||||||
|
"github.com/hashicorp/errwrap"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceAwsWafRegionalByteMatchSet() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceAwsWafRegionalByteMatchSetCreate,
|
||||||
|
Read: resourceAwsWafRegionalByteMatchSetRead,
|
||||||
|
Update: resourceAwsWafRegionalByteMatchSetUpdate,
|
||||||
|
Delete: resourceAwsWafRegionalByteMatchSetDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"byte_match_tuple": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"field_to_match": {
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Required: true,
|
||||||
|
MaxItems: 1,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"data": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"positional_constraint": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"target_string": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"text_transformation": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsWafRegionalByteMatchSetCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).wafregionalconn
|
||||||
|
region := meta.(*AWSClient).region
|
||||||
|
|
||||||
|
log.Printf("[INFO] Creating ByteMatchSet: %s", d.Get("name").(string))
|
||||||
|
|
||||||
|
wr := newWafRegionalRetryer(conn, region)
|
||||||
|
out, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
|
||||||
|
params := &waf.CreateByteMatchSetInput{
|
||||||
|
ChangeToken: token,
|
||||||
|
Name: aws.String(d.Get("name").(string)),
|
||||||
|
}
|
||||||
|
return conn.CreateByteMatchSet(params)
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return errwrap.Wrapf("[ERROR] Error creating ByteMatchSet: {{err}}", err)
|
||||||
|
}
|
||||||
|
resp := out.(*waf.CreateByteMatchSetOutput)
|
||||||
|
|
||||||
|
d.SetId(*resp.ByteMatchSet.ByteMatchSetId)
|
||||||
|
|
||||||
|
return resourceAwsWafRegionalByteMatchSetUpdate(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsWafRegionalByteMatchSetRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).wafregionalconn
|
||||||
|
|
||||||
|
log.Printf("[INFO] Reading ByteMatchSet: %s", d.Get("name").(string))
|
||||||
|
|
||||||
|
params := &waf.GetByteMatchSetInput{
|
||||||
|
ByteMatchSetId: aws.String(d.Id()),
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := conn.GetByteMatchSet(params)
|
||||||
|
if err != nil {
|
||||||
|
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "WAFNonexistentItemException" {
|
||||||
|
log.Printf("[WARN] WAF IPSet (%s) not found, error code (404)", d.Id())
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("byte_match_tuple", flattenWafByteMatchTuplesWR(resp.ByteMatchSet.ByteMatchTuples))
|
||||||
|
d.Set("name", resp.ByteMatchSet.Name)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenWafByteMatchTuplesWR(in []*waf.ByteMatchTuple) []interface{} {
|
||||||
|
tuples := make([]interface{}, len(in), len(in))
|
||||||
|
|
||||||
|
for i, tuple := range in {
|
||||||
|
field_to_match := tuple.FieldToMatch
|
||||||
|
m := map[string]interface{}{
|
||||||
|
"type": *field_to_match.Type,
|
||||||
|
}
|
||||||
|
|
||||||
|
if field_to_match.Data == nil {
|
||||||
|
m["data"] = ""
|
||||||
|
} else {
|
||||||
|
m["data"] = *field_to_match.Data
|
||||||
|
}
|
||||||
|
|
||||||
|
var ms []map[string]interface{}
|
||||||
|
ms = append(ms, m)
|
||||||
|
|
||||||
|
tuple := map[string]interface{}{
|
||||||
|
"field_to_match": ms,
|
||||||
|
"positional_constraint": *tuple.PositionalConstraint,
|
||||||
|
"target_string": tuple.TargetString,
|
||||||
|
"text_transformation": *tuple.TextTransformation,
|
||||||
|
}
|
||||||
|
tuples[i] = tuple
|
||||||
|
}
|
||||||
|
|
||||||
|
return tuples
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsWafRegionalByteMatchSetUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).wafregionalconn
|
||||||
|
region := meta.(*AWSClient).region
|
||||||
|
log.Printf("[INFO] Updating ByteMatchSet: %s", d.Get("name").(string))
|
||||||
|
|
||||||
|
if d.HasChange("byte_match_tuple") {
|
||||||
|
o, n := d.GetChange("byte_match_tuple")
|
||||||
|
oldT, newT := o.(*schema.Set).List(), n.(*schema.Set).List()
|
||||||
|
|
||||||
|
err := updateByteMatchSetResourceWR(d, oldT, newT, conn, region)
|
||||||
|
if err != nil {
|
||||||
|
return errwrap.Wrapf("[ERROR] Error updating ByteMatchSet: {{err}}", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resourceAwsWafRegionalByteMatchSetRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsWafRegionalByteMatchSetDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).wafregionalconn
|
||||||
|
region := meta.(*AWSClient).region
|
||||||
|
|
||||||
|
log.Printf("[INFO] Deleting ByteMatchSet: %s", d.Get("name").(string))
|
||||||
|
|
||||||
|
oldT := d.Get("byte_match_tuple").(*schema.Set).List()
|
||||||
|
|
||||||
|
if len(oldT) > 0 {
|
||||||
|
var newT []interface{}
|
||||||
|
|
||||||
|
err := updateByteMatchSetResourceWR(d, oldT, newT, conn, region)
|
||||||
|
if err != nil {
|
||||||
|
return errwrap.Wrapf("[ERROR] Error deleting ByteMatchSet: {{err}}", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wr := newWafRegionalRetryer(conn, region)
|
||||||
|
_, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
|
||||||
|
req := &waf.DeleteByteMatchSetInput{
|
||||||
|
ChangeToken: token,
|
||||||
|
ByteMatchSetId: aws.String(d.Id()),
|
||||||
|
}
|
||||||
|
return conn.DeleteByteMatchSet(req)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return errwrap.Wrapf("[ERROR] Error deleting ByteMatchSet: {{err}}", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateByteMatchSetResourceWR(d *schema.ResourceData, oldT, newT []interface{}, conn *wafregional.WAFRegional, region string) error {
|
||||||
|
wr := newWafRegionalRetryer(conn, region)
|
||||||
|
_, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
|
||||||
|
req := &waf.UpdateByteMatchSetInput{
|
||||||
|
ChangeToken: token,
|
||||||
|
ByteMatchSetId: aws.String(d.Id()),
|
||||||
|
Updates: diffByteMatchSetTuple(oldT, newT),
|
||||||
|
}
|
||||||
|
|
||||||
|
return conn.UpdateByteMatchSet(req)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return errwrap.Wrapf("[ERROR] Error updating ByteMatchSet: {{err}}", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandFieldToMatchWR(d map[string]interface{}) *waf.FieldToMatch {
|
||||||
|
return &waf.FieldToMatch{
|
||||||
|
Type: aws.String(d["type"].(string)),
|
||||||
|
Data: aws.String(d["data"].(string)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenFieldToMatchWR(fm *waf.FieldToMatch) map[string]interface{} {
|
||||||
|
m := make(map[string]interface{})
|
||||||
|
m["data"] = *fm.Data
|
||||||
|
m["type"] = *fm.Type
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func diffByteMatchSetTuple(oldT, newT []interface{}) []*waf.ByteMatchSetUpdate {
|
||||||
|
updates := make([]*waf.ByteMatchSetUpdate, 0)
|
||||||
|
|
||||||
|
for _, ot := range oldT {
|
||||||
|
tuple := ot.(map[string]interface{})
|
||||||
|
|
||||||
|
if idx, contains := sliceContainsMap(newT, tuple); contains {
|
||||||
|
newT = append(newT[:idx], newT[idx+1:]...)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
updates = append(updates, &waf.ByteMatchSetUpdate{
|
||||||
|
Action: aws.String(waf.ChangeActionDelete),
|
||||||
|
ByteMatchTuple: &waf.ByteMatchTuple{
|
||||||
|
FieldToMatch: expandFieldToMatch(tuple["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})),
|
||||||
|
PositionalConstraint: aws.String(tuple["positional_constraint"].(string)),
|
||||||
|
TargetString: []byte(tuple["target_string"].(string)),
|
||||||
|
TextTransformation: aws.String(tuple["text_transformation"].(string)),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, nt := range newT {
|
||||||
|
tuple := nt.(map[string]interface{})
|
||||||
|
|
||||||
|
updates = append(updates, &waf.ByteMatchSetUpdate{
|
||||||
|
Action: aws.String(waf.ChangeActionInsert),
|
||||||
|
ByteMatchTuple: &waf.ByteMatchTuple{
|
||||||
|
FieldToMatch: expandFieldToMatch(tuple["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})),
|
||||||
|
PositionalConstraint: aws.String(tuple["positional_constraint"].(string)),
|
||||||
|
TargetString: []byte(tuple["target_string"].(string)),
|
||||||
|
TextTransformation: aws.String(tuple["text_transformation"].(string)),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return updates
|
||||||
|
}
|
|
@ -0,0 +1,437 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/service/waf"
|
||||||
|
"github.com/hashicorp/errwrap"
|
||||||
|
"github.com/hashicorp/terraform/helper/acctest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccAWSWafRegionalByteMatchSet_basic(t *testing.T) {
|
||||||
|
var v waf.ByteMatchSet
|
||||||
|
byteMatchSet := fmt.Sprintf("byteMatchSet-%s", acctest.RandString(5))
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSWafRegionalByteMatchSetDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSWafRegionalByteMatchSetConfig(byteMatchSet),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSWafRegionalByteMatchSetExists("aws_wafregional_byte_match_set.byte_set", &v),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "name", byteMatchSet),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.#", "2"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.field_to_match.2991901334.data", "referer"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.field_to_match.2991901334.type", "HEADER"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.positional_constraint", "CONTAINS"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.target_string", "badrefer1"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.text_transformation", "NONE"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.field_to_match.2991901334.data", "referer"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.field_to_match.2991901334.type", "HEADER"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.positional_constraint", "CONTAINS"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.target_string", "badrefer2"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.text_transformation", "NONE"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSWafRegionalByteMatchSet_changeNameForceNew(t *testing.T) {
|
||||||
|
var before, after waf.ByteMatchSet
|
||||||
|
byteMatchSet := fmt.Sprintf("byteMatchSet-%s", acctest.RandString(5))
|
||||||
|
byteMatchSetNewName := fmt.Sprintf("byteMatchSet-%s", acctest.RandString(5))
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSWafRegionalByteMatchSetDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSWafRegionalByteMatchSetConfig(byteMatchSet),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSWafRegionalByteMatchSetExists("aws_wafregional_byte_match_set.byte_set", &before),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "name", byteMatchSet),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.#", "2"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.field_to_match.2991901334.data", "referer"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.field_to_match.2991901334.type", "HEADER"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.positional_constraint", "CONTAINS"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.target_string", "badrefer1"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.text_transformation", "NONE"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.field_to_match.2991901334.data", "referer"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.field_to_match.2991901334.type", "HEADER"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.positional_constraint", "CONTAINS"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.target_string", "badrefer2"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.text_transformation", "NONE"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Config: testAccAWSWafRegionalByteMatchSetConfigChangeName(byteMatchSetNewName),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSWafRegionalByteMatchSetExists("aws_wafregional_byte_match_set.byte_set", &after),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "name", byteMatchSetNewName),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.#", "2"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.field_to_match.2991901334.data", "referer"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.field_to_match.2991901334.type", "HEADER"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.positional_constraint", "CONTAINS"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.target_string", "badrefer1"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.text_transformation", "NONE"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.field_to_match.2991901334.data", "referer"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.field_to_match.2991901334.type", "HEADER"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.positional_constraint", "CONTAINS"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.target_string", "badrefer2"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.text_transformation", "NONE"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSWafRegionalByteMatchSet_changeByteMatchTuple(t *testing.T) {
|
||||||
|
var before, after waf.ByteMatchSet
|
||||||
|
byteMatchSetName := fmt.Sprintf("byte-batch-set-%s", acctest.RandString(5))
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSWafRegionalByteMatchSetDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSWafRegionalByteMatchSetConfig(byteMatchSetName),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSWafRegionalByteMatchSetExists("aws_wafregional_byte_match_set.byte_set", &before),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "name", byteMatchSetName),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.#", "2"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.field_to_match.2991901334.data", "referer"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.field_to_match.2991901334.type", "HEADER"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.positional_constraint", "CONTAINS"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.target_string", "badrefer1"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2174619346.text_transformation", "NONE"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.field_to_match.2991901334.data", "referer"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.field_to_match.2991901334.type", "HEADER"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.positional_constraint", "CONTAINS"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.target_string", "badrefer2"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.839525137.text_transformation", "NONE"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Config: testAccAWSWafRegionalByteMatchSetConfigChangeByteMatchTuple(byteMatchSetName),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSWafRegionalByteMatchSetExists("aws_wafregional_byte_match_set.byte_set", &after),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "name", byteMatchSetName),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.#", "2"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2397850647.field_to_match.4253810390.data", "GET"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2397850647.field_to_match.4253810390.type", "METHOD"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2397850647.positional_constraint", "STARTS_WITH"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2397850647.target_string", "badrefer1+"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.2397850647.text_transformation", "LOWERCASE"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.4153613423.field_to_match.3756326843.data", ""),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.4153613423.field_to_match.3756326843.type", "URI"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.4153613423.positional_constraint", "ENDS_WITH"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.4153613423.target_string", "badrefer2+"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_byte_match_set.byte_set", "byte_match_tuple.4153613423.text_transformation", "LOWERCASE"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSWafRegionalByteMatchSet_noByteMatchTuples(t *testing.T) {
|
||||||
|
var byteMatchSet waf.ByteMatchSet
|
||||||
|
byteMatchSetName := fmt.Sprintf("byte-batch-set-%s", acctest.RandString(5))
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSWafRegionalByteMatchSetDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSWafRegionalByteMatchSetConfig_noDescriptors(byteMatchSetName),
|
||||||
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
|
testAccCheckAWSWafRegionalByteMatchSetExists("aws_wafregional_byte_match_set.byte_match_set", &byteMatchSet),
|
||||||
|
resource.TestCheckResourceAttr("aws_wafregional_byte_match_set.byte_match_set", "name", byteMatchSetName),
|
||||||
|
resource.TestCheckResourceAttr("aws_wafregional_byte_match_set.byte_match_set", "byte_match_tuple.#", "0"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSWafRegionalByteMatchSet_disappears(t *testing.T) {
|
||||||
|
var v waf.ByteMatchSet
|
||||||
|
byteMatchSet := fmt.Sprintf("byteMatchSet-%s", acctest.RandString(5))
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSWafRegionalByteMatchSetDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSWafRegionalByteMatchSetConfig(byteMatchSet),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSWafRegionalByteMatchSetExists("aws_wafregional_byte_match_set.byte_set", &v),
|
||||||
|
testAccCheckAWSWafRegionalByteMatchSetDisappears(&v),
|
||||||
|
),
|
||||||
|
ExpectNonEmptyPlan: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAWSWafRegionalByteMatchSetDisappears(v *waf.ByteMatchSet) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).wafregionalconn
|
||||||
|
region := testAccProvider.Meta().(*AWSClient).region
|
||||||
|
|
||||||
|
wr := newWafRegionalRetryer(conn, region)
|
||||||
|
_, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
|
||||||
|
req := &waf.UpdateByteMatchSetInput{
|
||||||
|
ChangeToken: token,
|
||||||
|
ByteMatchSetId: v.ByteMatchSetId,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ByteMatchTuple := range v.ByteMatchTuples {
|
||||||
|
ByteMatchUpdate := &waf.ByteMatchSetUpdate{
|
||||||
|
Action: aws.String("DELETE"),
|
||||||
|
ByteMatchTuple: &waf.ByteMatchTuple{
|
||||||
|
FieldToMatch: ByteMatchTuple.FieldToMatch,
|
||||||
|
PositionalConstraint: ByteMatchTuple.PositionalConstraint,
|
||||||
|
TargetString: ByteMatchTuple.TargetString,
|
||||||
|
TextTransformation: ByteMatchTuple.TextTransformation,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
req.Updates = append(req.Updates, ByteMatchUpdate)
|
||||||
|
}
|
||||||
|
|
||||||
|
return conn.UpdateByteMatchSet(req)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return errwrap.Wrapf("[ERROR] Error updating ByteMatchSet: {{err}}", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = wr.RetryWithToken(func(token *string) (interface{}, error) {
|
||||||
|
opts := &waf.DeleteByteMatchSetInput{
|
||||||
|
ChangeToken: token,
|
||||||
|
ByteMatchSetId: v.ByteMatchSetId,
|
||||||
|
}
|
||||||
|
return conn.DeleteByteMatchSet(opts)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return errwrap.Wrapf("[ERROR] Error deleting ByteMatchSet: {{err}}", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAWSWafRegionalByteMatchSetExists(n string, v *waf.ByteMatchSet) 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 ByteMatchSet ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).wafregionalconn
|
||||||
|
resp, err := conn.GetByteMatchSet(&waf.GetByteMatchSetInput{
|
||||||
|
ByteMatchSetId: aws.String(rs.Primary.ID),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if *resp.ByteMatchSet.ByteMatchSetId == rs.Primary.ID {
|
||||||
|
*v = *resp.ByteMatchSet
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("WAF ByteMatchSet (%s) not found", rs.Primary.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAWSWafRegionalByteMatchSetDestroy(s *terraform.State) error {
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "aws_wafregional_byte_match_set" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).wafregionalconn
|
||||||
|
resp, err := conn.GetByteMatchSet(
|
||||||
|
&waf.GetByteMatchSetInput{
|
||||||
|
ByteMatchSetId: aws.String(rs.Primary.ID),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
if *resp.ByteMatchSet.ByteMatchSetId == rs.Primary.ID {
|
||||||
|
return fmt.Errorf("WAF ByteMatchSet %s still exists", rs.Primary.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return nil if the ByteMatchSet is already destroyed
|
||||||
|
if awsErr, ok := err.(awserr.Error); ok {
|
||||||
|
if awsErr.Code() == "WAFNonexistentItemException" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccAWSWafRegionalByteMatchSetConfig(name string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "aws_wafregional_byte_match_set" "byte_set" {
|
||||||
|
name = "%s"
|
||||||
|
byte_match_tuple {
|
||||||
|
text_transformation = "NONE"
|
||||||
|
target_string = "badrefer1"
|
||||||
|
positional_constraint = "CONTAINS"
|
||||||
|
field_to_match {
|
||||||
|
type = "HEADER"
|
||||||
|
data = "referer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byte_match_tuple {
|
||||||
|
text_transformation = "NONE"
|
||||||
|
target_string = "badrefer2"
|
||||||
|
positional_constraint = "CONTAINS"
|
||||||
|
field_to_match {
|
||||||
|
type = "HEADER"
|
||||||
|
data = "referer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccAWSWafRegionalByteMatchSetConfigChangeName(name string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "aws_wafregional_byte_match_set" "byte_set" {
|
||||||
|
name = "%s"
|
||||||
|
byte_match_tuple {
|
||||||
|
text_transformation = "NONE"
|
||||||
|
target_string = "badrefer1"
|
||||||
|
positional_constraint = "CONTAINS"
|
||||||
|
field_to_match {
|
||||||
|
type = "HEADER"
|
||||||
|
data = "referer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byte_match_tuple {
|
||||||
|
text_transformation = "NONE"
|
||||||
|
target_string = "badrefer2"
|
||||||
|
positional_constraint = "CONTAINS"
|
||||||
|
field_to_match {
|
||||||
|
type = "HEADER"
|
||||||
|
data = "referer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccAWSWafRegionalByteMatchSetConfig_noDescriptors(name string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "aws_wafregional_byte_match_set" "byte_match_set" {
|
||||||
|
name = "%s"
|
||||||
|
}`, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccAWSWafRegionalByteMatchSetConfigChangeByteMatchTuple(name string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "aws_wafregional_byte_match_set" "byte_set" {
|
||||||
|
name = "%s"
|
||||||
|
byte_match_tuple {
|
||||||
|
text_transformation = "LOWERCASE"
|
||||||
|
target_string = "badrefer1+"
|
||||||
|
positional_constraint = "STARTS_WITH"
|
||||||
|
field_to_match {
|
||||||
|
type = "METHOD"
|
||||||
|
data = "GET"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byte_match_tuple {
|
||||||
|
text_transformation = "LOWERCASE"
|
||||||
|
target_string = "badrefer2+"
|
||||||
|
positional_constraint = "ENDS_WITH"
|
||||||
|
field_to_match {
|
||||||
|
type = "URI"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`, name)
|
||||||
|
}
|
|
@ -0,0 +1,170 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/service/waf"
|
||||||
|
"github.com/aws/aws-sdk-go/service/wafregional"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceAwsWafRegionalIPSet() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceAwsWafRegionalIPSetCreate,
|
||||||
|
Read: resourceAwsWafRegionalIPSetRead,
|
||||||
|
Update: resourceAwsWafRegionalIPSetUpdate,
|
||||||
|
Delete: resourceAwsWafRegionalIPSetDelete,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"ip_set_descriptor": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"type": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"value": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsWafRegionalIPSetCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).wafregionalconn
|
||||||
|
region := meta.(*AWSClient).region
|
||||||
|
|
||||||
|
wr := newWafRegionalRetryer(conn, region)
|
||||||
|
out, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
|
||||||
|
params := &waf.CreateIPSetInput{
|
||||||
|
ChangeToken: token,
|
||||||
|
Name: aws.String(d.Get("name").(string)),
|
||||||
|
}
|
||||||
|
return conn.CreateIPSet(params)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
resp := out.(*waf.CreateIPSetOutput)
|
||||||
|
d.SetId(*resp.IPSet.IPSetId)
|
||||||
|
return resourceAwsWafRegionalIPSetUpdate(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsWafRegionalIPSetRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).wafregionalconn
|
||||||
|
|
||||||
|
params := &waf.GetIPSetInput{
|
||||||
|
IPSetId: aws.String(d.Id()),
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := conn.GetIPSet(params)
|
||||||
|
if err != nil {
|
||||||
|
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "WAFNonexistentItemException" {
|
||||||
|
log.Printf("[WARN] WAF IPSet (%s) not found, error code (404)", d.Id())
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("ip_set_descriptor", flattenWafIpSetDescriptorWR(resp.IPSet.IPSetDescriptors))
|
||||||
|
d.Set("name", resp.IPSet.Name)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenWafIpSetDescriptorWR(in []*waf.IPSetDescriptor) []interface{} {
|
||||||
|
descriptors := make([]interface{}, len(in), len(in))
|
||||||
|
|
||||||
|
for i, descriptor := range in {
|
||||||
|
d := map[string]interface{}{
|
||||||
|
"type": *descriptor.Type,
|
||||||
|
"value": *descriptor.Value,
|
||||||
|
}
|
||||||
|
descriptors[i] = d
|
||||||
|
}
|
||||||
|
|
||||||
|
return descriptors
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsWafRegionalIPSetUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).wafregionalconn
|
||||||
|
region := meta.(*AWSClient).region
|
||||||
|
|
||||||
|
if d.HasChange("ip_set_descriptor") {
|
||||||
|
o, n := d.GetChange("ip_set_descriptor")
|
||||||
|
oldD, newD := o.(*schema.Set).List(), n.(*schema.Set).List()
|
||||||
|
|
||||||
|
err := updateIPSetResourceWR(d.Id(), oldD, newD, conn, region)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Updating WAF IPSet: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resourceAwsWafRegionalIPSetRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceAwsWafRegionalIPSetDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).wafregionalconn
|
||||||
|
region := meta.(*AWSClient).region
|
||||||
|
|
||||||
|
oldD := d.Get("ip_set_descriptor").(*schema.Set).List()
|
||||||
|
|
||||||
|
if len(oldD) > 0 {
|
||||||
|
noD := []interface{}{}
|
||||||
|
err := updateIPSetResourceWR(d.Id(), oldD, noD, conn, region)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Removing IPSetDescriptors: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wr := newWafRegionalRetryer(conn, region)
|
||||||
|
_, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
|
||||||
|
req := &waf.DeleteIPSetInput{
|
||||||
|
ChangeToken: token,
|
||||||
|
IPSetId: aws.String(d.Id()),
|
||||||
|
}
|
||||||
|
log.Printf("[INFO] Deleting WAF IPSet")
|
||||||
|
return conn.DeleteIPSet(req)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Deleting WAF IPSet: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateIPSetResourceWR(id string, oldD, newD []interface{}, conn *wafregional.WAFRegional, region string) error {
|
||||||
|
|
||||||
|
wr := newWafRegionalRetryer(conn, region)
|
||||||
|
_, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
|
||||||
|
req := &waf.UpdateIPSetInput{
|
||||||
|
ChangeToken: token,
|
||||||
|
IPSetId: aws.String(id),
|
||||||
|
Updates: diffWafIpSetDescriptors(oldD, newD),
|
||||||
|
}
|
||||||
|
log.Printf("[INFO] Updating IPSet descriptor: %s", req)
|
||||||
|
|
||||||
|
return conn.UpdateIPSet(req)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Updating WAF IPSet: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,402 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/service/waf"
|
||||||
|
"github.com/aws/aws-sdk-go/service/wafregional"
|
||||||
|
"github.com/hashicorp/terraform/helper/acctest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccAWSWafRegionalIPSet_basic(t *testing.T) {
|
||||||
|
var v waf.IPSet
|
||||||
|
ipsetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5))
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSWafRegionalIPSetDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSWafRegionalIPSetConfig(ipsetName),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSWafRegionalIPSetExists("aws_wafregional_ipset.ipset", &v),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "name", ipsetName),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "ip_set_descriptor.4037960608.type", "IPV4"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "ip_set_descriptor.4037960608.value", "192.0.7.0/24"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSWafRegionalIPSet_disappears(t *testing.T) {
|
||||||
|
var v waf.IPSet
|
||||||
|
ipsetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5))
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSWafRegionalIPSetDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSWafRegionalIPSetConfig(ipsetName),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSWafRegionalIPSetExists("aws_wafregional_ipset.ipset", &v),
|
||||||
|
testAccCheckAWSWafRegionalIPSetDisappears(&v),
|
||||||
|
),
|
||||||
|
ExpectNonEmptyPlan: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSWafRegionalIPSet_changeNameForceNew(t *testing.T) {
|
||||||
|
var before, after waf.IPSet
|
||||||
|
ipsetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5))
|
||||||
|
ipsetNewName := fmt.Sprintf("ip-set-new-%s", acctest.RandString(5))
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSWafRegionalIPSetDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSWafRegionalIPSetConfig(ipsetName),
|
||||||
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
|
testAccCheckAWSWafRegionalIPSetExists("aws_wafregional_ipset.ipset", &before),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "name", ipsetName),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "ip_set_descriptor.4037960608.type", "IPV4"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "ip_set_descriptor.4037960608.value", "192.0.7.0/24"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Config: testAccAWSWafRegionalIPSetConfigChangeName(ipsetNewName),
|
||||||
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
|
testAccCheckAWSWafRegionalIPSetExists("aws_wafregional_ipset.ipset", &after),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "name", ipsetNewName),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "ip_set_descriptor.4037960608.type", "IPV4"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "ip_set_descriptor.4037960608.value", "192.0.7.0/24"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSWafRegionalIPSet_changeDescriptors(t *testing.T) {
|
||||||
|
var before, after waf.IPSet
|
||||||
|
ipsetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5))
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSWafRegionalIPSetDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSWafRegionalIPSetConfig(ipsetName),
|
||||||
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
|
testAccCheckAWSWafRegionalIPSetExists("aws_wafregional_ipset.ipset", &before),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "name", ipsetName),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "ip_set_descriptor.#", "1"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "ip_set_descriptor.4037960608.type", "IPV4"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "ip_set_descriptor.4037960608.value", "192.0.7.0/24"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Config: testAccAWSWafRegionalIPSetConfigChangeIPSetDescriptors(ipsetName),
|
||||||
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
|
testAccCheckAWSWafRegionalIPSetExists("aws_wafregional_ipset.ipset", &after),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "name", ipsetName),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "ip_set_descriptor.#", "1"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "ip_set_descriptor.115741513.type", "IPV4"),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "ip_set_descriptor.115741513.value", "192.0.8.0/24"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSWafRegionalIPSet_noDescriptors(t *testing.T) {
|
||||||
|
var ipset waf.IPSet
|
||||||
|
ipsetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5))
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSWafRegionalIPSetDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSWafRegionalIPSetConfig_noDescriptors(ipsetName),
|
||||||
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
|
testAccCheckAWSWafRegionalIPSetExists("aws_wafregional_ipset.ipset", &ipset),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "name", ipsetName),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_wafregional_ipset.ipset", "ip_set_descriptor.#", "0"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDiffWafRegionalIpSetDescriptors(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
Old []interface{}
|
||||||
|
New []interface{}
|
||||||
|
ExpectedUpdates []*waf.IPSetUpdate
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
// Change
|
||||||
|
Old: []interface{}{
|
||||||
|
map[string]interface{}{"type": "IPV4", "value": "192.0.7.0/24"},
|
||||||
|
},
|
||||||
|
New: []interface{}{
|
||||||
|
map[string]interface{}{"type": "IPV4", "value": "192.0.8.0/24"},
|
||||||
|
},
|
||||||
|
ExpectedUpdates: []*waf.IPSetUpdate{
|
||||||
|
&waf.IPSetUpdate{
|
||||||
|
Action: aws.String(wafregional.ChangeActionDelete),
|
||||||
|
IPSetDescriptor: &waf.IPSetDescriptor{
|
||||||
|
Type: aws.String("IPV4"),
|
||||||
|
Value: aws.String("192.0.7.0/24"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&waf.IPSetUpdate{
|
||||||
|
Action: aws.String(wafregional.ChangeActionInsert),
|
||||||
|
IPSetDescriptor: &waf.IPSetDescriptor{
|
||||||
|
Type: aws.String("IPV4"),
|
||||||
|
Value: aws.String("192.0.8.0/24"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Fresh IPSet
|
||||||
|
Old: []interface{}{},
|
||||||
|
New: []interface{}{
|
||||||
|
map[string]interface{}{"type": "IPV4", "value": "10.0.1.0/24"},
|
||||||
|
map[string]interface{}{"type": "IPV4", "value": "10.0.2.0/24"},
|
||||||
|
map[string]interface{}{"type": "IPV4", "value": "10.0.3.0/24"},
|
||||||
|
},
|
||||||
|
ExpectedUpdates: []*waf.IPSetUpdate{
|
||||||
|
&waf.IPSetUpdate{
|
||||||
|
Action: aws.String(wafregional.ChangeActionInsert),
|
||||||
|
IPSetDescriptor: &waf.IPSetDescriptor{
|
||||||
|
Type: aws.String("IPV4"),
|
||||||
|
Value: aws.String("10.0.1.0/24"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&waf.IPSetUpdate{
|
||||||
|
Action: aws.String(wafregional.ChangeActionInsert),
|
||||||
|
IPSetDescriptor: &waf.IPSetDescriptor{
|
||||||
|
Type: aws.String("IPV4"),
|
||||||
|
Value: aws.String("10.0.2.0/24"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&waf.IPSetUpdate{
|
||||||
|
Action: aws.String(wafregional.ChangeActionInsert),
|
||||||
|
IPSetDescriptor: &waf.IPSetDescriptor{
|
||||||
|
Type: aws.String("IPV4"),
|
||||||
|
Value: aws.String("10.0.3.0/24"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Deletion
|
||||||
|
Old: []interface{}{
|
||||||
|
map[string]interface{}{"type": "IPV4", "value": "192.0.7.0/24"},
|
||||||
|
map[string]interface{}{"type": "IPV4", "value": "192.0.8.0/24"},
|
||||||
|
},
|
||||||
|
New: []interface{}{},
|
||||||
|
ExpectedUpdates: []*waf.IPSetUpdate{
|
||||||
|
&waf.IPSetUpdate{
|
||||||
|
Action: aws.String(wafregional.ChangeActionDelete),
|
||||||
|
IPSetDescriptor: &waf.IPSetDescriptor{
|
||||||
|
Type: aws.String("IPV4"),
|
||||||
|
Value: aws.String("192.0.7.0/24"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&waf.IPSetUpdate{
|
||||||
|
Action: aws.String(wafregional.ChangeActionDelete),
|
||||||
|
IPSetDescriptor: &waf.IPSetDescriptor{
|
||||||
|
Type: aws.String("IPV4"),
|
||||||
|
Value: aws.String("192.0.8.0/24"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i, tc := range testCases {
|
||||||
|
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
||||||
|
updates := diffWafIpSetDescriptors(tc.Old, tc.New)
|
||||||
|
if !reflect.DeepEqual(updates, tc.ExpectedUpdates) {
|
||||||
|
t.Fatalf("IPSet updates don't match.\nGiven: %s\nExpected: %s",
|
||||||
|
updates, tc.ExpectedUpdates)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAWSWafRegionalIPSetDisappears(v *waf.IPSet) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).wafregionalconn
|
||||||
|
region := testAccProvider.Meta().(*AWSClient).region
|
||||||
|
|
||||||
|
wr := newWafRegionalRetryer(conn, region)
|
||||||
|
_, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
|
||||||
|
req := &waf.UpdateIPSetInput{
|
||||||
|
ChangeToken: token,
|
||||||
|
IPSetId: v.IPSetId,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, IPSetDescriptor := range v.IPSetDescriptors {
|
||||||
|
IPSetUpdate := &waf.IPSetUpdate{
|
||||||
|
Action: aws.String("DELETE"),
|
||||||
|
IPSetDescriptor: &waf.IPSetDescriptor{
|
||||||
|
Type: IPSetDescriptor.Type,
|
||||||
|
Value: IPSetDescriptor.Value,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
req.Updates = append(req.Updates, IPSetUpdate)
|
||||||
|
}
|
||||||
|
|
||||||
|
return conn.UpdateIPSet(req)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Updating WAF IPSet: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = wr.RetryWithToken(func(token *string) (interface{}, error) {
|
||||||
|
opts := &waf.DeleteIPSetInput{
|
||||||
|
ChangeToken: token,
|
||||||
|
IPSetId: v.IPSetId,
|
||||||
|
}
|
||||||
|
return conn.DeleteIPSet(opts)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error Deleting WAF IPSet: %s", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAWSWafRegionalIPSetDestroy(s *terraform.State) error {
|
||||||
|
for _, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "aws_wafregional_ipset" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).wafregionalconn
|
||||||
|
resp, err := conn.GetIPSet(
|
||||||
|
&waf.GetIPSetInput{
|
||||||
|
IPSetId: aws.String(rs.Primary.ID),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
if *resp.IPSet.IPSetId == rs.Primary.ID {
|
||||||
|
return fmt.Errorf("WAF IPSet %s still exists", rs.Primary.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return nil if the IPSet is already destroyed
|
||||||
|
if awsErr, ok := err.(awserr.Error); ok {
|
||||||
|
if awsErr.Code() == "WAFNonexistentItemException" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckAWSWafRegionalIPSetExists(n string, v *waf.IPSet) 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 IPSet ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
conn := testAccProvider.Meta().(*AWSClient).wafregionalconn
|
||||||
|
resp, err := conn.GetIPSet(&waf.GetIPSetInput{
|
||||||
|
IPSetId: aws.String(rs.Primary.ID),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if *resp.IPSet.IPSetId == rs.Primary.ID {
|
||||||
|
*v = *resp.IPSet
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("WAF IPSet (%s) not found", rs.Primary.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccAWSWafRegionalIPSetConfig(name string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "aws_wafregional_ipset" "ipset" {
|
||||||
|
name = "%s"
|
||||||
|
ip_set_descriptor {
|
||||||
|
type = "IPV4"
|
||||||
|
value = "192.0.7.0/24"
|
||||||
|
}
|
||||||
|
}`, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccAWSWafRegionalIPSetConfigChangeName(name string) string {
|
||||||
|
return fmt.Sprintf(`resource "aws_wafregional_ipset" "ipset" {
|
||||||
|
name = "%s"
|
||||||
|
ip_set_descriptor {
|
||||||
|
type = "IPV4"
|
||||||
|
value = "192.0.7.0/24"
|
||||||
|
}
|
||||||
|
}`, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccAWSWafRegionalIPSetConfigChangeIPSetDescriptors(name string) string {
|
||||||
|
return fmt.Sprintf(`resource "aws_wafregional_ipset" "ipset" {
|
||||||
|
name = "%s"
|
||||||
|
ip_set_descriptor {
|
||||||
|
type = "IPV4"
|
||||||
|
value = "192.0.8.0/24"
|
||||||
|
}
|
||||||
|
}`, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccAWSWafRegionalIPSetConfig_noDescriptors(name string) string {
|
||||||
|
return fmt.Sprintf(`resource "aws_wafregional_ipset" "ipset" {
|
||||||
|
name = "%s"
|
||||||
|
}`, name)
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/service/waf"
|
||||||
|
"github.com/aws/aws-sdk-go/service/wafregional"
|
||||||
|
"github.com/hashicorp/errwrap"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WafRegionalRetryer struct {
|
||||||
|
Connection *wafregional.WAFRegional
|
||||||
|
Region string
|
||||||
|
}
|
||||||
|
|
||||||
|
type withRegionalTokenFunc func(token *string) (interface{}, error)
|
||||||
|
|
||||||
|
func (t *WafRegionalRetryer) RetryWithToken(f withRegionalTokenFunc) (interface{}, error) {
|
||||||
|
awsMutexKV.Lock(t.Region)
|
||||||
|
defer awsMutexKV.Unlock(t.Region)
|
||||||
|
|
||||||
|
var out interface{}
|
||||||
|
err := resource.Retry(15*time.Minute, func() *resource.RetryError {
|
||||||
|
var err error
|
||||||
|
var tokenOut *waf.GetChangeTokenOutput
|
||||||
|
|
||||||
|
tokenOut, err = t.Connection.GetChangeToken(&waf.GetChangeTokenInput{})
|
||||||
|
if err != nil {
|
||||||
|
return resource.NonRetryableError(errwrap.Wrapf("Failed to acquire change token: {{err}}", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err = f(tokenOut.ChangeToken)
|
||||||
|
if err != nil {
|
||||||
|
awsErr, ok := err.(awserr.Error)
|
||||||
|
if ok && awsErr.Code() == "WAFStaleDataException" {
|
||||||
|
return resource.RetryableError(err)
|
||||||
|
}
|
||||||
|
return resource.NonRetryableError(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func newWafRegionalRetryer(conn *wafregional.WAFRegional, region string) *WafRegionalRetryer {
|
||||||
|
return &WafRegionalRetryer{Connection: conn, Region: region}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
---
|
||||||
|
layout: "aws"
|
||||||
|
page_title: "AWS: wafregional_byte_match_set"
|
||||||
|
sidebar_current: "docs-aws-resource-wafregional-bytematchset"
|
||||||
|
description: |-
|
||||||
|
Provides a AWS WAF Regional ByteMatchSet resource for use with ALB.
|
||||||
|
---
|
||||||
|
|
||||||
|
# aws\_wafregional\_byte\_match\_set
|
||||||
|
|
||||||
|
Provides a WAF Regional Byte Match Set Resource for use with Application Load Balancer.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "aws_wafregional_byte_match_set" "byte_set" {
|
||||||
|
name = "tf_waf_byte_match_set"
|
||||||
|
byte_match_tuple {
|
||||||
|
text_transformation = "NONE"
|
||||||
|
target_string = "badrefer1"
|
||||||
|
positional_constraint = "CONTAINS"
|
||||||
|
field_to_match {
|
||||||
|
type = "HEADER"
|
||||||
|
data = "referer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `name` - (Required) The name or description of the ByteMatchSet.
|
||||||
|
* `byte_match_tuple` - (Optional)Settings for the ByteMatchSet, such as the bytes (typically a string that corresponds with ASCII characters) that you want AWS WAF to search for in web requests. ByteMatchTuple documented below.
|
||||||
|
|
||||||
|
ByteMatchTuple(byte_match_tuple) support the following:
|
||||||
|
|
||||||
|
* `field_to_match` - (Required) Settings for the ByteMatchTuple. FieldToMatch documented below.
|
||||||
|
* `positional_constraint` - (Required) Within the portion of a web request that you want to search.
|
||||||
|
* `target_string` - (Required) The value that you want AWS WAF to search for. The maximum length of the value is 50 bytes.
|
||||||
|
* `text_transformation` - (Required) The formatting way for web request.
|
||||||
|
|
||||||
|
FieldToMatch(field_to_match) support following:
|
||||||
|
|
||||||
|
* `data` - (Optional) When the value of Type is HEADER, enter the name of the header that you want AWS WAF to search, for example, User-Agent or Referer. If the value of Type is any other value, omit Data.
|
||||||
|
* `type` - (Required) The part of the web request that you want AWS WAF to search for a specified string.
|
||||||
|
|
||||||
|
## Remarks
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `id` - The ID of the WAF ByteMatchSet.
|
|
@ -0,0 +1,44 @@
|
||||||
|
---
|
||||||
|
layout: "aws"
|
||||||
|
page_title: "AWS: wafregional_ipset"
|
||||||
|
sidebar_current: "docs-aws-resource-wafregional-ipset"
|
||||||
|
description: |-
|
||||||
|
Provides a AWS WAF Regional IPSet resource for use with ALB.
|
||||||
|
---
|
||||||
|
|
||||||
|
# aws\_wafregional\_ipset
|
||||||
|
|
||||||
|
Provides a WAF Regional IPSet Resource for use with Application Load Balancer.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
resource "aws_wafregional_ipset" "ipset" {
|
||||||
|
name = "tfIPSet"
|
||||||
|
ip_set_descriptor {
|
||||||
|
type = "IPV4"
|
||||||
|
value = "192.0.7.0/24"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `name` - (Required) The name or description of the IPSet.
|
||||||
|
* `ip_set_descriptor` - (Optional) The IP address type and IP address range (in CIDR notation) from which web requests originate.
|
||||||
|
|
||||||
|
IPSetDescriptor(ip_set_descriptor) support following:
|
||||||
|
|
||||||
|
* `type` - (Required) The string like IPV4 or IPV6.
|
||||||
|
* `value` - (Required) The CIDR notation.
|
||||||
|
|
||||||
|
|
||||||
|
## Remarks
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `id` - The ID of the WAF IPSet.
|
|
@ -1122,6 +1122,21 @@
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current(/^docs-aws-resource-wafregional/) %>>
|
||||||
|
<a href="#">WAF Regional Resources</a>
|
||||||
|
<ul class="nav nav-visible">
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-aws-resource-wafregional-bytematchset") %>>
|
||||||
|
<a href="/docs/providers/aws/r/wafregional_byte_match_set.html">aws_wafregional_byte_match_set</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-aws-resource-wafregional-ipset") %>>
|
||||||
|
<a href="/docs/providers/aws/r/wafregional_ipset.html">aws_wafregional_ipset</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-aws-resource-route53") %>>
|
<li<%= sidebar_current("docs-aws-resource-route53") %>>
|
||||||
<a href="#">Route53 Resources</a>
|
<a href="#">Route53 Resources</a>
|
||||||
|
|
Loading…
Reference in New Issue