From 86789519b06fc3f1928b22a96e0104517fdc5c3d Mon Sep 17 00:00:00 2001 From: philnichol Date: Thu, 15 Oct 2020 20:58:42 +0100 Subject: [PATCH 1/4] added validation to input_paths --- aws/resource_aws_cloudwatch_event_target.go | 4 +++ ...source_aws_cloudwatch_event_target_test.go | 19 ++++++++++- aws/validators.go | 34 +++++++++++++++++++ .../r/cloudwatch_event_target.html.markdown | 4 +++ 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_cloudwatch_event_target.go b/aws/resource_aws_cloudwatch_event_target.go index be45a0fd083..cd822317dc9 100644 --- a/aws/resource_aws_cloudwatch_event_target.go +++ b/aws/resource_aws_cloudwatch_event_target.go @@ -216,6 +216,10 @@ func resourceAwsCloudWatchEventTarget() *schema.Resource { Type: schema.TypeMap, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, + ValidateFunc: validation.All( + MapLenBetween(0, 10), + MapKeyNotMatch(regexp.MustCompile(`^AWS.*$`), "input_path must not start with \"AWS\""), + ), }, "input_template": { Type: schema.TypeString, diff --git a/aws/resource_aws_cloudwatch_event_target_test.go b/aws/resource_aws_cloudwatch_event_target_test.go index 067cec25dc9..d6aea0db8ab 100644 --- a/aws/resource_aws_cloudwatch_event_target_test.go +++ b/aws/resource_aws_cloudwatch_event_target_test.go @@ -1107,6 +1107,15 @@ resource "aws_cloudwatch_event_target" "test" { input_transformer { input_paths = { time = "$.time" + severity : "$.detail.severity", + Finding_ID : "$.detail.id", + instanceId : "$.detail.resource.instanceDetails.instanceId", + port : "$.detail.service.action.networkConnectionAction.localPortDetails.port", + eventFirstSeen : "$.detail.service.eventFirstSeen", + eventLastSeen : "$.detail.service.eventLastSeen", + count : "$.detail.service.count", + Finding_Type : "$.detail.type", + region : "$.region", } input_template = <, - "region": "eu-west-1", + "severity": , + "Finding_ID": , + "instanceId": , + "port": , + "eventFirstSeen": , + "eventLastSeen": , + "count": , + "Finding_Type": , + "region": , "detail": {} } EOF diff --git a/aws/validators.go b/aws/validators.go index 969c896f1b9..f53126c9160 100644 --- a/aws/validators.go +++ b/aws/validators.go @@ -2466,3 +2466,37 @@ func validateNestedExactlyOneOf(m map[string]interface{}, valid []string) error } return nil } + +func MapLenBetween(min, max int) schema.SchemaValidateFunc { + return func(i interface{}, k string) (warnings []string, errors []error) { + m, ok := i.(map[string]interface{}) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %s to be map", k)) + return warnings, errors + } + + if len(m) < min || len(m) > max { + errors = append(errors, fmt.Errorf("expected length of %s to be in the range (%d - %d), got %d", k, min, max, len(m))) + } + + return warnings, errors + } +} + +func MapKeyNotMatch(r *regexp.Regexp, message string) schema.SchemaValidateFunc { + return func(i interface{}, k string) (warnings []string, errors []error) { + m, ok := i.(map[string]interface{}) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %s to be map", k)) + return warnings, errors + } + + for key := range m { + if ok := r.MatchString(key); ok { + errors = append(errors, fmt.Errorf("%s: %s: %s", k, message, key)) + } + } + + return warnings, errors + } +} diff --git a/website/docs/r/cloudwatch_event_target.html.markdown b/website/docs/r/cloudwatch_event_target.html.markdown index 13f961ec1cb..ace05ce23fe 100644 --- a/website/docs/r/cloudwatch_event_target.html.markdown +++ b/website/docs/r/cloudwatch_event_target.html.markdown @@ -301,6 +301,10 @@ For more information, see [Task Networking](https://docs.aws.amazon.com/AmazonEC `input_transformer` support the following: * `input_paths` - (Optional) Key value pairs specified in the form of JSONPath (for example, time = $.time) + * You can have as many as 10 key-value pairs. + * You must use JSON dot notation, not bracket notation. + * The keys can't start with "AWS". + * `input_template` - (Required) Structure containing the template body. ## Import From b2b78dcba3554fb32766be29a364dc35266c1bfe Mon Sep 17 00:00:00 2001 From: philnichol Date: Sat, 17 Oct 2020 13:34:34 +0100 Subject: [PATCH 2/4] renamed validator functions --- aws/resource_aws_cloudwatch_event_target.go | 4 ++-- aws/validators.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_target.go b/aws/resource_aws_cloudwatch_event_target.go index cd822317dc9..18bdff07c4b 100644 --- a/aws/resource_aws_cloudwatch_event_target.go +++ b/aws/resource_aws_cloudwatch_event_target.go @@ -217,8 +217,8 @@ func resourceAwsCloudWatchEventTarget() *schema.Resource { Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, ValidateFunc: validation.All( - MapLenBetween(0, 10), - MapKeyNotMatch(regexp.MustCompile(`^AWS.*$`), "input_path must not start with \"AWS\""), + MapMaxItems(10), + MapKeysDoNotMatch(regexp.MustCompile(`^AWS.*$`), "input_path must not start with \"AWS\""), ), }, "input_template": { diff --git a/aws/validators.go b/aws/validators.go index f53126c9160..660e0170e6b 100644 --- a/aws/validators.go +++ b/aws/validators.go @@ -2467,7 +2467,7 @@ func validateNestedExactlyOneOf(m map[string]interface{}, valid []string) error return nil } -func MapLenBetween(min, max int) schema.SchemaValidateFunc { +func MapMaxItems(max int) schema.SchemaValidateFunc { return func(i interface{}, k string) (warnings []string, errors []error) { m, ok := i.(map[string]interface{}) if !ok { @@ -2475,15 +2475,15 @@ func MapLenBetween(min, max int) schema.SchemaValidateFunc { return warnings, errors } - if len(m) < min || len(m) > max { - errors = append(errors, fmt.Errorf("expected length of %s to be in the range (%d - %d), got %d", k, min, max, len(m))) + if len(m) > max { + errors = append(errors, fmt.Errorf("expected number of items in %s to be lesser than or equal to %d, got %d", k, max, len(m))) } return warnings, errors } } -func MapKeyNotMatch(r *regexp.Regexp, message string) schema.SchemaValidateFunc { +func MapKeysDoNotMatch(r *regexp.Regexp, message string) schema.SchemaValidateFunc { return func(i interface{}, k string) (warnings []string, errors []error) { m, ok := i.(map[string]interface{}) if !ok { From 31c1197329458eddca9139104609e9932efa99a0 Mon Sep 17 00:00:00 2001 From: philnichol Date: Sat, 17 Oct 2020 13:36:04 +0100 Subject: [PATCH 3/4] added expecterror to validation test --- ...source_aws_cloudwatch_event_target_test.go | 64 +++++++++++-------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_target_test.go b/aws/resource_aws_cloudwatch_event_target_test.go index d6aea0db8ab..37ea6023f2c 100644 --- a/aws/resource_aws_cloudwatch_event_target_test.go +++ b/aws/resource_aws_cloudwatch_event_target_test.go @@ -3,6 +3,8 @@ package aws import ( "fmt" "log" + "regexp" + "strings" "testing" "github.com/aws/aws-sdk-go/aws" @@ -359,7 +361,11 @@ func TestAccAWSCloudWatchEventTarget_input_transformer(t *testing.T) { CheckDestroy: testAccCheckAWSCloudWatchEventTargetDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSCloudWatchEventTargetConfigInputTransformer(rName), + Config: testAccAWSCloudWatchEventTargetConfigInputTransformer(rName, 11), + ExpectError: regexp.MustCompile(`.*expected number of items in.* to be lesser than or equal to.*`), + }, + { + Config: testAccAWSCloudWatchEventTargetConfigInputTransformer(rName, 10), Check: resource.ComposeTestCheckFunc( testAccCheckCloudWatchEventTargetExists("aws_cloudwatch_event_target.test", &target), ), @@ -1062,7 +1068,35 @@ resource "aws_sqs_queue" "sqs_queue" { `, rName) } -func testAccAWSCloudWatchEventTargetConfigInputTransformer(rName string) string { +func testAccAWSCloudWatchEventTargetConfigInputTransformer(rName string, inputPathCount int) string { + sampleInputPaths := [...]string{ + "account", + "count", + "eventFirstSeen", + "eventLastSeen", + "Finding_ID", + "Finding_Type", + "instanceId", + "port", + "region", + "severity", + "time", + } + var inputPaths strings.Builder + var inputTemplates strings.Builder + + if len(sampleInputPaths) < inputPathCount { + inputPathCount = len(sampleInputPaths) + } + for i := 0; i < inputPathCount; i++ { + fmt.Fprintf(&inputPaths, ` + %s = "$.%s"`, sampleInputPaths[i], sampleInputPaths[i]) + + fmt.Fprintf(&inputTemplates, ` + "%s": <%s>,`, sampleInputPaths[i], sampleInputPaths[i]) + + } + return fmt.Sprintf(` resource "aws_iam_role" "iam_for_lambda" { name = "tf_acc_input_transformer" @@ -1105,38 +1139,18 @@ resource "aws_cloudwatch_event_target" "test" { rule = aws_cloudwatch_event_rule.schedule.id input_transformer { - input_paths = { - time = "$.time" - severity : "$.detail.severity", - Finding_ID : "$.detail.id", - instanceId : "$.detail.resource.instanceDetails.instanceId", - port : "$.detail.service.action.networkConnectionAction.localPortDetails.port", - eventFirstSeen : "$.detail.service.eventFirstSeen", - eventLastSeen : "$.detail.service.eventLastSeen", - count : "$.detail.service.count", - Finding_Type : "$.detail.type", - region : "$.region", + input_paths = {%s } input_template = <, - "severity": , - "Finding_ID": , - "instanceId": , - "port": , - "eventFirstSeen": , - "eventLastSeen": , - "count": , - "Finding_Type": , - "region": , + "source": "aws.events",%s "detail": {} } EOF } } -`, rName) +`, rName, inputPaths.String(), inputTemplates.String()) } From 21fa7c249413e3d601998558a7034a89c647a874 Mon Sep 17 00:00:00 2001 From: philnichol Date: Sat, 17 Oct 2020 14:04:35 +0100 Subject: [PATCH 4/4] fixed formatting --- aws/resource_aws_cloudwatch_event_target_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_cloudwatch_event_target_test.go b/aws/resource_aws_cloudwatch_event_target_test.go index 37ea6023f2c..3d856779d3e 100644 --- a/aws/resource_aws_cloudwatch_event_target_test.go +++ b/aws/resource_aws_cloudwatch_event_target_test.go @@ -1088,13 +1088,13 @@ func testAccAWSCloudWatchEventTargetConfigInputTransformer(rName string, inputPa if len(sampleInputPaths) < inputPathCount { inputPathCount = len(sampleInputPaths) } + for i := 0; i < inputPathCount; i++ { fmt.Fprintf(&inputPaths, ` %s = "$.%s"`, sampleInputPaths[i], sampleInputPaths[i]) fmt.Fprintf(&inputTemplates, ` "%s": <%s>,`, sampleInputPaths[i], sampleInputPaths[i]) - } return fmt.Sprintf(` @@ -1139,7 +1139,8 @@ resource "aws_cloudwatch_event_target" "test" { rule = aws_cloudwatch_event_rule.schedule.id input_transformer { - input_paths = {%s + input_paths = { + %s } input_template = <