From 43d5b82f302a2f9a80e038f785fd0eed45480ebd Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Fri, 14 Apr 2017 21:12:04 +0100 Subject: [PATCH] provider/aws: Use mutex & retry for WAF change operations (#13656) --- .../aws/resource_aws_waf_byte_match_set.go | 91 +++++++--------- .../resource_aws_waf_byte_match_set_test.go | 62 +++++------ .../providers/aws/resource_aws_waf_ipset.go | 89 +++++++-------- .../aws/resource_aws_waf_ipset_test.go | 59 +++++----- .../providers/aws/resource_aws_waf_rule.go | 91 +++++++--------- .../aws/resource_aws_waf_rule_test.go | 61 +++++------ .../resource_aws_waf_size_constraint_set.go | 90 +++++++--------- ...source_aws_waf_size_constraint_set_test.go | 60 +++++------ ...esource_aws_waf_sql_injection_match_set.go | 86 +++++++-------- ...ce_aws_waf_sql_injection_match_set_test.go | 58 +++++----- .../providers/aws/resource_aws_waf_web_acl.go | 102 ++++++++---------- .../aws/resource_aws_waf_web_acl_test.go | 61 +++++------ .../aws/resource_aws_waf_xss_match_set.go | 85 +++++++-------- .../resource_aws_waf_xss_match_set_test.go | 58 +++++----- builtin/providers/aws/waf_token_handlers.go | 49 +++++++++ 15 files changed, 512 insertions(+), 590 deletions(-) create mode 100644 builtin/providers/aws/waf_token_handlers.go diff --git a/builtin/providers/aws/resource_aws_waf_byte_match_set.go b/builtin/providers/aws/resource_aws_waf_byte_match_set.go index b3a02b7d0..c28359351 100644 --- a/builtin/providers/aws/resource_aws_waf_byte_match_set.go +++ b/builtin/providers/aws/resource_aws_waf_byte_match_set.go @@ -69,24 +69,18 @@ func resourceAwsWafByteMatchSetCreate(d *schema.ResourceData, meta interface{}) log.Printf("[INFO] Creating ByteMatchSet: %s", d.Get("name").(string)) - // ChangeToken - var ct *waf.GetChangeTokenInput - - res, err := conn.GetChangeToken(ct) - if err != nil { - return errwrap.Wrapf("[ERROR] Error getting change token: {{err}}", err) - } - - params := &waf.CreateByteMatchSetInput{ - ChangeToken: res.ChangeToken, - Name: aws.String(d.Get("name").(string)), - } - - resp, err := conn.CreateByteMatchSet(params) - + wr := newWafRetryer(conn, "global") + 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) @@ -134,17 +128,14 @@ func resourceAwsWafByteMatchSetDelete(d *schema.ResourceData, meta interface{}) return errwrap.Wrapf("[ERROR] Error deleting ByteMatchSet: {{err}}", err) } - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - - req := &waf.DeleteByteMatchSetInput{ - ChangeToken: resp.ChangeToken, - ByteMatchSetId: aws.String(d.Id()), - } - - _, err = conn.DeleteByteMatchSet(req) - + wr := newWafRetryer(conn, "global") + _, 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) } @@ -155,34 +146,30 @@ func resourceAwsWafByteMatchSetDelete(d *schema.ResourceData, meta interface{}) func updateByteMatchSetResource(d *schema.ResourceData, meta interface{}, ChangeAction string) error { conn := meta.(*AWSClient).wafconn - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - if err != nil { - return errwrap.Wrapf("[ERROR] Error getting change token: {{err}}", err) - } - - req := &waf.UpdateByteMatchSetInput{ - ChangeToken: resp.ChangeToken, - ByteMatchSetId: aws.String(d.Id()), - } - - ByteMatchTuples := d.Get("byte_match_tuples").(*schema.Set) - for _, ByteMatchTuple := range ByteMatchTuples.List() { - ByteMatch := ByteMatchTuple.(map[string]interface{}) - ByteMatchUpdate := &waf.ByteMatchSetUpdate{ - Action: aws.String(ChangeAction), - ByteMatchTuple: &waf.ByteMatchTuple{ - FieldToMatch: expandFieldToMatch(ByteMatch["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})), - PositionalConstraint: aws.String(ByteMatch["positional_constraint"].(string)), - TargetString: []byte(ByteMatch["target_string"].(string)), - TextTransformation: aws.String(ByteMatch["text_transformation"].(string)), - }, + wr := newWafRetryer(conn, "global") + _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.UpdateByteMatchSetInput{ + ChangeToken: token, + ByteMatchSetId: aws.String(d.Id()), } - req.Updates = append(req.Updates, ByteMatchUpdate) - } - _, err = conn.UpdateByteMatchSet(req) + ByteMatchTuples := d.Get("byte_match_tuples").(*schema.Set) + for _, ByteMatchTuple := range ByteMatchTuples.List() { + ByteMatch := ByteMatchTuple.(map[string]interface{}) + ByteMatchUpdate := &waf.ByteMatchSetUpdate{ + Action: aws.String(ChangeAction), + ByteMatchTuple: &waf.ByteMatchTuple{ + FieldToMatch: expandFieldToMatch(ByteMatch["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})), + PositionalConstraint: aws.String(ByteMatch["positional_constraint"].(string)), + TargetString: []byte(ByteMatch["target_string"].(string)), + TextTransformation: aws.String(ByteMatch["text_transformation"].(string)), + }, + } + req.Updates = append(req.Updates, ByteMatchUpdate) + } + + return conn.UpdateByteMatchSet(req) + }) if err != nil { return errwrap.Wrapf("[ERROR] Error updating ByteMatchSet: {{err}}", err) } diff --git a/builtin/providers/aws/resource_aws_waf_byte_match_set_test.go b/builtin/providers/aws/resource_aws_waf_byte_match_set_test.go index ae9dae099..c5e0ce213 100644 --- a/builtin/providers/aws/resource_aws_waf_byte_match_set_test.go +++ b/builtin/providers/aws/resource_aws_waf_byte_match_set_test.go @@ -96,49 +96,43 @@ func testAccCheckAWSWafByteMatchSetDisappears(v *waf.ByteMatchSet) resource.Test return func(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).wafconn - // ChangeToken - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - if err != nil { - return fmt.Errorf("Error getting change token: %s", err) - } - - req := &waf.UpdateByteMatchSetInput{ - ChangeToken: resp.ChangeToken, - 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, - }, + wr := newWafRetryer(conn, "global") + _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.UpdateByteMatchSetInput{ + ChangeToken: token, + ByteMatchSetId: v.ByteMatchSetId, } - req.Updates = append(req.Updates, ByteMatchUpdate) - } - _, err = conn.UpdateByteMatchSet(req) + 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) } - resp, err = conn.GetChangeToken(ct) + _, 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 getting change token: {{err}}", err) + return errwrap.Wrapf("[ERROR] Error deleting ByteMatchSet: {{err}}", err) } - opts := &waf.DeleteByteMatchSetInput{ - ChangeToken: resp.ChangeToken, - ByteMatchSetId: v.ByteMatchSetId, - } - if _, err := conn.DeleteByteMatchSet(opts); err != nil { - return err - } return nil } } diff --git a/builtin/providers/aws/resource_aws_waf_ipset.go b/builtin/providers/aws/resource_aws_waf_ipset.go index 4b07f6419..426508db4 100644 --- a/builtin/providers/aws/resource_aws_waf_ipset.go +++ b/builtin/providers/aws/resource_aws_waf_ipset.go @@ -46,23 +46,18 @@ func resourceAwsWafIPSet() *schema.Resource { func resourceAwsWafIPSetCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).wafconn - // ChangeToken - var ct *waf.GetChangeTokenInput - - res, err := conn.GetChangeToken(ct) - if err != nil { - return fmt.Errorf("Error getting change token: %s", err) - } - - params := &waf.CreateIPSetInput{ - ChangeToken: res.ChangeToken, - Name: aws.String(d.Get("name").(string)), - } - - resp, err := conn.CreateIPSet(params) + wr := newWafRetryer(conn, "global") + 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 resourceAwsWafIPSetUpdate(d, meta) } @@ -117,18 +112,15 @@ func resourceAwsWafIPSetDelete(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("Error Removing IPSetDescriptors: %s", err) } - // ChangeToken - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - - req := &waf.DeleteIPSetInput{ - ChangeToken: resp.ChangeToken, - IPSetId: aws.String(d.Id()), - } - log.Printf("[INFO] Deleting WAF IPSet") - _, err = conn.DeleteIPSet(req) - + wr := newWafRetryer(conn, "global") + _, 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) } @@ -139,33 +131,28 @@ func resourceAwsWafIPSetDelete(d *schema.ResourceData, meta interface{}) error { func updateIPSetResource(d *schema.ResourceData, meta interface{}, ChangeAction string) error { conn := meta.(*AWSClient).wafconn - // ChangeToken - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - if err != nil { - return fmt.Errorf("Error getting change token: %s", err) - } - - req := &waf.UpdateIPSetInput{ - ChangeToken: resp.ChangeToken, - IPSetId: aws.String(d.Id()), - } - - IPSetDescriptors := d.Get("ip_set_descriptors").(*schema.Set) - for _, IPSetDescriptor := range IPSetDescriptors.List() { - IPSet := IPSetDescriptor.(map[string]interface{}) - IPSetUpdate := &waf.IPSetUpdate{ - Action: aws.String(ChangeAction), - IPSetDescriptor: &waf.IPSetDescriptor{ - Type: aws.String(IPSet["type"].(string)), - Value: aws.String(IPSet["value"].(string)), - }, + wr := newWafRetryer(conn, "global") + _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.UpdateIPSetInput{ + ChangeToken: token, + IPSetId: aws.String(d.Id()), } - req.Updates = append(req.Updates, IPSetUpdate) - } - _, err = conn.UpdateIPSet(req) + IPSetDescriptors := d.Get("ip_set_descriptors").(*schema.Set) + for _, IPSetDescriptor := range IPSetDescriptors.List() { + IPSet := IPSetDescriptor.(map[string]interface{}) + IPSetUpdate := &waf.IPSetUpdate{ + Action: aws.String(ChangeAction), + IPSetDescriptor: &waf.IPSetDescriptor{ + Type: aws.String(IPSet["type"].(string)), + Value: aws.String(IPSet["value"].(string)), + }, + } + req.Updates = append(req.Updates, IPSetUpdate) + } + + return conn.UpdateIPSet(req) + }) if err != nil { return fmt.Errorf("Error Updating WAF IPSet: %s", err) } diff --git a/builtin/providers/aws/resource_aws_waf_ipset_test.go b/builtin/providers/aws/resource_aws_waf_ipset_test.go index ffb4d6cb0..3db32dc44 100644 --- a/builtin/providers/aws/resource_aws_waf_ipset_test.go +++ b/builtin/providers/aws/resource_aws_waf_ipset_test.go @@ -100,46 +100,39 @@ func testAccCheckAWSWafIPSetDisappears(v *waf.IPSet) resource.TestCheckFunc { return func(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).wafconn - // ChangeToken - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - if err != nil { - return fmt.Errorf("Error getting change token: %s", err) - } - - req := &waf.UpdateIPSetInput{ - ChangeToken: resp.ChangeToken, - IPSetId: v.IPSetId, - } - - for _, IPSetDescriptor := range v.IPSetDescriptors { - IPSetUpdate := &waf.IPSetUpdate{ - Action: aws.String("DELETE"), - IPSetDescriptor: &waf.IPSetDescriptor{ - Type: IPSetDescriptor.Type, - Value: IPSetDescriptor.Value, - }, + wr := newWafRetryer(conn, "global") + _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.UpdateIPSetInput{ + ChangeToken: token, + IPSetId: v.IPSetId, } - req.Updates = append(req.Updates, IPSetUpdate) - } - _, err = conn.UpdateIPSet(req) + 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) } - resp, err = conn.GetChangeToken(ct) + _, 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 getting change token for waf IPSet: %s", err) - } - - opts := &waf.DeleteIPSetInput{ - ChangeToken: resp.ChangeToken, - IPSetId: v.IPSetId, - } - if _, err := conn.DeleteIPSet(opts); err != nil { - return err + return fmt.Errorf("Error Deleting WAF IPSet: %s", err) } return nil } diff --git a/builtin/providers/aws/resource_aws_waf_rule.go b/builtin/providers/aws/resource_aws_waf_rule.go index ba59bf222..f750f6ea0 100644 --- a/builtin/providers/aws/resource_aws_waf_rule.go +++ b/builtin/providers/aws/resource_aws_waf_rule.go @@ -71,24 +71,20 @@ func resourceAwsWafRule() *schema.Resource { func resourceAwsWafRuleCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).wafconn - // ChangeToken - var ct *waf.GetChangeTokenInput + wr := newWafRetryer(conn, "global") + out, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + params := &waf.CreateRuleInput{ + ChangeToken: token, + MetricName: aws.String(d.Get("metric_name").(string)), + Name: aws.String(d.Get("name").(string)), + } - res, err := conn.GetChangeToken(ct) - if err != nil { - return fmt.Errorf("Error getting change token: %s", err) - } - - params := &waf.CreateRuleInput{ - ChangeToken: res.ChangeToken, - MetricName: aws.String(d.Get("metric_name").(string)), - Name: aws.String(d.Get("name").(string)), - } - - resp, err := conn.CreateRule(params) + return conn.CreateRule(params) + }) if err != nil { return err } + resp := out.(*waf.CreateRuleOutput) d.SetId(*resp.Rule.RuleId) return resourceAwsWafRuleUpdate(d, meta) } @@ -143,18 +139,16 @@ func resourceAwsWafRuleDelete(d *schema.ResourceData, meta interface{}) error { if err != nil { return fmt.Errorf("Error Removing WAF Rule Predicates: %s", err) } - // ChangeToken - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - - req := &waf.DeleteRuleInput{ - ChangeToken: resp.ChangeToken, - RuleId: aws.String(d.Id()), - } - log.Printf("[INFO] Deleting WAF Rule") - _, err = conn.DeleteRule(req) + wr := newWafRetryer(conn, "global") + _, err = wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.DeleteRuleInput{ + ChangeToken: token, + RuleId: aws.String(d.Id()), + } + log.Printf("[INFO] Deleting WAF Rule") + return conn.DeleteRule(req) + }) if err != nil { return fmt.Errorf("Error deleting WAF Rule: %s", err) } @@ -165,34 +159,29 @@ func resourceAwsWafRuleDelete(d *schema.ResourceData, meta interface{}) error { func updateWafRuleResource(d *schema.ResourceData, meta interface{}, ChangeAction string) error { conn := meta.(*AWSClient).wafconn - // ChangeToken - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - if err != nil { - return fmt.Errorf("Error getting change token: %s", err) - } - - req := &waf.UpdateRuleInput{ - ChangeToken: resp.ChangeToken, - RuleId: aws.String(d.Id()), - } - - predicatesSet := d.Get("predicates").(*schema.Set) - for _, predicateI := range predicatesSet.List() { - predicate := predicateI.(map[string]interface{}) - updatePredicate := &waf.RuleUpdate{ - Action: aws.String(ChangeAction), - Predicate: &waf.Predicate{ - Negated: aws.Bool(predicate["negated"].(bool)), - Type: aws.String(predicate["type"].(string)), - DataId: aws.String(predicate["data_id"].(string)), - }, + wr := newWafRetryer(conn, "global") + _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.UpdateRuleInput{ + ChangeToken: token, + RuleId: aws.String(d.Id()), } - req.Updates = append(req.Updates, updatePredicate) - } - _, err = conn.UpdateRule(req) + predicatesSet := d.Get("predicates").(*schema.Set) + for _, predicateI := range predicatesSet.List() { + predicate := predicateI.(map[string]interface{}) + updatePredicate := &waf.RuleUpdate{ + Action: aws.String(ChangeAction), + Predicate: &waf.Predicate{ + Negated: aws.Bool(predicate["negated"].(bool)), + Type: aws.String(predicate["type"].(string)), + DataId: aws.String(predicate["data_id"].(string)), + }, + } + req.Updates = append(req.Updates, updatePredicate) + } + + return conn.UpdateRule(req) + }) if err != nil { return fmt.Errorf("Error Updating WAF Rule: %s", err) } diff --git a/builtin/providers/aws/resource_aws_waf_rule_test.go b/builtin/providers/aws/resource_aws_waf_rule_test.go index 52065b106..c8e6bafbf 100644 --- a/builtin/providers/aws/resource_aws_waf_rule_test.go +++ b/builtin/providers/aws/resource_aws_waf_rule_test.go @@ -99,47 +99,40 @@ func testAccCheckAWSWafRuleDisappears(v *waf.Rule) resource.TestCheckFunc { return func(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).wafconn - // ChangeToken - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - if err != nil { - return fmt.Errorf("Error getting change token: %s", err) - } - - req := &waf.UpdateRuleInput{ - ChangeToken: resp.ChangeToken, - RuleId: v.RuleId, - } - - for _, Predicate := range v.Predicates { - Predicate := &waf.RuleUpdate{ - Action: aws.String("DELETE"), - Predicate: &waf.Predicate{ - Negated: Predicate.Negated, - Type: Predicate.Type, - DataId: Predicate.DataId, - }, + wr := newWafRetryer(conn, "global") + _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.UpdateRuleInput{ + ChangeToken: token, + RuleId: v.RuleId, } - req.Updates = append(req.Updates, Predicate) - } - _, err = conn.UpdateRule(req) + for _, Predicate := range v.Predicates { + Predicate := &waf.RuleUpdate{ + Action: aws.String("DELETE"), + Predicate: &waf.Predicate{ + Negated: Predicate.Negated, + Type: Predicate.Type, + DataId: Predicate.DataId, + }, + } + req.Updates = append(req.Updates, Predicate) + } + + return conn.UpdateRule(req) + }) if err != nil { return fmt.Errorf("Error Updating WAF Rule: %s", err) } - resp, err = conn.GetChangeToken(ct) + _, err = wr.RetryWithToken(func(token *string) (interface{}, error) { + opts := &waf.DeleteRuleInput{ + ChangeToken: token, + RuleId: v.RuleId, + } + return conn.DeleteRule(opts) + }) if err != nil { - return fmt.Errorf("Error getting change token for waf Rule: %s", err) - } - - opts := &waf.DeleteRuleInput{ - ChangeToken: resp.ChangeToken, - RuleId: v.RuleId, - } - if _, err := conn.DeleteRule(opts); err != nil { - return err + return fmt.Errorf("Error Deleting WAF Rule: %s", err) } return nil } diff --git a/builtin/providers/aws/resource_aws_waf_size_constraint_set.go b/builtin/providers/aws/resource_aws_waf_size_constraint_set.go index 9f384e82c..db9d5c516 100644 --- a/builtin/providers/aws/resource_aws_waf_size_constraint_set.go +++ b/builtin/providers/aws/resource_aws_waf_size_constraint_set.go @@ -69,24 +69,19 @@ func resourceAwsWafSizeConstraintSetCreate(d *schema.ResourceData, meta interfac log.Printf("[INFO] Creating SizeConstraintSet: %s", d.Get("name").(string)) - // ChangeToken - var ct *waf.GetChangeTokenInput - - res, err := conn.GetChangeToken(ct) - if err != nil { - return errwrap.Wrapf("[ERROR] Error getting change token: {{err}}", err) - } - - params := &waf.CreateSizeConstraintSetInput{ - ChangeToken: res.ChangeToken, - Name: aws.String(d.Get("name").(string)), - } - - resp, err := conn.CreateSizeConstraintSet(params) + wr := newWafRetryer(conn, "global") + out, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + params := &waf.CreateSizeConstraintSetInput{ + ChangeToken: token, + Name: aws.String(d.Get("name").(string)), + } + return conn.CreateSizeConstraintSet(params) + }) if err != nil { return errwrap.Wrapf("[ERROR] Error creating SizeConstraintSet: {{err}}", err) } + resp := out.(*waf.CreateSizeConstraintSetOutput) d.SetId(*resp.SizeConstraintSet.SizeConstraintSetId) @@ -134,17 +129,14 @@ func resourceAwsWafSizeConstraintSetDelete(d *schema.ResourceData, meta interfac return errwrap.Wrapf("[ERROR] Error deleting SizeConstraintSet: {{err}}", err) } - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - - req := &waf.DeleteSizeConstraintSetInput{ - ChangeToken: resp.ChangeToken, - SizeConstraintSetId: aws.String(d.Id()), - } - - _, err = conn.DeleteSizeConstraintSet(req) - + wr := newWafRetryer(conn, "global") + _, err = wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.DeleteSizeConstraintSetInput{ + ChangeToken: token, + SizeConstraintSetId: aws.String(d.Id()), + } + return conn.DeleteSizeConstraintSet(req) + }) if err != nil { return errwrap.Wrapf("[ERROR] Error deleting SizeConstraintSet: {{err}}", err) } @@ -155,34 +147,30 @@ func resourceAwsWafSizeConstraintSetDelete(d *schema.ResourceData, meta interfac func updateSizeConstraintSetResource(d *schema.ResourceData, meta interface{}, ChangeAction string) error { conn := meta.(*AWSClient).wafconn - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - if err != nil { - return errwrap.Wrapf("[ERROR] Error getting change token: {{err}}", err) - } - - req := &waf.UpdateSizeConstraintSetInput{ - ChangeToken: resp.ChangeToken, - SizeConstraintSetId: aws.String(d.Id()), - } - - sizeConstraints := d.Get("size_constraints").(*schema.Set) - for _, sizeConstraint := range sizeConstraints.List() { - sc := sizeConstraint.(map[string]interface{}) - sizeConstraintUpdate := &waf.SizeConstraintSetUpdate{ - Action: aws.String(ChangeAction), - SizeConstraint: &waf.SizeConstraint{ - FieldToMatch: expandFieldToMatch(sc["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})), - ComparisonOperator: aws.String(sc["comparison_operator"].(string)), - Size: aws.Int64(int64(sc["size"].(int))), - TextTransformation: aws.String(sc["text_transformation"].(string)), - }, + wr := newWafRetryer(conn, "global") + _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.UpdateSizeConstraintSetInput{ + ChangeToken: token, + SizeConstraintSetId: aws.String(d.Id()), } - req.Updates = append(req.Updates, sizeConstraintUpdate) - } - _, err = conn.UpdateSizeConstraintSet(req) + sizeConstraints := d.Get("size_constraints").(*schema.Set) + for _, sizeConstraint := range sizeConstraints.List() { + sc := sizeConstraint.(map[string]interface{}) + sizeConstraintUpdate := &waf.SizeConstraintSetUpdate{ + Action: aws.String(ChangeAction), + SizeConstraint: &waf.SizeConstraint{ + FieldToMatch: expandFieldToMatch(sc["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})), + ComparisonOperator: aws.String(sc["comparison_operator"].(string)), + Size: aws.Int64(int64(sc["size"].(int))), + TextTransformation: aws.String(sc["text_transformation"].(string)), + }, + } + req.Updates = append(req.Updates, sizeConstraintUpdate) + } + + return conn.UpdateSizeConstraintSet(req) + }) if err != nil { return errwrap.Wrapf("[ERROR] Error updating SizeConstraintSet: {{err}}", err) } diff --git a/builtin/providers/aws/resource_aws_waf_size_constraint_set_test.go b/builtin/providers/aws/resource_aws_waf_size_constraint_set_test.go index 13eee40e4..a6bd5156e 100644 --- a/builtin/providers/aws/resource_aws_waf_size_constraint_set_test.go +++ b/builtin/providers/aws/resource_aws_waf_size_constraint_set_test.go @@ -96,45 +96,39 @@ func testAccCheckAWSWafSizeConstraintSetDisappears(v *waf.SizeConstraintSet) res return func(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).wafconn - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - if err != nil { - return fmt.Errorf("Error getting change token: %s", err) - } - - req := &waf.UpdateSizeConstraintSetInput{ - ChangeToken: resp.ChangeToken, - SizeConstraintSetId: v.SizeConstraintSetId, - } - - for _, sizeConstraint := range v.SizeConstraints { - sizeConstraintUpdate := &waf.SizeConstraintSetUpdate{ - Action: aws.String("DELETE"), - SizeConstraint: &waf.SizeConstraint{ - FieldToMatch: sizeConstraint.FieldToMatch, - ComparisonOperator: sizeConstraint.ComparisonOperator, - Size: sizeConstraint.Size, - TextTransformation: sizeConstraint.TextTransformation, - }, + wr := newWafRetryer(conn, "global") + _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.UpdateSizeConstraintSetInput{ + ChangeToken: token, + SizeConstraintSetId: v.SizeConstraintSetId, } - req.Updates = append(req.Updates, sizeConstraintUpdate) - } - _, err = conn.UpdateSizeConstraintSet(req) + + for _, sizeConstraint := range v.SizeConstraints { + sizeConstraintUpdate := &waf.SizeConstraintSetUpdate{ + Action: aws.String("DELETE"), + SizeConstraint: &waf.SizeConstraint{ + FieldToMatch: sizeConstraint.FieldToMatch, + ComparisonOperator: sizeConstraint.ComparisonOperator, + Size: sizeConstraint.Size, + TextTransformation: sizeConstraint.TextTransformation, + }, + } + req.Updates = append(req.Updates, sizeConstraintUpdate) + } + return conn.UpdateSizeConstraintSet(req) + }) if err != nil { return errwrap.Wrapf("[ERROR] Error updating SizeConstraintSet: {{err}}", err) } - resp, err = conn.GetChangeToken(ct) + _, err = wr.RetryWithToken(func(token *string) (interface{}, error) { + opts := &waf.DeleteSizeConstraintSetInput{ + ChangeToken: token, + SizeConstraintSetId: v.SizeConstraintSetId, + } + return conn.DeleteSizeConstraintSet(opts) + }) if err != nil { - return errwrap.Wrapf("[ERROR] Error getting change token: {{err}}", err) - } - - opts := &waf.DeleteSizeConstraintSetInput{ - ChangeToken: resp.ChangeToken, - SizeConstraintSetId: v.SizeConstraintSetId, - } - if _, err := conn.DeleteSizeConstraintSet(opts); err != nil { return err } return nil diff --git a/builtin/providers/aws/resource_aws_waf_sql_injection_match_set.go b/builtin/providers/aws/resource_aws_waf_sql_injection_match_set.go index 01efd6a32..c888efe5a 100644 --- a/builtin/providers/aws/resource_aws_waf_sql_injection_match_set.go +++ b/builtin/providers/aws/resource_aws_waf_sql_injection_match_set.go @@ -61,25 +61,19 @@ func resourceAwsWafSqlInjectionMatchSetCreate(d *schema.ResourceData, meta inter log.Printf("[INFO] Creating SqlInjectionMatchSet: %s", d.Get("name").(string)) - // ChangeToken - var ct *waf.GetChangeTokenInput - - res, err := conn.GetChangeToken(ct) - if err != nil { - return errwrap.Wrapf("[ERROR] Error getting change token: {{err}}", err) - } - - params := &waf.CreateSqlInjectionMatchSetInput{ - ChangeToken: res.ChangeToken, - Name: aws.String(d.Get("name").(string)), - } - - resp, err := conn.CreateSqlInjectionMatchSet(params) + wr := newWafRetryer(conn, "global") + out, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + params := &waf.CreateSqlInjectionMatchSetInput{ + ChangeToken: token, + Name: aws.String(d.Get("name").(string)), + } + return conn.CreateSqlInjectionMatchSet(params) + }) if err != nil { return errwrap.Wrapf("[ERROR] Error creating SqlInjectionMatchSet: {{err}}", err) } - + resp := out.(*waf.CreateSqlInjectionMatchSetOutput) d.SetId(*resp.SqlInjectionMatchSet.SqlInjectionMatchSetId) return resourceAwsWafSqlInjectionMatchSetUpdate(d, meta) @@ -126,17 +120,15 @@ func resourceAwsWafSqlInjectionMatchSetDelete(d *schema.ResourceData, meta inter return errwrap.Wrapf("[ERROR] Error deleting SqlInjectionMatchSet: {{err}}", err) } - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - - req := &waf.DeleteSqlInjectionMatchSetInput{ - ChangeToken: resp.ChangeToken, - SqlInjectionMatchSetId: aws.String(d.Id()), - } - - _, err = conn.DeleteSqlInjectionMatchSet(req) + wr := newWafRetryer(conn, "global") + _, err = wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.DeleteSqlInjectionMatchSetInput{ + ChangeToken: token, + SqlInjectionMatchSetId: aws.String(d.Id()), + } + return conn.DeleteSqlInjectionMatchSet(req) + }) if err != nil { return errwrap.Wrapf("[ERROR] Error deleting SqlInjectionMatchSet: {{err}}", err) } @@ -147,32 +139,28 @@ func resourceAwsWafSqlInjectionMatchSetDelete(d *schema.ResourceData, meta inter func updateSqlInjectionMatchSetResource(d *schema.ResourceData, meta interface{}, ChangeAction string) error { conn := meta.(*AWSClient).wafconn - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - if err != nil { - return errwrap.Wrapf("[ERROR] Error getting change token: {{err}}", err) - } - - req := &waf.UpdateSqlInjectionMatchSetInput{ - ChangeToken: resp.ChangeToken, - SqlInjectionMatchSetId: aws.String(d.Id()), - } - - sqlInjectionMatchTuples := d.Get("sql_injection_match_tuples").(*schema.Set) - for _, sqlInjectionMatchTuple := range sqlInjectionMatchTuples.List() { - simt := sqlInjectionMatchTuple.(map[string]interface{}) - sizeConstraintUpdate := &waf.SqlInjectionMatchSetUpdate{ - Action: aws.String(ChangeAction), - SqlInjectionMatchTuple: &waf.SqlInjectionMatchTuple{ - FieldToMatch: expandFieldToMatch(simt["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})), - TextTransformation: aws.String(simt["text_transformation"].(string)), - }, + wr := newWafRetryer(conn, "global") + _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.UpdateSqlInjectionMatchSetInput{ + ChangeToken: token, + SqlInjectionMatchSetId: aws.String(d.Id()), } - req.Updates = append(req.Updates, sizeConstraintUpdate) - } - _, err = conn.UpdateSqlInjectionMatchSet(req) + sqlInjectionMatchTuples := d.Get("sql_injection_match_tuples").(*schema.Set) + for _, sqlInjectionMatchTuple := range sqlInjectionMatchTuples.List() { + simt := sqlInjectionMatchTuple.(map[string]interface{}) + sizeConstraintUpdate := &waf.SqlInjectionMatchSetUpdate{ + Action: aws.String(ChangeAction), + SqlInjectionMatchTuple: &waf.SqlInjectionMatchTuple{ + FieldToMatch: expandFieldToMatch(simt["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})), + TextTransformation: aws.String(simt["text_transformation"].(string)), + }, + } + req.Updates = append(req.Updates, sizeConstraintUpdate) + } + + return conn.UpdateSqlInjectionMatchSet(req) + }) if err != nil { return errwrap.Wrapf("[ERROR] Error updating SqlInjectionMatchSet: {{err}}", err) } diff --git a/builtin/providers/aws/resource_aws_waf_sql_injection_match_set_test.go b/builtin/providers/aws/resource_aws_waf_sql_injection_match_set_test.go index f13f6711e..5ea8bca0f 100644 --- a/builtin/providers/aws/resource_aws_waf_sql_injection_match_set_test.go +++ b/builtin/providers/aws/resource_aws_waf_sql_injection_match_set_test.go @@ -96,44 +96,38 @@ func testAccCheckAWSWafSqlInjectionMatchSetDisappears(v *waf.SqlInjectionMatchSe return func(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).wafconn - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - if err != nil { - return fmt.Errorf("Error getting change token: %s", err) - } - - req := &waf.UpdateSqlInjectionMatchSetInput{ - ChangeToken: resp.ChangeToken, - SqlInjectionMatchSetId: v.SqlInjectionMatchSetId, - } - - for _, sqlInjectionMatchTuple := range v.SqlInjectionMatchTuples { - sqlInjectionMatchTupleUpdate := &waf.SqlInjectionMatchSetUpdate{ - Action: aws.String("DELETE"), - SqlInjectionMatchTuple: &waf.SqlInjectionMatchTuple{ - FieldToMatch: sqlInjectionMatchTuple.FieldToMatch, - TextTransformation: sqlInjectionMatchTuple.TextTransformation, - }, + wr := newWafRetryer(conn, "global") + _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.UpdateSqlInjectionMatchSetInput{ + ChangeToken: token, + SqlInjectionMatchSetId: v.SqlInjectionMatchSetId, } - req.Updates = append(req.Updates, sqlInjectionMatchTupleUpdate) - } - _, err = conn.UpdateSqlInjectionMatchSet(req) + + for _, sqlInjectionMatchTuple := range v.SqlInjectionMatchTuples { + sqlInjectionMatchTupleUpdate := &waf.SqlInjectionMatchSetUpdate{ + Action: aws.String("DELETE"), + SqlInjectionMatchTuple: &waf.SqlInjectionMatchTuple{ + FieldToMatch: sqlInjectionMatchTuple.FieldToMatch, + TextTransformation: sqlInjectionMatchTuple.TextTransformation, + }, + } + req.Updates = append(req.Updates, sqlInjectionMatchTupleUpdate) + } + return conn.UpdateSqlInjectionMatchSet(req) + }) if err != nil { return errwrap.Wrapf("[ERROR] Error updating SqlInjectionMatchSet: {{err}}", err) } - resp, err = conn.GetChangeToken(ct) + _, err = wr.RetryWithToken(func(token *string) (interface{}, error) { + opts := &waf.DeleteSqlInjectionMatchSetInput{ + ChangeToken: token, + SqlInjectionMatchSetId: v.SqlInjectionMatchSetId, + } + return conn.DeleteSqlInjectionMatchSet(opts) + }) if err != nil { - return errwrap.Wrapf("[ERROR] Error getting change token: {{err}}", err) - } - - opts := &waf.DeleteSqlInjectionMatchSetInput{ - ChangeToken: resp.ChangeToken, - SqlInjectionMatchSetId: v.SqlInjectionMatchSetId, - } - if _, err := conn.DeleteSqlInjectionMatchSet(opts); err != nil { - return err + return errwrap.Wrapf("[ERROR] Error deleting SqlInjectionMatchSet: {{err}}", err) } return nil } diff --git a/builtin/providers/aws/resource_aws_waf_web_acl.go b/builtin/providers/aws/resource_aws_waf_web_acl.go index dd3a9d1d3..a45b1cc0e 100644 --- a/builtin/providers/aws/resource_aws_waf_web_acl.go +++ b/builtin/providers/aws/resource_aws_waf_web_acl.go @@ -77,25 +77,21 @@ func resourceAwsWafWebAcl() *schema.Resource { func resourceAwsWafWebAclCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).wafconn - // ChangeToken - var ct *waf.GetChangeTokenInput + wr := newWafRetryer(conn, "global") + out, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + params := &waf.CreateWebACLInput{ + ChangeToken: token, + DefaultAction: expandDefaultAction(d), + MetricName: aws.String(d.Get("metric_name").(string)), + Name: aws.String(d.Get("name").(string)), + } - res, err := conn.GetChangeToken(ct) - if err != nil { - return fmt.Errorf("Error getting change token: %s", err) - } - - params := &waf.CreateWebACLInput{ - ChangeToken: res.ChangeToken, - DefaultAction: expandDefaultAction(d), - MetricName: aws.String(d.Get("metric_name").(string)), - Name: aws.String(d.Get("name").(string)), - } - - resp, err := conn.CreateWebACL(params) + return conn.CreateWebACL(params) + }) if err != nil { return err } + resp := out.(*waf.CreateWebACLOutput) d.SetId(*resp.WebACL.WebACLId) return resourceAwsWafWebAclUpdate(d, meta) } @@ -144,18 +140,16 @@ func resourceAwsWafWebAclDelete(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error Removing WAF ACL Rules: %s", err) } - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - - req := &waf.DeleteWebACLInput{ - ChangeToken: resp.ChangeToken, - WebACLId: aws.String(d.Id()), - } - - log.Printf("[INFO] Deleting WAF ACL") - _, err = conn.DeleteWebACL(req) + wr := newWafRetryer(conn, "global") + _, err = wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.DeleteWebACLInput{ + ChangeToken: token, + WebACLId: aws.String(d.Id()), + } + log.Printf("[INFO] Deleting WAF ACL") + return conn.DeleteWebACL(req) + }) if err != nil { return fmt.Errorf("Error Deleting WAF ACL: %s", err) } @@ -164,38 +158,34 @@ func resourceAwsWafWebAclDelete(d *schema.ResourceData, meta interface{}) error func updateWebAclResource(d *schema.ResourceData, meta interface{}, ChangeAction string) error { conn := meta.(*AWSClient).wafconn - // ChangeToken - var ct *waf.GetChangeTokenInput - resp, err := conn.GetChangeToken(ct) - if err != nil { - return fmt.Errorf("Error getting change token: %s", err) - } - - req := &waf.UpdateWebACLInput{ - ChangeToken: resp.ChangeToken, - WebACLId: aws.String(d.Id()), - } - - if d.HasChange("default_action") { - req.DefaultAction = expandDefaultAction(d) - } - - rules := d.Get("rules").(*schema.Set) - for _, rule := range rules.List() { - aclRule := rule.(map[string]interface{}) - action := aclRule["action"].(*schema.Set).List()[0].(map[string]interface{}) - aclRuleUpdate := &waf.WebACLUpdate{ - Action: aws.String(ChangeAction), - ActivatedRule: &waf.ActivatedRule{ - Priority: aws.Int64(int64(aclRule["priority"].(int))), - RuleId: aws.String(aclRule["rule_id"].(string)), - Action: &waf.WafAction{Type: aws.String(action["type"].(string))}, - }, + wr := newWafRetryer(conn, "global") + _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.UpdateWebACLInput{ + ChangeToken: token, + WebACLId: aws.String(d.Id()), } - req.Updates = append(req.Updates, aclRuleUpdate) - } - _, err = conn.UpdateWebACL(req) + + if d.HasChange("default_action") { + req.DefaultAction = expandDefaultAction(d) + } + + rules := d.Get("rules").(*schema.Set) + for _, rule := range rules.List() { + aclRule := rule.(map[string]interface{}) + action := aclRule["action"].(*schema.Set).List()[0].(map[string]interface{}) + aclRuleUpdate := &waf.WebACLUpdate{ + Action: aws.String(ChangeAction), + ActivatedRule: &waf.ActivatedRule{ + Priority: aws.Int64(int64(aclRule["priority"].(int))), + RuleId: aws.String(aclRule["rule_id"].(string)), + Action: &waf.WafAction{Type: aws.String(action["type"].(string))}, + }, + } + req.Updates = append(req.Updates, aclRuleUpdate) + } + return conn.UpdateWebACL(req) + }) if err != nil { return fmt.Errorf("Error Updating WAF ACL: %s", err) } diff --git a/builtin/providers/aws/resource_aws_waf_web_acl_test.go b/builtin/providers/aws/resource_aws_waf_web_acl_test.go index 265cb15a4..6591fed0e 100644 --- a/builtin/providers/aws/resource_aws_waf_web_acl_test.go +++ b/builtin/providers/aws/resource_aws_waf_web_acl_test.go @@ -159,47 +159,40 @@ func testAccCheckAWSWafWebAclDisappears(v *waf.WebACL) resource.TestCheckFunc { return func(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).wafconn - // ChangeToken - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - if err != nil { - return fmt.Errorf("Error getting change token: %s", err) - } - - req := &waf.UpdateWebACLInput{ - ChangeToken: resp.ChangeToken, - WebACLId: v.WebACLId, - } - - for _, ActivatedRule := range v.Rules { - WebACLUpdate := &waf.WebACLUpdate{ - Action: aws.String("DELETE"), - ActivatedRule: &waf.ActivatedRule{ - Priority: ActivatedRule.Priority, - RuleId: ActivatedRule.RuleId, - Action: ActivatedRule.Action, - }, + wr := newWafRetryer(conn, "global") + _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.UpdateWebACLInput{ + ChangeToken: token, + WebACLId: v.WebACLId, } - req.Updates = append(req.Updates, WebACLUpdate) - } - _, err = conn.UpdateWebACL(req) + for _, ActivatedRule := range v.Rules { + WebACLUpdate := &waf.WebACLUpdate{ + Action: aws.String("DELETE"), + ActivatedRule: &waf.ActivatedRule{ + Priority: ActivatedRule.Priority, + RuleId: ActivatedRule.RuleId, + Action: ActivatedRule.Action, + }, + } + req.Updates = append(req.Updates, WebACLUpdate) + } + + return conn.UpdateWebACL(req) + }) if err != nil { return fmt.Errorf("Error Updating WAF ACL: %s", err) } - resp, err = conn.GetChangeToken(ct) + _, err = wr.RetryWithToken(func(token *string) (interface{}, error) { + opts := &waf.DeleteWebACLInput{ + ChangeToken: token, + WebACLId: v.WebACLId, + } + return conn.DeleteWebACL(opts) + }) if err != nil { - return fmt.Errorf("Error getting change token for waf ACL: %s", err) - } - - opts := &waf.DeleteWebACLInput{ - ChangeToken: resp.ChangeToken, - WebACLId: v.WebACLId, - } - if _, err := conn.DeleteWebACL(opts); err != nil { - return err + return fmt.Errorf("Error Deleting WAF ACL: %s", err) } return nil } diff --git a/builtin/providers/aws/resource_aws_waf_xss_match_set.go b/builtin/providers/aws/resource_aws_waf_xss_match_set.go index 574245f8b..222940dd0 100644 --- a/builtin/providers/aws/resource_aws_waf_xss_match_set.go +++ b/builtin/providers/aws/resource_aws_waf_xss_match_set.go @@ -61,24 +61,19 @@ func resourceAwsWafXssMatchSetCreate(d *schema.ResourceData, meta interface{}) e log.Printf("[INFO] Creating XssMatchSet: %s", d.Get("name").(string)) - // ChangeToken - var ct *waf.GetChangeTokenInput - - res, err := conn.GetChangeToken(ct) - if err != nil { - return errwrap.Wrapf("[ERROR] Error getting change token: {{err}}", err) - } - - params := &waf.CreateXssMatchSetInput{ - ChangeToken: res.ChangeToken, - Name: aws.String(d.Get("name").(string)), - } - - resp, err := conn.CreateXssMatchSet(params) + wr := newWafRetryer(conn, "global") + out, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + params := &waf.CreateXssMatchSetInput{ + ChangeToken: token, + Name: aws.String(d.Get("name").(string)), + } + return conn.CreateXssMatchSet(params) + }) if err != nil { return errwrap.Wrapf("[ERROR] Error creating XssMatchSet: {{err}}", err) } + resp := out.(*waf.CreateXssMatchSetOutput) d.SetId(*resp.XssMatchSet.XssMatchSetId) @@ -126,17 +121,15 @@ func resourceAwsWafXssMatchSetDelete(d *schema.ResourceData, meta interface{}) e return errwrap.Wrapf("[ERROR] Error deleting XssMatchSet: {{err}}", err) } - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - - req := &waf.DeleteXssMatchSetInput{ - ChangeToken: resp.ChangeToken, - XssMatchSetId: aws.String(d.Id()), - } - - _, err = conn.DeleteXssMatchSet(req) + wr := newWafRetryer(conn, "global") + _, err = wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.DeleteXssMatchSetInput{ + ChangeToken: token, + XssMatchSetId: aws.String(d.Id()), + } + return conn.DeleteXssMatchSet(req) + }) if err != nil { return errwrap.Wrapf("[ERROR] Error deleting XssMatchSet: {{err}}", err) } @@ -147,32 +140,28 @@ func resourceAwsWafXssMatchSetDelete(d *schema.ResourceData, meta interface{}) e func updateXssMatchSetResource(d *schema.ResourceData, meta interface{}, ChangeAction string) error { conn := meta.(*AWSClient).wafconn - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - if err != nil { - return errwrap.Wrapf("[ERROR] Error getting change token: {{err}}", err) - } - - req := &waf.UpdateXssMatchSetInput{ - ChangeToken: resp.ChangeToken, - XssMatchSetId: aws.String(d.Id()), - } - - xssMatchTuples := d.Get("xss_match_tuples").(*schema.Set) - for _, xssMatchTuple := range xssMatchTuples.List() { - xmt := xssMatchTuple.(map[string]interface{}) - xssMatchTupleUpdate := &waf.XssMatchSetUpdate{ - Action: aws.String(ChangeAction), - XssMatchTuple: &waf.XssMatchTuple{ - FieldToMatch: expandFieldToMatch(xmt["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})), - TextTransformation: aws.String(xmt["text_transformation"].(string)), - }, + wr := newWafRetryer(conn, "global") + _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.UpdateXssMatchSetInput{ + ChangeToken: token, + XssMatchSetId: aws.String(d.Id()), } - req.Updates = append(req.Updates, xssMatchTupleUpdate) - } - _, err = conn.UpdateXssMatchSet(req) + xssMatchTuples := d.Get("xss_match_tuples").(*schema.Set) + for _, xssMatchTuple := range xssMatchTuples.List() { + xmt := xssMatchTuple.(map[string]interface{}) + xssMatchTupleUpdate := &waf.XssMatchSetUpdate{ + Action: aws.String(ChangeAction), + XssMatchTuple: &waf.XssMatchTuple{ + FieldToMatch: expandFieldToMatch(xmt["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})), + TextTransformation: aws.String(xmt["text_transformation"].(string)), + }, + } + req.Updates = append(req.Updates, xssMatchTupleUpdate) + } + + return conn.UpdateXssMatchSet(req) + }) if err != nil { return errwrap.Wrapf("[ERROR] Error updating XssMatchSet: {{err}}", err) } diff --git a/builtin/providers/aws/resource_aws_waf_xss_match_set_test.go b/builtin/providers/aws/resource_aws_waf_xss_match_set_test.go index 5128fc813..b2d223086 100644 --- a/builtin/providers/aws/resource_aws_waf_xss_match_set_test.go +++ b/builtin/providers/aws/resource_aws_waf_xss_match_set_test.go @@ -96,44 +96,38 @@ func testAccCheckAWSWafXssMatchSetDisappears(v *waf.XssMatchSet) resource.TestCh return func(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).wafconn - var ct *waf.GetChangeTokenInput - - resp, err := conn.GetChangeToken(ct) - if err != nil { - return fmt.Errorf("Error getting change token: %s", err) - } - - req := &waf.UpdateXssMatchSetInput{ - ChangeToken: resp.ChangeToken, - XssMatchSetId: v.XssMatchSetId, - } - - for _, xssMatchTuple := range v.XssMatchTuples { - xssMatchTupleUpdate := &waf.XssMatchSetUpdate{ - Action: aws.String("DELETE"), - XssMatchTuple: &waf.XssMatchTuple{ - FieldToMatch: xssMatchTuple.FieldToMatch, - TextTransformation: xssMatchTuple.TextTransformation, - }, + wr := newWafRetryer(conn, "global") + _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { + req := &waf.UpdateXssMatchSetInput{ + ChangeToken: token, + XssMatchSetId: v.XssMatchSetId, } - req.Updates = append(req.Updates, xssMatchTupleUpdate) - } - _, err = conn.UpdateXssMatchSet(req) + + for _, xssMatchTuple := range v.XssMatchTuples { + xssMatchTupleUpdate := &waf.XssMatchSetUpdate{ + Action: aws.String("DELETE"), + XssMatchTuple: &waf.XssMatchTuple{ + FieldToMatch: xssMatchTuple.FieldToMatch, + TextTransformation: xssMatchTuple.TextTransformation, + }, + } + req.Updates = append(req.Updates, xssMatchTupleUpdate) + } + return conn.UpdateXssMatchSet(req) + }) if err != nil { return errwrap.Wrapf("[ERROR] Error updating XssMatchSet: {{err}}", err) } - resp, err = conn.GetChangeToken(ct) + _, err = wr.RetryWithToken(func(token *string) (interface{}, error) { + opts := &waf.DeleteXssMatchSetInput{ + ChangeToken: token, + XssMatchSetId: v.XssMatchSetId, + } + return conn.DeleteXssMatchSet(opts) + }) if err != nil { - return errwrap.Wrapf("[ERROR] Error getting change token: {{err}}", err) - } - - opts := &waf.DeleteXssMatchSetInput{ - ChangeToken: resp.ChangeToken, - XssMatchSetId: v.XssMatchSetId, - } - if _, err := conn.DeleteXssMatchSet(opts); err != nil { - return err + return errwrap.Wrapf("[ERROR] Error deleting XssMatchSet: {{err}}", err) } return nil } diff --git a/builtin/providers/aws/waf_token_handlers.go b/builtin/providers/aws/waf_token_handlers.go new file mode 100644 index 000000000..ac99f0950 --- /dev/null +++ b/builtin/providers/aws/waf_token_handlers.go @@ -0,0 +1,49 @@ +package aws + +import ( + "time" + + "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/resource" +) + +type WafRetryer struct { + Connection *waf.WAF + Region string +} + +type withTokenFunc func(token *string) (interface{}, error) + +func (t *WafRetryer) RetryWithToken(f withTokenFunc) (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 newWafRetryer(conn *waf.WAF, region string) *WafRetryer { + return &WafRetryer{Connection: conn, Region: region} +}