From 05e027297dc15bdabde64e825cf87f3efaf47ee0 Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Tue, 12 Jul 2022 21:12:00 +0200 Subject: [PATCH 01/22] implement cookie match_pattern --- internal/service/wafv2/flex.go | 62 +++++++++++++++++++++++++++++++ internal/service/wafv2/schemas.go | 47 ++++++++++++++++++++++- 2 files changed, 107 insertions(+), 2 deletions(-) diff --git a/internal/service/wafv2/flex.go b/internal/service/wafv2/flex.go index 95b3ebf54b0..f554eb6b01a 100644 --- a/internal/service/wafv2/flex.go +++ b/internal/service/wafv2/flex.go @@ -395,6 +395,10 @@ func expandFieldToMatch(l []interface{}) *wafv2.FieldToMatch { f.Body = &wafv2.Body{} } + if v, ok := m["cookies"]; ok && len(v.([]interface{})) > 0 { + f.Cookies = expandCookies(m["cookies"].([]interface{})) + } + if v, ok := m["method"]; ok && len(v.([]interface{})) > 0 { f.Method = &wafv2.Method{} } @@ -445,6 +449,48 @@ func expandIPSetForwardedIPConfig(l []interface{}) *wafv2.IPSetForwardedIPConfig } } +func expandCookies(l []interface{}) *wafv2.Cookies { + if len(l) == 0 || l[0] == nil { + return nil + } + + m := l[0].(map[string]interface{}) + + cookies := &wafv2.Cookies{ + MatchScope: aws.String(m["match_scope"].(string)), + OversizeHandling: aws.String(m["oversize_handling"].(string)), + } + + if v, ok := m["match_pattern"]; ok && len(v.([]interface{})) > 0 { + cookies.MatchPattern = expandCookieMatchPattern(v.([]interface{})) + } + + return cookies +} + +func expandCookieMatchPattern(l []interface{}) *wafv2.CookieMatchPattern { + if len(l) == 0 || l[0] == nil { + return nil + } + + m := l[0].(map[string]interface{}) + CookieMatchPattern := &wafv2.CookieMatchPattern{} + + if v, ok := m["included_cookies"]; ok && len(v.([]interface{})) > 0 { + CookieMatchPattern.IncludedCookies = flex.ExpandStringList(v.([]interface{})) + } + + if v, ok := m["excluded_cookies"]; ok && len(v.([]interface{})) > 0 { + CookieMatchPattern.ExcludedCookies = flex.ExpandStringList(v.([]interface{})) + } + + if v, ok := m["all"]; ok && v == true { + CookieMatchPattern.All = &wafv2.All{} + } + + return CookieMatchPattern +} + func expandSingleHeader(l []interface{}) *wafv2.SingleHeader { if len(l) == 0 || l[0] == nil { return nil @@ -928,6 +974,10 @@ func flattenFieldToMatch(f *wafv2.FieldToMatch) interface{} { m["body"] = make([]map[string]interface{}, 1) } + if f.Body != nil { + m["cookies"] = make([]map[string]interface{}, 1) + } + if f.Method != nil { m["method"] = make([]map[string]interface{}, 1) } @@ -978,6 +1028,18 @@ func flattenIPSetForwardedIPConfig(i *wafv2.IPSetForwardedIPConfig) interface{} return []interface{}{m} } +//func flattenCookies(s *wafv2.Cookies) interface{} { +// if s == nil { +// return []interface{}{} +// } +// +// m := map[string]interface{}{ +// "name": aws.StringValue(s.Name), +// } +// +// return []interface{}{m} +//} + func flattenSingleHeader(s *wafv2.SingleHeader) interface{} { if s == nil { return []interface{}{} diff --git a/internal/service/wafv2/schemas.go b/internal/service/wafv2/schemas.go index 72ea6d290df..8968bad8008 100644 --- a/internal/service/wafv2/schemas.go +++ b/internal/service/wafv2/schemas.go @@ -334,8 +334,51 @@ func fieldToMatchBaseSchema() *schema.Resource { Schema: map[string]*schema.Schema{ "all_query_arguments": emptySchema(), "body": emptySchema(), - "method": emptySchema(), - "query_string": emptySchema(), + "cookies": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "match_scope": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(wafv2.MapMatchScope_Values(), false), + }, + "oversize_handling": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(wafv2.OversizeHandling_Values(), false), + }, + "match_pattern": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "all": { + Type: schema.TypeBool, + Default: false, + Optional: true, + }, + "included_cookies": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "excluded_cookies": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + }, + }, + }, + "method": emptySchema(), + "query_string": emptySchema(), "single_header": { Type: schema.TypeList, Optional: true, From ea9af55c0bf42d81d0c2e436c05c9c19ad25fca9 Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Sat, 16 Jul 2022 21:05:51 +0200 Subject: [PATCH 02/22] add 'cookies' to docs wafv2_rule_group --- website/docs/r/wafv2_rule_group.html.markdown | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/website/docs/r/wafv2_rule_group.html.markdown b/website/docs/r/wafv2_rule_group.html.markdown index 3c72ba019f9..4e59c1e10be 100644 --- a/website/docs/r/wafv2_rule_group.html.markdown +++ b/website/docs/r/wafv2_rule_group.html.markdown @@ -492,11 +492,12 @@ The part of a web request that you want AWS WAF to inspect. Include the single ` The `field_to_match` block supports the following arguments: -~> **NOTE:** Only one of `all_query_arguments`, `body`, `method`, `query_string`, `single_header`, `single_query_argument`, or `uri_path` can be specified. +~> **NOTE:** Only one of `all_query_arguments`, `body`, `cookies`, `method`, `query_string`, `single_header`, `single_query_argument`, or `uri_path` can be specified. An empty configuration block `{}` should be used when specifying `all_query_arguments`, `body`, `method`, or `query_string` attributes. * `all_query_arguments` - (Optional) Inspect all query arguments. * `body` - (Optional) Inspect the request body, which immediately follows the request headers. +* `cookies` - (Optional) Inspect the request cookies. * `method` - (Optional) Inspect the HTTP method. The method indicates the type of operation that the request is asking the origin to perform. * `query_string` - (Optional) Inspect the query string. This is the part of a URL that appears after a `?` character, if any. * `single_header` - (Optional) Inspect a single header. See [Single Header](#single-header) below for details. @@ -540,6 +541,17 @@ The `single_query_argument` block supports the following arguments: * `name` - (Optional) The name of the query header to inspect. This setting must be provided as lower case characters. +### Cookies + +Inspect the cookies in the web request. You can specify the parts of the cookies to inspect and you can narrow the set of cookies to inspect by including or excluding specific keys. +This is used to indicate the web request component to inspect, in the [FieldToMatch](https://docs.aws.amazon.com/waf/latest/APIReference/API_FieldToMatch.html) specification. + +The `cookies` block supports the following arguments: + +* `match_pattern` - (Required) The filter to use to identify the subset of cookies to inspect in a web request. You must specify exactly one setting: either `all`, `included_cookies` or `excluded_cookies`. More details: [CookieMatchPattern](https://docs.aws.amazon.com/waf/latest/APIReference/API_CookieMatchPattern.html) +* `match_scope` - (Required) The parts of the cookies to inspect with the rule inspection criteria. If you specify All, AWS WAF inspects both keys and values. Valid values: `ALL`, `KEY`, `VALUE` +* `oversize_handling` - (Required) What AWS WAF should do if the cookies of the request are larger than AWS WAF can inspect. AWS WAF does not support inspecting the entire contents of request cookies when they exceed 8 KB (8192 bytes) or 200 total cookies. The underlying host service forwards a maximum of 200 cookies and at most 8 KB of cookie contents to AWS WAF. Valid values: `CONTINUE`, `MATCH`, `NO_MATCH` + ### Text Transformation The `text_transformation` block supports the following arguments: From cc8fd9ac88f4225f1ce0d57b19b856dd49eaef26 Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Sat, 16 Jul 2022 21:18:28 +0200 Subject: [PATCH 03/22] implement flatten func for wafv2 --- internal/service/wafv2/flex.go | 40 ++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/internal/service/wafv2/flex.go b/internal/service/wafv2/flex.go index f554eb6b01a..2c4d4911323 100644 --- a/internal/service/wafv2/flex.go +++ b/internal/service/wafv2/flex.go @@ -975,7 +975,7 @@ func flattenFieldToMatch(f *wafv2.FieldToMatch) interface{} { } if f.Body != nil { - m["cookies"] = make([]map[string]interface{}, 1) + m["cookies"] = flattenCookies(f.Cookies) } if f.Method != nil { @@ -1028,17 +1028,33 @@ func flattenIPSetForwardedIPConfig(i *wafv2.IPSetForwardedIPConfig) interface{} return []interface{}{m} } -//func flattenCookies(s *wafv2.Cookies) interface{} { -// if s == nil { -// return []interface{}{} -// } -// -// m := map[string]interface{}{ -// "name": aws.StringValue(s.Name), -// } -// -// return []interface{}{m} -//} +func flattenCookies(c *wafv2.Cookies) interface{} { + if c == nil { + return []interface{}{} + } + + m := map[string]interface{}{ + "match_scope": aws.StringValue(c.MatchScope), + "oversize_handling": aws.StringValue(c.OversizeHandling), + "match_pattern": flattenCookiesMatchPattern(c.MatchPattern), + } + + return []interface{}{m} +} + +func flattenCookiesMatchPattern(c *wafv2.CookieMatchPattern) interface{} { + if c == nil { + return []interface{}{} + } + + m := map[string]interface{}{ + "all": c.All, + "included_cookies": aws.StringValueSlice(c.IncludedCookies), + "excluded_cookies": aws.StringValueSlice(c.ExcludedCookies), + } + + return []interface{}{m} +} func flattenSingleHeader(s *wafv2.SingleHeader) interface{} { if s == nil { From 20f0ab99676b6b48f95b40b82b58a14034f037f3 Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Sat, 16 Jul 2022 21:20:04 +0200 Subject: [PATCH 04/22] add changelog --- .changelog/25845.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/25845.txt diff --git a/.changelog/25845.txt b/.changelog/25845.txt new file mode 100644 index 00000000000..3eecc57df50 --- /dev/null +++ b/.changelog/25845.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_wafv2_rule_group: Add `cookies` attribute +``` From 7b1692724753d9cc162c1120745445f6135ef5d5 Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Sat, 16 Jul 2022 22:03:08 +0200 Subject: [PATCH 05/22] implement test for aws_wafv2_rule_group --- internal/service/wafv2/rule_group_test.go | 87 +++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/internal/service/wafv2/rule_group_test.go b/internal/service/wafv2/rule_group_test.go index b4d1b7974cc..62082862d4f 100644 --- a/internal/service/wafv2/rule_group_test.go +++ b/internal/service/wafv2/rule_group_test.go @@ -379,6 +379,7 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { "statement.0.byte_match_statement.0.field_to_match.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.body.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.method.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "0", @@ -399,6 +400,7 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { "statement.0.byte_match_statement.0.field_to_match.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.body.#": "1", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.method.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "0", @@ -407,6 +409,33 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { }), ), }, + { + Config: testAccRuleGroupConfig_byteMatchStatementFieldToMatchCookies(ruleGroupName), + Check: resource.ComposeTestCheckFunc( + testAccCheckRuleGroupExists(resourceName, &v), + acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/rulegroup/.+$`)), + resource.TestCheckResourceAttr(resourceName, "rule.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule.*", map[string]string{ + "statement.#": "1", + "statement.0.byte_match_statement.#": "1", + "statement.0.byte_match_statement.0.field_to_match.#": "1", + "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.body.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "1", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.match_scope": "ALL", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.oversize_handling": "NO_MATCH", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.match_pattern.#": "1", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.match_pattern.0.included_cookies.#": "1", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.match_pattern.0.included_cookies.0": "test", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.match_pattern.0.included_cookies.1": "cookie_test", + "statement.0.byte_match_statement.0.field_to_match.0.method.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.single_query_argument.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.uri_path.#": "0", + }), + ), + }, { Config: testAccRuleGroupConfig_byteMatchStatementFieldToMatchMethod(ruleGroupName), Check: resource.ComposeTestCheckFunc( @@ -419,6 +448,7 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { "statement.0.byte_match_statement.0.field_to_match.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.body.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.method.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "0", @@ -439,6 +469,7 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { "statement.0.byte_match_statement.0.field_to_match.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.body.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.method.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "0", @@ -459,6 +490,7 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { "statement.0.byte_match_statement.0.field_to_match.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.body.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.method.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "1", @@ -480,6 +512,7 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { "statement.0.byte_match_statement.0.field_to_match.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.body.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.method.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "0", @@ -501,6 +534,7 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { "statement.0.byte_match_statement.0.field_to_match.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.body.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.method.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "0", @@ -2528,6 +2562,59 @@ resource "aws_wafv2_rule_group" "test" { `, name) } +func testAccRuleGroupConfig_byteMatchStatementFieldToMatchCookies(name string) string { + return fmt.Sprintf(` +resource "aws_wafv2_rule_group" "test" { + capacity = 15 + name = "%s" + scope = "REGIONAL" + + rule { + name = "rule-1" + priority = 1 + + action { + allow {} + } + + statement { + byte_match_statement { + positional_constraint = "CONTAINS" + search_string = "word" + + field_to_match { + cookies { + match_pattern { + included_cookies = ["test", "cookie_test"] + } + match_scope = "ALL" + oversize_handling = "NO_MATCH" + } + } + + text_transformation { + priority = 1 + type = "NONE" + } + } + } + + visibility_config { + cloudwatch_metrics_enabled = false + metric_name = "friendly-rule-metric-name" + sampled_requests_enabled = false + } + } + + visibility_config { + cloudwatch_metrics_enabled = false + metric_name = "friendly-metric-name" + sampled_requests_enabled = false + } +} +`, name) +} + func testAccRuleGroupConfig_byteMatchStatementFieldToMatchSingleHeader(name string) string { return fmt.Sprintf(` resource "aws_wafv2_rule_group" "test" { From 820ac28bac5bf7969a3e6a2bc6b17dce0311a4f6 Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Tue, 12 Jul 2022 21:12:00 +0200 Subject: [PATCH 06/22] implement cookie match_pattern --- internal/service/wafv2/flex.go | 62 +++++++++++++++++++++++++++++++ internal/service/wafv2/schemas.go | 47 ++++++++++++++++++++++- 2 files changed, 107 insertions(+), 2 deletions(-) diff --git a/internal/service/wafv2/flex.go b/internal/service/wafv2/flex.go index 95b3ebf54b0..f554eb6b01a 100644 --- a/internal/service/wafv2/flex.go +++ b/internal/service/wafv2/flex.go @@ -395,6 +395,10 @@ func expandFieldToMatch(l []interface{}) *wafv2.FieldToMatch { f.Body = &wafv2.Body{} } + if v, ok := m["cookies"]; ok && len(v.([]interface{})) > 0 { + f.Cookies = expandCookies(m["cookies"].([]interface{})) + } + if v, ok := m["method"]; ok && len(v.([]interface{})) > 0 { f.Method = &wafv2.Method{} } @@ -445,6 +449,48 @@ func expandIPSetForwardedIPConfig(l []interface{}) *wafv2.IPSetForwardedIPConfig } } +func expandCookies(l []interface{}) *wafv2.Cookies { + if len(l) == 0 || l[0] == nil { + return nil + } + + m := l[0].(map[string]interface{}) + + cookies := &wafv2.Cookies{ + MatchScope: aws.String(m["match_scope"].(string)), + OversizeHandling: aws.String(m["oversize_handling"].(string)), + } + + if v, ok := m["match_pattern"]; ok && len(v.([]interface{})) > 0 { + cookies.MatchPattern = expandCookieMatchPattern(v.([]interface{})) + } + + return cookies +} + +func expandCookieMatchPattern(l []interface{}) *wafv2.CookieMatchPattern { + if len(l) == 0 || l[0] == nil { + return nil + } + + m := l[0].(map[string]interface{}) + CookieMatchPattern := &wafv2.CookieMatchPattern{} + + if v, ok := m["included_cookies"]; ok && len(v.([]interface{})) > 0 { + CookieMatchPattern.IncludedCookies = flex.ExpandStringList(v.([]interface{})) + } + + if v, ok := m["excluded_cookies"]; ok && len(v.([]interface{})) > 0 { + CookieMatchPattern.ExcludedCookies = flex.ExpandStringList(v.([]interface{})) + } + + if v, ok := m["all"]; ok && v == true { + CookieMatchPattern.All = &wafv2.All{} + } + + return CookieMatchPattern +} + func expandSingleHeader(l []interface{}) *wafv2.SingleHeader { if len(l) == 0 || l[0] == nil { return nil @@ -928,6 +974,10 @@ func flattenFieldToMatch(f *wafv2.FieldToMatch) interface{} { m["body"] = make([]map[string]interface{}, 1) } + if f.Body != nil { + m["cookies"] = make([]map[string]interface{}, 1) + } + if f.Method != nil { m["method"] = make([]map[string]interface{}, 1) } @@ -978,6 +1028,18 @@ func flattenIPSetForwardedIPConfig(i *wafv2.IPSetForwardedIPConfig) interface{} return []interface{}{m} } +//func flattenCookies(s *wafv2.Cookies) interface{} { +// if s == nil { +// return []interface{}{} +// } +// +// m := map[string]interface{}{ +// "name": aws.StringValue(s.Name), +// } +// +// return []interface{}{m} +//} + func flattenSingleHeader(s *wafv2.SingleHeader) interface{} { if s == nil { return []interface{}{} diff --git a/internal/service/wafv2/schemas.go b/internal/service/wafv2/schemas.go index 72ea6d290df..8968bad8008 100644 --- a/internal/service/wafv2/schemas.go +++ b/internal/service/wafv2/schemas.go @@ -334,8 +334,51 @@ func fieldToMatchBaseSchema() *schema.Resource { Schema: map[string]*schema.Schema{ "all_query_arguments": emptySchema(), "body": emptySchema(), - "method": emptySchema(), - "query_string": emptySchema(), + "cookies": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "match_scope": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(wafv2.MapMatchScope_Values(), false), + }, + "oversize_handling": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(wafv2.OversizeHandling_Values(), false), + }, + "match_pattern": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "all": { + Type: schema.TypeBool, + Default: false, + Optional: true, + }, + "included_cookies": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "excluded_cookies": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + }, + }, + }, + "method": emptySchema(), + "query_string": emptySchema(), "single_header": { Type: schema.TypeList, Optional: true, From d02559e99f657d018d3a992a3bbedb7c6a3f18d6 Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Sat, 16 Jul 2022 21:05:51 +0200 Subject: [PATCH 07/22] add 'cookies' to docs wafv2_rule_group --- website/docs/r/wafv2_rule_group.html.markdown | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/website/docs/r/wafv2_rule_group.html.markdown b/website/docs/r/wafv2_rule_group.html.markdown index 23b1c3d203f..69db541d5a4 100644 --- a/website/docs/r/wafv2_rule_group.html.markdown +++ b/website/docs/r/wafv2_rule_group.html.markdown @@ -492,11 +492,12 @@ The part of a web request that you want AWS WAF to inspect. Include the single ` The `field_to_match` block supports the following arguments: -~> **NOTE:** Only one of `all_query_arguments`, `body`, `method`, `query_string`, `single_header`, `single_query_argument`, or `uri_path` can be specified. +~> **NOTE:** Only one of `all_query_arguments`, `body`, `cookies`, `method`, `query_string`, `single_header`, `single_query_argument`, or `uri_path` can be specified. An empty configuration block `{}` should be used when specifying `all_query_arguments`, `body`, `method`, or `query_string` attributes. * `all_query_arguments` - (Optional) Inspect all query arguments. * `body` - (Optional) Inspect the request body, which immediately follows the request headers. +* `cookies` - (Optional) Inspect the request cookies. * `method` - (Optional) Inspect the HTTP method. The method indicates the type of operation that the request is asking the origin to perform. * `query_string` - (Optional) Inspect the query string. This is the part of a URL that appears after a `?` character, if any. * `single_header` - (Optional) Inspect a single header. See [Single Header](#single-header) below for details. @@ -540,6 +541,17 @@ The `single_query_argument` block supports the following arguments: * `name` - (Optional) The name of the query header to inspect. This setting must be provided as lower case characters. +### Cookies + +Inspect the cookies in the web request. You can specify the parts of the cookies to inspect and you can narrow the set of cookies to inspect by including or excluding specific keys. +This is used to indicate the web request component to inspect, in the [FieldToMatch](https://docs.aws.amazon.com/waf/latest/APIReference/API_FieldToMatch.html) specification. + +The `cookies` block supports the following arguments: + +* `match_pattern` - (Required) The filter to use to identify the subset of cookies to inspect in a web request. You must specify exactly one setting: either `all`, `included_cookies` or `excluded_cookies`. More details: [CookieMatchPattern](https://docs.aws.amazon.com/waf/latest/APIReference/API_CookieMatchPattern.html) +* `match_scope` - (Required) The parts of the cookies to inspect with the rule inspection criteria. If you specify All, AWS WAF inspects both keys and values. Valid values: `ALL`, `KEY`, `VALUE` +* `oversize_handling` - (Required) What AWS WAF should do if the cookies of the request are larger than AWS WAF can inspect. AWS WAF does not support inspecting the entire contents of request cookies when they exceed 8 KB (8192 bytes) or 200 total cookies. The underlying host service forwards a maximum of 200 cookies and at most 8 KB of cookie contents to AWS WAF. Valid values: `CONTINUE`, `MATCH`, `NO_MATCH` + ### Text Transformation The `text_transformation` block supports the following arguments: From fb6d6d7446142d88b2bddb286697c752e6406fe0 Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Sat, 16 Jul 2022 21:18:28 +0200 Subject: [PATCH 08/22] implement flatten func for wafv2 --- internal/service/wafv2/flex.go | 40 ++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/internal/service/wafv2/flex.go b/internal/service/wafv2/flex.go index f554eb6b01a..2c4d4911323 100644 --- a/internal/service/wafv2/flex.go +++ b/internal/service/wafv2/flex.go @@ -975,7 +975,7 @@ func flattenFieldToMatch(f *wafv2.FieldToMatch) interface{} { } if f.Body != nil { - m["cookies"] = make([]map[string]interface{}, 1) + m["cookies"] = flattenCookies(f.Cookies) } if f.Method != nil { @@ -1028,17 +1028,33 @@ func flattenIPSetForwardedIPConfig(i *wafv2.IPSetForwardedIPConfig) interface{} return []interface{}{m} } -//func flattenCookies(s *wafv2.Cookies) interface{} { -// if s == nil { -// return []interface{}{} -// } -// -// m := map[string]interface{}{ -// "name": aws.StringValue(s.Name), -// } -// -// return []interface{}{m} -//} +func flattenCookies(c *wafv2.Cookies) interface{} { + if c == nil { + return []interface{}{} + } + + m := map[string]interface{}{ + "match_scope": aws.StringValue(c.MatchScope), + "oversize_handling": aws.StringValue(c.OversizeHandling), + "match_pattern": flattenCookiesMatchPattern(c.MatchPattern), + } + + return []interface{}{m} +} + +func flattenCookiesMatchPattern(c *wafv2.CookieMatchPattern) interface{} { + if c == nil { + return []interface{}{} + } + + m := map[string]interface{}{ + "all": c.All, + "included_cookies": aws.StringValueSlice(c.IncludedCookies), + "excluded_cookies": aws.StringValueSlice(c.ExcludedCookies), + } + + return []interface{}{m} +} func flattenSingleHeader(s *wafv2.SingleHeader) interface{} { if s == nil { From dd33e58c3291b7cd135bfa81261c62931082769e Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Sat, 16 Jul 2022 21:20:04 +0200 Subject: [PATCH 09/22] add changelog --- .changelog/25845.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/25845.txt diff --git a/.changelog/25845.txt b/.changelog/25845.txt new file mode 100644 index 00000000000..3eecc57df50 --- /dev/null +++ b/.changelog/25845.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_wafv2_rule_group: Add `cookies` attribute +``` From f1773cb186039605f35d81d101a6771e086ef073 Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Sat, 16 Jul 2022 22:03:08 +0200 Subject: [PATCH 10/22] implement test for aws_wafv2_rule_group --- internal/service/wafv2/rule_group_test.go | 87 +++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/internal/service/wafv2/rule_group_test.go b/internal/service/wafv2/rule_group_test.go index ac18f1ce855..8065a4a36b7 100644 --- a/internal/service/wafv2/rule_group_test.go +++ b/internal/service/wafv2/rule_group_test.go @@ -379,6 +379,7 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { "statement.0.byte_match_statement.0.field_to_match.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.body.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.method.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "0", @@ -399,6 +400,7 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { "statement.0.byte_match_statement.0.field_to_match.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.body.#": "1", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.method.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "0", @@ -407,6 +409,33 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { }), ), }, + { + Config: testAccRuleGroupConfig_byteMatchStatementFieldToMatchCookies(ruleGroupName), + Check: resource.ComposeTestCheckFunc( + testAccCheckRuleGroupExists(resourceName, &v), + acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/rulegroup/.+$`)), + resource.TestCheckResourceAttr(resourceName, "rule.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule.*", map[string]string{ + "statement.#": "1", + "statement.0.byte_match_statement.#": "1", + "statement.0.byte_match_statement.0.field_to_match.#": "1", + "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.body.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "1", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.match_scope": "ALL", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.oversize_handling": "NO_MATCH", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.match_pattern.#": "1", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.match_pattern.0.included_cookies.#": "1", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.match_pattern.0.included_cookies.0": "test", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.match_pattern.0.included_cookies.1": "cookie_test", + "statement.0.byte_match_statement.0.field_to_match.0.method.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.single_query_argument.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.uri_path.#": "0", + }), + ), + }, { Config: testAccRuleGroupConfig_byteMatchStatementFieldToMatchMethod(ruleGroupName), Check: resource.ComposeTestCheckFunc( @@ -419,6 +448,7 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { "statement.0.byte_match_statement.0.field_to_match.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.body.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.method.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "0", @@ -439,6 +469,7 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { "statement.0.byte_match_statement.0.field_to_match.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.body.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.method.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "0", @@ -459,6 +490,7 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { "statement.0.byte_match_statement.0.field_to_match.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.body.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.method.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "1", @@ -480,6 +512,7 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { "statement.0.byte_match_statement.0.field_to_match.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.body.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.method.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "0", @@ -501,6 +534,7 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { "statement.0.byte_match_statement.0.field_to_match.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.all_query_arguments.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.body.#": "0", + "statement.0.byte_match_statement.0.field_to_match.0.cookies.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.method.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.query_string.#": "0", "statement.0.byte_match_statement.0.field_to_match.0.single_header.#": "0", @@ -2528,6 +2562,59 @@ resource "aws_wafv2_rule_group" "test" { `, name) } +func testAccRuleGroupConfig_byteMatchStatementFieldToMatchCookies(name string) string { + return fmt.Sprintf(` +resource "aws_wafv2_rule_group" "test" { + capacity = 15 + name = "%s" + scope = "REGIONAL" + + rule { + name = "rule-1" + priority = 1 + + action { + allow {} + } + + statement { + byte_match_statement { + positional_constraint = "CONTAINS" + search_string = "word" + + field_to_match { + cookies { + match_pattern { + included_cookies = ["test", "cookie_test"] + } + match_scope = "ALL" + oversize_handling = "NO_MATCH" + } + } + + text_transformation { + priority = 1 + type = "NONE" + } + } + } + + visibility_config { + cloudwatch_metrics_enabled = false + metric_name = "friendly-rule-metric-name" + sampled_requests_enabled = false + } + } + + visibility_config { + cloudwatch_metrics_enabled = false + metric_name = "friendly-metric-name" + sampled_requests_enabled = false + } +} +`, name) +} + func testAccRuleGroupConfig_byteMatchStatementFieldToMatchSingleHeader(name string) string { return fmt.Sprintf(` resource "aws_wafv2_rule_group" "test" { From 083d8d4384818962d439e1c8064f22f2032e18c0 Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Tue, 23 Aug 2022 19:47:00 +0200 Subject: [PATCH 11/22] replace body with cookie --- internal/service/wafv2/flex.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/wafv2/flex.go b/internal/service/wafv2/flex.go index 2c4d4911323..2084c607188 100644 --- a/internal/service/wafv2/flex.go +++ b/internal/service/wafv2/flex.go @@ -974,7 +974,7 @@ func flattenFieldToMatch(f *wafv2.FieldToMatch) interface{} { m["body"] = make([]map[string]interface{}, 1) } - if f.Body != nil { + if f.Cookies != nil { m["cookies"] = flattenCookies(f.Cookies) } From 171bc00fe0f3a55986875f1e327ae50677d6403f Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Tue, 23 Aug 2022 19:47:21 +0200 Subject: [PATCH 12/22] remove entry from test --- internal/service/wafv2/rule_group_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/service/wafv2/rule_group_test.go b/internal/service/wafv2/rule_group_test.go index 8065a4a36b7..ff847acc7b0 100644 --- a/internal/service/wafv2/rule_group_test.go +++ b/internal/service/wafv2/rule_group_test.go @@ -425,7 +425,6 @@ func TestAccWAFV2RuleGroup_ByteMatchStatement_fieldToMatch(t *testing.T) { "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.match_scope": "ALL", "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.oversize_handling": "NO_MATCH", "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.match_pattern.#": "1", - "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.match_pattern.0.included_cookies.#": "1", "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.match_pattern.0.included_cookies.0": "test", "statement.0.byte_match_statement.0.field_to_match.0.cookies.0.match_pattern.0.included_cookies.1": "cookie_test", "statement.0.byte_match_statement.0.field_to_match.0.method.#": "0", From 48851e3521955eff8021ad8bde3f950166bb6a12 Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Tue, 23 Aug 2022 19:47:54 +0200 Subject: [PATCH 13/22] add MaxItems to cookies --- internal/service/wafv2/schemas.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/service/wafv2/schemas.go b/internal/service/wafv2/schemas.go index 8968bad8008..c4c56c346ce 100644 --- a/internal/service/wafv2/schemas.go +++ b/internal/service/wafv2/schemas.go @@ -337,6 +337,7 @@ func fieldToMatchBaseSchema() *schema.Resource { "cookies": { Type: schema.TypeList, Optional: true, + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "match_scope": { @@ -362,13 +363,11 @@ func fieldToMatchBaseSchema() *schema.Resource { "included_cookies": { Type: schema.TypeList, Optional: true, - Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "excluded_cookies": { Type: schema.TypeList, Optional: true, - Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, }, From 42f0e6f3af743e91d976ebc904e540025688ef6a Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Tue, 23 Aug 2022 20:11:22 +0200 Subject: [PATCH 14/22] update indent for test file --- internal/service/wafv2/rule_group_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/service/wafv2/rule_group_test.go b/internal/service/wafv2/rule_group_test.go index ff847acc7b0..01b737be143 100644 --- a/internal/service/wafv2/rule_group_test.go +++ b/internal/service/wafv2/rule_group_test.go @@ -2582,13 +2582,13 @@ resource "aws_wafv2_rule_group" "test" { search_string = "word" field_to_match { - cookies { - match_pattern { - included_cookies = ["test", "cookie_test"] - } - match_scope = "ALL" - oversize_handling = "NO_MATCH" - } + cookies { + match_pattern { + included_cookies = ["test", "cookie_test"] + } + match_scope = "ALL" + oversize_handling = "NO_MATCH" + } } text_transformation { From ff3c745b2c5904f0288a22bdd2e0dbfdcbb36196 Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Tue, 23 Aug 2022 20:13:24 +0200 Subject: [PATCH 15/22] update indent for test file --- internal/service/wafv2/rule_group_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/wafv2/rule_group_test.go b/internal/service/wafv2/rule_group_test.go index 01b737be143..5eec8c39961 100644 --- a/internal/service/wafv2/rule_group_test.go +++ b/internal/service/wafv2/rule_group_test.go @@ -2585,7 +2585,7 @@ resource "aws_wafv2_rule_group" "test" { cookies { match_pattern { included_cookies = ["test", "cookie_test"] - } + } match_scope = "ALL" oversize_handling = "NO_MATCH" } From 0edc5e6c87768ae3527f1c37d7fc211aa9342cec Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Tue, 23 Aug 2022 20:53:30 +0200 Subject: [PATCH 16/22] update indent for test file --- internal/service/wafv2/rule_group_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/service/wafv2/rule_group_test.go b/internal/service/wafv2/rule_group_test.go index 5eec8c39961..135d441bd31 100644 --- a/internal/service/wafv2/rule_group_test.go +++ b/internal/service/wafv2/rule_group_test.go @@ -2582,13 +2582,13 @@ resource "aws_wafv2_rule_group" "test" { search_string = "word" field_to_match { - cookies { - match_pattern { - included_cookies = ["test", "cookie_test"] - } - match_scope = "ALL" - oversize_handling = "NO_MATCH" - } + cookies { + match_pattern { + included_cookies = ["test", "cookie_test"] + } + match_scope = "ALL" + oversize_handling = "NO_MATCH" + } } text_transformation { From 6a41c071c1252e6bbce4c66e56633604170a2037 Mon Sep 17 00:00:00 2001 From: tiborhercz Date: Thu, 25 Aug 2022 16:12:14 +0200 Subject: [PATCH 17/22] update all to struct instead of bool --- internal/service/wafv2/flex.go | 2 +- internal/service/wafv2/schemas.go | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/internal/service/wafv2/flex.go b/internal/service/wafv2/flex.go index 2084c607188..8396c97847a 100644 --- a/internal/service/wafv2/flex.go +++ b/internal/service/wafv2/flex.go @@ -484,7 +484,7 @@ func expandCookieMatchPattern(l []interface{}) *wafv2.CookieMatchPattern { CookieMatchPattern.ExcludedCookies = flex.ExpandStringList(v.([]interface{})) } - if v, ok := m["all"]; ok && v == true { + if v, ok := m["all"].([]interface{}); ok && len(v) > 0 { CookieMatchPattern.All = &wafv2.All{} } diff --git a/internal/service/wafv2/schemas.go b/internal/service/wafv2/schemas.go index c4c56c346ce..88c21fc7cac 100644 --- a/internal/service/wafv2/schemas.go +++ b/internal/service/wafv2/schemas.go @@ -355,11 +355,7 @@ func fieldToMatchBaseSchema() *schema.Resource { Required: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "all": { - Type: schema.TypeBool, - Default: false, - Optional: true, - }, + "all": emptySchema(), "included_cookies": { Type: schema.TypeList, Optional: true, From d00fd3943f0e9cf7d54a8a70a16fb9531ac02425 Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen <58337159+bschaatsbergen@users.noreply.github.com> Date: Thu, 25 Aug 2022 22:09:06 +0200 Subject: [PATCH 18/22] Update .changelog/25845.txt Co-authored-by: Kit Ewbank --- .changelog/25845.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/25845.txt b/.changelog/25845.txt index 3eecc57df50..d598fa75cdc 100644 --- a/.changelog/25845.txt +++ b/.changelog/25845.txt @@ -1,3 +1,3 @@ ```release-note:enhancement -resource/aws_wafv2_rule_group: Add `cookies` attribute +resource/aws_wafv2_rule_group: Add `cookies` attribute to the `field_to_match` block ``` From 19d575b420a4bb9bfa49e00e7a0560311e3f82bf Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Thu, 25 Aug 2022 22:10:23 +0200 Subject: [PATCH 19/22] Add `aws_wafv2_web_acl` entry --- .changelog/25845.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.changelog/25845.txt b/.changelog/25845.txt index d598fa75cdc..10f7605f71b 100644 --- a/.changelog/25845.txt +++ b/.changelog/25845.txt @@ -1,3 +1,7 @@ ```release-note:enhancement resource/aws_wafv2_rule_group: Add `cookies` attribute to the `field_to_match` block ``` + +```release-note:enhancement +resource/aws_wafv2_web_acl: Add `cookies` attribute to the `field_to_match` block +``` From 1207db97568f57efbcf5d47cedee4a01b0efedfa Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Thu, 25 Aug 2022 22:11:48 +0200 Subject: [PATCH 20/22] Add `cookies` to `field_to_match` note --- website/docs/r/wafv2_web_acl.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/wafv2_web_acl.html.markdown b/website/docs/r/wafv2_web_acl.html.markdown index 805dae3d8ba..c3cb4cf7206 100644 --- a/website/docs/r/wafv2_web_acl.html.markdown +++ b/website/docs/r/wafv2_web_acl.html.markdown @@ -545,7 +545,7 @@ The part of a web request that you want AWS WAF to inspect. Include the single ` The `field_to_match` block supports the following arguments: -~> **NOTE:** Only one of `all_query_arguments`, `body`, `method`, `query_string`, `single_header`, `single_query_argument`, or `uri_path` can be specified. +~> **NOTE:** Only one of `all_query_arguments`, `body`, `cookies`, `method`, `query_string`, `single_header`, `single_query_argument`, or `uri_path` can be specified. An empty configuration block `{}` should be used when specifying `all_query_arguments`, `body`, `method`, or `query_string` attributes. * `all_query_arguments` - (Optional) Inspect all query arguments. From ef1712d3b28164c317f2765ed81f3f27fdbb950a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 25 Aug 2022 16:57:26 -0400 Subject: [PATCH 21/22] r/aws_wafv2_web_acl: Additional documentation for 'cookies'. --- website/docs/r/wafv2_web_acl.html.markdown | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/website/docs/r/wafv2_web_acl.html.markdown b/website/docs/r/wafv2_web_acl.html.markdown index c3cb4cf7206..860be6a9889 100644 --- a/website/docs/r/wafv2_web_acl.html.markdown +++ b/website/docs/r/wafv2_web_acl.html.markdown @@ -550,6 +550,7 @@ An empty configuration block `{}` should be used when specifying `all_query_argu * `all_query_arguments` - (Optional) Inspect all query arguments. * `body` - (Optional) Inspect the request body, which immediately follows the request headers. +* `cookies` - (Optional) Inspect the request cookies. * `method` - (Optional) Inspect the HTTP method. The method indicates the type of operation that the request is asking the origin to perform. * `query_string` - (Optional) Inspect the query string. This is the part of a URL that appears after a `?` character, if any. * `single_header` - (Optional) Inspect a single header. See [Single Header](#single-header) below for details. @@ -593,6 +594,17 @@ The `single_query_argument` block supports the following arguments: * `name` - (Optional) Name of the query header to inspect. This setting must be provided as lower case characters. +### Cookies + +Inspect the cookies in the web request. You can specify the parts of the cookies to inspect and you can narrow the set of cookies to inspect by including or excluding specific keys. +This is used to indicate the web request component to inspect, in the [FieldToMatch](https://docs.aws.amazon.com/waf/latest/APIReference/API_FieldToMatch.html) specification. + +The `cookies` block supports the following arguments: + +* `match_pattern` - (Required) The filter to use to identify the subset of cookies to inspect in a web request. You must specify exactly one setting: either `all`, `included_cookies` or `excluded_cookies`. More details: [CookieMatchPattern](https://docs.aws.amazon.com/waf/latest/APIReference/API_CookieMatchPattern.html) +* `match_scope` - (Required) The parts of the cookies to inspect with the rule inspection criteria. If you specify All, AWS WAF inspects both keys and values. Valid values: `ALL`, `KEY`, `VALUE` +* `oversize_handling` - (Required) What AWS WAF should do if the cookies of the request are larger than AWS WAF can inspect. AWS WAF does not support inspecting the entire contents of request cookies when they exceed 8 KB (8192 bytes) or 200 total cookies. The underlying host service forwards a maximum of 200 cookies and at most 8 KB of cookie contents to AWS WAF. Valid values: `CONTINUE`, `MATCH`, `NO_MATCH` + ### Text Transformation The `text_transformation` block supports the following arguments: From cf49091ccf57c31b9f35ecc419bebac34618f76b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 25 Aug 2022 17:05:30 -0400 Subject: [PATCH 22/22] r/aws_wafv2_web_acl: Update 'TestAccWAFV2WebACL_Update_rule'. Acceptance test output: % make testacc TESTARGS='-run=TestAccWAFV2WebACL_Update_rule' PKG=wafv2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/wafv2/... -v -count 1 -parallel 20 -run=TestAccWAFV2WebACL_Update_rule -timeout 180m === RUN TestAccWAFV2WebACL_Update_rule === PAUSE TestAccWAFV2WebACL_Update_rule === RUN TestAccWAFV2WebACL_Update_ruleProperties === PAUSE TestAccWAFV2WebACL_Update_ruleProperties === CONT TestAccWAFV2WebACL_Update_rule === CONT TestAccWAFV2WebACL_Update_ruleProperties --- PASS: TestAccWAFV2WebACL_Update_rule (41.34s) --- PASS: TestAccWAFV2WebACL_Update_ruleProperties (59.22s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/wafv2 63.068s --- internal/service/wafv2/web_acl_test.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/internal/service/wafv2/web_acl_test.go b/internal/service/wafv2/web_acl_test.go index 262d9156f33..2c91a0f9979 100644 --- a/internal/service/wafv2/web_acl_test.go +++ b/internal/service/wafv2/web_acl_test.go @@ -98,12 +98,19 @@ func TestAccWAFV2WebACL_Update_rule(t *testing.T) { "visibility_config.0.metric_name": fmt.Sprintf("%s-metric-name-1", webACLName), "visibility_config.0.sampled_requests_enabled": "false", "statement.#": "1", - "statement.0.size_constraint_statement.#": "1", - "statement.0.size_constraint_statement.0.comparison_operator": "LT", - "statement.0.size_constraint_statement.0.field_to_match.#": "1", - "statement.0.size_constraint_statement.0.field_to_match.0.query_string.#": "1", - "statement.0.size_constraint_statement.0.size": "50", - "statement.0.size_constraint_statement.0.text_transformation.#": "2", + "statement.0.size_constraint_statement.#": "1", + "statement.0.size_constraint_statement.0.comparison_operator": "LT", + "statement.0.size_constraint_statement.0.field_to_match.#": "1", + "statement.0.size_constraint_statement.0.field_to_match.0.all_query_arguments.#": "0", + "statement.0.size_constraint_statement.0.field_to_match.0.body.#": "0", + "statement.0.size_constraint_statement.0.field_to_match.0.cookies.#": "0", + "statement.0.size_constraint_statement.0.field_to_match.0.method.#": "0", + "statement.0.size_constraint_statement.0.field_to_match.0.query_string.#": "1", + "statement.0.size_constraint_statement.0.field_to_match.0.single_header.#": "0", + "statement.0.size_constraint_statement.0.field_to_match.0.single_query_argument.#": "0", + "statement.0.size_constraint_statement.0.field_to_match.0.uri_path.#": "0", + "statement.0.size_constraint_statement.0.size": "50", + "statement.0.size_constraint_statement.0.text_transformation.#": "2", }), resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule.*.statement.0.size_constraint_statement.0.text_transformation.*", map[string]string{ "priority": "2",