From 69dda64735172e6c370a6475fc26658a66a85aea Mon Sep 17 00:00:00 2001 From: Timothy Mower Date: Thu, 20 Sep 2018 16:04:13 -0700 Subject: [PATCH 001/475] [docs] Clarify mfa_delete cannot toggle state --- website/docs/r/s3_bucket.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/s3_bucket.html.markdown b/website/docs/r/s3_bucket.html.markdown index 7d68b04a432..914373ad437 100644 --- a/website/docs/r/s3_bucket.html.markdown +++ b/website/docs/r/s3_bucket.html.markdown @@ -359,7 +359,7 @@ The `CORS` object supports the following: The `versioning` object supports the following: * `enabled` - (Optional) Enable versioning. Once you version-enable a bucket, it can never return to an unversioned state. You can, however, suspend versioning on that bucket. -* `mfa_delete` - (Optional) Enable MFA delete for either `Change the versioning state of your bucket` or `Permanently delete an object version`. Default is `false`. +* `mfa_delete` - (Optional) Enable MFA delete for either `Change the versioning state of your bucket` or `Permanently delete an object version`. Default is `false`. This cannot be used to toggle this setting but is available to allow managed buckets to reflect the state in AWS The `logging` object supports the following: From ee910c848a71b8ceade475c12c58767af58d34f0 Mon Sep 17 00:00:00 2001 From: Edward Date: Thu, 7 Feb 2019 13:37:43 +0000 Subject: [PATCH 002/475] Add support for DynamoDbv2 IoT topic rule action --- aws/resource_aws_iot_topic_rule.go | 38 ++++++++++++++++++-- aws/resource_aws_iot_topic_rule_test.go | 40 +++++++++++++++++++++ aws/structure.go | 16 +++++++++ website/docs/r/iot_topic_rule.html.markdown | 5 +++ 4 files changed, 96 insertions(+), 3 deletions(-) diff --git a/aws/resource_aws_iot_topic_rule.go b/aws/resource_aws_iot_topic_rule.go index 425247d9af8..0eedc0dbde3 100644 --- a/aws/resource_aws_iot_topic_rule.go +++ b/aws/resource_aws_iot_topic_rule.go @@ -146,6 +146,23 @@ func resourceAwsIotTopicRule() *schema.Resource { }, }, }, + "dynamodbv2": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "role_arn": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateArn, + }, + "table_name": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, "elasticsearch": { Type: schema.TypeSet, Optional: true, @@ -326,6 +343,7 @@ func createTopicRulePayload(d *schema.ResourceData) *iot.TopicRulePayload { cloudwatchAlarmActions := d.Get("cloudwatch_alarm").(*schema.Set).List() cloudwatchMetricActions := d.Get("cloudwatch_metric").(*schema.Set).List() dynamoDbActions := d.Get("dynamodb").(*schema.Set).List() + dynamoDbv2Actions := d.Get("dynamodbv2").(*schema.Set).List() elasticsearchActions := d.Get("elasticsearch").(*schema.Set).List() firehoseActions := d.Get("firehose").(*schema.Set).List() kinesisActions := d.Get("kinesis").(*schema.Set).List() @@ -336,9 +354,9 @@ func createTopicRulePayload(d *schema.ResourceData) *iot.TopicRulePayload { sqsActions := d.Get("sqs").(*schema.Set).List() numActions := len(cloudwatchAlarmActions) + len(cloudwatchMetricActions) + - len(dynamoDbActions) + len(elasticsearchActions) + len(firehoseActions) + - len(kinesisActions) + len(lambdaActions) + len(republishActions) + - len(s3Actions) + len(snsActions) + len(sqsActions) + len(dynamoDbActions) + len(dynamoDbv2Actions) + len(elasticsearchActions) + + len(firehoseActions) + len(kinesisActions) + len(lambdaActions) + + len(republishActions) + len(s3Actions) + len(snsActions) + len(sqsActions) actions := make([]*iot.Action, numActions) i := 0 @@ -401,6 +419,19 @@ func createTopicRulePayload(d *schema.ResourceData) *iot.TopicRulePayload { i++ } + // Add DynamoDBv2 actions + for _, a := range dynamoDbv2Actions { + raw := a.(map[string]interface{}) + act := &iot.Action{ + DynamoDBv2: &iot.DynamoDBv2Action{ + PutItem: &iot.PutItemInput{TableName: aws.String(raw["table_name"].(string))}, + RoleArn: aws.String(raw["role_arn"].(string)), + }, + } + actions[i] = act + i++ + } + // Add Elasticsearch actions for _, a := range elasticsearchActions { @@ -570,6 +601,7 @@ func resourceAwsIotTopicRuleRead(d *schema.ResourceData, meta interface{}) error d.Set("cloudwatch_alarm", flattenIoTRuleCloudWatchAlarmActions(out.Rule.Actions)) d.Set("cloudwatch_metric", flattenIoTRuleCloudWatchMetricActions(out.Rule.Actions)) d.Set("dynamodb", flattenIoTRuleDynamoDbActions(out.Rule.Actions)) + d.Set("dynamodbv2", flattenIoTRuleDynamoDbv2Actions(out.Rule.Actions)) d.Set("elasticsearch", flattenIoTRuleElasticSearchActions(out.Rule.Actions)) d.Set("firehose", flattenIoTRuleFirehoseActions(out.Rule.Actions)) d.Set("kinesis", flattenIoTRuleKinesisActions(out.Rule.Actions)) diff --git a/aws/resource_aws_iot_topic_rule_test.go b/aws/resource_aws_iot_topic_rule_test.go index c007ec82100..2244e2aa126 100644 --- a/aws/resource_aws_iot_topic_rule_test.go +++ b/aws/resource_aws_iot_topic_rule_test.go @@ -90,6 +90,24 @@ func TestAccAWSIoTTopicRule_cloudwatchmetric(t *testing.T) { }) } +func TestAccAWSIoTTopicRule_dynamoDbv2(t *testing.T) { + rName := acctest.RandString(5) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSIoTTopicRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSIoTTopicRule_dynamoDbv2(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + ), + }, + }, + }) +} + func TestAccAWSIoTTopicRule_elasticsearch(t *testing.T) { rName := acctest.RandString(5) @@ -396,6 +414,28 @@ resource "aws_iot_topic_rule" "rule" { `, rName) } +func testAccAWSIoTTopicRule_dynamoDbv2(rName string) string { + return fmt.Sprintf(testAccAWSIoTTopicRuleRole+` +data "aws_region" "current" { + current = true +} + +resource "aws_iot_topic_rule" "rule" { + name = "test_rule_%[1]s" + description = "Example rule" + enabled = true + sql = "SELECT field as column_name FROM 'topic/test'" + sql_version = "2015-10-08" + + dynamodbv2 { + table_name = "${aws_iam_role.iot_role.arn}" + role_arn = "${aws_dynamodb_table.iot_table.arn}" + } +} +`, rName) +} + + func testAccAWSIoTTopicRule_elasticsearch(rName string) string { return fmt.Sprintf(testAccAWSIoTTopicRuleRole+` data "aws_region" "current" { diff --git a/aws/structure.go b/aws/structure.go index 3fa41fcf3c0..9764f624d61 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -2858,6 +2858,22 @@ func flattenIoTRuleDynamoDbActions(actions []*iot.Action) []map[string]interface return results } +func flattenIoTRuleDynamoDbv2Actions(actions []*iot.Action) []map[string]interface{} { + results := make([]map[string]interface{}, 0) + + for _, a := range actions { + result := make(map[string]interface{}) + v := a.DynamoDBv2 + if v != nil { + result["role_arn"] = *v.RoleArn + result["table_name"] = *v.PutItem + results = append(results, result) + } + } + + return results +} + func flattenIoTRuleElasticSearchActions(actions []*iot.Action) []map[string]interface{} { results := make([]map[string]interface{}, 0) diff --git a/website/docs/r/iot_topic_rule.html.markdown b/website/docs/r/iot_topic_rule.html.markdown index 365905c5cf8..e48cfcf6802 100644 --- a/website/docs/r/iot_topic_rule.html.markdown +++ b/website/docs/r/iot_topic_rule.html.markdown @@ -103,6 +103,11 @@ The `dynamodb` object takes the following arguments: * `role_arn` - (Required) The ARN of the IAM role that grants access to the DynamoDB table. * `table_name` - (Required) The name of the DynamoDB table. +The `dynamodbv2` object takes the following arguments: + +* `role_arn` - (Required) The ARN of the IAM role that grants access to the DynamoDB table. +* `table_name` - (Required) The name of the DynamoDB table. + The `elasticsearch` object takes the following arguments: * `endpoint` - (Required) The endpoint of your Elasticsearch domain. From e84e78e16d9812a9d3328ef67c8f0af4b812e9e8 Mon Sep 17 00:00:00 2001 From: Edward Browncross Date: Fri, 8 Feb 2019 13:10:01 +0000 Subject: [PATCH 003/475] fix linting error --- aws/resource_aws_iot_topic_rule_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/aws/resource_aws_iot_topic_rule_test.go b/aws/resource_aws_iot_topic_rule_test.go index 2244e2aa126..b9688badaff 100644 --- a/aws/resource_aws_iot_topic_rule_test.go +++ b/aws/resource_aws_iot_topic_rule_test.go @@ -435,7 +435,6 @@ resource "aws_iot_topic_rule" "rule" { `, rName) } - func testAccAWSIoTTopicRule_elasticsearch(rName string) string { return fmt.Sprintf(testAccAWSIoTTopicRuleRole+` data "aws_region" "current" { From 50ed84d9d4847bc7fe862c507a8e5d25a47f7285 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 21 Aug 2019 15:44:33 +0300 Subject: [PATCH 004/475] Add iotAnalytics action --- aws/resource_aws_iot_topic_rule.go | 33 ++++++++++++++++++- aws/resource_aws_iot_topic_rule_test.go | 35 +++++++++++++++++++++ aws/structure.go | 17 ++++++++++ website/docs/r/iot_topic_rule.html.markdown | 4 +++ 4 files changed, 88 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_iot_topic_rule.go b/aws/resource_aws_iot_topic_rule.go index 42cd8900c6b..13d15077c4e 100644 --- a/aws/resource_aws_iot_topic_rule.go +++ b/aws/resource_aws_iot_topic_rule.go @@ -318,6 +318,23 @@ func resourceAwsIotTopicRule() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "iot_analytics_actions": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "channel_name": { + Type: schema.TypeString, + Required: true, + }, + "role_arn": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateArn, + }, + }, + }, + }, }, } } @@ -334,11 +351,12 @@ func createTopicRulePayload(d *schema.ResourceData) *iot.TopicRulePayload { s3Actions := d.Get("s3").(*schema.Set).List() snsActions := d.Get("sns").(*schema.Set).List() sqsActions := d.Get("sqs").(*schema.Set).List() + iotAnalyticsActions := d.Get("iot_analytics_actions").(*schema.Set).List() numActions := len(cloudwatchAlarmActions) + len(cloudwatchMetricActions) + len(dynamoDbActions) + len(elasticsearchActions) + len(firehoseActions) + len(kinesisActions) + len(lambdaActions) + len(republishActions) + - len(s3Actions) + len(snsActions) + len(sqsActions) + len(s3Actions) + len(snsActions) + len(sqsActions) + len(iotAnalyticsActions) actions := make([]*iot.Action, numActions) i := 0 @@ -522,6 +540,18 @@ func createTopicRulePayload(d *schema.ResourceData) *iot.TopicRulePayload { i++ } + // Add Analytic actions + for _, a := range iotAnalyticsActions { + raw := a.(map[string]interface{}) + actions[i] = &iot.Action{ + IotAnalytics: &iot.IotAnalyticsAction{ + ChannelName: aws.String(raw["channel_name"].(string)), + RoleArn: aws.String(raw["role_arn"].(string)), + }, + } + i++ + } + return &iot.TopicRulePayload{ Description: aws.String(d.Get("description").(string)), RuleDisabled: aws.Bool(!d.Get("enabled").(bool)), @@ -582,6 +612,7 @@ func resourceAwsIotTopicRuleRead(d *schema.ResourceData, meta interface{}) error d.Set("s3", flattenIoTRuleS3Actions(out.Rule.Actions)) d.Set("sns", flattenIoTRuleSnsActions(out.Rule.Actions)) d.Set("sqs", flattenIoTRuleSqsActions(out.Rule.Actions)) + d.Set("iot_analytics", flattenIoTRuleIotAnalyticsActions(out.Rule.Actions)) return nil } diff --git a/aws/resource_aws_iot_topic_rule_test.go b/aws/resource_aws_iot_topic_rule_test.go index f43fbfbe6b7..eb957af1a71 100644 --- a/aws/resource_aws_iot_topic_rule_test.go +++ b/aws/resource_aws_iot_topic_rule_test.go @@ -282,6 +282,24 @@ func TestAccAWSIoTTopicRule_sqs(t *testing.T) { }) } +func TestAccAWSIoTTopicRule_iot_analytics(t *testing.T) { + rName := acctest.RandString(5) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSIoTTopicRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSIoTTopicRule_iot_analytics(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + ), + }, + }, + }) +} + func testAccCheckAWSIoTTopicRuleDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).iotconn @@ -612,3 +630,20 @@ resource "aws_iot_topic_rule" "rule" { } `, rName) } + +func testAccAWSIoTTopicRule_iot_analytics(rName string) string { + return fmt.Sprintf(testAccAWSIoTTopicRuleRole+` +resource "aws_iot_topic_rule" "rule" { + name = "test_rule_%[1]s" + description = "Example rule" + enabled = true + sql = "SELECT * FROM 'topic/test'" + sql_version = "2015-10-08" + + iot_analytics { + channel_name = "fakedata" + role_arn = "${aws_iam_role.iot_role.arn}" + } +} +`, rName) +} diff --git a/aws/structure.go b/aws/structure.go index db19625ed74..2b7925c4460 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -2985,6 +2985,23 @@ func flattenIoTRuleSqsActions(actions []*iot.Action) []map[string]interface{} { return results } +func flattenIoTRuleIotAnalyticsActions(actions []*iot.Action) []map[string]interface{} { + results := make([]map[string]interface{}, 0) + + for _, a := range actions { + result := make(map[string]interface{}) + v := a.IotAnalytics + if v != nil { + result["role_arn"] = aws.StringValue(v.RoleArn) + result["channel_name"] = aws.StringValue(v.ChannelName) + + results = append(results, result) + } + } + + return results +} + func flattenCognitoUserPoolPasswordPolicy(s *cognitoidentityprovider.PasswordPolicyType) []map[string]interface{} { m := map[string]interface{}{} diff --git a/website/docs/r/iot_topic_rule.html.markdown b/website/docs/r/iot_topic_rule.html.markdown index 218dfc284db..a0e80268c98 100644 --- a/website/docs/r/iot_topic_rule.html.markdown +++ b/website/docs/r/iot_topic_rule.html.markdown @@ -152,6 +152,10 @@ The `sqs` object takes the following arguments: * `role_arn` - (Required) The ARN of the IAM role that grants access. * `use_base64` - (Required) Specifies whether to use Base64 encoding. +The `iot_analytics` object takes the following arguments: + +* `channel_name` - (Required) Name of AWS IOT Analytics channel. +* `role_arn` - (Required) The ARN of the IAM role that grants access. ## Attributes Reference In addition to all arguments above, the following attributes are exported: From f1cd27b697d37cca9085901a74303904a82d75b2 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Wed, 21 Aug 2019 16:58:33 +0300 Subject: [PATCH 005/475] Fix block name --- aws/resource_aws_iot_topic_rule.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_iot_topic_rule.go b/aws/resource_aws_iot_topic_rule.go index 13d15077c4e..0bfc3bddbfe 100644 --- a/aws/resource_aws_iot_topic_rule.go +++ b/aws/resource_aws_iot_topic_rule.go @@ -318,7 +318,7 @@ func resourceAwsIotTopicRule() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "iot_analytics_actions": { + "iot_analytics": { Type: schema.TypeSet, Optional: true, Elem: &schema.Resource{ @@ -351,7 +351,7 @@ func createTopicRulePayload(d *schema.ResourceData) *iot.TopicRulePayload { s3Actions := d.Get("s3").(*schema.Set).List() snsActions := d.Get("sns").(*schema.Set).List() sqsActions := d.Get("sqs").(*schema.Set).List() - iotAnalyticsActions := d.Get("iot_analytics_actions").(*schema.Set).List() + iotAnalyticsActions := d.Get("iot_analytics").(*schema.Set).List() numActions := len(cloudwatchAlarmActions) + len(cloudwatchMetricActions) + len(dynamoDbActions) + len(elasticsearchActions) + len(firehoseActions) + From 899414a08edfd16b91b91ccc6879894247f9bb49 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Fri, 23 Aug 2019 16:34:04 +0300 Subject: [PATCH 006/475] Add iotEvents action --- aws/resource_aws_iot_topic_rule.go | 41 ++++++++++++++++++++++++- aws/resource_aws_iot_topic_rule_test.go | 36 ++++++++++++++++++++++ aws/structure.go | 20 ++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_iot_topic_rule.go b/aws/resource_aws_iot_topic_rule.go index 42cd8900c6b..04d7b0b0f76 100644 --- a/aws/resource_aws_iot_topic_rule.go +++ b/aws/resource_aws_iot_topic_rule.go @@ -318,6 +318,26 @@ func resourceAwsIotTopicRule() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "iot_events": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "input_name": { + Type: schema.TypeString, + Required: true, + }, + "message_id": { + Type: schema.TypeString, + Optional: true, + }, + "role_arn": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, }, } } @@ -334,11 +354,12 @@ func createTopicRulePayload(d *schema.ResourceData) *iot.TopicRulePayload { s3Actions := d.Get("s3").(*schema.Set).List() snsActions := d.Get("sns").(*schema.Set).List() sqsActions := d.Get("sqs").(*schema.Set).List() + iotEventsActions := d.Get("iot_events").(*schema.Set).List() numActions := len(cloudwatchAlarmActions) + len(cloudwatchMetricActions) + len(dynamoDbActions) + len(elasticsearchActions) + len(firehoseActions) + len(kinesisActions) + len(lambdaActions) + len(republishActions) + - len(s3Actions) + len(snsActions) + len(sqsActions) + len(s3Actions) + len(snsActions) + len(sqsActions) + len(iotEventsActions) actions := make([]*iot.Action, numActions) i := 0 @@ -522,6 +543,23 @@ func createTopicRulePayload(d *schema.ResourceData) *iot.TopicRulePayload { i++ } + // Add IoT Events actions + + for _, a := range iotEventsActions { + raw := a.(map[string]interface{}) + act := &iot.Action{ + IotEvents: &iot.IotEventsAction{ + InputName: aws.String(raw["input_name"].(string)), + RoleArn: aws.String(raw["role_arn"].(string)), + }, + } + if v, ok := raw["message_id"].(string); ok && v != "" { + act.IotEvents.MessageId = aws.String(raw["message_id"].(string)) + } + actions[i] = act + i++ + } + return &iot.TopicRulePayload{ Description: aws.String(d.Get("description").(string)), RuleDisabled: aws.Bool(!d.Get("enabled").(bool)), @@ -582,6 +620,7 @@ func resourceAwsIotTopicRuleRead(d *schema.ResourceData, meta interface{}) error d.Set("s3", flattenIoTRuleS3Actions(out.Rule.Actions)) d.Set("sns", flattenIoTRuleSnsActions(out.Rule.Actions)) d.Set("sqs", flattenIoTRuleSqsActions(out.Rule.Actions)) + d.Set("iot_events", flattenIoTRuleIotEventsActions(out.Rule.Actions)) return nil } diff --git a/aws/resource_aws_iot_topic_rule_test.go b/aws/resource_aws_iot_topic_rule_test.go index f43fbfbe6b7..302c96d99b2 100644 --- a/aws/resource_aws_iot_topic_rule_test.go +++ b/aws/resource_aws_iot_topic_rule_test.go @@ -282,6 +282,24 @@ func TestAccAWSIoTTopicRule_sqs(t *testing.T) { }) } +func TestAccAWSIoTTopicRule_iot_events(t *testing.T) { + rName := acctest.RandString(5) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSIoTTopicRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSIoTTopicRule_iot_events(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + ), + }, + }, + }) +} + func testAccCheckAWSIoTTopicRuleDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).iotconn @@ -612,3 +630,21 @@ resource "aws_iot_topic_rule" "rule" { } `, rName) } + +func testAccAWSIoTTopicRule_iot_events(rName string) string { + return fmt.Sprintf(testAccAWSIoTTopicRuleRole+` +resource "aws_iot_topic_rule" "rule" { + name = "test_rule_%[1]s" + description = "Example rule" + enabled = true + sql = "SELECT * FROM 'topic/test'" + sql_version = "2015-10-08" + + iot_events { + input_name = "fake_input_name" + role_arn = "${aws_iam_role.iot_role.arn}" + message_id = "fake_message_id" + } +} +`, rName) +} diff --git a/aws/structure.go b/aws/structure.go index db19625ed74..1bd2d394968 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -2985,6 +2985,26 @@ func flattenIoTRuleSqsActions(actions []*iot.Action) []map[string]interface{} { return results } +func flattenIoTRuleIotEventsActions(actions []*iot.Action) []map[string]interface{} { + results := make([]map[string]interface{}, 0) + + for _, a := range actions { + result := make(map[string]interface{}) + v := a.IotEvents + if v != nil { + result["role_arn"] = aws.StringValue(v.RoleArn) + result["input_name"] = aws.StringValue(v.InputName) + if v.MessageId != nil { + result["message_id"] = aws.StringValue(v.MessageId) + } + + results = append(results, result) + } + } + + return results +} + func flattenCognitoUserPoolPasswordPolicy(s *cognitoidentityprovider.PasswordPolicyType) []map[string]interface{} { m := map[string]interface{}{} From 59cff6c437ac2b3e7ce62caf4300da79b80cf103 Mon Sep 17 00:00:00 2001 From: Oleksiy Veretiuk Date: Tue, 27 Aug 2019 12:00:33 +0300 Subject: [PATCH 007/475] Add docs --- website/docs/r/iot_topic_rule.html.markdown | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/website/docs/r/iot_topic_rule.html.markdown b/website/docs/r/iot_topic_rule.html.markdown index 218dfc284db..f9349a70b86 100644 --- a/website/docs/r/iot_topic_rule.html.markdown +++ b/website/docs/r/iot_topic_rule.html.markdown @@ -152,6 +152,12 @@ The `sqs` object takes the following arguments: * `role_arn` - (Required) The ARN of the IAM role that grants access. * `use_base64` - (Required) Specifies whether to use Base64 encoding. +The `iot_events` object takes the following arguments: + +* `input_name` - (Required) The name of the AWS IoT Events input. +* `role_arn` - (Required) The ARN of the IAM role that grants access. +* `message_id` - (Optional) Use this to ensure that only one input (message) with a given messageId is processed by an AWS IoT Events detector. + ## Attributes Reference In addition to all arguments above, the following attributes are exported: From 63213649d47f432f569eaaff75b2e0f7721f0fd9 Mon Sep 17 00:00:00 2001 From: Arata Notsu Date: Mon, 13 Jan 2020 03:29:56 +0900 Subject: [PATCH 008/475] aws_codebuild_project: allow empty value of environment variables --- aws/resource_aws_codebuild_project.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_codebuild_project.go b/aws/resource_aws_codebuild_project.go index 0162c6423e6..7317d82054d 100644 --- a/aws/resource_aws_codebuild_project.go +++ b/aws/resource_aws_codebuild_project.go @@ -836,7 +836,7 @@ func expandProjectEnvironment(d *schema.ResourceData) *codebuild.ProjectEnvironm projectEnvironmentVar.Name = &v } - if v := config["value"].(string); v != "" { + if v, ok := config["value"].(string); ok { projectEnvironmentVar.Value = &v } From 01d384b98470d456722bf9b1deb75d8f8d326fdb Mon Sep 17 00:00:00 2001 From: Kevin Tham Date: Wed, 29 Jan 2020 21:22:10 -0800 Subject: [PATCH 009/475] resource/aws_security_group_rule: Prevent resource replacement when source sg id is specified with account id prefix --- aws/resource_aws_security_group_rule.go | 14 ++++- aws/resource_aws_security_group_rule_test.go | 55 ++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_security_group_rule.go b/aws/resource_aws_security_group_rule.go index b9d4cdf73e6..2f2d5c4f45d 100644 --- a/aws/resource_aws_security_group_rule.go +++ b/aws/resource_aws_security_group_rule.go @@ -759,7 +759,19 @@ func setFromIPPerm(d *schema.ResourceData, sg *ec2.SecurityGroup, rule *ec2.IpPe s := rule.UserIdGroupPairs[0] if isVPC { - d.Set("source_security_group_id", *s.GroupId) + if existingSourceSgId, ok := d.GetOk("source_security_group_id"); ok { + sgIdComponents := strings.Split(existingSourceSgId.(string), "/") + hasAccountIdPrefix := len(sgIdComponents) == 2 + + if hasAccountIdPrefix { + // then ensure on refresh that we prefix the account id + d.Set("source_security_group_id", *s.UserId+"/"+*s.GroupId) + } else { + d.Set("source_security_group_id", *s.GroupId) + } + } else { + d.Set("source_security_group_id", *s.GroupId) + } } else { d.Set("source_security_group_id", *s.GroupName) } diff --git a/aws/resource_aws_security_group_rule_test.go b/aws/resource_aws_security_group_rule_test.go index cb6be2babff..213e7c9d59a 100644 --- a/aws/resource_aws_security_group_rule_test.go +++ b/aws/resource_aws_security_group_rule_test.go @@ -154,6 +154,32 @@ func TestAccAWSSecurityGroupRule_Ingress_VPC(t *testing.T) { }) } +func TestAccAWSSecurityGroupRule_Ingress_Source_With_Account_Id(t *testing.T) { + var group ec2.SecurityGroup + + rInt := acctest.RandInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSecurityGroupRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSecurityGroupRule_Ingress_Source_with_AccountId(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group), + ), + }, + // Ensure plan shows no difference after state is refreshed + { + Config: testAccAWSSecurityGroupRule_Ingress_Source_with_AccountId(rInt), + PlanOnly: true, + ExpectNonEmptyPlan: false, + }, + }, + }) +} + func TestAccAWSSecurityGroupRule_Ingress_Protocol(t *testing.T) { var group ec2.SecurityGroup @@ -2046,6 +2072,35 @@ resource "aws_security_group_rule" "allow_self" { `, rInt) } +func testAccAWSSecurityGroupRule_Ingress_Source_with_AccountId(rInt int) string { + return fmt.Sprintf(` +data "aws_caller_identity" "current" {} + +resource "aws_vpc" "foo" { + cidr_block = "10.1.0.0/16" + + tags = { + Name = "terraform-testacc-security-group-rule-self-ingress" + } +} + +resource "aws_security_group" "web" { + name = "allow_all-%d" + description = "Allow all inbound traffic" + vpc_id = "${aws_vpc.foo.id}" +} + +resource "aws_security_group_rule" "allow_self" { + type = "ingress" + from_port = 0 + to_port = 0 + protocol = "-1" + security_group_id = "${aws_security_group.web.id}" + source_security_group_id = "${data.aws_caller_identity.current.account_id}/${aws_security_group.web.id}" +} +`, rInt) +} + func testAccAWSSecurityGroupRuleExpectInvalidType(rInt int) string { return fmt.Sprintf(` resource "aws_vpc" "foo" { From ab807d6da66610ab3d12d0c2b4320441312a42a9 Mon Sep 17 00:00:00 2001 From: Kevin Tham Date: Wed, 26 Feb 2020 10:11:56 -0800 Subject: [PATCH 010/475] Fix --- aws/resource_aws_security_group_rule.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_security_group_rule.go b/aws/resource_aws_security_group_rule.go index d48c9e142e1..d727c6802b7 100644 --- a/aws/resource_aws_security_group_rule.go +++ b/aws/resource_aws_security_group_rule.go @@ -765,7 +765,7 @@ func setFromIPPerm(d *schema.ResourceData, sg *ec2.SecurityGroup, rule *ec2.IpPe if hasAccountIdPrefix { // then ensure on refresh that we prefix the account id - d.Set("source_security_group_id", s.UserId+"/"+s.GroupId) + d.Set("source_security_group_id", *s.UserId+"/"+*s.GroupId) } else { d.Set("source_security_group_id", s.GroupId) } From 6944aa589a22abd065ef352ef60369d749444804 Mon Sep 17 00:00:00 2001 From: Kristopher Linquist Date: Tue, 7 Apr 2020 12:17:58 -0700 Subject: [PATCH 011/475] IoT Rule DyanmoDB operation action --- aws/resource_aws_iot_topic_rule.go | 8 ++++++++ aws/resource_aws_iot_topic_rule_test.go | 5 +++-- aws/structure.go | 4 ++++ aws/validators.go | 12 ++++++++++++ website/docs/r/iot_topic_rule.html.markdown | 1 + 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_iot_topic_rule.go b/aws/resource_aws_iot_topic_rule.go index fdfc27bf4b6..e3ffc968ef5 100644 --- a/aws/resource_aws_iot_topic_rule.go +++ b/aws/resource_aws_iot_topic_rule.go @@ -144,6 +144,11 @@ func resourceAwsIotTopicRule() *schema.Resource { Type: schema.TypeString, Required: true, }, + "operation": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateIoTRuleDynamoDBOperation, + }, }, }, }, @@ -402,6 +407,9 @@ func createTopicRulePayload(d *schema.ResourceData) *iot.TopicRulePayload { if v, ok := raw["payload_field"].(string); ok && v != "" { act.DynamoDB.PayloadField = aws.String(v) } + if v, ok := raw["operation"].(string); ok && v != "" { + act.DynamoDB.Operation = aws.String(v) + } actions[i] = act i++ } diff --git a/aws/resource_aws_iot_topic_rule_test.go b/aws/resource_aws_iot_topic_rule_test.go index 4ebbed7c95b..75025f75277 100644 --- a/aws/resource_aws_iot_topic_rule_test.go +++ b/aws/resource_aws_iot_topic_rule_test.go @@ -481,7 +481,7 @@ resource "aws_iot_topic_rule" "rule" { hash_key_value = "hash_key_value" payload_field = "payload_field" role_arn = "${aws_iam_role.iot_role.arn}" - table_name = "table_name" + table_name = "table_name" } } `, rName) @@ -504,7 +504,8 @@ resource "aws_iot_topic_rule" "rule" { range_key_value = "range_key_value" range_key_type = "STRING" role_arn = "${aws_iam_role.iot_role.arn}" - table_name = "table_name" + table_name = "table_name" + operation = "INSERT" } } `, rName) diff --git a/aws/structure.go b/aws/structure.go index 7f0dc4fb2f1..f48c4cbae0f 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -2809,6 +2809,10 @@ func flattenIoTRuleDynamoDbActions(actions []*iot.Action) []map[string]interface m["range_key_value"] = aws.StringValue(v.RangeKeyValue) } + if v.Operation != nil { + m["operation"] = aws.StringValue(v.Operation) + } + items = append(items, m) } } diff --git a/aws/validators.go b/aws/validators.go index 5b1b685d960..b7a439fd67c 100644 --- a/aws/validators.go +++ b/aws/validators.go @@ -754,6 +754,18 @@ func validateHTTPMethod() schema.SchemaValidateFunc { }, false) } +func validateIoTRuleDynamoDBOperation(v interface{}, k string) (ws []string, errors []error) { + value := v.(string) + pattern := `^INSERT|UPDATE|DELETE$` + if !regexp.MustCompile(pattern).MatchString(value) { + errors = append(errors, fmt.Errorf( + "%q isn't a valid operation. Use INSERT, UPDATE, or DELETE", + k)) + } + + return +} + func validateLogMetricFilterName(v interface{}, k string) (ws []string, errors []error) { value := v.(string) diff --git a/website/docs/r/iot_topic_rule.html.markdown b/website/docs/r/iot_topic_rule.html.markdown index 0fd4f6ae5e7..d9d13bac5ae 100644 --- a/website/docs/r/iot_topic_rule.html.markdown +++ b/website/docs/r/iot_topic_rule.html.markdown @@ -102,6 +102,7 @@ The `dynamodb` object takes the following arguments: * `range_key_field` - (Optional) The range key name. * `range_key_type` - (Optional) The range key type. Valid values are "STRING" or "NUMBER". * `range_key_value` - (Optional) The range key value. +* `operation` - (Optional) The operation. Valid values are "INSERT", "UPDATE", or "DELETE". * `role_arn` - (Required) The ARN of the IAM role that grants access to the DynamoDB table. * `table_name` - (Required) The name of the DynamoDB table. From 76ac2691ce6e31f980d94265e25ae498d75302f1 Mon Sep 17 00:00:00 2001 From: drexler Date: Mon, 6 Apr 2020 21:31:45 -0400 Subject: [PATCH 012/475] docs: rename documentation file to match resource name --- website/aws.erb | 2 +- ...markdown => s3_bucket_analytics_configuration.html.markdown} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename website/docs/r/{s3_bucket_analysis_configuration.html.markdown => s3_bucket_analytics_configuration.html.markdown} (100%) diff --git a/website/aws.erb b/website/aws.erb index 8e1aeebabcb..dc9f62ce650 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -2689,7 +2689,7 @@ aws_s3_bucket
  • - aws_s3_bucket_analysis_configuration + aws_s3_bucket_analytics_configuration
  • aws_s3_bucket_inventory diff --git a/website/docs/r/s3_bucket_analysis_configuration.html.markdown b/website/docs/r/s3_bucket_analytics_configuration.html.markdown similarity index 100% rename from website/docs/r/s3_bucket_analysis_configuration.html.markdown rename to website/docs/r/s3_bucket_analytics_configuration.html.markdown From 267e71dc04a7143ba9ea50c24f8829edccd7a45d Mon Sep 17 00:00:00 2001 From: Max Marrone Date: Sun, 12 Apr 2020 18:10:22 -0700 Subject: [PATCH 013/475] Docs: aws_lambda_permission clarifications. --- website/docs/r/lambda_permission.html.markdown | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/website/docs/r/lambda_permission.html.markdown b/website/docs/r/lambda_permission.html.markdown index 25e93b409d1..09e9759c8e7 100644 --- a/website/docs/r/lambda_permission.html.markdown +++ b/website/docs/r/lambda_permission.html.markdown @@ -8,8 +8,7 @@ description: |- # Resource: aws_lambda_permission -Creates a Lambda permission to allow external sources invoking the Lambda function -(e.g. CloudWatch Event Rule, SNS or S3). +Gives an external source (like a CloudWatch Event Rule, SNS, or S3) permission to access the Lambda function. ## Example Usage @@ -141,16 +140,16 @@ resource "aws_lambda_permission" "lambda_permission" { The permission will then apply to the specific qualified ARN. e.g. `arn:aws:lambda:aws-region:acct-id:function:function-name:2` * `source_account` - (Optional) This parameter is used for S3 and SES. The AWS account ID (without a hyphen) of the source owner. - * `source_arn` - (Optional) When granting Amazon S3 or CloudWatch Events permission to - invoke your function, you should specify this field with the Amazon Resource Name (ARN) - for the S3 Bucket or CloudWatch Events Rule as its value. This ensures that only events - generated from the specified bucket or rule can invoke the function. - API Gateway ARNs have a unique structure described - [here](http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-control-access-using-iam-policies-to-invoke-api.html). + * `source_arn` - (Optional) When the principle is an AWS service, the ARN of the specific resource within that service to grant permission to. + Without this, any resource from `principle` will be granted permission – even if that resource is from another account. + For S3, this should be the ARN of the S3 Bucket. + For CloudWatch Events, this should be the ARN of the CloudWatch Events Rule. + For API Gateway, this should be the ARN of the API, as described [here][2]. * `statement_id` - (Optional) A unique statement identifier. By default generated by Terraform. * `statement_id_prefix` - (Optional) A statement identifier prefix. Terraform will generate a unique suffix. Conflicts with `statement_id`. [1]: https://developer.amazon.com/docs/custom-skills/host-a-custom-skill-as-an-aws-lambda-function.html#use-aws-cli +[2]: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-control-access-using-iam-policies-to-invoke-api.html. ## Import From c7a1a5cda9456140ee7a60d51de9f9e54c419369 Mon Sep 17 00:00:00 2001 From: Andrew Perry Date: Tue, 14 Apr 2020 15:47:29 +0100 Subject: [PATCH 014/475] docs: Add Federated Principal information to iam_policy_document This data source already supports Federated access. It just isn't documented. This change adds that documentation as well as providing an example of it being used. --- website/docs/d/iam_policy_document.html.markdown | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/website/docs/d/iam_policy_document.html.markdown b/website/docs/d/iam_policy_document.html.markdown index d8be0d66c6c..a6a83b4a9db 100644 --- a/website/docs/d/iam_policy_document.html.markdown +++ b/website/docs/d/iam_policy_document.html.markdown @@ -119,9 +119,11 @@ each accept the following arguments: Each policy may have either zero or more `principals` blocks or zero or more `not_principals` blocks, both of which each accept the following arguments: -* `type` (Required) The type of principal. For AWS ARNs this is "AWS". For AWS services (e.g. Lambda), this is "Service". +* `type` (Required) The type of principal. For AWS ARNs this is "AWS". For AWS services (e.g. Lambda), this is "Service". For Federated access the type is "Federated". * `identifiers` (Required) List of identifiers for principals. When `type` - is "AWS", these are IAM user or role ARNs. When `type` is "Service", these are AWS Service roles e.g. `lambda.amazonaws.com`. + is "AWS", these are IAM user or role ARNs. When `type` is "Service", these are AWS Service roles e.g. `lambda.amazonaws.com`. When `type` is "Federated", these are web identity users or SAML provider ARNs. + +For further examples or information about AWS principals then please refer to the [documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html). Each policy statement may have zero or more `condition` blocks, which each accept the following arguments: @@ -184,6 +186,10 @@ data "aws_iam_policy_document" "event_stream_bucket_role_assume_role_policy" { type = "AWS" identifiers = ["${var.trusted_role_arn}"] } + principals { + type = "Federated" + identifiers = ["arn:aws:iam::${var.account_id}:saml-provider/${var.provider_name}", "cognito-identity.amazonaws.com"] + } } } ``` From 256558c2c5296fec202e2170ff46f1a9cc977399 Mon Sep 17 00:00:00 2001 From: drexler Date: Thu, 16 Apr 2020 22:38:50 -0400 Subject: [PATCH 015/475] feat: add Qos field to IoT republish action --- aws/resource_aws_iot_topic_rule.go | 8 ++++++++ aws/structure.go | 1 + 2 files changed, 9 insertions(+) diff --git a/aws/resource_aws_iot_topic_rule.go b/aws/resource_aws_iot_topic_rule.go index fdfc27bf4b6..b2e33b8312e 100644 --- a/aws/resource_aws_iot_topic_rule.go +++ b/aws/resource_aws_iot_topic_rule.go @@ -6,6 +6,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/iot" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" ) func resourceAwsIotTopicRule() *schema.Resource { @@ -247,6 +248,12 @@ func resourceAwsIotTopicRule() *schema.Resource { Type: schema.TypeString, Required: true, }, + "qos": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + ValidateFunc: validation.IntBetween(0, 1), + }, }, }, }, @@ -476,6 +483,7 @@ func createTopicRulePayload(d *schema.ResourceData) *iot.TopicRulePayload { Republish: &iot.RepublishAction{ RoleArn: aws.String(raw["role_arn"].(string)), Topic: aws.String(raw["topic"].(string)), + Qos: aws.Int64(int64(raw["qos"].(int))), }, } i++ diff --git a/aws/structure.go b/aws/structure.go index a28c06ad0af..52670fba80d 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -2926,6 +2926,7 @@ func flattenIoTRuleRepublishActions(actions []*iot.Action) []map[string]interfac if v != nil { result["role_arn"] = *v.RoleArn result["topic"] = *v.Topic + result["qos"] = *v.Qos results = append(results, result) } From 31244acb2c55505e5041aa06bf17bb8828efbb33 Mon Sep 17 00:00:00 2001 From: drexler Date: Thu, 16 Apr 2020 22:44:25 -0400 Subject: [PATCH 016/475] test: add cover test for Qos field --- aws/resource_aws_iot_topic_rule_test.go | 42 +++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/aws/resource_aws_iot_topic_rule_test.go b/aws/resource_aws_iot_topic_rule_test.go index 4ebbed7c95b..b47e1d38fbb 100644 --- a/aws/resource_aws_iot_topic_rule_test.go +++ b/aws/resource_aws_iot_topic_rule_test.go @@ -267,6 +267,30 @@ func TestAccAWSIoTTopicRule_republish(t *testing.T) { }) } +func TestAccAWSIoTTopicRule_republish_with_qos(t *testing.T) { + rName := acctest.RandString(5) + resourceName := "aws_iot_topic_rule.rule" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSIoTTopicRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSIoTTopicRule_republish_with_qos(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAWSIoTTopicRule_s3(t *testing.T) { rName := acctest.RandString(5) resourceName := "aws_iot_topic_rule.rule" @@ -617,6 +641,24 @@ resource "aws_iot_topic_rule" "rule" { `, rName) } +func testAccAWSIoTTopicRule_republish_with_qos(rName string) string { + return fmt.Sprintf(testAccAWSIoTTopicRuleRole+` +resource "aws_iot_topic_rule" "rule" { + name = "test_rule_%[1]s" + description = "Example rule" + enabled = true + sql = "SELECT * FROM 'topic/test'" + sql_version = "2015-10-08" + + republish { + role_arn = "${aws_iam_role.iot_role.arn}" + topic = "mytopic" + qos = 1 + } +} +`, rName) +} + func testAccAWSIoTTopicRule_s3(rName string) string { return fmt.Sprintf(testAccAWSIoTTopicRuleRole+` resource "aws_iot_topic_rule" "rule" { From 586f2e85cb1187737a700975afa4f30042d89c72 Mon Sep 17 00:00:00 2001 From: drexler Date: Thu, 16 Apr 2020 22:47:50 -0400 Subject: [PATCH 017/475] docs: add documentation for Qos field --- website/docs/r/iot_topic_rule.html.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/website/docs/r/iot_topic_rule.html.markdown b/website/docs/r/iot_topic_rule.html.markdown index 0fd4f6ae5e7..c4eba6bfd25 100644 --- a/website/docs/r/iot_topic_rule.html.markdown +++ b/website/docs/r/iot_topic_rule.html.markdown @@ -133,6 +133,7 @@ The `republish` object takes the following arguments: * `role_arn` - (Required) The ARN of the IAM role that grants access. * `topic` - (Required) The name of the MQTT topic the message should be republished to. +* `qos` - (Optional) The Quality of Service (QoS) level to use when republishing messages. Valid values are 0 or 1. The default value is 0. The `s3` object takes the following arguments: From f5e09ff79bcef6101f5e9e8ec7ee7183589563c6 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 20 Apr 2020 17:18:16 -0400 Subject: [PATCH 018/475] r/aws_apigatewayv2_stage: Correctly handle diffs for HTTP API 'default_route_settings.logging_level' attribute, plus the special '$default' stage. --- ...ource_aws_apigatewayv2_api_mapping_test.go | 4 +- aws/resource_aws_apigatewayv2_stage.go | 47 ++++-- aws/resource_aws_apigatewayv2_stage_test.go | 151 ++++++++++++++++-- .../docs/r/apigatewayv2_stage.html.markdown | 2 +- 4 files changed, 175 insertions(+), 29 deletions(-) diff --git a/aws/resource_aws_apigatewayv2_api_mapping_test.go b/aws/resource_aws_apigatewayv2_api_mapping_test.go index c3d64e0e678..8658caea03c 100644 --- a/aws/resource_aws_apigatewayv2_api_mapping_test.go +++ b/aws/resource_aws_apigatewayv2_api_mapping_test.go @@ -264,7 +264,7 @@ resource "aws_apigatewayv2_domain_name" "test" { } func testAccAWSAPIGatewayV2ApiMappingConfig_basic(rName, certificateArn string) string { - return testAccAWSAPIGatewayV2ApiMappingConfig_base(rName, certificateArn) + testAccAWSAPIGatewayV2StageConfig_basic(rName) + fmt.Sprintf(` + return testAccAWSAPIGatewayV2ApiMappingConfig_base(rName, certificateArn) + testAccAWSAPIGatewayV2StageConfig_basicWebSocket(rName) + fmt.Sprintf(` resource "aws_apigatewayv2_api_mapping" "test" { api_id = "${aws_apigatewayv2_api.test.id}" domain_name = "${aws_apigatewayv2_domain_name.test.id}" @@ -274,7 +274,7 @@ resource "aws_apigatewayv2_api_mapping" "test" { } func testAccAWSAPIGatewayV2ApiMappingConfig_apiMappingKey(rName, certificateArn, apiMappingKey string) string { - return testAccAWSAPIGatewayV2ApiMappingConfig_base(rName, certificateArn) + testAccAWSAPIGatewayV2StageConfig_basic(rName) + fmt.Sprintf(` + return testAccAWSAPIGatewayV2ApiMappingConfig_base(rName, certificateArn) + testAccAWSAPIGatewayV2StageConfig_basicWebSocket(rName) + fmt.Sprintf(` resource "aws_apigatewayv2_api_mapping" "test" { api_id = "${aws_apigatewayv2_api.test.id}" domain_name = "${aws_apigatewayv2_domain_name.test.id}" diff --git a/aws/resource_aws_apigatewayv2_stage.go b/aws/resource_aws_apigatewayv2_stage.go index f6387966b05..778d8ee829a 100644 --- a/aws/resource_aws_apigatewayv2_stage.go +++ b/aws/resource_aws_apigatewayv2_stage.go @@ -15,6 +15,10 @@ import ( "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) +const ( + apigatewayv2DefaultStageName = "$default" +) + func resourceAwsApiGatewayV2Stage() *schema.Resource { return &schema.Resource{ Create: resourceAwsApiGatewayV2StageCreate, @@ -93,6 +97,13 @@ func resourceAwsApiGatewayV2Stage() *schema.Resource { apigatewayv2.LoggingLevelInfo, apigatewayv2.LoggingLevelOff, }, false), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + // Not set for HTTP APIs. + if old == "" && new == apigatewayv2.LoggingLevelOff { + return true + } + return false + }, }, "throttling_burst_limit": { Type: schema.TypeInt, @@ -260,15 +271,6 @@ func resourceAwsApiGatewayV2StageRead(d *schema.ResourceData, meta interface{}) } d.Set("deployment_id", resp.DeploymentId) d.Set("description", resp.Description) - executionArn := arn.ARN{ - Partition: meta.(*AWSClient).partition, - Service: "execute-api", - Region: region, - AccountID: meta.(*AWSClient).accountid, - Resource: fmt.Sprintf("%s/%s", apiId, stageName), - }.String() - d.Set("execution_arn", executionArn) - d.Set("invoke_url", fmt.Sprintf("wss://%s.execute-api.%s.amazonaws.com/%s", apiId, region, stageName)) d.Set("name", stageName) err = d.Set("route_settings", flattenApiGatewayV2RouteSettings(resp.RouteSettings)) if err != nil { @@ -282,6 +284,33 @@ func resourceAwsApiGatewayV2StageRead(d *schema.ResourceData, meta interface{}) return fmt.Errorf("error setting tags: %s", err) } + apiOutput, err := conn.GetApi(&apigatewayv2.GetApiInput{ + ApiId: aws.String(apiId), + }) + if err != nil { + return fmt.Errorf("error reading API Gateway v2 API (%s): %s", apiId, err) + } + + switch aws.StringValue(apiOutput.ProtocolType) { + case apigatewayv2.ProtocolTypeWebsocket: + executionArn := arn.ARN{ + Partition: meta.(*AWSClient).partition, + Service: "execute-api", + Region: region, + AccountID: meta.(*AWSClient).accountid, + Resource: fmt.Sprintf("%s/%s", apiId, stageName), + }.String() + d.Set("execution_arn", executionArn) + d.Set("invoke_url", fmt.Sprintf("wss://%s.execute-api.%s.amazonaws.com/%s", apiId, region, stageName)) + case apigatewayv2.ProtocolTypeHttp: + d.Set("execution_arn", "") + if stageName == apigatewayv2DefaultStageName { + d.Set("invoke_url", fmt.Sprintf("https://%s.execute-api.%s.amazonaws.com/", apiId, region)) + } else { + d.Set("invoke_url", fmt.Sprintf("https://%s.execute-api.%s.amazonaws.com/%s", apiId, region, stageName)) + } + } + return nil } diff --git a/aws/resource_aws_apigatewayv2_stage_test.go b/aws/resource_aws_apigatewayv2_stage_test.go index 85190779a37..495e99886c8 100644 --- a/aws/resource_aws_apigatewayv2_stage_test.go +++ b/aws/resource_aws_apigatewayv2_stage_test.go @@ -13,7 +13,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/terraform" ) -func TestAccAWSAPIGatewayV2Stage_basic(t *testing.T) { +func TestAccAWSAPIGatewayV2Stage_basicWebSocket(t *testing.T) { var apiId string var v apigatewayv2.GetStageOutput resourceName := "aws_apigatewayv2_stage.test" @@ -25,7 +25,7 @@ func TestAccAWSAPIGatewayV2Stage_basic(t *testing.T) { CheckDestroy: testAccCheckAWSAPIGatewayV2StageDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSAPIGatewayV2StageConfig_basic(rName), + Config: testAccAWSAPIGatewayV2StageConfig_basicWebSocket(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSAPIGatewayV2StageExists(resourceName, &apiId, &v), resource.TestCheckResourceAttr(resourceName, "access_log_settings.#", "0"), @@ -58,6 +58,96 @@ func TestAccAWSAPIGatewayV2Stage_basic(t *testing.T) { }) } +func TestAccAWSAPIGatewayV2Stage_basicHttp(t *testing.T) { + var apiId string + var v apigatewayv2.GetStageOutput + resourceName := "aws_apigatewayv2_stage.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSAPIGatewayV2StageDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSAPIGatewayV2StageConfig_basicHttp(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSAPIGatewayV2StageExists(resourceName, &apiId, &v), + resource.TestCheckResourceAttr(resourceName, "access_log_settings.#", "0"), + testAccMatchResourceAttrRegionalARNNoAccount(resourceName, "arn", "apigateway", regexp.MustCompile(fmt.Sprintf("/apis/.+/stages/%s", rName))), + resource.TestCheckResourceAttr(resourceName, "auto_deploy", "false"), + resource.TestCheckResourceAttr(resourceName, "client_certificate_id", ""), + resource.TestCheckResourceAttr(resourceName, "default_route_settings.#", "1"), + resource.TestCheckResourceAttr(resourceName, "default_route_settings.0.data_trace_enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "default_route_settings.0.detailed_metrics_enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "default_route_settings.0.logging_level", ""), + resource.TestCheckResourceAttr(resourceName, "default_route_settings.0.throttling_burst_limit", "0"), + resource.TestCheckResourceAttr(resourceName, "default_route_settings.0.throttling_rate_limit", "0"), + resource.TestCheckResourceAttr(resourceName, "deployment_id", ""), + resource.TestCheckResourceAttr(resourceName, "description", ""), + resource.TestCheckResourceAttr(resourceName, "execution_arn", ""), + resource.TestMatchResourceAttr(resourceName, "invoke_url", regexp.MustCompile(fmt.Sprintf("https://.+\\.execute-api\\.%s.amazonaws\\.com/%s", testAccGetRegion(), rName))), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "route_settings.#", "0"), + resource.TestCheckResourceAttr(resourceName, "stage_variables.%", "0"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportStateIdFunc: testAccAWSAPIGatewayV2StageImportStateIdFunc(resourceName), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSAPIGatewayV2Stage_defaultHttpStage(t *testing.T) { + var apiId string + var v apigatewayv2.GetStageOutput + resourceName := "aws_apigatewayv2_stage.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSAPIGatewayV2StageDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSAPIGatewayV2StageConfig_defaultHttpStage(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSAPIGatewayV2StageExists(resourceName, &apiId, &v), + resource.TestCheckResourceAttr(resourceName, "access_log_settings.#", "0"), + testAccMatchResourceAttrRegionalARNNoAccount(resourceName, "arn", "apigateway", regexp.MustCompile(`/apis/.+/stages/\$default`)), + resource.TestCheckResourceAttr(resourceName, "auto_deploy", "false"), + resource.TestCheckResourceAttr(resourceName, "client_certificate_id", ""), + resource.TestCheckResourceAttr(resourceName, "default_route_settings.#", "1"), + resource.TestCheckResourceAttr(resourceName, "default_route_settings.0.data_trace_enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "default_route_settings.0.detailed_metrics_enabled", "false"), + resource.TestCheckResourceAttr(resourceName, "default_route_settings.0.logging_level", ""), + resource.TestCheckResourceAttr(resourceName, "default_route_settings.0.throttling_burst_limit", "0"), + resource.TestCheckResourceAttr(resourceName, "default_route_settings.0.throttling_rate_limit", "0"), + resource.TestCheckResourceAttr(resourceName, "deployment_id", ""), + resource.TestCheckResourceAttr(resourceName, "description", ""), + resource.TestCheckResourceAttr(resourceName, "execution_arn", ""), + resource.TestMatchResourceAttr(resourceName, "invoke_url", regexp.MustCompile(fmt.Sprintf("https://.+\\.execute-api\\.%s.amazonaws\\.com/", testAccGetRegion()))), + resource.TestCheckResourceAttr(resourceName, "name", "$default"), + resource.TestCheckResourceAttr(resourceName, "route_settings.#", "0"), + resource.TestCheckResourceAttr(resourceName, "stage_variables.%", "0"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportStateIdFunc: testAccAWSAPIGatewayV2StageImportStateIdFunc(resourceName), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAWSAPIGatewayV2Stage_disappears(t *testing.T) { var apiId string var v apigatewayv2.GetStageOutput @@ -70,7 +160,7 @@ func TestAccAWSAPIGatewayV2Stage_disappears(t *testing.T) { CheckDestroy: testAccCheckAWSAPIGatewayV2StageDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSAPIGatewayV2StageConfig_basic(rName), + Config: testAccAWSAPIGatewayV2StageConfig_basicWebSocket(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSAPIGatewayV2StageExists(resourceName, &apiId, &v), testAccCheckAWSAPIGatewayV2StageDisappears(&apiId, &v), @@ -264,7 +354,7 @@ func TestAccAWSAPIGatewayV2Stage_DefaultRouteSettings(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccAWSAPIGatewayV2StageConfig_basic(rName), + Config: testAccAWSAPIGatewayV2StageConfig_basicWebSocket(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSAPIGatewayV2StageExists(resourceName, &apiId, &v), resource.TestCheckResourceAttr(resourceName, "access_log_settings.#", "0"), @@ -388,7 +478,7 @@ func TestAccAWSAPIGatewayV2Stage_RouteSettings(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccAWSAPIGatewayV2StageConfig_basic(rName), + Config: testAccAWSAPIGatewayV2StageConfig_basicWebSocket(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSAPIGatewayV2StageExists(resourceName, &apiId, &v), resource.TestCheckResourceAttr(resourceName, "access_log_settings.#", "0"), @@ -456,7 +546,7 @@ func TestAccAWSAPIGatewayV2Stage_StageVariables(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccAWSAPIGatewayV2StageConfig_basic(rName), + Config: testAccAWSAPIGatewayV2StageConfig_basicWebSocket(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSAPIGatewayV2StageExists(resourceName, &apiId, &v), resource.TestCheckResourceAttr(resourceName, "access_log_settings.#", "0"), @@ -524,7 +614,7 @@ func TestAccAWSAPIGatewayV2Stage_Tags(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccAWSAPIGatewayV2StageConfig_basic(rName), + Config: testAccAWSAPIGatewayV2StageConfig_basicWebSocket(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSAPIGatewayV2StageExists(resourceName, &apiId, &v), resource.TestCheckResourceAttr(resourceName, "access_log_settings.#", "0"), @@ -641,7 +731,7 @@ func testAccCheckAWSAPIGatewayV2StageAccessLogDestinationArn(resourceName, resou } } -func testAccAWSAPIGatewayV2StageConfig_api(rName string) string { +func testAccAWSAPIGatewayV2StageConfig_apiWebSocket(rName string) string { return fmt.Sprintf(` resource "aws_apigatewayv2_api" "test" { name = %[1]q @@ -651,8 +741,17 @@ resource "aws_apigatewayv2_api" "test" { `, rName) } -func testAccAWSAPIGatewayV2StageConfig_basic(rName string) string { - return testAccAWSAPIGatewayV2StageConfig_api(rName) + fmt.Sprintf(` +func testAccAWSAPIGatewayV2StageConfig_apiHttp(rName string) string { + return fmt.Sprintf(` +resource "aws_apigatewayv2_api" "test" { + name = %[1]q + protocol_type = "HTTP" +} +`, rName) +} + +func testAccAWSAPIGatewayV2StageConfig_basicWebSocket(rName string) string { + return testAccAWSAPIGatewayV2StageConfig_apiWebSocket(rName) + fmt.Sprintf(` resource "aws_apigatewayv2_stage" "test" { api_id = "${aws_apigatewayv2_api.test.id}" name = %[1]q @@ -660,8 +759,26 @@ resource "aws_apigatewayv2_stage" "test" { `, rName) } +func testAccAWSAPIGatewayV2StageConfig_basicHttp(rName string) string { + return testAccAWSAPIGatewayV2StageConfig_apiHttp(rName) + fmt.Sprintf(` +resource "aws_apigatewayv2_stage" "test" { + api_id = "${aws_apigatewayv2_api.test.id}" + name = %[1]q +} +`, rName) +} + +func testAccAWSAPIGatewayV2StageConfig_defaultHttpStage(rName string) string { + return testAccAWSAPIGatewayV2StageConfig_apiHttp(rName) + fmt.Sprintf(` +resource "aws_apigatewayv2_stage" "test" { + api_id = "${aws_apigatewayv2_api.test.id}" + name = "$default" +} +`) +} + func testAccAWSAPIGatewayV2StageConfig_accessLogSettings(rName, format string) string { - return testAccAWSAPIGatewayV2StageConfig_api(rName) + fmt.Sprintf(` + return testAccAWSAPIGatewayV2StageConfig_apiWebSocket(rName) + fmt.Sprintf(` resource "aws_iam_role" "test" { name = %[1]q @@ -724,7 +841,7 @@ resource "aws_apigatewayv2_stage" "test" { } func testAccAWSAPIGatewayV2StageConfig_clientCertificateIdAndDescription(rName string) string { - return testAccAWSAPIGatewayV2StageConfig_api(rName) + fmt.Sprintf(` + return testAccAWSAPIGatewayV2StageConfig_apiWebSocket(rName) + fmt.Sprintf(` resource "aws_api_gateway_client_certificate" "test" { description = %[1]q } @@ -740,7 +857,7 @@ resource "aws_apigatewayv2_stage" "test" { } func testAccAWSAPIGatewayV2StageConfig_clientCertificateIdAndDescriptionUpdated(rName string) string { - return testAccAWSAPIGatewayV2StageConfig_api(rName) + fmt.Sprintf(` + return testAccAWSAPIGatewayV2StageConfig_apiWebSocket(rName) + fmt.Sprintf(` resource "aws_api_gateway_client_certificate" "test" { description = %[1]q } @@ -756,7 +873,7 @@ resource "aws_apigatewayv2_stage" "test" { } func testAccAWSAPIGatewayV2StageConfig_defaultRouteSettings(rName string) string { - return testAccAWSAPIGatewayV2StageConfig_api(rName) + fmt.Sprintf(` + return testAccAWSAPIGatewayV2StageConfig_apiWebSocket(rName) + fmt.Sprintf(` resource "aws_apigatewayv2_stage" "test" { api_id = "${aws_apigatewayv2_api.test.id}" name = %[1]q @@ -784,7 +901,7 @@ resource "aws_apigatewayv2_stage" "test" { } func testAccAWSAPIGatewayV2StageConfig_routeSettings(rName string) string { - return testAccAWSAPIGatewayV2StageConfig_api(rName) + fmt.Sprintf(` + return testAccAWSAPIGatewayV2StageConfig_apiWebSocket(rName) + fmt.Sprintf(` resource "aws_apigatewayv2_stage" "test" { api_id = "${aws_apigatewayv2_api.test.id}" name = %[1]q @@ -807,7 +924,7 @@ resource "aws_apigatewayv2_stage" "test" { } func testAccAWSAPIGatewayV2StageConfig_stageVariables(rName string) string { - return testAccAWSAPIGatewayV2StageConfig_api(rName) + fmt.Sprintf(` + return testAccAWSAPIGatewayV2StageConfig_apiWebSocket(rName) + fmt.Sprintf(` resource "aws_apigatewayv2_stage" "test" { api_id = "${aws_apigatewayv2_api.test.id}" name = %[1]q @@ -821,7 +938,7 @@ resource "aws_apigatewayv2_stage" "test" { } func testAccAWSAPIGatewayV2StageConfig_tags(rName string) string { - return testAccAWSAPIGatewayV2StageConfig_api(rName) + fmt.Sprintf(` + return testAccAWSAPIGatewayV2StageConfig_apiWebSocket(rName) + fmt.Sprintf(` resource "aws_apigatewayv2_stage" "test" { api_id = "${aws_apigatewayv2_api.test.id}" name = %[1]q diff --git a/website/docs/r/apigatewayv2_stage.html.markdown b/website/docs/r/apigatewayv2_stage.html.markdown index 3fa9001331a..b870f9dbabc 100644 --- a/website/docs/r/apigatewayv2_stage.html.markdown +++ b/website/docs/r/apigatewayv2_stage.html.markdown @@ -76,7 +76,7 @@ In addition to all arguments above, the following attributes are exported: or in an [`aws_iam_policy`](/docs/providers/aws/r/iam_policy.html) to authorize access to the [`@connections` API](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-how-to-call-websocket-api-connections.html). See the [Amazon API Gateway Developer Guide](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-control-access-iam.html) for details. * `invoke_url` - The URL to invoke the API pointing to the stage, - e.g. `wss://z4675bid1j.execute-api.eu-west-2.amazonaws.com/example-stage` + e.g. `wss://z4675bid1j.execute-api.eu-west-2.amazonaws.com/example-stage`, or `https://z4675bid1j.execute-api.eu-west-2.amazonaws.com/` ## Import From 99afe7432873a787ff12b33ad37098ca4411e58f Mon Sep 17 00:00:00 2001 From: Micheal Harker Date: Thu, 16 Apr 2020 20:53:03 +0100 Subject: [PATCH 019/475] service/iam: replace custom SchemaValidateFunc with provided ones --- aws/resource_aws_iam_group.go | 13 ++------- aws/resource_aws_iam_group_test.go | 37 ------------------------ aws/resource_aws_iam_instance_profile.go | 29 ++----------------- aws/resource_aws_iam_policy.go | 29 ++----------------- aws/resource_aws_iam_role.go | 28 ++---------------- aws/resource_aws_iam_user.go | 12 +------- aws/resource_aws_iam_user_test.go | 37 ------------------------ 7 files changed, 11 insertions(+), 174 deletions(-) diff --git a/aws/resource_aws_iam_group.go b/aws/resource_aws_iam_group.go index 1e92696e4f3..7bd340b179a 100644 --- a/aws/resource_aws_iam_group.go +++ b/aws/resource_aws_iam_group.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/iam" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" ) func resourceAwsIamGroup() *schema.Resource { @@ -33,7 +34,7 @@ func resourceAwsIamGroup() *schema.Resource { "name": { Type: schema.TypeString, Required: true, - ValidateFunc: validateAwsIamGroupName, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[0-9A-Za-z=,.@\-_+]+$`), fmt.Sprintf("must only contain alphanumeric characters, hyphens, underscores, commas, periods, @ symbols, plus and equals signs")), }, "path": { Type: schema.TypeString, @@ -130,13 +131,3 @@ func resourceAwsIamGroupDelete(d *schema.ResourceData, meta interface{}) error { } return nil } - -func validateAwsIamGroupName(v interface{}, k string) (ws []string, errors []error) { - value := v.(string) - if !regexp.MustCompile(`^[0-9A-Za-z=,.@\-_+]+$`).MatchString(value) { - errors = append(errors, fmt.Errorf( - "only alphanumeric characters, hyphens, underscores, commas, periods, @ symbols, plus and equals signs allowed in %q: %q", - k, value)) - } - return -} diff --git a/aws/resource_aws_iam_group_test.go b/aws/resource_aws_iam_group_test.go index d51efa3effe..bca36220e26 100644 --- a/aws/resource_aws_iam_group_test.go +++ b/aws/resource_aws_iam_group_test.go @@ -13,43 +13,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/terraform" ) -func TestValidateIamGroupName(t *testing.T) { - validNames := []string{ - "test-group", - "test_group", - "testgroup123", - "TestGroup", - "Test-Group", - "test.group", - "test.123,group", - "testgroup@hashicorp", - "test+group@hashicorp.com", - } - for _, v := range validNames { - _, errs := validateAwsIamGroupName(v, "name") - if len(errs) != 0 { - t.Fatalf("%q should be a valid IAM Group name: %q", v, errs) - } - } - - invalidNames := []string{ - "!", - "/", - " ", - ":", - ";", - "test name", - "/slash-at-the-beginning", - "slash-at-the-end/", - } - for _, v := range invalidNames { - _, errs := validateAwsIamGroupName(v, "name") - if len(errs) == 0 { - t.Fatalf("%q should be an invalid IAM Group name", v) - } - } -} - func TestAccAWSIAMGroup_basic(t *testing.T) { var conf iam.GetGroupOutput resourceName := "aws_iam_group.test" diff --git a/aws/resource_aws_iam_instance_profile.go b/aws/resource_aws_iam_instance_profile.go index 1dbd2ebe371..2f6e931abb0 100644 --- a/aws/resource_aws_iam_instance_profile.go +++ b/aws/resource_aws_iam_instance_profile.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" ) func resourceAwsIamInstanceProfile() *schema.Resource { @@ -45,19 +46,7 @@ func resourceAwsIamInstanceProfile() *schema.Resource { Computed: true, ForceNew: true, ConflictsWith: []string{"name_prefix"}, - ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { - // https://github.com/boto/botocore/blob/2485f5c/botocore/data/iam/2010-05-08/service-2.json#L8196-L8201 - value := v.(string) - if len(value) > 128 { - errors = append(errors, fmt.Errorf( - "%q cannot be longer than 128 characters", k)) - } - if !regexp.MustCompile(`^[\w+=,.@-]+$`).MatchString(value) { - errors = append(errors, fmt.Errorf( - "%q must match [\\w+=,.@-]", k)) - } - return - }, + ValidateFunc: validation.All(validation.StringLenBetween(1, 128), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]")), }, "name_prefix": { @@ -65,19 +54,7 @@ func resourceAwsIamInstanceProfile() *schema.Resource { Optional: true, ForceNew: true, ConflictsWith: []string{"name"}, - ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { - // https://github.com/boto/botocore/blob/2485f5c/botocore/data/iam/2010-05-08/service-2.json#L8196-L8201 - value := v.(string) - if len(value) > 64 { - errors = append(errors, fmt.Errorf( - "%q cannot be longer than 64 characters, name is limited to 128", k)) - } - if !regexp.MustCompile(`^[\w+=,.@-]+$`).MatchString(value) { - errors = append(errors, fmt.Errorf( - "%q must match [\\w+=,.@-]", k)) - } - return - }, + ValidateFunc: validation.All(validation.StringLenBetween(1, 64), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]")), }, "path": { diff --git a/aws/resource_aws_iam_policy.go b/aws/resource_aws_iam_policy.go index 79185240f4a..561c82d2841 100644 --- a/aws/resource_aws_iam_policy.go +++ b/aws/resource_aws_iam_policy.go @@ -11,6 +11,7 @@ import ( "github.com/aws/aws-sdk-go/service/iam" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" ) func resourceAwsIamPolicy() *schema.Resource { @@ -47,38 +48,14 @@ func resourceAwsIamPolicy() *schema.Resource { Computed: true, ForceNew: true, ConflictsWith: []string{"name_prefix"}, - ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { - // https://github.com/boto/botocore/blob/2485f5c/botocore/data/iam/2010-05-08/service-2.json#L8329-L8334 - value := v.(string) - if len(value) > 128 { - errors = append(errors, fmt.Errorf( - "%q cannot be longer than 128 characters", k)) - } - if !regexp.MustCompile(`^[\w+=,.@-]*$`).MatchString(value) { - errors = append(errors, fmt.Errorf( - "%q must match [\\w+=,.@-]", k)) - } - return - }, + ValidateFunc: validation.All(validation.StringLenBetween(1, 128), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]")), }, "name_prefix": { Type: schema.TypeString, Optional: true, ForceNew: true, ConflictsWith: []string{"name"}, - ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { - // https://github.com/boto/botocore/blob/2485f5c/botocore/data/iam/2010-05-08/service-2.json#L8329-L8334 - value := v.(string) - if len(value) > 96 { - errors = append(errors, fmt.Errorf( - "%q cannot be longer than 96 characters, name is limited to 128", k)) - } - if !regexp.MustCompile(`^[\w+=,.@-]*$`).MatchString(value) { - errors = append(errors, fmt.Errorf( - "%q must match [\\w+=,.@-]", k)) - } - return - }, + ValidateFunc: validation.All(validation.StringLenBetween(1, 96), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]")), }, "arn": { Type: schema.TypeString, diff --git a/aws/resource_aws_iam_role.go b/aws/resource_aws_iam_role.go index 60f03f8dc02..501c7e87380 100644 --- a/aws/resource_aws_iam_role.go +++ b/aws/resource_aws_iam_role.go @@ -43,19 +43,7 @@ func resourceAwsIamRole() *schema.Resource { Computed: true, ForceNew: true, ConflictsWith: []string{"name_prefix"}, - ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { - // https://github.com/boto/botocore/blob/2485f5c/botocore/data/iam/2010-05-08/service-2.json#L8329-L8334 - value := v.(string) - if len(value) > 64 { - errors = append(errors, fmt.Errorf( - "%q cannot be longer than 64 characters", k)) - } - if !regexp.MustCompile(`^[\w+=,.@-]*$`).MatchString(value) { - errors = append(errors, fmt.Errorf( - "%q must match [\\w+=,.@-]", k)) - } - return - }, + ValidateFunc: validation.All(validation.StringLenBetween(1, 64), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]")), }, "name_prefix": { @@ -63,19 +51,7 @@ func resourceAwsIamRole() *schema.Resource { Optional: true, ForceNew: true, ConflictsWith: []string{"name"}, - ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { - // https://github.com/boto/botocore/blob/2485f5c/botocore/data/iam/2010-05-08/service-2.json#L8329-L8334 - value := v.(string) - if len(value) > 32 { - errors = append(errors, fmt.Errorf( - "%q cannot be longer than 32 characters, name is limited to 64", k)) - } - if !regexp.MustCompile(`^[\w+=,.@-]*$`).MatchString(value) { - errors = append(errors, fmt.Errorf( - "%q must match [\\w+=,.@-]", k)) - } - return - }, + ValidateFunc: validation.All(validation.StringLenBetween(1, 32), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]")), }, "path": { diff --git a/aws/resource_aws_iam_user.go b/aws/resource_aws_iam_user.go index 79d0fede53b..fabed2d35b0 100644 --- a/aws/resource_aws_iam_user.go +++ b/aws/resource_aws_iam_user.go @@ -45,7 +45,7 @@ func resourceAwsIamUser() *schema.Resource { "name": { Type: schema.TypeString, Required: true, - ValidateFunc: validateAwsIamUserName, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[0-9A-Za-z=,.@\-_+]+$`), fmt.Sprintf("must only contain alphanumeric characters, hyphens, underscores, commas, periods, @ symbols, plus and equals signs")), }, "path": { Type: schema.TypeString, @@ -244,16 +244,6 @@ func resourceAwsIamUserDelete(d *schema.ResourceData, meta interface{}) error { return nil } -func validateAwsIamUserName(v interface{}, k string) (ws []string, errors []error) { - value := v.(string) - if !regexp.MustCompile(`^[0-9A-Za-z=,.@\-_+]+$`).MatchString(value) { - errors = append(errors, fmt.Errorf( - "only alphanumeric characters, hyphens, underscores, commas, periods, @ symbols, plus and equals signs allowed in %q: %q", - k, value)) - } - return -} - func deleteAwsIamUserGroupMemberships(conn *iam.IAM, username string) error { var groups []string listGroups := &iam.ListGroupsForUserInput{ diff --git a/aws/resource_aws_iam_user_test.go b/aws/resource_aws_iam_user_test.go index eb6e2dad797..0a943e7ef0d 100644 --- a/aws/resource_aws_iam_user_test.go +++ b/aws/resource_aws_iam_user_test.go @@ -18,43 +18,6 @@ import ( "github.com/pquerna/otp/totp" ) -func TestValidateIamUserName(t *testing.T) { - validNames := []string{ - "test-user", - "test_user", - "testuser123", - "TestUser", - "Test-User", - "test.user", - "test.123,user", - "testuser@hashicorp", - "test+user@hashicorp.com", - } - for _, v := range validNames { - _, errors := validateAwsIamUserName(v, "name") - if len(errors) != 0 { - t.Fatalf("%q should be a valid IAM User name: %q", v, errors) - } - } - - invalidNames := []string{ - "!", - "/", - " ", - ":", - ";", - "test name", - "/slash-at-the-beginning", - "slash-at-the-end/", - } - for _, v := range invalidNames { - _, errors := validateAwsIamUserName(v, "name") - if len(errors) == 0 { - t.Fatalf("%q should be an invalid IAM User name", v) - } - } -} - func init() { resource.AddTestSweepers("aws_iam_user", &resource.Sweeper{ Name: "aws_iam_user", From a07d85330b059db5147933c69a89c23392bf11e9 Mon Sep 17 00:00:00 2001 From: Micheal Harker Date: Sat, 25 Apr 2020 12:37:17 +0100 Subject: [PATCH 020/475] service/iam: Clean up inlining mess I made. In hindsight, I figured it was better to try and reduce line length the best I can. --- aws/resource_aws_iam_group.go | 9 ++++++--- aws/resource_aws_iam_instance_profile.go | 10 ++++++++-- aws/resource_aws_iam_policy.go | 10 ++++++++-- aws/resource_aws_iam_role.go | 10 ++++++++-- aws/resource_aws_iam_user.go | 9 ++++++--- 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/aws/resource_aws_iam_group.go b/aws/resource_aws_iam_group.go index 7bd340b179a..f74fadc9dee 100644 --- a/aws/resource_aws_iam_group.go +++ b/aws/resource_aws_iam_group.go @@ -32,9 +32,12 @@ func resourceAwsIamGroup() *schema.Resource { Computed: true, }, "name": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[0-9A-Za-z=,.@\-_+]+$`), fmt.Sprintf("must only contain alphanumeric characters, hyphens, underscores, commas, periods, @ symbols, plus and equals signs")), + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile(`^[0-9A-Za-z=,.@\-_+]+$`), + fmt.Sprintf("must only contain alphanumeric characters, hyphens, underscores, commas, periods, @ symbols, plus and equals signs"), + ), }, "path": { Type: schema.TypeString, diff --git a/aws/resource_aws_iam_instance_profile.go b/aws/resource_aws_iam_instance_profile.go index 2f6e931abb0..caa7baad311 100644 --- a/aws/resource_aws_iam_instance_profile.go +++ b/aws/resource_aws_iam_instance_profile.go @@ -46,7 +46,10 @@ func resourceAwsIamInstanceProfile() *schema.Resource { Computed: true, ForceNew: true, ConflictsWith: []string{"name_prefix"}, - ValidateFunc: validation.All(validation.StringLenBetween(1, 128), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]")), + ValidateFunc: validation.All( + validation.StringLenBetween(1, 128), + validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]"), + ), }, "name_prefix": { @@ -54,7 +57,10 @@ func resourceAwsIamInstanceProfile() *schema.Resource { Optional: true, ForceNew: true, ConflictsWith: []string{"name"}, - ValidateFunc: validation.All(validation.StringLenBetween(1, 64), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]")), + ValidateFunc: validation.All( + validation.StringLenBetween(1, 64), + validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]"), + ), }, "path": { diff --git a/aws/resource_aws_iam_policy.go b/aws/resource_aws_iam_policy.go index 561c82d2841..6d803375ab1 100644 --- a/aws/resource_aws_iam_policy.go +++ b/aws/resource_aws_iam_policy.go @@ -48,14 +48,20 @@ func resourceAwsIamPolicy() *schema.Resource { Computed: true, ForceNew: true, ConflictsWith: []string{"name_prefix"}, - ValidateFunc: validation.All(validation.StringLenBetween(1, 128), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]")), + ValidateFunc: validation.All( + validation.StringLenBetween(1, 128), + validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]"), + ), }, "name_prefix": { Type: schema.TypeString, Optional: true, ForceNew: true, ConflictsWith: []string{"name"}, - ValidateFunc: validation.All(validation.StringLenBetween(1, 96), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]")), + ValidateFunc: validation.All( + validation.StringLenBetween(1, 96), + validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]"), + ), }, "arn": { Type: schema.TypeString, diff --git a/aws/resource_aws_iam_role.go b/aws/resource_aws_iam_role.go index 501c7e87380..ceb021f8f14 100644 --- a/aws/resource_aws_iam_role.go +++ b/aws/resource_aws_iam_role.go @@ -43,7 +43,10 @@ func resourceAwsIamRole() *schema.Resource { Computed: true, ForceNew: true, ConflictsWith: []string{"name_prefix"}, - ValidateFunc: validation.All(validation.StringLenBetween(1, 64), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]")), + ValidateFunc: validation.All( + validation.StringLenBetween(1, 64), + validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]"), + ), }, "name_prefix": { @@ -51,7 +54,10 @@ func resourceAwsIamRole() *schema.Resource { Optional: true, ForceNew: true, ConflictsWith: []string{"name"}, - ValidateFunc: validation.All(validation.StringLenBetween(1, 32), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]")), + ValidateFunc: validation.All( + validation.StringLenBetween(1, 32), + validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]"), + ), }, "path": { diff --git a/aws/resource_aws_iam_user.go b/aws/resource_aws_iam_user.go index fabed2d35b0..be5ba909ea8 100644 --- a/aws/resource_aws_iam_user.go +++ b/aws/resource_aws_iam_user.go @@ -43,9 +43,12 @@ func resourceAwsIamUser() *schema.Resource { Computed: true, }, "name": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[0-9A-Za-z=,.@\-_+]+$`), fmt.Sprintf("must only contain alphanumeric characters, hyphens, underscores, commas, periods, @ symbols, plus and equals signs")), + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile(`^[0-9A-Za-z=,.@\-_+]+$`), + fmt.Sprintf("must only contain alphanumeric characters, hyphens, underscores, commas, periods, @ symbols, plus and equals signs"), + ), }, "path": { Type: schema.TypeString, From 2cab2bdccc2e30c049b2341508dfffdcb58f0a9f Mon Sep 17 00:00:00 2001 From: Micheal Harker Date: Sat, 25 Apr 2020 21:07:15 +0100 Subject: [PATCH 021/475] service/vpn: tech debt: replace custom validation functions --- aws/resource_aws_vpn_connection.go | 81 +++++++++---------------- aws/resource_aws_vpn_connection_test.go | 23 +++---- 2 files changed, 39 insertions(+), 65 deletions(-) diff --git a/aws/resource_aws_vpn_connection.go b/aws/resource_aws_vpn_connection.go index 7a4d268284f..80698fe8921 100644 --- a/aws/resource_aws_vpn_connection.go +++ b/aws/resource_aws_vpn_connection.go @@ -5,10 +5,8 @@ import ( "encoding/xml" "fmt" "log" - "net" "regexp" "sort" - "strings" "time" "github.com/aws/aws-sdk-go/aws" @@ -17,6 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/hashcode" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) @@ -114,7 +113,7 @@ func resourceAwsVpnConnection() *schema.Resource { Optional: true, Computed: true, ForceNew: true, - ValidateFunc: validateVpnConnectionTunnelInsideCIDR, + ValidateFunc: validateVpnConnectionTunnelInsideCIDR(), }, "tunnel1_preshared_key": { @@ -123,7 +122,7 @@ func resourceAwsVpnConnection() *schema.Resource { Sensitive: true, Computed: true, ForceNew: true, - ValidateFunc: validateVpnConnectionTunnelPreSharedKey, + ValidateFunc: validateVpnConnectionTunnelPreSharedKey(), }, "tunnel2_inside_cidr": { @@ -131,7 +130,7 @@ func resourceAwsVpnConnection() *schema.Resource { Optional: true, Computed: true, ForceNew: true, - ValidateFunc: validateVpnConnectionTunnelInsideCIDR, + ValidateFunc: validateVpnConnectionTunnelInsideCIDR(), }, "tunnel2_preshared_key": { @@ -140,7 +139,7 @@ func resourceAwsVpnConnection() *schema.Resource { Sensitive: true, Computed: true, ForceNew: true, - ValidateFunc: validateVpnConnectionTunnelPreSharedKey, + ValidateFunc: validateVpnConnectionTunnelPreSharedKey(), }, "tags": tagsSchema(), @@ -618,55 +617,29 @@ func xmlConfigToTunnelInfo(xmlConfig string) (*TunnelInfo, error) { return &tunnelInfo, nil } -func validateVpnConnectionTunnelPreSharedKey(v interface{}, k string) (ws []string, errors []error) { - value := v.(string) - - if (len(value) < 8) || (len(value) > 64) { - errors = append(errors, fmt.Errorf("%q must be between 8 and 64 characters in length", k)) - } - - if strings.HasPrefix(value, "0") { - errors = append(errors, fmt.Errorf("%q cannot start with zero character", k)) - } - - if !regexp.MustCompile(`^[0-9a-zA-Z_.]+$`).MatchString(value) { - errors = append(errors, fmt.Errorf("%q can only contain alphanumeric, period and underscore characters", k)) - } - - return +func validateVpnConnectionTunnelPreSharedKey() schema.SchemaValidateFunc { + return validation.All( + validation.StringLenBetween(8, 64), + validation.StringDoesNotMatch(regexp.MustCompile(`(?i)^0`), "cannot start with zero character"), + validation.StringMatch(regexp.MustCompile(`^[0-9a-zA-Z_.]+$`), "can only contain alphanumeric, period and underscore characters"), + ) } // https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_VpnTunnelOptionsSpecification.html -func validateVpnConnectionTunnelInsideCIDR(v interface{}, k string) (ws []string, errors []error) { - value := v.(string) - _, ipnet, err := net.ParseCIDR(value) - - if err != nil { - errors = append(errors, fmt.Errorf("%q must contain a valid CIDR, got error parsing: %s", k, err)) - return - } - - if !strings.HasSuffix(ipnet.String(), "/30") { - errors = append(errors, fmt.Errorf("%q must be /30 CIDR", k)) - } - - if !strings.HasPrefix(ipnet.String(), "169.254.") { - errors = append(errors, fmt.Errorf("%q must be within 169.254.0.0/16", k)) - } else if ipnet.String() == "169.254.0.0/30" { - errors = append(errors, fmt.Errorf("%q cannot be 169.254.0.0/30", k)) - } else if ipnet.String() == "169.254.1.0/30" { - errors = append(errors, fmt.Errorf("%q cannot be 169.254.1.0/30", k)) - } else if ipnet.String() == "169.254.2.0/30" { - errors = append(errors, fmt.Errorf("%q cannot be 169.254.2.0/30", k)) - } else if ipnet.String() == "169.254.3.0/30" { - errors = append(errors, fmt.Errorf("%q cannot be 169.254.3.0/30", k)) - } else if ipnet.String() == "169.254.4.0/30" { - errors = append(errors, fmt.Errorf("%q cannot be 169.254.4.0/30", k)) - } else if ipnet.String() == "169.254.5.0/30" { - errors = append(errors, fmt.Errorf("%q cannot be 169.254.5.0/30", k)) - } else if ipnet.String() == "169.254.169.252/30" { - errors = append(errors, fmt.Errorf("%q cannot be 169.254.169.252/30", k)) - } - - return +func validateVpnConnectionTunnelInsideCIDR() schema.SchemaValidateFunc { + disallowedCidrs := []string{ + "169.254.0.0/30", + "169.254.1.0/30", + "169.254.2.0/30", + "169.254.3.0/30", + "169.254.4.0/30", + "169.254.5.0/30", + "169.254.169.252/30", + } + + return validation.All( + validation.IsCIDRNetwork(30, 30), + validation.StringMatch(regexp.MustCompile(`^169\.254\.`), "must be within 169.254.0.0/16"), + validation.StringNotInSlice(disallowedCidrs, false), + ) } diff --git a/aws/resource_aws_vpn_connection_test.go b/aws/resource_aws_vpn_connection_test.go index 387b9923fe7..efd8c4d263a 100644 --- a/aws/resource_aws_vpn_connection_test.go +++ b/aws/resource_aws_vpn_connection_test.go @@ -139,6 +139,7 @@ func TestAccAWSVpnConnection_TransitGatewayID(t *testing.T) { } func TestAccAWSVpnConnection_tunnelOptions(t *testing.T) { + badCidrRangeErr := regexp.MustCompile(`expected \w+ to not be any of \[[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/30\s?]+\]`) rBgpAsn := acctest.RandIntRange(64512, 65534) resourceName := "aws_vpn_connection.test" var vpn ec2.VpnConnection @@ -153,11 +154,11 @@ func TestAccAWSVpnConnection_tunnelOptions(t *testing.T) { // Checking CIDR blocks { Config: testAccAwsVpnConnectionConfigSingleTunnelOptions(rBgpAsn, "12345678", "not-a-cidr"), - ExpectError: regexp.MustCompile(`must contain a valid CIDR`), + ExpectError: regexp.MustCompile(`invalid CIDR address: not-a-cidr`), }, { Config: testAccAwsVpnConnectionConfigSingleTunnelOptions(rBgpAsn, "12345678", "169.254.254.0/31"), - ExpectError: regexp.MustCompile(`must be /30 CIDR`), + ExpectError: regexp.MustCompile(`expected "\w+" to contain a network Value with between 30 and 30 significant bits`), }, { Config: testAccAwsVpnConnectionConfigSingleTunnelOptions(rBgpAsn, "12345678", "172.16.0.0/30"), @@ -165,41 +166,41 @@ func TestAccAWSVpnConnection_tunnelOptions(t *testing.T) { }, { Config: testAccAwsVpnConnectionConfigSingleTunnelOptions(rBgpAsn, "12345678", "169.254.0.0/30"), - ExpectError: regexp.MustCompile(`cannot be 169.254.0.0/30`), + ExpectError: badCidrRangeErr, }, { Config: testAccAwsVpnConnectionConfigSingleTunnelOptions(rBgpAsn, "12345678", "169.254.1.0/30"), - ExpectError: regexp.MustCompile(`cannot be 169.254.1.0/30`), + ExpectError: badCidrRangeErr, }, { Config: testAccAwsVpnConnectionConfigSingleTunnelOptions(rBgpAsn, "12345678", "169.254.2.0/30"), - ExpectError: regexp.MustCompile(`cannot be 169.254.2.0/30`), + ExpectError: badCidrRangeErr, }, { Config: testAccAwsVpnConnectionConfigSingleTunnelOptions(rBgpAsn, "12345678", "169.254.3.0/30"), - ExpectError: regexp.MustCompile(`cannot be 169.254.3.0/30`), + ExpectError: badCidrRangeErr, }, { Config: testAccAwsVpnConnectionConfigSingleTunnelOptions(rBgpAsn, "12345678", "169.254.4.0/30"), - ExpectError: regexp.MustCompile(`cannot be 169.254.4.0/30`), + ExpectError: badCidrRangeErr, }, { Config: testAccAwsVpnConnectionConfigSingleTunnelOptions(rBgpAsn, "12345678", "169.254.5.0/30"), - ExpectError: regexp.MustCompile(`cannot be 169.254.5.0/30`), + ExpectError: badCidrRangeErr, }, { Config: testAccAwsVpnConnectionConfigSingleTunnelOptions(rBgpAsn, "12345678", "169.254.169.252/30"), - ExpectError: regexp.MustCompile(`cannot be 169.254.169.252/30`), + ExpectError: badCidrRangeErr, }, // Checking PreShared Key { Config: testAccAwsVpnConnectionConfigSingleTunnelOptions(rBgpAsn, "1234567", "169.254.254.0/30"), - ExpectError: regexp.MustCompile(`must be between 8 and 64 characters in length`), + ExpectError: regexp.MustCompile(`expected length of \w+ to be in the range \(8 - 64\)`), }, { Config: testAccAwsVpnConnectionConfigSingleTunnelOptions(rBgpAsn, acctest.RandStringFromCharSet(65, acctest.CharSetAlpha), "169.254.254.0/30"), - ExpectError: regexp.MustCompile(`must be between 8 and 64 characters in length`), + ExpectError: regexp.MustCompile(`expected length of \w+ to be in the range \(8 - 64\)`), }, { Config: testAccAwsVpnConnectionConfigSingleTunnelOptions(rBgpAsn, "01234567", "169.254.254.0/30"), From 114ff7a54f03951b81fb80d7b03f165dc3280cb8 Mon Sep 17 00:00:00 2001 From: Micheal Harker Date: Tue, 28 Apr 2020 18:36:14 +0100 Subject: [PATCH 022/475] Format code --- aws/resource_aws_iam_instance_profile.go | 8 ++++---- aws/resource_aws_iam_policy.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/aws/resource_aws_iam_instance_profile.go b/aws/resource_aws_iam_instance_profile.go index caa7baad311..b5d0ca55e01 100644 --- a/aws/resource_aws_iam_instance_profile.go +++ b/aws/resource_aws_iam_instance_profile.go @@ -46,8 +46,8 @@ func resourceAwsIamInstanceProfile() *schema.Resource { Computed: true, ForceNew: true, ConflictsWith: []string{"name_prefix"}, - ValidateFunc: validation.All( - validation.StringLenBetween(1, 128), + ValidateFunc: validation.All( + validation.StringLenBetween(1, 128), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]"), ), }, @@ -57,8 +57,8 @@ func resourceAwsIamInstanceProfile() *schema.Resource { Optional: true, ForceNew: true, ConflictsWith: []string{"name"}, - ValidateFunc: validation.All( - validation.StringLenBetween(1, 64), + ValidateFunc: validation.All( + validation.StringLenBetween(1, 64), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]"), ), }, diff --git a/aws/resource_aws_iam_policy.go b/aws/resource_aws_iam_policy.go index 6d803375ab1..f51a2a61524 100644 --- a/aws/resource_aws_iam_policy.go +++ b/aws/resource_aws_iam_policy.go @@ -48,7 +48,7 @@ func resourceAwsIamPolicy() *schema.Resource { Computed: true, ForceNew: true, ConflictsWith: []string{"name_prefix"}, - ValidateFunc: validation.All( + ValidateFunc: validation.All( validation.StringLenBetween(1, 128), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]"), ), @@ -58,7 +58,7 @@ func resourceAwsIamPolicy() *schema.Resource { Optional: true, ForceNew: true, ConflictsWith: []string{"name"}, - ValidateFunc: validation.All( + ValidateFunc: validation.All( validation.StringLenBetween(1, 96), validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]*$`), "must match [\\w+=,.@-]"), ), From 34e16be6612f22ff3d6ec7bc7408cf46f74d2375 Mon Sep 17 00:00:00 2001 From: Mike Dalrymple Date: Tue, 28 Apr 2020 20:48:21 -0600 Subject: [PATCH 023/475] Clarified options for `email_sending_account` and associated `source_arn`. Updated `from_email_address` formatting to properly display in generated pages and replaced smith.com with example.com. --- website/docs/r/cognito_user_pool.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/docs/r/cognito_user_pool.markdown b/website/docs/r/cognito_user_pool.markdown index 63aaa512cf8..0e1d250a212 100644 --- a/website/docs/r/cognito_user_pool.markdown +++ b/website/docs/r/cognito_user_pool.markdown @@ -89,9 +89,9 @@ The following arguments are supported: #### Email Configuration * `reply_to_email_address` (Optional) - The REPLY-TO email address. - * `source_arn` (Optional) - The ARN of the email source. - * `from_email_address` (Optional) - Sender’s email address or sender’s name with their email address (e.g. "john@smith.com" or "John Smith ") - * `email_sending_account` (Optional) - Instruct Cognito to either use its built-in functional or Amazon SES to send out emails. + * `source_arn` (Optional) - The ARN of the SES verified email identity to to use. Required if `email_sending_account` is set to `DEVELOPER`. + * `from_email_address` (Optional) - Sender’s email address or sender’s name with their email address (e.g. "john@example.com" or "John Smith <john@example.com>") + * `email_sending_account` (Optional) - The email delivery method to use. `COGNITO_DEFAULT` for the default email functionality built into Cognito or `DEVELOPER` to use your Amazon SES configuration. #### Lambda Configuration From 69312e357f8b1d81e62deeafa56ee0f0b0711c99 Mon Sep 17 00:00:00 2001 From: Pascal van Buijtene Date: Thu, 16 Jan 2020 11:38:23 +0100 Subject: [PATCH 024/475] Basic functionality --- aws/provider.go | 1 + aws/resource_aws_wafv2_ip_set.go | 191 ++++++++++++++++++++++++++ aws/resource_aws_wafv2_ip_set_test.go | 116 ++++++++++++++++ 3 files changed, 308 insertions(+) create mode 100644 aws/resource_aws_wafv2_ip_set.go create mode 100644 aws/resource_aws_wafv2_ip_set_test.go diff --git a/aws/provider.go b/aws/provider.go index 6a1e1e768bf..6801fabe536 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -881,6 +881,7 @@ func Provider() terraform.ResourceProvider { "aws_wafregional_xss_match_set": resourceAwsWafRegionalXssMatchSet(), "aws_wafregional_web_acl": resourceAwsWafRegionalWebAcl(), "aws_wafregional_web_acl_association": resourceAwsWafRegionalWebAclAssociation(), + "aws_wafv2_ip_set": resourceAwsWafv2IPSet(), "aws_worklink_fleet": resourceAwsWorkLinkFleet(), "aws_worklink_website_certificate_authority_association": resourceAwsWorkLinkWebsiteCertificateAuthorityAssociation(), "aws_workspaces_directory": resourceAwsWorkspacesDirectory(), diff --git a/aws/resource_aws_wafv2_ip_set.go b/aws/resource_aws_wafv2_ip_set.go new file mode 100644 index 00000000000..a526ce6246e --- /dev/null +++ b/aws/resource_aws_wafv2_ip_set.go @@ -0,0 +1,191 @@ +package aws + +import ( + "fmt" + "github.com/aws/aws-sdk-go/service/wafv2" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "log" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func resourceAwsWafv2IPSet() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsWafv2IPSetCreate, + Read: resourceAwsWafv2IPSetRead, + Update: resourceAwsWafv2IPSetUpdate, + Delete: resourceAwsWafv2IPSetDelete, + + Schema: map[string]*schema.Schema{ + "addresses": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "ip_address_version": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + wafv2.IPAddressVersionIpv4, + wafv2.IPAddressVersionIpv6, + }, false), + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "scope": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + wafv2.ScopeCloudfront, + wafv2.ScopeRegional, + }, false), + }, + "tags": tagsSchema(), + }, + } +} + +func resourceAwsWafv2IPSetCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).wafv2conn + var resp *wafv2.CreateIPSetOutput + + params := &wafv2.CreateIPSetInput{ + Addresses: expandStringSet(d.Get("addresses").(*schema.Set)), + Description: aws.String(d.Get("description").(string)), + IPAddressVersion: aws.String(d.Get("ip_address_version").(string)), + Name: aws.String(d.Get("name").(string)), + Scope: aws.String(d.Get("scope").(string)), + } + err := resource.Retry(15*time.Minute, func() *resource.RetryError { + var err error + resp, err = conn.CreateIPSet(params) + if err != nil { + if isAWSErr(err, wafv2.ErrCodeWAFInternalErrorException, "AWS WAF couldn’t perform the operation because of a system problem") { + return resource.RetryableError(err) + } + if isAWSErr(err, wafv2.ErrCodeWAFTagOperationException, "An error occurred during the tagging operation") { + return resource.RetryableError(err) + } + if isAWSErr(err, wafv2.ErrCodeWAFTagOperationInternalErrorException, "AWS WAF couldn’t perform your tagging operation because of an internal error") { + return resource.RetryableError(err) + } + if isAWSErr(err, wafv2.ErrCodeWAFOptimisticLockException, "AWS WAF couldn’t save your changes because you tried to update or delete a resource that has changed since you last retrieved it") { + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + if isResourceTimeoutError(err) { + _, err = conn.CreateIPSet(params) + } + if err != nil { + return err + } + d.SetId(*resp.Summary.Id) + + return resourceAwsWafv2IPSetRead(d, meta) +} + +func resourceAwsWafv2IPSetRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).wafv2conn + + params := &wafv2.GetIPSetInput{ + Id: aws.String(d.Id()), + Name: aws.String(d.Get("name").(string)), + Scope: aws.String(d.Get("scope").(string)), + } + + resp, err := conn.GetIPSet(params) + if err != nil { + if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == wafv2.ErrCodeWAFNonexistentItemException { + log.Printf("[WARN] WAFV2 IPSet (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + return err + } + + d.Set("name", resp.IPSet.Name) + d.Set("description", resp.IPSet.Description) + d.Set("ip_address_version", resp.IPSet.IPAddressVersion) + d.Set("addresses", resp.IPSet.Addresses) + d.Set("arn", resp.IPSet.ARN) + + return nil +} + +func resourceAwsWafv2IPSetUpdate(d *schema.ResourceData, meta interface{}) error { + return resourceAwsWafv2IPSetRead(d, meta) +} + +func resourceAwsWafv2IPSetDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).wafv2conn + var resp *wafv2.GetIPSetOutput + params := &wafv2.GetIPSetInput{ + Id: aws.String(d.Id()), + Name: aws.String(d.Get("name").(string)), + Scope: aws.String(d.Get("scope").(string)), + } + log.Printf("[INFO] Deleting WAFV2 IPSet %s", d.Id()) + + err := resource.Retry(15*time.Minute, func() *resource.RetryError { + var err error + resp, err = conn.GetIPSet(params) + if err != nil { + return resource.NonRetryableError(fmt.Errorf("Error getting lock token: %s", err)) + } + + _, err = conn.DeleteIPSet(&wafv2.DeleteIPSetInput{ + Id: aws.String(d.Id()), + Name: aws.String(d.Get("name").(string)), + Scope: aws.String(d.Get("scope").(string)), + LockToken: resp.LockToken, + }) + + if err != nil { + if isAWSErr(err, wafv2.ErrCodeWAFInternalErrorException, "AWS WAF couldn’t perform the operation because of a system problem") { + return resource.RetryableError(err) + } + if isAWSErr(err, wafv2.ErrCodeWAFOptimisticLockException, "AWS WAF couldn’t save your changes because you tried to update or delete a resource that has changed since you last retrieved it") { + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + + if isResourceTimeoutError(err) { + _, err = conn.DeleteIPSet(&wafv2.DeleteIPSetInput{ + Id: aws.String(d.Id()), + Name: aws.String(d.Get("name").(string)), + Scope: aws.String(d.Get("scope").(string)), + LockToken: resp.LockToken, + }) + } + + if err != nil { + return fmt.Errorf("Error deleting WAFV2 IPSet: %s", err) + } + + return nil +} diff --git a/aws/resource_aws_wafv2_ip_set_test.go b/aws/resource_aws_wafv2_ip_set_test.go new file mode 100644 index 00000000000..01dc52d1ae2 --- /dev/null +++ b/aws/resource_aws_wafv2_ip_set_test.go @@ -0,0 +1,116 @@ +package aws + +import ( + "fmt" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/wafv2" + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + + "github.com/aws/aws-sdk-go/aws" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" +) + +func TestAccAwsWafv2IPSet_basic(t *testing.T) { + var v wafv2.IPSet + ipSetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5)) + resourceName := "aws_wafv2_ip_set.ip_set" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSWafv2IPSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsWafv2IPSetConfig(ipSetName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)), + resource.TestCheckResourceAttr(resourceName, "name", ipSetName), + resource.TestCheckResourceAttr(resourceName, "description", ipSetName), + resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional), + resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4), + ), + }, + }, + }) +} + +func testAccCheckAWSWafv2IPSetDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_wafv2_ip_set" { + continue + } + + conn := testAccProvider.Meta().(*AWSClient).wafv2conn + resp, err := conn.GetIPSet( + &wafv2.GetIPSetInput{ + Id: aws.String(rs.Primary.ID), + Name: aws.String(rs.Primary.Attributes["name"]), + Scope: aws.String(rs.Primary.Attributes["scope"]), + }) + + if err == nil { + if *resp.IPSet.Id == rs.Primary.ID { + return fmt.Errorf("WAFV2 IPSet %s still exists", rs.Primary.ID) + } + } + + // Return nil if the IPSet is already destroyed + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == wafv2.ErrCodeWAFNonexistentItemException { + return nil + } + } + + return err + } + + return nil +} + +func testAccCheckAWSWafv2IPSetExists(n string, v *wafv2.IPSet) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No WAFV2 IPSet ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).wafv2conn + resp, err := conn.GetIPSet(&wafv2.GetIPSetInput{ + Id: aws.String(rs.Primary.ID), + Name: aws.String(rs.Primary.Attributes["name"]), + Scope: aws.String(rs.Primary.Attributes["scope"]), + }) + + if err != nil { + return err + } + + if *resp.IPSet.Id == rs.Primary.ID { + *v = *resp.IPSet + return nil + } + + return fmt.Errorf("WAFV2 IPSet (%s) not found", rs.Primary.ID) + } +} + +func testAccAwsWafv2IPSetConfig(name string) string { + return fmt.Sprintf(` +resource "aws_wafv2_ip_set" "ip_set" { + name = "%s" + description = "%s" + scope = "REGIONAL" + ip_address_version = "IPV4" + addresses = ["1.2.3.4/32", "5.6.7.8/32"] +} +`, name, name) +} From 5bbb31f61291618a9890e90241ec16bcd4e87bb6 Mon Sep 17 00:00:00 2001 From: Pascal van Buijtene Date: Fri, 17 Jan 2020 17:08:39 +0100 Subject: [PATCH 025/475] Fix addresses --- aws/resource_aws_wafv2_ip_set.go | 9 +++++---- aws/resource_aws_wafv2_ip_set_test.go | 3 +++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/aws/resource_aws_wafv2_ip_set.go b/aws/resource_aws_wafv2_ip_set.go index a526ce6246e..86440355f6d 100644 --- a/aws/resource_aws_wafv2_ip_set.go +++ b/aws/resource_aws_wafv2_ip_set.go @@ -22,8 +22,8 @@ func resourceAwsWafv2IPSet() *schema.Resource { Schema: map[string]*schema.Schema{ "addresses": { - Type: schema.TypeSet, - Required: true, + Type: schema.TypeList, + Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "arn": { @@ -68,12 +68,13 @@ func resourceAwsWafv2IPSetCreate(d *schema.ResourceData, meta interface{}) error var resp *wafv2.CreateIPSetOutput params := &wafv2.CreateIPSetInput{ - Addresses: expandStringSet(d.Get("addresses").(*schema.Set)), + Addresses: expandStringList(d.Get("addresses").([]interface{})), Description: aws.String(d.Get("description").(string)), IPAddressVersion: aws.String(d.Get("ip_address_version").(string)), Name: aws.String(d.Get("name").(string)), Scope: aws.String(d.Get("scope").(string)), } + err := resource.Retry(15*time.Minute, func() *resource.RetryError { var err error resp, err = conn.CreateIPSet(params) @@ -128,8 +129,8 @@ func resourceAwsWafv2IPSetRead(d *schema.ResourceData, meta interface{}) error { d.Set("name", resp.IPSet.Name) d.Set("description", resp.IPSet.Description) d.Set("ip_address_version", resp.IPSet.IPAddressVersion) - d.Set("addresses", resp.IPSet.Addresses) d.Set("arn", resp.IPSet.ARN) + d.Set("addresses", flattenStringList(resp.IPSet.Addresses)) return nil } diff --git a/aws/resource_aws_wafv2_ip_set_test.go b/aws/resource_aws_wafv2_ip_set_test.go index 01dc52d1ae2..82406b35d35 100644 --- a/aws/resource_aws_wafv2_ip_set_test.go +++ b/aws/resource_aws_wafv2_ip_set_test.go @@ -33,6 +33,9 @@ func TestAccAwsWafv2IPSet_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "description", ipSetName), resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional), resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4), + resource.TestCheckResourceAttr(resourceName, "addresses.#", "2"), + resource.TestCheckResourceAttr(resourceName, "addresses.0", "1.2.3.4/32"), + resource.TestCheckResourceAttr(resourceName, "addresses.1", "5.6.7.8/32"), ), }, }, From cfa3efc25faa02cb55efe704d3fdc8e516cdf247 Mon Sep 17 00:00:00 2001 From: Pascal van Buijtene Date: Thu, 23 Jan 2020 17:12:52 +0100 Subject: [PATCH 026/475] Add update --- aws/resource_aws_wafv2_ip_set.go | 93 ++++++++++++++++++++++++--- aws/resource_aws_wafv2_ip_set_test.go | 62 +++++++++++++++++- 2 files changed, 143 insertions(+), 12 deletions(-) diff --git a/aws/resource_aws_wafv2_ip_set.go b/aws/resource_aws_wafv2_ip_set.go index 86440355f6d..6eca7cf99ae 100644 --- a/aws/resource_aws_wafv2_ip_set.go +++ b/aws/resource_aws_wafv2_ip_set.go @@ -22,8 +22,10 @@ func resourceAwsWafv2IPSet() *schema.Resource { Schema: map[string]*schema.Schema{ "addresses": { - Type: schema.TypeList, + Type: schema.TypeSet, Optional: true, + MinItems: 1, + MaxItems: 50, Elem: &schema.Schema{Type: schema.TypeString}, }, "arn": { @@ -31,9 +33,9 @@ func resourceAwsWafv2IPSet() *schema.Resource { Computed: true, }, "description": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(1, 256), }, "ip_address_version": { Type: schema.TypeString, @@ -45,9 +47,10 @@ func resourceAwsWafv2IPSet() *schema.Resource { }, false), }, "name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 128), }, "scope": { Type: schema.TypeString, @@ -68,13 +71,20 @@ func resourceAwsWafv2IPSetCreate(d *schema.ResourceData, meta interface{}) error var resp *wafv2.CreateIPSetOutput params := &wafv2.CreateIPSetInput{ - Addresses: expandStringList(d.Get("addresses").([]interface{})), - Description: aws.String(d.Get("description").(string)), + Addresses: []*string{}, IPAddressVersion: aws.String(d.Get("ip_address_version").(string)), Name: aws.String(d.Get("name").(string)), Scope: aws.String(d.Get("scope").(string)), } + if v, ok := d.GetOk("addresses"); ok && v.(*schema.Set).Len() > 0 { + params.Addresses = expandStringSet(d.Get("addresses").(*schema.Set)) + } + + if d.HasChange("description") { + params.Description = aws.String(d.Get("description").(string)) + } + err := resource.Retry(15*time.Minute, func() *resource.RetryError { var err error resp, err = conn.CreateIPSet(params) @@ -130,12 +140,75 @@ func resourceAwsWafv2IPSetRead(d *schema.ResourceData, meta interface{}) error { d.Set("description", resp.IPSet.Description) d.Set("ip_address_version", resp.IPSet.IPAddressVersion) d.Set("arn", resp.IPSet.ARN) - d.Set("addresses", flattenStringList(resp.IPSet.Addresses)) + + if err := d.Set("addresses", schema.NewSet(schema.HashString, flattenStringList(resp.IPSet.Addresses))); err != nil { + return fmt.Errorf("Error setting addresses: %s", err) + } return nil } func resourceAwsWafv2IPSetUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).wafv2conn + var resp *wafv2.GetIPSetOutput + params := &wafv2.GetIPSetInput{ + Id: aws.String(d.Id()), + Name: aws.String(d.Get("name").(string)), + Scope: aws.String(d.Get("scope").(string)), + } + log.Printf("[INFO] Updating WAFV2 IPSet %s", d.Id()) + + err := resource.Retry(15*time.Minute, func() *resource.RetryError { + var err error + resp, err = conn.GetIPSet(params) + if err != nil { + return resource.NonRetryableError(fmt.Errorf("Error getting lock token: %s", err)) + } + + u := &wafv2.UpdateIPSetInput{ + Id: aws.String(d.Id()), + Name: aws.String(d.Get("name").(string)), + Scope: aws.String(d.Get("scope").(string)), + Addresses: []*string{}, + Description: aws.String(d.Get("description").(string)), + LockToken: resp.LockToken, + } + + if v, ok := d.GetOk("addresses"); ok && v.(*schema.Set).Len() > 0 { + u.Addresses = expandStringSet(d.Get("addresses").(*schema.Set)) + } + + if d.HasChange("description") { + u.Description = aws.String(d.Get("description").(string)) + } + + _, err = conn.UpdateIPSet(u) + + if err != nil { + if isAWSErr(err, wafv2.ErrCodeWAFInternalErrorException, "AWS WAF couldn’t perform the operation because of a system problem") { + return resource.RetryableError(err) + } + if isAWSErr(err, wafv2.ErrCodeWAFOptimisticLockException, "AWS WAF couldn’t save your changes because you tried to update or delete a resource that has changed since you last retrieved it") { + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + + if isResourceTimeoutError(err) { + _, err = conn.DeleteIPSet(&wafv2.DeleteIPSetInput{ + Id: aws.String(d.Id()), + Name: aws.String(d.Get("name").(string)), + Scope: aws.String(d.Get("scope").(string)), + LockToken: resp.LockToken, + }) + } + + if err != nil { + return fmt.Errorf("Error updating WAFV2 IPSet: %s", err) + } + return resourceAwsWafv2IPSetRead(d, meta) } diff --git a/aws/resource_aws_wafv2_ip_set_test.go b/aws/resource_aws_wafv2_ip_set_test.go index 82406b35d35..b395eb79a96 100644 --- a/aws/resource_aws_wafv2_ip_set_test.go +++ b/aws/resource_aws_wafv2_ip_set_test.go @@ -34,8 +34,44 @@ func TestAccAwsWafv2IPSet_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional), resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4), resource.TestCheckResourceAttr(resourceName, "addresses.#", "2"), - resource.TestCheckResourceAttr(resourceName, "addresses.0", "1.2.3.4/32"), - resource.TestCheckResourceAttr(resourceName, "addresses.1", "5.6.7.8/32"), + ), + }, + { + Config: testAccAwsWafv2IPSetConfigUpdate(ipSetName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)), + resource.TestCheckResourceAttr(resourceName, "name", ipSetName), + resource.TestCheckResourceAttr(resourceName, "description", "Updated"), + resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional), + resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4), + resource.TestCheckResourceAttr(resourceName, "addresses.#", "3"), + ), + }, + }, + }) +} + +func TestAccAwsWafv2IPSet_minimal(t *testing.T) { + var v wafv2.IPSet + ipSetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5)) + resourceName := "aws_wafv2_ip_set.ip_set" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSWafv2IPSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsWafv2IPSetConfigMinimal(ipSetName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)), + resource.TestCheckResourceAttr(resourceName, "name", ipSetName), + resource.TestCheckResourceAttr(resourceName, "description", ""), + resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional), + resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4), + resource.TestCheckResourceAttr(resourceName, "addresses.#", "0"), ), }, }, @@ -117,3 +153,25 @@ resource "aws_wafv2_ip_set" "ip_set" { } `, name, name) } + +func testAccAwsWafv2IPSetConfigUpdate(name string) string { + return fmt.Sprintf(` +resource "aws_wafv2_ip_set" "ip_set" { + name = "%s" + description = "Updated" + scope = "REGIONAL" + ip_address_version = "IPV4" + addresses = ["1.1.1.1/32", "2.2.2.2/32", "3.3.3.3/32"] +} +`, name) +} + +func testAccAwsWafv2IPSetConfigMinimal(name string) string { + return fmt.Sprintf(` +resource "aws_wafv2_ip_set" "ip_set" { + name = "%s" + scope = "REGIONAL" + ip_address_version = "IPV4" +} +`, name) +} From 92d36954170b38615487f95370d8829997a15db9 Mon Sep 17 00:00:00 2001 From: Pascal van Buijtene Date: Wed, 12 Feb 2020 16:20:21 +0100 Subject: [PATCH 027/475] Add force new test --- aws/resource_aws_wafv2_ip_set_test.go | 39 +++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/aws/resource_aws_wafv2_ip_set_test.go b/aws/resource_aws_wafv2_ip_set_test.go index b395eb79a96..986ad0c7aa7 100644 --- a/aws/resource_aws_wafv2_ip_set_test.go +++ b/aws/resource_aws_wafv2_ip_set_test.go @@ -78,6 +78,45 @@ func TestAccAwsWafv2IPSet_minimal(t *testing.T) { }) } +func TestAccAwsWafv2IPSet_changeNameForceNew(t *testing.T) { + var before, after wafv2.IPSet + ipSetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5)) + ipSetNewName := fmt.Sprintf("ip-set-%s", acctest.RandString(5)) + resourceName := "aws_wafv2_ip_set.ip_set" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSWafv2IPSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsWafv2IPSetConfig(ipSetName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &before), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)), + resource.TestCheckResourceAttr(resourceName, "name", ipSetName), + resource.TestCheckResourceAttr(resourceName, "description", ipSetName), + resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional), + resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4), + resource.TestCheckResourceAttr(resourceName, "addresses.#", "2"), + ), + }, + { + Config: testAccAwsWafv2IPSetConfig(ipSetNewName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &after), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)), + resource.TestCheckResourceAttr(resourceName, "name", ipSetNewName), + resource.TestCheckResourceAttr(resourceName, "description", ipSetNewName), + resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional), + resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4), + resource.TestCheckResourceAttr(resourceName, "addresses.#", "2"), + ), + }, + }, + }) +} + func testAccCheckAWSWafv2IPSetDestroy(s *terraform.State) error { for _, rs := range s.RootModule().Resources { if rs.Type != "aws_wafv2_ip_set" { From d6c40b64661862e7cf1da81a2f1deb8fb60701aa Mon Sep 17 00:00:00 2001 From: Pascal van Buijtene Date: Wed, 12 Feb 2020 17:28:20 +0100 Subject: [PATCH 028/475] Add import --- aws/resource_aws_wafv2_ip_set.go | 16 ++++++++++++++++ aws/resource_aws_wafv2_ip_set_test.go | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/aws/resource_aws_wafv2_ip_set.go b/aws/resource_aws_wafv2_ip_set.go index 6eca7cf99ae..f2a27f4f24c 100644 --- a/aws/resource_aws_wafv2_ip_set.go +++ b/aws/resource_aws_wafv2_ip_set.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" "log" + "strings" "time" "github.com/aws/aws-sdk-go/aws" @@ -19,6 +20,21 @@ func resourceAwsWafv2IPSet() *schema.Resource { Read: resourceAwsWafv2IPSetRead, Update: resourceAwsWafv2IPSetUpdate, Delete: resourceAwsWafv2IPSetDelete, + Importer: &schema.ResourceImporter{ + State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + idParts := strings.Split(d.Id(), "/") + if len(idParts) != 3 || idParts[0] == "" || idParts[1] == "" || idParts[2] == "" { + return nil, fmt.Errorf("Unexpected format of ID (%q), expected ID/NAME/SCOPE", d.Id()) + } + id := idParts[0] + name := idParts[1] + scope := idParts[2] + d.SetId(id) + d.Set("name", name) + d.Set("scope", scope) + return []*schema.ResourceData{d}, nil + }, + }, Schema: map[string]*schema.Schema{ "addresses": { diff --git a/aws/resource_aws_wafv2_ip_set_test.go b/aws/resource_aws_wafv2_ip_set_test.go index 986ad0c7aa7..8ff911d300f 100644 --- a/aws/resource_aws_wafv2_ip_set_test.go +++ b/aws/resource_aws_wafv2_ip_set_test.go @@ -48,6 +48,12 @@ func TestAccAwsWafv2IPSet_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "addresses.#", "3"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: testAccAWSWafv2IPSetImportStateIdFunc(resourceName), + }, }, }) } @@ -117,6 +123,8 @@ func TestAccAwsWafv2IPSet_changeNameForceNew(t *testing.T) { }) } +// TAGS + func testAccCheckAWSWafv2IPSetDestroy(s *terraform.State) error { for _, rs := range s.RootModule().Resources { if rs.Type != "aws_wafv2_ip_set" { @@ -214,3 +222,14 @@ resource "aws_wafv2_ip_set" "ip_set" { } `, name) } + +func testAccAWSWafv2IPSetImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("Not found: %s", resourceName) + } + + return fmt.Sprintf("%s/%s/%s", rs.Primary.ID, rs.Primary.Attributes["name"], rs.Primary.Attributes["scope"]), nil + } +} From e0b7a44d96fef0aedd933c66a1f09518818dcbad Mon Sep 17 00:00:00 2001 From: Pascal van Buijtene Date: Mon, 17 Feb 2020 17:31:03 +0100 Subject: [PATCH 029/475] Add tags support --- aws/resource_aws_wafv2_ip_set.go | 22 +++++++ aws/resource_aws_wafv2_ip_set_test.go | 89 ++++++++++++++++++++++++++- 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_wafv2_ip_set.go b/aws/resource_aws_wafv2_ip_set.go index f2a27f4f24c..37e5712e832 100644 --- a/aws/resource_aws_wafv2_ip_set.go +++ b/aws/resource_aws_wafv2_ip_set.go @@ -5,6 +5,7 @@ import ( "github.com/aws/aws-sdk-go/service/wafv2" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" "log" "strings" "time" @@ -101,6 +102,10 @@ func resourceAwsWafv2IPSetCreate(d *schema.ResourceData, meta interface{}) error params.Description = aws.String(d.Get("description").(string)) } + if v := d.Get("tags").(map[string]interface{}); len(v) > 0 { + params.Tags = keyvaluetags.New(v).IgnoreAws().Wafv2Tags() + } + err := resource.Retry(15*time.Minute, func() *resource.RetryError { var err error resp, err = conn.CreateIPSet(params) @@ -161,11 +166,21 @@ func resourceAwsWafv2IPSetRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("Error setting addresses: %s", err) } + tags, err := keyvaluetags.Wafv2ListTags(conn, *resp.IPSet.ARN) + if err != nil { + return fmt.Errorf("error listing tags for WAFV2 IpSet (%s): %s", *resp.IPSet.ARN, err) + } + + if err := d.Set("tags", tags.IgnoreAws().Map()); err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + return nil } func resourceAwsWafv2IPSetUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).wafv2conn + //tags := keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().Wafv2Tags() var resp *wafv2.GetIPSetOutput params := &wafv2.GetIPSetInput{ Id: aws.String(d.Id()), @@ -225,6 +240,13 @@ func resourceAwsWafv2IPSetUpdate(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error updating WAFV2 IPSet: %s", err) } + if d.HasChange("tags") { + o, n := d.GetChange("tags") + if err := keyvaluetags.Wafv2UpdateTags(conn, d.Get("arn").(string), o, n); err != nil { + return fmt.Errorf("error updating tags: %s", err) + } + } + return resourceAwsWafv2IPSetRead(d, meta) } diff --git a/aws/resource_aws_wafv2_ip_set_test.go b/aws/resource_aws_wafv2_ip_set_test.go index 8ff911d300f..1697922c6cd 100644 --- a/aws/resource_aws_wafv2_ip_set_test.go +++ b/aws/resource_aws_wafv2_ip_set_test.go @@ -34,6 +34,9 @@ func TestAccAwsWafv2IPSet_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional), resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv4), resource.TestCheckResourceAttr(resourceName, "addresses.#", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.Tag1", "Value1"), + resource.TestCheckResourceAttr(resourceName, "tags.Tag2", "Value2"), ), }, { @@ -123,7 +126,53 @@ func TestAccAwsWafv2IPSet_changeNameForceNew(t *testing.T) { }) } -// TAGS +func TestAccAwsWafv2IPSet_tags(t *testing.T) { + var v wafv2.IPSet + ipSetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5)) + resourceName := "aws_wafv2_ip_set.ip_set" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSWafv2IPSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsWafv2IPSetConfigOneTag(ipSetName, "Tag1", "Value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Tag1", "Value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: testAccAWSWafv2IPSetImportStateIdFunc(resourceName), + }, + { + Config: testAccAwsWafv2IPSetConfigTwoTags(ipSetName, "Tag1", "Value1Updated", "Tag2", "Value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.Tag1", "Value1Updated"), + resource.TestCheckResourceAttr(resourceName, "tags.Tag2", "Value2"), + ), + }, + { + Config: testAccAwsWafv2IPSetConfigOneTag(ipSetName, "Tag2", "Value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSWafv2IPSetExists("aws_wafv2_ip_set.ip_set", &v), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Tag2", "Value2"), + ), + }, + }, + }) +} func testAccCheckAWSWafv2IPSetDestroy(s *terraform.State) error { for _, rs := range s.RootModule().Resources { @@ -197,6 +246,11 @@ resource "aws_wafv2_ip_set" "ip_set" { scope = "REGIONAL" ip_address_version = "IPV4" addresses = ["1.2.3.4/32", "5.6.7.8/32"] + + tags = { + Tag1 = "Value1" + Tag2 = "Value2" + } } `, name, name) } @@ -223,6 +277,39 @@ resource "aws_wafv2_ip_set" "ip_set" { `, name) } +func testAccAwsWafv2IPSetConfigOneTag(name, tagKey, tagValue string) string { + return fmt.Sprintf(` +resource "aws_wafv2_ip_set" "ip_set" { + name = "%s" + description = "%s" + scope = "REGIONAL" + ip_address_version = "IPV4" + addresses = ["1.2.3.4/32", "5.6.7.8/32"] + + tags = { + %q = %q + } +} +`, name, name, tagKey, tagValue) +} + +func testAccAwsWafv2IPSetConfigTwoTags(name, tag1Key, tag1Value, tag2Key, tag2Value string) string { + return fmt.Sprintf(` +resource "aws_wafv2_ip_set" "ip_set" { + name = "%s" + description = "%s" + scope = "REGIONAL" + ip_address_version = "IPV4" + addresses = ["1.2.3.4/32", "5.6.7.8/32"] + + tags = { + %q = %q + %q = %q + } +} +`, name, name, tag1Key, tag1Value, tag2Key, tag2Value) +} + func testAccAWSWafv2IPSetImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { return func(s *terraform.State) (string, error) { rs, ok := s.RootModule().Resources[resourceName] From abc188cc29d42f8d710e8603904a4bfa3a28b003 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 4 May 2020 16:34:35 -0400 Subject: [PATCH 030/475] r/aws_route53_query_log: Add test sweeper. --- aws/resource_aws_cloudwatch_log_group_test.go | 2 +- aws/resource_aws_route53_query_log_test.go | 54 ++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_cloudwatch_log_group_test.go b/aws/resource_aws_cloudwatch_log_group_test.go index 76b616b87f8..bf9ccfec0a1 100644 --- a/aws/resource_aws_cloudwatch_log_group_test.go +++ b/aws/resource_aws_cloudwatch_log_group_test.go @@ -36,7 +36,7 @@ func init() { "aws_mq_broker", "aws_msk_cluster", "aws_rds_cluster", - // Not currently implemented: "aws_route53_query_log", + "aws_route53_query_log", "aws_sagemaker_endpoint", "aws_storagegateway_gateway", }, diff --git a/aws/resource_aws_route53_query_log_test.go b/aws/resource_aws_route53_query_log_test.go index c241a2df125..68a21d3d109 100644 --- a/aws/resource_aws_route53_query_log_test.go +++ b/aws/resource_aws_route53_query_log_test.go @@ -2,18 +2,70 @@ package aws import ( "fmt" + "log" "os" "strings" "testing" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/route53" - + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" ) +func init() { + resource.AddTestSweepers("aws_route53_query_log", &resource.Sweeper{ + Name: "aws_route53_query_log", + F: testSweepRoute53QueryLogs, + }) +} + +func testSweepRoute53QueryLogs(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).r53conn + var sweeperErrs *multierror.Error + + err = conn.ListQueryLoggingConfigsPages(&route53.ListQueryLoggingConfigsInput{}, func(page *route53.ListQueryLoggingConfigsOutput, isLast bool) bool { + if page == nil { + return !isLast + } + + for _, queryLoggingConfig := range page.QueryLoggingConfigs { + id := aws.StringValue(queryLoggingConfig.Id) + + log.Printf("[INFO] Deleting Route53 query logging configuration: %s", id) + _, err := conn.DeleteQueryLoggingConfig(&route53.DeleteQueryLoggingConfigInput{ + Id: aws.String(id), + }) + if isAWSErr(err, route53.ErrCodeNoSuchQueryLoggingConfig, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error deleting Route53 query logging configuration (%s): %w", id, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + return !isLast + }) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping Route53 query logging configurations sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving Route53 query logging configurations: %w", err)) + } + + return sweeperErrs.ErrorOrNil() +} + func TestAccAWSRoute53QueryLog_Basic(t *testing.T) { // The underlying resources are sensitive to where they are located // Use us-east-1 for testing From 8b7b3ce273c686566455f09f9e066e6cc3d6f423 Mon Sep 17 00:00:00 2001 From: Pascal van Buijtene Date: Fri, 21 Feb 2020 15:10:23 +0100 Subject: [PATCH 031/475] Add docs --- website/allowed-subcategories.txt | 1 + website/aws.erb | 13 ++++++ website/docs/r/wafv2_ip_set.html.markdown | 54 +++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 website/docs/r/wafv2_ip_set.html.markdown diff --git a/website/allowed-subcategories.txt b/website/allowed-subcategories.txt index 2f7427c5abb..191b7117809 100644 --- a/website/allowed-subcategories.txt +++ b/website/allowed-subcategories.txt @@ -105,6 +105,7 @@ Transfer VPC WAF Regional WAF +WAFv2 WorkLink WorkMail WorkSpaces diff --git a/website/aws.erb b/website/aws.erb index 9c2b258301d..58c7fdf91e1 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -3553,6 +3553,19 @@
  • +
  • + WAFv2 + +
  • WorkLink
  • -
  • - Resources - -
  • @@ -3589,6 +3581,9 @@
  • aws_workspaces_ip_group
  • +
  • + aws_workspaces_workspace +
  • diff --git a/website/docs/r/workspaces_workspace.html.markdown b/website/docs/r/workspaces_workspace.html.markdown new file mode 100644 index 00000000000..c1563a7db95 --- /dev/null +++ b/website/docs/r/workspaces_workspace.html.markdown @@ -0,0 +1,84 @@ +--- +subcategory: "WorkSpaces" +layout: "aws" +page_title: "AWS: aws_workspaces_workspace" +description: |- + Provides a workspaces in AWS Workspaces Service. +--- + +# Resource: aws_workspace + +Provides a workspace in [AWS Workspaces](https://docs.aws.amazon.com/workspaces/latest/adminguide/amazon-workspaces.html) Service + +## Example Usage + +```hcl +data "aws_workspaces_directory" "main" { + directory_id = "d-ten5h0y19" +} + +data "aws_workspaces_bundle" "value_windows_10" { + bundle_id = "wsb-bh8rsxt14" # Value with Windows 10 (English) +} + +resource "aws_workspaces_workspace" "jhon.doe" { + directory_id = "${data.aws_workspaces_directory.main.id}" + bundle_id = "${data.aws_workspaces_bundle.value_windows_10.id}" + user_name = "jhon.doe" + + root_volume_encryption_enabled = true + user_volume_encryption_enabled = true + volume_encryption_key = "aws/workspaces" + + workspace_properties { + compute_type_name = "VALUE" + user_volume_size_gib = 10 + root_volume_size_gib = 80 + running_mode = "AUTO_STOP" + running_mode_auto_stop_timeout_in_minutes = 60 + } + + tags = { + Department = "IT" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `directory_id` - (Required) The ID of the directory for the WorkSpace. +* `bundle_id` - (Required) The ID of the bundle for the WorkSpace. +* `user_name` – (Required) The user name of the user for the WorkSpace. This user name must exist in the directory for the WorkSpace. +* `root_volume_encryption_enabled` - (Optional) Indicates whether the data stored on the root volume is encrypted. +* `user_volume_encryption_enabled` – (Optional) Indicates whether the data stored on the user volume is encrypted. +* `volume_encryption_key` – (Optional) The symmetric AWS KMS customer master key (CMK) used to encrypt data stored on your WorkSpace. Amazon WorkSpaces does not support asymmetric CMKs. +* `tags` - (Optional) The tags for the WorkSpace. +* `workspace_properties` – (Optional) The WorkSpace properties. + +`workspace_properties` supports the following: + +* `compute_type_name` – (Optional) The compute type. For more information, see [Amazon WorkSpaces Bundles](http://aws.amazon.com/workspaces/details/#Amazon_WorkSpaces_Bundles). Valid values are `VALUE`, `STANDARD`, `PERFORMANCE`, `POWER`, `GRAPHICS`, `POWERPRO` and `GRAPHICSPRO`. +* `root_volume_size_gib` – (Optional) The size of the root volume. +* `running_mode` – (Optional) The size of the root volume. The running mode. For more information, see [Manage the WorkSpace Running Mode](https://docs.aws.amazon.com/workspaces/latest/adminguide/running-mode.html). Valid values are `AUTO_STOP` and `ALWAYS_ON`. +* `running_mode_auto_stop_timeout_in_minutes` – (Optional) The time after a user logs off when WorkSpaces are automatically stopped. Configured in 60-minute intervals. +* `user_volume_size_gib` – (Optional) The size of the user storage. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The workspaces ID. +* `ip_address` - The IP address of the WorkSpace. +* `computer_name` - The name of the WorkSpace, as seen by the operating system. +* `state` - The operational state of the WorkSpace. + +## Import + +Workspaces can be imported using their ID, e.g. + +``` +$ terraform import aws_workspaces_workspace.example ws-9z9zmbkhv +``` + From 0762d2b9ea67677317ab4b1f0f795e38c14a9a87 Mon Sep 17 00:00:00 2001 From: Andrew Babichev Date: Wed, 6 May 2020 10:40:22 +0300 Subject: [PATCH 042/475] Add workspaces_directory sweeper dependency on workspaces_workspace --- aws/resource_aws_workspaces_directory.go | 12 ++++++------ aws/resource_aws_workspaces_directory_test.go | 5 +++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/aws/resource_aws_workspaces_directory.go b/aws/resource_aws_workspaces_directory.go index 81e90d4188c..b98a3f0404f 100644 --- a/aws/resource_aws_workspaces_directory.go +++ b/aws/resource_aws_workspaces_directory.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/workspaces" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) @@ -252,18 +253,15 @@ func resourceAwsWorkspacesDirectoryDelete(d *schema.ResourceData, meta interface if err != nil { return fmt.Errorf("error deleting workspaces directory (%s): %s", d.Id(), err) } - log.Printf("[DEBUG] Workspaces directory %q is deregistered", d.Id()) return nil } func workspacesDirectoryDelete(id string, conn *workspaces.WorkSpaces) error { - input := &workspaces.DeregisterWorkspaceDirectoryInput{ - DirectoryId: aws.String(id), - } - log.Printf("[DEBUG] Deregistering Workspace Directory %q", id) - _, err := conn.DeregisterWorkspaceDirectory(input) + _, err := conn.DeregisterWorkspaceDirectory(&workspaces.DeregisterWorkspaceDirectoryInput{ + DirectoryId: aws.String(id), + }) if err != nil { return fmt.Errorf("error deregistering Workspace Directory %q: %w", id, err) } @@ -286,6 +284,8 @@ func workspacesDirectoryDelete(id string, conn *workspaces.WorkSpaces) error { if err != nil { return fmt.Errorf("error waiting for Workspace Directory %q to be deregistered: %w", id, err) } + log.Printf("[DEBUG] Workspaces Directory %q is deregistered", id) + return nil } diff --git a/aws/resource_aws_workspaces_directory_test.go b/aws/resource_aws_workspaces_directory_test.go index 1947b0c58b4..1ddc73e588f 100644 --- a/aws/resource_aws_workspaces_directory_test.go +++ b/aws/resource_aws_workspaces_directory_test.go @@ -16,8 +16,9 @@ import ( func init() { resource.AddTestSweepers("aws_workspaces_directory", &resource.Sweeper{ - Name: "aws_workspaces_directory", - F: testSweepWorkspacesDirectories, + Name: "aws_workspaces_directory", + F: testSweepWorkspacesDirectories, + Dependencies: []string{"aws_workspaces_workspace"}, }) } From 264edcce4c96364c59f8e722656ffbff08f2296a Mon Sep 17 00:00:00 2001 From: Andrew Babichev Date: Wed, 6 May 2020 10:59:40 +0300 Subject: [PATCH 043/475] Fix workspaces default role --- aws/resource_aws_workspaces_workspace_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/aws/resource_aws_workspaces_workspace_test.go b/aws/resource_aws_workspaces_workspace_test.go index c11862e8810..a90d9236026 100644 --- a/aws/resource_aws_workspaces_workspace_test.go +++ b/aws/resource_aws_workspaces_workspace_test.go @@ -317,14 +317,14 @@ resource "aws_iam_role" "workspaces-default" { assume_role_policy = data.aws_iam_policy_document.workspaces.json } -resource "aws_iam_role_policy_attachment" "workspaces-default-skylight-service-access" { +resource "aws_iam_role_policy_attachment" "workspaces-default-service-access" { role = aws_iam_role.workspaces-default.name - policy_arn = "arn:aws:iam::aws:policy/SkyLightServiceAccess" + policy_arn = "arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess" } -resource "aws_iam_role_policy_attachment" "workspaces-default-skylight-self-service-access" { +resource "aws_iam_role_policy_attachment" "workspaces-default-self-service-access" { role = aws_iam_role.workspaces-default.name - policy_arn = "arn:aws:iam::aws:policy/SkyLightSelfServiceAccess" + policy_arn = "arn:aws:iam::aws:policy/AmazonWorkSpacesSelfServiceAccess" } data "aws_workspaces_bundle" "test" { From 802c1109b3f3321c0a51e7ac4f2d4891fdc79c67 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Wed, 6 May 2020 12:17:25 +0300 Subject: [PATCH 044/475] add plan time validation to `rules.source` add tags test fix state removal when does not exist --- aws/resource_aws_workspaces_ip_group.go | 22 ++- aws/resource_aws_workspaces_ip_group_test.go | 135 ++++++++++++++++--- 2 files changed, 131 insertions(+), 26 deletions(-) diff --git a/aws/resource_aws_workspaces_ip_group.go b/aws/resource_aws_workspaces_ip_group.go index c0781a38e95..ec92c8f11e7 100644 --- a/aws/resource_aws_workspaces_ip_group.go +++ b/aws/resource_aws_workspaces_ip_group.go @@ -7,6 +7,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/workspaces" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) @@ -37,8 +38,9 @@ func resourceAwsWorkspacesIpGroup() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "source": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.IsCIDR, }, "description": { Type: schema.TypeString, @@ -91,9 +93,19 @@ func resourceAwsWorkspacesIpGroupRead(d *schema.ResourceData, meta interface{}) return err } - d.Set("name", resp.Result[0].GroupName) - d.Set("description", resp.Result[0].GroupDesc) - d.Set("rules", flattenIpGroupRules(resp.Result[0].UserRules)) + ipGroups := resp.Result + + if len(ipGroups) == 0 { + log.Printf("[WARN] Workspaces Ip Group (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + ipGroup := ipGroups[0] + + d.Set("name", ipGroup.GroupName) + d.Set("description", ipGroup.GroupDesc) + d.Set("rules", flattenIpGroupRules(ipGroup.UserRules)) tags, err := keyvaluetags.WorkspacesListTags(conn, d.Id()) if err != nil { diff --git a/aws/resource_aws_workspaces_ip_group_test.go b/aws/resource_aws_workspaces_ip_group_test.go index 8dd52a09a45..0bc23485499 100644 --- a/aws/resource_aws_workspaces_ip_group_test.go +++ b/aws/resource_aws_workspaces_ip_group_test.go @@ -14,8 +14,8 @@ import ( func TestAccAwsWorkspacesIpGroup_basic(t *testing.T) { var v workspaces.IpGroup - ipGroupName := fmt.Sprintf("terraform-acctest-%s", acctest.RandString(10)) - ipGroupNewName := fmt.Sprintf("terraform-acctest-new-%s", acctest.RandString(10)) + ipGroupName := acctest.RandomWithPrefix("tf-acc-test") + ipGroupNewName := acctest.RandomWithPrefix("tf-acc-test-upd") ipGroupDescription := fmt.Sprintf("Terraform Acceptance Test %s", strings.Title(acctest.RandString(20))) resourceName := "aws_workspaces_ip_group.test" @@ -31,10 +31,7 @@ func TestAccAwsWorkspacesIpGroup_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "name", ipGroupName), resource.TestCheckResourceAttr(resourceName, "description", ipGroupDescription), resource.TestCheckResourceAttr(resourceName, "rules.#", "2"), - resource.TestCheckResourceAttr(resourceName, "tags.%", "3"), - resource.TestCheckResourceAttr(resourceName, "tags.Name", "test"), - resource.TestCheckResourceAttr(resourceName, "tags.Terraform", "true"), - resource.TestCheckResourceAttr(resourceName, "tags.IPGroup", "Home"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, { @@ -49,9 +46,6 @@ func TestAccAwsWorkspacesIpGroup_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "name", ipGroupNewName), resource.TestCheckResourceAttr(resourceName, "description", ipGroupDescription), resource.TestCheckResourceAttr(resourceName, "rules.#", "1"), - resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), - resource.TestCheckResourceAttr(resourceName, "tags.IPGroup", "Home"), - resource.TestCheckResourceAttr(resourceName, "tags.Purpose", "test"), ), }, { @@ -63,6 +57,73 @@ func TestAccAwsWorkspacesIpGroup_basic(t *testing.T) { }) } +func TestAccAwsWorkspacesIpGroup_tags(t *testing.T) { + var v workspaces.IpGroup + resourceName := "aws_workspaces_ip_group.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsWorkspacesIpGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsWorkspacesIpGroupConfigTags1(rName, "key1", "value1"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAwsWorkspacesIpGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAwsWorkspacesIpGroupConfigTags2(rName, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAwsWorkspacesIpGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccAwsWorkspacesIpGroupConfigTags1(rName, "key2", "value2"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAwsWorkspacesIpGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) +} + +func TestAccAwsWorkspacesIpGroup_disappears(t *testing.T) { + var v workspaces.IpGroup + ipGroupName := acctest.RandomWithPrefix("tf-acc-test") + ipGroupDescription := fmt.Sprintf("Terraform Acceptance Test %s", strings.Title(acctest.RandString(20))) + resourceName := "aws_workspaces_ip_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsWorkspacesIpGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsWorkspacesIpGroupConfigA(ipGroupName, ipGroupDescription), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAwsWorkspacesIpGroupExists(resourceName, &v), + testAccCheckResourceDisappears(testAccProvider, resourceAwsWorkspacesIpGroup(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + func testAccCheckAwsWorkspacesIpGroupDestroy(s *terraform.State) error { for _, rs := range s.RootModule().Resources { if rs.Type != "aws_workspaces_ip_group" { @@ -122,8 +183,8 @@ func testAccCheckAwsWorkspacesIpGroupExists(n string, v *workspaces.IpGroup) res func testAccAwsWorkspacesIpGroupConfigA(name, description string) string { return fmt.Sprintf(` resource "aws_workspaces_ip_group" "test" { - name = "%s" - description = "%s" + name = %[1]q + description = %[2]q rules { source = "10.0.0.0/16" @@ -133,21 +194,32 @@ resource "aws_workspaces_ip_group" "test" { source = "10.0.0.1/16" description = "Home" } +} +`, name, description) +} - tags = { - Name = "test" - Terraform = true - IPGroup = "Home" +func testAccAwsWorkspacesIpGroupConfigB(name, description string) string { + return fmt.Sprintf(` +resource "aws_workspaces_ip_group" "test" { + name = %[1]q + description = %[2]q + + rules { + source = "10.0.0.1/16" + description = "Home" } } `, name, description) } -func testAccAwsWorkspacesIpGroupConfigB(name, description string) string { +func testAccAwsWorkspacesIpGroupConfigTags1(name, tagKey1, tagValue1 string) string { return fmt.Sprintf(` resource "aws_workspaces_ip_group" "test" { - name = "%s" - description = "%s" + name = %[1]q + + rules { + source = "10.0.0.0/16" + } rules { source = "10.0.0.1/16" @@ -155,9 +227,30 @@ resource "aws_workspaces_ip_group" "test" { } tags = { - Purpose = "test" - IPGroup = "Home" + %[2]q = %[3]q } } -`, name, description) +`, name, tagKey1, tagValue1) +} + +func testAccAwsWorkspacesIpGroupConfigTags2(name, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_workspaces_ip_group" "test" { + name = %[1]q + + rules { + source = "10.0.0.0/16" + } + + rules { + source = "10.0.0.1/16" + description = "Home" + } + + tags = { + %[2]q = %[3]q + %[4]q = %[5]q + } +} +`, name, tagKey1, tagValue1, tagKey2, tagValue2) } From 691e2de181c5e12db1288842a142054c5a8a56cc Mon Sep 17 00:00:00 2001 From: Micheal Harker Date: Wed, 6 May 2020 17:00:24 +0100 Subject: [PATCH 045/475] r/vpn_connection: Remove case-insensitive mode parameter --- aws/resource_aws_vpn_connection.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_vpn_connection.go b/aws/resource_aws_vpn_connection.go index 80698fe8921..7e5a1576204 100644 --- a/aws/resource_aws_vpn_connection.go +++ b/aws/resource_aws_vpn_connection.go @@ -620,7 +620,7 @@ func xmlConfigToTunnelInfo(xmlConfig string) (*TunnelInfo, error) { func validateVpnConnectionTunnelPreSharedKey() schema.SchemaValidateFunc { return validation.All( validation.StringLenBetween(8, 64), - validation.StringDoesNotMatch(regexp.MustCompile(`(?i)^0`), "cannot start with zero character"), + validation.StringDoesNotMatch(regexp.MustCompile(`^0`), "cannot start with zero character"), validation.StringMatch(regexp.MustCompile(`^[0-9a-zA-Z_.]+$`), "can only contain alphanumeric, period and underscore characters"), ) } From f848f090d2f2aba8fccd57ff5d882af34411845c Mon Sep 17 00:00:00 2001 From: Pascal van Buijtene Date: Wed, 6 May 2020 23:09:43 +0200 Subject: [PATCH 046/475] Suppress IPv6 state diffs --- aws/resource_aws_wafv2_ip_set.go | 22 ++++++++++++ aws/resource_aws_wafv2_ip_set_test.go | 51 +++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/aws/resource_aws_wafv2_ip_set.go b/aws/resource_aws_wafv2_ip_set.go index 317f9f20548..6c95d656642 100644 --- a/aws/resource_aws_wafv2_ip_set.go +++ b/aws/resource_aws_wafv2_ip_set.go @@ -42,6 +42,28 @@ func resourceAwsWafv2IPSet() *schema.Resource { Optional: true, MaxItems: 50, Elem: &schema.Schema{Type: schema.TypeString}, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + o, n := d.GetChange("addresses") + oldAddresses := o.(*schema.Set).List() + newAddresses := n.(*schema.Set).List() + if len(oldAddresses) == len(newAddresses) { + for _, ov := range oldAddresses { + hasAddress := false + for _, nv := range newAddresses { + // isIpv6CidrsEquals works for both IPv4 and IPv6 + if isIpv6CidrsEquals(ov.(string), nv.(string)) { + hasAddress = true + break + } + } + if !hasAddress { + return false + } + } + return true + } + return false + }, }, "arn": { Type: schema.TypeString, diff --git a/aws/resource_aws_wafv2_ip_set_test.go b/aws/resource_aws_wafv2_ip_set_test.go index da0ef229f8d..4d12fb832f3 100644 --- a/aws/resource_aws_wafv2_ip_set_test.go +++ b/aws/resource_aws_wafv2_ip_set_test.go @@ -82,6 +82,41 @@ func TestAccAwsWafv2IPSet_Disappears(t *testing.T) { }) } +func TestAccAwsWafv2IPSet_IPv6(t *testing.T) { + var v wafv2.IPSet + ipSetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5)) + resourceName := "aws_wafv2_ip_set.ip_set" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSWafv2IPSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsWafv2IPSetConfigIPv6(ipSetName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSWafv2IPSetExists(resourceName, &v), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexp.MustCompile(`regional/ipset/.+$`)), + resource.TestCheckResourceAttr(resourceName, "name", ipSetName), + resource.TestCheckResourceAttr(resourceName, "description", ipSetName), + resource.TestCheckResourceAttr(resourceName, "scope", wafv2.ScopeRegional), + resource.TestCheckResourceAttr(resourceName, "ip_address_version", wafv2.IPAddressVersionIpv6), + resource.TestCheckResourceAttr(resourceName, "addresses.#", "3"), + resource.TestCheckResourceAttr(resourceName, "addresses.1676510651", "1234:5678:9abc:6811:0000:0000:0000:0000/64"), + resource.TestCheckResourceAttr(resourceName, "addresses.3671909787", "2001:db8::/32"), + resource.TestCheckResourceAttr(resourceName, "addresses.4089736081", "0:0:0:0:0:ffff:7f00:1/64"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: testAccAWSWafv2IPSetImportStateIdFunc(resourceName), + }, + }, + }) +} + func TestAccAwsWafv2IPSet_Minimal(t *testing.T) { var v wafv2.IPSet ipSetName := fmt.Sprintf("ip-set-%s", acctest.RandString(5)) @@ -294,6 +329,22 @@ resource "aws_wafv2_ip_set" "ip_set" { `, name) } +func testAccAwsWafv2IPSetConfigIPv6(name string) string { + return fmt.Sprintf(` +resource "aws_wafv2_ip_set" "ip_set" { + name = "%s" + description = "%s" + scope = "REGIONAL" + ip_address_version = "IPV6" + addresses = [ + "0:0:0:0:0:ffff:7f00:1/64", + "1234:5678:9abc:6811:0000:0000:0000:0000/64", + "2001:db8::/32" + ] +} +`, name, name) +} + func testAccAwsWafv2IPSetConfigMinimal(name string) string { return fmt.Sprintf(` resource "aws_wafv2_ip_set" "ip_set" { From 7c0a5daf2730e6069816bc9ec295ea5561dcae86 Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Wed, 6 May 2020 18:35:48 -0700 Subject: [PATCH 047/475] Updates Neptune acceptance tests to use ARN testing check functions Addresses: aws/resource_aws_neptune_cluster_instance_test.go:30:6: AWSAT001: prefer resource.TestCheckResourceAttrPair() or ARN check functions (e.g. testAccMatchResourceAttrRegionalARN) aws/resource_aws_neptune_cluster_instance_test.go:163:6: AWSAT001: prefer resource.TestCheckResourceAttrPair() or ARN check functions (e.g. testAccMatchResourceAttrRegionalARN) aws/resource_aws_neptune_cluster_parameter_group_test.go:31:6: AWSAT001: prefer resource.TestCheckResourceAttrPair() or ARN check functions (e.g. testAccMatchResourceAttrRegionalARN) aws/resource_aws_neptune_cluster_snapshot_test.go:31:6: AWSAT001: prefer resource.TestCheckResourceAttrPair() or ARN check functions (e.g. testAccMatchResourceAttrRegionalARN) aws/resource_aws_neptune_event_subscription_test.go:30:6: AWSAT001: prefer resource.TestCheckResourceAttrPair() or ARN check functions (e.g. testAccMatchResourceAttrRegionalARN) aws/resource_aws_neptune_parameter_group_test.go:30:6: AWSAT001: prefer resource.TestCheckResourceAttrPair() or ARN check functions (e.g. testAccMatchResourceAttrRegionalARN) --- aws/resource_aws_neptune_cluster.go | 4 +- aws/resource_aws_neptune_cluster_instance.go | 2 +- ...ource_aws_neptune_cluster_instance_test.go | 289 ++++++++++-------- ...ws_neptune_cluster_parameter_group_test.go | 107 ++++--- ...ource_aws_neptune_cluster_snapshot_test.go | 8 +- aws/resource_aws_neptune_cluster_test.go | 36 ++- ...rce_aws_neptune_event_subscription_test.go | 150 ++++----- ...source_aws_neptune_parameter_group_test.go | 2 +- 8 files changed, 328 insertions(+), 270 deletions(-) diff --git a/aws/resource_aws_neptune_cluster.go b/aws/resource_aws_neptune_cluster.go index 9b26405ab12..974f42ed00b 100644 --- a/aws/resource_aws_neptune_cluster.go +++ b/aws/resource_aws_neptune_cluster.go @@ -21,6 +21,8 @@ const ( // is not currently available in the AWS sdk-for-go // https://docs.aws.amazon.com/sdk-for-go/api/service/neptune/#pkg-constants CloudwatchLogsExportsAudit = "audit" + + neptuneDefaultPort = 8182 ) func resourceAwsNeptuneCluster() *schema.Resource { @@ -194,7 +196,7 @@ func resourceAwsNeptuneCluster() *schema.Resource { "port": { Type: schema.TypeInt, Optional: true, - Default: 8182, + Default: neptuneDefaultPort, ForceNew: true, }, diff --git a/aws/resource_aws_neptune_cluster_instance.go b/aws/resource_aws_neptune_cluster_instance.go index 87d7738974a..3ae7e12a258 100644 --- a/aws/resource_aws_neptune_cluster_instance.go +++ b/aws/resource_aws_neptune_cluster_instance.go @@ -134,7 +134,7 @@ func resourceAwsNeptuneClusterInstance() *schema.Resource { "port": { Type: schema.TypeInt, Optional: true, - Default: 8182, + Default: neptuneDefaultPort, ForceNew: true, }, diff --git a/aws/resource_aws_neptune_cluster_instance_test.go b/aws/resource_aws_neptune_cluster_instance_test.go index 0e913a1ce31..0fcd6bc3d41 100644 --- a/aws/resource_aws_neptune_cluster_instance_test.go +++ b/aws/resource_aws_neptune_cluster_instance_test.go @@ -3,6 +3,7 @@ package aws import ( "fmt" "regexp" + "strconv" "strings" "testing" @@ -15,6 +16,13 @@ import ( func TestAccAWSNeptuneClusterInstance_basic(t *testing.T) { var v neptune.DBInstance + rInt := acctest.RandInt() + + resourceName := "aws_neptune_cluster_instance.cluster_instances" + clusterResourceName := "aws_neptune_cluster.default" + parameterGroupResourceName := "aws_neptune_parameter_group.test" + + clusterInstanceName := fmt.Sprintf("tf-cluster-instance-%d", rInt) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -22,40 +30,38 @@ func TestAccAWSNeptuneClusterInstance_basic(t *testing.T) { CheckDestroy: testAccCheckAWSNeptuneClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSNeptuneClusterInstanceConfig(acctest.RandInt()), + Config: testAccAWSNeptuneClusterInstanceConfig(clusterInstanceName, rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSNeptuneClusterInstanceExists("aws_neptune_cluster_instance.cluster_instances", &v), + testAccCheckAWSNeptuneClusterInstanceExists(resourceName, &v), testAccCheckAWSNeptuneClusterInstanceAttributes(&v), - resource.TestCheckResourceAttrSet("aws_neptune_cluster_instance.cluster_instances", "address"), - resource.TestMatchResourceAttr("aws_neptune_cluster_instance.cluster_instances", "arn", regexp.MustCompile(`^arn:[^:]+:rds:[^:]+:[^:]+:db:.+`)), - resource.TestCheckResourceAttr("aws_neptune_cluster_instance.cluster_instances", "auto_minor_version_upgrade", "true"), - resource.TestMatchResourceAttr("aws_neptune_cluster_instance.cluster_instances", "availability_zone", regexp.MustCompile(fmt.Sprintf("^%s", testAccGetRegion()))), - resource.TestCheckResourceAttrSet("aws_neptune_cluster_instance.cluster_instances", "cluster_identifier"), - resource.TestCheckResourceAttrSet("aws_neptune_cluster_instance.cluster_instances", "dbi_resource_id"), - resource.TestMatchResourceAttr("aws_neptune_cluster_instance.cluster_instances", "endpoint", regexp.MustCompile(`:8182$`)), - resource.TestCheckResourceAttr("aws_neptune_cluster_instance.cluster_instances", "engine", "neptune"), - resource.TestCheckResourceAttrSet("aws_neptune_cluster_instance.cluster_instances", "engine_version"), - resource.TestCheckResourceAttrSet("aws_neptune_cluster_instance.cluster_instances", "identifier"), - resource.TestCheckResourceAttr("aws_neptune_cluster_instance.cluster_instances", "instance_class", "db.r4.large"), - resource.TestCheckResourceAttr("aws_neptune_cluster_instance.cluster_instances", "kms_key_arn", ""), - resource.TestMatchResourceAttr("aws_neptune_cluster_instance.cluster_instances", "neptune_parameter_group_name", regexp.MustCompile(`^tf-cluster-test-group-`)), - resource.TestCheckResourceAttr("aws_neptune_cluster_instance.cluster_instances", "neptune_subnet_group_name", "default"), - resource.TestCheckResourceAttr("aws_neptune_cluster_instance.cluster_instances", "port", "8182"), - resource.TestCheckResourceAttrSet("aws_neptune_cluster_instance.cluster_instances", "preferred_backup_window"), - resource.TestCheckResourceAttrSet("aws_neptune_cluster_instance.cluster_instances", "preferred_maintenance_window"), - resource.TestCheckResourceAttr("aws_neptune_cluster_instance.cluster_instances", "promotion_tier", "3"), - resource.TestCheckResourceAttr("aws_neptune_cluster_instance.cluster_instances", "publicly_accessible", "false"), - resource.TestCheckResourceAttr("aws_neptune_cluster_instance.cluster_instances", "storage_encrypted", "false"), - resource.TestCheckResourceAttr("aws_neptune_cluster_instance.cluster_instances", "tags.%", "0"), - resource.TestCheckResourceAttr("aws_neptune_cluster_instance.cluster_instances", "writer", "true"), + testAccCheckNeptuneClusterAddress(&v, resourceName, neptuneDefaultPort), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "rds", fmt.Sprintf("db:%s", clusterInstanceName)), + resource.TestCheckResourceAttr(resourceName, "auto_minor_version_upgrade", "true"), + resource.TestMatchResourceAttr(resourceName, "availability_zone", regexp.MustCompile(fmt.Sprintf("^%s[a-z]{1}$", testAccGetRegion()))), + resource.TestCheckResourceAttrPair(resourceName, "cluster_identifier", clusterResourceName, "id"), + resource.TestCheckResourceAttrSet(resourceName, "dbi_resource_id"), + resource.TestCheckResourceAttr(resourceName, "engine", "neptune"), + resource.TestCheckResourceAttrSet(resourceName, "engine_version"), + resource.TestCheckResourceAttr(resourceName, "identifier", clusterInstanceName), + resource.TestCheckResourceAttr(resourceName, "instance_class", "db.r4.large"), + resource.TestCheckResourceAttr(resourceName, "kms_key_arn", ""), + resource.TestCheckResourceAttrPair(resourceName, "neptune_parameter_group_name", parameterGroupResourceName, "name"), + resource.TestCheckResourceAttr(resourceName, "neptune_subnet_group_name", "default"), + resource.TestCheckResourceAttrSet(resourceName, "preferred_backup_window"), + resource.TestCheckResourceAttrSet(resourceName, "preferred_maintenance_window"), + resource.TestCheckResourceAttr(resourceName, "promotion_tier", "3"), + resource.TestCheckResourceAttr(resourceName, "publicly_accessible", "false"), + resource.TestCheckResourceAttr(resourceName, "storage_encrypted", "false"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "writer", "true"), ), }, { - Config: testAccAWSNeptuneClusterInstanceConfigModified(acctest.RandInt()), + Config: testAccAWSNeptuneClusterInstanceConfigModified(clusterInstanceName, rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSNeptuneClusterInstanceExists("aws_neptune_cluster_instance.cluster_instances", &v), + testAccCheckAWSNeptuneClusterInstanceExists(resourceName, &v), testAccCheckAWSNeptuneClusterInstanceAttributes(&v), - resource.TestCheckResourceAttr("aws_neptune_cluster_instance.cluster_instances", "auto_minor_version_upgrade", "false"), + resource.TestCheckResourceAttr(resourceName, "auto_minor_version_upgrade", "false"), ), }, }, @@ -64,6 +70,10 @@ func TestAccAWSNeptuneClusterInstance_basic(t *testing.T) { func TestAccAWSNeptuneClusterInstance_withaz(t *testing.T) { var v neptune.DBInstance + rInt := acctest.RandInt() + + resourceName := "aws_neptune_cluster_instance.cluster_instances" + availabiltyZonesDataSourceName := "data.aws_availability_zones.available" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -71,11 +81,12 @@ func TestAccAWSNeptuneClusterInstance_withaz(t *testing.T) { CheckDestroy: testAccCheckAWSNeptuneClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSNeptuneClusterInstanceConfig_az(acctest.RandInt()), + Config: testAccAWSNeptuneClusterInstanceConfig_az(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSNeptuneClusterInstanceExists("aws_neptune_cluster_instance.cluster_instances", &v), + testAccCheckAWSNeptuneClusterInstanceExists(resourceName, &v), testAccCheckAWSNeptuneClusterInstanceAttributes(&v), - resource.TestMatchResourceAttr("aws_neptune_cluster_instance.cluster_instances", "availability_zone", regexp.MustCompile("^us-west-2[a-z]{1}$")), + resource.TestMatchResourceAttr(resourceName, "availability_zone", regexp.MustCompile(fmt.Sprintf("^%s[a-z]{1}$", testAccGetRegion()))), // NOPE + resource.TestCheckResourceAttrPair(resourceName, "availability_zone", availabiltyZonesDataSourceName, "names.0"), ), }, }, @@ -86,18 +97,21 @@ func TestAccAWSNeptuneClusterInstance_namePrefix(t *testing.T) { var v neptune.DBInstance rInt := acctest.RandInt() + resourceName := "aws_neptune_cluster_instance.test" + + namePrefix := "tf-cluster-instance-" + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSNeptuneClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSNeptuneClusterInstanceConfig_namePrefix(rInt), + Config: testAccAWSNeptuneClusterInstanceConfig_namePrefix(namePrefix, rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSNeptuneClusterInstanceExists("aws_neptune_cluster_instance.test", &v), + testAccCheckAWSNeptuneClusterInstanceExists(resourceName, &v), testAccCheckAWSNeptuneClusterInstanceAttributes(&v), - resource.TestMatchResourceAttr( - "aws_neptune_cluster_instance.test", "identifier", regexp.MustCompile("^tf-cluster-instance-")), + resource.TestMatchResourceAttr(resourceName, "identifier", regexp.MustCompile(fmt.Sprintf("^%s", namePrefix))), ), }, }, @@ -108,6 +122,9 @@ func TestAccAWSNeptuneClusterInstance_withSubnetGroup(t *testing.T) { var v neptune.DBInstance rInt := acctest.RandInt() + resourceName := "aws_neptune_cluster_instance.test" + subnetGroupResourceName := "aws_neptune_subnet_group.test" + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -116,10 +133,9 @@ func TestAccAWSNeptuneClusterInstance_withSubnetGroup(t *testing.T) { { Config: testAccAWSNeptuneClusterInstanceConfig_withSubnetGroup(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSNeptuneClusterInstanceExists("aws_neptune_cluster_instance.test", &v), + testAccCheckAWSNeptuneClusterInstanceExists(resourceName, &v), testAccCheckAWSNeptuneClusterInstanceAttributes(&v), - resource.TestCheckResourceAttr( - "aws_neptune_cluster_instance.test", "neptune_subnet_group_name", fmt.Sprintf("tf-test-%d", rInt)), + resource.TestCheckResourceAttrPair(resourceName, "neptune_subnet_group_name", subnetGroupResourceName, "name"), ), }, }, @@ -128,6 +144,9 @@ func TestAccAWSNeptuneClusterInstance_withSubnetGroup(t *testing.T) { func TestAccAWSNeptuneClusterInstance_generatedName(t *testing.T) { var v neptune.DBInstance + rInt := acctest.RandInt() + + resourceName := "aws_neptune_cluster_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -135,12 +154,11 @@ func TestAccAWSNeptuneClusterInstance_generatedName(t *testing.T) { CheckDestroy: testAccCheckAWSNeptuneClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSNeptuneClusterInstanceConfig_generatedName(acctest.RandInt()), + Config: testAccAWSNeptuneClusterInstanceConfig_generatedName(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSNeptuneClusterInstanceExists("aws_neptune_cluster_instance.test", &v), + testAccCheckAWSNeptuneClusterInstanceExists(resourceName, &v), testAccCheckAWSNeptuneClusterInstanceAttributes(&v), - resource.TestMatchResourceAttr( - "aws_neptune_cluster_instance.test", "identifier", regexp.MustCompile("^tf-")), + resource.TestMatchResourceAttr(resourceName, "identifier", regexp.MustCompile("^tf-")), ), }, }, @@ -149,7 +167,10 @@ func TestAccAWSNeptuneClusterInstance_generatedName(t *testing.T) { func TestAccAWSNeptuneClusterInstance_kmsKey(t *testing.T) { var v neptune.DBInstance - keyRegex := regexp.MustCompile("^arn:aws:kms:") + rInt := acctest.RandInt() + + resourceName := "aws_neptune_cluster_instance.cluster_instances" + kmsKeyResourceName := "aws_kms_key.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -157,11 +178,10 @@ func TestAccAWSNeptuneClusterInstance_kmsKey(t *testing.T) { CheckDestroy: testAccCheckAWSNeptuneClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSNeptuneClusterInstanceConfigKmsKey(acctest.RandInt()), + Config: testAccAWSNeptuneClusterInstanceConfigKmsKey(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSNeptuneClusterInstanceExists("aws_neptune_cluster_instance.cluster_instances", &v), - resource.TestMatchResourceAttr( - "aws_neptune_cluster_instance.cluster_instances", "kms_key_arn", keyRegex), + testAccCheckAWSNeptuneClusterInstanceExists(resourceName, &v), + resource.TestCheckResourceAttrPair(resourceName, "kms_key_arn", kmsKeyResourceName, "arn"), ), }, }, @@ -214,24 +234,46 @@ func testAccCheckAWSNeptuneClusterInstanceAttributes(v *neptune.DBInstance) reso } } -func testAccAWSNeptuneClusterInstanceConfig(n int) string { - return fmt.Sprintf(` -resource "aws_neptune_cluster" "default" { - cluster_identifier = "tf-neptune-cluster-test-%d" - availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] - skip_final_snapshot = true +func testAccCheckNeptuneClusterAddress(v *neptune.DBInstance, resourceName string, portNumber int) resource.TestCheckFunc { + return func(s *terraform.State) error { + address := aws.StringValue(v.Endpoint.Address) + if err := resource.TestCheckResourceAttr(resourceName, "address", address)(s); err != nil { + return err + } + + port := strconv.Itoa(portNumber) + if err := resource.TestCheckResourceAttr(resourceName, "port", port)(s); err != nil { + return err + } + + if err := resource.TestCheckResourceAttr(resourceName, "endpoint", fmt.Sprintf("%s:%s", address, port))(s); err != nil { + return err + } + + return nil + } } +func testAccAWSNeptuneClusterInstanceConfig(instanceName string, n int) string { + return composeConfig( + testAccAWSNeptuneClusterConfigBase, + fmt.Sprintf(` resource "aws_neptune_cluster_instance" "cluster_instances" { - identifier = "tf-cluster-instance-%d" + identifier = %[1]q cluster_identifier = "${aws_neptune_cluster.default.id}" instance_class = "db.r4.large" - neptune_parameter_group_name = "${aws_neptune_parameter_group.bar.name}" + neptune_parameter_group_name = "${aws_neptune_parameter_group.test.name}" promotion_tier = "3" } -resource "aws_neptune_parameter_group" "bar" { - name = "tf-cluster-test-group-%d" +resource "aws_neptune_cluster" "default" { + cluster_identifier = "tf-neptune-cluster-test-%[2]d" + availability_zones = local.availability_zone_names + skip_final_snapshot = true +} + +resource "aws_neptune_parameter_group" "test" { + name = "tf-cluster-test-group-%[2]d" family = "neptune1" parameter { @@ -240,31 +282,33 @@ resource "aws_neptune_parameter_group" "bar" { } tags = { - foo = "bar" + Name = "test" } } -`, n, n, n) -} - -func testAccAWSNeptuneClusterInstanceConfigModified(n int) string { - return fmt.Sprintf(` -resource "aws_neptune_cluster" "default" { - cluster_identifier = "tf-neptune-cluster-test-%d" - availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"] - skip_final_snapshot = true +`, instanceName, n)) } +func testAccAWSNeptuneClusterInstanceConfigModified(instanceName string, n int) string { + return composeConfig( + testAccAWSNeptuneClusterConfigBase, + fmt.Sprintf(` resource "aws_neptune_cluster_instance" "cluster_instances" { - identifier = "tf-cluster-instance-%d" + identifier = %[1]q cluster_identifier = "${aws_neptune_cluster.default.id}" instance_class = "db.r4.large" - neptune_parameter_group_name = "${aws_neptune_parameter_group.bar.name}" + neptune_parameter_group_name = "${aws_neptune_parameter_group.test.name}" auto_minor_version_upgrade = false promotion_tier = "3" } -resource "aws_neptune_parameter_group" "bar" { - name = "tf-cluster-test-group-%d" +resource "aws_neptune_cluster" "default" { + cluster_identifier = "tf-neptune-cluster-test-%[2]d" + availability_zones = local.availability_zone_names + skip_final_snapshot = true +} + +resource "aws_neptune_parameter_group" "test" { + name = "tf-cluster-test-group-%[2]d" family = "neptune1" parameter { @@ -273,40 +317,33 @@ resource "aws_neptune_parameter_group" "bar" { } tags = { - foo = "bar" + Name = "test" } } -`, n, n, n) +`, instanceName, n)) } func testAccAWSNeptuneClusterInstanceConfig_az(n int) string { - return fmt.Sprintf(` -data "aws_availability_zones" "available" { - state = "available" - - filter { - name = "opt-in-status" - values = ["opt-in-not-required"] - } -} - -resource "aws_neptune_cluster" "default" { - cluster_identifier = "tf-neptune-cluster-test-%d" - availability_zones = ["${data.aws_availability_zones.available.names[0]}", "${data.aws_availability_zones.available.names[1]}", "${data.aws_availability_zones.available.names[2]}"] - skip_final_snapshot = true -} - + return composeConfig( + testAccAWSNeptuneClusterConfigBase, + fmt.Sprintf(` resource "aws_neptune_cluster_instance" "cluster_instances" { - identifier = "tf-cluster-instance-%d" + identifier = "tf-cluster-instance-%[1]d" cluster_identifier = "${aws_neptune_cluster.default.id}" instance_class = "db.r4.large" - neptune_parameter_group_name = "${aws_neptune_parameter_group.bar.name}" + neptune_parameter_group_name = "${aws_neptune_parameter_group.test.name}" promotion_tier = "3" - availability_zone = "${data.aws_availability_zones.available.names[0]}" + availability_zone = data.aws_availability_zones.available.names[0] +} + +resource "aws_neptune_cluster" "default" { + cluster_identifier = "tf-neptune-cluster-test-%[1]d" + availability_zones = local.availability_zone_names + skip_final_snapshot = true } -resource "aws_neptune_parameter_group" "bar" { - name = "tf-cluster-test-group-%d" +resource "aws_neptune_parameter_group" "test" { + name = "tf-cluster-test-group-%[1]d" family = "neptune1" parameter { @@ -315,22 +352,24 @@ resource "aws_neptune_parameter_group" "bar" { } tags = { - foo = "bar" + Name = "test" } } -`, n, n, n) +`, n)) } func testAccAWSNeptuneClusterInstanceConfig_withSubnetGroup(n int) string { - return fmt.Sprintf(` + return composeConfig( + testAccAWSNeptuneClusterConfigBase, + fmt.Sprintf(` resource "aws_neptune_cluster_instance" "test" { - identifier = "tf-cluster-instance-%d" + identifier = "tf-cluster-instance-%[1]d" cluster_identifier = "${aws_neptune_cluster.test.id}" instance_class = "db.r4.large" } resource "aws_neptune_cluster" "test" { - cluster_identifier = "tf-neptune-cluster-%d" + cluster_identifier = "tf-neptune-cluster-%[1]d" neptune_subnet_group_name = "${aws_neptune_subnet_group.test.name}" skip_final_snapshot = true } @@ -364,22 +403,24 @@ resource "aws_subnet" "b" { } resource "aws_neptune_subnet_group" "test" { - name = "tf-test-%d" + name = "tf-test-%[1]d" subnet_ids = ["${aws_subnet.a.id}", "${aws_subnet.b.id}"] } -`, n, n, n) +`, n)) } -func testAccAWSNeptuneClusterInstanceConfig_namePrefix(n int) string { - return fmt.Sprintf(` +func testAccAWSNeptuneClusterInstanceConfig_namePrefix(namePrefix string, n int) string { + return composeConfig( + testAccAWSNeptuneClusterConfigBase, + fmt.Sprintf(` resource "aws_neptune_cluster_instance" "test" { - identifier_prefix = "tf-cluster-instance-" + identifier_prefix = %[1]q cluster_identifier = "${aws_neptune_cluster.test.id}" instance_class = "db.r4.large" } resource "aws_neptune_cluster" "test" { - cluster_identifier = "tf-neptune-cluster-%d" + cluster_identifier = "tf-neptune-cluster-%[2]d" neptune_subnet_group_name = "${aws_neptune_subnet_group.test.name}" skip_final_snapshot = true } @@ -413,21 +454,23 @@ resource "aws_subnet" "b" { } resource "aws_neptune_subnet_group" "test" { - name = "tf-test-%d" + name = "tf-test-%[2]d" subnet_ids = ["${aws_subnet.a.id}", "${aws_subnet.b.id}"] } -`, n, n) +`, namePrefix, n)) } func testAccAWSNeptuneClusterInstanceConfig_generatedName(n int) string { - return fmt.Sprintf(` + return composeConfig( + testAccAWSNeptuneClusterConfigBase, + fmt.Sprintf(` resource "aws_neptune_cluster_instance" "test" { cluster_identifier = "${aws_neptune_cluster.test.id}" instance_class = "db.r4.large" } resource "aws_neptune_cluster" "test" { - cluster_identifier = "tf-neptune-cluster-%d" + cluster_identifier = "tf-neptune-cluster-%[1]d" neptune_subnet_group_name = "${aws_neptune_subnet_group.test.name}" skip_final_snapshot = true } @@ -461,16 +504,18 @@ resource "aws_subnet" "b" { } resource "aws_neptune_subnet_group" "test" { - name = "tf-test-%d" + name = "tf-test-%[1]d" subnet_ids = ["${aws_subnet.a.id}", "${aws_subnet.b.id}"] } -`, n, n) +`, n)) } func testAccAWSNeptuneClusterInstanceConfigKmsKey(n int) string { - return fmt.Sprintf(` -resource "aws_kms_key" "foo" { - description = "Terraform acc test %d" + return composeConfig( + testAccAWSNeptuneClusterConfigBase, + fmt.Sprintf(` +resource "aws_kms_key" "test" { + description = "Terraform acc test %[1]d" policy = < Date: Fri, 10 Apr 2020 17:47:33 +0300 Subject: [PATCH 048/475] use enums + refactor tests --- aws/resource_aws_volume_attachment.go | 21 +- aws/resource_aws_volume_attachment_test.go | 259 ++++++++++++++------- 2 files changed, 179 insertions(+), 101 deletions(-) diff --git a/aws/resource_aws_volume_attachment.go b/aws/resource_aws_volume_attachment.go index 228b97e0d15..ee9ac728ba4 100644 --- a/aws/resource_aws_volume_attachment.go +++ b/aws/resource_aws_volume_attachment.go @@ -97,9 +97,9 @@ func resourceAwsVolumeAttachmentCreate(d *schema.ResourceData, meta interface{}) // a spot request and whilst the request has been fulfilled the // instance is not running yet stateConf := &resource.StateChangeConf{ - Pending: []string{"pending", "stopping"}, - Target: []string{"running", "stopped"}, - Refresh: InstanceStateRefreshFunc(conn, iID, []string{"terminated"}), + Pending: []string{ec2.InstanceStateNamePending, ec2.InstanceStateNameStopping}, + Target: []string{ec2.InstanceStateNameRunning, ec2.InstanceStateNameStopped}, + Refresh: InstanceStateRefreshFunc(conn, iID, []string{ec2.InstanceStateNameTerminated}), Timeout: 10 * time.Minute, Delay: 10 * time.Second, MinTimeout: 3 * time.Second, @@ -126,13 +126,12 @@ func resourceAwsVolumeAttachmentCreate(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error attaching volume (%s) to instance (%s), message: \"%s\", code: \"%s\"", vID, iID, awsErr.Message(), awsErr.Code()) } - return err } } stateConf := &resource.StateChangeConf{ - Pending: []string{"attaching"}, - Target: []string{"attached"}, + Pending: []string{ec2.VolumeAttachmentStateAttaching}, + Target: []string{ec2.VolumeAttachmentStateAttached}, Refresh: volumeAttachmentStateRefreshFunc(conn, name, vID, iID), Timeout: 5 * time.Minute, Delay: 10 * time.Second, @@ -183,7 +182,7 @@ func volumeAttachmentStateRefreshFunc(conn *ec2.EC2, name, volumeID, instanceID } } // assume detached if volume count is 0 - return 42, "detached", nil + return 42, ec2.VolumeAttachmentStateDetached, nil } } @@ -206,14 +205,14 @@ func resourceAwsVolumeAttachmentRead(d *schema.ResourceData, meta interface{}) e vols, err := conn.DescribeVolumes(request) if err != nil { - if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidVolume.NotFound" { + if isAWSErr(err, "InvalidVolume.NotFound", "") { d.SetId("") return nil } return fmt.Errorf("Error reading EC2 volume %s for instance: %s: %#v", d.Get("volume_id").(string), d.Get("instance_id").(string), err) } - if len(vols.Volumes) == 0 || *vols.Volumes[0].State == "available" { + if len(vols.Volumes) == 0 || *vols.Volumes[0].State == ec2.VolumeStateAvailable { log.Printf("[DEBUG] Volume Attachment (%s) not found, removing from state", d.Id()) d.SetId("") } @@ -250,8 +249,8 @@ func resourceAwsVolumeAttachmentDelete(d *schema.ResourceData, meta interface{}) vID, iID, err) } stateConf := &resource.StateChangeConf{ - Pending: []string{"detaching"}, - Target: []string{"detached"}, + Pending: []string{ec2.VolumeAttachmentStateDetaching}, + Target: []string{ec2.VolumeAttachmentStateDetached}, Refresh: volumeAttachmentStateRefreshFunc(conn, name, vID, iID), Timeout: 5 * time.Minute, Delay: 10 * time.Second, diff --git a/aws/resource_aws_volume_attachment_test.go b/aws/resource_aws_volume_attachment_test.go index db85ebfd1c2..f8d761f9ffe 100644 --- a/aws/resource_aws_volume_attachment_test.go +++ b/aws/resource_aws_volume_attachment_test.go @@ -15,6 +15,7 @@ import ( func TestAccAWSVolumeAttachment_basic(t *testing.T) { var i ec2.Instance var v ec2.Volume + resourceName := "aws_volume_attachment.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -24,14 +25,10 @@ func TestAccAWSVolumeAttachment_basic(t *testing.T) { { Config: testAccVolumeAttachmentConfig, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr( - "aws_volume_attachment.ebs_att", "device_name", "/dev/sdh"), - testAccCheckInstanceExists( - "aws_instance.web", &i), - testAccCheckVolumeExists( - "aws_ebs_volume.example", &v), - testAccCheckVolumeAttachmentExists( - "aws_volume_attachment.ebs_att", &i, &v), + resource.TestCheckResourceAttr(resourceName, "device_name", "/dev/sdh"), + testAccCheckInstanceExists("aws_instance.test", &i), + testAccCheckVolumeExists("aws_ebs_volume.test", &v), + testAccCheckVolumeAttachmentExists(resourceName, &i, &v), ), }, { @@ -47,6 +44,7 @@ func TestAccAWSVolumeAttachment_basic(t *testing.T) { func TestAccAWSVolumeAttachment_skipDestroy(t *testing.T) { var i ec2.Instance var v ec2.Volume + resourceName := "aws_volume_attachment.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -56,14 +54,10 @@ func TestAccAWSVolumeAttachment_skipDestroy(t *testing.T) { { Config: testAccVolumeAttachmentConfigSkipDestroy, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr( - "aws_volume_attachment.ebs_att", "device_name", "/dev/sdh"), - testAccCheckInstanceExists( - "aws_instance.web", &i), - testAccCheckVolumeExists( - "aws_ebs_volume.example", &v), - testAccCheckVolumeAttachmentExists( - "aws_volume_attachment.ebs_att", &i, &v), + resource.TestCheckResourceAttr(resourceName, "device_name", "/dev/sdh"), + testAccCheckInstanceExists("aws_instance.test", &i), + testAccCheckVolumeExists("aws_ebs_volume.test", &v), + testAccCheckVolumeAttachmentExists(resourceName, &i, &v), ), }, { @@ -82,6 +76,7 @@ func TestAccAWSVolumeAttachment_skipDestroy(t *testing.T) { func TestAccAWSVolumeAttachment_attachStopped(t *testing.T) { var i ec2.Instance var v ec2.Volume + resourceName := "aws_volume_attachment.test" stopInstance := func() { conn := testAccProvider.Meta().(*AWSClient).ec2conn @@ -94,8 +89,8 @@ func TestAccAWSVolumeAttachment_attachStopped(t *testing.T) { } stateConf := &resource.StateChangeConf{ - Pending: []string{"pending", "running", "stopping"}, - Target: []string{"stopped"}, + Pending: []string{ec2.InstanceStateNamePending, ec2.InstanceStateNameRunning, ec2.InstanceStateNameStopping}, + Target: []string{ec2.InstanceStateNameStopped}, Refresh: InstanceStateRefreshFunc(conn, *i.InstanceId, []string{}), Timeout: 10 * time.Minute, Delay: 10 * time.Second, @@ -116,22 +111,17 @@ func TestAccAWSVolumeAttachment_attachStopped(t *testing.T) { { Config: testAccVolumeAttachmentConfigInstanceOnly, Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists( - "aws_instance.web", &i), + testAccCheckInstanceExists("aws_instance.test", &i), ), }, { PreConfig: stopInstance, Config: testAccVolumeAttachmentConfig, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr( - "aws_volume_attachment.ebs_att", "device_name", "/dev/sdh"), - testAccCheckInstanceExists( - "aws_instance.web", &i), - testAccCheckVolumeExists( - "aws_ebs_volume.example", &v), - testAccCheckVolumeAttachmentExists( - "aws_volume_attachment.ebs_att", &i, &v), + resource.TestCheckResourceAttr(resourceName, "device_name", "/dev/sdh"), + testAccCheckInstanceExists("aws_instance.test", &i), + testAccCheckVolumeExists("aws_ebs_volume.test", &v), + testAccCheckVolumeAttachmentExists(resourceName, &i, &v), ), }, { @@ -145,6 +135,8 @@ func TestAccAWSVolumeAttachment_attachStopped(t *testing.T) { } func TestAccAWSVolumeAttachment_update(t *testing.T) { + resourceName := "aws_volume_attachment.test" + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -153,10 +145,8 @@ func TestAccAWSVolumeAttachment_update(t *testing.T) { { Config: testAccVolumeAttachmentConfig_update(false), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr( - "aws_volume_attachment.ebs_att", "force_detach", "false"), - resource.TestCheckResourceAttr( - "aws_volume_attachment.ebs_att", "skip_destroy", "false"), + resource.TestCheckResourceAttr(resourceName, "force_detach", "false"), + resource.TestCheckResourceAttr(resourceName, "skip_destroy", "false"), ), }, { @@ -172,10 +162,8 @@ func TestAccAWSVolumeAttachment_update(t *testing.T) { { Config: testAccVolumeAttachmentConfig_update(true), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr( - "aws_volume_attachment.ebs_att", "force_detach", "true"), - resource.TestCheckResourceAttr( - "aws_volume_attachment.ebs_att", "skip_destroy", "true"), + resource.TestCheckResourceAttr(resourceName, "force_detach", "true"), + resource.TestCheckResourceAttr(resourceName, "skip_destroy", "true"), ), }, { @@ -192,6 +180,28 @@ func TestAccAWSVolumeAttachment_update(t *testing.T) { }) } +func TestAccAWSVolumeAttachment_disappears(t *testing.T) { + var i ec2.Instance + var v ec2.Volume + resourceName := "aws_volume_attachment.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckVolumeAttachmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccVolumeAttachmentConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckVolumeAttachmentExists(resourceName, &i, &v), + testAccCheckVolumeAttachmentDisappears(resourceName, &i, &v), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + func testAccCheckVolumeAttachmentExists(n string, i *ec2.Instance, v *ec2.Volume) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -205,7 +215,9 @@ func testAccCheckVolumeAttachmentExists(n string, i *ec2.Instance, v *ec2.Volume for _, b := range i.BlockDeviceMappings { if rs.Primary.Attributes["device_name"] == *b.DeviceName { - if b.Ebs.VolumeId != nil && rs.Primary.Attributes["volume_id"] == *b.Ebs.VolumeId { + if b.Ebs.VolumeId != nil && + rs.Primary.Attributes["volume_id"] == *b.Ebs.VolumeId && + rs.Primary.Attributes["volume_id"] == *v.VolumeId { // pass return nil } @@ -216,107 +228,174 @@ func testAccCheckVolumeAttachmentExists(n string, i *ec2.Instance, v *ec2.Volume } } +func testAccCheckVolumeAttachmentDisappears(n string, i *ec2.Instance, v *ec2.Volume) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).ec2conn + + opts := &ec2.DetachVolumeInput{ + Device: aws.String(rs.Primary.Attributes["device_name"]), + InstanceId: i.InstanceId, + VolumeId: v.VolumeId, + Force: aws.Bool(true), + } + + _, err := conn.DetachVolume(opts) + if err != nil { + return err + } + + vId := aws.StringValue(v.VolumeId) + iId := aws.StringValue(i.InstanceId) + + stateConf := &resource.StateChangeConf{ + Pending: []string{ec2.VolumeAttachmentStateDetaching}, + Target: []string{ec2.VolumeAttachmentStateDetached}, + Refresh: volumeAttachmentStateRefreshFunc(conn, rs.Primary.Attributes["device_name"], vId, iId), + Timeout: 5 * time.Minute, + Delay: 10 * time.Second, + MinTimeout: 3 * time.Second, + } + + log.Printf("[DEBUG] Detaching Volume (%s) from Instance (%s)", vId, iId) + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf( + "Error waiting for Volume (%s) to detach from Instance (%s): %s", + vId, iId, err) + } + + return err + } +} + func testAccCheckVolumeAttachmentDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).ec2conn + for _, rs := range s.RootModule().Resources { - log.Printf("\n\n----- This is never called") if rs.Type != "aws_volume_attachment" { continue } + + request := &ec2.DescribeVolumesInput{ + VolumeIds: []*string{aws.String(rs.Primary.Attributes["volume_id"])}, + Filters: []*ec2.Filter{ + { + Name: aws.String("attachment.device"), + Values: []*string{aws.String(rs.Primary.Attributes["device_name"])}, + }, + { + Name: aws.String("attachment.instance-id"), + Values: []*string{aws.String(rs.Primary.Attributes["instance_id"])}, + }, + }, + } + + _, err := conn.DescribeVolumes(request) + if err != nil { + if isAWSErr(err, "InvalidVolume.NotFound", "") { + return nil + } + return fmt.Errorf("error describing volumes (%s): %s", rs.Primary.ID, err) + } } return nil } const testAccVolumeAttachmentConfigInstanceOnly = ` -resource "aws_instance" "web" { - ami = "ami-21f78e11" - availability_zone = "us-west-2a" - instance_type = "t1.micro" - tags = { - Name = "HelloWorld" +data "aws_availability_zones" "available" { + state = "available" + + filter { + name = "opt-in-status" + values = ["opt-in-not-required"] } } -` -const testAccVolumeAttachmentConfig = ` -resource "aws_instance" "web" { - ami = "ami-21f78e11" - availability_zone = "us-west-2a" - instance_type = "t1.micro" +resource "aws_instance" "test" { + ami = "ami-21f78e11" + availability_zone = "${data.aws_availability_zones.available.names[0]}" + instance_type = "t1.micro" + tags = { - Name = "HelloWorld" + Name = "tf-acc-test-volume-attachment" } } +` + +const testAccVolumeAttachmentConfig = testAccVolumeAttachmentConfigInstanceOnly + ` +resource "aws_ebs_volume" "test" { + availability_zone = "${data.aws_availability_zones.available.names[0]}" + size = 1 -resource "aws_ebs_volume" "example" { - availability_zone = "us-west-2a" - size = 1 + tags = { + Name = "tf-acc-test-volume-attachment" + } } -resource "aws_volume_attachment" "ebs_att" { +resource "aws_volume_attachment" "test" { device_name = "/dev/sdh" - volume_id = "${aws_ebs_volume.example.id}" - instance_id = "${aws_instance.web.id}" + volume_id = "${aws_ebs_volume.test.id}" + instance_id = "${aws_instance.test.id}" } ` -const testAccVolumeAttachmentConfigSkipDestroy = ` -resource "aws_instance" "web" { - ami = "ami-21f78e11" - availability_zone = "us-west-2a" - instance_type = "t1.micro" - tags = { - Name = "HelloWorld" - } -} +const testAccVolumeAttachmentConfigSkipDestroy = testAccVolumeAttachmentConfigInstanceOnly + ` +resource "aws_ebs_volume" "test" { + availability_zone = "${data.aws_availability_zones.available.names[0]}" + size = 1 -resource "aws_ebs_volume" "example" { - availability_zone = "us-west-2a" - size = 1 tags = { - Name = "TestVolume" + Name = "tf-acc-test-volume-attachment" } } -data "aws_ebs_volume" "ebs_volume" { +data "aws_ebs_volume" "test" { filter { name = "size" - values = ["${aws_ebs_volume.example.size}"] + values = ["${aws_ebs_volume.test.size}"] } filter { name = "availability-zone" - values = ["${aws_ebs_volume.example.availability_zone}"] + values = ["${aws_ebs_volume.test.availability_zone}"] } filter { name = "tag:Name" - values = ["TestVolume"] + values = ["tf-acc-test-volume-attachment"] } } -resource "aws_volume_attachment" "ebs_att" { - device_name = "/dev/sdh" - volume_id = "${data.aws_ebs_volume.ebs_volume.id}" - instance_id = "${aws_instance.web.id}" +resource "aws_volume_attachment" "test" { + device_name = "/dev/sdh" + volume_id = "${data.aws_ebs_volume.test.id}" + instance_id = "${aws_instance.test.id}" skip_destroy = true } ` func testAccVolumeAttachmentConfig_update(detach bool) string { - return fmt.Sprintf(` -resource "aws_instance" "web" { - ami = "ami-21f78e11" - availability_zone = "us-west-2a" - instance_type = "t1.micro" -} - -resource "aws_ebs_volume" "example" { - availability_zone = "us-west-2a" + return testAccVolumeAttachmentConfigInstanceOnly + fmt.Sprintf(` +resource "aws_ebs_volume" "test" { + availability_zone = "${data.aws_availability_zones.available.names[0]}" size = 1 + + tags = { + Name = "tf-acc-test-volume-attachment" + } } -resource "aws_volume_attachment" "ebs_att" { +resource "aws_volume_attachment" "test" { device_name = "/dev/sdh" - volume_id = "${aws_ebs_volume.example.id}" - instance_id = "${aws_instance.web.id}" + volume_id = "${aws_ebs_volume.test.id}" + instance_id = "${aws_instance.test.id}" force_detach = %t skip_destroy = %t } From ac28a4e29a2d4bd7e4c2417adcc1db6c83491077 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 10 Apr 2020 17:51:56 +0300 Subject: [PATCH 049/475] fix missing test --- aws/resource_aws_volume_attachment_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aws/resource_aws_volume_attachment_test.go b/aws/resource_aws_volume_attachment_test.go index f8d761f9ffe..f03c3237474 100644 --- a/aws/resource_aws_volume_attachment_test.go +++ b/aws/resource_aws_volume_attachment_test.go @@ -193,6 +193,8 @@ func TestAccAWSVolumeAttachment_disappears(t *testing.T) { { Config: testAccVolumeAttachmentConfig, Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceExists("aws_instance.test", &i), + testAccCheckVolumeExists("aws_ebs_volume.test", &v), testAccCheckVolumeAttachmentExists(resourceName, &i, &v), testAccCheckVolumeAttachmentDisappears(resourceName, &i, &v), ), From dfd902bd1bf1f3d303e5774ccfb2c4a1ccced374 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 10 Apr 2020 18:50:01 +0300 Subject: [PATCH 050/475] randomize resource names --- aws/resource_aws_volume_attachment_test.go | 90 ++++++++++++---------- 1 file changed, 49 insertions(+), 41 deletions(-) diff --git a/aws/resource_aws_volume_attachment_test.go b/aws/resource_aws_volume_attachment_test.go index f03c3237474..1c56a7157a8 100644 --- a/aws/resource_aws_volume_attachment_test.go +++ b/aws/resource_aws_volume_attachment_test.go @@ -8,6 +8,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" ) @@ -16,6 +17,7 @@ func TestAccAWSVolumeAttachment_basic(t *testing.T) { var i ec2.Instance var v ec2.Volume resourceName := "aws_volume_attachment.test" + rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -23,7 +25,7 @@ func TestAccAWSVolumeAttachment_basic(t *testing.T) { CheckDestroy: testAccCheckVolumeAttachmentDestroy, Steps: []resource.TestStep{ { - Config: testAccVolumeAttachmentConfig, + Config: testAccVolumeAttachmentConfig(rName), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "device_name", "/dev/sdh"), testAccCheckInstanceExists("aws_instance.test", &i), @@ -45,6 +47,7 @@ func TestAccAWSVolumeAttachment_skipDestroy(t *testing.T) { var i ec2.Instance var v ec2.Volume resourceName := "aws_volume_attachment.test" + rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -52,7 +55,7 @@ func TestAccAWSVolumeAttachment_skipDestroy(t *testing.T) { CheckDestroy: testAccCheckVolumeAttachmentDestroy, Steps: []resource.TestStep{ { - Config: testAccVolumeAttachmentConfigSkipDestroy, + Config: testAccVolumeAttachmentConfigSkipDestroy(rName), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "device_name", "/dev/sdh"), testAccCheckInstanceExists("aws_instance.test", &i), @@ -77,6 +80,7 @@ func TestAccAWSVolumeAttachment_attachStopped(t *testing.T) { var i ec2.Instance var v ec2.Volume resourceName := "aws_volume_attachment.test" + rName := acctest.RandomWithPrefix("tf-acc-test") stopInstance := func() { conn := testAccProvider.Meta().(*AWSClient).ec2conn @@ -109,14 +113,14 @@ func TestAccAWSVolumeAttachment_attachStopped(t *testing.T) { CheckDestroy: testAccCheckVolumeAttachmentDestroy, Steps: []resource.TestStep{ { - Config: testAccVolumeAttachmentConfigInstanceOnly, + Config: testAccVolumeAttachmentConfigBase(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_instance.test", &i), ), }, { PreConfig: stopInstance, - Config: testAccVolumeAttachmentConfig, + Config: testAccVolumeAttachmentConfig(rName), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "device_name", "/dev/sdh"), testAccCheckInstanceExists("aws_instance.test", &i), @@ -136,6 +140,7 @@ func TestAccAWSVolumeAttachment_attachStopped(t *testing.T) { func TestAccAWSVolumeAttachment_update(t *testing.T) { resourceName := "aws_volume_attachment.test" + rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -143,7 +148,7 @@ func TestAccAWSVolumeAttachment_update(t *testing.T) { CheckDestroy: testAccCheckVolumeAttachmentDestroy, Steps: []resource.TestStep{ { - Config: testAccVolumeAttachmentConfig_update(false), + Config: testAccVolumeAttachmentUpdateConfig(rName, false), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "force_detach", "false"), resource.TestCheckResourceAttr(resourceName, "skip_destroy", "false"), @@ -160,7 +165,7 @@ func TestAccAWSVolumeAttachment_update(t *testing.T) { }, }, { - Config: testAccVolumeAttachmentConfig_update(true), + Config: testAccVolumeAttachmentUpdateConfig(rName, true), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "force_detach", "true"), resource.TestCheckResourceAttr(resourceName, "skip_destroy", "true"), @@ -184,6 +189,7 @@ func TestAccAWSVolumeAttachment_disappears(t *testing.T) { var i ec2.Instance var v ec2.Volume resourceName := "aws_volume_attachment.test" + rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -191,7 +197,7 @@ func TestAccAWSVolumeAttachment_disappears(t *testing.T) { CheckDestroy: testAccCheckVolumeAttachmentDestroy, Steps: []resource.TestStep{ { - Config: testAccVolumeAttachmentConfig, + Config: testAccVolumeAttachmentConfig(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_instance.test", &i), testAccCheckVolumeExists("aws_ebs_volume.test", &v), @@ -312,7 +318,8 @@ func testAccCheckVolumeAttachmentDestroy(s *terraform.State) error { return nil } -const testAccVolumeAttachmentConfigInstanceOnly = ` +func testAccVolumeAttachmentInstanceOnlyConfigBase(rName string) string { + return fmt.Sprintf(` data "aws_availability_zones" "available" { state = "available" @@ -328,49 +335,58 @@ resource "aws_instance" "test" { instance_type = "t1.micro" tags = { - Name = "tf-acc-test-volume-attachment" + Name = %[1]q + } +} +`, rName) +} + +func testAccVolumeAttachmentConfigBase(rName string) string { + return testAccVolumeAttachmentInstanceOnlyConfigBase(rName) + fmt.Sprintf(` +data "aws_availability_zones" "available" { + state = "available" + + filter { + name = "opt-in-status" + values = ["opt-in-not-required"] } } -` -const testAccVolumeAttachmentConfig = testAccVolumeAttachmentConfigInstanceOnly + ` -resource "aws_ebs_volume" "test" { +resource "aws_instance" "test" { + ami = "ami-21f78e11" availability_zone = "${data.aws_availability_zones.available.names[0]}" - size = 1 + instance_type = "t1.micro" tags = { - Name = "tf-acc-test-volume-attachment" + Name = %[1]q } } +`, rName) +} +func testAccVolumeAttachmentConfig(rName string) string { + return testAccVolumeAttachmentConfigBase(rName) + fmt.Sprintf(` resource "aws_volume_attachment" "test" { device_name = "/dev/sdh" volume_id = "${aws_ebs_volume.test.id}" instance_id = "${aws_instance.test.id}" } -` - -const testAccVolumeAttachmentConfigSkipDestroy = testAccVolumeAttachmentConfigInstanceOnly + ` -resource "aws_ebs_volume" "test" { - availability_zone = "${data.aws_availability_zones.available.names[0]}" - size = 1 - - tags = { - Name = "tf-acc-test-volume-attachment" - } +`) } +func testAccVolumeAttachmentConfigSkipDestroy(rName string) string { + return testAccVolumeAttachmentConfigBase(rName) + fmt.Sprintf(` data "aws_ebs_volume" "test" { filter { - name = "size" + name = "size" values = ["${aws_ebs_volume.test.size}"] } filter { - name = "availability-zone" + name = "availability-zone" values = ["${aws_ebs_volume.test.availability_zone}"] } filter { - name = "tag:Name" + name = "tag:Name" values = ["tf-acc-test-volume-attachment"] } } @@ -381,27 +397,19 @@ resource "aws_volume_attachment" "test" { instance_id = "${aws_instance.test.id}" skip_destroy = true } -` - -func testAccVolumeAttachmentConfig_update(detach bool) string { - return testAccVolumeAttachmentConfigInstanceOnly + fmt.Sprintf(` -resource "aws_ebs_volume" "test" { - availability_zone = "${data.aws_availability_zones.available.names[0]}" - size = 1 - - tags = { - Name = "tf-acc-test-volume-attachment" - } +`) } +func testAccVolumeAttachmentUpdateConfig(rName string, detach bool) string { + return testAccVolumeAttachmentConfigBase(rName) + fmt.Sprintf(` resource "aws_volume_attachment" "test" { device_name = "/dev/sdh" volume_id = "${aws_ebs_volume.test.id}" instance_id = "${aws_instance.test.id}" - force_detach = %t - skip_destroy = %t + force_detach = %[1]t + skip_destroy = %[1]t } -`, detach, detach) +`, detach) } func testAccAWSVolumeAttachmentImportStateIDFunc(resourceName string) resource.ImportStateIdFunc { From d141274040ebaa1a40ea500b739c95c01552459e Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 10 Apr 2020 18:55:41 +0300 Subject: [PATCH 051/475] randomize resource names - fix oops --- aws/resource_aws_volume_attachment_test.go | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/aws/resource_aws_volume_attachment_test.go b/aws/resource_aws_volume_attachment_test.go index 1c56a7157a8..9f1a0b6dffd 100644 --- a/aws/resource_aws_volume_attachment_test.go +++ b/aws/resource_aws_volume_attachment_test.go @@ -343,19 +343,9 @@ resource "aws_instance" "test" { func testAccVolumeAttachmentConfigBase(rName string) string { return testAccVolumeAttachmentInstanceOnlyConfigBase(rName) + fmt.Sprintf(` -data "aws_availability_zones" "available" { - state = "available" - - filter { - name = "opt-in-status" - values = ["opt-in-not-required"] - } -} - -resource "aws_instance" "test" { - ami = "ami-21f78e11" +resource "aws_ebs_volume" "test" { availability_zone = "${data.aws_availability_zones.available.names[0]}" - instance_type = "t1.micro" + size = 1 tags = { Name = %[1]q From dd406bc93983852f25676fcf4bd177438870c3e7 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 10 Apr 2020 19:02:11 +0300 Subject: [PATCH 052/475] fix skip test data source filter --- aws/resource_aws_volume_attachment_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_volume_attachment_test.go b/aws/resource_aws_volume_attachment_test.go index 9f1a0b6dffd..d63b0c50152 100644 --- a/aws/resource_aws_volume_attachment_test.go +++ b/aws/resource_aws_volume_attachment_test.go @@ -377,7 +377,7 @@ data "aws_ebs_volume" "test" { } filter { name = "tag:Name" - values = ["tf-acc-test-volume-attachment"] + values = ["%[1]s"] } } @@ -387,7 +387,7 @@ resource "aws_volume_attachment" "test" { instance_id = "${aws_instance.test.id}" skip_destroy = true } -`) +`, rName) } func testAccVolumeAttachmentUpdateConfig(rName string, detach bool) string { From bbf81793c46b6e73a5b8d719c4405b8658e3f672 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 10 Apr 2020 19:09:54 +0300 Subject: [PATCH 053/475] add missing hashibot labeler --- .hashibot.hcl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.hashibot.hcl b/.hashibot.hcl index f8334a4bb71..f78aa3f79d0 100644 --- a/.hashibot.hcl +++ b/.hashibot.hcl @@ -232,6 +232,7 @@ behavior "regexp_issue_labeler_v2" "service_labels" { "aws_spot", "aws_route(\"|`|$)", "aws_vpn_", + "aws_volume_attachment", ], "service/ecr" = [ "aws_ecr_", @@ -805,6 +806,7 @@ behavior "pull_request_path_labeler" "service_labels" { "aws/*_aws_subnet*", "aws/*_aws_vpc*", "aws/*_aws_vpn*", + "aws/*_aws_volume_attachment*", "website/**/availability_zone*", "website/**/customer_gateway*", "website/**/default_network_acl*", @@ -833,7 +835,8 @@ behavior "pull_request_path_labeler" "service_labels" { "website/**/spot_*", "website/**/subnet*", "website/**/vpc*", - "website/**/vpn*" + "website/**/vpn*", + "website/**/volume_attachment*" ] "service/ecr" = [ "**/*_ecr_*", From f4d6fae855ad98a853bc3e584f27f4f43da48696 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Sat, 25 Apr 2020 22:33:04 +0300 Subject: [PATCH 054/475] use resource name variable --- aws/resource_aws_volume_attachment_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/aws/resource_aws_volume_attachment_test.go b/aws/resource_aws_volume_attachment_test.go index d63b0c50152..8f9fca65892 100644 --- a/aws/resource_aws_volume_attachment_test.go +++ b/aws/resource_aws_volume_attachment_test.go @@ -34,9 +34,9 @@ func TestAccAWSVolumeAttachment_basic(t *testing.T) { ), }, { - ResourceName: "aws_volume_attachment.ebs_att", + ResourceName: resourceName, ImportState: true, - ImportStateIdFunc: testAccAWSVolumeAttachmentImportStateIDFunc("aws_volume_attachment.ebs_att"), + ImportStateIdFunc: testAccAWSVolumeAttachmentImportStateIDFunc(resourceName), ImportStateVerify: true, }, }, @@ -64,9 +64,9 @@ func TestAccAWSVolumeAttachment_skipDestroy(t *testing.T) { ), }, { - ResourceName: "aws_volume_attachment.ebs_att", + ResourceName: resourceName, ImportState: true, - ImportStateIdFunc: testAccAWSVolumeAttachmentImportStateIDFunc("aws_volume_attachment.ebs_att"), + ImportStateIdFunc: testAccAWSVolumeAttachmentImportStateIDFunc(resourceName), ImportStateVerify: true, ImportStateVerifyIgnore: []string{ "skip_destroy", // attribute only used on resource deletion @@ -129,9 +129,9 @@ func TestAccAWSVolumeAttachment_attachStopped(t *testing.T) { ), }, { - ResourceName: "aws_volume_attachment.ebs_att", + ResourceName: resourceName, ImportState: true, - ImportStateIdFunc: testAccAWSVolumeAttachmentImportStateIDFunc("aws_volume_attachment.ebs_att"), + ImportStateIdFunc: testAccAWSVolumeAttachmentImportStateIDFunc(resourceName), ImportStateVerify: true, }, }, @@ -155,9 +155,9 @@ func TestAccAWSVolumeAttachment_update(t *testing.T) { ), }, { - ResourceName: "aws_volume_attachment.ebs_att", + ResourceName: resourceName, ImportState: true, - ImportStateIdFunc: testAccAWSVolumeAttachmentImportStateIDFunc("aws_volume_attachment.ebs_att"), + ImportStateIdFunc: testAccAWSVolumeAttachmentImportStateIDFunc(resourceName), ImportStateVerify: true, ImportStateVerifyIgnore: []string{ "force_detach", // attribute only used on resource deletion @@ -172,9 +172,9 @@ func TestAccAWSVolumeAttachment_update(t *testing.T) { ), }, { - ResourceName: "aws_volume_attachment.ebs_att", + ResourceName: resourceName, ImportState: true, - ImportStateIdFunc: testAccAWSVolumeAttachmentImportStateIDFunc("aws_volume_attachment.ebs_att"), + ImportStateIdFunc: testAccAWSVolumeAttachmentImportStateIDFunc(resourceName), ImportStateVerify: true, ImportStateVerifyIgnore: []string{ "force_detach", // attribute only used on resource deletion From 0e416b9b5b5ac09f3c3099e129fae61c63dbc36d Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Sat, 25 Apr 2020 22:39:10 +0300 Subject: [PATCH 055/475] remove hardcoded ami id and instance type --- aws/resource_aws_volume_attachment_test.go | 40 +++++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/aws/resource_aws_volume_attachment_test.go b/aws/resource_aws_volume_attachment_test.go index 8f9fca65892..9aa75b4f373 100644 --- a/aws/resource_aws_volume_attachment_test.go +++ b/aws/resource_aws_volume_attachment_test.go @@ -222,10 +222,10 @@ func testAccCheckVolumeAttachmentExists(n string, i *ec2.Instance, v *ec2.Volume } for _, b := range i.BlockDeviceMappings { - if rs.Primary.Attributes["device_name"] == *b.DeviceName { + if rs.Primary.Attributes["device_name"] == aws.StringValue(b.DeviceName) { if b.Ebs.VolumeId != nil && - rs.Primary.Attributes["volume_id"] == *b.Ebs.VolumeId && - rs.Primary.Attributes["volume_id"] == *v.VolumeId { + rs.Primary.Attributes["volume_id"] == aws.StringValue(b.Ebs.VolumeId) && + rs.Primary.Attributes["volume_id"] == aws.StringValue(v.VolumeId) { // pass return nil } @@ -329,10 +329,40 @@ data "aws_availability_zones" "available" { } } +data "aws_ami" "amzn-ami-minimal-hvm-ebs" { + most_recent = true + owners = ["amazon"] + + filter { + name = "name" + values = ["amzn-ami-minimal-hvm-*"] + } + + filter { + name = "root-device-type" + values = ["ebs"] + } +} + +data "aws_ec2_instance_type_offering" "available" { + filter { + name = "instance-type" + values = ["t3.micro", "t2.micro"] + } + + filter { + name = "location" + values = [aws_subnet.test.availability_zone] + } + + location_type = "availability-zone" + preferred_instance_types = ["t3.micro", "t2.micro"] +} + resource "aws_instance" "test" { - ami = "ami-21f78e11" + ami = "${data.aws_ami.amzn-ami-minimal-hvm-ebs.id}" availability_zone = "${data.aws_availability_zones.available.names[0]}" - instance_type = "t1.micro" + instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" tags = { Name = %[1]q From bee91066022a65ef602ec06b38a7d199b3de11cf Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Sat, 25 Apr 2020 22:40:26 +0300 Subject: [PATCH 056/475] remove hardcoded ami id and instance type --- aws/resource_aws_volume_attachment_test.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/aws/resource_aws_volume_attachment_test.go b/aws/resource_aws_volume_attachment_test.go index 9aa75b4f373..1c6ec3e18bb 100644 --- a/aws/resource_aws_volume_attachment_test.go +++ b/aws/resource_aws_volume_attachment_test.go @@ -350,11 +350,6 @@ data "aws_ec2_instance_type_offering" "available" { values = ["t3.micro", "t2.micro"] } - filter { - name = "location" - values = [aws_subnet.test.availability_zone] - } - location_type = "availability-zone" preferred_instance_types = ["t3.micro", "t2.micro"] } From f22b06e69ccbb3db2023fbba28e22264c44a534c Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Sun, 26 Apr 2020 09:52:48 +0300 Subject: [PATCH 057/475] reuse --- aws/resource_aws_volume_attachment_test.go | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/aws/resource_aws_volume_attachment_test.go b/aws/resource_aws_volume_attachment_test.go index 1c6ec3e18bb..9153de6a2be 100644 --- a/aws/resource_aws_volume_attachment_test.go +++ b/aws/resource_aws_volume_attachment_test.go @@ -319,7 +319,7 @@ func testAccCheckVolumeAttachmentDestroy(s *terraform.State) error { } func testAccVolumeAttachmentInstanceOnlyConfigBase(rName string) string { - return fmt.Sprintf(` + return testAccLatestAmazonLinuxHvmEbsAmiConfig() + fmt.Sprintf(` data "aws_availability_zones" "available" { state = "available" @@ -329,21 +329,6 @@ data "aws_availability_zones" "available" { } } -data "aws_ami" "amzn-ami-minimal-hvm-ebs" { - most_recent = true - owners = ["amazon"] - - filter { - name = "name" - values = ["amzn-ami-minimal-hvm-*"] - } - - filter { - name = "root-device-type" - values = ["ebs"] - } -} - data "aws_ec2_instance_type_offering" "available" { filter { name = "instance-type" From a37093b183436b2e0c7c85495a1799e210837e13 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Thu, 7 May 2020 21:29:26 +0300 Subject: [PATCH 058/475] refactor disappears func --- aws/resource_aws_volume_attachment_test.go | 52 +--------------------- 1 file changed, 1 insertion(+), 51 deletions(-) diff --git a/aws/resource_aws_volume_attachment_test.go b/aws/resource_aws_volume_attachment_test.go index 9153de6a2be..a00fe8db942 100644 --- a/aws/resource_aws_volume_attachment_test.go +++ b/aws/resource_aws_volume_attachment_test.go @@ -2,7 +2,6 @@ package aws import ( "fmt" - "log" "testing" "time" @@ -202,7 +201,7 @@ func TestAccAWSVolumeAttachment_disappears(t *testing.T) { testAccCheckInstanceExists("aws_instance.test", &i), testAccCheckVolumeExists("aws_ebs_volume.test", &v), testAccCheckVolumeAttachmentExists(resourceName, &i, &v), - testAccCheckVolumeAttachmentDisappears(resourceName, &i, &v), + testAccCheckResourceDisappears(testAccProvider, resourceAwsVolumeAttachment(), resourceName), ), ExpectNonEmptyPlan: true, }, @@ -236,55 +235,6 @@ func testAccCheckVolumeAttachmentExists(n string, i *ec2.Instance, v *ec2.Volume } } -func testAccCheckVolumeAttachmentDisappears(n string, i *ec2.Instance, v *ec2.Volume) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("Not found: %s", n) - } - - if rs.Primary.ID == "" { - return fmt.Errorf("No ID is set") - } - - conn := testAccProvider.Meta().(*AWSClient).ec2conn - - opts := &ec2.DetachVolumeInput{ - Device: aws.String(rs.Primary.Attributes["device_name"]), - InstanceId: i.InstanceId, - VolumeId: v.VolumeId, - Force: aws.Bool(true), - } - - _, err := conn.DetachVolume(opts) - if err != nil { - return err - } - - vId := aws.StringValue(v.VolumeId) - iId := aws.StringValue(i.InstanceId) - - stateConf := &resource.StateChangeConf{ - Pending: []string{ec2.VolumeAttachmentStateDetaching}, - Target: []string{ec2.VolumeAttachmentStateDetached}, - Refresh: volumeAttachmentStateRefreshFunc(conn, rs.Primary.Attributes["device_name"], vId, iId), - Timeout: 5 * time.Minute, - Delay: 10 * time.Second, - MinTimeout: 3 * time.Second, - } - - log.Printf("[DEBUG] Detaching Volume (%s) from Instance (%s)", vId, iId) - _, err = stateConf.WaitForState() - if err != nil { - return fmt.Errorf( - "Error waiting for Volume (%s) to detach from Instance (%s): %s", - vId, iId, err) - } - - return err - } -} - func testAccCheckVolumeAttachmentDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).ec2conn From e5e5adbd26c143d5a83f775659d5aa9f4c984c8b Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Sat, 25 Apr 2020 21:54:56 +0300 Subject: [PATCH 059/475] refactor iam saml provider to use arn package instead of custom logic + add tests --- aws/resource_aws_iam_saml_provider.go | 40 ++++++++--------- aws/resource_aws_iam_saml_provider_test.go | 51 ++++++++++++++++++++-- 2 files changed, 67 insertions(+), 24 deletions(-) diff --git a/aws/resource_aws_iam_saml_provider.go b/aws/resource_aws_iam_saml_provider.go index d114c881c00..41f8213ad42 100644 --- a/aws/resource_aws_iam_saml_provider.go +++ b/aws/resource_aws_iam_saml_provider.go @@ -3,13 +3,12 @@ package aws import ( "fmt" "log" - "regexp" + "strings" "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/iam" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) @@ -47,14 +46,14 @@ func resourceAwsIamSamlProvider() *schema.Resource { } func resourceAwsIamSamlProviderCreate(d *schema.ResourceData, meta interface{}) error { - iamconn := meta.(*AWSClient).iamconn + conn := meta.(*AWSClient).iamconn input := &iam.CreateSAMLProviderInput{ Name: aws.String(d.Get("name").(string)), SAMLMetadataDocument: aws.String(d.Get("saml_metadata_document").(string)), } - out, err := iamconn.CreateSAMLProvider(input) + out, err := conn.CreateSAMLProvider(input) if err != nil { return err } @@ -65,14 +64,14 @@ func resourceAwsIamSamlProviderCreate(d *schema.ResourceData, meta interface{}) } func resourceAwsIamSamlProviderRead(d *schema.ResourceData, meta interface{}) error { - iamconn := meta.(*AWSClient).iamconn + conn := meta.(*AWSClient).iamconn input := &iam.GetSAMLProviderInput{ SAMLProviderArn: aws.String(d.Id()), } - out, err := iamconn.GetSAMLProvider(input) + out, err := conn.GetSAMLProvider(input) if err != nil { - if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" { + if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") { log.Printf("[WARN] IAM SAML Provider %q not found.", d.Id()) d.SetId("") return nil @@ -81,7 +80,7 @@ func resourceAwsIamSamlProviderRead(d *schema.ResourceData, meta interface{}) er } d.Set("arn", d.Id()) - name, err := extractNameFromIAMSamlProviderArn(d.Id(), meta.(*AWSClient).partition) + name, err := extractNameFromIAMSamlProviderArn(d.Id()) if err != nil { return err } @@ -93,13 +92,13 @@ func resourceAwsIamSamlProviderRead(d *schema.ResourceData, meta interface{}) er } func resourceAwsIamSamlProviderUpdate(d *schema.ResourceData, meta interface{}) error { - iamconn := meta.(*AWSClient).iamconn + conn := meta.(*AWSClient).iamconn input := &iam.UpdateSAMLProviderInput{ SAMLProviderArn: aws.String(d.Id()), SAMLMetadataDocument: aws.String(d.Get("saml_metadata_document").(string)), } - _, err := iamconn.UpdateSAMLProvider(input) + _, err := conn.UpdateSAMLProvider(input) if err != nil { return err } @@ -108,22 +107,23 @@ func resourceAwsIamSamlProviderUpdate(d *schema.ResourceData, meta interface{}) } func resourceAwsIamSamlProviderDelete(d *schema.ResourceData, meta interface{}) error { - iamconn := meta.(*AWSClient).iamconn + conn := meta.(*AWSClient).iamconn input := &iam.DeleteSAMLProviderInput{ SAMLProviderArn: aws.String(d.Id()), } - _, err := iamconn.DeleteSAMLProvider(input) + _, err := conn.DeleteSAMLProvider(input) return err } -func extractNameFromIAMSamlProviderArn(arn, partition string) (string, error) { - // arn:aws:iam::123456789012:saml-provider/tf-salesforce-test - r := regexp.MustCompile(fmt.Sprintf("^arn:%s:iam::[0-9]{12}:saml-provider/(.+)$", partition)) - submatches := r.FindStringSubmatch(arn) - if len(submatches) != 2 { - return "", fmt.Errorf("Unable to extract name from a given ARN: %q", arn) +func extractNameFromIAMSamlProviderArn(samlArn string) (string, error) { + parsedArn, err := arn.Parse(samlArn) + if err != nil { + return "", fmt.Errorf("Unable to extract name from a given ARN: %q", parsedArn) } - return submatches[1], nil + + name := strings.TrimPrefix(parsedArn.Resource, "saml-provider/") + + return name, nil } diff --git a/aws/resource_aws_iam_saml_provider_test.go b/aws/resource_aws_iam_saml_provider_test.go index 28b60b6f8ab..d5c6a24738d 100644 --- a/aws/resource_aws_iam_saml_provider_test.go +++ b/aws/resource_aws_iam_saml_provider_test.go @@ -2,6 +2,7 @@ package aws import ( "fmt" + "regexp" "testing" "github.com/aws/aws-sdk-go/aws" @@ -24,6 +25,7 @@ func TestAccAWSIAMSamlProvider_basic(t *testing.T) { Config: testAccIAMSamlProviderConfig(rName), Check: resource.ComposeTestCheckFunc( testAccCheckIAMSamlProviderExists(resourceName), + testAccMatchResourceAttrGlobalARN(resourceName, "arn", "iam", regexp.MustCompile(`saml-provider/.+`)), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttrSet(resourceName, "saml_metadata_document"), ), @@ -45,8 +47,29 @@ func TestAccAWSIAMSamlProvider_basic(t *testing.T) { }) } +func TestAccAWSIAMSamlProvider_disappears(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_iam_saml_provider.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckIAMSamlProviderDestroy, + Steps: []resource.TestStep{ + { + Config: testAccIAMSamlProviderConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckIAMSamlProviderExists(resourceName), + testAccCheckIAMSamlProviderDisappears(resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + func testAccCheckIAMSamlProviderDestroy(s *terraform.State) error { - iamconn := testAccProvider.Meta().(*AWSClient).iamconn + conn := testAccProvider.Meta().(*AWSClient).iamconn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_iam_saml_provider" { @@ -56,7 +79,7 @@ func testAccCheckIAMSamlProviderDestroy(s *terraform.State) error { input := &iam.GetSAMLProviderInput{ SAMLProviderArn: aws.String(rs.Primary.ID), } - out, err := iamconn.GetSAMLProvider(input) + out, err := conn.GetSAMLProvider(input) if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") { continue @@ -85,8 +108,28 @@ func testAccCheckIAMSamlProviderExists(id string) resource.TestCheckFunc { return fmt.Errorf("No ID is set") } - iamconn := testAccProvider.Meta().(*AWSClient).iamconn - _, err := iamconn.GetSAMLProvider(&iam.GetSAMLProviderInput{ + conn := testAccProvider.Meta().(*AWSClient).iamconn + _, err := conn.GetSAMLProvider(&iam.GetSAMLProviderInput{ + SAMLProviderArn: aws.String(rs.Primary.ID), + }) + + return err + } +} + +func testAccCheckIAMSamlProviderDisappears(id string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[id] + if !ok { + return fmt.Errorf("Not Found: %s", id) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).iamconn + _, err := conn.DeleteSAMLProvider(&iam.DeleteSAMLProviderInput{ SAMLProviderArn: aws.String(rs.Primary.ID), }) From 2198d5c017cff25fc54e9fd07b4dc45369360a27 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Thu, 7 May 2020 22:08:39 +0300 Subject: [PATCH 060/475] use disappears test func --- aws/resource_aws_iam_saml_provider_test.go | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/aws/resource_aws_iam_saml_provider_test.go b/aws/resource_aws_iam_saml_provider_test.go index d5c6a24738d..fe6aadf2b64 100644 --- a/aws/resource_aws_iam_saml_provider_test.go +++ b/aws/resource_aws_iam_saml_provider_test.go @@ -60,7 +60,7 @@ func TestAccAWSIAMSamlProvider_disappears(t *testing.T) { Config: testAccIAMSamlProviderConfig(rName), Check: resource.ComposeTestCheckFunc( testAccCheckIAMSamlProviderExists(resourceName), - testAccCheckIAMSamlProviderDisappears(resourceName), + testAccCheckResourceDisappears(testAccProvider, resourceAwsIamSamlProvider(), resourceName), ), ExpectNonEmptyPlan: true, }, @@ -117,26 +117,6 @@ func testAccCheckIAMSamlProviderExists(id string) resource.TestCheckFunc { } } -func testAccCheckIAMSamlProviderDisappears(id string) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[id] - if !ok { - return fmt.Errorf("Not Found: %s", id) - } - - if rs.Primary.ID == "" { - return fmt.Errorf("No ID is set") - } - - conn := testAccProvider.Meta().(*AWSClient).iamconn - _, err := conn.DeleteSAMLProvider(&iam.DeleteSAMLProviderInput{ - SAMLProviderArn: aws.String(rs.Primary.ID), - }) - - return err - } -} - func testAccIAMSamlProviderConfig(rName string) string { return fmt.Sprintf(` resource "aws_iam_saml_provider" "test" { From 4d8b6d477bed5757d8d5ef5fee2b56fd323a8971 Mon Sep 17 00:00:00 2001 From: tf-release-bot Date: Fri, 8 May 2020 01:10:35 +0000 Subject: [PATCH 061/475] Cleanup after v2.61.0 release --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ec0361f141..689ded43ef6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ +## 2.62.0 (Unreleased) ## 2.61.0 (May 08, 2020) FEATURES: From fc36c9893c54393e68a50143bfd8b5608a1043bf Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Mon, 4 May 2020 17:16:29 -0700 Subject: [PATCH 062/475] refactor docs and add FAQ (+36 squashed commits) Squashed commits: [5a63f2c16] docs rename to info [c5f59c350] added automation column [1eb8f8bb5] refactor table [69e916147] made team deets look a little prettier [d8a17e4c6] remove triage WIP for now [1bc508703] all the labels [16d6057f4] all the labels [17e00f086] more labels [61abf2892] css hascks [2baaba82e] labels [29ebff847] label dictionary [f836f5d02] heading fix [e4bcd5c3b] heading fix [3cc15d6fd] heading fix [76b566921] heading fix [90fac88ea] heading fix [ab54df13e] more acc test split [3cad5f885] rename dev title [1226dfb32] CAPS [b8f4431fa] heading fun [7812068a2] another round of splitting [2a062002d] move roadmap, some other layout [fb923e216] first attempt at splitting [83d09b69e] remove trailing forum id [cecb06227] copy over FAQ [d56e2dd0a] lowercase the d [544db33f7] remove md from link names [d02cecf32] using link [a2e521ddf] reorder links to be consistent [3db9d4484] development > developing [8be60b508] fix requirements link [d0fa12fcc] create docs folder [f958d0ace] remove community source section [85c962931] punctuation [bacfd0a36] fix terrform.io link [8c066dcdb] fix some links (+1 squashed commit) Squashed commits: [56a3e58ba] slimmed down readme --- .github/CONTRIBUTING.md | 1222 ----------------- README.md | 97 +- info/CONTRIBUTING.md | 18 + info/DEVELOPMENT.md | 53 + info/FAQ.md | 65 + {.github => info}/MAINTAINING.md | 108 +- info/contributing/contribution-checklists.md | 567 ++++++++ .../issue-reporting-and-lifecycle.md | 77 ++ .../pullrequest-submission-and-lifecycle.md | 128 ++ .../running-and-writing-acceptance-tests.md | 439 ++++++ 10 files changed, 1477 insertions(+), 1297 deletions(-) delete mode 100644 .github/CONTRIBUTING.md create mode 100644 info/CONTRIBUTING.md create mode 100644 info/DEVELOPMENT.md create mode 100644 info/FAQ.md rename {.github => info}/MAINTAINING.md (60%) create mode 100644 info/contributing/contribution-checklists.md create mode 100644 info/contributing/issue-reporting-and-lifecycle.md create mode 100644 info/contributing/pullrequest-submission-and-lifecycle.md create mode 100644 info/contributing/running-and-writing-acceptance-tests.md diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md deleted file mode 100644 index e8548f92086..00000000000 --- a/.github/CONTRIBUTING.md +++ /dev/null @@ -1,1222 +0,0 @@ -# Contributing to Terraform - AWS Provider - -**First:** if you're unsure or afraid of _anything_, ask for help! You can -submit a work in progress (WIP) pull request, or file an issue with the parts -you know. We'll do our best to guide you in the right direction, and let you -know if there are guidelines we will need to follow. We want people to be able -to participate without fear of doing the wrong thing. - -Below are our expectations for contributors. Following these guidelines gives us -the best opportunity to work with you, by making sure we have the things we need -in order to make it happen. Doing your best to follow it will speed up our -ability to merge PRs and respond to issues. - - - -- [Issues](#issues) - - [Issue Reporting Checklists](#issue-reporting-checklists) - - [Bug Reports](#bug-reports) - - [Feature Requests](#feature-requests) - - [Questions](#questions) - - [Issue Lifecycle](#issue-lifecycle) -- [Pull Requests](#pull-requests) - - [Pull Request Lifecycle](#pull-request-lifecycle) - - [Checklists for Contribution](#checklists-for-contribution) - - [Documentation Update](#documentation-update) - - [Enhancement/Bugfix to a Resource](#enhancementbugfix-to-a-resource) - - [Adding Resource Import Support](#adding-resource-import-support) - - [Adding Resource Name Generation Support](#adding-resource-name-generation-support) - - [Adding Resource Tagging Support](#adding-resource-tagging-support) - - [New Resource](#new-resource) - - [New Service](#new-service) - - [New Region](#new-region) - - [Common Review Items](#common-review-items) - - [Go Coding Style](#go-coding-style) - - [Resource Contribution Guidelines](#resource-contribution-guidelines) - - [Acceptance Testing Guidelines](#acceptance-testing-guidelines) - - [Writing Acceptance Tests](#writing-acceptance-tests) - - [Acceptance Tests Often Cost Money to Run](#acceptance-tests-often-cost-money-to-run) - - [Running an Acceptance Test](#running-an-acceptance-test) - - [Writing an Acceptance Test](#writing-an-acceptance-test) - - [Writing and running Cross-Account Acceptance Tests](#writing-and-running-cross-account-acceptance-tests) - - [Writing and running Cross-Region Acceptance Tests](#writing-and-running-cross-region-acceptance-tests) - - - -## Issues - -### Issue Reporting Checklists - -We welcome issues of all kinds including feature requests, bug reports, and -general questions. Below you'll find checklists with guidelines for well-formed -issues of each type. - -#### [Bug Reports](https://github.com/terraform-providers/terraform-provider-aws/issues/new?template=Bug_Report.md) - - - [ ] __Test against latest release__: Make sure you test against the latest - released version. It is possible we already fixed the bug you're experiencing. - - - [ ] __Search for possible duplicate reports__: It's helpful to keep bug - reports consolidated to one thread, so do a quick search on existing bug - reports to check if anybody else has reported the same thing. You can [scope - searches by the label "bug"](https://github.com/terraform-providers/terraform-provider-aws/issues?q=is%3Aopen+is%3Aissue+label%3Abug) to help narrow things down. - - - [ ] __Include steps to reproduce__: Provide steps to reproduce the issue, - along with your `.tf` files, with secrets removed, so we can try to - reproduce it. Without this, it makes it much harder to fix the issue. - - - [ ] __For panics, include `crash.log`__: If you experienced a panic, please - create a [gist](https://gist.github.com) of the *entire* generated crash log - for us to look at. Double check no sensitive items were in the log. - -#### [Feature Requests](https://github.com/terraform-providers/terraform-provider-aws/issues/new?labels=enhancement&template=Feature_Request.md) - - - [ ] __Search for possible duplicate requests__: It's helpful to keep requests - consolidated to one thread, so do a quick search on existing requests to - check if anybody else has reported the same thing. You can [scope searches by - the label "enhancement"](https://github.com/terraform-providers/terraform-provider-aws/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement) to help narrow things down. - - - [ ] __Include a use case description__: In addition to describing the - behavior of the feature you'd like to see added, it's helpful to also lay - out the reason why the feature would be important and how it would benefit - Terraform users. - -#### [Questions](https://github.com/terraform-providers/terraform-provider-aws/issues/new?labels=question&template=Question.md) - - - [ ] __Search for answers in Terraform documentation__: We're happy to answer - questions in GitHub Issues, but it helps reduce issue churn and maintainer - workload if you work to [find answers to common questions in the - documentation](https://www.terraform.io/docs/providers/aws/index.html). Oftentimes Question issues result in documentation updates - to help future users, so if you don't find an answer, you can give us - pointers for where you'd expect to see it in the docs. - -### Issue Lifecycle - -1. The issue is reported. - -2. The issue is verified and categorized by a Terraform collaborator. - Categorization is done via GitHub labels. We generally use a two-label - system of (1) issue/PR type, and (2) section of the codebase. Type is - one of "bug", "enhancement", "documentation", or "question", and section - is usually the AWS service name. - -3. An initial triage process determines whether the issue is critical and must - be addressed immediately, or can be left open for community discussion. - -4. The issue is addressed in a pull request or commit. The issue number will be - referenced in the commit message so that the code that fixes it is clearly - linked. - -5. The issue is closed. Sometimes, valid issues will be closed because they are - tracked elsewhere or non-actionable. The issue is still indexed and - available for future viewers, or can be re-opened if necessary. - -## Pull Requests - -We appreciate direct contributions to the provider codebase. Here's what to -expect: - - * For pull requests that follow the guidelines, we will proceed to reviewing - and merging, following the provider team's review schedule. There may be some - internal or community discussion needed before we can complete this. - * Pull requests that don't follow the guidelines will be commented with what - they're missing. The person who submits the pull request or another community - member will need to address those requests before they move forward. - -### Pull Request Lifecycle - -1. [Fork the GitHub repository](https://help.github.com/en/articles/fork-a-repo), - modify the code, and [create a pull request](https://help.github.com/en/articles/creating-a-pull-request-from-a-fork). - You are welcome to submit your pull request for commentary or review before - it is fully completed by creating a [draft pull request](https://help.github.com/en/articles/about-pull-requests#draft-pull-requests) - or adding `[WIP]` to the beginning of the pull request title. - Please include specific questions or items you'd like feedback on. - -1. Once you believe your pull request is ready to be reviewed, ensure the - pull request is not a draft pull request by [marking it ready for review](https://help.github.com/en/articles/changing-the-stage-of-a-pull-request) - or removing `[WIP]` from the pull request title if necessary, and a - maintainer will review it. Follow [the checklists below](#checklists-for-contribution) - to help ensure that your contribution can be easily reviewed and potentially - merged. - -1. One of Terraform's provider team members will look over your contribution and - either approve it or provide comments letting you know if there is anything - left to do. We do our best to keep up with the volume of PRs waiting for - review, but it may take some time depending on the complexity of the work. - -1. Once all outstanding comments and checklist items have been addressed, your - contribution will be merged! Merged PRs will be included in the next - Terraform release. The provider team takes care of updating the CHANGELOG as - they merge. - -1. In some cases, we might decide that a PR should be closed without merging. - We'll make sure to provide clear reasoning when this happens. - -### Checklists for Contribution - -There are several different kinds of contribution, each of which has its own -standards for a speedy review. The following sections describe guidelines for -each type of contribution. - -#### Documentation Update - -The [Terraform AWS Provider's website source][website] is in this repository -along with the code and tests. Below are some common items that will get -flagged during documentation reviews: - -- [ ] __Reasoning for Change__: Documentation updates should include an explanation for why the update is needed. -- [ ] __Prefer AWS Documentation__: Documentation about AWS service features and valid argument values that are likely to update over time should link to AWS service user guides and API references where possible. -- [ ] __Large Example Configurations__: Example Terraform configuration that includes multiple resource definitions should be added to the repository `examples` directory instead of an individual resource documentation page. Each directory under `examples` should be self-contained to call `terraform apply` without special configuration. -- [ ] __Terraform Configuration Language Features__: Individual resource documentation pages and examples should refrain from highlighting particular Terraform configuration language syntax workarounds or features such as `variable`, `local`, `count`, and built-in functions. - -#### Enhancement/Bugfix to a Resource - -Working on existing resources is a great way to get started as a Terraform -contributor because you can work within existing code and tests to get a feel -for what to do. - -In addition to the below checklist, please see the [Common Review -Items](#common-review-items) sections for more specific coding and testing -guidelines. - - - [ ] __Acceptance test coverage of new behavior__: Existing resources each - have a set of [acceptance tests][acctests] covering their functionality. - These tests should exercise all the behavior of the resource. Whether you are - adding something or fixing a bug, the idea is to have an acceptance test that - fails if your code were to be removed. Sometimes it is sufficient to - "enhance" an existing test by adding an assertion or tweaking the config - that is used, but it's often better to add a new test. You can copy/paste an - existing test and follow the conventions you see there, modifying the test - to exercise the behavior of your code. - - [ ] __Documentation updates__: If your code makes any changes that need to - be documented, you should include those doc updates in the same PR. This - includes things like new resource attributes or changes in default values. - The [Terraform website][website] source is in this repo and includes - instructions for getting a local copy of the site up and running if you'd - like to preview your changes. - - [ ] __Well-formed Code__: Do your best to follow existing conventions you - see in the codebase, and ensure your code is formatted with `go fmt`. (The - Travis CI build will fail if `go fmt` has not been run on incoming code.) - The PR reviewers can help out on this front, and may provide comments with - suggestions on how to improve the code. - - [ ] __Vendor additions__: Create a separate PR if you are updating the vendor - folder. This is to avoid conflicts as the vendor versions tend to be fast- - moving targets. We will plan to merge the PR with this change first. - -#### Adding Resource Import Support - -Adding import support for Terraform resources will allow existing infrastructure to be managed within Terraform. This type of enhancement generally requires a small to moderate amount of code changes. - -Comprehensive code examples and information about resource import support can be found in the [Extending Terraform documentation](https://www.terraform.io/docs/extend/resources/import.html). - -In addition to the below checklist and the items noted in the Extending Terraform documentation, please see the [Common Review Items](#common-review-items) sections for more specific coding and testing guidelines. - -- [ ] _Resource Code Implementation_: In the resource code (e.g. `aws/resource_aws_service_thing.go`), implementation of `Importer` `State` function -- [ ] _Resource Acceptance Testing Implementation_: In the resource acceptance testing (e.g. `aws/resource_aws_service_thing_test.go`), implementation of `TestStep`s with `ImportState: true` -- [ ] _Resource Documentation Implementation_: In the resource documentation (e.g. `website/docs/r/service_thing.html.markdown`), addition of `Import` documentation section at the bottom of the page - -#### Adding Resource Name Generation Support - -Terraform AWS Provider resources can use shared logic to support and test name generation, where the operator can choose between an expected naming value, a generated naming value with a prefix, or a fully generated name. - -Implementing name generation support for Terraform AWS Provider resources requires the following, each with its own section below: - -- [ ] _Resource Name Generation Code Implementation_: In the resource code (e.g. `aws/resource_aws_service_thing.go`), implementation of `name_prefix` attribute, along with handling in `Create` function. -- [ ] _Resource Name Generation Testing Implementation_: In the resource acceptance testing (e.g. `aws/resource_aws_service_thing_test.go`), implementation of new acceptance test functions and configurations to exercise new naming logic. -- [ ] _Resource Name Generation Documentation Implementation_: In the resource documentation (e.g. `website/docs/r/service_thing.html.markdown`), addition of `name_prefix` argument and update of `name` argument description. - -##### Resource Name Generation Code Implementation - -- In the resource Go file (e.g. `aws/resource_aws_service_thing.go`), add the following Go import: `"github.com/terraform-providers/terraform-provider-aws/aws/internal/naming"` -- In the resource schema, add the new `name_prefix` attribute and adjust the `name` attribute to be `Optional`, `Computed`, and `ConflictsWith` the `name_prefix` attribute. Ensure to keep any existing schema fields on `name` such as `ValidateFunc`. e.g. - -```go -"name": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ConflictsWith: []string{"name_prefix"}, -}, -"name_prefix": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - ConflictsWith: []string{"name"}, -}, -``` - -- In the resource `Create` function, switch any calls from `d.Get("name").(string)` to instead use the `naming.Generate()` function, e.g. - -```go -name := naming.Generate(d.Get("name").(string), d.Get("name_prefix").(string)) - -// ... in AWS Go SDK Input types, etc. use aws.String(name) -``` - -##### Resource Name Generation Testing Implementation - -- In the resource testing (e.g. `aws/resource_aws_service_thing_test.go`), add the following Go import: `"github.com/terraform-providers/terraform-provider-aws/aws/internal/naming"` -- In the resource testing, implement two new tests named `_Name_Generated` and `_NamePrefix` with associated configurations, that verifies creating the resource without `name` and `name_prefix` arguments (for the former) and with only the `name_prefix` argument (for the latter). e.g. - -```go -func TestAccAWSServiceThing_Name_Generated(t *testing.T) { - var thing service.ServiceThing - resourceName := "aws_service_thing.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSServiceThingDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSServiceThingConfigNameGenerated(), - Check: resource.ComposeTestCheckFunc( - testAccCheckAWSServiceThingExists(resourceName, &thing), - naming.TestCheckResourceAttrNameGenerated(resourceName, "name"), - ), - }, - // If the resource supports import: - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccAWSServiceThing_NamePrefix(t *testing.T) { - var thing service.ServiceThing - resourceName := "aws_service_thing.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSServiceThingDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSServiceThingConfigNamePrefix("tf-acc-test-prefix-"), - Check: resource.ComposeTestCheckFunc( - testAccCheckAWSServiceThingExists(resourceName, &thing), - naming.TestCheckResourceAttrNameFromPrefix(resourceName, "name", "tf-acc-test-prefix-"), - ), - }, - // If the resource supports import: - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func testAccAWSServiceThingConfigNameGenerated() string { - return fmt.Sprintf(` -resource "aws_service_thing" "test" { - # ... other configuration ... -} -`) -} - -func testAccAWSServiceThingConfigNamePrefix(namePrefix string) string { - return fmt.Sprintf(` -resource "aws_service_thing" "test" { - # ... other configuration ... - - name_prefix = %[1]q -} -`, namePrefix) -} -``` - -##### Resource Code Generation Documentation Implementation - -- In the resource documentation (e.g. `website/docs/r/service_thing.html.markdown`), add the following to the arguments reference: - -```markdown -* `name_prefix` - (Optional) Creates a unique name beginning with the specified prefix. Conflicts with `name`. -``` - -- Adjust the existing `name` argument reference to ensure its denoted as `Optional`, includes a mention that it can be generated, and that it conflicts with `name_prefix`: - -```markdown -* `name` - (Optional) Name of the thing. If omitted, Terraform will assign a random, unique name. Conflicts with `name_prefix`. -``` - -#### Adding Resource Tagging Support - -AWS provides key-value metadata across many services and resources, which can be used for a variety of use cases including billing, ownership, and more. See the [AWS Tagging Strategy page](https://aws.amazon.com/answers/account-management/aws-tagging-strategies/) for more information about tagging at a high level. - -Implementing tagging support for Terraform AWS Provider resources requires the following, each with its own section below: - -- [ ] _Generated Service Tagging Code_: In the internal code generators (e.g. `aws/internal/keyvaluetags`), implementation and customization of how a service handles tagging, which is standardized for the resources. -- [ ] _Resource Tagging Code Implementation_: In the resource code (e.g. `aws/resource_aws_service_thing.go`), implementation of `tags` schema attribute, along with handling in `Create`, `Read`, and `Update` functions. -- [ ] _Resource Tagging Acceptance Testing Implementation_: In the resource acceptance testing (e.g. `aws/resource_aws_service_thing_test.go`), implementation of new acceptance test function and configurations to exercise new tagging logic. -- [ ] _Resource Tagging Documentation Implementation_: In the resource documentation (e.g. `website/docs/r/service_thing.html.markdown`), addition of `tags` argument - -See also a [full example pull request for implementing EKS tagging](https://github.com/terraform-providers/terraform-provider-aws/pull/10307). - -##### Adding Service to Tag Generating Code - -This step is only necessary for the first implementation and may have been previously completed. If so, move on to the next section. - -More details about this code generation, including fixes for potential error messages in this process, can be found in the [keyvaluetags documentation](../aws/internal/keyvaluetags/README.md). - -- Open the AWS Go SDK documentation for the service, e.g. for [`service/eks`](https://docs.aws.amazon.com/sdk-for-go/api/service/eks/). Note: there can be a delay between the AWS announcement and the updated AWS Go SDK documentation. -- Determine the "type" of tagging implementation. Some services will use a simple map style (`map[string]*string` in Go) while others will have a separate structure shape (`[]service.Tag` struct with `Key` and `Value` fields). - - - If the type is a map, add the AWS Go SDK service name (e.g. `eks`) to `mapServiceNames` in `aws/internal/keyvaluetags/generators/servicetags/main.go` - - Otherwise, if the type is a struct, add the AWS Go SDK service name (e.g. `eks`) to `sliceServiceNames` in `aws/internal/keyvaluetags/generators/servicetags/main.go`. If the struct name is not exactly `Tag`, it can be customized via the `ServiceTagType` function. If the struct key field is not exactly `Key`, it can be customized via the `ServiceTagTypeKeyField` function. If the struct value field is not exactly `Value`, it can be customized via the `ServiceTagTypeValueField` function. - -- Determine if the service API includes functionality for listing tags (usually a `ListTags` or `ListTagsForResource` API call) or updating tags (usually `TagResource` and `UntagResource` API calls). If so, add the AWS Go SDK service client information to `ServiceClientType` (along with the new required import) in `aws/internal/keyvaluetags/service_generation_customizations.go`, e.g. for EKS: - - ```go - case "eks": - funcType = reflect.TypeOf(eks.New) - ``` - - - If the service API includes functionality for listing tags, add the AWS Go SDK service name (e.g. `eks`) to `serviceNames` in `aws/internal/keyvaluetags/generators/listtags/main.go`. - - If the service API includes functionality for updating tags, add the AWS Go SDK service name (e.g. `eks`) to `serviceNames` in `aws/internal/keyvaluetags/generators/updatetags/main.go`. - -- Run `make gen` (`go generate ./...`) and ensure there are no errors via `make test` (`go test ./...`) - -##### Resource Tagging Code Implementation - -- In the resource Go file (e.g. `aws/resource_aws_eks_cluster.go`), add the following Go import: `"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"` -- In the resource schema, add `"tags": tagsSchema(),` -- If the API supports tagging on creation (the `Input` struct accepts a `Tags` field), in the resource `Create` function, implement the logic to convert the configuration tags into the service tags, e.g. with EKS Clusters: - - ```go - input := &eks.CreateClusterInput{ - /* ... other configuration ... */ - Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().EksTags(), - } - ``` - - If the service API does not allow passing an empty list, the logic can be adjusted similar to: - - ```go - input := &eks.CreateClusterInput{ - /* ... other configuration ... */ - } - - if v := d.Get("tags").(map[string]interface{}); len(v) > 0 { - input.Tags = keyvaluetags.New(v).IgnoreAws().EksTags() - } - ``` - -- Otherwise if the API does not support tagging on creation (the `Input` struct does not accept a `Tags` field), in the resource `Create` function, implement the logic to convert the configuration tags into the service API call to tag a resource, e.g. with ElasticSearch Domain: - - ```go - if v := d.Get("tags").(map[string]interface{}); len(v) > 0 { - if err := keyvaluetags.ElasticsearchserviceUpdateTags(conn, d.Id(), nil, v); err != nil { - return fmt.Errorf("error adding Elasticsearch Cluster (%s) tags: %s", d.Id(), err) - } - } - ``` - -- Some EC2 resources (for example [`aws_ec2_fleet`](https://www.terraform.io/docs/providers/aws/r/ec2_fleet.html)) have a `TagsSpecification` field in the `InputStruct` instead of a `Tags` field. In these cases the `ec2TagSpecificationsFromMap()` helper function should be used, e.g.: - - ```go - input := &ec2.CreateFleetInput{ - /* ... other configuration ... */ - TagSpecifications: ec2TagSpecificationsFromMap(d.Get("tags").(map[string]interface{}), ec2.ResourceTypeFleet), - } - ``` - -- In the resource `Read` function, implement the logic to convert the service tags to save them into the Terraform state for drift detection, e.g. with EKS Clusters (which had the tags available in the DescribeCluster API call): - - ```go - // Typically declared near conn := /* ... */ - ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig - - if err := d.Set("tags", keyvaluetags.EksKeyValueTags(cluster.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) - } - ``` - - If the service API does not return the tags directly from reading the resource and requires a separate API call, its possible to use the `keyvaluetags` functionality like the following, e.g. with Athena Workgroups: - - ```go - // Typically declared near conn := /* ... */ - ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig - - tags, err := keyvaluetags.AthenaListTags(conn, arn.String()) - - if err != nil { - return fmt.Errorf("error listing tags for resource (%s): %s", arn, err) - } - - if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) - } - ``` - -- In the resource `Update` function (this may be the first functionality requiring the creation of the `Update` function), implement the logic to handle tagging updates, e.g. with EKS Clusters: - - ```go - if d.HasChange("tags") { - o, n := d.GetChange("tags") - if err := keyvaluetags.EksUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { - return fmt.Errorf("error updating tags: %s", err) - } - } - ``` - -##### Resource Tagging Acceptance Testing Implementation - -- In the resource testing (e.g. `aws/resource_aws_eks_cluster_test.go`), verify that existing resources without tagging are unaffected and do not have tags saved into their Terraform state. This should be done in the `_basic` acceptance test by adding a line similar to `resource.TestCheckResourceAttr(resourceName, "tags.%s", "0"),` -- In the resource testing, implement a new test named `_Tags` with associated configurations, that verifies creating the resource with tags and updating tags. e.g. EKS Clusters: - - ```go - func TestAccAWSEksCluster_Tags(t *testing.T) { - var cluster1, cluster2, cluster3 eks.Cluster - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_eks_cluster.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSEks(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSEksClusterDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSEksClusterConfigTags1(rName, "key1", "value1"), - Check: resource.ComposeTestCheckFunc( - testAccCheckAWSEksClusterExists(resourceName, &cluster1), - resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), - resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccAWSEksClusterConfigTags2(rName, "key1", "value1updated", "key2", "value2"), - Check: resource.ComposeTestCheckFunc( - testAccCheckAWSEksClusterExists(resourceName, &cluster2), - resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), - resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), - resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), - ), - }, - { - Config: testAccAWSEksClusterConfigTags1(rName, "key2", "value2"), - Check: resource.ComposeTestCheckFunc( - testAccCheckAWSEksClusterExists(resourceName, &cluster3), - resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), - resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), - ), - }, - }, - }) - } - - func testAccAWSEksClusterConfigTags1(rName, tagKey1, tagValue1 string) string { - return testAccAWSEksClusterConfig_Base(rName) + fmt.Sprintf(` - resource "aws_eks_cluster" "test" { - name = %[1]q - role_arn = "${aws_iam_role.test.arn}" - - tags = { - %[2]q = %[3]q - } - - vpc_config { - subnet_ids = ["${aws_subnet.test.*.id[0]}", "${aws_subnet.test.*.id[1]}"] - } - - depends_on = ["aws_iam_role_policy_attachment.test-AmazonEKSClusterPolicy", "aws_iam_role_policy_attachment.test-AmazonEKSServicePolicy"] - } - `, rName, tagKey1, tagValue1) - } - - func testAccAWSEksClusterConfigTags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { - return testAccAWSEksClusterConfig_Base(rName) + fmt.Sprintf(` - resource "aws_eks_cluster" "test" { - name = %[1]q - role_arn = "${aws_iam_role.test.arn}" - - tags = { - %[2]q = %[3]q - %[4]q = %[5]q - } - - vpc_config { - subnet_ids = ["${aws_subnet.test.*.id[0]}", "${aws_subnet.test.*.id[1]}"] - } - - depends_on = ["aws_iam_role_policy_attachment.test-AmazonEKSClusterPolicy", "aws_iam_role_policy_attachment.test-AmazonEKSServicePolicy"] - } - `, rName, tagKey1, tagValue1, tagKey2, tagValue2) - } - ``` - -- Verify all acceptance testing passes for the resource (e.g. `make testacc TESTARGS='-run=TestAccAWSEksCluster_'`) - -#### Resource Tagging Documentation Implementation - -- In the resource documentation (e.g. `website/docs/r/eks_cluster.html.markdown`), add the following to the arguments reference: - - ```markdown - * `tags` - (Optional) Key-value mapping of resource tags - ``` - -#### New Resource - -Implementing a new resource is a good way to learn more about how Terraform -interacts with upstream APIs. There are plenty of examples to draw from in the -existing resources, but you still get to implement something completely new. - -In addition to the below checklist, please see the [Common Review -Items](#common-review-items) sections for more specific coding and testing -guidelines. - - - [ ] __Minimal LOC__: It's difficult for both the reviewer and author to go - through long feedback cycles on a big PR with many resources. We ask you to - only submit **1 resource at a time**. - - [ ] __Acceptance tests__: New resources should include acceptance tests - covering their behavior. See [Writing Acceptance - Tests](#writing-acceptance-tests) below for a detailed guide on how to - approach these. - - [ ] __Resource Naming__: Resources should be named `aws__`, - using underscores (`_`) as the separator. Resources are namespaced with the - service name to allow easier searching of related resources, to align - the resource naming with the service for [Customizing Endpoints](https://www.terraform.io/docs/providers/aws/guides/custom-service-endpoints.html#available-endpoint-customizations), - and to prevent future conflicts with new AWS services/resources. - For reference: - - - `service` is the AWS short service name that matches the entry in - `endpointServiceNames` (created via the [New Service](#new-service) - section) - - `name` represents the conceptual infrastructure represented by the - create, read, update, and delete methods of the service API. It should - be a singular noun. For example, in an API that has methods such as - `CreateThing`, `DeleteThing`, `DescribeThing`, and `ModifyThing` the name - of the resource would end in `_thing`. - - - [ ] __Arguments_and_Attributes__: The HCL for arguments and attributes should - mimic the types and structs presented by the AWS API. API arguments should be - converted from `CamelCase` to `camel_case`. - - [ ] __Documentation__: Each resource gets a page in the Terraform - documentation. The [Terraform website][website] source is in this - repo and includes instructions for getting a local copy of the site up and - running if you'd like to preview your changes. For a resource, you'll want - to add a new file in the appropriate place and add a link to the sidebar for - that page. - - [ ] __Well-formed Code__: Do your best to follow existing conventions you - see in the codebase, and ensure your code is formatted with `go fmt`. (The - Travis CI build will fail if `go fmt` has not been run on incoming code.) - The PR reviewers can help out on this front, and may provide comments with - suggestions on how to improve the code. - - [ ] __Vendor updates__: Create a separate PR if you are adding to the vendor - folder. This is to avoid conflicts as the vendor versions tend to be fast- - moving targets. We will plan to merge the PR with this change first. - -#### New Service - -Implementing a new AWS service gives Terraform the ability to manage resources in -a whole new API. It's a larger undertaking, but brings major new functionality -into Terraform. - -- [ ] __Service Client__: Before new resources are submitted, we request - a separate pull request containing just the new AWS Go SDK service client. - Doing so will pull the AWS Go SDK service code into the project at the - current version. Since the AWS Go SDK is updated frequently, these pull - requests can easily have merge conflicts or be out of date. The maintainers - prioritize reviewing and merging these quickly to prevent those situations. - - To add the AWS Go SDK service client: - - - In `aws/provider.go` Add a new service entry to `endpointServiceNames`. - This service name should match the AWS Go SDK or AWS CLI service name. - - In `aws/config.go`: Add a new import for the AWS Go SDK code. e.g. - `github.com/aws/aws-sdk-go/service/quicksight` - - In `aws/config.go`: Add a new `{SERVICE}conn` field to the `AWSClient` - struct for the service client. The service name should match the name - in `endpointServiceNames`. e.g. `quicksightconn *quicksight.QuickSight` - - In `aws/config.go`: Create the new service client in the `{SERVICE}conn` - field in the `AWSClient` instantiation within `Client()`. e.g. - `quicksightconn: quicksight.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["quicksight"])})),` - - In `website/allowed-subcategories.txt`: Add a name acceptable for the documentation navigation. - - In `website/docs/guides/custom-service-endpoints.html.md`: Add the service - name in the list of customizable endpoints. - - In `infrastructure/repository/labels-service.tf`: Add the new service to create a repository label. - - In `.hashibot.hcl`: Add the new service to automated issue and pull request labeling. e.g. with the `quicksight` service - - ```hcl - behavior "regexp_issue_labeler_v2" "service_labels" { - # ... other configuration ... - - label_map = { - # ... other services ... - "service/quicksight" = [ - "aws_quicksight_", - ], - # ... other services ... - } - } - - behavior "pull_request_path_labeler" "service_labels" - # ... other configuration ... - - label_map = { - # ... other services ... - "service/quicksight" = [ - "**/*_quicksight_*", - "**/quicksight_*", - ], - # ... other services ... - } - } - ``` - - - Run the following then submit the pull request: - - ```sh - go test ./aws - go mod tidy - go mod vendor - ``` - -- [ ] __Initial Resource__: Some services can be big and it can be - difficult for both reviewer & author to go through long feedback cycles - on a big PR with many resources. Often feedback items in one resource - will also need to be applied in other resources. We prefer you to submit - the necessary minimum in a single PR, ideally **just the first resource** - of the service. - -The initial resource and changes afterwards should follow the other sections -of this guide as appropriate. - -#### New Region - -While region validation is automatically added with SDK updates, new regions -are generally limited in which services they support. Below are some -manually sourced values from documentation. - - - [ ] Check [Elastic Load Balancing endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/elb.html#elb_region) and add Route53 Hosted Zone ID if available to `aws/data_source_aws_elb_hosted_zone_id.go` - - [ ] Check [Amazon Simple Storage Service endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/s3.html#s3_region) and add Route53 Hosted Zone ID if available to `aws/hosted_zones.go` - - [ ] Check [CloudTrail Supported Regions docs](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-supported-regions.html#cloudtrail-supported-regions) and add AWS Account ID if available to `aws/data_source_aws_cloudtrail_service_account.go` - - [ ] Check [Elastic Load Balancing Access Logs docs](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-access-logs.html#attach-bucket-policy) and add Elastic Load Balancing Account ID if available to `aws/data_source_aws_elb_service_account.go` - - [ ] Check [Redshift Database Audit Logging docs](https://docs.aws.amazon.com/redshift/latest/mgmt/db-auditing.html#db-auditing-bucket-permissions) and add AWS Account ID if available to `aws/data_source_aws_redshift_service_account.go` - - [ ] Check [AWS Elastic Beanstalk endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/elasticbeanstalk.html#elasticbeanstalk_region) and add Route53 Hosted Zone ID if available to `aws/data_source_aws_elastic_beanstalk_hosted_zone.go` - -### Common Review Items - -The Terraform AWS Provider follows common practices to ensure consistent and -reliable implementations across all resources in the project. While there may be -older resource and testing code that predates these guidelines, new submissions -are generally expected to adhere to these items to maintain Terraform Provider -quality. For any guidelines listed, contributors are encouraged to ask any -questions and community reviewers are encouraged to provide review suggestions -based on these guidelines to speed up the review and merge process. - -#### Go Coding Style - -The following Go language resources provide common coding preferences that may be referenced during review, if not automatically handled by the project's linting tools. - -- [Effective Go](https://golang.org/doc/effective_go.html) -- [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments) - -#### Resource Contribution Guidelines - -The following resource checks need to be addressed before your contribution can be merged. The exclusion of any applicable check may result in a delayed time to merge. - -- [ ] __Passes Testing__: All code and documentation changes must pass unit testing, code linting, and website link testing. Resource code changes must pass all acceptance testing for the resource. -- [ ] __Avoids API Calls Across Account, Region, and Service Boundaries__: Resources should not implement cross-account, cross-region, or cross-service API calls. -- [ ] __Avoids Optional and Required for Non-Configurable Attributes__: Resource schema definitions for read-only attributes should not include `Optional: true` or `Required: true`. -- [ ] __Avoids resource.Retry() without resource.RetryableError()__: Resource logic should only implement [`resource.Retry()`](https://godoc.org/github.com/hashicorp/terraform/helper/resource#Retry) if there is a retryable condition (e.g. `return resource.RetryableError(err)`). -- [ ] __Avoids Resource Read Function in Data Source Read Function__: Data sources should fully implement their own resource `Read` functionality including duplicating `d.Set()` calls. -- [ ] __Avoids Reading Schema Structure in Resource Code__: The resource `Schema` should not be read in resource `Create`/`Read`/`Update`/`Delete` functions to perform looping or otherwise complex attribute logic. Use [`d.Get()`](https://godoc.org/github.com/hashicorp/terraform/helper/schema#ResourceData.Get) and [`d.Set()`](https://godoc.org/github.com/hashicorp/terraform/helper/schema#ResourceData.Set) directly with individual attributes instead. -- [ ] __Avoids ResourceData.GetOkExists()__: Resource logic should avoid using [`ResourceData.GetOkExists()`](https://godoc.org/github.com/hashicorp/terraform/helper/schema#ResourceData.GetOkExists) as its expected functionality is not guaranteed in all scenarios. -- [ ] __Implements Read After Create and Update__: Except where API eventual consistency prohibits immediate reading of resources or updated attributes, resource `Create` and `Update` functions should return the resource `Read` function. -- [ ] __Implements Immediate Resource ID Set During Create__: Immediately after calling the API creation function, the resource ID should be set with [`d.SetId()`](https://godoc.org/github.com/hashicorp/terraform/helper/schema#ResourceData.SetId) before other API operations or returning the `Read` function. -- [ ] __Implements Attribute Refreshes During Read__: All attributes available in the API should have [`d.Set()`](https://godoc.org/github.com/hashicorp/terraform/helper/schema#ResourceData.Set) called their values in the Terraform state during the `Read` function. -- [ ] __Implements Error Checks with Non-Primative Attribute Refreshes__: When using [`d.Set()`](https://godoc.org/github.com/hashicorp/terraform/helper/schema#ResourceData.Set) with non-primative types (`schema.TypeList`, `schema.TypeSet`, or `schema.TypeMap`), perform error checking to [prevent issues where the code is not properly able to refresh the Terraform state](https://www.terraform.io/docs/extend/best-practices/detecting-drift.html#error-checking-aggregate-types). -- [ ] __Implements Import Acceptance Testing and Documentation__: Support for resource import (`Importer` in resource schema) must include `ImportState` acceptance testing (see also the [Acceptance Testing Guidelines](#acceptance-testing-guidelines) below) and `## Import` section in resource documentation. -- [ ] __Implements Customizable Timeouts Documentation__: Support for customizable timeouts (`Timeouts` in resource schema) must include `## Timeouts` section in resource documentation. -- [ ] __Implements State Migration When Adding New Virtual Attribute__: For new "virtual" attributes (those only in Terraform and not in the API), the schema should implement [State Migration](https://www.terraform.io/docs/extend/resources.html#state-migrations) to prevent differences for existing configurations that upgrade. -- [ ] __Uses AWS Go SDK Constants__: Many AWS services provide string constants for value enumerations, error codes, and status types. See also the "Constants" sections under each of the service packages in the [AWS Go SDK documentation](https://docs.aws.amazon.com/sdk-for-go/api/). -- [ ] __Uses AWS Go SDK Pointer Conversion Functions__: Many APIs return pointer types and these functions return the zero value for the type if the pointer is `nil`. This prevents potential panics from unchecked `*` pointer dereferences and can eliminate boilerplate `nil` checking in many cases. See also the [`aws` package in the AWS Go SDK documentation](https://docs.aws.amazon.com/sdk-for-go/api/aws/). -- [ ] __Uses AWS Go SDK Types__: Use available SDK structs instead of implementing custom types with indirection. -- [ ] __Uses TypeList and MaxItems: 1__: Configuration block attributes (e.g. `Type: schema.TypeList` or `Type: schema.TypeSet` with `Elem: &schema.Resource{...}`) that can only have one block should use `Type: schema.TypeList` and `MaxItems: 1` in the schema definition. -- [ ] __Uses Existing Validation Functions__: Schema definitions including `ValidateFunc` for attribute validation should use available [Terraform `helper/validation` package](https://godoc.org/github.com/hashicorp/terraform/helper/validation) functions. `All()`/`Any()` can be used for combining multiple validation function behaviors. -- [ ] __Uses isResourceTimeoutError() with resource.Retry()__: Resource logic implementing [`resource.Retry()`](https://godoc.org/github.com/hashicorp/terraform/helper/resource#Retry) should error check with `isResourceTimeoutError(err error)` and potentially unset the error before returning the error. For example: - - ```go - var output *kms.CreateKeyOutput - err := resource.Retry(1*time.Minute, func() *resource.RetryError { - var err error - - output, err = conn.CreateKey(input) - - /* ... */ - - return nil - }) - - if isResourceTimeoutError(err) { - output, err = conn.CreateKey(input) - } - - if err != nil { - return fmt.Errorf("error creating KMS External Key: %s", err) - } - ``` - -- [ ] __Uses resource.NotFoundError__: Custom errors for missing resources should use [`resource.NotFoundError`](https://godoc.org/github.com/hashicorp/terraform/helper/resource#NotFoundError). -- [ ] __Uses resource.UniqueId()__: API fields for concurrency protection such as `CallerReference` and `IdempotencyToken` should use [`resource.UniqueId()`](https://godoc.org/github.com/hashicorp/terraform/helper/resource#UniqueId). The implementation includes a monotonic counter which is safer for concurrent operations than solutions such as `time.Now()`. -- [ ] __Skips Exists Function__: Implementing a resource `Exists` function is extraneous as it often duplicates resource `Read` functionality. Ensure `d.SetId("")` is used to appropriately trigger resource recreation in the resource `Read` function. -- [ ] __Skips id Attribute__: The `id` attribute is implicit for all Terraform resources and does not need to be defined in the schema. - -The below are style-based items that _may_ be noted during review and are recommended for simplicity, consistency, and quality assurance: - -- [ ] __Avoids CustomizeDiff__: Usage of `CustomizeDiff` is generally discouraged. -- [ ] __Implements Error Message Context__: Returning errors from resource `Create`, `Read`, `Update`, and `Delete` functions should include additional messaging about the location or cause of the error for operators and code maintainers by wrapping with [`fmt.Errorf()`](https://godoc.org/golang.org/x/exp/errors/fmt#Errorf). - - An example `Delete` API error: `return fmt.Errorf("error deleting {SERVICE} {THING} (%s): %s", d.Id(), err)` - - An example `d.Set()` error: `return fmt.Errorf("error setting {ATTRIBUTE}: %s", err)` -- [ ] __Implements arn Attribute__: APIs that return an Amazon Resource Name (ARN), should implement `arn` as an attribute. -- [ ] __Implements Warning Logging With Resource State Removal__: If a resource is removed outside of Terraform (e.g. via different tool, API, or web UI), `d.SetId("")` and `return nil` can be used in the resource `Read` function to trigger resource recreation. When this occurs, a warning log message should be printed beforehand: `log.Printf("[WARN] {SERVICE} {THING} (%s) not found, removing from state", d.Id())` -- [ ] __Uses isAWSErr() with AWS Go SDK Error Objects__: Use the available `isAWSErr(err error, code string, message string)` helper function instead of the `awserr` package to compare error code and message contents. -- [ ] __Uses %s fmt Verb with AWS Go SDK Objects__: AWS Go SDK objects implement `String()` so using the `%v`, `%#v`, or `%+v` fmt verbs with the object are extraneous or provide unhelpful detail. -- [ ] __Uses Elem with TypeMap__: While provider schema validation does not error when the `Elem` configuration is not present with `Type: schema.TypeMap` attributes, including the explicit `Elem: &schema.Schema{Type: schema.TypeString}` is recommended. -- [ ] __Uses American English for Attribute Naming__: For any ambiguity with attribute naming, prefer American English over British English. e.g. `color` instead of `colour`. -- [ ] __Skips Timestamp Attributes__: Generally, creation and modification dates from the API should be omitted from the schema. -- [ ] __Skips Error() Call with AWS Go SDK Error Objects__: Error objects do not need to have `Error()` called. - -#### Acceptance Testing Guidelines - -The below are required items that will be noted during submission review and prevent immediate merging: - -- [ ] __Implements CheckDestroy__: Resource testing should include a `CheckDestroy` function (typically named `testAccCheckAws{SERVICE}{RESOURCE}Destroy`) that calls the API to verify that the Terraform resource has been deleted or disassociated as appropriate. More information about `CheckDestroy` functions can be found in the [Extending Terraform TestCase documentation](https://www.terraform.io/docs/extend/testing/acceptance-tests/testcase.html#checkdestroy). -- [ ] __Implements Exists Check Function__: Resource testing should include a `TestCheckFunc` function (typically named `testAccCheckAws{SERVICE}{RESOURCE}Exists`) that calls the API to verify that the Terraform resource has been created or associated as appropriate. Preferably, this function will also accept a pointer to an API object representing the Terraform resource from the API response that can be set for potential usage in later `TestCheckFunc`. More information about these functions can be found in the [Extending Terraform Custom Check Functions documentation](https://www.terraform.io/docs/extend/testing/acceptance-tests/testcase.html#checkdestroy). -- [ ] __Excludes Provider Declarations__: Test configurations should not include `provider "aws" {...}` declarations. If necessary, only the provider declarations in `provider_test.go` should be used for multiple account/region or otherwise specialized testing. -- [ ] __Passes in us-west-2 Region__: Tests default to running in `us-west-2` and at a minimum should pass in that region or include necessary `PreCheck` functions to skip the test when ran outside an expected environment. -- [ ] __Uses resource.ParallelTest__: Tests should utilize [`resource.ParallelTest()`](https://godoc.org/github.com/hashicorp/terraform/helper/resource#ParallelTest) instead of [`resource.Test()`](https://godoc.org/github.com/hashicorp/terraform/helper/resource#Test) except where serialized testing is absolutely required. -- [ ] __Uses fmt.Sprintf()__: Test configurations preferably should to be separated into their own functions (typically named `testAccAws{SERVICE}{RESOURCE}Config{PURPOSE}`) that call [`fmt.Sprintf()`](https://golang.org/pkg/fmt/#Sprintf) for variable injection or a string `const` for completely static configurations. Test configurations should avoid `var` or other variable injection functionality such as [`text/template`](https://golang.org/pkg/text/template/). -- [ ] __Uses Randomized Infrastructure Naming__: Test configurations that utilize resources where a unique name is required should generate a random name. Typically this is created via `rName := acctest.RandomWithPrefix("tf-acc-test")` in the acceptance test function before generating the configuration. - -For resources that support import, the additional item below is required that will be noted during submission review and prevent immediate merging: - -- [ ] __Implements ImportState Testing__: Tests should include an additional `TestStep` configuration that verifies resource import via `ImportState: true` and `ImportStateVerify: true`. This `TestStep` should be added to all possible tests for the resource to ensure that all infrastructure configurations are properly imported into Terraform. - -The below are style-based items that _may_ be noted during review and are recommended for simplicity, consistency, and quality assurance: - -- [ ] __Uses Builtin Check Functions__: Tests should utilize already available check functions, e.g. `resource.TestCheckResourceAttr()`, to verify values in the Terraform state over creating custom `TestCheckFunc`. More information about these functions can be found in the [Extending Terraform Builtin Check Functions documentation](https://www.terraform.io/docs/extend/testing/acceptance-tests/teststep.html#builtin-check-functions). -- [ ] __Uses TestCheckResoureAttrPair() for Data Sources__: Tests should utilize [`resource.TestCheckResourceAttrPair()`](https://godoc.org/github.com/hashicorp/terraform/helper/resource#TestCheckResourceAttrPair) to verify values in the Terraform state for data sources attributes to compare them with their expected resource attributes. -- [ ] __Excludes Timeouts Configurations__: Test configurations should not include `timeouts {...}` configuration blocks except for explicit testing of customizable timeouts (typically very short timeouts with `ExpectError`). -- [ ] __Implements Default and Zero Value Validation__: The basic test for a resource (typically named `TestAccAws{SERVICE}{RESOURCE}_basic`) should utilize available check functions, e.g. `resource.TestCheckResourceAttr()`, to verify default and zero values in the Terraform state for all attributes. Empty/missing configuration blocks can be verified with `resource.TestCheckResourceAttr(resourceName, "{ATTRIBUTE}.#", "0")` and empty maps with `resource.TestCheckResourceAttr(resourceName, "{ATTRIBUTE}.%", "0")` - -The below are location-based items that _may_ be noted during review and are recommended for consistency with testing flexibility. Resource testing is expected to pass across multiple AWS environments supported by the Terraform AWS Provider (e.g. AWS Standard and AWS GovCloud (US)). Contributors are not expected or required to perform testing outside of AWS Standard, e.g. running only in the `us-west-2` region is perfectly acceptable, however these are provided for reference: - -- [ ] __Uses aws_ami Data Source__: Any hardcoded AMI ID configuration, e.g. `ami-12345678`, should be replaced with the [`aws_ami` data source](https://www.terraform.io/docs/providers/aws/d/ami.html) pointing to an Amazon Linux image. A common pattern is a configuration like the below, which will likely be moved into a common configuration function in the future: - - ```hcl - data "aws_ami" "amzn-ami-minimal-hvm-ebs" { - most_recent = true - owners = ["amazon"] - - filter { - name = "name" - values = ["amzn-ami-minimal-hvm-*"] - } - filter { - name = "root-device-type" - values = ["ebs"] - } - } - ``` - -- [ ] __Uses aws_availability_zones Data Source__: Any hardcoded AWS Availability Zone configuration, e.g. `us-west-2a`, should be replaced with the [`aws_availability_zones` data source](https://www.terraform.io/docs/providers/aws/d/availability_zones.html). A common pattern is declaring `data "aws_availability_zones" "available" {...}` and referencing it via `data.aws_availability_zones.available.names[0]` or `data.aws_availability_zones.available.names[count.index]` in resources utilizing `count`. - - ```hcl - data "aws_availability_zones" "available" { - state = "available" - - filter { - name = "opt-in-status" - values = ["opt-in-not-required"] - } - } - ``` - -- [ ] __Uses aws_region Data Source__: Any hardcoded AWS Region configuration, e.g. `us-west-2`, should be replaced with the [`aws_region` data source](https://www.terraform.io/docs/providers/aws/d/region.html). A common pattern is declaring `data "aws_region" "current" {}` and referencing it via `data.aws_region.current.name` -- [ ] __Uses aws_partition Data Source__: Any hardcoded AWS Partition configuration, e.g. the `aws` in a `arn:aws:SERVICE:REGION:ACCOUNT:RESOURCE` ARN, should be replaced with the [`aws_partition` data source](https://www.terraform.io/docs/providers/aws/d/partition.html). A common pattern is declaring `data "aws_partition" "current" {}` and referencing it via `data.aws_partition.current.partition` -- [ ] __Uses Builtin ARN Check Functions__: Tests should utilize available ARN check functions, e.g. `testAccMatchResourceAttrRegionalARN()`, to validate ARN attribute values in the Terraform state over `resource.TestCheckResourceAttrSet()` and `resource.TestMatchResourceAttr()` -- [ ] __Uses testAccCheckResourceAttrAccountID()__: Tests should utilize the available AWS Account ID check function, `testAccCheckResourceAttrAccountID()` to validate account ID attribute values in the Terraform state over `resource.TestCheckResourceAttrSet()` and `resource.TestMatchResourceAttr()` - -### Writing Acceptance Tests - -Terraform includes an acceptance test harness that does most of the repetitive -work involved in testing a resource. For additional information about testing -Terraform Providers, see the [Extending Terraform documentation](https://www.terraform.io/docs/extend/testing/index.html). - -#### Acceptance Tests Often Cost Money to Run - -Because acceptance tests create real resources, they often cost money to run. -Because the resources only exist for a short period of time, the total amount -of money required is usually a relatively small. Nevertheless, we don't want -financial limitations to be a barrier to contribution, so if you are unable to -pay to run acceptance tests for your contribution, mention this in your -pull request. We will happily accept "best effort" implementations of -acceptance tests and run them for you on our side. This might mean that your PR -takes a bit longer to merge, but it most definitely is not a blocker for -contributions. - -#### Running an Acceptance Test - -Acceptance tests can be run using the `testacc` target in the Terraform -`Makefile`. The individual tests to run can be controlled using a regular -expression. Prior to running the tests provider configuration details such as -access keys must be made available as environment variables. - -For example, to run an acceptance test against the Amazon Web Services -provider, the following environment variables must be set: - -```sh -# Using a profile -export AWS_PROFILE=... -# Otherwise -export AWS_ACCESS_KEY_ID=... -export AWS_SECRET_ACCESS_KEY=... -export AWS_DEFAULT_REGION=... -``` - -Please note that the default region for the testing is `us-west-2` and must be -overriden via the `AWS_DEFAULT_REGION` environment variable, if necessary. This -is especially important for testing AWS GovCloud (US), which requires: - -```sh -export AWS_DEFAULT_REGION=us-gov-west-1 -``` - -Tests can then be run by specifying the target provider and a regular -expression defining the tests to run: - -```sh -$ make testacc TEST=./aws TESTARGS='-run=TestAccAWSCloudWatchDashboard_update' -==> Checking that code complies with gofmt requirements... -TF_ACC=1 go test ./aws -v -run=TestAccAWSCloudWatchDashboard_update -timeout 120m -=== RUN TestAccAWSCloudWatchDashboard_update ---- PASS: TestAccAWSCloudWatchDashboard_update (26.56s) -PASS -ok github.com/terraform-providers/terraform-provider-aws/aws 26.607s -``` - -Entire resource test suites can be targeted by using the naming convention to -write the regular expression. For example, to run all tests of the -`aws_cloudwatch_dashboard` resource rather than just the update test, you can start -testing like this: - -```sh -$ make testacc TEST=./aws TESTARGS='-run=TestAccAWSCloudWatchDashboard' -==> Checking that code complies with gofmt requirements... -TF_ACC=1 go test ./aws -v -run=TestAccAWSCloudWatchDashboard -timeout 120m -=== RUN TestAccAWSCloudWatchDashboard_importBasic ---- PASS: TestAccAWSCloudWatchDashboard_importBasic (15.06s) -=== RUN TestAccAWSCloudWatchDashboard_basic ---- PASS: TestAccAWSCloudWatchDashboard_basic (12.70s) -=== RUN TestAccAWSCloudWatchDashboard_update ---- PASS: TestAccAWSCloudWatchDashboard_update (27.81s) -PASS -ok github.com/terraform-providers/terraform-provider-aws/aws 55.619s -``` - -Please Note: On macOS 10.14 and later (and some Linux distributions), the default user open file limit is 256. This may cause unexpected issues when running the acceptance testing since this can prevent various operations from occurring such as opening network connections to AWS. To view this limit, the `ulimit -n` command can be run. To update this limit, run `ulimit -n 1024` (or higher). - -#### Writing an Acceptance Test - -Terraform has a framework for writing acceptance tests which minimises the -amount of boilerplate code necessary to use common testing patterns. The entry -point to the framework is the `resource.ParallelTest()` function. - -Tests are divided into `TestStep`s. Each `TestStep` proceeds by applying some -Terraform configuration using the provider under test, and then verifying that -results are as expected by making assertions using the provider API. It is -common for a single test function to exercise both the creation of and updates -to a single resource. Most tests follow a similar structure. - -1. Pre-flight checks are made to ensure that sufficient provider configuration - is available to be able to proceed - for example in an acceptance test - targeting AWS, `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` must be set prior - to running acceptance tests. This is common to all tests exercising a single - provider. - -Each `TestStep` is defined in the call to `resource.ParallelTest()`. Most assertion -functions are defined out of band with the tests. This keeps the tests -readable, and allows reuse of assertion functions across different tests of the -same type of resource. The definition of a complete test looks like this: - -```go -func TestAccAWSCloudWatchDashboard_basic(t *testing.T) { - var dashboard cloudwatch.GetDashboardOutput - rInt := acctest.RandInt() - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSCloudWatchDashboardDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSCloudWatchDashboardConfig(rInt), - Check: resource.ComposeTestCheckFunc( - testAccCheckCloudWatchDashboardExists("aws_cloudwatch_dashboard.foobar", &dashboard), - resource.TestCheckResourceAttr("aws_cloudwatch_dashboard.foobar", "dashboard_name", testAccAWSCloudWatchDashboardName(rInt)), - ), - }, - }, - }) -} -``` - -When executing the test, the following steps are taken for each `TestStep`: - -1. The Terraform configuration required for the test is applied. This is - responsible for configuring the resource under test, and any dependencies it - may have. For example, to test the `aws_cloudwatch_dashboard` resource, a valid configuration with the requisite fields is required. This results in configuration which looks like this: - - ```hcl - resource "aws_cloudwatch_dashboard" "foobar" { - dashboard_name = "terraform-test-dashboard-%d" - dashboard_body = < + Terraform logo + -- Website: https://www.terraform.io -- [![Gitter chat](https://badges.gitter.im/hashicorp-terraform/Lobby.png)](https://gitter.im/hashicorp-terraform/Lobby) -- Mailing list: [Google Groups](http://groups.google.com/group/terraform-tool) +# Terraform Provider for AWS - +[![Build Status][travis-badge]][travis] +[![Forums][discuss-badge]][discuss] +[![GoReportCard][report-badge]][report] -Requirements ------------- +[travis-badge]: https://api.travis-ci.org/terraform-providers/terraform-provider-aws.svg?branch=master +[travis]: https://travis-ci.org/github/terraform-providers/terraform-provider-aws +[discuss-badge]: https://img.shields.io/badge/discuss-terraform--aws-623CE4.svg?style=flat +[discuss]: https://discuss.hashicorp.com/c/terraform-providers/tf-aws/ +[report-badge]: https://goreportcard.com/badge/github.com/terraform-providers/terraform-provider-aws +[report]: https://goreportcard.com/report/github.com/terraform-providers/terraform-provider-aws -- [Terraform](https://www.terraform.io/downloads.html) 0.10+ -- [Go](https://golang.org/doc/install) 1.13 (to build the provider plugin) -Developing the Provider ---------------------- +- Website: [terraform.io](https://terraform.io) +- Tutorials: [learn.hashicorp.com](https://learn.hashicorp.com/terraform?track=getting-started#getting-started) +- Forum: [discuss.hashicorp.com](https://discuss.hashicorp.com/c/terraform-providers/tf-aws/) +- Chat: [gitter](https://gitter.im/hashicorp-terraform/Lobby) +- Mailing List: [Google Groups](http://groups.google.com/group/terraform-tool) -If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (please check the [requirements](https://github.com/terraform-providers/terraform-provider-aws#requirements) before proceeding). +The Terraform AWS provider is a plugin for Terraform that allows for the full lifecycle management of AWS resources. +This provider is maintained internally by the HashiCorp AWS Provider team. -*Note:* This project uses [Go Modules](https://blog.golang.org/using-go-modules) making it safe to work with it outside of your existing [GOPATH](http://golang.org/doc/code.html#GOPATH). The instructions that follow assume a directory in your home directory outside of the standard GOPATH (i.e `$HOME/development/terraform-providers/`). +Please note: We take Terraform's security and our users' trust very seriously. If you believe you have found a security issue in the Terraform AWS Provider, please responsibly disclose by contacting us at security@hashicorp.com. -Clone repository to: `$HOME/development/terraform-providers/` +## Quick Starts -```sh -$ mkdir -p $HOME/development/terraform-providers/; cd $HOME/development/terraform-providers/ -$ git clone git@github.com:terraform-providers/terraform-provider-aws -... -``` +- [Using the provider](https://www.terraform.io/docs/providers/aws/index.html) +- [Provider development](info/DEVELOPMENT.md) -Enter the provider directory and run `make tools`. This will install the needed tools for the provider. +## Documentation -```sh -$ make tools -``` +Full, comprehensive documentation is available on the Terraform website: -To compile the provider, run `make build`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory. +https://terraform.io/docs/providers/aws/index.html -```sh -$ make build -... -$ $GOPATH/bin/terraform-provider-aws -... -``` +## Roadmap -Using the Provider ----------------------- +Our roadmap for expanding support in Terraform for AWS resources can be found in our [Roadmap](ROADMAP.md) -To use a released provider in your Terraform environment, run [`terraform init`](https://www.terraform.io/docs/commands/init.html) and Terraform will automatically install the provider. To specify a particular provider version when installing released providers, see the [Terraform documentation on provider versioning](https://www.terraform.io/docs/configuration/providers.html#version-provider-versions). +## Frequently Asked Questions -To instead use a custom-built provider in your Terraform environment (e.g. the provider binary from the build instructions above), follow the instructions to [install it as a plugin.](https://www.terraform.io/docs/plugins/basics.html#installing-plugins) After placing the custom-built provider into your plugins directory, run `terraform init` to initialize it. +Responses to our most frequently asked questions can be found in our [FAQ](info/FAQ.md ) -For either installation method, documentation about the provider specific configuration options can be found on the [provider's website](https://www.terraform.io/docs/providers/aws/index.html). +## Contributing -Testing the Provider ---------------------------- - -In order to test the provider, you can run `make test`. - -*Note:* Make sure no `AWS_ACCESS_KEY_ID` or `AWS_SECRET_ACCESS_KEY` variables are set, and there's no `[default]` section in the AWS credentials file `~/.aws/credentials`. - -```sh -$ make test -``` - -In order to run the full suite of Acceptance tests, run `make testacc`. - -*Note:* Acceptance tests create real resources, and often cost money to run. Please read [Running an Acceptance Test](https://github.com/terraform-providers/terraform-provider-aws/blob/master/.github/CONTRIBUTING.md#running-an-acceptance-test) in the contribution guidelines for more information on usage. - -```sh -$ make testacc -``` - -Contributing ---------------------------- - -Terraform is the work of thousands of contributors. We appreciate your help! - -To contribute, please read the contribution guidelines: [Contributing to Terraform - AWS Provider](.github/CONTRIBUTING.md) - -Issues on GitHub are intended to be related to bugs or feature requests with provider codebase. See https://www.terraform.io/docs/extend/community/index.html for a list of community resources to ask questions about Terraform. +The Terraform AWS Provider is the work of thousands of contributors. We appreciate your help! +To contribute, please read the contribution guidelines: [Contributing to Terraform - AWS Provider](info/CONTRIBUTING.md) \ No newline at end of file diff --git a/info/CONTRIBUTING.md b/info/CONTRIBUTING.md new file mode 100644 index 00000000000..0455bda6f02 --- /dev/null +++ b/info/CONTRIBUTING.md @@ -0,0 +1,18 @@ +# Contributing to Terraform - AWS Provider + +**First:** if you're unsure or afraid of _anything_, ask for help! You can +submit a work in progress (WIP) pull request, or file an issue with the parts +you know. We'll do our best to guide you in the right direction, and let you +know if there are guidelines we will need to follow. We want people to be able +to participate without fear of doing the wrong thing. + +Below are our expectations for contributors. Following these guidelines gives us +the best opportunity to work with you, by making sure we have the things we need +in order to make it happen. Doing your best to follow it will speed up our +ability to merge PRs and respond to issues. + +- [Development Environment Setup](DEVELOPMENT.md) +- [Issue Reporting and Lifecycle](contributing/issue-reporting-and-lifecycle.md) +- [Pull Request Submission and Lifecycle](contributing/pullrequest-submission-and-lifecycle.md) +- [Contribution Types and Checklists](contributing/contribution-checklists.md) +- [Running and Writing Acceptance Tests](contributing/running-and-writing-acceptance-tests.md) diff --git a/info/DEVELOPMENT.md b/info/DEVELOPMENT.md new file mode 100644 index 00000000000..0a1bf4ee5c2 --- /dev/null +++ b/info/DEVELOPMENT.md @@ -0,0 +1,53 @@ +# Development Environment Setup + +## Requirements + +- [Terraform](https://www.terraform.io/downloads.html) 0.10+ +- [Go](https://golang.org/doc/install) 1.13 (to build the provider plugin) + +## Quick Start + +If you wish to work on the provider, you'll first need [Go](http://www.golang.org) installed on your machine (please check the [requirements](#requirements) before proceeding). + +*Note:* This project uses [Go Modules](https://blog.golang.org/using-go-modules) making it safe to work with it outside of your existing [GOPATH](http://golang.org/doc/code.html#GOPATH). The instructions that follow assume a directory in your home directory outside of the standard GOPATH (i.e `$HOME/development/terraform-providers/`). + +Clone repository to: `$HOME/development/terraform-providers/` + +```sh +$ mkdir -p $HOME/development/terraform-providers/; cd $HOME/development/terraform-providers/ +$ git clone git@github.com:terraform-providers/terraform-provider-aws +... +``` + +Enter the provider directory and run `make tools`. This will install the needed tools for the provider. + +```sh +$ make tools +``` + +To compile the provider, run `make build`. This will build the provider and put the provider binary in the `$GOPATH/bin` directory. + +```sh +$ make build +... +$ $GOPATH/bin/terraform-provider-aws +... +``` + +## Testing the Provider + +In order to test the provider, you can run `make test`. + +*Note:* Make sure no `AWS_ACCESS_KEY_ID` or `AWS_SECRET_ACCESS_KEY` variables are set, and there's no `[default]` section in the AWS credentials file `~/.aws/credentials`. + +```sh +$ make test +``` + +In order to run the full suite of Acceptance tests, run `make testacc`. + +*Note:* Acceptance tests create real resources, and often cost money to run. Please read [Running an Acceptance Test](https://github.com/terraform-providers/terraform-provider-aws/blob/master/.github/CONTRIBUTING.md#running-an-acceptance-test) in the contribution guidelines for more information on usage. + +```sh +$ make testacc +``` \ No newline at end of file diff --git a/info/FAQ.md b/info/FAQ.md new file mode 100644 index 00000000000..4ca45b5b256 --- /dev/null +++ b/info/FAQ.md @@ -0,0 +1,65 @@ +# Frequently Asked Questions + +### Who are the maintainers? + +The HashiCorp Terraform AWS provider team is : + +* Mary Cutrali, Product Manager - GitHub [@maryelizbeth](https://github.com/maryelizbeth) Twitter [@marycutrali](https://twitter.com/marycutrali) +* Brian Flad, Engineering Lead GitHub [@bflad](https://github.com/bflad) +* Graham Davison, Engineer - GitHub [@gdavison](https://github.com/gdavison) +* Angie Pinilla, Engineer - GitHub [@angie44](https://github.com/angie44) +* Simon Davis, Engineering Manager - GitHub [@breathingdust](https://github.com/breathingdust) +* Kerim Satirli, Developer Advocate - GitHub [@satirli](https://github.com/ksatirli) + +### Why isn’t my PR merged yet? + +Unfortunately, due to the volume of issues and new pull requests we receive, we are unable to give each one the full attention that we would like. We always focus on the contributions that provide the most value to the most community members. + +### How do you decide what gets merged for each release? + +The number one factor we look at when deciding what issues to look at are your reactions, comments, and upvotes on the issues or PR’s. The items with the most support are always on our radar, and we commit to keep the community updated on their status and potential timelines. + +We also are investing time to improve the contributing experience by improving documentation, adding more linter coverage to ensure that incoming PR's can be in as good shape as possible. This will allow us to get through them quicker. + +### How often do you release? + +We release weekly on Thursday. We release often to ensure we can bring value to the community at a frequent cadence and to ensure we are in a good place to react to AWS region launches and service announcements. + +### Backward Compatibility Promise + +Our policy is described on the Terraform website [here](https://www.terraform.io/docs/extend/best-practices/versioning.html). + +### AWS just announced a new region, when will I see it in the provider. + +Normally pretty quickly. We usually see the region appear within the `aws-go-sdk` within a couple days of the announcement. Depending on when it lands, we can often get it out within the current or following weekly release. Comparatively, adding support for a new region in the S3 backend can take a little longer, as it is shipped as part of Terraform Core and not via the AWS Provider. + +Please note that this new region requires a manual process to enable in your account. Once enabled in the console, it takes a few minutes for everything to work properly. + +If the region is not enabled properly, or the enablement process is still in progress, you may receive errors like these: + +``` +$ terraform apply + +Error: error validating provider credentials: error calling sts:GetCallerIdentity: InvalidClientTokenId: The security token included in the request is invalid. + status code: 403, request id: 142f947b-b2c3-11e9-9959-c11ab17bcc63 + + on main.tf line 1, in provider "aws": + 1: provider "aws" { + +To use this new region before support has been added to the Terraform AWS Provider, you can disable the provider's automatic region validation via: +provider "aws" { + # ... potentially other configuration ... + + region = "af-south-1" + skip_region_validation = true +} + +``` + +### How can I help? + +Great question, if you have contributed before check out issues with the `help-wanted` label. These are normally issues with support, but we are currently unable to field resources to work on. If you are just getting started, take a look at issues with the `good-first-issue` label. Items with these labels will always be given priority for response. + +### How can I become a maintainer? + +This is an area under active research. Stay tuned! \ No newline at end of file diff --git a/.github/MAINTAINING.md b/info/MAINTAINING.md similarity index 60% rename from .github/MAINTAINING.md rename to info/MAINTAINING.md index be32dee870d..a70c5f4ca84 100644 --- a/.github/MAINTAINING.md +++ b/info/MAINTAINING.md @@ -13,10 +13,15 @@ - [yaml.v2 Updates](#yaml-v2-updates) - [Pull Request Merge Process](#pull-request-merge-process) - [Pull Request Types to CHANGELOG](#pull-request-types-to-changelog) -- [Release Process](#release-process) +- [Label Dictionary](#label-dictionary) +## Triage + +Incoming issues are classified using labels. These are assigned either by automation, or manually during the triage process. At a minimum tickets should be classified by type and by the area of the provider they affect. + + ## Pull Requests ### Pull Request Review Process @@ -282,7 +287,7 @@ The fix for this has been merged and will release with version X.Y.Z of the Terr The CHANGELOG is intended to show operator-impacting changes to the codebase for a particular version. If every change or commit to the code resulted in an entry, the CHANGELOG would become less useful for operators. The lists below are general guidelines on when a decision needs to be made to decide whether a change should have an entry. -Changes that should have a CHANGELOG entry: +#### Changes that should have a CHANGELOG entry: - New Resources and Data Sources - New full-length documentation guides (e.g. EKS Getting Started Guide, IAM Policy Documents with Terraform) @@ -291,20 +296,99 @@ Changes that should have a CHANGELOG entry: - Deprecations - Removals -Changes that may have a CHANGELOG entry: +#### Changes that may have a CHANGELOG entry: - Dependency updates: If the update contains relevant bug fixes or enhancements that affect operators, those should be called out. -Changes that should _not_ have a CHANGELOG entry: +#### Changes that should _not_ have a CHANGELOG entry: - Resource and provider documentation updates - Testing updates -## Release Process - -- Create a milestone for the next release after this release (generally, the next milestone will be a minor version increase unless previously decided for a major or patch version) -- Check the existing release milestone for open items and either work through them or move them to the next milestone -- Run the HashiCorp (non-OSS) TeamCity release job with the `DEPLOYMENT_TARGET_VERSION` matching the expected release milestone and `DEPLOYMENT_NEXT_VERSION` matching the next release milestone -- Wait for the TeamCity release job and CircleCI website deployment jobs to complete either by watching the build logs or Slack notifications -- Close the release milestone -- Create a new GitHub release with the release title exactly matching the tag and milestone (e.g. `v2.22.0`) and copy the notes from the CHANGELOG to the release notes. This will trigger [HashiBot](https://github.com/apps/hashibot) release comments. +## Label Dictionary + + + +| Label | Description | Automation | +|---------|-------------|----------| +| [![breaking-change][breaking-change-badge]][breaking-change]                                    | Introduces a breaking change in current functionality; breaking changes are usually deferred to the next major release. | None | +| [![bug][bug-badge]][bug] | Addresses a defect in current functionality. | None | +| [![crash][crash-badge]][crash] | Results from or addresses a Terraform crash or kernel panic. | None | +| [![dependencies][dependencies-badge]][dependencies] | Used to indicate a dependency version update. | Added by the Renovate bot. Configuration is found in the `renovate.json` file. | +| [![documentation][documentation-badge]][documentation] | Introduces or discusses updates to documentation. | None | +| [![enhancement][enhancement-badge]][enhancement] | Requests to existing resources that expand the functionality or scope. | None | +| [![good first issue][good-first-issue-badge]][good-first-issue] | Call to action for new contributors looking for a place to start. Smaller or straightforward issues. | None | +| [![hacktoberfest][hacktoberfest-badge]][hacktoberfest] | Call to action for Hacktoberfest (OSS Initiative). | None | +| [![hashibot ignore][hashibot-ignore-badge]][hashibot-ignore] | Issues or PRs labelled with this are ignored by Hashibot. | None | +| [![help wanted][help-wanted-badge]][help-wanted] | Call to action for contributors. Indicates an area of the codebase we’d like to expand/work on but don’t have the bandwidth inside the team. | None | +| [![needs-triage][needs-triage-badge]][needs-triage] | Waiting for first response or review from a maintainer. | Added to all new issues or PRs by GitHub action in `.github/workflows/issues.yml` unless they were submitted by a maintainer. | +| [![new-data-source][new-data-source-badge]][new-data-source] | Introduces a new data source. | None | +| [![new-resource][new-resource-badge]][new-resource] | Introduces a new resrouce. | None | +| [![proposal][proposal-badge]][proposal] | Proposes new design or functionality. | None | +| [![provider][provider-badge]][provider] | Pertains to the provider itself, rather than any interaction with AWS. | Added by Hashibot when the code change is in an area configured in `.hashibot.hcl` | +| [![question][question-badge]][question] | Includes a question about existing functionality; most questions will be re-routed to discuss.hashicorp.com. | None | +| [![regression][regression-badge]][regression] | Pertains to a degraded workflow resulting from an upstream patch or internal enhancement; usually categorized as a bug. | None | +| [![reinvent][reinvent-badge]][reinvent] | Pertains to a service or feature announced at reinvent. | None | +| ![service <*>][service-badge] | Indicates the service that is covered or introduced (i.e. service/s3) | Added by Hashibot when the code change matches a service definition in `.hashibot.hcl`. +| ![size%2F<*>][size-badge] | Managed by automation to categorize the size of a PR | Added by Hashibot to indicate the size of the PR. | +| [![stale][stale-badge]][stale] | Old or inactive issues managed by automation, if no further action taken these will get closed. | Added by a Github Action, configuration is found: `.github/workflows/stale.yml`. | +| [![technical-debt][technical-debt-badge]][technical-debt] | +Addresses areas of the codebase that need refactoring or redesign. | None| +| [![tests][tests-badge]][tests] | On a PR this indicates expanded test coverage. On an Issue this proposes expanded coverage or enhancement to test infrastructure. | None | +| [![thinking][thinking-badge]][thinking] | Requires additional research by the maintainers. | None | +| [![upstream-terraform][upstream-terraform-badge]][upstream-terraform] | Addresses functionality related to the Terraform core binary. | None | +| [![upstream][upstream-badge]][upstream] | Addresses functionality related to the cloud provider. | None | +| [![waiting-response](https://img.shields.io/badge/waiting--response-5319e7)](https://github.com/terraform-providers/terraform-provider-aws/labels/waiting-response) | Addresses functionality related to the cloud provider. | None | + +[breaking-change-badge]: https://img.shields.io/badge/breaking--change-d93f0b +[breaking-change]: https://github.com/terraform-providers/terraform-provider-aws/labels/breaking-change +[bug-badge]: https://img.shields.io/badge/bug-f7c6c7 +[bug]: https://github.com/terraform-providers/terraform-provider-aws/labels/bug +[crash-badge]: https://img.shields.io/badge/crash-e11d21 +[crash]: https://github.com/terraform-providers/terraform-provider-aws/labels/crash +[dependencies-badge]: https://img.shields.io/badge/dependencies-fad8c7 +[dependencies]: https://github.com/terraform-providers/terraform-provider-aws/labels/dependencies +[documentation-badge]: https://img.shields.io/badge/documentation-fef2c0 +[documentation]: https://github.com/terraform-providers/terraform-provider-aws/labels/documentation +[enhancement-badge]: https://img.shields.io/badge/enhancement-d4c5f9 +[enhancement]: https://github.com/terraform-providers/terraform-provider-aws/labels/enhancement +[good-first-issue-badge]: https://img.shields.io/badge/good%20first%20issue-128A0C +[good-first-issue]: https://github.com/terraform-providers/terraform-provider-aws/labels/good%20first%20issue +[hacktoberfest-badge]: https://img.shields.io/badge/hacktoberfest-2c0fad +[hacktoberfest]: https://github.com/terraform-providers/terraform-provider-aws/labels/hacktoberfest +[hashibot-ignore-badge]: https://img.shields.io/badge/hashibot%2Fignore-2c0fad +[hashibot-ignore]: https://github.com/terraform-providers/terraform-provider-aws/labels/hashibot-ignore +[help-wanted-badge]: https://img.shields.io/badge/help%20wanted-128A0C +[help-wanted]: https://github.com/terraform-providers/terraform-provider-aws/labels/help-wanted +[needs-triage-badge]: https://img.shields.io/badge/needs--triage-e236d7 +[needs-triage]: https://github.com/terraform-providers/terraform-provider-aws/labels/needs-triage +[new-data-source-badge]: https://img.shields.io/badge/new--data--source-d4c5f9 +[new-data-source]: https://github.com/terraform-providers/terraform-provider-aws/labels/new-data-source +[new-resource-badge]: https://img.shields.io/badge/new--resource-d4c5f9 +[new-resource]: https://github.com/terraform-providers/terraform-provider-aws/labels/new-resource +[proposal-badge]: https://img.shields.io/badge/proposal-fbca04 +[proposal]: https://github.com/terraform-providers/terraform-provider-aws/labels/proposal +[provider-badge]: https://img.shields.io/badge/provider-bfd4f2 +[provider]: https://github.com/terraform-providers/terraform-provider-aws/labels/provider +[question-badge]: https://img.shields.io/badge/question-d4c5f9 +[question]: https://github.com/terraform-providers/terraform-provider-aws/labels/question +[regression-badge]: https://img.shields.io/badge/regression-e11d21 +[regression]: https://github.com/terraform-providers/terraform-provider-aws/labels/regression +[reinvent-badge]: https://img.shields.io/badge/reinvent-c5def5 +[reinvent]: https://github.com/terraform-providers/terraform-provider-aws/labels/reinvent +[service-badge]: https://img.shields.io/badge/service%2F<*>-bfd4f2 +[size-badge]: https://img.shields.io/badge/size%2F<*>-ffffff +[stale-badge]: https://img.shields.io/badge/stale-e11d21 +[stale]: https://github.com/terraform-providers/terraform-provider-aws/labels/stale +[technical-debt-badge]: https://img.shields.io/badge/technical--debt-1d76db +[technical-debt]: https://github.com/terraform-providers/terraform-provider-aws/labels/technical-debt +[tests-badge]: https://img.shields.io/badge/tests-DDDDDD +[tests]: https://github.com/terraform-providers/terraform-provider-aws/labels/tests +[thinking-badge]: https://img.shields.io/badge/thinking-bfd4f2 +[thinking]: https://github.com/terraform-providers/terraform-provider-aws/labels/thinking +[upstream-terraform-badge]: https://img.shields.io/badge/upstream--terraform-CCCCCC +[upstream-terraform]: https://github.com/terraform-providers/terraform-provider-aws/labels/upstream-terraform +[upstream-badge]: https://img.shields.io/badge/upstream-fad8c7 +[upstream]: https://github.com/terraform-providers/terraform-provider-aws/labels/upstream +[waiting-response-badge]: https://img.shields.io/badge/waiting-response-bfd4f2 +[waiting-response]: https://github.com/terraform-providers/terraform-provider-aws/labels/waiting-response diff --git a/info/contributing/contribution-checklists.md b/info/contributing/contribution-checklists.md new file mode 100644 index 00000000000..8da282e2eb6 --- /dev/null +++ b/info/contributing/contribution-checklists.md @@ -0,0 +1,567 @@ +# Contribution Types and Checklists + +There are several different kinds of contribution, each of which has its own +standards for a speedy review. The following sections describe guidelines for +each type of contribution. + +- [Documentation Update](#documentation-update) +- [Enhancement/Bugfix to a Resource](#enhancementbugfix-to-a-resource) +- [Adding Resource Import Support](#adding-resource-import-support) +- [Adding Resource Name Generation Support](#adding-resource-name-generation-support) + - [Resource Name Generation Code Implementation](#resource-name-generation-code-implementation) + - [Resource Name Generation Testing Implementation](#resource-name-generation-testing-implementation) + - [Resource Code Generation Documentation Implementation](#resource-code-generation-documentation-implementation) +- [Adding Resource Tagging Support](#adding-resource-tagging-support) + - [Adding Service to Tag Generating Code](#adding-service-to-tag-generating-code) + - [Resource Tagging Code Implementation](#resource-tagging-code-implementation) + - [Resource Tagging Acceptance Testing Implementation](#resource-tagging-acceptance-testing-implementation) +- [Resource Tagging Documentation Implementation](#resource-tagging-documentation-implementation) +- [New Resource](#new-resource) +- [New Service](#new-service) +- [New Region](#new-region) + +## Documentation Update + +The [Terraform AWS Provider's website source][website] is in this repository +along with the code and tests. Below are some common items that will get +flagged during documentation reviews: + +- [ ] __Reasoning for Change__: Documentation updates should include an explanation for why the update is needed. +- [ ] __Prefer AWS Documentation__: Documentation about AWS service features and valid argument values that are likely to update over time should link to AWS service user guides and API references where possible. +- [ ] __Large Example Configurations__: Example Terraform configuration that includes multiple resource definitions should be added to the repository `examples` directory instead of an individual resource documentation page. Each directory under `examples` should be self-contained to call `terraform apply` without special configuration. +- [ ] __Terraform Configuration Language Features__: Individual resource documentation pages and examples should refrain from highlighting particular Terraform configuration language syntax workarounds or features such as `variable`, `local`, `count`, and built-in functions. + +## Enhancement/Bugfix to a Resource + +Working on existing resources is a great way to get started as a Terraform +contributor because you can work within existing code and tests to get a feel +for what to do. + +In addition to the below checklist, please see the [Common Review +Items](#common-review-items) sections for more specific coding and testing +guidelines. + + - [ ] __Acceptance test coverage of new behavior__: Existing resources each + have a set of [acceptance tests][acctests] covering their functionality. + These tests should exercise all the behavior of the resource. Whether you are + adding something or fixing a bug, the idea is to have an acceptance test that + fails if your code were to be removed. Sometimes it is sufficient to + "enhance" an existing test by adding an assertion or tweaking the config + that is used, but it's often better to add a new test. You can copy/paste an + existing test and follow the conventions you see there, modifying the test + to exercise the behavior of your code. + - [ ] __Documentation updates__: If your code makes any changes that need to + be documented, you should include those doc updates in the same PR. This + includes things like new resource attributes or changes in default values. + The [Terraform website][website] source is in this repo and includes + instructions for getting a local copy of the site up and running if you'd + like to preview your changes. + - [ ] __Well-formed Code__: Do your best to follow existing conventions you + see in the codebase, and ensure your code is formatted with `go fmt`. (The + Travis CI build will fail if `go fmt` has not been run on incoming code.) + The PR reviewers can help out on this front, and may provide comments with + suggestions on how to improve the code. + - [ ] __Vendor additions__: Create a separate PR if you are updating the vendor + folder. This is to avoid conflicts as the vendor versions tend to be fast- + moving targets. We will plan to merge the PR with this change first. + +## Adding Resource Import Support + +Adding import support for Terraform resources will allow existing infrastructure to be managed within Terraform. This type of enhancement generally requires a small to moderate amount of code changes. + +Comprehensive code examples and information about resource import support can be found in the [Extending Terraform documentation](https://www.terraform.io/docs/extend/resources/import.html). + +In addition to the below checklist and the items noted in the Extending Terraform documentation, please see the [Common Review Items](#common-review-items) sections for more specific coding and testing guidelines. + +- [ ] _Resource Code Implementation_: In the resource code (e.g. `aws/resource_aws_service_thing.go`), implementation of `Importer` `State` function +- [ ] _Resource Acceptance Testing Implementation_: In the resource acceptance testing (e.g. `aws/resource_aws_service_thing_test.go`), implementation of `TestStep`s with `ImportState: true` +- [ ] _Resource Documentation Implementation_: In the resource documentation (e.g. `website/docs/r/service_thing.html.markdown`), addition of `Import` documentation section at the bottom of the page + +## Adding Resource Name Generation Support + +Terraform AWS Provider resources can use shared logic to support and test name generation, where the operator can choose between an expected naming value, a generated naming value with a prefix, or a fully generated name. + +Implementing name generation support for Terraform AWS Provider resources requires the following, each with its own section below: + +- [ ] _Resource Name Generation Code Implementation_: In the resource code (e.g. `aws/resource_aws_service_thing.go`), implementation of `name_prefix` attribute, along with handling in `Create` function. +- [ ] _Resource Name Generation Testing Implementation_: In the resource acceptance testing (e.g. `aws/resource_aws_service_thing_test.go`), implementation of new acceptance test functions and configurations to exercise new naming logic. +- [ ] _Resource Name Generation Documentation Implementation_: In the resource documentation (e.g. `website/docs/r/service_thing.html.markdown`), addition of `name_prefix` argument and update of `name` argument description. + +### Resource Name Generation Code Implementation + +- In the resource Go file (e.g. `aws/resource_aws_service_thing.go`), add the following Go import: `"github.com/terraform-providers/terraform-provider-aws/aws/internal/naming"` +- In the resource schema, add the new `name_prefix` attribute and adjust the `name` attribute to be `Optional`, `Computed`, and `ConflictsWith` the `name_prefix` attribute. Ensure to keep any existing schema fields on `name` such as `ValidateFunc`. e.g. + +```go +"name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"name_prefix"}, +}, +"name_prefix": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ConflictsWith: []string{"name"}, +}, +``` + +- In the resource `Create` function, switch any calls from `d.Get("name").(string)` to instead use the `naming.Generate()` function, e.g. + +```go +name := naming.Generate(d.Get("name").(string), d.Get("name_prefix").(string)) + +// ... in AWS Go SDK Input types, etc. use aws.String(name) +``` + +### Resource Name Generation Testing Implementation + +- In the resource testing (e.g. `aws/resource_aws_service_thing_test.go`), add the following Go import: `"github.com/terraform-providers/terraform-provider-aws/aws/internal/naming"` +- In the resource testing, implement two new tests named `_Name_Generated` and `_NamePrefix` with associated configurations, that verifies creating the resource without `name` and `name_prefix` arguments (for the former) and with only the `name_prefix` argument (for the latter). e.g. + +```go +func TestAccAWSServiceThing_Name_Generated(t *testing.T) { + var thing service.ServiceThing + resourceName := "aws_service_thing.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSServiceThingDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSServiceThingConfigNameGenerated(), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSServiceThingExists(resourceName, &thing), + naming.TestCheckResourceAttrNameGenerated(resourceName, "name"), + ), + }, + // If the resource supports import: + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSServiceThing_NamePrefix(t *testing.T) { + var thing service.ServiceThing + resourceName := "aws_service_thing.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSServiceThingDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSServiceThingConfigNamePrefix("tf-acc-test-prefix-"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSServiceThingExists(resourceName, &thing), + naming.TestCheckResourceAttrNameFromPrefix(resourceName, "name", "tf-acc-test-prefix-"), + ), + }, + // If the resource supports import: + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAWSServiceThingConfigNameGenerated() string { + return fmt.Sprintf(` +resource "aws_service_thing" "test" { + # ... other configuration ... +} +`) +} + +func testAccAWSServiceThingConfigNamePrefix(namePrefix string) string { + return fmt.Sprintf(` +resource "aws_service_thing" "test" { + # ... other configuration ... + + name_prefix = %[1]q +} +`, namePrefix) +} +``` + +### Resource Code Generation Documentation Implementation + +- In the resource documentation (e.g. `website/docs/r/service_thing.html.markdown`), add the following to the arguments reference: + +```markdown +* `name_prefix` - (Optional) Creates a unique name beginning with the specified prefix. Conflicts with `name`. +``` + +- Adjust the existing `name` argument reference to ensure its denoted as `Optional`, includes a mention that it can be generated, and that it conflicts with `name_prefix`: + +```markdown +* `name` - (Optional) Name of the thing. If omitted, Terraform will assign a random, unique name. Conflicts with `name_prefix`. +``` + +## Adding Resource Tagging Support + +AWS provides key-value metadata across many services and resources, which can be used for a variety of use cases including billing, ownership, and more. See the [AWS Tagging Strategy page](https://aws.amazon.com/answers/account-management/aws-tagging-strategies/) for more information about tagging at a high level. + +Implementing tagging support for Terraform AWS Provider resources requires the following, each with its own section below: + +- [ ] _Generated Service Tagging Code_: In the internal code generators (e.g. `aws/internal/keyvaluetags`), implementation and customization of how a service handles tagging, which is standardized for the resources. +- [ ] _Resource Tagging Code Implementation_: In the resource code (e.g. `aws/resource_aws_service_thing.go`), implementation of `tags` schema attribute, along with handling in `Create`, `Read`, and `Update` functions. +- [ ] _Resource Tagging Acceptance Testing Implementation_: In the resource acceptance testing (e.g. `aws/resource_aws_service_thing_test.go`), implementation of new acceptance test function and configurations to exercise new tagging logic. +- [ ] _Resource Tagging Documentation Implementation_: In the resource documentation (e.g. `website/docs/r/service_thing.html.markdown`), addition of `tags` argument + +See also a [full example pull request for implementing EKS tagging](https://github.com/terraform-providers/terraform-provider-aws/pull/10307). + +### Adding Service to Tag Generating Code + +This step is only necessary for the first implementation and may have been previously completed. If so, move on to the next section. + +More details about this code generation, including fixes for potential error messages in this process, can be found in the [keyvaluetags documentation](../aws/internal/keyvaluetags/README.md). + +- Open the AWS Go SDK documentation for the service, e.g. for [`service/eks`](https://docs.aws.amazon.com/sdk-for-go/api/service/eks/). Note: there can be a delay between the AWS announcement and the updated AWS Go SDK documentation. +- Determine the "type" of tagging implementation. Some services will use a simple map style (`map[string]*string` in Go) while others will have a separate structure shape (`[]service.Tag` struct with `Key` and `Value` fields). + + - If the type is a map, add the AWS Go SDK service name (e.g. `eks`) to `mapServiceNames` in `aws/internal/keyvaluetags/generators/servicetags/main.go` + - Otherwise, if the type is a struct, add the AWS Go SDK service name (e.g. `eks`) to `sliceServiceNames` in `aws/internal/keyvaluetags/generators/servicetags/main.go`. If the struct name is not exactly `Tag`, it can be customized via the `ServiceTagType` function. If the struct key field is not exactly `Key`, it can be customized via the `ServiceTagTypeKeyField` function. If the struct value field is not exactly `Value`, it can be customized via the `ServiceTagTypeValueField` function. + +- Determine if the service API includes functionality for listing tags (usually a `ListTags` or `ListTagsForResource` API call) or updating tags (usually `TagResource` and `UntagResource` API calls). If so, add the AWS Go SDK service client information to `ServiceClientType` (along with the new required import) in `aws/internal/keyvaluetags/service_generation_customizations.go`, e.g. for EKS: + + ```go + case "eks": + funcType = reflect.TypeOf(eks.New) + ``` + + - If the service API includes functionality for listing tags, add the AWS Go SDK service name (e.g. `eks`) to `serviceNames` in `aws/internal/keyvaluetags/generators/listtags/main.go`. + - If the service API includes functionality for updating tags, add the AWS Go SDK service name (e.g. `eks`) to `serviceNames` in `aws/internal/keyvaluetags/generators/updatetags/main.go`. + +- Run `make gen` (`go generate ./...`) and ensure there are no errors via `make test` (`go test ./...`) + +### Resource Tagging Code Implementation + +- In the resource Go file (e.g. `aws/resource_aws_eks_cluster.go`), add the following Go import: `"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"` +- In the resource schema, add `"tags": tagsSchema(),` +- If the API supports tagging on creation (the `Input` struct accepts a `Tags` field), in the resource `Create` function, implement the logic to convert the configuration tags into the service tags, e.g. with EKS Clusters: + + ```go + input := &eks.CreateClusterInput{ + /* ... other configuration ... */ + Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().EksTags(), + } + ``` + + If the service API does not allow passing an empty list, the logic can be adjusted similar to: + + ```go + input := &eks.CreateClusterInput{ + /* ... other configuration ... */ + } + + if v := d.Get("tags").(map[string]interface{}); len(v) > 0 { + input.Tags = keyvaluetags.New(v).IgnoreAws().EksTags() + } + ``` + +- Otherwise if the API does not support tagging on creation (the `Input` struct does not accept a `Tags` field), in the resource `Create` function, implement the logic to convert the configuration tags into the service API call to tag a resource, e.g. with ElasticSearch Domain: + + ```go + if v := d.Get("tags").(map[string]interface{}); len(v) > 0 { + if err := keyvaluetags.ElasticsearchserviceUpdateTags(conn, d.Id(), nil, v); err != nil { + return fmt.Errorf("error adding Elasticsearch Cluster (%s) tags: %s", d.Id(), err) + } + } + ``` + +- Some EC2 resources (for example [`aws_ec2_fleet`](https://www.terraform.io/docs/providers/aws/r/ec2_fleet.html)) have a `TagsSpecification` field in the `InputStruct` instead of a `Tags` field. In these cases the `ec2TagSpecificationsFromMap()` helper function should be used, e.g.: + + ```go + input := &ec2.CreateFleetInput{ + /* ... other configuration ... */ + TagSpecifications: ec2TagSpecificationsFromMap(d.Get("tags").(map[string]interface{}), ec2.ResourceTypeFleet), + } + ``` + +- In the resource `Read` function, implement the logic to convert the service tags to save them into the Terraform state for drift detection, e.g. with EKS Clusters (which had the tags available in the DescribeCluster API call): + + ```go + // Typically declared near conn := /* ... */ + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + + if err := d.Set("tags", keyvaluetags.EksKeyValueTags(cluster.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + ``` + + If the service API does not return the tags directly from reading the resource and requires a separate API call, its possible to use the `keyvaluetags` functionality like the following, e.g. with Athena Workgroups: + + ```go + // Typically declared near conn := /* ... */ + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + + tags, err := keyvaluetags.AthenaListTags(conn, arn.String()) + + if err != nil { + return fmt.Errorf("error listing tags for resource (%s): %s", arn, err) + } + + if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + ``` + +- In the resource `Update` function (this may be the first functionality requiring the creation of the `Update` function), implement the logic to handle tagging updates, e.g. with EKS Clusters: + + ```go + if d.HasChange("tags") { + o, n := d.GetChange("tags") + if err := keyvaluetags.EksUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { + return fmt.Errorf("error updating tags: %s", err) + } + } + ``` + +### Resource Tagging Acceptance Testing Implementation + +- In the resource testing (e.g. `aws/resource_aws_eks_cluster_test.go`), verify that existing resources without tagging are unaffected and do not have tags saved into their Terraform state. This should be done in the `_basic` acceptance test by adding a line similar to `resource.TestCheckResourceAttr(resourceName, "tags.%s", "0"),` +- In the resource testing, implement a new test named `_Tags` with associated configurations, that verifies creating the resource with tags and updating tags. e.g. EKS Clusters: + + ```go + func TestAccAWSEksCluster_Tags(t *testing.T) { + var cluster1, cluster2, cluster3 eks.Cluster + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_eks_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSEks(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSEksClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSEksClusterConfigTags1(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksClusterExists(resourceName, &cluster1), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSEksClusterConfigTags2(rName, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksClusterExists(resourceName, &cluster2), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccAWSEksClusterConfigTags1(rName, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksClusterExists(resourceName, &cluster3), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) + } + + func testAccAWSEksClusterConfigTags1(rName, tagKey1, tagValue1 string) string { + return testAccAWSEksClusterConfig_Base(rName) + fmt.Sprintf(` + resource "aws_eks_cluster" "test" { + name = %[1]q + role_arn = "${aws_iam_role.test.arn}" + + tags = { + %[2]q = %[3]q + } + + vpc_config { + subnet_ids = ["${aws_subnet.test.*.id[0]}", "${aws_subnet.test.*.id[1]}"] + } + + depends_on = ["aws_iam_role_policy_attachment.test-AmazonEKSClusterPolicy", "aws_iam_role_policy_attachment.test-AmazonEKSServicePolicy"] + } + `, rName, tagKey1, tagValue1) + } + + func testAccAWSEksClusterConfigTags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return testAccAWSEksClusterConfig_Base(rName) + fmt.Sprintf(` + resource "aws_eks_cluster" "test" { + name = %[1]q + role_arn = "${aws_iam_role.test.arn}" + + tags = { + %[2]q = %[3]q + %[4]q = %[5]q + } + + vpc_config { + subnet_ids = ["${aws_subnet.test.*.id[0]}", "${aws_subnet.test.*.id[1]}"] + } + + depends_on = ["aws_iam_role_policy_attachment.test-AmazonEKSClusterPolicy", "aws_iam_role_policy_attachment.test-AmazonEKSServicePolicy"] + } + `, rName, tagKey1, tagValue1, tagKey2, tagValue2) + } + ``` + +- Verify all acceptance testing passes for the resource (e.g. `make testacc TESTARGS='-run=TestAccAWSEksCluster_'`) + +## Resource Tagging Documentation Implementation + +- In the resource documentation (e.g. `website/docs/r/eks_cluster.html.markdown`), add the following to the arguments reference: + + ```markdown + * `tags` - (Optional) Key-value mapping of resource tags + ``` + +## New Resource + +Implementing a new resource is a good way to learn more about how Terraform +interacts with upstream APIs. There are plenty of examples to draw from in the +existing resources, but you still get to implement something completely new. + +In addition to the below checklist, please see the [Common Review +Items](#common-review-items) sections for more specific coding and testing +guidelines. + + - [ ] __Minimal LOC__: It's difficult for both the reviewer and author to go + through long feedback cycles on a big PR with many resources. We ask you to + only submit **1 resource at a time**. + - [ ] __Acceptance tests__: New resources should include acceptance tests + covering their behavior. See [Writing Acceptance + Tests](#writing-acceptance-tests) below for a detailed guide on how to + approach these. + - [ ] __Resource Naming__: Resources should be named `aws__`, + using underscores (`_`) as the separator. Resources are namespaced with the + service name to allow easier searching of related resources, to align + the resource naming with the service for [Customizing Endpoints](https://www.terraform.io/docs/providers/aws/guides/custom-service-endpoints.html#available-endpoint-customizations), + and to prevent future conflicts with new AWS services/resources. + For reference: + + - `service` is the AWS short service name that matches the entry in + `endpointServiceNames` (created via the [New Service](#new-service) + section) + - `name` represents the conceptual infrastructure represented by the + create, read, update, and delete methods of the service API. It should + be a singular noun. For example, in an API that has methods such as + `CreateThing`, `DeleteThing`, `DescribeThing`, and `ModifyThing` the name + of the resource would end in `_thing`. + + - [ ] __Arguments_and_Attributes__: The HCL for arguments and attributes should + mimic the types and structs presented by the AWS API. API arguments should be + converted from `CamelCase` to `camel_case`. + - [ ] __Documentation__: Each resource gets a page in the Terraform + documentation. The [Terraform website][website] source is in this + repo and includes instructions for getting a local copy of the site up and + running if you'd like to preview your changes. For a resource, you'll want + to add a new file in the appropriate place and add a link to the sidebar for + that page. + - [ ] __Well-formed Code__: Do your best to follow existing conventions you + see in the codebase, and ensure your code is formatted with `go fmt`. (The + Travis CI build will fail if `go fmt` has not been run on incoming code.) + The PR reviewers can help out on this front, and may provide comments with + suggestions on how to improve the code. + - [ ] __Vendor updates__: Create a separate PR if you are adding to the vendor + folder. This is to avoid conflicts as the vendor versions tend to be fast- + moving targets. We will plan to merge the PR with this change first. + +## New Service + +Implementing a new AWS service gives Terraform the ability to manage resources in +a whole new API. It's a larger undertaking, but brings major new functionality +into Terraform. + +- [ ] __Service Client__: Before new resources are submitted, we request + a separate pull request containing just the new AWS Go SDK service client. + Doing so will pull the AWS Go SDK service code into the project at the + current version. Since the AWS Go SDK is updated frequently, these pull + requests can easily have merge conflicts or be out of date. The maintainers + prioritize reviewing and merging these quickly to prevent those situations. + + To add the AWS Go SDK service client: + + - In `aws/provider.go` Add a new service entry to `endpointServiceNames`. + This service name should match the AWS Go SDK or AWS CLI service name. + - In `aws/config.go`: Add a new import for the AWS Go SDK code. e.g. + `github.com/aws/aws-sdk-go/service/quicksight` + - In `aws/config.go`: Add a new `{SERVICE}conn` field to the `AWSClient` + struct for the service client. The service name should match the name + in `endpointServiceNames`. e.g. `quicksightconn *quicksight.QuickSight` + - In `aws/config.go`: Create the new service client in the `{SERVICE}conn` + field in the `AWSClient` instantiation within `Client()`. e.g. + `quicksightconn: quicksight.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["quicksight"])})),` + - In `website/allowed-subcategories.txt`: Add a name acceptable for the documentation navigation. + - In `website/docs/guides/custom-service-endpoints.html.md`: Add the service + name in the list of customizable endpoints. + - In `.hashibot.hcl`: Add the new service to automated issue and pull request labeling. e.g. with the `quicksight` service + + ```hcl + behavior "regexp_issue_labeler_v2" "service_labels" { + # ... other configuration ... + + label_map = { + # ... other services ... + "service/quicksight" = [ + "aws_quicksight_", + ], + # ... other services ... + } + } + + behavior "pull_request_path_labeler" "service_labels" + # ... other configuration ... + + label_map = { + # ... other services ... + "service/quicksight" = [ + "**/*_quicksight_*", + "**/quicksight_*", + ], + # ... other services ... + } + } + ``` + + - Run the following then submit the pull request: + + ```sh + go test ./aws + go mod tidy + go mod vendor + ``` + +- [ ] __Initial Resource__: Some services can be big and it can be + difficult for both reviewer & author to go through long feedback cycles + on a big PR with many resources. Often feedback items in one resource + will also need to be applied in other resources. We prefer you to submit + the necessary minimum in a single PR, ideally **just the first resource** + of the service. + +The initial resource and changes afterwards should follow the other sections +of this guide as appropriate. + +## New Region + +While region validation is automatically added with SDK updates, new regions +are generally limited in which services they support. Below are some +manually sourced values from documentation. + + - [ ] Check [Elastic Load Balancing endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/elb.html#elb_region) and add Route53 Hosted Zone ID if available to `aws/data_source_aws_elb_hosted_zone_id.go` + - [ ] Check [Amazon Simple Storage Service endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/s3.html#s3_region) and add Route53 Hosted Zone ID if available to `aws/hosted_zones.go` + - [ ] Check [CloudTrail Supported Regions docs](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-supported-regions.html#cloudtrail-supported-regions) and add AWS Account ID if available to `aws/data_source_aws_cloudtrail_service_account.go` + - [ ] Check [Elastic Load Balancing Access Logs docs](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-access-logs.html#attach-bucket-policy) and add Elastic Load Balancing Account ID if available to `aws/data_source_aws_elb_service_account.go` + - [ ] Check [Redshift Database Audit Logging docs](https://docs.aws.amazon.com/redshift/latest/mgmt/db-auditing.html#db-auditing-bucket-permissions) and add AWS Account ID if available to `aws/data_source_aws_redshift_service_account.go` + - [ ] Check [AWS Elastic Beanstalk endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/elasticbeanstalk.html#elasticbeanstalk_region) and add Route53 Hosted Zone ID if available to `aws/data_source_aws_elastic_beanstalk_hosted_zone.go` \ No newline at end of file diff --git a/info/contributing/issue-reporting-and-lifecycle.md b/info/contributing/issue-reporting-and-lifecycle.md new file mode 100644 index 00000000000..98f029fd8ea --- /dev/null +++ b/info/contributing/issue-reporting-and-lifecycle.md @@ -0,0 +1,77 @@ +# Issue Reporting and Lifecycle + + + +- [Issue Reporting Checklists](#issue-reporting-checklists) + - [Bug Reports](https://github.com/terraform-providers/terraform-provider-aws/issues/new?template=Bug_Report.md) + - [Feature Requests](https://github.com/terraform-providers/terraform-provider-aws/issues/new?labels=enhancement&template=Feature_Request.md) + - [Questions](https://github.com/terraform-providers/terraform-provider-aws/issues/new?labels=question&template=Question.md) +- [Issue Lifecycle](#issue-lifecycle) + + + +## Issue Reporting Checklists + +We welcome issues of all kinds including feature requests, bug reports, and +general questions. Below you'll find checklists with guidelines for well-formed +issues of each type. + +### [Bug Reports](https://github.com/terraform-providers/terraform-provider-aws/issues/new?template=Bug_Report.md) + + - [ ] __Test against latest release__: Make sure you test against the latest + released version. It is possible we already fixed the bug you're experiencing. + + - [ ] __Search for possible duplicate reports__: It's helpful to keep bug + reports consolidated to one thread, so do a quick search on existing bug + reports to check if anybody else has reported the same thing. You can [scope + searches by the label "bug"](https://github.com/terraform-providers/terraform-provider-aws/issues?q=is%3Aopen+is%3Aissue+label%3Abug) to help narrow things down. + + - [ ] __Include steps to reproduce__: Provide steps to reproduce the issue, + along with your `.tf` files, with secrets removed, so we can try to + reproduce it. Without this, it makes it much harder to fix the issue. + + - [ ] __For panics, include `crash.log`__: If you experienced a panic, please + create a [gist](https://gist.github.com) of the *entire* generated crash log + for us to look at. Double check no sensitive items were in the log. + +### [Feature Requests](https://github.com/terraform-providers/terraform-provider-aws/issues/new?labels=enhancement&template=Feature_Request.md) + + - [ ] __Search for possible duplicate requests__: It's helpful to keep requests + consolidated to one thread, so do a quick search on existing requests to + check if anybody else has reported the same thing. You can [scope searches by + the label "enhancement"](https://github.com/terraform-providers/terraform-provider-aws/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement) to help narrow things down. + + - [ ] __Include a use case description__: In addition to describing the + behavior of the feature you'd like to see added, it's helpful to also lay + out the reason why the feature would be important and how it would benefit + Terraform users. + +### [Questions](https://github.com/terraform-providers/terraform-provider-aws/issues/new?labels=question&template=Question.md) + + - [ ] __Search for answers in Terraform documentation__: We're happy to answer + questions in GitHub Issues, but it helps reduce issue churn and maintainer + workload if you work to [find answers to common questions in the + documentation](https://www.terraform.io/docs/providers/aws/index.html). Oftentimes Question issues result in documentation updates + to help future users, so if you don't find an answer, you can give us + pointers for where you'd expect to see it in the docs. + +## Issue Lifecycle + +1. The issue is reported. + +2. The issue is verified and categorized by a Terraform collaborator. + Categorization is done via GitHub labels. We generally use a two-label + system of (1) issue/PR type, and (2) section of the codebase. Type is + one of "bug", "enhancement", "documentation", or "question", and section + is usually the AWS service name. + +3. An initial triage process determines whether the issue is critical and must + be addressed immediately, or can be left open for community discussion. + +4. The issue is addressed in a pull request or commit. The issue number will be + referenced in the commit message so that the code that fixes it is clearly + linked. + +5. The issue is closed. Sometimes, valid issues will be closed because they are + tracked elsewhere or non-actionable. The issue is still indexed and + available for future viewers, or can be re-opened if necessary. \ No newline at end of file diff --git a/info/contributing/pullrequest-submission-and-lifecycle.md b/info/contributing/pullrequest-submission-and-lifecycle.md new file mode 100644 index 00000000000..1608624805b --- /dev/null +++ b/info/contributing/pullrequest-submission-and-lifecycle.md @@ -0,0 +1,128 @@ +# Pull Request Submission and Lifecycle + +- [Pull Request Lifecycle](#pull-request-lifecycle) +- [Common Review Items](#common-review-items) + - [Go Coding Style](#go-coding-style) + - [Resource Contribution Guidelines](#resource-contribution-guidelines) + +We appreciate direct contributions to the provider codebase. Here's what to +expect: + + * For pull requests that follow the guidelines, we will proceed to reviewing + and merging, following the provider team's review schedule. There may be some + internal or community discussion needed before we can complete this. + * Pull requests that don't follow the guidelines will be commented with what + they're missing. The person who submits the pull request or another community + member will need to address those requests before they move forward. + +## Pull Request Lifecycle + +1. [Fork the GitHub repository](https://help.github.com/en/articles/fork-a-repo), + modify the code, and [create a pull request](https://help.github.com/en/articles/creating-a-pull-request-from-a-fork). + You are welcome to submit your pull request for commentary or review before + it is fully completed by creating a [draft pull request](https://help.github.com/en/articles/about-pull-requests#draft-pull-requests) + or adding `[WIP]` to the beginning of the pull request title. + Please include specific questions or items you'd like feedback on. + +1. Once you believe your pull request is ready to be reviewed, ensure the + pull request is not a draft pull request by [marking it ready for review](https://help.github.com/en/articles/changing-the-stage-of-a-pull-request) + or removing `[WIP]` from the pull request title if necessary, and a + maintainer will review it. Follow [the checklists below](#checklists-for-contribution) + to help ensure that your contribution can be easily reviewed and potentially + merged. + +1. One of Terraform's provider team members will look over your contribution and + either approve it or provide comments letting you know if there is anything + left to do. We do our best to keep up with the volume of PRs waiting for + review, but it may take some time depending on the complexity of the work. + +1. Once all outstanding comments and checklist items have been addressed, your + contribution will be merged! Merged PRs will be included in the next + Terraform release. The provider team takes care of updating the CHANGELOG as + they merge. + +1. In some cases, we might decide that a PR should be closed without merging. + We'll make sure to provide clear reasoning when this happens. + +## Common Review Items + +The Terraform AWS Provider follows common practices to ensure consistent and +reliable implementations across all resources in the project. While there may be +older resource and testing code that predates these guidelines, new submissions +are generally expected to adhere to these items to maintain Terraform Provider +quality. For any guidelines listed, contributors are encouraged to ask any +questions and community reviewers are encouraged to provide review suggestions +based on these guidelines to speed up the review and merge process. + +### Go Coding Style + +The following Go language resources provide common coding preferences that may be referenced during review, if not automatically handled by the project's linting tools. + +- [Effective Go](https://golang.org/doc/effective_go.html) +- [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments) + +### Resource Contribution Guidelines + +The following resource checks need to be addressed before your contribution can be merged. The exclusion of any applicable check may result in a delayed time to merge. + +- [ ] __Passes Testing__: All code and documentation changes must pass unit testing, code linting, and website link testing. Resource code changes must pass all acceptance testing for the resource. +- [ ] __Avoids API Calls Across Account, Region, and Service Boundaries__: Resources should not implement cross-account, cross-region, or cross-service API calls. +- [ ] __Avoids Optional and Required for Non-Configurable Attributes__: Resource schema definitions for read-only attributes should not include `Optional: true` or `Required: true`. +- [ ] __Avoids resource.Retry() without resource.RetryableError()__: Resource logic should only implement [`resource.Retry()`](https://godoc.org/github.com/hashicorp/terraform/helper/resource#Retry) if there is a retryable condition (e.g. `return resource.RetryableError(err)`). +- [ ] __Avoids Resource Read Function in Data Source Read Function__: Data sources should fully implement their own resource `Read` functionality including duplicating `d.Set()` calls. +- [ ] __Avoids Reading Schema Structure in Resource Code__: The resource `Schema` should not be read in resource `Create`/`Read`/`Update`/`Delete` functions to perform looping or otherwise complex attribute logic. Use [`d.Get()`](https://godoc.org/github.com/hashicorp/terraform/helper/schema#ResourceData.Get) and [`d.Set()`](https://godoc.org/github.com/hashicorp/terraform/helper/schema#ResourceData.Set) directly with individual attributes instead. +- [ ] __Avoids ResourceData.GetOkExists()__: Resource logic should avoid using [`ResourceData.GetOkExists()`](https://godoc.org/github.com/hashicorp/terraform/helper/schema#ResourceData.GetOkExists) as its expected functionality is not guaranteed in all scenarios. +- [ ] __Implements Read After Create and Update__: Except where API eventual consistency prohibits immediate reading of resources or updated attributes, resource `Create` and `Update` functions should return the resource `Read` function. +- [ ] __Implements Immediate Resource ID Set During Create__: Immediately after calling the API creation function, the resource ID should be set with [`d.SetId()`](https://godoc.org/github.com/hashicorp/terraform/helper/schema#ResourceData.SetId) before other API operations or returning the `Read` function. +- [ ] __Implements Attribute Refreshes During Read__: All attributes available in the API should have [`d.Set()`](https://godoc.org/github.com/hashicorp/terraform/helper/schema#ResourceData.Set) called their values in the Terraform state during the `Read` function. +- [ ] __Implements Error Checks with Non-Primative Attribute Refreshes__: When using [`d.Set()`](https://godoc.org/github.com/hashicorp/terraform/helper/schema#ResourceData.Set) with non-primative types (`schema.TypeList`, `schema.TypeSet`, or `schema.TypeMap`), perform error checking to [prevent issues where the code is not properly able to refresh the Terraform state](https://www.terraform.io/docs/extend/best-practices/detecting-drift.html#error-checking-aggregate-types). +- [ ] __Implements Import Acceptance Testing and Documentation__: Support for resource import (`Importer` in resource schema) must include `ImportState` acceptance testing (see also the [Acceptance Testing Guidelines](#acceptance-testing-guidelines) below) and `## Import` section in resource documentation. +- [ ] __Implements Customizable Timeouts Documentation__: Support for customizable timeouts (`Timeouts` in resource schema) must include `## Timeouts` section in resource documentation. +- [ ] __Implements State Migration When Adding New Virtual Attribute__: For new "virtual" attributes (those only in Terraform and not in the API), the schema should implement [State Migration](https://www.terraform.io/docs/extend/resources.html#state-migrations) to prevent differences for existing configurations that upgrade. +- [ ] __Uses AWS Go SDK Constants__: Many AWS services provide string constants for value enumerations, error codes, and status types. See also the "Constants" sections under each of the service packages in the [AWS Go SDK documentation](https://docs.aws.amazon.com/sdk-for-go/api/). +- [ ] __Uses AWS Go SDK Pointer Conversion Functions__: Many APIs return pointer types and these functions return the zero value for the type if the pointer is `nil`. This prevents potential panics from unchecked `*` pointer dereferences and can eliminate boilerplate `nil` checking in many cases. See also the [`aws` package in the AWS Go SDK documentation](https://docs.aws.amazon.com/sdk-for-go/api/aws/). +- [ ] __Uses AWS Go SDK Types__: Use available SDK structs instead of implementing custom types with indirection. +- [ ] __Uses TypeList and MaxItems: 1__: Configuration block attributes (e.g. `Type: schema.TypeList` or `Type: schema.TypeSet` with `Elem: &schema.Resource{...}`) that can only have one block should use `Type: schema.TypeList` and `MaxItems: 1` in the schema definition. +- [ ] __Uses Existing Validation Functions__: Schema definitions including `ValidateFunc` for attribute validation should use available [Terraform `helper/validation` package](https://godoc.org/github.com/hashicorp/terraform/helper/validation) functions. `All()`/`Any()` can be used for combining multiple validation function behaviors. +- [ ] __Uses isResourceTimeoutError() with resource.Retry()__: Resource logic implementing [`resource.Retry()`](https://godoc.org/github.com/hashicorp/terraform/helper/resource#Retry) should error check with `isResourceTimeoutError(err error)` and potentially unset the error before returning the error. For example: + + ```go + var output *kms.CreateKeyOutput + err := resource.Retry(1*time.Minute, func() *resource.RetryError { + var err error + + output, err = conn.CreateKey(input) + + /* ... */ + + return nil + }) + + if isResourceTimeoutError(err) { + output, err = conn.CreateKey(input) + } + + if err != nil { + return fmt.Errorf("error creating KMS External Key: %s", err) + } + ``` + +- [ ] __Uses resource.NotFoundError__: Custom errors for missing resources should use [`resource.NotFoundError`](https://godoc.org/github.com/hashicorp/terraform/helper/resource#NotFoundError). +- [ ] __Uses resource.UniqueId()__: API fields for concurrency protection such as `CallerReference` and `IdempotencyToken` should use [`resource.UniqueId()`](https://godoc.org/github.com/hashicorp/terraform/helper/resource#UniqueId). The implementation includes a monotonic counter which is safer for concurrent operations than solutions such as `time.Now()`. +- [ ] __Skips Exists Function__: Implementing a resource `Exists` function is extraneous as it often duplicates resource `Read` functionality. Ensure `d.SetId("")` is used to appropriately trigger resource recreation in the resource `Read` function. +- [ ] __Skips id Attribute__: The `id` attribute is implicit for all Terraform resources and does not need to be defined in the schema. + +The below are style-based items that _may_ be noted during review and are recommended for simplicity, consistency, and quality assurance: + +- [ ] __Avoids CustomizeDiff__: Usage of `CustomizeDiff` is generally discouraged. +- [ ] __Implements Error Message Context__: Returning errors from resource `Create`, `Read`, `Update`, and `Delete` functions should include additional messaging about the location or cause of the error for operators and code maintainers by wrapping with [`fmt.Errorf()`](https://godoc.org/golang.org/x/exp/errors/fmt#Errorf). + - An example `Delete` API error: `return fmt.Errorf("error deleting {SERVICE} {THING} (%s): %s", d.Id(), err)` + - An example `d.Set()` error: `return fmt.Errorf("error setting {ATTRIBUTE}: %s", err)` +- [ ] __Implements arn Attribute__: APIs that return an Amazon Resource Name (ARN), should implement `arn` as an attribute. +- [ ] __Implements Warning Logging With Resource State Removal__: If a resource is removed outside of Terraform (e.g. via different tool, API, or web UI), `d.SetId("")` and `return nil` can be used in the resource `Read` function to trigger resource recreation. When this occurs, a warning log message should be printed beforehand: `log.Printf("[WARN] {SERVICE} {THING} (%s) not found, removing from state", d.Id())` +- [ ] __Uses isAWSErr() with AWS Go SDK Error Objects__: Use the available `isAWSErr(err error, code string, message string)` helper function instead of the `awserr` package to compare error code and message contents. +- [ ] __Uses %s fmt Verb with AWS Go SDK Objects__: AWS Go SDK objects implement `String()` so using the `%v`, `%#v`, or `%+v` fmt verbs with the object are extraneous or provide unhelpful detail. +- [ ] __Uses Elem with TypeMap__: While provider schema validation does not error when the `Elem` configuration is not present with `Type: schema.TypeMap` attributes, including the explicit `Elem: &schema.Schema{Type: schema.TypeString}` is recommended. +- [ ] __Uses American English for Attribute Naming__: For any ambiguity with attribute naming, prefer American English over British English. e.g. `color` instead of `colour`. +- [ ] __Skips Timestamp Attributes__: Generally, creation and modification dates from the API should be omitted from the schema. +- [ ] __Skips Error() Call with AWS Go SDK Error Objects__: Error objects do not need to have `Error()` called. \ No newline at end of file diff --git a/info/contributing/running-and-writing-acceptance-tests.md b/info/contributing/running-and-writing-acceptance-tests.md new file mode 100644 index 00000000000..7d419488676 --- /dev/null +++ b/info/contributing/running-and-writing-acceptance-tests.md @@ -0,0 +1,439 @@ +# Running and Writing Acceptance Tests + + - [Acceptance Tests Often Cost Money to Run](#acceptance-tests-often-cost-money-to-run) + - [Running an Acceptance Test](#running-an-acceptance-test) + - [Writing an Acceptance Test](#writing-an-acceptance-test) + - [Writing and running Cross-Account Acceptance Tests](#writing-and-running-cross-account-acceptance-tests) + - [Writing and running Cross-Region Acceptance Tests](#writing-and-running-cross-region-acceptance-tests) + - [Acceptance Test Checklist](#acceptance-test-checklist) + +Terraform includes an acceptance test harness that does most of the repetitive +work involved in testing a resource. For additional information about testing +Terraform Providers, see the [Extending Terraform documentation](https://www.terraform.io/docs/extend/testing/index.html). + +## Acceptance Tests Often Cost Money to Run + +Because acceptance tests create real resources, they often cost money to run. +Because the resources only exist for a short period of time, the total amount +of money required is usually a relatively small. Nevertheless, we don't want +financial limitations to be a barrier to contribution, so if you are unable to +pay to run acceptance tests for your contribution, mention this in your +pull request. We will happily accept "best effort" implementations of +acceptance tests and run them for you on our side. This might mean that your PR +takes a bit longer to merge, but it most definitely is not a blocker for +contributions. + +## Running an Acceptance Test + +Acceptance tests can be run using the `testacc` target in the Terraform +`Makefile`. The individual tests to run can be controlled using a regular +expression. Prior to running the tests provider configuration details such as +access keys must be made available as environment variables. + +For example, to run an acceptance test against the Amazon Web Services +provider, the following environment variables must be set: + +```sh +# Using a profile +export AWS_PROFILE=... +# Otherwise +export AWS_ACCESS_KEY_ID=... +export AWS_SECRET_ACCESS_KEY=... +export AWS_DEFAULT_REGION=... +``` + +Please note that the default region for the testing is `us-west-2` and must be +overriden via the `AWS_DEFAULT_REGION` environment variable, if necessary. This +is especially important for testing AWS GovCloud (US), which requires: + +```sh +export AWS_DEFAULT_REGION=us-gov-west-1 +``` + +Tests can then be run by specifying the target provider and a regular +expression defining the tests to run: + +```sh +$ make testacc TEST=./aws TESTARGS='-run=TestAccAWSCloudWatchDashboard_update' +==> Checking that code complies with gofmt requirements... +TF_ACC=1 go test ./aws -v -run=TestAccAWSCloudWatchDashboard_update -timeout 120m +=== RUN TestAccAWSCloudWatchDashboard_update +--- PASS: TestAccAWSCloudWatchDashboard_update (26.56s) +PASS +ok github.com/terraform-providers/terraform-provider-aws/aws 26.607s +``` + +Entire resource test suites can be targeted by using the naming convention to +write the regular expression. For example, to run all tests of the +`aws_cloudwatch_dashboard` resource rather than just the update test, you can start +testing like this: + +```sh +$ make testacc TEST=./aws TESTARGS='-run=TestAccAWSCloudWatchDashboard' +==> Checking that code complies with gofmt requirements... +TF_ACC=1 go test ./aws -v -run=TestAccAWSCloudWatchDashboard -timeout 120m +=== RUN TestAccAWSCloudWatchDashboard_importBasic +--- PASS: TestAccAWSCloudWatchDashboard_importBasic (15.06s) +=== RUN TestAccAWSCloudWatchDashboard_basic +--- PASS: TestAccAWSCloudWatchDashboard_basic (12.70s) +=== RUN TestAccAWSCloudWatchDashboard_update +--- PASS: TestAccAWSCloudWatchDashboard_update (27.81s) +PASS +ok github.com/terraform-providers/terraform-provider-aws/aws 55.619s +``` + +Please Note: On macOS 10.14 and later (and some Linux distributions), the default user open file limit is 256. This may cause unexpected issues when running the acceptance testing since this can prevent various operations from occurring such as opening network connections to AWS. To view this limit, the `ulimit -n` command can be run. To update this limit, run `ulimit -n 1024` (or higher). + +## Writing an Acceptance Test + +Terraform has a framework for writing acceptance tests which minimises the +amount of boilerplate code necessary to use common testing patterns. The entry +point to the framework is the `resource.ParallelTest()` function. + +Tests are divided into `TestStep`s. Each `TestStep` proceeds by applying some +Terraform configuration using the provider under test, and then verifying that +results are as expected by making assertions using the provider API. It is +common for a single test function to exercise both the creation of and updates +to a single resource. Most tests follow a similar structure. + +1. Pre-flight checks are made to ensure that sufficient provider configuration + is available to be able to proceed - for example in an acceptance test + targeting AWS, `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` must be set prior + to running acceptance tests. This is common to all tests exercising a single + provider. + +Each `TestStep` is defined in the call to `resource.ParallelTest()`. Most assertion +functions are defined out of band with the tests. This keeps the tests +readable, and allows reuse of assertion functions across different tests of the +same type of resource. The definition of a complete test looks like this: + +```go +func TestAccAWSCloudWatchDashboard_basic(t *testing.T) { + var dashboard cloudwatch.GetDashboardOutput + rInt := acctest.RandInt() + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCloudWatchDashboardDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudWatchDashboardConfig(rInt), + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudWatchDashboardExists("aws_cloudwatch_dashboard.foobar", &dashboard), + resource.TestCheckResourceAttr("aws_cloudwatch_dashboard.foobar", "dashboard_name", testAccAWSCloudWatchDashboardName(rInt)), + ), + }, + }, + }) +} +``` + +When executing the test, the following steps are taken for each `TestStep`: + +1. The Terraform configuration required for the test is applied. This is + responsible for configuring the resource under test, and any dependencies it + may have. For example, to test the `aws_cloudwatch_dashboard` resource, a valid configuration with the requisite fields is required. This results in configuration which looks like this: + + ```hcl + resource "aws_cloudwatch_dashboard" "foobar" { + dashboard_name = "terraform-test-dashboard-%d" + dashboard_body = < Date: Thu, 7 May 2020 21:54:56 -0400 Subject: [PATCH 063/475] Update module bflad/tfproviderdocs to v0.5.3 (#13225) Co-authored-by: Renovate Bot --- go.mod | 2 +- go.sum | 4 ++-- vendor/github.com/bflad/tfproviderdocs/.gitignore | 1 + vendor/github.com/bflad/tfproviderdocs/CHANGELOG.md | 6 ++++++ .../github.com/bflad/tfproviderdocs/check/directory.go | 10 +++++++++- .../check/sidenavigation/sidenavigation.go | 2 +- .../github.com/bflad/tfproviderdocs/version/version.go | 2 +- vendor/modules.txt | 2 +- 8 files changed, 22 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 120bddb6b06..fe28e1d0016 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.13 require ( github.com/aws/aws-sdk-go v1.30.21 github.com/beevik/etree v1.1.0 - github.com/bflad/tfproviderdocs v0.5.2 + github.com/bflad/tfproviderdocs v0.5.3 github.com/bflad/tfproviderlint v0.14.0 github.com/client9/misspell v0.3.4 github.com/golangci/golangci-lint v1.26.0 diff --git a/go.sum b/go.sum index bc78c6c6174..63b3b715bd3 100644 --- a/go.sum +++ b/go.sum @@ -47,8 +47,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/bflad/gopaniccheck v0.1.0 h1:tJftp+bv42ouERmUMWLoUn/5bi/iQZjHPznM00cP/bU= github.com/bflad/gopaniccheck v0.1.0/go.mod h1:ZCj2vSr7EqVeDaqVsWN4n2MwdROx1YL+LFo47TSWtsA= -github.com/bflad/tfproviderdocs v0.5.2 h1:iQoJJTXYcd9eVuWICK6gBNSYcy4FCS2ZdhwiH/iLfq8= -github.com/bflad/tfproviderdocs v0.5.2/go.mod h1:d0k1fQLEu1pdeORxozwuwmvauFaEmMBREQ1fw3J+pPc= +github.com/bflad/tfproviderdocs v0.5.3 h1:0JozhslEaLujgTnV6OdljbFiT/FCponx5hruFSkizGk= +github.com/bflad/tfproviderdocs v0.5.3/go.mod h1:d0k1fQLEu1pdeORxozwuwmvauFaEmMBREQ1fw3J+pPc= github.com/bflad/tfproviderlint v0.14.0 h1:iki5tDr4l0jp0zEL0chZylptMT5QdE09E60cziFQNZA= github.com/bflad/tfproviderlint v0.14.0/go.mod h1:1Jtjs6DPKoyqPrbPyMiy33h0ViO2h831uzoOuikCA60= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= diff --git a/vendor/github.com/bflad/tfproviderdocs/.gitignore b/vendor/github.com/bflad/tfproviderdocs/.gitignore index 560afc14739..b7c5ec8050d 100644 --- a/vendor/github.com/bflad/tfproviderdocs/.gitignore +++ b/vendor/github.com/bflad/tfproviderdocs/.gitignore @@ -3,3 +3,4 @@ .idea/ .vscode/ dist/ +RELEASE-NOTES.md diff --git a/vendor/github.com/bflad/tfproviderdocs/CHANGELOG.md b/vendor/github.com/bflad/tfproviderdocs/CHANGELOG.md index 4a88a5e8c01..515bfc5325e 100644 --- a/vendor/github.com/bflad/tfproviderdocs/CHANGELOG.md +++ b/vendor/github.com/bflad/tfproviderdocs/CHANGELOG.md @@ -1,3 +1,9 @@ +# v0.5.3 + +BUG FIXES + +* check: Prevent additional errors when `docs/` contains files outside Terraform Provider documentation + # v0.5.2 BUG FIXES diff --git a/vendor/github.com/bflad/tfproviderdocs/check/directory.go b/vendor/github.com/bflad/tfproviderdocs/check/directory.go index 0fa488fd46e..aa3738e1e73 100644 --- a/vendor/github.com/bflad/tfproviderdocs/check/directory.go +++ b/vendor/github.com/bflad/tfproviderdocs/check/directory.go @@ -9,7 +9,7 @@ import ( ) const ( - DocumentationGlobPattern = `{docs,website/docs}/**/*` + DocumentationGlobPattern = `{docs/index.md,docs/{data-sources,guides,resources},website/docs}/**/*` LegacyIndexDirectory = `website/docs` LegacyDataSourcesDirectory = `website/docs/d` @@ -127,6 +127,14 @@ func GetDirectories(basepath string) (map[string][]string, error) { } directory := filepath.Dir(file) + + // Skip handling of docs/ files except index.md + // if directory == RegistryIndexDirectory && filepath.Base(file) != "index.md" { + // continue + // } + + // Skip handling of docs/** outside valid Registry Directories + directories[directory] = append(directories[directory], file) } diff --git a/vendor/github.com/bflad/tfproviderdocs/check/sidenavigation/sidenavigation.go b/vendor/github.com/bflad/tfproviderdocs/check/sidenavigation/sidenavigation.go index 7cf27416694..e64fb7d8c95 100644 --- a/vendor/github.com/bflad/tfproviderdocs/check/sidenavigation/sidenavigation.go +++ b/vendor/github.com/bflad/tfproviderdocs/check/sidenavigation/sidenavigation.go @@ -48,7 +48,7 @@ func FindFile(path string) (*SideNavigation, error) { fileContents, err := ioutil.ReadFile(path) if err != nil { - log.Fatalf("error opening file (%s): %w", path, err) + log.Fatalf("error opening file (%s): %s", path, err) } return FindString(string(fileContents)) diff --git a/vendor/github.com/bflad/tfproviderdocs/version/version.go b/vendor/github.com/bflad/tfproviderdocs/version/version.go index 1bdf10bbfe9..97f2848c8b4 100644 --- a/vendor/github.com/bflad/tfproviderdocs/version/version.go +++ b/vendor/github.com/bflad/tfproviderdocs/version/version.go @@ -11,7 +11,7 @@ var ( GitDescribe string // The main version number that is being run at the moment. - Version = "0.5.2" + Version = "0.5.3" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release diff --git a/vendor/modules.txt b/vendor/modules.txt index db362e04db2..1e0da311f48 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -215,7 +215,7 @@ github.com/bflad/gopaniccheck/passes/logpaniccallexpr github.com/bflad/gopaniccheck/passes/logpanicfcallexpr github.com/bflad/gopaniccheck/passes/logpaniclncallexpr github.com/bflad/gopaniccheck/passes/paniccallexpr -# github.com/bflad/tfproviderdocs v0.5.2 +# github.com/bflad/tfproviderdocs v0.5.3 github.com/bflad/tfproviderdocs github.com/bflad/tfproviderdocs/check github.com/bflad/tfproviderdocs/check/sidenavigation From 11577bb5501b5f0dd93ada2ae7f2c2d34ea6afc8 Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Thu, 7 May 2020 18:55:27 -0700 Subject: [PATCH 064/475] add link to the label dictionary --- info/MAINTAINING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/info/MAINTAINING.md b/info/MAINTAINING.md index a70c5f4ca84..867ce11b159 100644 --- a/info/MAINTAINING.md +++ b/info/MAINTAINING.md @@ -19,7 +19,7 @@ ## Triage -Incoming issues are classified using labels. These are assigned either by automation, or manually during the triage process. At a minimum tickets should be classified by type and by the area of the provider they affect. +Incoming issues are classified using labels. These are assigned either by automation, or manually during the triage process. At a minimum tickets should be classified by type and by the area of the provider they affect. A full listing of the labels and how they are used can be found in the [Label Dictionary](#label-dictionary) ## Pull Requests From 5c1cafdffd4b9c57f59dcf56c6f7029b4a85b2a2 Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Thu, 7 May 2020 20:08:35 -0700 Subject: [PATCH 065/475] some FAQ changes --- info/FAQ.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/info/FAQ.md b/info/FAQ.md index 4ca45b5b256..43bdaad89ec 100644 --- a/info/FAQ.md +++ b/info/FAQ.md @@ -13,12 +13,14 @@ The HashiCorp Terraform AWS provider team is : ### Why isn’t my PR merged yet? -Unfortunately, due to the volume of issues and new pull requests we receive, we are unable to give each one the full attention that we would like. We always focus on the contributions that provide the most value to the most community members. +Unfortunately, due to the volume of issues and new pull requests we receive, we are unable to give each one the full attention that we would like. We always focus on the contributions that provide the greatest value to the most community members. ### How do you decide what gets merged for each release? The number one factor we look at when deciding what issues to look at are your reactions, comments, and upvotes on the issues or PR’s. The items with the most support are always on our radar, and we commit to keep the community updated on their status and potential timelines. +We publish a [roadmap](../ROADMAP.md) every quarter which describes major themes or specific product areas of focus. + We also are investing time to improve the contributing experience by improving documentation, adding more linter coverage to ensure that incoming PR's can be in as good shape as possible. This will allow us to get through them quicker. ### How often do you release? @@ -58,7 +60,7 @@ provider "aws" { ### How can I help? -Great question, if you have contributed before check out issues with the `help-wanted` label. These are normally issues with support, but we are currently unable to field resources to work on. If you are just getting started, take a look at issues with the `good-first-issue` label. Items with these labels will always be given priority for response. +Great question, if you have contributed before check out issues with the `help-wanted` label. These are normally features which we want to support, but we are currently unable to field resources to work on. If you are just getting started, take a look at issues with the `good-first-issue` label. Items with these labels will always be given priority for response. ### How can I become a maintainer? From 565152f88741dd6d9c8a8c8f8c6f136258ba848b Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Thu, 7 May 2020 20:15:44 -0700 Subject: [PATCH 066/475] Update info/FAQ.md Co-authored-by: Brian Flad --- info/FAQ.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/info/FAQ.md b/info/FAQ.md index 43bdaad89ec..c28b1824bb9 100644 --- a/info/FAQ.md +++ b/info/FAQ.md @@ -47,8 +47,11 @@ Error: error validating provider credentials: error calling sts:GetCallerIdentit on main.tf line 1, in provider "aws": 1: provider "aws" { +``` To use this new region before support has been added to the Terraform AWS Provider, you can disable the provider's automatic region validation via: + +```hcl provider "aws" { # ... potentially other configuration ... @@ -64,4 +67,4 @@ Great question, if you have contributed before check out issues with the `help-w ### How can I become a maintainer? -This is an area under active research. Stay tuned! \ No newline at end of file +This is an area under active research. Stay tuned! From c874930731eb7f08151a0ef467c623567aad49f7 Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Thu, 7 May 2020 20:16:15 -0700 Subject: [PATCH 067/475] Update info/MAINTAINING.md Co-authored-by: Brian Flad --- info/MAINTAINING.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/info/MAINTAINING.md b/info/MAINTAINING.md index 867ce11b159..7ee79e7b2f2 100644 --- a/info/MAINTAINING.md +++ b/info/MAINTAINING.md @@ -332,8 +332,7 @@ The CHANGELOG is intended to show operator-impacting changes to the codebase for | ![service <*>][service-badge] | Indicates the service that is covered or introduced (i.e. service/s3) | Added by Hashibot when the code change matches a service definition in `.hashibot.hcl`. | ![size%2F<*>][size-badge] | Managed by automation to categorize the size of a PR | Added by Hashibot to indicate the size of the PR. | | [![stale][stale-badge]][stale] | Old or inactive issues managed by automation, if no further action taken these will get closed. | Added by a Github Action, configuration is found: `.github/workflows/stale.yml`. | -| [![technical-debt][technical-debt-badge]][technical-debt] | -Addresses areas of the codebase that need refactoring or redesign. | None| +| [![technical-debt][technical-debt-badge]][technical-debt] | Addresses areas of the codebase that need refactoring or redesign. | None | | [![tests][tests-badge]][tests] | On a PR this indicates expanded test coverage. On an Issue this proposes expanded coverage or enhancement to test infrastructure. | None | | [![thinking][thinking-badge]][thinking] | Requires additional research by the maintainers. | None | | [![upstream-terraform][upstream-terraform-badge]][upstream-terraform] | Addresses functionality related to the Terraform core binary. | None | From 990b8e4062660c85e9cc76ea9d42b4d2df7d950c Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Thu, 7 May 2020 20:20:13 -0700 Subject: [PATCH 068/475] fix waiting response tag link --- info/MAINTAINING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/info/MAINTAINING.md b/info/MAINTAINING.md index 7ee79e7b2f2..b8f9fa8767b 100644 --- a/info/MAINTAINING.md +++ b/info/MAINTAINING.md @@ -19,7 +19,7 @@ ## Triage -Incoming issues are classified using labels. These are assigned either by automation, or manually during the triage process. At a minimum tickets should be classified by type and by the area of the provider they affect. A full listing of the labels and how they are used can be found in the [Label Dictionary](#label-dictionary) +Incoming issues are classified using labels. These are assigned either by automation, or manually during the triage process. At a minimum tickets should be classified by type and by the area of the provider they affect. A full listing of the labels and how they are used can be found in the [Label Dictionary](#label-dictionary). ## Pull Requests @@ -337,7 +337,7 @@ The CHANGELOG is intended to show operator-impacting changes to the codebase for | [![thinking][thinking-badge]][thinking] | Requires additional research by the maintainers. | None | | [![upstream-terraform][upstream-terraform-badge]][upstream-terraform] | Addresses functionality related to the Terraform core binary. | None | | [![upstream][upstream-badge]][upstream] | Addresses functionality related to the cloud provider. | None | -| [![waiting-response](https://img.shields.io/badge/waiting--response-5319e7)](https://github.com/terraform-providers/terraform-provider-aws/labels/waiting-response) | Addresses functionality related to the cloud provider. | None | +| [![waiting-response][waiting-response-badge]][waiting-response] | Addresses functionality related to the cloud provider. | None | [breaking-change-badge]: https://img.shields.io/badge/breaking--change-d93f0b [breaking-change]: https://github.com/terraform-providers/terraform-provider-aws/labels/breaking-change @@ -389,5 +389,5 @@ The CHANGELOG is intended to show operator-impacting changes to the codebase for [upstream-terraform]: https://github.com/terraform-providers/terraform-provider-aws/labels/upstream-terraform [upstream-badge]: https://img.shields.io/badge/upstream-fad8c7 [upstream]: https://github.com/terraform-providers/terraform-provider-aws/labels/upstream -[waiting-response-badge]: https://img.shields.io/badge/waiting-response-bfd4f2 +[waiting-response-badge]: https://img.shields.io/badge/waiting--response-5319e7 [waiting-response]: https://github.com/terraform-providers/terraform-provider-aws/labels/waiting-response From a19c634ecf986ab5f91789e1030a5ebabbf8750c Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Thu, 7 May 2020 20:26:04 -0700 Subject: [PATCH 069/475] Update info/contributing/contribution-checklists.md Co-authored-by: Brian Flad --- info/contributing/contribution-checklists.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/info/contributing/contribution-checklists.md b/info/contributing/contribution-checklists.md index 8da282e2eb6..d29e1394d57 100644 --- a/info/contributing/contribution-checklists.md +++ b/info/contributing/contribution-checklists.md @@ -506,6 +506,7 @@ into Terraform. - In `website/allowed-subcategories.txt`: Add a name acceptable for the documentation navigation. - In `website/docs/guides/custom-service-endpoints.html.md`: Add the service name in the list of customizable endpoints. + - In `infrastructure/repository/labels-service.tf`: Add the new service to create a repository label. - In `.hashibot.hcl`: Add the new service to automated issue and pull request labeling. e.g. with the `quicksight` service ```hcl @@ -564,4 +565,4 @@ manually sourced values from documentation. - [ ] Check [CloudTrail Supported Regions docs](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-supported-regions.html#cloudtrail-supported-regions) and add AWS Account ID if available to `aws/data_source_aws_cloudtrail_service_account.go` - [ ] Check [Elastic Load Balancing Access Logs docs](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-access-logs.html#attach-bucket-policy) and add Elastic Load Balancing Account ID if available to `aws/data_source_aws_elb_service_account.go` - [ ] Check [Redshift Database Audit Logging docs](https://docs.aws.amazon.com/redshift/latest/mgmt/db-auditing.html#db-auditing-bucket-permissions) and add AWS Account ID if available to `aws/data_source_aws_redshift_service_account.go` - - [ ] Check [AWS Elastic Beanstalk endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/elasticbeanstalk.html#elasticbeanstalk_region) and add Route53 Hosted Zone ID if available to `aws/data_source_aws_elastic_beanstalk_hosted_zone.go` \ No newline at end of file + - [ ] Check [AWS Elastic Beanstalk endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/elasticbeanstalk.html#elasticbeanstalk_region) and add Route53 Hosted Zone ID if available to `aws/data_source_aws_elastic_beanstalk_hosted_zone.go` From 7e1db5a0748b0871dd6551f98f0e548124de33e5 Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Thu, 7 May 2020 20:26:43 -0700 Subject: [PATCH 070/475] Update info/FAQ.md Co-authored-by: Brian Flad --- info/FAQ.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/info/FAQ.md b/info/FAQ.md index c28b1824bb9..9e2d1fd4eab 100644 --- a/info/FAQ.md +++ b/info/FAQ.md @@ -29,7 +29,9 @@ We release weekly on Thursday. We release often to ensure we can bring value to ### Backward Compatibility Promise -Our policy is described on the Terraform website [here](https://www.terraform.io/docs/extend/best-practices/versioning.html). +Our policy is described on the Terraform website [here](https://www.terraform.io/docs/extend/best-practices/versioning.html). While we do our best to prevent breaking changes until major version releases of the provider, it is generally recommended to [pin the provider version in your configuration](https://www.terraform.io/docs/configuration/providers.html#provider-versions). + +Due to the constant release pace of AWS and the relatively infrequent major version releases of the provider, there can be cases where a minor version update may contain unexpected changes depending on your configuration or environment. These may include items such as a resource requiring additional IAM permissions to support newer functionality. We typically base these decisions on a pragmatic compromise between introducing a relatively minor one-time inconvenience for a subset of the community versus better overall user experience for the entire community. ### AWS just announced a new region, when will I see it in the provider. From 5f84a958c3a49ee7be18aeaf7e5dffa8c6c704ba Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Thu, 7 May 2020 20:27:56 -0700 Subject: [PATCH 071/475] code review fixes --- info/FAQ.md | 4 +++- info/MAINTAINING.md | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/info/FAQ.md b/info/FAQ.md index c28b1824bb9..e62b6e3a27b 100644 --- a/info/FAQ.md +++ b/info/FAQ.md @@ -63,7 +63,9 @@ provider "aws" { ### How can I help? -Great question, if you have contributed before check out issues with the `help-wanted` label. These are normally features which we want to support, but we are currently unable to field resources to work on. If you are just getting started, take a look at issues with the `good-first-issue` label. Items with these labels will always be given priority for response. +Great question, if you have contributed before check out issues with the `help-wanted` label. These are normally enhancement issues that will have a great impact, but the maintainers are unable to develop them in the near future. If you are just getting started, take a look at issues with the `good-first-issue` label. Items with these labels will always be given priority for response. + +Check out the [Contributing Guide](CONTRIBUTING.md) for additional information. ### How can I become a maintainer? diff --git a/info/MAINTAINING.md b/info/MAINTAINING.md index b8f9fa8767b..3bf4e6baec7 100644 --- a/info/MAINTAINING.md +++ b/info/MAINTAINING.md @@ -314,14 +314,14 @@ The CHANGELOG is intended to show operator-impacting changes to the codebase for | [![breaking-change][breaking-change-badge]][breaking-change]                                    | Introduces a breaking change in current functionality; breaking changes are usually deferred to the next major release. | None | | [![bug][bug-badge]][bug] | Addresses a defect in current functionality. | None | | [![crash][crash-badge]][crash] | Results from or addresses a Terraform crash or kernel panic. | None | -| [![dependencies][dependencies-badge]][dependencies] | Used to indicate a dependency version update. | Added by the Renovate bot. Configuration is found in the `renovate.json` file. | +| [![dependencies][dependencies-badge]][dependencies] | Used to indicate dependency or vendoring changes. | Added by Hashibot. | | [![documentation][documentation-badge]][documentation] | Introduces or discusses updates to documentation. | None | | [![enhancement][enhancement-badge]][enhancement] | Requests to existing resources that expand the functionality or scope. | None | | [![good first issue][good-first-issue-badge]][good-first-issue] | Call to action for new contributors looking for a place to start. Smaller or straightforward issues. | None | | [![hacktoberfest][hacktoberfest-badge]][hacktoberfest] | Call to action for Hacktoberfest (OSS Initiative). | None | | [![hashibot ignore][hashibot-ignore-badge]][hashibot-ignore] | Issues or PRs labelled with this are ignored by Hashibot. | None | | [![help wanted][help-wanted-badge]][help-wanted] | Call to action for contributors. Indicates an area of the codebase we’d like to expand/work on but don’t have the bandwidth inside the team. | None | -| [![needs-triage][needs-triage-badge]][needs-triage] | Waiting for first response or review from a maintainer. | Added to all new issues or PRs by GitHub action in `.github/workflows/issues.yml` unless they were submitted by a maintainer. | +| [![needs-triage][needs-triage-badge]][needs-triage] | Waiting for first response or review from a maintainer. | Added to all new issues or PRs by GitHub action in `.github/workflows/issues.yml` or PRs by Hashibot in `.hashibot.hcl` unless they were submitted by a maintainer. | | [![new-data-source][new-data-source-badge]][new-data-source] | Introduces a new data source. | None | | [![new-resource][new-resource-badge]][new-resource] | Introduces a new resrouce. | None | | [![proposal][proposal-badge]][proposal] | Proposes new design or functionality. | None | @@ -337,7 +337,7 @@ The CHANGELOG is intended to show operator-impacting changes to the codebase for | [![thinking][thinking-badge]][thinking] | Requires additional research by the maintainers. | None | | [![upstream-terraform][upstream-terraform-badge]][upstream-terraform] | Addresses functionality related to the Terraform core binary. | None | | [![upstream][upstream-badge]][upstream] | Addresses functionality related to the cloud provider. | None | -| [![waiting-response][waiting-response-badge]][waiting-response] | Addresses functionality related to the cloud provider. | None | +| [![waiting-response][waiting-response-badge]][waiting-response] | Maintainers are waiting on response from community or contributor. | None | [breaking-change-badge]: https://img.shields.io/badge/breaking--change-d93f0b [breaking-change]: https://github.com/terraform-providers/terraform-provider-aws/labels/breaking-change From 1e58589b9332370d54f93aefa93c50df7c5f530d Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Thu, 7 May 2020 20:30:24 -0700 Subject: [PATCH 072/475] FAQ revision --- info/FAQ.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/info/FAQ.md b/info/FAQ.md index 69566cdfc4c..daf43af1edf 100644 --- a/info/FAQ.md +++ b/info/FAQ.md @@ -17,7 +17,7 @@ Unfortunately, due to the volume of issues and new pull requests we receive, we ### How do you decide what gets merged for each release? -The number one factor we look at when deciding what issues to look at are your reactions, comments, and upvotes on the issues or PR’s. The items with the most support are always on our radar, and we commit to keep the community updated on their status and potential timelines. +The number one factor we look at when deciding what issues to look at are your 👍 [reactions](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue/PR description as these can be easily discovered. Comments that further explain desired use cases or poor user experience are also heavily factored. The items with the most support are always on our radar, and we commit to keep the community updated on their status and potential timelines. We publish a [roadmap](../ROADMAP.md) every quarter which describes major themes or specific product areas of focus. From 2e44671f325ec1154f1d908eaa83854c1cb2f55f Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Thu, 7 May 2020 20:36:40 -0700 Subject: [PATCH 073/475] info > docs --- README.md | 6 +++--- {info => docs}/CONTRIBUTING.md | 0 {info => docs}/CORE_SERVICES.md | 0 {info => docs}/DEVELOPMENT.md | 2 +- {info => docs}/FAQ.md | 0 {info => docs}/MAINTAINING.md | 0 {info => docs}/contributing/contribution-checklists.md | 0 .../contributing/issue-reporting-and-lifecycle.md | 0 .../contributing/pullrequest-submission-and-lifecycle.md | 0 .../contributing/running-and-writing-acceptance-tests.md | 0 10 files changed, 4 insertions(+), 4 deletions(-) rename {info => docs}/CONTRIBUTING.md (100%) rename {info => docs}/CORE_SERVICES.md (100%) rename {info => docs}/DEVELOPMENT.md (87%) rename {info => docs}/FAQ.md (100%) rename {info => docs}/MAINTAINING.md (100%) rename {info => docs}/contributing/contribution-checklists.md (100%) rename {info => docs}/contributing/issue-reporting-and-lifecycle.md (100%) rename {info => docs}/contributing/pullrequest-submission-and-lifecycle.md (100%) rename {info => docs}/contributing/running-and-writing-acceptance-tests.md (100%) diff --git a/README.md b/README.md index cf02d4ddf61..45fb5e8cedb 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Please note: We take Terraform's security and our users' trust very seriously. I ## Quick Starts - [Using the provider](https://www.terraform.io/docs/providers/aws/index.html) -- [Provider development](info/DEVELOPMENT.md) +- [Provider development](docs/DEVELOPMENT.md) ## Documentation @@ -44,10 +44,10 @@ Our roadmap for expanding support in Terraform for AWS resources can be found in ## Frequently Asked Questions -Responses to our most frequently asked questions can be found in our [FAQ](info/FAQ.md ) +Responses to our most frequently asked questions can be found in our [FAQ](docs/FAQ.md ) ## Contributing The Terraform AWS Provider is the work of thousands of contributors. We appreciate your help! -To contribute, please read the contribution guidelines: [Contributing to Terraform - AWS Provider](info/CONTRIBUTING.md) \ No newline at end of file +To contribute, please read the contribution guidelines: [Contributing to Terraform - AWS Provider](docs/CONTRIBUTING.md) \ No newline at end of file diff --git a/info/CONTRIBUTING.md b/docs/CONTRIBUTING.md similarity index 100% rename from info/CONTRIBUTING.md rename to docs/CONTRIBUTING.md diff --git a/info/CORE_SERVICES.md b/docs/CORE_SERVICES.md similarity index 100% rename from info/CORE_SERVICES.md rename to docs/CORE_SERVICES.md diff --git a/info/DEVELOPMENT.md b/docs/DEVELOPMENT.md similarity index 87% rename from info/DEVELOPMENT.md rename to docs/DEVELOPMENT.md index 0a1bf4ee5c2..017f1706f19 100644 --- a/info/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -46,7 +46,7 @@ $ make test In order to run the full suite of Acceptance tests, run `make testacc`. -*Note:* Acceptance tests create real resources, and often cost money to run. Please read [Running an Acceptance Test](https://github.com/terraform-providers/terraform-provider-aws/blob/master/.github/CONTRIBUTING.md#running-an-acceptance-test) in the contribution guidelines for more information on usage. +*Note:* Acceptance tests create real resources, and often cost money to run. Please read [Running and Writing Acceptance Tests](contributing/running-and-writing-acceptance-tests.md) in the contribution guidelines for more information on usage. ```sh $ make testacc diff --git a/info/FAQ.md b/docs/FAQ.md similarity index 100% rename from info/FAQ.md rename to docs/FAQ.md diff --git a/info/MAINTAINING.md b/docs/MAINTAINING.md similarity index 100% rename from info/MAINTAINING.md rename to docs/MAINTAINING.md diff --git a/info/contributing/contribution-checklists.md b/docs/contributing/contribution-checklists.md similarity index 100% rename from info/contributing/contribution-checklists.md rename to docs/contributing/contribution-checklists.md diff --git a/info/contributing/issue-reporting-and-lifecycle.md b/docs/contributing/issue-reporting-and-lifecycle.md similarity index 100% rename from info/contributing/issue-reporting-and-lifecycle.md rename to docs/contributing/issue-reporting-and-lifecycle.md diff --git a/info/contributing/pullrequest-submission-and-lifecycle.md b/docs/contributing/pullrequest-submission-and-lifecycle.md similarity index 100% rename from info/contributing/pullrequest-submission-and-lifecycle.md rename to docs/contributing/pullrequest-submission-and-lifecycle.md diff --git a/info/contributing/running-and-writing-acceptance-tests.md b/docs/contributing/running-and-writing-acceptance-tests.md similarity index 100% rename from info/contributing/running-and-writing-acceptance-tests.md rename to docs/contributing/running-and-writing-acceptance-tests.md From 3d63d920fa49a79192de7ede6a114d55c7fbe698 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 8 May 2020 17:39:28 -0400 Subject: [PATCH 074/475] add elem attribute to typemaps --- aws/data_source_aws_ami.go | 2 ++ aws/data_source_aws_cloudformation_stack.go | 2 ++ aws/data_source_aws_elasticsearch_domain.go | 1 + aws/data_source_aws_lb_listener.go | 2 ++ aws/data_source_aws_s3_bucket_object.go | 1 + aws/data_source_aws_secretsmanager_secret.go | 1 + aws/resource_aws_api_gateway_stage.go | 1 + aws/resource_aws_autoscaling_group.go | 9 ++++++--- aws/resource_aws_budgets_budget.go | 1 + aws/resource_aws_cloudformation_stack.go | 2 ++ aws/resource_aws_cloudfront_distribution.go | 1 + aws/resource_aws_cloudwatch_event_target.go | 1 + aws/resource_aws_cloudwatch_metric_alarm.go | 2 ++ aws/resource_aws_cognito_identity_provider.go | 1 + aws/resource_aws_dlm_lifecycle_policy.go | 2 ++ aws/resource_aws_elastic_transcoder_preset.go | 1 + aws/resource_aws_elasticsearch_domain.go | 1 + aws/resource_aws_emr_cluster.go | 1 + aws/resource_aws_glue_connection.go | 1 + aws/resource_aws_glue_job.go | 1 + aws/resource_aws_glue_trigger.go | 1 + aws/resource_aws_inspector_resource_group.go | 1 + aws/resource_aws_iot_thing.go | 1 + aws/resource_aws_lb_listener.go | 2 ++ aws/resource_aws_lb_listener_rule.go | 2 ++ aws/resource_aws_s3_bucket_analytics_configuration.go | 1 + aws/resource_aws_sagemaker_model.go | 2 ++ aws/resource_aws_spot_fleet_request.go | 1 + aws/resource_aws_spot_instance_request.go | 1 + aws/resource_aws_ssm_association.go | 1 + aws/tags.go | 3 +++ 31 files changed, 47 insertions(+), 3 deletions(-) diff --git a/aws/data_source_aws_ami.go b/aws/data_source_aws_ami.go index 0f5e9e12d92..f244ad4bae4 100644 --- a/aws/data_source_aws_ami.go +++ b/aws/data_source_aws_ami.go @@ -149,6 +149,7 @@ func dataSourceAwsAmi() *schema.Resource { "ebs": { Type: schema.TypeMap, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, }, }, @@ -173,6 +174,7 @@ func dataSourceAwsAmi() *schema.Resource { "state_reason": { Type: schema.TypeMap, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "tags": tagsSchemaComputed(), }, diff --git a/aws/data_source_aws_cloudformation_stack.go b/aws/data_source_aws_cloudformation_stack.go index 93a5a36bba5..9255192ae8e 100644 --- a/aws/data_source_aws_cloudformation_stack.go +++ b/aws/data_source_aws_cloudformation_stack.go @@ -46,10 +46,12 @@ func dataSourceAwsCloudFormationStack() *schema.Resource { "parameters": { Type: schema.TypeMap, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "outputs": { Type: schema.TypeMap, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "timeout_in_minutes": { Type: schema.TypeInt, diff --git a/aws/data_source_aws_elasticsearch_domain.go b/aws/data_source_aws_elasticsearch_domain.go index aab4877483c..3860ce98c7a 100644 --- a/aws/data_source_aws_elasticsearch_domain.go +++ b/aws/data_source_aws_elasticsearch_domain.go @@ -22,6 +22,7 @@ func dataSourceAwsElasticSearchDomain() *schema.Resource { "advanced_options": { Type: schema.TypeMap, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "domain_name": { Type: schema.TypeString, diff --git a/aws/data_source_aws_lb_listener.go b/aws/data_source_aws_lb_listener.go index f4bca086bd4..f35b59ebb36 100644 --- a/aws/data_source_aws_lb_listener.go +++ b/aws/data_source_aws_lb_listener.go @@ -62,6 +62,7 @@ func dataSourceAwsLbListener() *schema.Resource { "authentication_request_extra_params": { Type: schema.TypeMap, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "on_unauthenticated_request": { Type: schema.TypeString, @@ -102,6 +103,7 @@ func dataSourceAwsLbListener() *schema.Resource { "authentication_request_extra_params": { Type: schema.TypeMap, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "authorization_endpoint": { Type: schema.TypeString, diff --git a/aws/data_source_aws_s3_bucket_object.go b/aws/data_source_aws_s3_bucket_object.go index ec7d78300a0..d7b46197a35 100644 --- a/aws/data_source_aws_s3_bucket_object.go +++ b/aws/data_source_aws_s3_bucket_object.go @@ -74,6 +74,7 @@ func dataSourceAwsS3BucketObject() *schema.Resource { "metadata": { Type: schema.TypeMap, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "object_lock_legal_hold_status": { Type: schema.TypeString, diff --git a/aws/data_source_aws_secretsmanager_secret.go b/aws/data_source_aws_secretsmanager_secret.go index 76e5fbaca13..2f17ecbbe95 100644 --- a/aws/data_source_aws_secretsmanager_secret.go +++ b/aws/data_source_aws_secretsmanager_secret.go @@ -63,6 +63,7 @@ func dataSourceAwsSecretsManagerSecret() *schema.Resource { "tags": { Type: schema.TypeMap, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, }, } diff --git a/aws/resource_aws_api_gateway_stage.go b/aws/resource_aws_api_gateway_stage.go index 6131a706f78..96c6c62b146 100644 --- a/aws/resource_aws_api_gateway_stage.go +++ b/aws/resource_aws_api_gateway_stage.go @@ -113,6 +113,7 @@ func resourceAwsApiGatewayStage() *schema.Resource { "variables": { Type: schema.TypeMap, Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "tags": tagsSchema(), "xray_tracing_enabled": { diff --git a/aws/resource_aws_autoscaling_group.go b/aws/resource_aws_autoscaling_group.go index 189dcc90918..79ce5024fd4 100644 --- a/aws/resource_aws_autoscaling_group.go +++ b/aws/resource_aws_autoscaling_group.go @@ -396,9 +396,12 @@ func resourceAwsAutoscalingGroup() *schema.Resource { "tag": autoscalingTagSchema(), "tags": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeMap}, + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeMap, + Elem: &schema.Schema{Type: schema.TypeString}, + }, ConflictsWith: []string{"tag"}, }, diff --git a/aws/resource_aws_budgets_budget.go b/aws/resource_aws_budgets_budget.go index 8298b7fb0f2..d8a59d0a57b 100644 --- a/aws/resource_aws_budgets_budget.go +++ b/aws/resource_aws_budgets_budget.go @@ -130,6 +130,7 @@ func resourceAwsBudgetsBudget() *schema.Resource { Type: schema.TypeMap, Optional: true, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "notification": { Type: schema.TypeSet, diff --git a/aws/resource_aws_cloudformation_stack.go b/aws/resource_aws_cloudformation_stack.go index efeed23d0fa..ffea86d7de5 100644 --- a/aws/resource_aws_cloudformation_stack.go +++ b/aws/resource_aws_cloudformation_stack.go @@ -79,10 +79,12 @@ func resourceAwsCloudFormationStack() *schema.Resource { Type: schema.TypeMap, Optional: true, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "outputs": { Type: schema.TypeMap, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "policy_body": { Type: schema.TypeString, diff --git a/aws/resource_aws_cloudfront_distribution.go b/aws/resource_aws_cloudfront_distribution.go index 93607c5eb1e..827b84b97aa 100644 --- a/aws/resource_aws_cloudfront_distribution.go +++ b/aws/resource_aws_cloudfront_distribution.go @@ -704,6 +704,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { "active_trusted_signers": { Type: schema.TypeMap, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "domain_name": { Type: schema.TypeString, diff --git a/aws/resource_aws_cloudwatch_event_target.go b/aws/resource_aws_cloudwatch_event_target.go index 9e559012e15..46fc9003207 100644 --- a/aws/resource_aws_cloudwatch_event_target.go +++ b/aws/resource_aws_cloudwatch_event_target.go @@ -215,6 +215,7 @@ func resourceAwsCloudWatchEventTarget() *schema.Resource { "input_paths": { Type: schema.TypeMap, Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "input_template": { Type: schema.TypeString, diff --git a/aws/resource_aws_cloudwatch_metric_alarm.go b/aws/resource_aws_cloudwatch_metric_alarm.go index d073979218d..aecc3289b6e 100644 --- a/aws/resource_aws_cloudwatch_metric_alarm.go +++ b/aws/resource_aws_cloudwatch_metric_alarm.go @@ -71,6 +71,7 @@ func resourceAwsCloudWatchMetricAlarm() *schema.Resource { "dimensions": { Type: schema.TypeMap, Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "metric_name": { Type: schema.TypeString, @@ -163,6 +164,7 @@ func resourceAwsCloudWatchMetricAlarm() *schema.Resource { Type: schema.TypeMap, Optional: true, ConflictsWith: []string{"metric_query"}, + Elem: &schema.Schema{Type: schema.TypeString}, }, "insufficient_data_actions": { Type: schema.TypeSet, diff --git a/aws/resource_aws_cognito_identity_provider.go b/aws/resource_aws_cognito_identity_provider.go index 8364786aed5..ca9e5ff4398 100644 --- a/aws/resource_aws_cognito_identity_provider.go +++ b/aws/resource_aws_cognito_identity_provider.go @@ -49,6 +49,7 @@ func resourceAwsCognitoIdentityProvider() *schema.Resource { "provider_details": { Type: schema.TypeMap, Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "provider_name": { diff --git a/aws/resource_aws_dlm_lifecycle_policy.go b/aws/resource_aws_dlm_lifecycle_policy.go index 9c3f27ad115..3a99a9662a4 100644 --- a/aws/resource_aws_dlm_lifecycle_policy.go +++ b/aws/resource_aws_dlm_lifecycle_policy.go @@ -115,6 +115,7 @@ func resourceAwsDlmLifecyclePolicy() *schema.Resource { "tags_to_add": { Type: schema.TypeMap, Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, }, }, @@ -122,6 +123,7 @@ func resourceAwsDlmLifecyclePolicy() *schema.Resource { "target_tags": { Type: schema.TypeMap, Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, }, }, diff --git a/aws/resource_aws_elastic_transcoder_preset.go b/aws/resource_aws_elastic_transcoder_preset.go index 2273b12b2be..ca57e63b119 100644 --- a/aws/resource_aws_elastic_transcoder_preset.go +++ b/aws/resource_aws_elastic_transcoder_preset.go @@ -313,6 +313,7 @@ func resourceAwsElasticTranscoderPreset() *schema.Resource { Type: schema.TypeMap, Optional: true, ForceNew: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, }, } diff --git a/aws/resource_aws_elasticsearch_domain.go b/aws/resource_aws_elasticsearch_domain.go index d870352eeda..e932d9d4beb 100644 --- a/aws/resource_aws_elasticsearch_domain.go +++ b/aws/resource_aws_elasticsearch_domain.go @@ -69,6 +69,7 @@ func resourceAwsElasticSearchDomain() *schema.Resource { Type: schema.TypeMap, Optional: true, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "domain_name": { Type: schema.TypeString, diff --git a/aws/resource_aws_emr_cluster.go b/aws/resource_aws_emr_cluster.go index 65b6c160c2f..de696e96baf 100644 --- a/aws/resource_aws_emr_cluster.go +++ b/aws/resource_aws_emr_cluster.go @@ -561,6 +561,7 @@ func resourceAwsEMRCluster() *schema.Resource { Type: schema.TypeMap, Optional: true, ForceNew: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, }, }, diff --git a/aws/resource_aws_glue_connection.go b/aws/resource_aws_glue_connection.go index 6491868ab3d..46109fe255f 100644 --- a/aws/resource_aws_glue_connection.go +++ b/aws/resource_aws_glue_connection.go @@ -32,6 +32,7 @@ func resourceAwsGlueConnection() *schema.Resource { Type: schema.TypeMap, Required: true, Sensitive: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "connection_type": { Type: schema.TypeString, diff --git a/aws/resource_aws_glue_job.go b/aws/resource_aws_glue_job.go index 9e5579a7d17..1ac7ae6ebdc 100644 --- a/aws/resource_aws_glue_job.go +++ b/aws/resource_aws_glue_job.go @@ -67,6 +67,7 @@ func resourceAwsGlueJob() *schema.Resource { "default_arguments": { Type: schema.TypeMap, Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "description": { Type: schema.TypeString, diff --git a/aws/resource_aws_glue_trigger.go b/aws/resource_aws_glue_trigger.go index 7ddb8be631c..be43a4ee273 100644 --- a/aws/resource_aws_glue_trigger.go +++ b/aws/resource_aws_glue_trigger.go @@ -38,6 +38,7 @@ func resourceAwsGlueTrigger() *schema.Resource { "arguments": { Type: schema.TypeMap, Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "crawler_name": { Type: schema.TypeString, diff --git a/aws/resource_aws_inspector_resource_group.go b/aws/resource_aws_inspector_resource_group.go index 47de0a45f2d..4508a3b7523 100644 --- a/aws/resource_aws_inspector_resource_group.go +++ b/aws/resource_aws_inspector_resource_group.go @@ -20,6 +20,7 @@ func resourceAWSInspectorResourceGroup() *schema.Resource { ForceNew: true, Required: true, Type: schema.TypeMap, + Elem: &schema.Schema{Type: schema.TypeString}, }, "arn": { Type: schema.TypeString, diff --git a/aws/resource_aws_iot_thing.go b/aws/resource_aws_iot_thing.go index 19c4b44d1c9..c6d76ab45fb 100644 --- a/aws/resource_aws_iot_thing.go +++ b/aws/resource_aws_iot_thing.go @@ -30,6 +30,7 @@ func resourceAwsIotThing() *schema.Resource { "attributes": { Type: schema.TypeMap, Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "thing_type_name": { Type: schema.TypeString, diff --git a/aws/resource_aws_lb_listener.go b/aws/resource_aws_lb_listener.go index 81976c0e739..74d1f327998 100644 --- a/aws/resource_aws_lb_listener.go +++ b/aws/resource_aws_lb_listener.go @@ -204,6 +204,7 @@ func resourceAwsLbListener() *schema.Resource { "authentication_request_extra_params": { Type: schema.TypeMap, Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "on_unauthenticated_request": { Type: schema.TypeString, @@ -256,6 +257,7 @@ func resourceAwsLbListener() *schema.Resource { "authentication_request_extra_params": { Type: schema.TypeMap, Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "authorization_endpoint": { Type: schema.TypeString, diff --git a/aws/resource_aws_lb_listener_rule.go b/aws/resource_aws_lb_listener_rule.go index ab72c11dc20..c4cbac50cb4 100644 --- a/aws/resource_aws_lb_listener_rule.go +++ b/aws/resource_aws_lb_listener_rule.go @@ -172,6 +172,7 @@ func resourceAwsLbbListenerRule() *schema.Resource { "authentication_request_extra_params": { Type: schema.TypeMap, Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "on_unauthenticated_request": { Type: schema.TypeString, @@ -224,6 +225,7 @@ func resourceAwsLbbListenerRule() *schema.Resource { "authentication_request_extra_params": { Type: schema.TypeMap, Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "authorization_endpoint": { Type: schema.TypeString, diff --git a/aws/resource_aws_s3_bucket_analytics_configuration.go b/aws/resource_aws_s3_bucket_analytics_configuration.go index 0929e0a5fed..9b687af31ce 100644 --- a/aws/resource_aws_s3_bucket_analytics_configuration.go +++ b/aws/resource_aws_s3_bucket_analytics_configuration.go @@ -50,6 +50,7 @@ func resourceAwsS3BucketAnalyticsConfiguration() *schema.Resource { Type: schema.TypeMap, Optional: true, AtLeastOneOf: filterAtLeastOneOfKeys, + Elem: &schema.Schema{Type: schema.TypeString}, }, }, }, diff --git a/aws/resource_aws_sagemaker_model.go b/aws/resource_aws_sagemaker_model.go index 7edd9ad9a91..18dade3623b 100644 --- a/aws/resource_aws_sagemaker_model.go +++ b/aws/resource_aws_sagemaker_model.go @@ -69,6 +69,7 @@ func resourceAwsSagemakerModel() *schema.Resource { Optional: true, ForceNew: true, ValidateFunc: validateSagemakerEnvironment, + Elem: &schema.Schema{Type: schema.TypeString}, }, }, }, @@ -140,6 +141,7 @@ func resourceAwsSagemakerModel() *schema.Resource { Optional: true, ForceNew: true, ValidateFunc: validateSagemakerEnvironment, + Elem: &schema.Schema{Type: schema.TypeString}, }, }, }, diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 6566271e1f9..19279970fa8 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -311,6 +311,7 @@ func resourceAwsSpotFleetRequest() *schema.Resource { Type: schema.TypeMap, Optional: true, ForceNew: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, }, }, diff --git a/aws/resource_aws_spot_instance_request.go b/aws/resource_aws_spot_instance_request.go index 04c623975f2..69ca0396d11 100644 --- a/aws/resource_aws_spot_instance_request.go +++ b/aws/resource_aws_spot_instance_request.go @@ -41,6 +41,7 @@ func resourceAwsSpotInstanceRequest() *schema.Resource { s["volume_tags"] = &schema.Schema{ Type: schema.TypeMap, Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, } s["spot_price"] = &schema.Schema{ diff --git a/aws/resource_aws_ssm_association.go b/aws/resource_aws_ssm_association.go index a79ffa0a871..da7fd9ffd33 100644 --- a/aws/resource_aws_ssm_association.go +++ b/aws/resource_aws_ssm_association.go @@ -62,6 +62,7 @@ func resourceAwsSsmAssociation() *schema.Resource { Type: schema.TypeMap, Optional: true, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, }, "schedule_expression": { Type: schema.TypeString, diff --git a/aws/tags.go b/aws/tags.go index c35f62ef62d..2123771346c 100644 --- a/aws/tags.go +++ b/aws/tags.go @@ -13,6 +13,7 @@ func tagsSchema() *schema.Schema { return &schema.Schema{ Type: schema.TypeMap, Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, } } @@ -21,6 +22,7 @@ func tagsSchemaComputed() *schema.Schema { Type: schema.TypeMap, Optional: true, Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, } } @@ -29,6 +31,7 @@ func tagsSchemaForceNew() *schema.Schema { Type: schema.TypeMap, Optional: true, ForceNew: true, + Elem: &schema.Schema{Type: schema.TypeString}, } } From c7e021e333ff88df3f5e00e7e9e4e3cc76be46c1 Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Fri, 8 May 2020 18:54:46 -0700 Subject: [PATCH 075/475] add breaking changes section --- docs/MAINTAINING.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/MAINTAINING.md b/docs/MAINTAINING.md index 3bf4e6baec7..ab9417fa5b5 100644 --- a/docs/MAINTAINING.md +++ b/docs/MAINTAINING.md @@ -13,6 +13,7 @@ - [yaml.v2 Updates](#yaml-v2-updates) - [Pull Request Merge Process](#pull-request-merge-process) - [Pull Request Types to CHANGELOG](#pull-request-types-to-changelog) +- [Breaking Changes](#breaking-changes) - [Label Dictionary](#label-dictionary) @@ -305,6 +306,13 @@ The CHANGELOG is intended to show operator-impacting changes to the codebase for - Resource and provider documentation updates - Testing updates +## Breaking Changes + +When breaking changes to the provider are necessary we release them in a major version. If an issue or PR necessitates a breaking change, then the following procedure should be observed: +- Add the `breaking-change` label. +- Add the issue/PR to the next major version milestone. +- Leave a comment why this is a breaking change or otherwise only being considered for a major version update. If possible, detail any changes that might be made for the contributor to accomplish the task without a breaking change. + ## Label Dictionary From 1cb3110584731d14abd16ed997ddf5d576f87712 Mon Sep 17 00:00:00 2001 From: Micheal Harker Date: Sat, 9 May 2020 19:02:13 +0100 Subject: [PATCH 076/475] r/organizations_account: tech debt: replace custom validation funcs --- aws/resource_aws_organizations_account.go | 43 +++++------------------ 1 file changed, 8 insertions(+), 35 deletions(-) diff --git a/aws/resource_aws_organizations_account.go b/aws/resource_aws_organizations_account.go index 952ef540be4..14cd7648ee2 100644 --- a/aws/resource_aws_organizations_account.go +++ b/aws/resource_aws_organizations_account.go @@ -54,10 +54,13 @@ func resourceAwsOrganizationsAccount() *schema.Resource { ValidateFunc: validation.StringLenBetween(1, 50), }, "email": { - ForceNew: true, - Type: schema.TypeString, - Required: true, - ValidateFunc: validateAwsOrganizationsAccountEmail, + ForceNew: true, + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.All( + validation.StringLenBetween(6, 64), + validation.StringMatch(regexp.MustCompile(`^[^\s@]+@[^\s@]+\.[^\s@]+$`), "must be a valid email address"), + ), }, "iam_user_access_to_billing": { ForceNew: true, @@ -69,7 +72,7 @@ func resourceAwsOrganizationsAccount() *schema.Resource { ForceNew: true, Type: schema.TypeString, Optional: true, - ValidateFunc: validateAwsOrganizationsAccountRoleName, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`^[\w+=,.@-]{1,64}$`), "must consist of uppercase letters, lowercase letters, digits with no spaces, and any of the following characters"), }, "tags": tagsSchema(), }, @@ -299,36 +302,6 @@ func resourceAwsOrganizationsAccountStateRefreshFunc(conn *organizations.Organiz } } -func validateAwsOrganizationsAccountEmail(v interface{}, k string) (ws []string, errors []error) { - value := v.(string) - if !regexp.MustCompile(`^[^\s@]+@[^\s@]+\.[^\s@]+$`).MatchString(value) { - errors = append(errors, fmt.Errorf( - "%q must be a valid email address", value)) - } - - if len(value) < 6 { - errors = append(errors, fmt.Errorf( - "%q cannot be less than 6 characters", value)) - } - - if len(value) > 64 { - errors = append(errors, fmt.Errorf( - "%q cannot be greater than 64 characters", value)) - } - - return -} - -func validateAwsOrganizationsAccountRoleName(v interface{}, k string) (ws []string, errors []error) { - value := v.(string) - if !regexp.MustCompile(`^[\w+=,.@-]{1,64}$`).MatchString(value) { - errors = append(errors, fmt.Errorf( - "%q must consist of uppercase letters, lowercase letters, digits with no spaces, and any of the following characters: =,.@-", value)) - } - - return -} - func resourceAwsOrganizationsAccountGetParentId(conn *organizations.Organizations, childId string) (string, error) { input := &organizations.ListParentsInput{ ChildId: aws.String(childId), From 245472063af946849bbd5c39a6b3e74cc6abe71b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 10 May 2020 00:15:26 -0400 Subject: [PATCH 077/475] Update module hashicorp/terraform-plugin-sdk to v1.12.0 (#12740) Co-authored-by: Renovate Bot --- go.mod | 2 +- go.sum | 6 +- .../terraform-plugin-sdk/acctest/doc.go | 31 +++++++ .../helper/encryption/encryption.go | 8 ++ .../helper/resource/testing.go | 92 ++++++++++++++----- .../helper/resource/testing_new.go | 42 ++++++--- .../helper/resource/testing_new_config.go | 1 + .../helper/schema/field_reader.go | 2 + .../helper/schema/resource.go | 2 + .../helper/schema/schema.go | 79 ++++++++++++++-- .../terraform-plugin-sdk/helper/schema/set.go | 37 +++++++- .../terraform-plugin-sdk/meta/meta.go | 2 +- .../terraform-plugin-sdk/terraform/state.go | 4 + .../hashicorp/terraform-plugin-test/helper.go | 7 +- .../hashicorp/terraform-plugin-test/util.go | 40 ++++++++ vendor/modules.txt | 4 +- 16 files changed, 305 insertions(+), 54 deletions(-) create mode 100644 vendor/github.com/hashicorp/terraform-plugin-sdk/acctest/doc.go diff --git a/go.mod b/go.mod index fe28e1d0016..769223c578b 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.1 github.com/hashicorp/go-multierror v1.0.0 github.com/hashicorp/go-version v1.2.0 - github.com/hashicorp/terraform-plugin-sdk v1.9.0 + github.com/hashicorp/terraform-plugin-sdk v1.12.0 github.com/hashicorp/vault v0.10.4 github.com/jen20/awspolicyequivalence v1.1.0 github.com/katbyte/terrafmt v0.2.1-0.20200303174203-e6a3e82cb21b diff --git a/go.sum b/go.sum index 63b3b715bd3..5d3eca21f10 100644 --- a/go.sum +++ b/go.sum @@ -266,10 +266,12 @@ github.com/hashicorp/terraform-json v0.4.0 h1:KNh29iNxozP5adfUFBJ4/fWd0Cu3taGgjH github.com/hashicorp/terraform-json v0.4.0/go.mod h1:eAbqb4w0pSlRmdvl8fOyHAi/+8jnkVYN28gJkSJrLhU= github.com/hashicorp/terraform-plugin-sdk v1.7.0 h1:B//oq0ZORG+EkVrIJy0uPGSonvmXqxSzXe8+GhknoW0= github.com/hashicorp/terraform-plugin-sdk v1.7.0/go.mod h1:OjgQmey5VxnPej/buEhe+YqKm0KNvV3QqU4hkqHqPCY= -github.com/hashicorp/terraform-plugin-sdk v1.9.0 h1:WBHHIX/RgF6/lbfMCzx0qKl96BbQy3bexWFvDqt1bhE= -github.com/hashicorp/terraform-plugin-sdk v1.9.0/go.mod h1:C/AXwmDHqbc3h6URiHpIsVKrwV4PS0Sh0+VTaeEkShw= +github.com/hashicorp/terraform-plugin-sdk v1.12.0 h1:HPp65ShSsKUMPf6jD50UQn/xAjyrGVO4FxI63bvu+pc= +github.com/hashicorp/terraform-plugin-sdk v1.12.0/go.mod h1:HiWIPD/T9HixIhQUwaSoDQxo4BLFdmiBi/Qz5gjB8Q0= github.com/hashicorp/terraform-plugin-test v1.2.0 h1:AWFdqyfnOj04sxTdaAF57QqvW7XXrT8PseUHkbKsE8I= github.com/hashicorp/terraform-plugin-test v1.2.0/go.mod h1:QIJHYz8j+xJtdtLrFTlzQVC0ocr3rf/OjIpgZLK56Hs= +github.com/hashicorp/terraform-plugin-test v1.3.0 h1:hU5LoxrOn9qvOo+LTKN6mSav2J+dAMprbdxJPEQvp4U= +github.com/hashicorp/terraform-plugin-test v1.3.0/go.mod h1:QIJHYz8j+xJtdtLrFTlzQVC0ocr3rf/OjIpgZLK56Hs= github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596 h1:hjyO2JsNZUKT1ym+FAdlBEkGPevazYsmVgIMw7dVELg= github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg= github.com/hashicorp/vault v0.10.4 h1:4x0lHxui/ZRp/B3E0Auv1QNBJpzETqHR2kQD3mHSBJU= diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/acctest/doc.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/acctest/doc.go new file mode 100644 index 00000000000..08bff3c88b5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/acctest/doc.go @@ -0,0 +1,31 @@ +// Package acctest provides the ability to opt in to the new binary test driver. The binary +// test driver allows you to run your acceptance tests with a binary of Terraform instead of +// an emulated version packaged inside the SDK. This allows for a number of important +// enhancements, but most notably a more realistic testing experience and matrix testing +// against multiple versions of Terraform CLI. This also allows the SDK to be completely +// separated, at a dependency level, from the Terraform CLI, as long as it is >= 0.12.0 +// +// The new test driver must be enabled by initialising the test helper in your TestMain +// function in all provider packages that run acceptance tests. Most providers have only +// one package. +// +// In v2 of the SDK, the binary test driver will be mandatory. +// +// After importing this package, you can add code similar to the following: +// +// func TestMain(m *testing.M) { +// acctest.UseBinaryDriver("provider_name", Provider) +// resource.TestMain(m) +// } +// +// Where `Provider` is the function that returns the instance of a configured `terraform.ResourceProvider` +// Some providers already have a TestMain defined, usually for the purpose of enabling test +// sweepers. These additional occurrences should be removed. +// +// Initialising the binary test helper using UseBinaryDriver causes all tests to be run using +// the new binary driver. Until SDK v2, the DisableBinaryDriver boolean property can be used +// to use the legacy test driver for an individual TestCase. +// +// It is no longer necessary to import other Terraform providers as Go modules: these +// imports should be removed. +package acctest diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/encryption/encryption.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/encryption/encryption.go index 110ed18cd96..a84bf4020e3 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/encryption/encryption.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/encryption/encryption.go @@ -12,6 +12,10 @@ import ( // RetrieveGPGKey returns the PGP key specified as the pgpKey parameter, or queries // the public key from the keybase service if the parameter is a keybase username // prefixed with the phrase "keybase:" +// +// Deprecated: This function will be removed in v2 without replacement. Please +// see https://www.terraform.io/docs/extend/best-practices/sensitive-state.html#don-39-t-encrypt-state +// for more information. func RetrieveGPGKey(pgpKey string) (string, error) { const keybasePrefix = "keybase:" @@ -29,6 +33,10 @@ func RetrieveGPGKey(pgpKey string) (string, error) { // EncryptValue encrypts the given value with the given encryption key. Description // should be set such that errors return a meaningful user-facing response. +// +// Deprecated: This function will be removed in v2 without replacement. Please +// see https://www.terraform.io/docs/extend/best-practices/sensitive-state.html#don-39-t-encrypt-state +// for more information. func EncryptValue(encryptionKey, value, description string) (string, string, error) { fingerprints, encryptedValue, err := pgpkeys.EncryptShares([][]byte{[]byte(value)}, []string{encryptionKey}) diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/resource/testing.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/resource/testing.go index 7b331d80d13..1f63e615d29 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/resource/testing.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/resource/testing.go @@ -12,6 +12,7 @@ import ( "path/filepath" "reflect" "regexp" + "strconv" "strings" "syscall" "testing" @@ -108,10 +109,15 @@ func TestMain(m *testing.M) { os.Exit(1) } } else { + exitCode := m.Run() + if acctest.TestHelper != nil { - defer acctest.TestHelper.Close() + err := acctest.TestHelper.Close() + if err != nil { + log.Printf("Error cleaning up temporary test files: %s", err) + } } - os.Exit(m.Run()) + os.Exit(exitCode) } } @@ -255,6 +261,7 @@ func runSweeperWithRegion(region string, s *Sweeper, sweepers map[string]*Sweepe } const TestEnvVar = "TF_ACC" +const TestDisableBinaryTestingFlagEnvVar = "TF_DISABLE_BINARY_TESTING" // TestProvider can be implemented by any ResourceProvider to provide custom // reset functionality at the start of an acceptance test. @@ -543,6 +550,14 @@ func Test(t TestT, c TestCase) { TestEnvVar)) return } + if v := os.Getenv(TestDisableBinaryTestingFlagEnvVar); v != "" { + b, err := strconv.ParseBool(v) + if err != nil { + t.Error(fmt.Errorf("Error parsing EnvVar %q value %q: %s", TestDisableBinaryTestingFlagEnvVar, v, err)) + } + + c.DisableBinaryDriver = b + } logWriter, err := LogOutput(t) if err != nil { @@ -553,7 +568,6 @@ func Test(t TestT, c TestCase) { // We require verbose mode so that the user knows what is going on. if !testTesting && !testing.Verbose() && !c.IsUnitTest { t.Fatal("Acceptance tests must be run with the -v flag on tests") - return } // get instances of all providers, so we can use the individual @@ -1016,28 +1030,28 @@ func ComposeAggregateTestCheckFunc(fs ...TestCheckFunc) TestCheckFunc { // testing that computed values were set, when it is not possible to // know ahead of time what the values will be. func TestCheckResourceAttrSet(name, key string) TestCheckFunc { - return func(s *terraform.State) error { + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { is, err := primaryInstanceState(s, name) if err != nil { return err } return testCheckResourceAttrSet(is, name, key) - } + }) } // TestCheckModuleResourceAttrSet - as per TestCheckResourceAttrSet but with // support for non-root modules func TestCheckModuleResourceAttrSet(mp []string, name string, key string) TestCheckFunc { mpt := addrs.Module(mp).UnkeyedInstanceShim() - return func(s *terraform.State) error { + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { is, err := modulePathPrimaryInstanceState(s, mpt, name) if err != nil { return err } return testCheckResourceAttrSet(is, name, key) - } + }) } func testCheckResourceAttrSet(is *terraform.InstanceState, name string, key string) error { @@ -1051,28 +1065,28 @@ func testCheckResourceAttrSet(is *terraform.InstanceState, name string, key stri // TestCheckResourceAttr is a TestCheckFunc which validates // the value in state for the given name/key combination. func TestCheckResourceAttr(name, key, value string) TestCheckFunc { - return func(s *terraform.State) error { + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { is, err := primaryInstanceState(s, name) if err != nil { return err } return testCheckResourceAttr(is, name, key, value) - } + }) } // TestCheckModuleResourceAttr - as per TestCheckResourceAttr but with // support for non-root modules func TestCheckModuleResourceAttr(mp []string, name string, key string, value string) TestCheckFunc { mpt := addrs.Module(mp).UnkeyedInstanceShim() - return func(s *terraform.State) error { + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { is, err := modulePathPrimaryInstanceState(s, mpt, name) if err != nil { return err } return testCheckResourceAttr(is, name, key, value) - } + }) } func testCheckResourceAttr(is *terraform.InstanceState, name string, key string, value string) error { @@ -1106,28 +1120,28 @@ func testCheckResourceAttr(is *terraform.InstanceState, name string, key string, // TestCheckNoResourceAttr is a TestCheckFunc which ensures that // NO value exists in state for the given name/key combination. func TestCheckNoResourceAttr(name, key string) TestCheckFunc { - return func(s *terraform.State) error { + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { is, err := primaryInstanceState(s, name) if err != nil { return err } return testCheckNoResourceAttr(is, name, key) - } + }) } // TestCheckModuleNoResourceAttr - as per TestCheckNoResourceAttr but with // support for non-root modules func TestCheckModuleNoResourceAttr(mp []string, name string, key string) TestCheckFunc { mpt := addrs.Module(mp).UnkeyedInstanceShim() - return func(s *terraform.State) error { + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { is, err := modulePathPrimaryInstanceState(s, mpt, name) if err != nil { return err } return testCheckNoResourceAttr(is, name, key) - } + }) } func testCheckNoResourceAttr(is *terraform.InstanceState, name string, key string) error { @@ -1154,28 +1168,28 @@ func testCheckNoResourceAttr(is *terraform.InstanceState, name string, key strin // TestMatchResourceAttr is a TestCheckFunc which checks that the value // in state for the given name/key combination matches the given regex. func TestMatchResourceAttr(name, key string, r *regexp.Regexp) TestCheckFunc { - return func(s *terraform.State) error { + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { is, err := primaryInstanceState(s, name) if err != nil { return err } return testMatchResourceAttr(is, name, key, r) - } + }) } // TestModuleMatchResourceAttr - as per TestMatchResourceAttr but with // support for non-root modules func TestModuleMatchResourceAttr(mp []string, name string, key string, r *regexp.Regexp) TestCheckFunc { mpt := addrs.Module(mp).UnkeyedInstanceShim() - return func(s *terraform.State) error { + return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { is, err := modulePathPrimaryInstanceState(s, mpt, name) if err != nil { return err } return testMatchResourceAttr(is, name, key, r) - } + }) } func testMatchResourceAttr(is *terraform.InstanceState, name string, key string, r *regexp.Regexp) error { @@ -1211,7 +1225,7 @@ func TestCheckModuleResourceAttrPtr(mp []string, name string, key string, value // TestCheckResourceAttrPair is a TestCheckFunc which validates that the values // in state for a pair of name/key combinations are equal. func TestCheckResourceAttrPair(nameFirst, keyFirst, nameSecond, keySecond string) TestCheckFunc { - return func(s *terraform.State) error { + return checkIfIndexesIntoTypeSetPair(keyFirst, keySecond, func(s *terraform.State) error { isFirst, err := primaryInstanceState(s, nameFirst) if err != nil { return err @@ -1223,7 +1237,7 @@ func TestCheckResourceAttrPair(nameFirst, keyFirst, nameSecond, keySecond string } return testCheckResourceAttrPair(isFirst, nameFirst, keyFirst, isSecond, nameSecond, keySecond) - } + }) } // TestCheckModuleResourceAttrPair - as per TestCheckResourceAttrPair but with @@ -1231,7 +1245,7 @@ func TestCheckResourceAttrPair(nameFirst, keyFirst, nameSecond, keySecond string func TestCheckModuleResourceAttrPair(mpFirst []string, nameFirst string, keyFirst string, mpSecond []string, nameSecond string, keySecond string) TestCheckFunc { mptFirst := addrs.Module(mpFirst).UnkeyedInstanceShim() mptSecond := addrs.Module(mpSecond).UnkeyedInstanceShim() - return func(s *terraform.State) error { + return checkIfIndexesIntoTypeSetPair(keyFirst, keySecond, func(s *terraform.State) error { isFirst, err := modulePathPrimaryInstanceState(s, mptFirst, nameFirst) if err != nil { return err @@ -1243,7 +1257,7 @@ func TestCheckModuleResourceAttrPair(mpFirst []string, nameFirst string, keyFirs } return testCheckResourceAttrPair(isFirst, nameFirst, keyFirst, isSecond, nameSecond, keySecond) - } + }) } func testCheckResourceAttrPair(isFirst *terraform.InstanceState, nameFirst string, keyFirst string, isSecond *terraform.InstanceState, nameSecond string, keySecond string) error { @@ -1419,3 +1433,35 @@ func detailedErrorMessage(err error) string { return err.Error() } } + +// indexesIntoTypeSet is a heuristic to try and identify if a flatmap style +// string address uses a precalculated TypeSet hash, which are integers and +// typically are large and obviously not a list index +func indexesIntoTypeSet(key string) bool { + for _, part := range strings.Split(key, ".") { + if i, err := strconv.Atoi(part); err == nil && i > 100 { + return true + } + } + return false +} + +func checkIfIndexesIntoTypeSet(key string, f TestCheckFunc) TestCheckFunc { + return func(s *terraform.State) error { + err := f(s) + if err != nil && s.IsBinaryDrivenTest && indexesIntoTypeSet(key) { + return fmt.Errorf("Error in test check: %s\nTest check address %q likely indexes into TypeSet\nThis is not possible in V1 of the SDK while using the binary driver\nPlease disable the driver for this TestCase with DisableBinaryDriver: true", err, key) + } + return err + } +} + +func checkIfIndexesIntoTypeSetPair(keyFirst, keySecond string, f TestCheckFunc) TestCheckFunc { + return func(s *terraform.State) error { + err := f(s) + if err != nil && s.IsBinaryDrivenTest && (indexesIntoTypeSet(keyFirst) || indexesIntoTypeSet(keySecond)) { + return fmt.Errorf("Error in test check: %s\nTest check address %q or %q likely indexes into TypeSet\nThis is not possible in V1 of the SDK while using the binary driver\nPlease disable the driver for this TestCase with DisableBinaryDriver: true", err, keyFirst, keySecond) + } + return err + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/resource/testing_new.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/resource/testing_new.go index 8ba9c85d31b..34244e095f8 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/resource/testing_new.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/resource/testing_new.go @@ -14,13 +14,18 @@ import ( tftest "github.com/hashicorp/terraform-plugin-test" ) -func getState(t *testing.T, wd *tftest.WorkingDir) *terraform.State { - jsonState := wd.RequireState(t) - state, err := shimStateFromJson(jsonState) - if err != nil { - t.Fatal(err) +func runPostTestDestroy(t *testing.T, c TestCase, wd *tftest.WorkingDir) error { + wd.RequireDestroy(t) + + if c.CheckDestroy != nil { + statePostDestroy := getState(t, wd) + + if err := c.CheckDestroy(statePostDestroy); err != nil { + return err + } } - return state + + return nil } func RunNewTest(t *testing.T, c TestCase, providers map[string]terraform.ResourceProvider) { @@ -29,15 +34,12 @@ func RunNewTest(t *testing.T, c TestCase, providers map[string]terraform.Resourc wd := acctest.TestHelper.RequireNewWorkingDir(t) defer func() { - wd.RequireDestroy(t) + statePreDestroy := getState(t, wd) - if c.CheckDestroy != nil { - statePostDestroy := getState(t, wd) - - if err := c.CheckDestroy(statePostDestroy); err != nil { - t.Fatal(err) - } + if !stateIsEmpty(statePreDestroy) { + runPostTestDestroy(t, c, wd) } + wd.Close() }() @@ -98,6 +100,19 @@ func RunNewTest(t *testing.T, c TestCase, providers map[string]terraform.Resourc } } +func getState(t *testing.T, wd *tftest.WorkingDir) *terraform.State { + jsonState := wd.RequireState(t) + state, err := shimStateFromJson(jsonState) + if err != nil { + t.Fatal(err) + } + return state +} + +func stateIsEmpty(state *terraform.State) bool { + return state.Empty() || !state.HasResources() +} + func planIsEmpty(plan *tfjson.Plan) bool { for _, rc := range plan.ResourceChanges { if rc.Mode == tfjson.DataResourceMode { @@ -114,6 +129,7 @@ func planIsEmpty(plan *tfjson.Plan) bool { } return true } + func testIDRefresh(c TestCase, t *testing.T, wd *tftest.WorkingDir, step TestStep, r *terraform.ResourceState) error { spewConf := spew.NewDefaultConfig() spewConf.SortKeys = true diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/resource/testing_new_config.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/resource/testing_new_config.go index d2fbf29d783..a59d685d8d9 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/resource/testing_new_config.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/resource/testing_new_config.go @@ -32,6 +32,7 @@ func testStepNewConfig(t *testing.T, c TestCase, wd *tftest.WorkingDir, step Tes state := getState(t, wd) if step.Check != nil { + state.IsBinaryDrivenTest = true if err := step.Check(state); err != nil { t.Fatal(err) } diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/field_reader.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/field_reader.go index 622e9b13eb2..b3c023d19f1 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/field_reader.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/field_reader.go @@ -44,6 +44,8 @@ func (r *FieldReadResult) ValueOrZero(s *Schema) interface{} { // SchemasForFlatmapPath tries its best to find a sequence of schemas that // the given dot-delimited attribute path traverses through. +// +// Deprecated: This function will be removed in version 2 without replacement. func SchemasForFlatmapPath(path string, schemaMap map[string]*Schema) []*Schema { parts := strings.Split(path, ".") return addrToSchema(parts, schemaMap) diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/resource.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/resource.go index 75cfe8857a3..1bc30808819 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/resource.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/resource.go @@ -770,6 +770,8 @@ func (r *Resource) TestResourceData() *ResourceData { // SchemasForFlatmapPath tries its best to find a sequence of schemas that // the given dot-delimited attribute path traverses through in the schema // of the receiving Resource. +// +// Deprecated: This function will be removed in version 2 without replacement. func (r *Resource) SchemasForFlatmapPath(path string) []*Schema { return SchemasForFlatmapPath(path, r.Schema) } diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/schema.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/schema.go index 69ab09b7c5a..df0172fa108 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/schema.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/schema.go @@ -223,9 +223,12 @@ type Schema struct { // // AtLeastOneOf is a set of schema keys that, when set, at least one of // the keys in that list must be specified. + // + // RequiredWith is a set of schema keys that must be set simultaneously. ConflictsWith []string ExactlyOneOf []string AtLeastOneOf []string + RequiredWith []string // When Deprecated is set, this attribute is deprecated. // @@ -236,6 +239,9 @@ type Schema struct { // When Removed is set, this attribute has been removed from the schema // + // Deprecated: This field will be removed in version 2 without replacement + // as the functionality is not necessary. + // // Removed attributes can be left in the Schema to generate informative error // messages for the user when they show up in resource configurations. // This string is the message shown to the user with instructions on @@ -767,21 +773,28 @@ func (m schemaMap) internalValidate(topSchemaMap schemaMap, attrsOnly bool) erro } if len(v.ConflictsWith) > 0 { - err := checkKeysAgainstSchemaFlags(k, v.ConflictsWith, topSchemaMap) + err := checkKeysAgainstSchemaFlags(k, v.ConflictsWith, topSchemaMap, v, false) if err != nil { return fmt.Errorf("ConflictsWith: %+v", err) } } + if len(v.RequiredWith) > 0 { + err := checkKeysAgainstSchemaFlags(k, v.RequiredWith, topSchemaMap, v, true) + if err != nil { + return fmt.Errorf("RequiredWith: %+v", err) + } + } + if len(v.ExactlyOneOf) > 0 { - err := checkKeysAgainstSchemaFlags(k, v.ExactlyOneOf, topSchemaMap) + err := checkKeysAgainstSchemaFlags(k, v.ExactlyOneOf, topSchemaMap, v, true) if err != nil { return fmt.Errorf("ExactlyOneOf: %+v", err) } } if len(v.AtLeastOneOf) > 0 { - err := checkKeysAgainstSchemaFlags(k, v.AtLeastOneOf, topSchemaMap) + err := checkKeysAgainstSchemaFlags(k, v.AtLeastOneOf, topSchemaMap, v, true) if err != nil { return fmt.Errorf("AtLeastOneOf: %+v", err) } @@ -850,14 +863,20 @@ func (m schemaMap) internalValidate(topSchemaMap schemaMap, attrsOnly bool) erro return nil } -func checkKeysAgainstSchemaFlags(k string, keys []string, topSchemaMap schemaMap) error { +func checkKeysAgainstSchemaFlags(k string, keys []string, topSchemaMap schemaMap, self *Schema, allowSelfReference bool) error { for _, key := range keys { parts := strings.Split(key, ".") sm := topSchemaMap var target *Schema - for _, part := range parts { - // Skip index fields - if _, err := strconv.Atoi(part); err == nil { + for idx, part := range parts { + // Skip index fields if 0 + partInt, err := strconv.Atoi(part) + + if err == nil { + if partInt != 0 { + return fmt.Errorf("%s configuration block reference (%s) can only use the .0. index for TypeList and MaxItems: 1 configuration blocks", k, key) + } + continue } @@ -866,13 +885,28 @@ func checkKeysAgainstSchemaFlags(k string, keys []string, topSchemaMap schemaMap return fmt.Errorf("%s references unknown attribute (%s) at part (%s)", k, key, part) } - if subResource, ok := target.Elem.(*Resource); ok { - sm = schemaMap(subResource.Schema) + subResource, ok := target.Elem.(*Resource) + + if !ok { + continue + } + + // Skip Type/MaxItems check if not the last element + if (target.Type == TypeSet || target.MaxItems != 1) && idx+1 != len(parts) { + return fmt.Errorf("%s configuration block reference (%s) can only be used with TypeList and MaxItems: 1 configuration blocks", k, key) } + + sm = schemaMap(subResource.Schema) } + if target == nil { return fmt.Errorf("%s cannot find target attribute (%s), sm: %#v", k, key, sm) } + + if target == self && !allowSelfReference { + return fmt.Errorf("%s cannot reference self (%s)", k, key) + } + if target.Required { return fmt.Errorf("%s cannot contain Required attribute (%s)", k, key) } @@ -881,6 +915,7 @@ func checkKeysAgainstSchemaFlags(k string, keys []string, topSchemaMap schemaMap return fmt.Errorf("%s cannot contain Computed(When) attribute (%s)", k, key) } } + return nil } @@ -1414,6 +1449,11 @@ func (m schemaMap) validate( "%q: this field cannot be set", k)} } + err = validateRequiredWithAttribute(k, schema, c) + if err != nil { + return nil, []error{err} + } + // If the value is unknown then we can't validate it yet. // In particular, this avoids spurious type errors where downstream // validation code sees UnknownVariableValue as being just a string. @@ -1494,6 +1534,27 @@ func removeDuplicates(elements []string) []string { return result } +func validateRequiredWithAttribute( + k string, + schema *Schema, + c *terraform.ResourceConfig) error { + + if len(schema.RequiredWith) == 0 { + return nil + } + + allKeys := removeDuplicates(append(schema.RequiredWith, k)) + sort.Strings(allKeys) + + for _, key := range allKeys { + if _, ok := c.Get(key); !ok { + return fmt.Errorf("%q: all of `%s` must be specified", k, strings.Join(allKeys, ",")) + } + } + + return nil +} + func validateExactlyOneAttribute( k string, schema *Schema, diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/set.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/set.go index daa431ddb1c..1b39ff639d1 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/set.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/helper/schema/set.go @@ -150,13 +150,46 @@ func (s *Set) Union(other *Set) *Set { return result } +func checkSetMapEqual(m1, m2 map[string]interface{}) bool { + if (m1 == nil) != (m2 == nil) { + return false + } + if len(m1) != len(m2) { + return false + } + for k := range m1 { + v1 := m1[k] + v2, ok := m2[k] + if !ok { + return false + } + switch v1.(type) { + case map[string]interface{}: + same := checkSetMapEqual(v1.(map[string]interface{}), v2.(map[string]interface{})) + if !same { + return false + } + case *Set: + same := v1.(*Set).Equal(v2) + if !same { + return false + } + default: + same := reflect.DeepEqual(v1, v2) + if !same { + return false + } + } + } + return true +} + func (s *Set) Equal(raw interface{}) bool { other, ok := raw.(*Set) if !ok { return false } - - return reflect.DeepEqual(s.m, other.m) + return checkSetMapEqual(s.m, other.m) } // HashEqual simply checks to the keys the top-level map to the keys in the diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/meta/meta.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/meta/meta.go index 0363c2d9371..345d1cab6d4 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/meta/meta.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/meta/meta.go @@ -11,7 +11,7 @@ import ( ) // The main version number that is being run at the moment. -var SDKVersion = "1.9.0" +var SDKVersion = "1.12.0" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/terraform/state.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/terraform/state.go index b2b308e7905..98b20be7cbe 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/terraform/state.go +++ b/vendor/github.com/hashicorp/terraform-plugin-sdk/terraform/state.go @@ -112,6 +112,10 @@ type State struct { Modules []*ModuleState `json:"modules"` mu sync.Mutex + + // IsBinaryDrivenTest is a special flag that assists with a binary driver + // heuristic, it should not be set externally + IsBinaryDrivenTest bool } func (s *State) Lock() { s.mu.Lock() } diff --git a/vendor/github.com/hashicorp/terraform-plugin-test/helper.go b/vendor/github.com/hashicorp/terraform-plugin-test/helper.go index d4de44680e8..8a519aaf088 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-test/helper.go +++ b/vendor/github.com/hashicorp/terraform-plugin-test/helper.go @@ -196,6 +196,11 @@ func symlinkAuxiliaryProviders(pluginDir string) error { return nil } +// GetPluginName returns the configured plugin name. +func (h *Helper) GetPluginName() string { + return h.pluginName +} + // Close cleans up temporary files and directories created to support this // helper, returning an error if any of the cleanup fails. // @@ -218,7 +223,7 @@ func (h *Helper) NewWorkingDir() (*WorkingDir, error) { } // symlink the provider source files into the base directory - err = symlinkDir(h.sourceDir, dir) + err = symlinkDirectoriesOnly(h.sourceDir, dir) if err != nil { return nil, err } diff --git a/vendor/github.com/hashicorp/terraform-plugin-test/util.go b/vendor/github.com/hashicorp/terraform-plugin-test/util.go index 0732c82d197..57bc84f2dcc 100644 --- a/vendor/github.com/hashicorp/terraform-plugin-test/util.go +++ b/vendor/github.com/hashicorp/terraform-plugin-test/util.go @@ -53,3 +53,43 @@ func symlinkDir(srcDir string, destDir string) (err error) { } return } + +// symlinkDirectoriesOnly finds only the first-level child directories in srcDir +// and symlinks them into destDir. +// Unlike symlinkDir, this is done non-recursively in order to limit the number +// of file descriptors used. +func symlinkDirectoriesOnly(srcDir string, destDir string) (err error) { + srcInfo, err := os.Stat(srcDir) + if err != nil { + return err + } + + err = os.MkdirAll(destDir, srcInfo.Mode()) + if err != nil { + return err + } + + directory, err := os.Open(srcDir) + if err != nil { + return err + } + defer directory.Close() + objects, err := directory.Readdir(-1) + if err != nil { + return err + } + + for _, obj := range objects { + srcPath := filepath.Join(srcDir, obj.Name()) + destPath := filepath.Join(destDir, obj.Name()) + + if obj.IsDir() { + err = symlinkFile(srcPath, destPath) + if err != nil { + return err + } + } + + } + return +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 1e0da311f48..1d827ac71fa 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -527,7 +527,7 @@ github.com/hashicorp/logutils github.com/hashicorp/terraform-config-inspect/tfconfig # github.com/hashicorp/terraform-json v0.4.0 github.com/hashicorp/terraform-json -# github.com/hashicorp/terraform-plugin-sdk v1.9.0 +# github.com/hashicorp/terraform-plugin-sdk v1.12.0 github.com/hashicorp/terraform-plugin-sdk/acctest github.com/hashicorp/terraform-plugin-sdk/helper/acctest github.com/hashicorp/terraform-plugin-sdk/helper/customdiff @@ -579,7 +579,7 @@ github.com/hashicorp/terraform-plugin-sdk/internal/version github.com/hashicorp/terraform-plugin-sdk/meta github.com/hashicorp/terraform-plugin-sdk/plugin github.com/hashicorp/terraform-plugin-sdk/terraform -# github.com/hashicorp/terraform-plugin-test v1.2.0 +# github.com/hashicorp/terraform-plugin-test v1.3.0 github.com/hashicorp/terraform-plugin-test # github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596 github.com/hashicorp/terraform-svchost From 74fdc28b49d4bd5b20eddce369d1ed919c312a7e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 10 May 2020 00:35:45 -0400 Subject: [PATCH 078/475] Update module bflad/tfproviderdocs to v0.6.0 (#13246) Co-authored-by: Renovate Bot --- go.mod | 2 +- go.sum | 9 +- .../bflad/tfproviderdocs/CHANGELOG.md | 9 ++ .../bflad/tfproviderdocs/check/check.go | 50 ++++------ .../tfproviderdocs/check/file_mismatch.go | 85 +++++++++++++++-- .../bflad/tfproviderdocs/command/check.go | 93 ++++++++++++++----- vendor/github.com/bflad/tfproviderdocs/go.mod | 2 +- vendor/github.com/bflad/tfproviderdocs/go.sum | 10 +- .../bflad/tfproviderdocs/version/version.go | 2 +- .../hashicorp/terraform-json/schemas.go | 29 +++++- vendor/modules.txt | 4 +- 11 files changed, 220 insertions(+), 75 deletions(-) diff --git a/go.mod b/go.mod index 769223c578b..bb57dafcf6f 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.13 require ( github.com/aws/aws-sdk-go v1.30.21 github.com/beevik/etree v1.1.0 - github.com/bflad/tfproviderdocs v0.5.3 + github.com/bflad/tfproviderdocs v0.6.0 github.com/bflad/tfproviderlint v0.14.0 github.com/client9/misspell v0.3.4 github.com/golangci/golangci-lint v1.26.0 diff --git a/go.sum b/go.sum index 5d3eca21f10..ab0868d9339 100644 --- a/go.sum +++ b/go.sum @@ -47,8 +47,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/bflad/gopaniccheck v0.1.0 h1:tJftp+bv42ouERmUMWLoUn/5bi/iQZjHPznM00cP/bU= github.com/bflad/gopaniccheck v0.1.0/go.mod h1:ZCj2vSr7EqVeDaqVsWN4n2MwdROx1YL+LFo47TSWtsA= -github.com/bflad/tfproviderdocs v0.5.3 h1:0JozhslEaLujgTnV6OdljbFiT/FCponx5hruFSkizGk= -github.com/bflad/tfproviderdocs v0.5.3/go.mod h1:d0k1fQLEu1pdeORxozwuwmvauFaEmMBREQ1fw3J+pPc= +github.com/bflad/tfproviderdocs v0.6.0 h1:P5XMTe0tB44xlMZmIvoQx/nfPht0pNymLtEArvYSOQE= +github.com/bflad/tfproviderdocs v0.6.0/go.mod h1:W6wVZPtBa6V5bpjaK1eJAoVCL/7B4Amfrld0dro+fHU= github.com/bflad/tfproviderlint v0.14.0 h1:iki5tDr4l0jp0zEL0chZylptMT5QdE09E60cziFQNZA= github.com/bflad/tfproviderlint v0.14.0/go.mod h1:1Jtjs6DPKoyqPrbPyMiy33h0ViO2h831uzoOuikCA60= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= @@ -260,10 +260,10 @@ github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/terraform-config-inspect v0.0.0-20191115094559-17f92b0546e8 h1:+RyjwU+Gnd/aTJBPZVDNm903eXVjjqhbaR4Ypx3xYyY= github.com/hashicorp/terraform-config-inspect v0.0.0-20191115094559-17f92b0546e8/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A= -github.com/hashicorp/terraform-json v0.3.1 h1:vRiOLck4YX4UqzljVhdQKsVLixX4L+Pgnm/q+xu6QvE= -github.com/hashicorp/terraform-json v0.3.1/go.mod h1:MdwQStcJb00ht55L/2YH0ypAO9RNtczJ1MaUlf+gJcg= github.com/hashicorp/terraform-json v0.4.0 h1:KNh29iNxozP5adfUFBJ4/fWd0Cu3taGgjHB38JYqOF4= github.com/hashicorp/terraform-json v0.4.0/go.mod h1:eAbqb4w0pSlRmdvl8fOyHAi/+8jnkVYN28gJkSJrLhU= +github.com/hashicorp/terraform-json v0.5.0 h1:7TV3/F3y7QVSuN4r9BEXqnWqrAyeOtON8f0wvREtyzs= +github.com/hashicorp/terraform-json v0.5.0/go.mod h1:eAbqb4w0pSlRmdvl8fOyHAi/+8jnkVYN28gJkSJrLhU= github.com/hashicorp/terraform-plugin-sdk v1.7.0 h1:B//oq0ZORG+EkVrIJy0uPGSonvmXqxSzXe8+GhknoW0= github.com/hashicorp/terraform-plugin-sdk v1.7.0/go.mod h1:OjgQmey5VxnPej/buEhe+YqKm0KNvV3QqU4hkqHqPCY= github.com/hashicorp/terraform-plugin-sdk v1.12.0 h1:HPp65ShSsKUMPf6jD50UQn/xAjyrGVO4FxI63bvu+pc= @@ -518,7 +518,6 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/zclconf/go-cty v0.0.0-20190430221426-d36a6f0dbffd/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.1.0 h1:uJwc9HiBOCpoKIObTQaLR+tsEXx1HBHnOsOOpcdhZgw= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= diff --git a/vendor/github.com/bflad/tfproviderdocs/CHANGELOG.md b/vendor/github.com/bflad/tfproviderdocs/CHANGELOG.md index 515bfc5325e..07ac77c6bc2 100644 --- a/vendor/github.com/bflad/tfproviderdocs/CHANGELOG.md +++ b/vendor/github.com/bflad/tfproviderdocs/CHANGELOG.md @@ -1,3 +1,12 @@ +# v0.6.0 + +ENHANCEMENTS + +* check: Add `-ignore-file-mismatch-data-sources` option +* check: Add `-ignore-file-mismatch-resources` option +* check: Add `-ignore-file-missing-data-sources` option +* check: Add `-ignore-file-missing-resources` option + # v0.5.3 BUG FIXES diff --git a/vendor/github.com/bflad/tfproviderdocs/check/check.go b/vendor/github.com/bflad/tfproviderdocs/check/check.go index fabca3661d3..d29be21cc68 100644 --- a/vendor/github.com/bflad/tfproviderdocs/check/check.go +++ b/vendor/github.com/bflad/tfproviderdocs/check/check.go @@ -4,7 +4,6 @@ import ( "sort" "github.com/hashicorp/go-multierror" - tfjson "github.com/hashicorp/terraform-json" ) const ( @@ -22,6 +21,8 @@ type Check struct { } type CheckOptions struct { + DataSourceFileMismatch *FileMismatchOptions + LegacyDataSourceFile *LegacyDataSourceFileOptions LegacyGuideFile *LegacyGuideFileOptions LegacyIndexFile *LegacyIndexFileOptions @@ -34,8 +35,7 @@ type CheckOptions struct { RegistryIndexFile *RegistryIndexFileOptions RegistryResourceFile *RegistryResourceFileOptions - SchemaDataSources map[string]*tfjson.Schema - SchemaResources map[string]*tfjson.Schema + ResourceFileMismatch *FileMismatchOptions SideNavigation *SideNavigationOptions } @@ -65,37 +65,13 @@ func (check *Check) Run(directories map[string][]string) error { return err } - if len(check.Options.SchemaDataSources) > 0 && false { - var dataSourceFiles []string - - if files, ok := directories[RegistryDataSourcesDirectory]; ok { - dataSourceFiles = files - } else if files, ok := directories[LegacyDataSourcesDirectory]; ok { - dataSourceFiles = files - } - - if err := ResourceFileMismatchCheck(check.Options.ProviderName, ResourceTypeDataSource, check.Options.SchemaDataSources, dataSourceFiles); err != nil { - return err - } - } - - if len(check.Options.SchemaResources) > 0 { - var resourceFiles []string - - if files, ok := directories[RegistryResourcesDirectory]; ok { - resourceFiles = files - } else if files, ok := directories[LegacyResourcesDirectory]; ok { - resourceFiles = files - } - - if err := ResourceFileMismatchCheck(check.Options.ProviderName, ResourceTypeResource, check.Options.SchemaResources, resourceFiles); err != nil { - return err - } - } - var result *multierror.Error if files, ok := directories[RegistryDataSourcesDirectory]; ok { + if err := NewFileMismatchCheck(check.Options.DataSourceFileMismatch).Run(files); err != nil { + result = multierror.Append(result, err) + } + if err := NewRegistryDataSourceFileCheck(check.Options.RegistryDataSourceFile).RunAll(files); err != nil { result = multierror.Append(result, err) } @@ -114,6 +90,10 @@ func (check *Check) Run(directories map[string][]string) error { } if files, ok := directories[RegistryResourcesDirectory]; ok { + if err := NewFileMismatchCheck(check.Options.ResourceFileMismatch).Run(files); err != nil { + result = multierror.Append(result, err) + } + if err := NewRegistryResourceFileCheck(check.Options.RegistryResourceFile).RunAll(files); err != nil { result = multierror.Append(result, err) } @@ -123,6 +103,10 @@ func (check *Check) Run(directories map[string][]string) error { legacyResourcesFiles, legacyResourcesOk := directories[LegacyResourcesDirectory] if legacyDataSourcesOk { + if err := NewFileMismatchCheck(check.Options.DataSourceFileMismatch).Run(legacyDataSourcesFiles); err != nil { + result = multierror.Append(result, err) + } + if err := NewLegacyDataSourceFileCheck(check.Options.LegacyDataSourceFile).RunAll(legacyDataSourcesFiles); err != nil { result = multierror.Append(result, err) } @@ -141,6 +125,10 @@ func (check *Check) Run(directories map[string][]string) error { } if legacyResourcesOk { + if err := NewFileMismatchCheck(check.Options.ResourceFileMismatch).Run(legacyResourcesFiles); err != nil { + result = multierror.Append(result, err) + } + if err := NewLegacyResourceFileCheck(check.Options.LegacyResourceFile).RunAll(legacyResourcesFiles); err != nil { result = multierror.Append(result, err) } diff --git a/vendor/github.com/bflad/tfproviderdocs/check/file_mismatch.go b/vendor/github.com/bflad/tfproviderdocs/check/file_mismatch.go index b5c4868dd36..85898240300 100644 --- a/vendor/github.com/bflad/tfproviderdocs/check/file_mismatch.go +++ b/vendor/github.com/bflad/tfproviderdocs/check/file_mismatch.go @@ -2,26 +2,79 @@ package check import ( "fmt" + "log" "sort" "github.com/hashicorp/go-multierror" tfjson "github.com/hashicorp/terraform-json" ) -func ResourceFileMismatchCheck(providerName string, resourceType string, schemaResources map[string]*tfjson.Schema, files []string) error { +type FileMismatchOptions struct { + *FileOptions + + IgnoreFileMismatch []string + + IgnoreFileMissing []string + + ProviderName string + + ResourceType string + + Schemas map[string]*tfjson.Schema +} + +type FileMismatchCheck struct { + Options *FileMismatchOptions +} + +func NewFileMismatchCheck(opts *FileMismatchOptions) *FileMismatchCheck { + check := &FileMismatchCheck{ + Options: opts, + } + + if check.Options == nil { + check.Options = &FileMismatchOptions{} + } + + if check.Options.FileOptions == nil { + check.Options.FileOptions = &FileOptions{} + } + + return check +} + +func (check *FileMismatchCheck) Run(files []string) error { + if len(files) == 0 { + log.Printf("[DEBUG] Skipping %s file mismatch checks due to missing file list", check.Options.ResourceType) + return nil + } + + if len(check.Options.Schemas) == 0 { + log.Printf("[DEBUG] Skipping %s file mismatch checks due to missing schemas", check.Options.ResourceType) + return nil + } + var extraFiles []string var missingFiles []string for _, file := range files { - if fileHasResource(schemaResources, providerName, file) { + if fileHasResource(check.Options.Schemas, check.Options.ProviderName, file) { + continue + } + + if check.IgnoreFileMismatch(file) { continue } extraFiles = append(extraFiles, file) } - for _, resourceName := range resourceNames(schemaResources) { - if resourceHasFile(files, providerName, resourceName) { + for _, resourceName := range resourceNames(check.Options.Schemas) { + if resourceHasFile(files, check.Options.ProviderName, resourceName) { + continue + } + + if check.IgnoreFileMissing(resourceName) { continue } @@ -31,18 +84,38 @@ func ResourceFileMismatchCheck(providerName string, resourceType string, schemaR var result *multierror.Error for _, extraFile := range extraFiles { - err := fmt.Errorf("matching %s for documentation file (%s) not found, file is extraneous or incorrectly named", resourceType, extraFile) + err := fmt.Errorf("matching %s for documentation file (%s) not found, file is extraneous or incorrectly named", check.Options.ResourceType, extraFile) result = multierror.Append(result, err) } for _, missingFile := range missingFiles { - err := fmt.Errorf("missing documentation file for %s: %s", resourceType, missingFile) + err := fmt.Errorf("missing documentation file for %s: %s", check.Options.ResourceType, missingFile) result = multierror.Append(result, err) } return result.ErrorOrNil() } +func (check *FileMismatchCheck) IgnoreFileMismatch(file string) bool { + for _, ignoreResourceName := range check.Options.IgnoreFileMismatch { + if ignoreResourceName == fileResourceName(check.Options.ProviderName, file) { + return true + } + } + + return false +} + +func (check *FileMismatchCheck) IgnoreFileMissing(resourceName string) bool { + for _, ignoreResourceName := range check.Options.IgnoreFileMissing { + if ignoreResourceName == resourceName { + return true + } + } + + return false +} + func fileHasResource(schemaResources map[string]*tfjson.Schema, providerName, file string) bool { if _, ok := schemaResources[fileResourceName(providerName, file)]; ok { return true diff --git a/vendor/github.com/bflad/tfproviderdocs/command/check.go b/vendor/github.com/bflad/tfproviderdocs/command/check.go index d83d8aca8f0..43934bb5833 100644 --- a/vendor/github.com/bflad/tfproviderdocs/command/check.go +++ b/vendor/github.com/bflad/tfproviderdocs/command/check.go @@ -24,6 +24,10 @@ type CheckCommandConfig struct { AllowedGuideSubcategoriesFile string AllowedResourceSubcategories string AllowedResourceSubcategoriesFile string + IgnoreFileMismatchDataSources string + IgnoreFileMismatchResources string + IgnoreFileMissingDataSources string + IgnoreFileMissingResources string IgnoreSideNavigationDataSources string IgnoreSideNavigationResources string LogLevel string @@ -47,6 +51,10 @@ func (*CheckCommand) Help() string { fmt.Fprintf(opts, CommandHelpOptionFormat, "-allowed-guide-subcategories-file", "Path to newline separated file of allowed guide frontmatter subcategories.") fmt.Fprintf(opts, CommandHelpOptionFormat, "-allowed-resource-subcategories", "Comma separated list of allowed data source and resource frontmatter subcategories.") fmt.Fprintf(opts, CommandHelpOptionFormat, "-allowed-resource-subcategories-file", "Path to newline separated file of allowed data source and resource frontmatter subcategories.") + fmt.Fprintf(opts, CommandHelpOptionFormat, "-ignore-file-mismatch-data-sources", "Comma separated list of data sources to ignore mismatched/extra files.") + fmt.Fprintf(opts, CommandHelpOptionFormat, "-ignore-file-mismatch-resources", "Comma separated list of resources to ignore mismatched/extra files.") + fmt.Fprintf(opts, CommandHelpOptionFormat, "-ignore-file-missing-data-sources", "Comma separated list of data sources to ignore missing files.") + fmt.Fprintf(opts, CommandHelpOptionFormat, "-ignore-file-missing-resources", "Comma separated list of resources to ignore missing files.") fmt.Fprintf(opts, CommandHelpOptionFormat, "-ignore-side-navigation-data-sources", "Comma separated list of data sources to ignore side navigation validation.") fmt.Fprintf(opts, CommandHelpOptionFormat, "-ignore-side-navigation-resources", "Comma separated list of resources to ignore side navigation validation.") fmt.Fprintf(opts, CommandHelpOptionFormat, "-provider-name", "Terraform Provider name. Automatically determined if current working directory or provided path is prefixed with terraform-provider-*.") @@ -80,6 +88,10 @@ func (c *CheckCommand) Run(args []string) int { flags.StringVar(&config.AllowedGuideSubcategoriesFile, "allowed-guide-subcategories-file", "", "") flags.StringVar(&config.AllowedResourceSubcategories, "allowed-resource-subcategories", "", "") flags.StringVar(&config.AllowedResourceSubcategoriesFile, "allowed-resource-subcategories-file", "", "") + flags.StringVar(&config.IgnoreFileMismatchDataSources, "ignore-file-mismatch-data-sources", "", "") + flags.StringVar(&config.IgnoreFileMismatchResources, "ignore-file-mismatch-resources", "", "") + flags.StringVar(&config.IgnoreFileMissingDataSources, "ignore-file-missing-data-sources", "", "") + flags.StringVar(&config.IgnoreFileMissingResources, "ignore-file-missing-resources", "", "") flags.StringVar(&config.IgnoreSideNavigationDataSources, "ignore-side-navigation-data-sources", "", "") flags.StringVar(&config.IgnoreSideNavigationResources, "ignore-side-navigation-resources", "", "") flags.StringVar(&config.ProviderName, "provider-name", "", "") @@ -131,8 +143,7 @@ func (c *CheckCommand) Run(args []string) int { return 1 } - var allowedGuideSubcategories, allowedResourceSubcategories, ignoreSideNavigationDataSources, ignoreSideNavigationResources []string - + var allowedGuideSubcategories []string if v := config.AllowedGuideSubcategories; v != "" { allowedGuideSubcategories = strings.Split(v, ",") } @@ -147,6 +158,7 @@ func (c *CheckCommand) Run(args []string) int { } } + var allowedResourceSubcategories []string if v := config.AllowedResourceSubcategories; v != "" { allowedResourceSubcategories = strings.Split(v, ",") } @@ -161,18 +173,68 @@ func (c *CheckCommand) Run(args []string) int { } } + var ignoreFileMismatchDataSources []string + if v := config.IgnoreFileMismatchDataSources; v != "" { + ignoreFileMismatchDataSources = strings.Split(v, ",") + } + + var ignoreFileMismatchResources []string + if v := config.IgnoreFileMismatchResources; v != "" { + ignoreFileMismatchResources = strings.Split(v, ",") + } + + var ignoreFileMissingDataSources []string + if v := config.IgnoreFileMissingDataSources; v != "" { + ignoreFileMissingDataSources = strings.Split(v, ",") + } + + var ignoreFileMissingResources []string + if v := config.IgnoreFileMissingResources; v != "" { + ignoreFileMissingResources = strings.Split(v, ",") + } + + var ignoreSideNavigationDataSources []string if v := config.IgnoreSideNavigationDataSources; v != "" { ignoreSideNavigationDataSources = strings.Split(v, ",") } + var ignoreSideNavigationResources []string if v := config.IgnoreSideNavigationResources; v != "" { ignoreSideNavigationResources = strings.Split(v, ",") } + var schemaDataSources, schemaResources map[string]*tfjson.Schema + if config.ProvidersSchemaJson != "" { + ps, err := providerSchemas(config.ProvidersSchemaJson) + + if err != nil { + c.Ui.Error(fmt.Sprintf("Error enabling Terraform Provider schema checks: %s", err)) + return 1 + } + + if config.ProviderName == "" { + msg := `Unknown provider name for enabling Terraform Provider schema checks. + +Check that the current working directory or provided path is prefixed with terraform-provider-*.` + c.Ui.Error(msg) + return 1 + } + + schemaDataSources = providerSchemasDataSources(ps, config.ProviderName) + schemaResources = providerSchemasResources(ps, config.ProviderName) + } + fileOpts := &check.FileOptions{ BasePath: config.Path, } checkOpts := &check.CheckOptions{ + DataSourceFileMismatch: &check.FileMismatchOptions{ + IgnoreFileMismatch: ignoreFileMismatchDataSources, + IgnoreFileMissing: ignoreFileMissingDataSources, + ProviderName: config.ProviderName, + ResourceType: check.ResourceTypeDataSource, + Schemas: schemaDataSources, + }, LegacyDataSourceFile: &check.LegacyDataSourceFileOptions{ FileOptions: fileOpts, FrontMatter: &check.FrontMatterOptions{ @@ -222,6 +284,13 @@ func (c *CheckCommand) Run(args []string) int { RequireSubcategory: config.RequireResourceSubcategory, }, }, + ResourceFileMismatch: &check.FileMismatchOptions{ + IgnoreFileMismatch: ignoreFileMismatchResources, + IgnoreFileMissing: ignoreFileMissingResources, + ProviderName: config.ProviderName, + ResourceType: check.ResourceTypeResource, + Schemas: schemaResources, + }, SideNavigation: &check.SideNavigationOptions{ FileOptions: fileOpts, IgnoreDataSources: ignoreSideNavigationDataSources, @@ -230,26 +299,6 @@ func (c *CheckCommand) Run(args []string) int { }, } - if config.ProvidersSchemaJson != "" { - ps, err := providerSchemas(config.ProvidersSchemaJson) - - if err != nil { - c.Ui.Error(fmt.Sprintf("Error enabling Terraform Provider schema checks: %s", err)) - return 1 - } - - if config.ProviderName == "" { - msg := `Unknown provider name for enabling Terraform Provider schema checks. - -Check that the current working directory or provided path is prefixed with terraform-provider-*.` - c.Ui.Error(msg) - return 1 - } - - checkOpts.SchemaDataSources = providerSchemasDataSources(ps, config.ProviderName) - checkOpts.SchemaResources = providerSchemasResources(ps, config.ProviderName) - } - if err := check.NewCheck(checkOpts).Run(directories); err != nil { c.Ui.Error(fmt.Sprintf("Error checking Terraform Provider documentation: %s", err)) return 1 diff --git a/vendor/github.com/bflad/tfproviderdocs/go.mod b/vendor/github.com/bflad/tfproviderdocs/go.mod index 11196dd4f7a..94e895337aa 100644 --- a/vendor/github.com/bflad/tfproviderdocs/go.mod +++ b/vendor/github.com/bflad/tfproviderdocs/go.mod @@ -6,7 +6,7 @@ require ( github.com/bmatcuk/doublestar v1.2.1 github.com/hashicorp/go-hclog v0.10.0 github.com/hashicorp/go-multierror v1.0.0 - github.com/hashicorp/terraform-json v0.3.1 + github.com/hashicorp/terraform-json v0.5.0 github.com/mattn/go-colorable v0.1.4 github.com/mitchellh/cli v1.0.0 golang.org/x/net v0.0.0-20180811021610-c39426892332 diff --git a/vendor/github.com/bflad/tfproviderdocs/go.sum b/vendor/github.com/bflad/tfproviderdocs/go.sum index 915d3453fb2..ed5ba548b98 100644 --- a/vendor/github.com/bflad/tfproviderdocs/go.sum +++ b/vendor/github.com/bflad/tfproviderdocs/go.sum @@ -10,14 +10,16 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-hclog v0.10.0 h1:b86HUuA126IcSHyC55WjPo7KtCOVeTCKIjr+3lBhPxI= github.com/hashicorp/go-hclog v0.10.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/terraform-json v0.3.1 h1:vRiOLck4YX4UqzljVhdQKsVLixX4L+Pgnm/q+xu6QvE= -github.com/hashicorp/terraform-json v0.3.1/go.mod h1:MdwQStcJb00ht55L/2YH0ypAO9RNtczJ1MaUlf+gJcg= +github.com/hashicorp/terraform-json v0.5.0 h1:7TV3/F3y7QVSuN4r9BEXqnWqrAyeOtON8f0wvREtyzs= +github.com/hashicorp/terraform-json v0.5.0/go.mod h1:eAbqb4w0pSlRmdvl8fOyHAi/+8jnkVYN28gJkSJrLhU= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -40,8 +42,8 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/zclconf/go-cty v0.0.0-20190430221426-d36a6f0dbffd h1:NZOOU7h+pDtcKo6xlqm8PwnarS8nJ+6+I83jT8ZfLPI= -github.com/zclconf/go-cty v0.0.0-20190430221426-d36a6f0dbffd/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= +github.com/zclconf/go-cty v1.2.1 h1:vGMsygfmeCl4Xb6OA5U5XVAaQZ69FvoG7X2jUtQujb8= +github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= golang.org/x/net v0.0.0-20180811021610-c39426892332 h1:efGso+ep0DjyCBJPjvoz0HI6UldX4Md2F1rZFe1ir0E= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/vendor/github.com/bflad/tfproviderdocs/version/version.go b/vendor/github.com/bflad/tfproviderdocs/version/version.go index 97f2848c8b4..c2072752726 100644 --- a/vendor/github.com/bflad/tfproviderdocs/version/version.go +++ b/vendor/github.com/bflad/tfproviderdocs/version/version.go @@ -11,7 +11,7 @@ var ( GitDescribe string // The main version number that is being run at the moment. - Version = "0.5.3" + Version = "0.6.0" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release diff --git a/vendor/github.com/hashicorp/terraform-json/schemas.go b/vendor/github.com/hashicorp/terraform-json/schemas.go index e025fbe0410..5dd430a5553 100644 --- a/vendor/github.com/hashicorp/terraform-json/schemas.go +++ b/vendor/github.com/hashicorp/terraform-json/schemas.go @@ -83,6 +83,18 @@ type Schema struct { Block *SchemaBlock `json:"block,omitempty"` } +// SchemaDescriptionKind describes the format type for a particular description's field. +type SchemaDescriptionKind string + +const ( + // SchemaDescriptionKindPlain indicates a string in plain text format. + SchemaDescriptionKindPlain SchemaDescriptionKind = "plaintext" + + // SchemaDescriptionKindMarkdown indicates a Markdown string and may need to be + // processed prior to presentation. + SchemaDescriptionKindMarkdown SchemaDescriptionKind = "markdown" +) + // SchemaBlock represents a nested block within a particular schema. type SchemaBlock struct { // The attributes defined at the particular level of this block. @@ -90,6 +102,14 @@ type SchemaBlock struct { // Any nested blocks within this particular block. NestedBlocks map[string]*SchemaBlockType `json:"block_types,omitempty"` + + // The description for this block and format of the description. If + // no kind is provided, it can be assumed to be plain text. + Description string `json:"description,omitempty"` + DescriptionKind SchemaDescriptionKind `json:"description_kind,omitempty"` + + // If true, this block is deprecated. + Deprecated bool `json:"deprecated,omitempty"` } // SchemaNestingMode is the nesting mode for a particular nested @@ -145,8 +165,13 @@ type SchemaAttribute struct { // The attribute type. AttributeType cty.Type `json:"type,omitempty"` - // The description field for this attribute. - Description string `json:"description,omitempty"` + // The description field for this attribute. If no kind is + // provided, it can be assumed to be plain text. + Description string `json:"description,omitempty"` + DescriptionKind SchemaDescriptionKind `json:"description_kind,omitempty"` + + // If true, this attribute is deprecated. + Deprecated bool `json:"deprecated,omitempty"` // If true, this attribute is required - it has to be entered in // configuration. diff --git a/vendor/modules.txt b/vendor/modules.txt index 1d827ac71fa..3459394f6b1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -215,7 +215,7 @@ github.com/bflad/gopaniccheck/passes/logpaniccallexpr github.com/bflad/gopaniccheck/passes/logpanicfcallexpr github.com/bflad/gopaniccheck/passes/logpaniclncallexpr github.com/bflad/gopaniccheck/passes/paniccallexpr -# github.com/bflad/tfproviderdocs v0.5.3 +# github.com/bflad/tfproviderdocs v0.6.0 github.com/bflad/tfproviderdocs github.com/bflad/tfproviderdocs/check github.com/bflad/tfproviderdocs/check/sidenavigation @@ -525,7 +525,7 @@ github.com/hashicorp/hcl/v2/json github.com/hashicorp/logutils # github.com/hashicorp/terraform-config-inspect v0.0.0-20191115094559-17f92b0546e8 github.com/hashicorp/terraform-config-inspect/tfconfig -# github.com/hashicorp/terraform-json v0.4.0 +# github.com/hashicorp/terraform-json v0.5.0 github.com/hashicorp/terraform-json # github.com/hashicorp/terraform-plugin-sdk v1.12.0 github.com/hashicorp/terraform-plugin-sdk/acctest From b00fe10c595064f13b4cb6bb485661f6c78de346 Mon Sep 17 00:00:00 2001 From: Tom Fotherby Date: Mon, 11 May 2020 13:44:10 +0100 Subject: [PATCH 079/475] Wording fix: noncurrent object versions --- website/docs/r/s3_bucket.html.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/docs/r/s3_bucket.html.markdown b/website/docs/r/s3_bucket.html.markdown index 6eb96a9d192..054d8094810 100644 --- a/website/docs/r/s3_bucket.html.markdown +++ b/website/docs/r/s3_bucket.html.markdown @@ -414,12 +414,12 @@ The `transition` object supports the following The `noncurrent_version_expiration` object supports the following -* `days` (Required) Specifies the number of days an object is noncurrent object versions expire. +* `days` (Required) Specifies the number of days noncurrent object versions expire. The `noncurrent_version_transition` object supports the following -* `days` (Required) Specifies the number of days an object is noncurrent object versions expire. -* `storage_class` (Required) Specifies the Amazon S3 storage class to which you want the noncurrent versions object to transition. Can be `ONEZONE_IA`, `STANDARD_IA`, `INTELLIGENT_TIERING`, `GLACIER`, or `DEEP_ARCHIVE`. +* `days` (Required) Specifies the number of days noncurrent object versions transition. +* `storage_class` (Required) Specifies the Amazon S3 storage class to which you want the noncurrent object versions to transition. Can be `ONEZONE_IA`, `STANDARD_IA`, `INTELLIGENT_TIERING`, `GLACIER`, or `DEEP_ARCHIVE`. The `replication_configuration` object supports the following: From 2562a50e12ae444cb198731011e56a4546d9671d Mon Sep 17 00:00:00 2001 From: Gerard Costa Date: Mon, 11 May 2020 18:54:15 +0200 Subject: [PATCH 080/475] Update enabled_cloudwatch_logs_exports description Update enabled_cloudwatch_logs_exports argument description to be more clear. --- website/docs/r/db_instance.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/db_instance.html.markdown b/website/docs/r/db_instance.html.markdown index dc8d64870a2..0e3c90421d3 100644 --- a/website/docs/r/db_instance.html.markdown +++ b/website/docs/r/db_instance.html.markdown @@ -107,7 +107,7 @@ for additional read replica contraints. * `deletion_protection` - (Optional) If the DB instance should have deletion protection enabled. The database can't be deleted when this value is set to `true`. The default is `false`. * `domain` - (Optional) The ID of the Directory Service Active Directory domain to create the instance in. * `domain_iam_role_name` - (Optional, but required if domain is provided) The name of the IAM role to be used when making API calls to the Directory Service. -* `enabled_cloudwatch_logs_exports` - (Optional) List of log types to enable for exporting to CloudWatch logs. If omitted, no logs will be exported. Valid values (depending on `engine`): `agent` (MSSQL), `alert`, `audit`, `error`, `general`, `listener`, `slowquery`, `trace`, `postgresql` (PostgreSQL), `upgrade` (PostgreSQL). +* `enabled_cloudwatch_logs_exports` - (Optional) List of log types to enable for exporting to CloudWatch logs. If omitted, no logs will be exported. Valid values (depending on `engine`). MySQL and MariaDB: `audit`, `error`, `general`, `slowquery`. PostgreSQL: `postgresql`, `upgrade`. MSSQL: `agent` , `error`. Oracle: `alert`, `audit`, `listener`, `trace`. * `engine` - (Required unless a `snapshot_identifier` or `replicate_source_db` is provided) The database engine to use. For supported values, see the Engine parameter in [API action CreateDBInstance](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBInstance.html). Note that for Amazon Aurora instances the engine must match the [DB cluster](/docs/providers/aws/r/rds_cluster.html)'s engine'. From ebc340674f79f119b159bd1cc47a9b7b324c705e Mon Sep 17 00:00:00 2001 From: Akihito Nakano Date: Tue, 12 May 2020 02:15:19 +0900 Subject: [PATCH 081/475] resource/aws_appsync_resolver: Add CachingConfig support (#12747) Output from acceptance testing: ``` --- PASS: TestAccAwsAppsyncResolver_disappears (17.59s) --- PASS: TestAccAwsAppsyncResolver_CachingConfig (21.28s) --- PASS: TestAccAwsAppsyncResolver_PipelineConfig (21.32s) --- PASS: TestAccAwsAppsyncResolver_ResponseTemplate (27.75s) --- PASS: TestAccAwsAppsyncResolver_basic (30.41s) --- PASS: TestAccAwsAppsyncResolver_RequestTemplate (32.44s) --- PASS: TestAccAwsAppsyncResolver_multipleResolvers (33.10s) --- PASS: TestAccAwsAppsyncResolver_DataSource (35.67s) ``` --- aws/resource_aws_appsync_resolver.go | 84 ++++++++++++++++ aws/resource_aws_appsync_resolver_test.go | 98 +++++++++++++++++++ aws/structure.go | 17 ---- website/docs/r/appsync_resolver.html.markdown | 18 +++- 4 files changed, 195 insertions(+), 22 deletions(-) diff --git a/aws/resource_aws_appsync_resolver.go b/aws/resource_aws_appsync_resolver.go index 470f47ef3eb..11b3e52e988 100644 --- a/aws/resource_aws_appsync_resolver.go +++ b/aws/resource_aws_appsync_resolver.go @@ -77,6 +77,27 @@ func resourceAwsAppsyncResolver() *schema.Resource { }, }, }, + "caching_config": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "caching_keys": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Set: schema.HashString, + }, + "ttl": { + Type: schema.TypeInt, + Optional: true, + }, + }, + }, + }, "arn": { Type: schema.TypeString, Computed: true, @@ -108,6 +129,10 @@ func resourceAwsAppsyncResolverCreate(d *schema.ResourceData, meta interface{}) } } + if v, ok := d.GetOk("caching_config"); ok { + input.CachingConfig = expandAppsyncResolverCachingConfig(v.([]interface{})) + } + mutexKey := fmt.Sprintf("appsync-schema-%s", d.Get("api_id").(string)) awsMutexKV.Lock(mutexKey) defer awsMutexKV.Unlock(mutexKey) @@ -165,6 +190,10 @@ func resourceAwsAppsyncResolverRead(d *schema.ResourceData, meta interface{}) er return fmt.Errorf("Error setting pipeline_config: %s", err) } + if err := d.Set("caching_config", flattenAppsyncCachingConfig(resp.Resolver.CachingConfig)); err != nil { + return fmt.Errorf("Error setting caching_config: %s", err) + } + return nil } @@ -191,6 +220,10 @@ func resourceAwsAppsyncResolverUpdate(d *schema.ResourceData, meta interface{}) } } + if v, ok := d.GetOk("caching_config"); ok { + input.CachingConfig = expandAppsyncResolverCachingConfig(v.([]interface{})) + } + mutexKey := fmt.Sprintf("appsync-schema-%s", d.Get("api_id").(string)) awsMutexKV.Lock(mutexKey) defer awsMutexKV.Unlock(mutexKey) @@ -243,3 +276,54 @@ func decodeAppsyncResolverID(id string) (string, string, string, error) { } return idParts[0], idParts[1], idParts[2], nil } + +func expandAppsyncResolverCachingConfig(l []interface{}) *appsync.CachingConfig { + if len(l) < 1 || l[0] == nil { + return nil + } + + m := l[0].(map[string]interface{}) + + cachingConfig := &appsync.CachingConfig{ + CachingKeys: expandStringSet(m["caching_keys"].(*schema.Set)), + } + + if v, ok := m["ttl"].(int); ok && v != 0 { + cachingConfig.Ttl = aws.Int64(int64(v)) + } + + return cachingConfig +} + +func flattenAppsyncPipelineConfig(c *appsync.PipelineConfig) []interface{} { + if c == nil { + return nil + } + + if len(c.Functions) == 0 { + return nil + } + + m := map[string]interface{}{ + "functions": flattenStringList(c.Functions), + } + + return []interface{}{m} +} + +func flattenAppsyncCachingConfig(c *appsync.CachingConfig) []interface{} { + if c == nil { + return nil + } + + if len(c.CachingKeys) == 0 && *(c.Ttl) == 0 { + return nil + } + + m := map[string]interface{}{ + "caching_keys": flattenStringSet(c.CachingKeys), + "ttl": int(aws.Int64Value(c.Ttl)), + } + + return []interface{}{m} +} diff --git a/aws/resource_aws_appsync_resolver_test.go b/aws/resource_aws_appsync_resolver_test.go index 7b18942e7b1..8cbbfec9df8 100644 --- a/aws/resource_aws_appsync_resolver_test.go +++ b/aws/resource_aws_appsync_resolver_test.go @@ -220,6 +220,33 @@ func TestAccAwsAppsyncResolver_PipelineConfig(t *testing.T) { }) } +func TestAccAwsAppsyncResolver_CachingConfig(t *testing.T) { + var resolver appsync.Resolver + rName := fmt.Sprintf("tfacctest%d", acctest.RandInt()) + resourceName := "aws_appsync_resolver.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsAppsyncResolverDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAppsyncResolver_cachingConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsAppsyncResolverExists(resourceName, &resolver), + resource.TestCheckResourceAttr(resourceName, "caching_config.0.caching_keys.#", "2"), + resource.TestCheckResourceAttr(resourceName, "caching_config.0.ttl", "60"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccCheckAwsAppsyncResolverDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).appsyncconn for _, rs := range s.RootModule().Resources { @@ -739,3 +766,74 @@ EOF `, rName) } + +func testAccAppsyncResolver_cachingConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_appsync_graphql_api" "test" { + authentication_type = "API_KEY" + name = "%[1]s" + schema = < Date: Mon, 11 May 2020 13:17:22 -0400 Subject: [PATCH 082/475] Update CHANGELOG for #12747 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 689ded43ef6..a9a8e4d25f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ ## 2.62.0 (Unreleased) + +ENHANCEMENTS: + +* resource/aws_appsync_resolver: Add `cache_config` configuration block [GH-12747] + ## 2.61.0 (May 08, 2020) FEATURES: From 766f45e00214b46772f9e56259f8a6b3efd2fb60 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 11 May 2020 14:02:11 -0400 Subject: [PATCH 083/475] tests/resource/aws_budgets_budget: Add test sweeper. (#13210) Output from sweeper in AWS Commercial: ``` 2020/05/11 13:29:44 [INFO] Deleting Budget: test-budget-6271992019102694956 2020/05/11 13:29:44 [INFO] Deleting Budget: test-budget-630276250939568571 2020/05/11 13:29:44 [INFO] Deleting Budget: test-budget-6433868691412216261 2020/05/11 13:29:45 [INFO] Deleting Budget: test-budget-7261892134268242315 2020/05/11 13:29:45 Sweeper Tests ran successfully: - aws_budgets_budget ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/11 13:29:52 [WARN] Skipping Budgets sweep for us-gov-west-1: RequestError: send request failed caused by: Post "https://budgets.us-gov-west-1.amazonaws.com/": dial tcp: lookup budgets.us-gov-west-1.amazonaws.com: no such host 2020/05/11 13:29:52 Sweeper Tests ran successfully: - aws_budgets_budget ``` --- aws/resource_aws_budgets_budget_test.go | 64 ++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_budgets_budget_test.go b/aws/resource_aws_budgets_budget_test.go index 65ddb8b7310..6cb5b1fa3ef 100644 --- a/aws/resource_aws_budgets_budget_test.go +++ b/aws/resource_aws_budgets_budget_test.go @@ -2,6 +2,7 @@ package aws import ( "fmt" + "log" "reflect" "regexp" "strconv" @@ -11,11 +12,70 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/budgets" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" ) +func init() { + resource.AddTestSweepers("aws_budgets_budget", &resource.Sweeper{ + Name: "aws_budgets_budget", + F: testSweepBudgetsBudgets, + }) +} + +func testSweepBudgetsBudgets(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).budgetconn + accountID := client.(*AWSClient).accountid + input := &budgets.DescribeBudgetsInput{ + AccountId: aws.String(accountID), + } + var sweeperErrs *multierror.Error + + for { + output, err := conn.DescribeBudgets(input) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping Budgets sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving Budgets: %w", err)) + return sweeperErrs + } + + for _, budget := range output.Budgets { + name := aws.StringValue(budget.BudgetName) + + log.Printf("[INFO] Deleting Budget: %s", name) + _, err := conn.DeleteBudget(&budgets.DeleteBudgetInput{ + AccountId: aws.String(accountID), + BudgetName: aws.String(name), + }) + if isAWSErr(err, budgets.ErrCodeNotFoundException, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error deleting Budget (%s): %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + if aws.StringValue(output.NextToken) == "" { + break + } + input.NextToken = output.NextToken + } + + return sweeperErrs.ErrorOrNil() +} + func TestAccAWSBudgetsBudget_basic(t *testing.T) { costFilterKey := "AZ" name := fmt.Sprintf("test-budget-%d", acctest.RandInt()) @@ -584,10 +644,10 @@ resource "aws_budgets_budget" "foo" { use_blended = "%t" } - time_period_start = "%s" + time_period_start = "%s" time_period_end = "%s" time_unit = "%s" - + %s } `, *budgetConfig.BudgetName, *budgetConfig.BudgetType, *budgetConfig.BudgetLimit.Amount, *budgetConfig.BudgetLimit.Unit, *budgetConfig.CostTypes.IncludeTax, *budgetConfig.CostTypes.IncludeSubscription, *budgetConfig.CostTypes.UseBlended, timePeriodStart, timePeriodEnd, *budgetConfig.TimeUnit, strings.Join(notificationStrings, "\n")) From e395572d260be21e1d1aaa072364f0b360784290 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 28 Jul 2019 17:03:13 -0400 Subject: [PATCH 084/475] API Gateway WebSocket chat application example --- .../api-gateway-websocket-chat-app/.gitignore | 1 + .../api-gateway-websocket-chat-app/README.md | 17 + .../api-gateway-websocket-chat-app/main.tf | 456 ++++++++++++++++++ .../onconnect/app.js | 22 + .../onconnect/package.json | 11 + .../ondisconnect/app.js | 22 + .../ondisconnect/package.json | 11 + .../sendmessage/app.js | 46 ++ .../sendmessage/package.json | 11 + .../terraform.template.tfvars | 5 + .../variables.tf | 11 + 11 files changed, 613 insertions(+) create mode 100644 examples/api-gateway-websocket-chat-app/.gitignore create mode 100644 examples/api-gateway-websocket-chat-app/README.md create mode 100644 examples/api-gateway-websocket-chat-app/main.tf create mode 100644 examples/api-gateway-websocket-chat-app/onconnect/app.js create mode 100644 examples/api-gateway-websocket-chat-app/onconnect/package.json create mode 100644 examples/api-gateway-websocket-chat-app/ondisconnect/app.js create mode 100644 examples/api-gateway-websocket-chat-app/ondisconnect/package.json create mode 100644 examples/api-gateway-websocket-chat-app/sendmessage/app.js create mode 100644 examples/api-gateway-websocket-chat-app/sendmessage/package.json create mode 100644 examples/api-gateway-websocket-chat-app/terraform.template.tfvars create mode 100644 examples/api-gateway-websocket-chat-app/variables.tf diff --git a/examples/api-gateway-websocket-chat-app/.gitignore b/examples/api-gateway-websocket-chat-app/.gitignore new file mode 100644 index 00000000000..c4c4ffc6aa4 --- /dev/null +++ b/examples/api-gateway-websocket-chat-app/.gitignore @@ -0,0 +1 @@ +*.zip diff --git a/examples/api-gateway-websocket-chat-app/README.md b/examples/api-gateway-websocket-chat-app/README.md new file mode 100644 index 00000000000..74e065f6a3b --- /dev/null +++ b/examples/api-gateway-websocket-chat-app/README.md @@ -0,0 +1,17 @@ +# API Gateway WebSocket Chat Application + +This example demonstrates how to create a simple chat application using [API Gateway's WebSocket-based API](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api.html) features. +It's based on the [AWS Serverless Application Model](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) [`simple-websockets-chat-app`](https://github.com/aws-samples/simple-websockets-chat-app). + +## Running this Example + +Either `cp terraform.template.tfvars terraform.tfvars` and modify that new file accordingly or provide variables via CLI: + +``` +terraform apply \ + -var="aws_access_key=yourawsaccesskey" \ + -var="aws_secret_key=yourawssecretkey" \ + -var="aws_region=us-east-1" +``` + +The `WebSocketURI` output contains the URL of the API endpoint to be used when following the [instructions](https://github.com/aws-samples/simple-websockets-chat-app#testing-the-chat-api) for testing. diff --git a/examples/api-gateway-websocket-chat-app/main.tf b/examples/api-gateway-websocket-chat-app/main.tf new file mode 100644 index 00000000000..4b5c485d339 --- /dev/null +++ b/examples/api-gateway-websocket-chat-app/main.tf @@ -0,0 +1,456 @@ +# +# Terraform configuration for simple-websockets-chat-app that has the DynamoDB table and +# Lambda functions needed to demonstrate the Websocket protocol on API Gateway. +# + +# +# Providers. +# + +provider "aws" { + access_key = "${var.aws_access_key}" + secret_key = "${var.aws_secret_key}" + region = "${var.aws_region}" +} + +provider "archive" {} + +# +# Data sources for current AWS account ID, partition and region. +# + +data "aws_caller_identity" "current" {} + +data "aws_partition" "current" {} + +data "aws_region" "current" {} + +# +# DynamoDB table resources. +# + +resource "aws_dynamodb_table" "ConnectionsTable" { + name = "simplechat_connections" + read_capacity = 5 + write_capacity = 5 + hash_key = "connectionId" + + attribute { + name = "connectionId" + type = "S" + } + + server_side_encryption { + enabled = true + } +} + +# See https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-policy-template-list.html#dynamo-db-crud-policy. +resource "aws_iam_policy" "DynamoDBCrudPolicy" { + name = "DynamoDBCrudPolicy" + + policy = < { + let connectionData; + + try { + connectionData = await ddb.scan({ TableName: TABLE_NAME, ProjectionExpression: 'connectionId' }).promise(); + } catch (e) { + return { statusCode: 500, body: e.stack }; + } + + const apigwManagementApi = new AWS.ApiGatewayManagementApi({ + apiVersion: '2018-11-29', + endpoint: event.requestContext.domainName + '/' + event.requestContext.stage + }); + + const postData = JSON.parse(event.body).data; + + const postCalls = connectionData.Items.map(async ({ connectionId }) => { + try { + await apigwManagementApi.postToConnection({ ConnectionId: connectionId, Data: postData }).promise(); + } catch (e) { + if (e.statusCode === 410) { + console.log(`Found stale connection, deleting ${connectionId}`); + await ddb.delete({ TableName: TABLE_NAME, Key: { connectionId } }).promise(); + } else { + throw e; + } + } + }); + + try { + await Promise.all(postCalls); + } catch (e) { + return { statusCode: 500, body: e.stack }; + } + + return { statusCode: 200, body: 'Data sent.' }; +}; diff --git a/examples/api-gateway-websocket-chat-app/sendmessage/package.json b/examples/api-gateway-websocket-chat-app/sendmessage/package.json new file mode 100644 index 00000000000..6b3b04aa615 --- /dev/null +++ b/examples/api-gateway-websocket-chat-app/sendmessage/package.json @@ -0,0 +1,11 @@ +{ + "name": "send-message", + "version": "1.0.0", + "description": "sendmessage example for WebSockets on API Gateway", + "main": "src/app.js", + "author": "SAM CLI", + "license": "MIT", + "dependencies": { + "aws-sdk": "^2.434.0" + } +} diff --git a/examples/api-gateway-websocket-chat-app/terraform.template.tfvars b/examples/api-gateway-websocket-chat-app/terraform.template.tfvars new file mode 100644 index 00000000000..286c3091224 --- /dev/null +++ b/examples/api-gateway-websocket-chat-app/terraform.template.tfvars @@ -0,0 +1,5 @@ +aws_access_key = "yourawsaccesskey" + +aws_secret_key = "yourawssecretkey" + +aws_region = "us-east-1" diff --git a/examples/api-gateway-websocket-chat-app/variables.tf b/examples/api-gateway-websocket-chat-app/variables.tf new file mode 100644 index 00000000000..e1143d86d0a --- /dev/null +++ b/examples/api-gateway-websocket-chat-app/variables.tf @@ -0,0 +1,11 @@ +variable "aws_access_key" { + description = "" +} + +variable "aws_secret_key" { + description = "" +} + +variable "aws_region" { + description = "" +} From f7e9818ad2d62345b00828da14d61babe54c1974 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sat, 18 Apr 2020 19:04:46 -0400 Subject: [PATCH 085/475] Updated resource names (aws_apigatewayv2_). --- .../api-gateway-websocket-chat-app/main.tf | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/examples/api-gateway-websocket-chat-app/main.tf b/examples/api-gateway-websocket-chat-app/main.tf index 4b5c485d339..8e8f7ad43b1 100644 --- a/examples/api-gateway-websocket-chat-app/main.tf +++ b/examples/api-gateway-websocket-chat-app/main.tf @@ -78,81 +78,81 @@ EOT # WebSocket API resources. # -resource "aws_api_gateway_v2_api" "SimpleChatWebSocket" { +resource "aws_apigatewayv2_api" "SimpleChatWebSocket" { name = "SimpleChatWebSocket" protocol_type = "WEBSOCKET" route_selection_expression = "$request.body.message" } -resource "aws_api_gateway_v2_deployment" "Deployment" { - api_id = "${aws_api_gateway_v2_api.SimpleChatWebSocket.id}" +resource "aws_apigatewayv2_deployment" "Deployment" { + api_id = "${aws_apigatewayv2_api.SimpleChatWebSocket.id}" depends_on = [ - "aws_api_gateway_v2_route.ConnectRoute", - "aws_api_gateway_v2_route.DisconnectRoute", - "aws_api_gateway_v2_route.SendRoute", + "aws_apigatewayv2_route.ConnectRoute", + "aws_apigatewayv2_route.DisconnectRoute", + "aws_apigatewayv2_route.SendRoute", ] } -resource "aws_api_gateway_v2_stage" "Stage" { - api_id = "${aws_api_gateway_v2_api.SimpleChatWebSocket.id}" +resource "aws_apigatewayv2_stage" "Stage" { + api_id = "${aws_apigatewayv2_api.SimpleChatWebSocket.id}" name = "Prod" description = "Prod Stage" - deployment_id = "${aws_api_gateway_v2_deployment.Deployment.id}" + deployment_id = "${aws_apigatewayv2_deployment.Deployment.id}" } ########### # OnConnect ########### -resource "aws_api_gateway_v2_integration" "ConnectIntegrat" { - api_id = "${aws_api_gateway_v2_api.SimpleChatWebSocket.id}" +resource "aws_apigatewayv2_integration" "ConnectIntegrat" { + api_id = "${aws_apigatewayv2_api.SimpleChatWebSocket.id}" integration_type = "AWS_PROXY" description = "Connect Integration" integration_uri = "${aws_lambda_function.OnConnectFunction.invoke_arn}" integration_method = "POST" } -resource "aws_api_gateway_v2_route" "ConnectRoute" { - api_id = "${aws_api_gateway_v2_api.SimpleChatWebSocket.id}" +resource "aws_apigatewayv2_route" "ConnectRoute" { + api_id = "${aws_apigatewayv2_api.SimpleChatWebSocket.id}" route_key = "$connect" operation_name = "ConnectRoute" - target = "integrations/${aws_api_gateway_v2_integration.ConnectIntegrat.id}" + target = "integrations/${aws_apigatewayv2_integration.ConnectIntegrat.id}" } ############## # OnDisconnect ############## -resource "aws_api_gateway_v2_integration" "DisconnectInteg" { - api_id = "${aws_api_gateway_v2_api.SimpleChatWebSocket.id}" +resource "aws_apigatewayv2_integration" "DisconnectInteg" { + api_id = "${aws_apigatewayv2_api.SimpleChatWebSocket.id}" integration_type = "AWS_PROXY" description = "Disconnect Integration" integration_uri = "${aws_lambda_function.OnDisconnectFunction.invoke_arn}" integration_method = "POST" } -resource "aws_api_gateway_v2_route" "DisconnectRoute" { - api_id = "${aws_api_gateway_v2_api.SimpleChatWebSocket.id}" +resource "aws_apigatewayv2_route" "DisconnectRoute" { + api_id = "${aws_apigatewayv2_api.SimpleChatWebSocket.id}" route_key = "$disconnect" operation_name = "DisconnectRoute" - target = "integrations/${aws_api_gateway_v2_integration.DisconnectInteg.id}" + target = "integrations/${aws_apigatewayv2_integration.DisconnectInteg.id}" } ############# # SendMessage ############# -resource "aws_api_gateway_v2_integration" "SendInteg" { - api_id = "${aws_api_gateway_v2_api.SimpleChatWebSocket.id}" +resource "aws_apigatewayv2_integration" "SendInteg" { + api_id = "${aws_apigatewayv2_api.SimpleChatWebSocket.id}" integration_type = "AWS_PROXY" description = "Send Integration" integration_uri = "${aws_lambda_function.SendMessageFunction.invoke_arn}" integration_method = "POST" } -resource "aws_api_gateway_v2_route" "SendRoute" { - api_id = "${aws_api_gateway_v2_api.SimpleChatWebSocket.id}" +resource "aws_apigatewayv2_route" "SendRoute" { + api_id = "${aws_apigatewayv2_api.SimpleChatWebSocket.id}" route_key = "sendmessage" operation_name = "SendRoute" - target = "integrations/${aws_api_gateway_v2_integration.SendInteg.id}" + target = "integrations/${aws_apigatewayv2_integration.SendInteg.id}" } # @@ -420,7 +420,7 @@ resource "aws_iam_policy" "SendMessageManageConnectionsPolicy" { "Statement": [{ "Effect": "Allow", "Action": "execute-api:ManageConnections", - "Resource": "${aws_api_gateway_v2_api.SimpleChatWebSocket.execution_arn}/*" + "Resource": "${aws_apigatewayv2_api.SimpleChatWebSocket.execution_arn}/*" }] } EOT @@ -452,5 +452,5 @@ output "SendMessageFunctionArn" { } output "WebSocketURI" { - value = "${aws_api_gateway_v2_stage.Stage.invoke_url}" + value = "${aws_apigatewayv2_stage.Stage.invoke_url}" } From c841d796fe4fcbf5ae82777b7b7a829440f1856a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 19 Apr 2020 16:27:44 -0400 Subject: [PATCH 086/475] Update AWS SDK version. Equivalent to https://github.com/aws-samples/simple-websockets-chat-app/commit/59bcc3f64491dbb0dc222bb90dc7bf81e6f873e4. --- examples/api-gateway-websocket-chat-app/onconnect/package.json | 2 +- .../api-gateway-websocket-chat-app/ondisconnect/package.json | 2 +- .../api-gateway-websocket-chat-app/sendmessage/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/api-gateway-websocket-chat-app/onconnect/package.json b/examples/api-gateway-websocket-chat-app/onconnect/package.json index 1731da25369..c3af0703f89 100644 --- a/examples/api-gateway-websocket-chat-app/onconnect/package.json +++ b/examples/api-gateway-websocket-chat-app/onconnect/package.json @@ -6,6 +6,6 @@ "author": "SAM CLI", "license": "MIT", "dependencies": { - "aws-sdk": "^2.434.0" + "aws-sdk": "^2.655.0" } } diff --git a/examples/api-gateway-websocket-chat-app/ondisconnect/package.json b/examples/api-gateway-websocket-chat-app/ondisconnect/package.json index 833297462b9..3d3d07cdcaa 100644 --- a/examples/api-gateway-websocket-chat-app/ondisconnect/package.json +++ b/examples/api-gateway-websocket-chat-app/ondisconnect/package.json @@ -6,6 +6,6 @@ "author": "SAM CLI", "license": "MIT", "dependencies": { - "aws-sdk": "^2.434.0" + "aws-sdk": "^2.655.0" } } diff --git a/examples/api-gateway-websocket-chat-app/sendmessage/package.json b/examples/api-gateway-websocket-chat-app/sendmessage/package.json index 6b3b04aa615..1f96ca5faef 100644 --- a/examples/api-gateway-websocket-chat-app/sendmessage/package.json +++ b/examples/api-gateway-websocket-chat-app/sendmessage/package.json @@ -6,6 +6,6 @@ "author": "SAM CLI", "license": "MIT", "dependencies": { - "aws-sdk": "^2.434.0" + "aws-sdk": "^2.655.0" } } From b6d0974c0c3f644e33af37e8b4dcc4c30465b314 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 19 Apr 2020 16:29:37 -0400 Subject: [PATCH 087/475] Bump lambda runtime Node version. Equivalent to https://github.com/aws-samples/simple-websockets-chat-app/commit/a0315590d3b6c4b98711281f4881b212e1039bc1. --- examples/api-gateway-websocket-chat-app/main.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/api-gateway-websocket-chat-app/main.tf b/examples/api-gateway-websocket-chat-app/main.tf index 8e8f7ad43b1..963c3257503 100644 --- a/examples/api-gateway-websocket-chat-app/main.tf +++ b/examples/api-gateway-websocket-chat-app/main.tf @@ -173,7 +173,7 @@ resource "aws_lambda_function" "OnConnectFunction" { function_name = "OnConnectFunction" role = "${aws_iam_role.OnConnectRole.arn}" handler = "app.handler" - runtime = "nodejs10.x" + runtime = "nodejs12.x" memory_size = 256 environment { @@ -257,7 +257,7 @@ resource "aws_lambda_function" "OnDisconnectFunction" { function_name = "OnDisconnectFunction" role = "${aws_iam_role.OnDisconnectRole.arn}" handler = "app.handler" - runtime = "nodejs10.x" + runtime = "nodejs12.x" memory_size = 256 environment { @@ -341,7 +341,7 @@ resource "aws_lambda_function" "SendMessageFunction" { function_name = "SendMessageFunction" role = "${aws_iam_role.SendMessageRole.arn}" handler = "app.handler" - runtime = "nodejs10.x" + runtime = "nodejs12.x" memory_size = 256 environment { From 29dfd54faf26340e09ffd9f5ba52a3ae9e5c1c72 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 19 Apr 2020 16:33:15 -0400 Subject: [PATCH 088/475] Cleanup code and make it consistent across all handlers. Equivalent to https://github.com/aws-samples/simple-websockets-chat-app/commit/acab347f4a8265b7828ba51fabee854d772dce3e and https://github.com/aws-samples/simple-websockets-chat-app/commit/8539381d453da1a886ce92d94b118f98a45951e3. --- .../onconnect/app.js | 25 +++++++------- .../ondisconnect/app.js | 33 +++++++++++-------- .../sendmessage/app.js | 14 ++++---- 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/examples/api-gateway-websocket-chat-app/onconnect/app.js b/examples/api-gateway-websocket-chat-app/onconnect/app.js index 3166943dcaf..560b720acfd 100644 --- a/examples/api-gateway-websocket-chat-app/onconnect/app.js +++ b/examples/api-gateway-websocket-chat-app/onconnect/app.js @@ -1,22 +1,23 @@ // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: MIT-0 -var AWS = require("aws-sdk"); -AWS.config.update({ region: process.env.AWS_REGION }); -var DDB = new AWS.DynamoDB({ apiVersion: "2012-10-08" }); +const AWS = require('aws-sdk'); -exports.handler = function (event, context, callback) { - var putParams = { +const ddb = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10', region: process.env.AWS_REGION }); + +exports.handler = async event => { + const putParams = { TableName: process.env.TABLE_NAME, Item: { - connectionId: { S: event.requestContext.connectionId } + connectionId: event.requestContext.connectionId } }; - DDB.putItem(putParams, function (err) { - callback(null, { - statusCode: err ? 500 : 200, - body: err ? "Failed to connect: " + JSON.stringify(err) : "Connected." - }); - }); + try { + await ddb.put(putParams).promise(); + } catch (err) { + return { statusCode: 500, body: 'Failed to connect: ' + JSON.stringify(err) }; + } + + return { statusCode: 200, body: 'Connected.' }; }; diff --git a/examples/api-gateway-websocket-chat-app/ondisconnect/app.js b/examples/api-gateway-websocket-chat-app/ondisconnect/app.js index 43326d7dec1..7c6c2d7d739 100644 --- a/examples/api-gateway-websocket-chat-app/ondisconnect/app.js +++ b/examples/api-gateway-websocket-chat-app/ondisconnect/app.js @@ -1,22 +1,29 @@ // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: MIT-0 -var AWS = require("aws-sdk"); -AWS.config.update({ region: process.env.AWS_REGION }); -var DDB = new AWS.DynamoDB({ apiVersion: "2012-10-08" }); +// https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-route-keys-connect-disconnect.html +// The $disconnect route is executed after the connection is closed. +// The connection can be closed by the server or by the client. As the connection is already closed when it is executed, +// $disconnect is a best-effort event. +// API Gateway will try its best to deliver the $disconnect event to your integration, but it cannot guarantee delivery. -exports.handler = function (event, context, callback) { - var deleteParams = { +const AWS = require('aws-sdk'); + +const ddb = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10', region: process.env.AWS_REGION }); + +exports.handler = async event => { + const deleteParams = { TableName: process.env.TABLE_NAME, Key: { - connectionId: { S: event.requestContext.connectionId } + connectionId: event.requestContext.connectionId } }; - DDB.deleteItem(deleteParams, function (err) { - callback(null, { - statusCode: err ? 500 : 200, - body: err ? "Failed to disconnect: " + JSON.stringify(err) : "Disconnected." - }); - }); -}; \ No newline at end of file + try { + await ddb.delete(deleteParams).promise(); + } catch (err) { + return { statusCode: 500, body: 'Failed to disconnect: ' + JSON.stringify(err) }; + } + + return { statusCode: 200, body: 'Disconnected.' }; +}; diff --git a/examples/api-gateway-websocket-chat-app/sendmessage/app.js b/examples/api-gateway-websocket-chat-app/sendmessage/app.js index 5df63d3c77f..c217de88007 100644 --- a/examples/api-gateway-websocket-chat-app/sendmessage/app.js +++ b/examples/api-gateway-websocket-chat-app/sendmessage/app.js @@ -3,26 +3,26 @@ const AWS = require('aws-sdk'); -const ddb = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10' }); +const ddb = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10', region: process.env.AWS_REGION }); const { TABLE_NAME } = process.env; -exports.handler = async (event, context) => { +exports.handler = async event => { let connectionData; - + try { connectionData = await ddb.scan({ TableName: TABLE_NAME, ProjectionExpression: 'connectionId' }).promise(); } catch (e) { return { statusCode: 500, body: e.stack }; } - + const apigwManagementApi = new AWS.ApiGatewayManagementApi({ apiVersion: '2018-11-29', endpoint: event.requestContext.domainName + '/' + event.requestContext.stage }); - + const postData = JSON.parse(event.body).data; - + const postCalls = connectionData.Items.map(async ({ connectionId }) => { try { await apigwManagementApi.postToConnection({ ConnectionId: connectionId, Data: postData }).promise(); @@ -35,7 +35,7 @@ exports.handler = async (event, context) => { } } }); - + try { await Promise.all(postCalls); } catch (e) { From 88e26162cb7f7f377e77e9df1e3486d17585c27c Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Mon, 11 May 2020 11:18:02 -0700 Subject: [PATCH 089/475] brief triage section --- docs/MAINTAINING.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/MAINTAINING.md b/docs/MAINTAINING.md index ab9417fa5b5..33b3e81113f 100644 --- a/docs/MAINTAINING.md +++ b/docs/MAINTAINING.md @@ -20,8 +20,7 @@ ## Triage -Incoming issues are classified using labels. These are assigned either by automation, or manually during the triage process. At a minimum tickets should be classified by type and by the area of the provider they affect. A full listing of the labels and how they are used can be found in the [Label Dictionary](#label-dictionary). - +Incoming issues are classified using labels. These are assigned either by automation, or manually during the triage process. We follow a two-label system where we classify by type and by the area of the provider they affect. A full listing of the labels and how they are used can be found in the [Label Dictionary](#label-dictionary). ## Pull Requests From 5bb0f1e4013aab9c5931231d58a251510426ef27 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 11 May 2020 14:18:40 -0400 Subject: [PATCH 090/475] tests/resource/aws_db_event_subscription: Add test sweeper. (#13213) Output from sweeper in AWS Commercial: ``` 2020/05/11 14:14:22 [DEBUG] Running Sweepers for region (us-west-2): ... 2020/05/11 14:14:25 [INFO] Deleting RDS Event Subscription: tf-acc-test-rds-event-subs-20191021133601971700000001 2020/05/11 14:14:25 [DEBUG] Waiting for state to become: [NotFound] 2020/05/11 14:14:26 [INFO] Deleting RDS Event Subscription: tf-acc-test-rds-event-subs-with-ids-361763032171412572 2020/05/11 14:14:26 [DEBUG] Waiting for state to become: [NotFound] 2020/05/11 14:14:27 Sweeper Tests ran successfully: - aws_db_event_subscription 2020/05/11 14:14:27 [DEBUG] Running Sweepers for region (us-east-1): ... 2020/05/11 14:14:28 [INFO] Deleting RDS Event Subscription: tf-acc-test-rds-event-subs-1820955943561857838 2020/05/11 14:14:28 [DEBUG] Waiting for state to become: [NotFound] 2020/05/11 14:14:28 [INFO] Deleting RDS Event Subscription: tf-acc-test-rds-event-subs-20200423224041091000000003 2020/05/11 14:14:28 [DEBUG] Waiting for state to become: [NotFound] 2020/05/11 14:14:28 [INFO] Deleting RDS Event Subscription: tf-acc-test-rds-event-subs-20200423224810295700000005 2020/05/11 14:14:28 [DEBUG] Waiting for state to become: [NotFound] 2020/05/11 14:14:29 [INFO] Deleting RDS Event Subscription: tf-acc-test-rds-event-subs-2179228110378263774 2020/05/11 14:14:29 [DEBUG] Waiting for state to become: [NotFound] 2020/05/11 14:14:29 [INFO] Deleting RDS Event Subscription: tf-acc-test-rds-event-subs-6780601559120754865 2020/05/11 14:14:29 [DEBUG] Waiting for state to become: [NotFound] 2020/05/11 14:14:29 [INFO] Deleting RDS Event Subscription: tf-acc-test-rds-event-subs-9207950827952522213 2020/05/11 14:14:29 [DEBUG] Waiting for state to become: [NotFound] 2020/05/11 14:14:29 [INFO] Deleting RDS Event Subscription: tf-acc-test-rds-event-subs-with-ids-4506979627267242866 2020/05/11 14:14:29 [DEBUG] Waiting for state to become: [NotFound] 2020/05/11 14:14:29 [INFO] Deleting RDS Event Subscription: tf-acc-test-rds-event-subs-with-ids-5063938615852179267 2020/05/11 14:14:29 [DEBUG] Waiting for state to become: [NotFound] 2020/05/11 14:14:30 Sweeper Tests ran successfully: - aws_db_event_subscription ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/11 14:13:52 [DEBUG] Running Sweepers for region (us-gov-west-1): ... 2020/05/11 14:13:55 Sweeper Tests ran successfully: - aws_db_event_subscription ``` --- aws/internal/service/rds/waiter/status.go | 36 ++++++++++ aws/internal/service/rds/waiter/waiter.go | 31 +++++++++ ...resource_aws_db_event_subscription_test.go | 65 +++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 aws/internal/service/rds/waiter/status.go create mode 100644 aws/internal/service/rds/waiter/waiter.go diff --git a/aws/internal/service/rds/waiter/status.go b/aws/internal/service/rds/waiter/status.go new file mode 100644 index 00000000000..62e70a79523 --- /dev/null +++ b/aws/internal/service/rds/waiter/status.go @@ -0,0 +1,36 @@ +package waiter + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/rds" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +const ( + // EventSubscription NotFound + EventSubscriptionStatusNotFound = "NotFound" + + // EventSubscription Unknown + EventSubscriptionStatusUnknown = "Unknown" +) + +// EventSubscriptionStatus fetches the EventSubscription and its Status +func EventSubscriptionStatus(conn *rds.RDS, subscriptionName string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + input := &rds.DescribeEventSubscriptionsInput{ + SubscriptionName: aws.String(subscriptionName), + } + + output, err := conn.DescribeEventSubscriptions(input) + + if err != nil { + return nil, EventSubscriptionStatusUnknown, err + } + + if len(output.EventSubscriptionsList) == 0 { + return nil, EventSubscriptionStatusNotFound, nil + } + + return output.EventSubscriptionsList[0], aws.StringValue(output.EventSubscriptionsList[0].Status), nil + } +} diff --git a/aws/internal/service/rds/waiter/waiter.go b/aws/internal/service/rds/waiter/waiter.go new file mode 100644 index 00000000000..482b98573ad --- /dev/null +++ b/aws/internal/service/rds/waiter/waiter.go @@ -0,0 +1,31 @@ +package waiter + +import ( + "time" + + "github.com/aws/aws-sdk-go/service/rds" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +const ( + // Maximum amount of time to wait for an EventSubscription to return Deleted + EventSubscriptionDeletedTimeout = 10 * time.Minute +) + +// DeploymentDeployed waits for a EventSubscription to return Deleted +func EventSubscriptionDeleted(conn *rds.RDS, subscriptionName string) (*rds.EventSubscription, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{"deleting"}, + Target: []string{EventSubscriptionStatusNotFound}, + Refresh: EventSubscriptionStatus(conn, subscriptionName), + Timeout: EventSubscriptionDeletedTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if v, ok := outputRaw.(*rds.EventSubscription); ok { + return v, err + } + + return nil, err +} diff --git a/aws/resource_aws_db_event_subscription_test.go b/aws/resource_aws_db_event_subscription_test.go index 60d5966dac4..5d52b3328e9 100644 --- a/aws/resource_aws_db_event_subscription_test.go +++ b/aws/resource_aws_db_event_subscription_test.go @@ -2,17 +2,82 @@ package aws import ( "fmt" + "log" "regexp" "testing" "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/rds" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/rds/waiter" ) +func init() { + resource.AddTestSweepers("aws_db_event_subscription", &resource.Sweeper{ + Name: "aws_db_event_subscription", + F: testSweepDbEventSubscriptions, + }) +} + +func testSweepDbEventSubscriptions(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).rdsconn + var sweeperErrs *multierror.Error + + err = conn.DescribeEventSubscriptionsPages(&rds.DescribeEventSubscriptionsInput{}, func(page *rds.DescribeEventSubscriptionsOutput, isLast bool) bool { + if page == nil { + return !isLast + } + + for _, eventSubscription := range page.EventSubscriptionsList { + name := aws.StringValue(eventSubscription.CustSubscriptionId) + + log.Printf("[INFO] Deleting RDS Event Subscription: %s", name) + _, err = conn.DeleteEventSubscription(&rds.DeleteEventSubscriptionInput{ + SubscriptionName: aws.String(name), + }) + if isAWSErr(err, rds.ErrCodeSubscriptionNotFoundFault, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error deleting RDS Event Subscription (%s): %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + + _, err = waiter.EventSubscriptionDeleted(conn, name) + if isAWSErr(err, rds.ErrCodeSubscriptionNotFoundFault, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error waiting for RDS Event Subscription (%s) deletion: %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + return !isLast + }) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping RDS Event Subscriptions sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving RDS Event Subscriptions: %w", err)) + } + + return sweeperErrs.ErrorOrNil() +} + func TestAccAWSDBEventSubscription_basicUpdate(t *testing.T) { var v rds.EventSubscription rInt := acctest.RandInt() From d4bc44b46bc9e12cff4896d20f1d4c3589384b50 Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Mon, 11 May 2020 11:25:59 -0700 Subject: [PATCH 091/475] add community guidelines link --- docs/MAINTAINING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/MAINTAINING.md b/docs/MAINTAINING.md index 33b3e81113f..4bf01519358 100644 --- a/docs/MAINTAINING.md +++ b/docs/MAINTAINING.md @@ -18,6 +18,10 @@ +## Community Maintainers + +Members of the community who participate in any aspects of maintaining the provider must adhere to the HashiCorp [Community Guidelines](https://www.hashicorp.com/community-guidelines). + ## Triage Incoming issues are classified using labels. These are assigned either by automation, or manually during the triage process. We follow a two-label system where we classify by type and by the area of the provider they affect. A full listing of the labels and how they are used can be found in the [Label Dictionary](#label-dictionary). From 281dc31651af88e32bab12e9c2ce1bc130c1599b Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Mon, 11 May 2020 11:36:46 -0700 Subject: [PATCH 092/475] extra blurb on roadmap --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 45fb5e8cedb..8f685f06e21 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ https://terraform.io/docs/providers/aws/index.html ## Roadmap -Our roadmap for expanding support in Terraform for AWS resources can be found in our [Roadmap](ROADMAP.md) +Our roadmap for expanding support in Terraform for AWS resources can be found in our [Roadmap](ROADMAP.md) which is published quarterly. ## Frequently Asked Questions From 50c2628ae89ea85f8fac5ef84d8aa9cf3d6563e6 Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Mon, 11 May 2020 11:38:38 -0700 Subject: [PATCH 093/475] fix kerims handle --- docs/FAQ.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/FAQ.md b/docs/FAQ.md index daf43af1edf..180bc97de3a 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -9,7 +9,7 @@ The HashiCorp Terraform AWS provider team is : * Graham Davison, Engineer - GitHub [@gdavison](https://github.com/gdavison) * Angie Pinilla, Engineer - GitHub [@angie44](https://github.com/angie44) * Simon Davis, Engineering Manager - GitHub [@breathingdust](https://github.com/breathingdust) -* Kerim Satirli, Developer Advocate - GitHub [@satirli](https://github.com/ksatirli) +* Kerim Satirli, Developer Advocate - GitHub [@ksatirli](https://github.com/ksatirli) ### Why isn’t my PR merged yet? From 98b6c395e92f6593412e07a195304eeb17b12395 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 11 May 2020 15:00:36 -0400 Subject: [PATCH 094/475] tests/resource/aws_neptune_event_subscription: Add sweeper (#13214) Output from acceptance testing: ``` --- PASS: TestAccAWSNeptuneEventSubscription_withPrefix (69.43s) --- PASS: TestAccAWSNeptuneEventSubscription_withSourceIds (75.35s) --- PASS: TestAccAWSNeptuneEventSubscription_basic (105.22s) --- PASS: TestAccAWSNeptuneEventSubscription_withCategories (105.28s) ``` Output from sweeper in AWS Commercial: ``` 2020/05/11 14:59:05 Sweeper Tests ran successfully: - aws_neptune_event_subscription ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/11 14:59:04 Sweeper Tests ran successfully: - aws_neptune_event_subscription ``` --- aws/internal/service/neptune/waiter/status.go | 36 ++++++++ aws/internal/service/neptune/waiter/waiter.go | 31 +++++++ ...rce_aws_neptune_event_subscription_test.go | 84 ++++++++++++++++--- 3 files changed, 138 insertions(+), 13 deletions(-) create mode 100644 aws/internal/service/neptune/waiter/status.go create mode 100644 aws/internal/service/neptune/waiter/waiter.go diff --git a/aws/internal/service/neptune/waiter/status.go b/aws/internal/service/neptune/waiter/status.go new file mode 100644 index 00000000000..9bd81125fb3 --- /dev/null +++ b/aws/internal/service/neptune/waiter/status.go @@ -0,0 +1,36 @@ +package waiter + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/neptune" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +const ( + // EventSubscription NotFound + EventSubscriptionStatusNotFound = "NotFound" + + // EventSubscription Unknown + EventSubscriptionStatusUnknown = "Unknown" +) + +// EventSubscriptionStatus fetches the EventSubscription and its Status +func EventSubscriptionStatus(conn *neptune.Neptune, subscriptionName string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + input := &neptune.DescribeEventSubscriptionsInput{ + SubscriptionName: aws.String(subscriptionName), + } + + output, err := conn.DescribeEventSubscriptions(input) + + if err != nil { + return nil, EventSubscriptionStatusUnknown, err + } + + if len(output.EventSubscriptionsList) == 0 { + return nil, EventSubscriptionStatusNotFound, nil + } + + return output.EventSubscriptionsList[0], aws.StringValue(output.EventSubscriptionsList[0].Status), nil + } +} diff --git a/aws/internal/service/neptune/waiter/waiter.go b/aws/internal/service/neptune/waiter/waiter.go new file mode 100644 index 00000000000..63b287a6876 --- /dev/null +++ b/aws/internal/service/neptune/waiter/waiter.go @@ -0,0 +1,31 @@ +package waiter + +import ( + "time" + + "github.com/aws/aws-sdk-go/service/neptune" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +const ( + // Maximum amount of time to wait for an EventSubscription to return Deleted + EventSubscriptionDeletedTimeout = 10 * time.Minute +) + +// DeploymentDeployed waits for a EventSubscription to return Deleted +func EventSubscriptionDeleted(conn *neptune.Neptune, subscriptionName string) (*neptune.EventSubscription, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{"deleting"}, + Target: []string{EventSubscriptionStatusNotFound}, + Refresh: EventSubscriptionStatus(conn, subscriptionName), + Timeout: EventSubscriptionDeletedTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if v, ok := outputRaw.(*neptune.EventSubscription); ok { + return v, err + } + + return nil, err +} diff --git a/aws/resource_aws_neptune_event_subscription_test.go b/aws/resource_aws_neptune_event_subscription_test.go index 7820ebf486e..642c3529a05 100644 --- a/aws/resource_aws_neptune_event_subscription_test.go +++ b/aws/resource_aws_neptune_event_subscription_test.go @@ -2,17 +2,81 @@ package aws import ( "fmt" + "log" "regexp" "testing" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/neptune" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/neptune/waiter" ) +func init() { + resource.AddTestSweepers("aws_neptune_event_subscription", &resource.Sweeper{ + Name: "aws_neptune_event_subscription", + F: testSweepNeptuneEventSubscriptions, + }) +} + +func testSweepNeptuneEventSubscriptions(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).neptuneconn + var sweeperErrs *multierror.Error + + err = conn.DescribeEventSubscriptionsPages(&neptune.DescribeEventSubscriptionsInput{}, func(page *neptune.DescribeEventSubscriptionsOutput, isLast bool) bool { + if page == nil { + return !isLast + } + + for _, eventSubscription := range page.EventSubscriptionsList { + name := aws.StringValue(eventSubscription.CustSubscriptionId) + + log.Printf("[INFO] Deleting Neptune Event Subscription: %s", name) + _, err = conn.DeleteEventSubscription(&neptune.DeleteEventSubscriptionInput{ + SubscriptionName: aws.String(name), + }) + if isAWSErr(err, neptune.ErrCodeSubscriptionNotFoundFault, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error deleting Neptune Event Subscription (%s): %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + + _, err = waiter.EventSubscriptionDeleted(conn, name) + if isAWSErr(err, neptune.ErrCodeSubscriptionNotFoundFault, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error waiting for Neptune Event Subscription (%s) deletion: %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + return !isLast + }) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping Neptune Event Subscriptions sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving Neptune Event Subscriptions: %w", err)) + } + + return sweeperErrs.ErrorOrNil() +} + func TestAccAWSNeptuneEventSubscription_basic(t *testing.T) { var v neptune.EventSubscription rInt := acctest.RandInt() @@ -205,23 +269,17 @@ func testAccCheckAWSNeptuneEventSubscriptionDestroy(s *terraform.State) error { SubscriptionName: aws.String(rs.Primary.ID), }) - if ae, ok := err.(awserr.Error); ok && ae.Code() == "SubscriptionNotFound" { + if isAWSErr(err, neptune.ErrCodeSubscriptionNotFoundFault, "") { continue } - if err == nil { - if len(resp.EventSubscriptionsList) != 0 && - aws.StringValue(resp.EventSubscriptionsList[0].CustSubscriptionId) == rs.Primary.ID { - return fmt.Errorf("Event Subscription still exists") - } - } - - newerr, ok := err.(awserr.Error) - if !ok { + if err != nil { return err } - if newerr.Code() != "SubscriptionNotFound" { - return err + + if len(resp.EventSubscriptionsList) != 0 && + aws.StringValue(resp.EventSubscriptionsList[0].CustSubscriptionId) == rs.Primary.ID { + return fmt.Errorf("Event Subscription still exists") } } From 12f378090071bb11254a50619fdeca22a8e55dfc Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 11 May 2020 15:03:44 -0400 Subject: [PATCH 095/475] tests/resource/aws_redshift_event_subscription: Add sweeper (#13215) Output from acceptance testing: ``` --- PASS: TestAccAWSRedshiftEventSubscription_withSourceIds (15.01s) --- PASS: TestAccAWSRedshiftEventSubscription_categoryUpdate (15.03s) --- PASS: TestAccAWSRedshiftEventSubscription_basicUpdate (15.12s) --- PASS: TestAccAWSRedshiftEventSubscription_withPrefix (19.41s) --- PASS: TestAccAWSRedshiftEventSubscription_tagsUpdate (33.67s) ``` Output from sweeper in AWS Commercial: ``` 2020/05/11 15:02:12 [INFO] Deleting Redshift Event Subscription: tf-acc-test-redshift-event-subs-355677199278903155 2020/05/11 15:02:12 [INFO] Deleting Redshift Event Subscription: tf-acc-test-redshift-event-subs-6008710189813830042 2020/05/11 15:02:13 [INFO] Deleting Redshift Event Subscription: tf-acc-test-redshift-event-subs-with-ids-6512691407830475824 2020/05/11 15:02:13 Sweeper Tests ran successfully: - aws_redshift_event_subscription ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/11 15:02:24 Sweeper Tests ran successfully: - aws_redshift_event_subscription ``` --- ...ce_aws_redshift_event_subscription_test.go | 73 +++++++++++++++---- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/aws/resource_aws_redshift_event_subscription_test.go b/aws/resource_aws_redshift_event_subscription_test.go index bf47f132fa0..b873820f40b 100644 --- a/aws/resource_aws_redshift_event_subscription_test.go +++ b/aws/resource_aws_redshift_event_subscription_test.go @@ -2,16 +2,68 @@ package aws import ( "fmt" + "log" "testing" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/redshift" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" ) +func init() { + resource.AddTestSweepers("aws_redshift_event_subscription", &resource.Sweeper{ + Name: "aws_redshift_event_subscription", + F: testSweepRedshiftEventSubscriptions, + }) +} + +func testSweepRedshiftEventSubscriptions(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).redshiftconn + var sweeperErrs *multierror.Error + + err = conn.DescribeEventSubscriptionsPages(&redshift.DescribeEventSubscriptionsInput{}, func(page *redshift.DescribeEventSubscriptionsOutput, isLast bool) bool { + if page == nil { + return !isLast + } + + for _, eventSubscription := range page.EventSubscriptionsList { + name := aws.StringValue(eventSubscription.CustSubscriptionId) + + log.Printf("[INFO] Deleting Redshift Event Subscription: %s", name) + _, err = conn.DeleteEventSubscription(&redshift.DeleteEventSubscriptionInput{ + SubscriptionName: aws.String(name), + }) + if isAWSErr(err, redshift.ErrCodeSubscriptionNotFoundFault, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error deleting Redshift Event Subscription (%s): %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + return !isLast + }) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping Redshift Event Subscriptions sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving Redshift Event Subscriptions: %w", err)) + } + + return sweeperErrs.ErrorOrNil() +} + func TestAccAWSRedshiftEventSubscription_basicUpdate(t *testing.T) { var v redshift.EventSubscription rInt := acctest.RandInt() @@ -268,24 +320,17 @@ func testAccCheckAWSRedshiftEventSubscriptionDestroy(s *terraform.State) error { SubscriptionName: aws.String(rs.Primary.ID), }) - if ae, ok := err.(awserr.Error); ok && ae.Code() == "SubscriptionNotFound" { + if isAWSErr(err, redshift.ErrCodeSubscriptionNotFoundFault, "") { continue } - if err == nil { - if len(resp.EventSubscriptionsList) != 0 && - *resp.EventSubscriptionsList[0].CustSubscriptionId == rs.Primary.ID { - return fmt.Errorf("Event Subscription still exists") - } - } - - // Verify the error - newerr, ok := err.(awserr.Error) - if !ok { + if err != nil { return err } - if newerr.Code() != "SubscriptionNotFound" { - return err + + if len(resp.EventSubscriptionsList) != 0 && + *resp.EventSubscriptionsList[0].CustSubscriptionId == rs.Primary.ID { + return fmt.Errorf("Event Subscription still exists") } } From 670917e1c988b5078b48a2812c4cfe049efa8b3c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 11 May 2020 15:13:35 -0400 Subject: [PATCH 096/475] tests/resource/aws_ses_configuration_set: Add sweeper (#13216) Output from sweeper in AWS Commercial: ``` 2020/05/11 15:12:01 [INFO] Deleting SES Configuration Set: event_config 2020/05/11 15:12:01 [INFO] Deleting SES Configuration Set: some-configuration-set-2981819045392895787 2020/05/11 15:12:02 [INFO] Deleting SES Configuration Set: some-configuration-set-4661762272036991094 2020/05/11 15:12:02 [INFO] Deleting SES Configuration Set: tf_acc_cfg_ses_event_dst_qjipi62k 2020/05/11 15:12:03 [INFO] Deleting SES Configuration Set: tf_acc_cfg_ses_event_dst_v28ltiav 2020/05/11 15:12:03 Sweeper Tests ran successfully: - aws_ses_configuration_set 2020/05/11 15:12:05 [INFO] Deleting SES Configuration Set: some-configuration-set-2459335473671996120 2020/05/11 15:12:05 Sweeper Tests ran successfully: - aws_ses_configuration_set ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/11 15:12:11 Sweeper Tests ran successfully: - aws_ses_configuration_set ``` --- ...resource_aws_ses_configuration_set_test.go | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/aws/resource_aws_ses_configuration_set_test.go b/aws/resource_aws_ses_configuration_set_test.go index 1999f22bca6..d98b8005e32 100644 --- a/aws/resource_aws_ses_configuration_set_test.go +++ b/aws/resource_aws_ses_configuration_set_test.go @@ -2,14 +2,71 @@ package aws import ( "fmt" + "log" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ses" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" ) +func init() { + resource.AddTestSweepers("aws_ses_configuration_set", &resource.Sweeper{ + Name: "aws_ses_configuration_set", + F: testSweepSesConfigurationSets, + }) +} + +func testSweepSesConfigurationSets(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).sesconn + input := &ses.ListConfigurationSetsInput{} + var sweeperErrs *multierror.Error + + for { + output, err := conn.ListConfigurationSets(input) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping SES Configuration Sets sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving SES Configuration Sets: %w", err)) + return sweeperErrs + } + + for _, configurationSet := range output.ConfigurationSets { + name := aws.StringValue(configurationSet.Name) + + log.Printf("[INFO] Deleting SES Configuration Set: %s", name) + _, err := conn.DeleteConfigurationSet(&ses.DeleteConfigurationSetInput{ + ConfigurationSetName: aws.String(name), + }) + if isAWSErr(err, ses.ErrCodeConfigurationSetDoesNotExistException, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error deleting SES Configuration Set (%s): %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + if aws.StringValue(output.NextToken) == "" { + break + } + input.NextToken = output.NextToken + } + + return sweeperErrs.ErrorOrNil() +} + func TestAccAWSSESConfigurationSet_basic(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { From 0c1e8fc7c39d2429fa80a62fdddce1a98b199438 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Mon, 11 May 2020 15:20:16 -0400 Subject: [PATCH 097/475] add S006 linter rule --- GNUmakefile | 1 + 1 file changed, 1 insertion(+) diff --git a/GNUmakefile b/GNUmakefile index 8b86351dce1..feef8d3c111 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -84,6 +84,7 @@ lint: -S003 \ -S004 \ -S005 \ + -S006 \ -S007 \ -S008 \ -S009 \ From fa393a2d4386c8ce22d0f80aa4fe1f702739ee85 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 11 May 2020 15:22:02 -0400 Subject: [PATCH 098/475] tests/service/ses: Add sweepers for aws_ses_domain_identity and aws_ses_email_identity resources (#13217) Output from sweeper in AWS Commercial: ``` 2020/05/11 15:18:08 [DEBUG] Running Sweepers for region (us-west-2): 2020/05/11 15:18:08 [DEBUG] Running Sweeper (aws_ses_domain_identity) in region (us-west-2) ... 2020/05/11 15:18:11 [INFO] Deleting SES Identity: u0vs67afvm.terraformtesting.com 2020/05/11 15:18:11 [INFO] Deleting SES Identity: ev8la34dmn.terraformtesting.com 2020/05/11 15:18:12 [INFO] Deleting SES Identity: sandw6a1ly.terraformtesting.com 2020/05/11 15:18:12 [INFO] Deleting SES Identity: ar9kkg48xm.terraformtesting.com 2020/05/11 15:18:13 [INFO] Deleting SES Identity: t7uux8as6i.terraformtesting.com 2020/05/11 15:18:13 [INFO] Deleting SES Identity: ct7cxvtwpy.terraformtesting.com 2020/05/11 15:18:14 [INFO] Deleting SES Identity: iup8rdmzsa.terraformtesting.com 2020/05/11 15:18:14 [INFO] Deleting SES Identity: ayhkvplwms.terraformtesting.com 2020/05/11 15:18:15 [INFO] Deleting SES Identity: kqmsovrsbe.terraformtesting.com 2020/05/11 15:18:15 [INFO] Deleting SES Identity: 2prm894o4o.terraformtesting.com 2020/05/11 15:18:16 [INFO] Deleting SES Identity: yf3lp40d1b.terraformtesting.com 2020/05/11 15:18:16 [INFO] Deleting SES Identity: v3jv80wyfp.terraformtesting.com 2020/05/11 15:18:17 [INFO] Deleting SES Identity: m29t130h73.terraformtesting.com 2020/05/11 15:18:17 [INFO] Deleting SES Identity: 93uiyxvr7e.terraformtesting.com 2020/05/11 15:18:18 [INFO] Deleting SES Identity: 0t78sotjyi.terraformtesting.com 2020/05/11 15:18:18 [INFO] Deleting SES Identity: 3s8g6i8ohb.terraformtesting.com 2020/05/11 15:18:19 [INFO] Deleting SES Identity: v0xczapxsy.terraformtesting.com 2020/05/11 15:18:19 [INFO] Deleting SES Identity: o0igbw66dq.terraformtesting.com 2020/05/11 15:18:20 [INFO] Deleting SES Identity: g26fhmlk3z.terraformtesting.com 2020/05/11 15:18:20 [INFO] Deleting SES Identity: rnjinah71k.terraformtesting.com 2020/05/11 15:18:21 [INFO] Deleting SES Identity: u2yh38lex4.terraformtesting.com 2020/05/11 15:18:21 [INFO] Deleting SES Identity: 7jaor22vrs.terraformtesting.com 2020/05/11 15:18:22 [INFO] Deleting SES Identity: frbmutital.terraformtesting.com 2020/05/11 15:18:22 [INFO] Deleting SES Identity: lg6ct2sxbx.terraformtesting.com 2020/05/11 15:18:23 [INFO] Deleting SES Identity: izb9lhzyvg.terraformtesting.com 2020/05/11 15:18:23 [INFO] Deleting SES Identity: 6q240n91ut.terraformtesting.com 2020/05/11 15:18:24 [INFO] Deleting SES Identity: iayvi6kjw6.terraformtesting.com 2020/05/11 15:18:24 [INFO] Deleting SES Identity: wxdqpsedxk.terraformtesting.com 2020/05/11 15:18:25 [INFO] Deleting SES Identity: qd1udhklyy.terraformtesting.com 2020/05/11 15:18:26 [INFO] Deleting SES Identity: mo6int19jy.terraformtesting.com 2020/05/11 15:18:26 [INFO] Deleting SES Identity: nkulrwqdgk.terraformtesting.com 2020/05/11 15:18:27 [INFO] Deleting SES Identity: bsx4ajh43w.terraformtesting.com 2020/05/11 15:18:27 [INFO] Deleting SES Identity: onl7slmmvt.terraformtesting.com 2020/05/11 15:18:28 [INFO] Deleting SES Identity: fmef1p760i.terraformtesting.com 2020/05/11 15:18:28 [INFO] Deleting SES Identity: 9fr6iefj31.terraformtesting.com 2020/05/11 15:18:29 [INFO] Deleting SES Identity: 76mu3hngu2.terraformtesting.com 2020/05/11 15:18:29 [INFO] Deleting SES Identity: 0vx0tr3btl.terraformtesting.com 2020/05/11 15:18:30 [INFO] Deleting SES Identity: qs3dyrhfkh.terraformtesting.com 2020/05/11 15:18:30 [INFO] Deleting SES Identity: 4j4erypx61.terraformtesting.com 2020/05/11 15:18:31 [INFO] Deleting SES Identity: 9kux6l6jz2.terraformtesting.com 2020/05/11 15:18:31 [INFO] Deleting SES Identity: 92j22syd6b.terraformtesting.com 2020/05/11 15:18:32 [INFO] Deleting SES Identity: yj7pft1hwp.terraformtesting.com 2020/05/11 15:18:32 [INFO] Deleting SES Identity: hcs01cm41r.terraformtesting.com 2020/05/11 15:18:33 [INFO] Deleting SES Identity: 2jrnqs9022.terraformtesting.com 2020/05/11 15:18:34 [INFO] Deleting SES Identity: nwxpiq8pjs.terraformtesting.com 2020/05/11 15:18:34 [INFO] Deleting SES Identity: gcwweydjxr.terraformtesting.com 2020/05/11 15:18:35 [INFO] Deleting SES Identity: ej288oisci.terraformtesting.com 2020/05/11 15:18:35 [INFO] Deleting SES Identity: ubqvb8ryi8.terraformtesting.com 2020/05/11 15:18:36 [INFO] Deleting SES Identity: x3lbs2zvjs.terraformtesting.com 2020/05/11 15:18:36 [INFO] Deleting SES Identity: kkgdc4v810.terraformtesting.com 2020/05/11 15:18:37 [INFO] Deleting SES Identity: 7c699fz6zx.terraformtesting.com 2020/05/11 15:18:39 [INFO] Deleting SES Identity: acgjvc2bpl.terraformtesting.com 2020/05/11 15:18:39 [INFO] Deleting SES Identity: upwsljnrgd.terraformtesting.com 2020/05/11 15:18:40 [INFO] Deleting SES Identity: 974cqc2hnj.terraformtesting.com 2020/05/11 15:18:40 [INFO] Deleting SES Identity: 7ia7ojlf8t.terraformtesting.com 2020/05/11 15:18:41 [INFO] Deleting SES Identity: 0dep1b9pz4.terraformtesting.com 2020/05/11 15:18:43 [INFO] Deleting SES Identity: om1wgkavjs.terraformtesting.com 2020/05/11 15:18:44 [INFO] Deleting SES Identity: x1zq4k02vx.terraformtesting.com 2020/05/11 15:18:45 [INFO] Deleting SES Identity: sb8z9iotdz.terraformtesting.com 2020/05/11 15:18:45 [INFO] Deleting SES Identity: qbc913s6sk.terraformtesting.com 2020/05/11 15:18:46 [INFO] Deleting SES Identity: dp2tkrnvk3.terraformtesting.com 2020/05/11 15:18:49 [INFO] Deleting SES Identity: unfpswaoag.terraformtesting.com 2020/05/11 15:18:50 [INFO] Deleting SES Identity: meedn8bson.terraformtesting.com 2020/05/11 15:18:50 [INFO] Deleting SES Identity: kdcxmoe1fl.terraformtesting.com 2020/05/11 15:18:51 [INFO] Deleting SES Identity: 84wvkwq9xl.terraformtesting.com 2020/05/11 15:18:52 [INFO] Deleting SES Identity: 4owrz0txfe.terraformtesting.com 2020/05/11 15:18:53 [DEBUG] Running Sweeper (aws_ses_email_identity) in region (us-west-2) 2020/05/11 15:18:53 [INFO] Deleting SES Identity: af3bem6w38@terraformtesting.com 2020/05/11 15:18:54 [INFO] Deleting SES Identity: fi4ryuwgnq@terraformtesting.com 2020/05/11 15:18:54 [INFO] Deleting SES Identity: jkmbzg3u2d@terraformtesting.com 2020/05/11 15:18:55 [INFO] Deleting SES Identity: tic8byzr40@terraformtesting.com 2020/05/11 15:18:58 [INFO] Deleting SES Identity: 3hgpwdfj9f@terraformtesting.com 2020/05/11 15:18:59 [INFO] Deleting SES Identity: 6l8a29ytfz@terraformtesting.com 2020/05/11 15:18:59 [INFO] Deleting SES Identity: qytzqtr9zk@terraformtesting.com 2020/05/11 15:19:00 [INFO] Deleting SES Identity: --OMITTED-- 2020/05/11 15:19:00 Sweeper Tests ran successfully: - aws_ses_domain_identity - aws_ses_email_identity 2020/05/11 15:19:00 [DEBUG] Running Sweepers for region (us-east-1): 2020/05/11 15:19:00 [DEBUG] Running Sweeper (aws_ses_email_identity) in region (us-east-1) ... 2020/05/11 15:19:02 [DEBUG] Running Sweeper (aws_ses_domain_identity) in region (us-east-1) 2020/05/11 15:19:02 Sweeper Tests ran successfully: - aws_ses_email_identity - aws_ses_domain_identity ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/11 15:18:57 [INFO] Deleting SES Identity: vi7dnxj3lc.terraformtesting.com 2020/05/11 15:18:58 [INFO] Deleting SES Identity: gy7wq1o1ij.terraformtesting.com 2020/05/11 15:18:58 [INFO] Deleting SES Identity: 0sl0vx0f4i.terraformtesting.com 2020/05/11 15:18:59 [INFO] Deleting SES Identity: ourqxjrhs7.terraformtesting.com 2020/05/11 15:18:59 [INFO] Deleting SES Identity: tve3qppqux.terraformtesting.com 2020/05/11 15:19:00 [INFO] Deleting SES Identity: w6j4ibqw6u.terraformtesting.com 2020/05/11 15:19:00 [INFO] Deleting SES Identity: jtoyaeg044.terraformtesting.com 2020/05/11 15:19:01 [INFO] Deleting SES Identity: mtba3tts7h.terraformtesting.com 2020/05/11 15:19:01 [DEBUG] Running Sweeper (aws_ses_email_identity) in region (us-gov-west-1) 2020/05/11 15:19:02 Sweeper Tests ran successfully: - aws_ses_domain_identity - aws_ses_email_identity ``` --- aws/resource_aws_ses_domain_identity_test.go | 53 ++++++++++++++++++++ aws/resource_aws_ses_email_identity_test.go | 7 +++ 2 files changed, 60 insertions(+) diff --git a/aws/resource_aws_ses_domain_identity_test.go b/aws/resource_aws_ses_domain_identity_test.go index f7249b221d8..60c7991de10 100644 --- a/aws/resource_aws_ses_domain_identity_test.go +++ b/aws/resource_aws_ses_domain_identity_test.go @@ -2,17 +2,70 @@ package aws import ( "fmt" + "log" "strings" "testing" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/ses" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" ) +func init() { + resource.AddTestSweepers("aws_ses_domain_identity", &resource.Sweeper{ + Name: "aws_ses_domain_identity", + F: func(region string) error { return testSweepSesIdentities(region, ses.IdentityTypeDomain) }, + }) +} + +func testSweepSesIdentities(region, identityType string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).sesconn + input := &ses.ListIdentitiesInput{ + IdentityType: aws.String(identityType), + } + var sweeperErrs *multierror.Error + + err = conn.ListIdentitiesPages(input, func(page *ses.ListIdentitiesOutput, isLast bool) bool { + if page == nil { + return !isLast + } + + for _, identity := range page.Identities { + identity := aws.StringValue(identity) + + log.Printf("[INFO] Deleting SES Identity: %s", identity) + _, err = conn.DeleteIdentity(&ses.DeleteIdentityInput{ + Identity: aws.String(identity), + }) + if err != nil { + sweeperErr := fmt.Errorf("error deleting SES Identity (%s): %w", identity, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + return !isLast + }) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping SES Identities sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving SES Identities: %w", err)) + } + + return sweeperErrs.ErrorOrNil() +} + func TestAccAWSSESDomainIdentity_basic(t *testing.T) { domain := fmt.Sprintf( "%s.terraformtesting.com", diff --git a/aws/resource_aws_ses_email_identity_test.go b/aws/resource_aws_ses_email_identity_test.go index 7104cf1b26e..f7a37a5db2b 100644 --- a/aws/resource_aws_ses_email_identity_test.go +++ b/aws/resource_aws_ses_email_identity_test.go @@ -13,6 +13,13 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/terraform" ) +func init() { + resource.AddTestSweepers("aws_ses_email_identity", &resource.Sweeper{ + Name: "aws_ses_email_identity", + F: func(region string) error { return testSweepSesIdentities(region, ses.IdentityTypeEmailAddress) }, + }) +} + func TestAccAWSSESEmailIdentity_basic(t *testing.T) { email := fmt.Sprintf( "%s@terraformtesting.com", From 43e2c8c52e8586e8c4b0b03f9c6c79167a08e236 Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Mon, 11 May 2020 12:24:52 -0700 Subject: [PATCH 099/475] Updates RAM acceptance tests to use ARN testing check functions Addresses: aws/resource_aws_ram_resource_share_accepter_test.go:34:6: AWSAT001: prefer resource.TestCheckResourceAttrPair() or ARN check functions (e.g. testAccMatchResourceAttrRegionalARN) aws/resource_aws_ram_resource_share_accepter_test.go:35:6: AWSAT001: prefer resource.TestCheckResourceAttrPair() or ARN check functions (e.g. testAccMatchResourceAttrRegionalARN) --- ...esource_aws_ram_resource_share_accepter_test.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/aws/resource_aws_ram_resource_share_accepter_test.go b/aws/resource_aws_ram_resource_share_accepter_test.go index ec93a33c892..36fe5cd318a 100644 --- a/aws/resource_aws_ram_resource_share_accepter_test.go +++ b/aws/resource_aws_ram_resource_share_accepter_test.go @@ -17,6 +17,8 @@ import ( func TestAccAwsRamResourceShareAccepter_basic(t *testing.T) { var providers []*schema.Provider resourceName := "aws_ram_resource_share_accepter.test" + principalAssociationResourceName := "aws_ram_principal_association.test" + shareName := fmt.Sprintf("tf-%s", acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)) resource.ParallelTest(t, resource.TestCase{ @@ -31,8 +33,8 @@ func TestAccAwsRamResourceShareAccepter_basic(t *testing.T) { Config: testAccAwsRamResourceShareAccepterBasic(shareName), Check: resource.ComposeTestCheckFunc( testAccCheckAwsRamResourceShareAccepterExists(resourceName), - resource.TestMatchResourceAttr(resourceName, "share_arn", regexp.MustCompile(`^arn\:aws\:ram\:.*resource-share/.+$`)), - resource.TestMatchResourceAttr(resourceName, "invitation_arn", regexp.MustCompile(`^arn\:aws\:ram\:.*resource-share-invitation/.+$`)), + resource.TestCheckResourceAttrPair(resourceName, "share_arn", principalAssociationResourceName, "resource_share_arn"), + testAccMatchResourceAttrRegionalARN(resourceName, "invitation_arn", "ram", regexp.MustCompile("resource-share-invitation/.+$")), resource.TestMatchResourceAttr(resourceName, "share_id", regexp.MustCompile(`^rs-.+$`)), resource.TestCheckResourceAttr(resourceName, "status", ram.ResourceShareStatusActive), resource.TestMatchResourceAttr(resourceName, "receiver_account_id", regexp.MustCompile(`\d{12}`)), @@ -106,6 +108,10 @@ func testAccCheckAwsRamResourceShareAccepterExists(name string) resource.TestChe func testAccAwsRamResourceShareAccepterBasic(shareName string) string { return testAccAlternateAccountProviderConfig() + fmt.Sprintf(` +resource "aws_ram_resource_share_accepter" "test" { + share_arn = "${aws_ram_principal_association.test.resource_share_arn}" +} + resource "aws_ram_resource_share" "test" { provider = "aws.alternate" @@ -125,9 +131,5 @@ resource "aws_ram_principal_association" "test" { } data "aws_caller_identity" "receiver" {} - -resource "aws_ram_resource_share_accepter" "test" { - share_arn = "${aws_ram_principal_association.test.resource_share_arn}" -} `, shareName) } From 33bf1d8da960eca472004ebf8832b1704ef0bda5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 11 May 2020 15:27:02 -0400 Subject: [PATCH 100/475] tests/resource/aws_iot_topic_rule: Add sweeper (#13245) Output from sweeper in AWS Commercial: ``` 2020/05/11 15:25:02 [INFO] Deleting IoT Topic Rule: backup 2020/05/11 15:25:03 [INFO] Deleting IoT Topic Rule: test_rule_nvg4m 2020/05/11 15:25:03 [INFO] Deleting IoT Topic Rule: test_rule_8mrf4 2020/05/11 15:25:04 [INFO] Deleting IoT Topic Rule: test_rule_6au9c 2020/05/11 15:25:04 [INFO] Deleting IoT Topic Rule: test_rule_abbmo 2020/05/11 15:25:05 [INFO] Deleting IoT Topic Rule: test_rule_us4e3 2020/05/11 15:25:05 [INFO] Deleting IoT Topic Rule: test_rule_xsxxn 2020/05/11 15:25:06 [INFO] Deleting IoT Topic Rule: test_rule_j9jba 2020/05/11 15:25:06 Sweeper Tests ran successfully: - aws_iot_topic_rule ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/11 15:25:12 Sweeper Tests ran successfully: - aws_iot_topic_rule ``` --- aws/resource_aws_iot_topic_rule_test.go | 57 +++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/aws/resource_aws_iot_topic_rule_test.go b/aws/resource_aws_iot_topic_rule_test.go index 4ebbed7c95b..60a537753f2 100644 --- a/aws/resource_aws_iot_topic_rule_test.go +++ b/aws/resource_aws_iot_topic_rule_test.go @@ -2,14 +2,71 @@ package aws import ( "fmt" + "log" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/iot" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" ) +func init() { + resource.AddTestSweepers("aws_iot_topic_rule", &resource.Sweeper{ + Name: "aws_iot_topic_rule", + F: testSweepIotTopicRules, + }) +} + +func testSweepIotTopicRules(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).iotconn + input := &iot.ListTopicRulesInput{} + var sweeperErrs *multierror.Error + + for { + output, err := conn.ListTopicRules(input) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping IoT Topic Rules sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving IoT Topic Rules: %w", err)) + return sweeperErrs + } + + for _, rule := range output.Rules { + name := aws.StringValue(rule.RuleName) + + log.Printf("[INFO] Deleting IoT Topic Rule: %s", name) + _, err := conn.DeleteTopicRule(&iot.DeleteTopicRuleInput{ + RuleName: aws.String(name), + }) + if isAWSErr(err, iot.ErrCodeUnauthorizedException, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error deleting IoT Topic Rule (%s): %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + if aws.StringValue(output.NextToken) == "" { + break + } + input.NextToken = output.NextToken + } + + return sweeperErrs.ErrorOrNil() +} + func TestAccAWSIoTTopicRule_basic(t *testing.T) { rName := acctest.RandString(5) resourceName := "aws_iot_topic_rule.rule" From 256f50dd6b7358ccf7de46fb867bc383d28208a4 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 11 May 2020 15:54:47 -0400 Subject: [PATCH 101/475] tests/resource/aws_glacier_vault: Add sweeper (#13184) Output from sweeper in AWS Commercial: ``` 2020/05/11 15:52:25 [DEBUG] Running Sweepers for region (us-west-2): 2020/05/11 15:52:25 [DEBUG] Running Sweeper (aws_glacier_vault) in region (us-west-2) ... 2020/05/11 15:52:28 [INFO] Deleting Glacier Vault (my_test_vault_2971843858825982230) Notifications 2020/05/11 15:52:28 [INFO] Deleting Glacier Vault: my_test_vault_2971843858825982230 2020/05/11 15:52:29 [INFO] Deleting Glacier Vault (my_test_vault_4774217224167628574) Notifications 2020/05/11 15:52:29 [INFO] Deleting Glacier Vault: my_test_vault_4774217224167628574 2020/05/11 15:52:30 [INFO] Deleting Glacier Vault (my_test_vault_5344879983212095753) Notifications 2020/05/11 15:52:30 [INFO] Deleting Glacier Vault: my_test_vault_5344879983212095753 2020/05/11 15:52:30 Sweeper Tests ran successfully: - aws_glacier_vault 2020/05/11 15:52:30 [DEBUG] Running Sweepers for region (us-east-1): 2020/05/11 15:52:30 [DEBUG] Running Sweeper (aws_glacier_vault) in region (us-east-1) ... 2020/05/11 15:52:33 Sweeper Tests ran successfully: - aws_glacier_vault ok github.com/terraform-providers/terraform-provider-aws/aws 10.242s ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/11 15:52:44 [DEBUG] Running Sweepers for region (us-gov-west-1): 2020/05/11 15:52:44 [DEBUG] Running Sweeper (aws_glacier_vault) in region (us-gov-west-1) ... 2020/05/11 15:52:47 Sweeper Tests ran successfully: - aws_glacier_vault ok github.com/terraform-providers/terraform-provider-aws/aws 4.070s ``` --- aws/resource_aws_glacier_vault_test.go | 62 ++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/aws/resource_aws_glacier_vault_test.go b/aws/resource_aws_glacier_vault_test.go index e97a630f973..6061ea784c1 100644 --- a/aws/resource_aws_glacier_vault_test.go +++ b/aws/resource_aws_glacier_vault_test.go @@ -2,16 +2,78 @@ package aws import ( "fmt" + "log" "testing" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/glacier" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" ) +func init() { + resource.AddTestSweepers("aws_glacier_vault", &resource.Sweeper{ + Name: "aws_glacier_vault", + F: testSweepGlacierVaults, + }) +} + +func testSweepGlacierVaults(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).glacierconn + var sweeperErrs *multierror.Error + + err = conn.ListVaultsPages(&glacier.ListVaultsInput{}, func(page *glacier.ListVaultsOutput, isLast bool) bool { + if page == nil { + return !isLast + } + + for _, vault := range page.VaultList { + name := aws.StringValue(vault.VaultName) + + // First attempt to delete the vault's notification configuration in case the vault deletion fails. + log.Printf("[INFO] Deleting Glacier Vault (%s) Notifications", name) + _, err := conn.DeleteVaultNotifications(&glacier.DeleteVaultNotificationsInput{ + VaultName: aws.String(name), + }) + if err != nil { + sweeperErr := fmt.Errorf("error deleting Glacier Vault (%s) Notifications: %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + + log.Printf("[INFO] Deleting Glacier Vault: %s", name) + _, err = conn.DeleteVault(&glacier.DeleteVaultInput{ + VaultName: aws.String(name), + }) + if err != nil { + sweeperErr := fmt.Errorf("error deleting Glacier Vault (%s): %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + return !isLast + }) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping Glacier Vaults sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving Glacier Vaults: %w", err)) + } + + return sweeperErrs.ErrorOrNil() +} + func TestAccAWSGlacierVault_basic(t *testing.T) { rInt := acctest.RandInt() resourceName := "aws_glacier_vault.test" From 5e80d7899afcde9195c652bbd392450a6f2690ec Mon Sep 17 00:00:00 2001 From: Pascal van Buijtene Date: Mon, 11 May 2020 21:58:12 +0200 Subject: [PATCH 102/475] Remove error message condition --- aws/resource_aws_wafv2_ip_set.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_wafv2_ip_set.go b/aws/resource_aws_wafv2_ip_set.go index 6c95d656642..1daebf2fc49 100644 --- a/aws/resource_aws_wafv2_ip_set.go +++ b/aws/resource_aws_wafv2_ip_set.go @@ -151,7 +151,7 @@ func resourceAwsWafv2IPSetRead(d *schema.ResourceData, meta interface{}) error { resp, err := conn.GetIPSet(params) if err != nil { - if isAWSErr(err, wafv2.ErrCodeWAFNonexistentItemException, "AWS WAF couldn’t perform the operation because your resource doesn’t exist") { + if isAWSErr(err, wafv2.ErrCodeWAFNonexistentItemException, "") { log.Printf("[WARN] WAFv2 IPSet (%s) not found, removing from state", d.Id()) d.SetId("") return nil @@ -235,7 +235,7 @@ func resourceAwsWafv2IPSetDelete(d *schema.ResourceData, meta interface{}) error var err error _, err = conn.DeleteIPSet(params) if err != nil { - if isAWSErr(err, wafv2.ErrCodeWAFAssociatedItemException, "AWS WAF couldn’t perform the operation because your resource is being used by another resource or it’s associated with another resource") { + if isAWSErr(err, wafv2.ErrCodeWAFAssociatedItemException, "") { return resource.RetryableError(err) } return resource.NonRetryableError(err) From 8f83bb20e193d6b67799ce3d4d812f3fef463ae6 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 11 May 2020 16:57:10 -0400 Subject: [PATCH 103/475] tests/resource/aws_ses_receipt_rule_set: Add sweeper (#13169) Output from sweeper in AWS Commercial: ``` 2020/05/11 16:56:04 [DEBUG] Running Sweepers for region (us-west-2): 2020/05/11 16:56:04 [DEBUG] Running Sweeper (aws_ses_receipt_rule_set) in region (us-west-2) ... 2020/05/11 16:56:07 [INFO] Disabling any currently active SES Receipt Rule Set 2020/05/11 16:56:07 Sweeper Tests ran successfully: - aws_ses_receipt_rule_set 2020/05/11 16:56:07 [DEBUG] Running Sweepers for region (us-east-1): 2020/05/11 16:56:07 [DEBUG] Running Sweeper (aws_ses_receipt_rule_set) in region (us-east-1) ... 2020/05/11 16:56:09 [INFO] Disabling any currently active SES Receipt Rule Set 2020/05/11 16:56:09 Sweeper Tests ran successfully: - aws_ses_receipt_rule_set ok github.com/terraform-providers/terraform-provider-aws/aws 7.008s ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/11 16:56:19 [DEBUG] Running Sweepers for region (us-gov-west-1): 2020/05/11 16:56:19 [DEBUG] Running Sweeper (aws_ses_receipt_rule_set) in region (us-gov-west-1) ... 2020/05/11 16:56:22 [INFO] Disabling any currently active SES Receipt Rule Set 2020/05/11 16:56:22 [WARN] Skipping SES Receipt Rule Sets sweep for us-gov-west-1: InvalidAction: Unavailable Operation status code: 400, request id: 6b002f42-d212-49a1-9c4d-bb88eab5a319 2020/05/11 16:56:22 Sweeper Tests ran successfully: - aws_ses_receipt_rule_set ok github.com/terraform-providers/terraform-provider-aws/aws 3.653s ``` --- aws/provider_test.go | 4 ++ aws/resource_aws_ses_receipt_rule_set_test.go | 69 +++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/aws/provider_test.go b/aws/provider_test.go index c59e7a202e8..cb69efd2e09 100644 --- a/aws/provider_test.go +++ b/aws/provider_test.go @@ -692,6 +692,10 @@ func testSweepSkipSweepError(err error) bool { if isAWSErr(err, "InvalidAction", "is not valid") { return true } + // For example from GovCloud SES.SetActiveReceiptRuleSet. + if isAWSErr(err, "InvalidAction", "Unavailable Operation") { + return true + } return false } diff --git a/aws/resource_aws_ses_receipt_rule_set_test.go b/aws/resource_aws_ses_receipt_rule_set_test.go index 7ed8dabea9b..d6f7b662da5 100644 --- a/aws/resource_aws_ses_receipt_rule_set_test.go +++ b/aws/resource_aws_ses_receipt_rule_set_test.go @@ -2,15 +2,84 @@ package aws import ( "fmt" + "log" "testing" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ses" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" ) +func init() { + resource.AddTestSweepers("aws_ses_receipt_rule_set", &resource.Sweeper{ + Name: "aws_ses_receipt_rule_set", + F: testSweepSesReceiptRuleSets, + }) +} + +func testSweepSesReceiptRuleSets(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).sesconn + + // You cannot delete the receipt rule set that is currently active. + // Setting the name of the receipt rule set to make active to null disables all email receiving. + log.Printf("[INFO] Disabling any currently active SES Receipt Rule Set") + _, err = conn.SetActiveReceiptRuleSet(&ses.SetActiveReceiptRuleSetInput{}) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping SES Receipt Rule Sets sweep for %s: %s", region, err) + return nil + } + if err != nil { + return fmt.Errorf("error disabling any currently active SES Receipt Rule Set: %w", err) + } + + input := &ses.ListReceiptRuleSetsInput{} + var sweeperErrs *multierror.Error + + for { + output, err := conn.ListReceiptRuleSets(input) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping SES Receipt Rule Sets sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving SES Receipt Rule Sets: %w", err)) + return sweeperErrs + } + + for _, ruleSet := range output.RuleSets { + name := aws.StringValue(ruleSet.Name) + + log.Printf("[INFO] Deleting SES Receipt Rule Set: %s", name) + _, err := conn.DeleteReceiptRuleSet(&ses.DeleteReceiptRuleSetInput{ + RuleSetName: aws.String(name), + }) + if isAWSErr(err, ses.ErrCodeRuleSetDoesNotExistException, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error deleting SES Receipt Rule Set (%s): %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + if aws.StringValue(output.NextToken) == "" { + break + } + input.NextToken = output.NextToken + } + + return sweeperErrs.ErrorOrNil() +} + func TestAccAWSSESReceiptRuleSet_basic(t *testing.T) { resourceName := "aws_ses_receipt_rule_set.test" rName := acctest.RandomWithPrefix("tf-acc-test") From 8d5ecae7bccb5b4cea2ad21d53241b1869122f3c Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Mon, 11 May 2020 14:10:47 -0700 Subject: [PATCH 104/475] Updates Kinesis Firehose acceptance tests to use ARN testing check functions --- aws/resource_aws_kinesis_firehose_delivery_stream_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/aws/resource_aws_kinesis_firehose_delivery_stream_test.go b/aws/resource_aws_kinesis_firehose_delivery_stream_test.go index 099f901f27b..2314de76a7e 100644 --- a/aws/resource_aws_kinesis_firehose_delivery_stream_test.go +++ b/aws/resource_aws_kinesis_firehose_delivery_stream_test.go @@ -762,6 +762,7 @@ func TestAccAWSKinesisFirehoseDeliveryStream_ExtendedS3KmsKeyArn(t *testing.T) { testAccCheckKinesisFirehoseDeliveryStreamExists(resourceName, &stream), testAccCheckAWSKinesisFirehoseDeliveryStreamAttributes(&stream, nil, nil, nil, nil, nil), resource.TestMatchResourceAttr(resourceName, "extended_s3_configuration.0.kms_key_arn", regexp.MustCompile(`^arn:[^:]+:kms:[^:]+:[^:]+:key/.+$`)), + resource.TestCheckResourceAttrPair(resourceName, "extended_s3_configuration.0.kms_key_arn", "aws_kms_key.test", "arn"), ), }, { From fa1ac3af9e453fa885bd0e1e190b2921b35eeff6 Mon Sep 17 00:00:00 2001 From: Ilia Lazebnik Date: Tue, 12 May 2020 00:32:12 +0300 Subject: [PATCH 105/475] return original arn in parsing error --- aws/resource_aws_iam_saml_provider.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_iam_saml_provider.go b/aws/resource_aws_iam_saml_provider.go index 41f8213ad42..d33c5a89c72 100644 --- a/aws/resource_aws_iam_saml_provider.go +++ b/aws/resource_aws_iam_saml_provider.go @@ -120,7 +120,7 @@ func resourceAwsIamSamlProviderDelete(d *schema.ResourceData, meta interface{}) func extractNameFromIAMSamlProviderArn(samlArn string) (string, error) { parsedArn, err := arn.Parse(samlArn) if err != nil { - return "", fmt.Errorf("Unable to extract name from a given ARN: %q", parsedArn) + return "", fmt.Errorf("Unable to extract name from a given ARN: %q", samlArn) } name := strings.TrimPrefix(parsedArn.Resource, "saml-provider/") From c818bd09670a873f3a6d41ca89e63f19fd037392 Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Mon, 11 May 2020 14:40:53 -0700 Subject: [PATCH 106/475] Updates Organizations acceptance tests to use ARN testing check functions Addresses: aws/resource_aws_organizations_policy_test.go:31:6: AWSAT001: prefer resource.TestCheckResourceAttrPair() or ARN check functions (e.g. testAccMatchResourceAttrRegionalARN) --- aws/resource_aws_organizations_policy_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/aws/resource_aws_organizations_policy_test.go b/aws/resource_aws_organizations_policy_test.go index e0d8b9d829b..3fde24bbbc4 100644 --- a/aws/resource_aws_organizations_policy_test.go +++ b/aws/resource_aws_organizations_policy_test.go @@ -29,6 +29,7 @@ func testAccAwsOrganizationsPolicy_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckAwsOrganizationsPolicyExists(resourceName, &policy), resource.TestMatchResourceAttr(resourceName, "arn", regexp.MustCompile(`^arn:[^:]+:organizations::[^:]+:policy/o-.+/service_control_policy/p-.+$`)), + testAccMatchResourceAttrGlobalARN(resourceName, "arn", "organizations", regexp.MustCompile("policy/o-.+/service_control_policy/p-.+$")), resource.TestCheckResourceAttr(resourceName, "content", content1), resource.TestCheckResourceAttr(resourceName, "description", ""), resource.TestCheckResourceAttr(resourceName, "name", rName), From 63534025495e1b42e5f8ed4485d298769a73a683 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 11 May 2020 18:20:20 -0400 Subject: [PATCH 107/475] tests/resource/aws_kinesis_analytics_application: Add sweeper (#13153) Output from sweeper in AWS Commercial: ``` 2020/05/11 18:18:54 [DEBUG] Running Sweepers for region (us-west-2): 2020/05/11 18:18:54 [DEBUG] Running Sweeper (aws_kinesis_analytics_application) in region (us-west-2) ... 2020/05/11 18:18:57 [INFO] Deleting Kinesis Analytics Application: testAcc-4080158281457541086 2020/05/11 18:18:57 [DEBUG] Waiting for state to become: [NotFound] 2020/05/11 18:18:59 [INFO] Deleting Kinesis Analytics Application: testAcc-4842219764002843260 2020/05/11 18:18:59 [DEBUG] Waiting for state to become: [NotFound] 2020/05/11 18:19:00 [INFO] Deleting Kinesis Analytics Application: testAcc-5293425581687425252 2020/05/11 18:19:00 [DEBUG] Waiting for state to become: [NotFound] 2020/05/11 18:19:02 [INFO] Deleting Kinesis Analytics Application: testAcc-9212510978665833895 2020/05/11 18:19:02 [DEBUG] Waiting for state to become: [NotFound] 2020/05/11 18:19:03 Sweeper Tests ran successfully: - aws_kinesis_analytics_application 2020/05/11 18:19:03 [DEBUG] Running Sweepers for region (us-east-1): 2020/05/11 18:19:03 [DEBUG] Running Sweeper (aws_kinesis_analytics_application) in region (us-east-1) ... 2020/05/11 18:19:05 Sweeper Tests ran successfully: - aws_kinesis_analytics_application ok github.com/terraform-providers/terraform-provider-aws/aws 13.084s ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/11 18:19:15 [DEBUG] Running Sweepers for region (us-gov-west-1): 2020/05/11 18:19:15 [DEBUG] Running Sweeper (aws_kinesis_analytics_application) in region (us-gov-west-1) ... 2020/05/11 18:19:18 [WARN] Skipping Kinesis Analytics Application sweep for us-gov-west-1: AccessDeniedException: status code: 400, request id: 2f8867f6-da5b-4f81-807f-fae53353bae1 2020/05/11 18:19:18 Sweeper Tests ran successfully: - aws_kinesis_analytics_application ok github.com/terraform-providers/terraform-provider-aws/aws 3.316s ``` --- .../service/kinesisanalytics/waiter/status.go | 38 ++++++++ .../service/kinesisanalytics/waiter/waiter.go | 31 +++++++ aws/resource_aws_cloudwatch_log_group_test.go | 2 +- ..._aws_kinesis_analytics_application_test.go | 87 +++++++++++++++++++ 4 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 aws/internal/service/kinesisanalytics/waiter/status.go create mode 100644 aws/internal/service/kinesisanalytics/waiter/waiter.go diff --git a/aws/internal/service/kinesisanalytics/waiter/status.go b/aws/internal/service/kinesisanalytics/waiter/status.go new file mode 100644 index 00000000000..3620aa6455b --- /dev/null +++ b/aws/internal/service/kinesisanalytics/waiter/status.go @@ -0,0 +1,38 @@ +package waiter + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/kinesisanalytics" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +const ( + // ApplicationStatus NotFound + ApplicationStatusNotFound = "NotFound" + + // ApplicationStatus Unknown + ApplicationStatusUnknown = "Unknown" +) + +// ApplicationStatus fetches the Application and its Status +func ApplicationStatus(conn *kinesisanalytics.KinesisAnalytics, applicationName string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + input := &kinesisanalytics.DescribeApplicationInput{ + ApplicationName: aws.String(applicationName), + } + + output, err := conn.DescribeApplication(input) + + if err != nil { + return nil, ApplicationStatusUnknown, err + } + + application := output.ApplicationDetail + + if application == nil { + return application, ApplicationStatusNotFound, nil + } + + return application, aws.StringValue(application.ApplicationStatus), nil + } +} diff --git a/aws/internal/service/kinesisanalytics/waiter/waiter.go b/aws/internal/service/kinesisanalytics/waiter/waiter.go new file mode 100644 index 00000000000..240de251295 --- /dev/null +++ b/aws/internal/service/kinesisanalytics/waiter/waiter.go @@ -0,0 +1,31 @@ +package waiter + +import ( + "time" + + "github.com/aws/aws-sdk-go/service/kinesisanalytics" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +const ( + // Maximum amount of time to wait for an Application to be deleted + ApplicationDeletedTimeout = 20 * time.Minute +) + +// ApplicationDeleted waits for an Application to be deleted +func ApplicationDeleted(conn *kinesisanalytics.KinesisAnalytics, applicationName string) (*kinesisanalytics.ApplicationSummary, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{kinesisanalytics.ApplicationStatusRunning, kinesisanalytics.ApplicationStatusDeleting}, + Target: []string{ApplicationStatusNotFound}, + Refresh: ApplicationStatus(conn, applicationName), + Timeout: ApplicationDeletedTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if v, ok := outputRaw.(*kinesisanalytics.ApplicationSummary); ok { + return v, err + } + + return nil, err +} diff --git a/aws/resource_aws_cloudwatch_log_group_test.go b/aws/resource_aws_cloudwatch_log_group_test.go index 76b616b87f8..040d0ff1169 100644 --- a/aws/resource_aws_cloudwatch_log_group_test.go +++ b/aws/resource_aws_cloudwatch_log_group_test.go @@ -30,7 +30,7 @@ func init() { "aws_elasticsearch_domain", // Not currently implemented: "aws_flow_log", "aws_glue_job", - // Not currently implemented: "aws_kinesis_analytics_application", + "aws_kinesis_analytics_application", "aws_kinesis_firehose_delivery_stream", "aws_lambda_function", "aws_mq_broker", diff --git a/aws/resource_aws_kinesis_analytics_application_test.go b/aws/resource_aws_kinesis_analytics_application_test.go index 36bf1348106..1ae5e8c1bc2 100644 --- a/aws/resource_aws_kinesis_analytics_application_test.go +++ b/aws/resource_aws_kinesis_analytics_application_test.go @@ -2,15 +2,102 @@ package aws import ( "fmt" + "log" "testing" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/kinesisanalytics" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/kinesisanalytics/waiter" ) +func init() { + resource.AddTestSweepers("aws_kinesis_analytics_application", &resource.Sweeper{ + Name: "aws_kinesis_analytics_application", + F: testSweepKinesisAnalyticsApplications, + }) +} + +func testSweepKinesisAnalyticsApplications(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).kinesisanalyticsconn + input := &kinesisanalytics.ListApplicationsInput{} + var sweeperErrs *multierror.Error + + for { + output, err := conn.ListApplications(input) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping Kinesis Analytics Application sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving Kinesis Analytics Applications: %w", err)) + return sweeperErrs + } + + var name string + for _, applicationSummary := range output.ApplicationSummaries { + name = aws.StringValue(applicationSummary.ApplicationName) + + output, err := conn.DescribeApplication(&kinesisanalytics.DescribeApplicationInput{ + ApplicationName: aws.String(name), + }) + if isAWSErr(err, kinesisanalytics.ErrCodeResourceNotFoundException, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error describing Kinesis Analytics Application (%s): %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + + if output.ApplicationDetail == nil { + continue + } + + log.Printf("[INFO] Deleting Kinesis Analytics Application: %s", name) + _, err = conn.DeleteApplication(&kinesisanalytics.DeleteApplicationInput{ + ApplicationName: aws.String(name), + CreateTimestamp: output.ApplicationDetail.CreateTimestamp, + }) + if isAWSErr(err, kinesisanalytics.ErrCodeResourceNotFoundException, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error deleting Kinesis Analytics Application (%s): %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + + _, err = waiter.ApplicationDeleted(conn, name) + if isAWSErr(err, kinesisanalytics.ErrCodeResourceNotFoundException, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error waiting for Kinesis Analytics Application (%s) to be deleted: %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + if !aws.BoolValue(output.HasMoreApplications) { + break + } + input.ExclusiveStartApplicationName = aws.String(name) + } + + return sweeperErrs.ErrorOrNil() +} + func TestAccAWSKinesisAnalyticsApplication_basic(t *testing.T) { var application kinesisanalytics.ApplicationDetail resName := "aws_kinesis_analytics_application.test" From 8f50831fd5b558113abe703feb470d17178a964e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 11 May 2020 18:25:04 -0400 Subject: [PATCH 108/475] tests/resource/aws_sns_platform_application: Add sweeper (#13168) Output from sweeper in AWS Commercial: ``` 2020/05/11 18:24:00 [DEBUG] Running Sweepers for region (us-west-2): 2020/05/11 18:24:00 [DEBUG] Running Sweeper (aws_sns_platform_application) in region (us-west-2) ... 2020/05/11 18:24:03 Sweeper Tests ran successfully: - aws_sns_platform_application 2020/05/11 18:24:03 [DEBUG] Running Sweepers for region (us-east-1): 2020/05/11 18:24:03 [DEBUG] Running Sweeper (aws_sns_platform_application) in region (us-east-1) ... 2020/05/11 18:24:04 Sweeper Tests ran successfully: - aws_sns_platform_application ok github.com/terraform-providers/terraform-provider-aws/aws 6.433s ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/11 18:24:15 [DEBUG] Running Sweepers for region (us-gov-west-1): 2020/05/11 18:24:15 [DEBUG] Running Sweeper (aws_sns_platform_application) in region (us-gov-west-1) ... 2020/05/11 18:24:17 Sweeper Tests ran successfully: - aws_sns_platform_application ok github.com/terraform-providers/terraform-provider-aws/aws 3.435s ``` --- ...ource_aws_sns_platform_application_test.go | 58 ++++++++++++++++++- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/aws/resource_aws_sns_platform_application_test.go b/aws/resource_aws_sns_platform_application_test.go index 7fc9ed4cce8..960d976a89a 100644 --- a/aws/resource_aws_sns_platform_application_test.go +++ b/aws/resource_aws_sns_platform_application_test.go @@ -9,14 +9,66 @@ import ( "strings" "testing" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/sns" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/sns" ) +func init() { + resource.AddTestSweepers("aws_sns_platform_application", &resource.Sweeper{ + Name: "aws_sns_platform_application", + F: testSweepSnsPlatformApplications, + }) +} + +func testSweepSnsPlatformApplications(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).snsconn + var sweeperErrs *multierror.Error + + err = conn.ListPlatformApplicationsPages(&sns.ListPlatformApplicationsInput{}, func(page *sns.ListPlatformApplicationsOutput, isLast bool) bool { + if page == nil { + return !isLast + } + + for _, platformApplication := range page.PlatformApplications { + arn := aws.StringValue(platformApplication.PlatformApplicationArn) + + log.Printf("[INFO] Deleting SNS Platform Application: %s", arn) + _, err := conn.DeletePlatformApplication(&sns.DeletePlatformApplicationInput{ + PlatformApplicationArn: aws.String(arn), + }) + if isAWSErr(err, sns.ErrCodeNotFoundException, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error deleting SNS Platform Application (%s): %w", arn, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + return !isLast + }) + + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping SNS Platform Applications sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving SNS Platform Applications: %w", err)) + } + + return sweeperErrs.ErrorOrNil() +} + /** Before running this test, at least one of these ENV variables combinations must be set: From d639e9dd15017316c3afc2f26ff3e79ee15bcc83 Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Mon, 11 May 2020 15:28:31 -0700 Subject: [PATCH 109/475] Updates IOT acceptance tests to use ARN testing check functions Addresses: aws/resource_aws_iot_role_alias_test.go:65:6: AWSAT001: prefer resource.TestCheckResourceAttrPair() or ARN check functions (e.g. testAccMatchResourceAttrRegionalARN) --- aws/resource_aws_iot_role_alias_test.go | 35 ++++++++++++------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/aws/resource_aws_iot_role_alias_test.go b/aws/resource_aws_iot_role_alias_test.go index 087574c660f..ea321d97fa9 100644 --- a/aws/resource_aws_iot_role_alias_test.go +++ b/aws/resource_aws_iot_role_alias_test.go @@ -15,6 +15,9 @@ func TestAccAWSIotRoleAlias_basic(t *testing.T) { alias := acctest.RandomWithPrefix("RoleAlias-") alias2 := acctest.RandomWithPrefix("RoleAlias2-") + resourceName := "aws_iot_role_alias.ra" + resourceName2 := "aws_iot_role_alias.ra2" + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -23,51 +26,47 @@ func TestAccAWSIotRoleAlias_basic(t *testing.T) { { Config: testAccAWSIotRoleAliasConfig(alias), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIotRoleAliasExists("aws_iot_role_alias.ra"), - testAccCheckResourceAttrRegionalARN("aws_iot_role_alias.ra", "arn", "iot", fmt.Sprintf("rolealias/%s", alias)), - resource.TestCheckResourceAttr( - "aws_iot_role_alias.ra", "credential_duration", "3600"), + testAccCheckAWSIotRoleAliasExists(resourceName), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "iot", fmt.Sprintf("rolealias/%s", alias)), + resource.TestCheckResourceAttr(resourceName, "credential_duration", "3600"), ), }, { Config: testAccAWSIotRoleAliasConfigUpdate1(alias, alias2), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIotRoleAliasExists("aws_iot_role_alias.ra"), - testAccCheckAWSIotRoleAliasExists("aws_iot_role_alias.ra2"), - testAccCheckResourceAttrRegionalARN("aws_iot_role_alias.ra", "arn", "iot", fmt.Sprintf("rolealias/%s", alias)), - resource.TestCheckResourceAttr( - "aws_iot_role_alias.ra", "credential_duration", "1800"), + testAccCheckAWSIotRoleAliasExists(resourceName), + testAccCheckAWSIotRoleAliasExists(resourceName2), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "iot", fmt.Sprintf("rolealias/%s", alias)), + resource.TestCheckResourceAttr(resourceName, "credential_duration", "1800"), ), }, { Config: testAccAWSIotRoleAliasConfigUpdate2(alias2), - Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIotRoleAliasExists("aws_iot_role_alias.ra2"), - ), + Check: resource.ComposeTestCheckFunc(testAccCheckAWSIotRoleAliasExists(resourceName2)), }, { Config: testAccAWSIotRoleAliasConfigUpdate3(alias2), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIotRoleAliasExists("aws_iot_role_alias.ra2"), + testAccCheckAWSIotRoleAliasExists(resourceName2), ), ExpectError: regexp.MustCompile("Role alias .+? already exists for this account"), }, { Config: testAccAWSIotRoleAliasConfigUpdate4(alias2), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIotRoleAliasExists("aws_iot_role_alias.ra2"), + testAccCheckAWSIotRoleAliasExists(resourceName2), ), }, { Config: testAccAWSIotRoleAliasConfigUpdate5(alias2), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIotRoleAliasExists("aws_iot_role_alias.ra2"), - resource.TestMatchResourceAttr( - "aws_iot_role_alias.ra2", "role_arn", regexp.MustCompile(".+?bogus")), + testAccCheckAWSIotRoleAliasExists(resourceName2), + resource.TestMatchResourceAttr(resourceName2, "role_arn", regexp.MustCompile(".+?bogus")), + testAccMatchResourceAttrGlobalARN(resourceName2, "role_arn", "iam", regexp.MustCompile("role/rolebogus")), ), }, { - ResourceName: "aws_iot_role_alias.ra2", + ResourceName: resourceName2, ImportState: true, ImportStateVerify: true, }, From f34c8da7c52add159ff2361390fcecfed9a425b4 Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Mon, 11 May 2020 15:31:52 -0700 Subject: [PATCH 110/475] Updates Glue acceptance tests to use ARN testing check functions Addresses: aws/resource_aws_glue_job_test.go:78:6: AWSAT001: prefer resource.TestCheckResourceAttrPair() or ARN check functions (e.g. testAccMatchResourceAttrRegionalARN) --- aws/resource_aws_glue_job_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_glue_job_test.go b/aws/resource_aws_glue_job_test.go index 065550c1b11..99c7029afe6 100644 --- a/aws/resource_aws_glue_job_test.go +++ b/aws/resource_aws_glue_job_test.go @@ -60,6 +60,7 @@ func TestAccAWSGlueJob_Basic(t *testing.T) { rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5)) resourceName := "aws_glue_job.test" + roleResourceName := "aws_iam_role.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -75,7 +76,7 @@ func TestAccAWSGlueJob_Basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "command.0.script_location", "testscriptlocation"), resource.TestCheckResourceAttr(resourceName, "default_arguments.%", "0"), resource.TestCheckResourceAttr(resourceName, "name", rName), - resource.TestMatchResourceAttr(resourceName, "role_arn", regexp.MustCompile(fmt.Sprintf("^arn:[^:]+:iam::[^:]+:role/%s", rName))), + resource.TestCheckResourceAttrPair(resourceName, "role_arn", roleResourceName, "arn"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), resource.TestCheckResourceAttr(resourceName, "timeout", "2880"), ), From ab7a5c97f2e44cf21a7a94e1b83d3d7b5dd4cf4a Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Mon, 11 May 2020 19:11:09 -0400 Subject: [PATCH 111/475] tests/resource/aws_route53_query_log: Skip SerializationError and AccessDeniedException for sweeper To workaround API and SDK issues in AWS GovCloud (US). Output from sweeper in AWS Commercial: ``` 2020/05/11 19:06:27 [DEBUG] Running Sweepers for region (us-west-2): 2020/05/11 19:06:27 [DEBUG] Running Sweeper (aws_route53_query_log) in region (us-west-2) ... 2020/05/11 19:06:30 Sweeper Tests ran successfully: - aws_route53_query_log 2020/05/11 19:06:30 [DEBUG] Running Sweepers for region (us-east-1): 2020/05/11 19:06:30 [DEBUG] Running Sweeper (aws_route53_query_log) in region (us-east-1) ... 2020/05/11 19:06:31 Sweeper Tests ran successfully: - aws_route53_query_log ok github.com/terraform-providers/terraform-provider-aws/aws 4.962s ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/11 19:06:42 [DEBUG] Running Sweepers for region (us-gov-west-1): 2020/05/11 19:06:42 [DEBUG] Running Sweeper (aws_route53_query_log) in region (us-gov-west-1) ... 2020/05/11 19:06:47 [WARN] Skipping Route53 query logging configurations sweep for us-gov-west-1: SerializationError: failed to unmarshal error message status code: 403, request id: 3e3de32d-ddfa-4895-9eaf-5cab66edf80f caused by: UnmarshalError: failed to unmarshal error message 00000000 3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e 3d 22 31 |.. | 00000030 3c 4d 65 73 73 61 67 65 3e 55 6e 61 62 6c 65 20 |Unable | 00000040 74 6f 20 64 65 74 65 72 6d 69 6e 65 20 73 65 72 |to determine ser| 00000050 76 69 63 65 2f 6f 70 65 72 61 74 69 6f 6e 20 6e |vice/operation n| 00000060 61 6d 65 20 74 6f 20 62 65 20 61 75 74 68 6f 72 |ame to be author| 00000070 69 7a 65 64 3c 2f 4d 65 73 73 61 67 65 3e 0a 3c |ized.<| 00000080 2f 41 63 63 65 73 73 44 65 6e 69 65 64 45 78 63 |/AccessDeniedExc| 00000090 65 70 74 69 6f 6e 3e 0a |eption>.| caused by: unknown error response tag, {{ AccessDeniedException} []} 2020/05/11 19:06:47 Sweeper Tests ran successfully: - aws_route53_query_log ok github.com/terraform-providers/terraform-provider-aws/aws 6.092s ``` --- aws/resource_aws_route53_query_log_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_route53_query_log_test.go b/aws/resource_aws_route53_query_log_test.go index 68a21d3d109..8a236e055e5 100644 --- a/aws/resource_aws_route53_query_log_test.go +++ b/aws/resource_aws_route53_query_log_test.go @@ -55,7 +55,9 @@ func testSweepRoute53QueryLogs(region string) error { return !isLast }) - if testSweepSkipSweepError(err) { + // In unsupported AWS partitions, the API may return an error even the SDK cannot handle. + // Reference: https://github.com/aws/aws-sdk-go/issues/3313 + if testSweepSkipSweepError(err) || isAWSErr(err, "SerializationError", "failed to unmarshal error message") || isAWSErr(err, "AccessDeniedException", "Unable to determine service/operation name to be authorized") { log.Printf("[WARN] Skipping Route53 query logging configurations sweep for %s: %s", region, err) return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors } From f6603e5b8e4c5b29b110e7caa9fa1c60d5ae6246 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 11 May 2020 19:24:14 -0400 Subject: [PATCH 112/475] tests/resource/aws_flow_log: Add sweeper (#13149) Output from sweeper in AWS Commercial: ``` 2020/05/11 19:22:53 [DEBUG] Running Sweepers for region (us-west-2): 2020/05/11 19:22:53 [DEBUG] Running Sweeper (aws_flow_log) in region (us-west-2) ... 2020/05/11 19:22:55 Sweeper Tests ran successfully: - aws_flow_log 2020/05/11 19:22:55 [DEBUG] Running Sweepers for region (us-east-1): 2020/05/11 19:22:55 [DEBUG] Running Sweeper (aws_flow_log) in region (us-east-1) ... 2020/05/11 19:22:57 Sweeper Tests ran successfully: - aws_flow_log ok github.com/terraform-providers/terraform-provider-aws/aws 6.513s ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/11 19:23:07 [DEBUG] Running Sweepers for region (us-gov-west-1): 2020/05/11 19:23:07 [DEBUG] Running Sweeper (aws_flow_log) in region (us-gov-west-1) ... 2020/05/11 19:23:10 Sweeper Tests ran successfully: - aws_flow_log ok github.com/terraform-providers/terraform-provider-aws/aws 3.671s ``` --- aws/resource_aws_cloudwatch_log_group_test.go | 2 +- aws/resource_aws_flow_log_test.go | 53 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_cloudwatch_log_group_test.go b/aws/resource_aws_cloudwatch_log_group_test.go index 0aaa8f6de11..cf008bf9d83 100644 --- a/aws/resource_aws_cloudwatch_log_group_test.go +++ b/aws/resource_aws_cloudwatch_log_group_test.go @@ -28,7 +28,7 @@ func init() { "aws_ec2_client_vpn_endpoint", "aws_eks_cluster", "aws_elasticsearch_domain", - // Not currently implemented: "aws_flow_log", + "aws_flow_log", "aws_glue_job", "aws_kinesis_analytics_application", "aws_kinesis_firehose_delivery_stream", diff --git a/aws/resource_aws_flow_log_test.go b/aws/resource_aws_flow_log_test.go index 44c09455775..9b5d912f930 100644 --- a/aws/resource_aws_flow_log_test.go +++ b/aws/resource_aws_flow_log_test.go @@ -2,16 +2,69 @@ package aws import ( "fmt" + "log" "regexp" "testing" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" ) +func init() { + resource.AddTestSweepers("aws_flow_log", &resource.Sweeper{ + Name: "aws_flow_log", + F: testSweepFlowLogs, + }) +} + +func testSweepFlowLogs(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).ec2conn + var sweeperErrs *multierror.Error + + err = conn.DescribeFlowLogsPages(&ec2.DescribeFlowLogsInput{}, func(page *ec2.DescribeFlowLogsOutput, isLast bool) bool { + if page == nil { + return !isLast + } + + for _, flowLog := range page.FlowLogs { + id := aws.StringValue(flowLog.FlowLogId) + + log.Printf("[INFO] Deleting Flow Log: %s", id) + _, err := conn.DeleteFlowLogs(&ec2.DeleteFlowLogsInput{ + FlowLogIds: aws.StringSlice([]string{id}), + }) + if isAWSErr(err, "InvalidFlowLogId.NotFound", "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error deleting Flow Log (%s): %w", id, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + return !isLast + }) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping Flow Logs sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving Flow Logs: %w", err)) + } + + return sweeperErrs.ErrorOrNil() +} + func TestAccAWSFlowLog_VPCID(t *testing.T) { var flowLog ec2.FlowLog cloudwatchLogGroupResourceName := "aws_cloudwatch_log_group.test" From ea88e1839110afa53b7f039295f11968b48b38b9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 11 May 2020 19:29:26 -0400 Subject: [PATCH 113/475] tests/resource/aws_cloudtrail: Add sweeper (#13150) Output from sweeper in AWS Commercial: ``` 2020/05/11 19:28:05 [DEBUG] Running Sweepers for region (us-west-2): 2020/05/11 19:28:05 [DEBUG] Running Sweeper (aws_cloudtrail) in region (us-west-2) ... 2020/05/11 19:28:09 [INFO] Deleting CloudTrail: AWSMacieTrail-DO-NOT-EDIT 2020/05/11 19:28:10 [INFO] Deleting CloudTrail: account-187416307283 2020/05/11 19:28:12 [INFO] CloudTrail (hc-org-trail) not found, skipping 2020/05/11 19:28:13 [INFO] Deleting CloudTrail: tf-trail-foobar-740692971207085083 2020/05/11 19:28:13 Sweeper Tests ran successfully: - aws_cloudtrail 2020/05/11 19:28:13 [DEBUG] Running Sweepers for region (us-east-1): 2020/05/11 19:28:13 [DEBUG] Running Sweeper (aws_cloudtrail) in region (us-east-1) ... 2020/05/11 19:28:15 [INFO] CloudTrail (hc-org-trail) not found, skipping 2020/05/11 19:28:16 [INFO] Deleting CloudTrail: tf-trail-foobar-2250818700904448419 2020/05/11 19:28:16 Sweeper Tests ran successfully: - aws_cloudtrail ok github.com/terraform-providers/terraform-provider-aws/aws 12.816s ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/11 19:28:26 [DEBUG] Running Sweepers for region (us-gov-west-1): 2020/05/11 19:28:26 [DEBUG] Running Sweeper (aws_cloudtrail) in region (us-gov-west-1) ... 2020/05/11 19:28:28 Sweeper Tests ran successfully: - aws_cloudtrail ok github.com/terraform-providers/terraform-provider-aws/aws 3.375s ``` --- aws/resource_aws_cloudtrail_test.go | 72 +++++++++++++++++++ aws/resource_aws_cloudwatch_log_group_test.go | 2 +- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_cloudtrail_test.go b/aws/resource_aws_cloudtrail_test.go index 72b518357b2..ee0786c4d10 100644 --- a/aws/resource_aws_cloudtrail_test.go +++ b/aws/resource_aws_cloudtrail_test.go @@ -9,11 +9,83 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/cloudtrail" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" ) +func init() { + resource.AddTestSweepers("aws_cloudtrail", &resource.Sweeper{ + Name: "aws_cloudtrail", + F: testSweepCloudTrails, + }) +} + +func testSweepCloudTrails(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).cloudtrailconn + var sweeperErrs *multierror.Error + + err = conn.ListTrailsPages(&cloudtrail.ListTrailsInput{}, func(page *cloudtrail.ListTrailsOutput, isLast bool) bool { + if page == nil { + return !isLast + } + + for _, trail := range page.Trails { + name := aws.StringValue(trail.Name) + + output, err := conn.DescribeTrails(&cloudtrail.DescribeTrailsInput{ + TrailNameList: aws.StringSlice([]string{name}), + }) + if err != nil { + sweeperErr := fmt.Errorf("error describing CloudTrail (%s): %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + + if len(output.TrailList) == 0 { + log.Printf("[INFO] CloudTrail (%s) not found, skipping", name) + continue + } + + if aws.BoolValue(output.TrailList[0].IsOrganizationTrail) { + log.Printf("[INFO] CloudTrail (%s) is an organization trail, skipping", name) + continue + } + + log.Printf("[INFO] Deleting CloudTrail: %s", name) + _, err = conn.DeleteTrail(&cloudtrail.DeleteTrailInput{ + Name: aws.String(name), + }) + if isAWSErr(err, cloudtrail.ErrCodeTrailNotFoundException, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error deleting CloudTrail (%s): %w", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + return !isLast + }) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping CloudTrail sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving CloudTrails: %w", err)) + } + + return sweeperErrs.ErrorOrNil() +} + func TestAccAWSCloudTrail(t *testing.T) { testCases := map[string]map[string]func(t *testing.T){ "Trail": { diff --git a/aws/resource_aws_cloudwatch_log_group_test.go b/aws/resource_aws_cloudwatch_log_group_test.go index cf008bf9d83..f48d6c68aae 100644 --- a/aws/resource_aws_cloudwatch_log_group_test.go +++ b/aws/resource_aws_cloudwatch_log_group_test.go @@ -21,7 +21,7 @@ func init() { Dependencies: []string{ "aws_api_gateway_rest_api", "aws_cloudhsm_v2_cluster", - // Not currently implemented: "aws_cloudtrail", + "aws_cloudtrail", "aws_datasync_task", "aws_db_instance", "aws_directory_service_directory", From 7df13d0f8c9801b5c3e11b700dca798e7e0670fb Mon Sep 17 00:00:00 2001 From: Micheal Harker Date: Tue, 12 May 2020 00:36:33 +0100 Subject: [PATCH 114/475] tests/resource/aws_ecr_repository: Implement sweeper (#12834) Output from sweeper in AWS Commercial: ``` 2020/05/11 19:35:10 [DEBUG] Running Sweepers for region (us-west-2): 2020/05/11 19:35:10 [DEBUG] Running Sweeper (aws_ecr_repository) in region (us-west-2) ... 2020/05/11 19:35:12 [INFO] Deleting ECR repository: tf-acc-test-ecr-jynnb8fr46 2020/05/11 19:35:13 [INFO] Deleting ECR repository: tf-acc-test-lifecycle-eynj6yvxr7 2020/05/11 19:35:13 [INFO] Deleting ECR repository: tf-acc-test-lifecycle-8c7g6nd8fe 2020/05/11 19:35:13 [INFO] Deleting ECR repository: tf-acc-test-ecr-xkk8bx2mxz 2020/05/11 19:35:14 [INFO] Deleting ECR repository: tf-acc-test-lifecycle-fmlgi1nwzb 2020/05/11 19:35:14 [INFO] Deleting ECR repository: tf-acc-test-lifecycle-vm96ysp8bc 2020/05/11 19:35:15 [INFO] Deleting ECR repository: tf-acc-test-ecr-ba2v8fhova 2020/05/11 19:35:15 [INFO] Deleting ECR repository: tf-acc-test-6050143170194165363 2020/05/11 19:35:16 [INFO] Deleting ECR repository: tf-acc-test-ecr-ff08cszgny 2020/05/11 19:35:16 [INFO] Deleting ECR repository: tf-acc-test-ecr-se3ehbyrhb 2020/05/11 19:35:16 [INFO] Deleting ECR repository: tf-acc-test-6889266986464638074 2020/05/11 19:35:17 [INFO] Deleting ECR repository: tf-acc-test-ecr-o2t30n9cnx 2020/05/11 19:35:17 [INFO] Deleting ECR repository: bar 2020/05/11 19:35:18 [INFO] Deleting ECR repository: tf-acc-test-ecr-04h02y7eg3 2020/05/11 19:35:18 [INFO] Deleting ECR repository: tf-acc-test-4382088656668134051 2020/05/11 19:35:19 [INFO] Deleting ECR repository: tf-acc-test-lifecycle-i7l3dvpph9 2020/05/11 19:35:19 [INFO] Deleting ECR repository: tf-acc-test-1524363012416375905 2020/05/11 19:35:19 Sweeper Tests ran successfully: - aws_ecr_repository 2020/05/11 19:35:19 [DEBUG] Running Sweepers for region (us-east-1): 2020/05/11 19:35:19 [DEBUG] Running Sweeper (aws_ecr_repository) in region (us-east-1) ... 2020/05/11 19:35:21 [INFO] Deleting ECR repository: tf-acc-test-ecr-1lkbnobdkl 2020/05/11 19:35:21 [INFO] Deleting ECR repository: tf-acc-test-ecr-q3ungwfsrb 2020/05/11 19:35:21 Sweeper Tests ran successfully: - aws_ecr_repository ok github.com/terraform-providers/terraform-provider-aws/aws 14.934s ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/11 19:35:32 [DEBUG] Running Sweepers for region (us-gov-west-1): 2020/05/11 19:35:32 [DEBUG] Running Sweeper (aws_ecr_repository) in region (us-gov-west-1) ... 2020/05/11 19:35:35 Sweeper Tests ran successfully: - aws_ecr_repository ok github.com/terraform-providers/terraform-provider-aws/aws 4.519s ``` --- aws/resource_aws_ecr_repository_test.go | 56 +++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/aws/resource_aws_ecr_repository_test.go b/aws/resource_aws_ecr_repository_test.go index 3c54a6476cb..a0bd6dfb695 100644 --- a/aws/resource_aws_ecr_repository_test.go +++ b/aws/resource_aws_ecr_repository_test.go @@ -2,15 +2,71 @@ package aws import ( "fmt" + "log" "testing" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ecr" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" ) +func init() { + resource.AddTestSweepers("aws_ecr_repository", &resource.Sweeper{ + Name: "aws_ecr_repository", + F: testSweepEcrRepositories, + }) +} + +func testSweepEcrRepositories(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).ecrconn + + var errors error + err = conn.DescribeRepositoriesPages(&ecr.DescribeRepositoriesInput{}, func(page *ecr.DescribeRepositoriesOutput, isLast bool) bool { + if page == nil { + return !isLast + } + + for _, repository := range page.Repositories { + repositoryName := aws.StringValue(repository.RepositoryName) + log.Printf("[INFO] Deleting ECR repository: %s", repositoryName) + + shouldForce := true + _, err = conn.DeleteRepository(&ecr.DeleteRepositoryInput{ + // We should probably sweep repositories even if there are images. + Force: &shouldForce, + RegistryId: repository.RegistryId, + RepositoryName: repository.RepositoryName, + }) + if err != nil { + if !isAWSErr(err, ecr.ErrCodeRepositoryNotFoundException, "") { + sweeperErr := fmt.Errorf("Error deleting ECR repository (%s): %w", repositoryName, err) + log.Printf("[ERROR] %s", sweeperErr) + errors = multierror.Append(errors, sweeperErr) + } + continue + } + } + + return !isLast + }) + if err != nil { + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping ECR repository sweep for %s: %s", region, err) + return nil + } + errors = multierror.Append(errors, fmt.Errorf("Error retreiving ECR repositories: %w", err)) + } + + return errors +} + func TestAccAWSEcrRepository_basic(t *testing.T) { rName := acctest.RandomWithPrefix("tf-acc-test") resourceName := "aws_ecr_repository.default" From 7fc1f5942794d2386b88945f3823f09e3199a6e8 Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Mon, 11 May 2020 17:22:22 -0700 Subject: [PATCH 115/475] remove GoReport --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 8f685f06e21..ae3c4c3fa90 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,11 @@ [![Build Status][travis-badge]][travis] [![Forums][discuss-badge]][discuss] -[![GoReportCard][report-badge]][report] [travis-badge]: https://api.travis-ci.org/terraform-providers/terraform-provider-aws.svg?branch=master [travis]: https://travis-ci.org/github/terraform-providers/terraform-provider-aws [discuss-badge]: https://img.shields.io/badge/discuss-terraform--aws-623CE4.svg?style=flat [discuss]: https://discuss.hashicorp.com/c/terraform-providers/tf-aws/ -[report-badge]: https://goreportcard.com/badge/github.com/terraform-providers/terraform-provider-aws -[report]: https://goreportcard.com/report/github.com/terraform-providers/terraform-provider-aws - - Website: [terraform.io](https://terraform.io) - Tutorials: [learn.hashicorp.com](https://learn.hashicorp.com/terraform?track=getting-started#getting-started) From db1de8d3574c2e80e6f679dfaf8cda7448dbfdde Mon Sep 17 00:00:00 2001 From: Kevin Tham Date: Mon, 11 May 2020 18:23:46 -0700 Subject: [PATCH 116/475] Remove extraneous lines in acc test --- aws/resource_aws_security_group_rule_test.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/aws/resource_aws_security_group_rule_test.go b/aws/resource_aws_security_group_rule_test.go index 213e7c9d59a..12faae390ad 100644 --- a/aws/resource_aws_security_group_rule_test.go +++ b/aws/resource_aws_security_group_rule_test.go @@ -170,12 +170,6 @@ func TestAccAWSSecurityGroupRule_Ingress_Source_With_Account_Id(t *testing.T) { testAccCheckAWSSecurityGroupRuleExists("aws_security_group.web", &group), ), }, - // Ensure plan shows no difference after state is refreshed - { - Config: testAccAWSSecurityGroupRule_Ingress_Source_with_AccountId(rInt), - PlanOnly: true, - ExpectNonEmptyPlan: false, - }, }, }) } From e9b33d48247d3ace6917e2a38eb390cc3aa50103 Mon Sep 17 00:00:00 2001 From: Kevin Tham Date: Mon, 11 May 2020 18:44:17 -0700 Subject: [PATCH 117/475] Add nil check for s.UserId parameter --- aws/resource_aws_security_group_rule.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aws/resource_aws_security_group_rule.go b/aws/resource_aws_security_group_rule.go index d727c6802b7..4529116f503 100644 --- a/aws/resource_aws_security_group_rule.go +++ b/aws/resource_aws_security_group_rule.go @@ -763,9 +763,9 @@ func setFromIPPerm(d *schema.ResourceData, sg *ec2.SecurityGroup, rule *ec2.IpPe sgIdComponents := strings.Split(existingSourceSgId.(string), "/") hasAccountIdPrefix := len(sgIdComponents) == 2 - if hasAccountIdPrefix { - // then ensure on refresh that we prefix the account id - d.Set("source_security_group_id", *s.UserId+"/"+*s.GroupId) + if hasAccountIdPrefix && s.UserId != nil { + // then ensure on refresh that we preserve the account id prefix + d.Set("source_security_group_id", fmt.Sprintf("%s/%s", aws.StringValue(s.UserId), aws.StringValue(s.GroupId))) } else { d.Set("source_security_group_id", s.GroupId) } From b7291e36c387c3126cfb168fee43b7c4818cfefb Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Mon, 11 May 2020 21:41:48 -0700 Subject: [PATCH 118/475] Fixes ENI deletion by ensuring service role has the needed policy --- aws/resource_aws_subnet.go | 2 +- aws/resource_aws_workspaces_workspace.go | 4 +- aws/resource_aws_workspaces_workspace_test.go | 150 +++++++++--------- .../docs/r/workspaces_workspace.html.markdown | 3 + 4 files changed, 83 insertions(+), 76 deletions(-) diff --git a/aws/resource_aws_subnet.go b/aws/resource_aws_subnet.go index 52ee954b1ef..6d75dcc2e33 100644 --- a/aws/resource_aws_subnet.go +++ b/aws/resource_aws_subnet.go @@ -398,7 +398,7 @@ func resourceAwsSubnetDelete(d *schema.ResourceData, meta interface{}) error { } if _, err := wait.WaitForState(); err != nil { - return fmt.Errorf("Error deleting subnet: %s", err) + return fmt.Errorf("error deleting subnet (%s): %s", d.Id(), err) } return nil diff --git a/aws/resource_aws_workspaces_workspace.go b/aws/resource_aws_workspaces_workspace.go index 0be6179f204..34ab2eb4d09 100644 --- a/aws/resource_aws_workspaces_workspace.go +++ b/aws/resource_aws_workspaces_workspace.go @@ -326,10 +326,10 @@ func workspaceDelete(id string, conn *workspaces.WorkSpaces) error { workspaces.WorkspaceStateUpdating, workspaces.WorkspaceStateStopping, workspaces.WorkspaceStateStopped, + workspaces.WorkspaceStateTerminating, workspaces.WorkspaceStateError, }, Target: []string{ - workspaces.WorkspaceStateTerminating, workspaces.WorkspaceStateTerminated, }, Refresh: workspaceRefreshStateFunc(conn, id), @@ -425,7 +425,7 @@ func workspaceRefreshStateFunc(conn *workspaces.WorkSpaces, workspaceID string) return nil, workspaces.WorkspaceStateError, err } if len(resp.Workspaces) == 0 { - return resp, workspaces.WorkspaceStateTerminated, nil + return nil, workspaces.WorkspaceStateTerminated, nil } workspace := resp.Workspaces[0] return workspace, aws.StringValue(workspace.State), nil diff --git a/aws/resource_aws_workspaces_workspace_test.go b/aws/resource_aws_workspaces_workspace_test.go index a90d9236026..e4adfb38573 100644 --- a/aws/resource_aws_workspaces_workspace_test.go +++ b/aws/resource_aws_workspaces_workspace_test.go @@ -265,86 +265,34 @@ func testAccCheckAwsWorkspacesWorkspaceExists(n string) resource.TestCheckFunc { } func testAccAwsWorkspacesWorkspaceConfig_Prerequisites() string { - return fmt.Sprintf(` -data "aws_region" "current" {} - -data "aws_availability_zones" "available" { - state = "available" -} - -locals { - region_workspaces_az_ids = { - "us-east-1" = formatlist("use1-az%%d", [2, 4, 6]) - } - - workspaces_az_ids = lookup(local.region_workspaces_az_ids, data.aws_region.current.name, data.aws_availability_zones.available.zone_ids) -} - -data "aws_vpc" "default" { - default = true -} - -data "aws_subnet" "default" { - count = length(local.workspaces_az_ids) - availability_zone_id = "${local.workspaces_az_ids[count.index]}" - default_for_az = true -} - -resource "aws_directory_service_directory" "test" { - size = "Small" - name = "tf-acctest.neverland.com" - password = "#S1ncerely" - - vpc_settings { - vpc_id = "${data.aws_vpc.default.id}" - subnet_ids = ["${data.aws_subnet.default.*.id[0]}", "${data.aws_subnet.default.*.id[1]}"] - } -} - -data "aws_iam_policy_document" "workspaces" { - statement { - actions = ["sts:AssumeRole"] - - principals { - type = "Service" - identifiers = ["workspaces.amazonaws.com"] - } - } -} - -resource "aws_iam_role" "workspaces-default" { - name = "workspaces_DefaultRole" - assume_role_policy = data.aws_iam_policy_document.workspaces.json -} - -resource "aws_iam_role_policy_attachment" "workspaces-default-service-access" { - role = aws_iam_role.workspaces-default.name - policy_arn = "arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess" -} - -resource "aws_iam_role_policy_attachment" "workspaces-default-self-service-access" { - role = aws_iam_role.workspaces-default.name - policy_arn = "arn:aws:iam::aws:policy/AmazonWorkSpacesSelfServiceAccess" -} - + return composeConfig( + testAccAwsWorkspacesDirectoryConfig_Prerequisites(""), + fmt.Sprintf(` data "aws_workspaces_bundle" "test" { bundle_id = "wsb-bh8rsxt14" # Value with Windows 10 (English) } resource "aws_workspaces_directory" "test" { - directory_id = "${aws_directory_service_directory.test.id}" + directory_id = "${aws_directory_service_directory.main.id}" } -`) +`)) } func testAccWorkspacesWorkspaceConfig() string { return testAccAwsWorkspacesWorkspaceConfig_Prerequisites() + fmt.Sprintf(` resource "aws_workspaces_workspace" "test" { - bundle_id = "${data.aws_workspaces_bundle.test.id}" + bundle_id = "${data.aws_workspaces_bundle.test.id}" directory_id = "${aws_workspaces_directory.test.id}" + # NOTE: WorkSpaces API doesn't allow creating users in the directory. # However, "Administrator"" user is always present in a bare directory. user_name = "Administrator" + + depends_on = [ + # The role "workspaces_DefaultRole" requires the policy arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess + # to create and delete the ENI that the Workspaces service creates for the Workspace + aws_iam_role_policy_attachment.workspaces-default-service-access, + ] } `) } @@ -352,8 +300,9 @@ resource "aws_workspaces_workspace" "test" { func testAccWorkspacesWorkspaceConfig_TagsA() string { return testAccAwsWorkspacesWorkspaceConfig_Prerequisites() + fmt.Sprintf(` resource "aws_workspaces_workspace" "test" { - bundle_id = "${data.aws_workspaces_bundle.test.id}" + bundle_id = "${data.aws_workspaces_bundle.test.id}" directory_id = "${aws_workspaces_directory.test.id}" + # NOTE: WorkSpaces API doesn't allow creating users in the directory. # However, "Administrator"" user is always present in a bare directory. user_name = "Administrator" @@ -362,6 +311,12 @@ resource "aws_workspaces_workspace" "test" { TerraformProviderAwsTest = true Alpha = 1 } + + depends_on = [ + # The role "workspaces_DefaultRole" requires the policy arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess + # to create and delete the ENI that the Workspaces service creates for the Workspace + aws_iam_role_policy_attachment.workspaces-default-service-access, + ] } `) } @@ -369,8 +324,9 @@ resource "aws_workspaces_workspace" "test" { func testAccWorkspacesWorkspaceConfig_TagsB() string { return testAccAwsWorkspacesWorkspaceConfig_Prerequisites() + fmt.Sprintf(` resource "aws_workspaces_workspace" "test" { - bundle_id = "${data.aws_workspaces_bundle.test.id}" + bundle_id = "${data.aws_workspaces_bundle.test.id}" directory_id = "${aws_workspaces_directory.test.id}" + # NOTE: WorkSpaces API doesn't allow creating users in the directory. # However, "Administrator"" user is always present in a bare directory. user_name = "Administrator" @@ -379,6 +335,12 @@ resource "aws_workspaces_workspace" "test" { TerraformProviderAwsTest = true Beta = 2 } + + depends_on = [ + # The role "workspaces_DefaultRole" requires the policy arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess + # to create and delete the ENI that the Workspaces service creates for the Workspace + aws_iam_role_policy_attachment.workspaces-default-service-access, + ] } `) } @@ -386,8 +348,9 @@ resource "aws_workspaces_workspace" "test" { func testAccWorkspacesWorkspaceConfig_TagsC() string { return testAccAwsWorkspacesWorkspaceConfig_Prerequisites() + fmt.Sprintf(` resource "aws_workspaces_workspace" "test" { - bundle_id = "${data.aws_workspaces_bundle.test.id}" + bundle_id = "${data.aws_workspaces_bundle.test.id}" directory_id = "${aws_workspaces_directory.test.id}" + # NOTE: WorkSpaces API doesn't allow creating users in the directory. # However, "Administrator"" user is always present in a bare directory. user_name = "Administrator" @@ -395,6 +358,12 @@ resource "aws_workspaces_workspace" "test" { tags = { TerraformProviderAwsTest = true } + + depends_on = [ + # The role "workspaces_DefaultRole" requires the policy arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess + # to create and delete the ENI that the Workspaces service creates for the Workspace + aws_iam_role_policy_attachment.workspaces-default-service-access, + ] } `) } @@ -402,8 +371,9 @@ resource "aws_workspaces_workspace" "test" { func testAccWorkspacesWorkspaceConfig_WorkspacePropertiesA() string { return testAccAwsWorkspacesWorkspaceConfig_Prerequisites() + fmt.Sprintf(` resource "aws_workspaces_workspace" "test" { - bundle_id = "${data.aws_workspaces_bundle.test.id}" + bundle_id = "${data.aws_workspaces_bundle.test.id}" directory_id = "${aws_workspaces_directory.test.id}" + # NOTE: WorkSpaces API doesn't allow creating users in the directory. # However, "Administrator"" user is always present in a bare directory. user_name = "Administrator" @@ -417,6 +387,12 @@ resource "aws_workspaces_workspace" "test" { tags = { TerraformProviderAwsTest = true } + + depends_on = [ + # The role "workspaces_DefaultRole" requires the policy arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess + # to create and delete the ENI that the Workspaces service creates for the Workspace + aws_iam_role_policy_attachment.workspaces-default-service-access, + ] } `) } @@ -424,8 +400,9 @@ resource "aws_workspaces_workspace" "test" { func testAccWorkspacesWorkspaceConfig_WorkspacePropertiesB() string { return testAccAwsWorkspacesWorkspaceConfig_Prerequisites() + fmt.Sprintf(` resource "aws_workspaces_workspace" "test" { - bundle_id = "${data.aws_workspaces_bundle.test.id}" + bundle_id = "${data.aws_workspaces_bundle.test.id}" directory_id = "${aws_workspaces_directory.test.id}" + # NOTE: WorkSpaces API doesn't allow creating users in the directory. # However, "Administrator"" user is always present in a bare directory. user_name = "Administrator" @@ -438,6 +415,12 @@ resource "aws_workspaces_workspace" "test" { tags = { TerraformProviderAwsTest = true } + + depends_on = [ + # The role "workspaces_DefaultRole" requires the policy arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess + # to create and delete the ENI that the Workspaces service creates for the Workspace + aws_iam_role_policy_attachment.workspaces-default-service-access, + ] } `) } @@ -445,14 +428,21 @@ resource "aws_workspaces_workspace" "test" { func testAccWorkspacesWorkspaceConfig_WorkspacePropertiesC() string { return testAccAwsWorkspacesWorkspaceConfig_Prerequisites() + fmt.Sprintf(` resource "aws_workspaces_workspace" "test" { - bundle_id = "${data.aws_workspaces_bundle.test.id}" + bundle_id = "${data.aws_workspaces_bundle.test.id}" directory_id = "${aws_workspaces_directory.test.id}" + # NOTE: WorkSpaces API doesn't allow creating users in the directory. # However, "Administrator"" user is always present in a bare directory. user_name = "Administrator" workspace_properties { } + + depends_on = [ + # The role "workspaces_DefaultRole" requires the policy arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess + # to create and delete the ENI that the Workspaces service creates for the Workspace + aws_iam_role_policy_attachment.workspaces-default-service-access, + ] } `) } @@ -460,8 +450,9 @@ resource "aws_workspaces_workspace" "test" { func testAccWorkspacesWorkspaceConfig_validateRootVolumeSize() string { return testAccAwsWorkspacesWorkspaceConfig_Prerequisites() + fmt.Sprintf(` resource "aws_workspaces_workspace" "test" { - bundle_id = "${data.aws_workspaces_bundle.test.id}" + bundle_id = "${data.aws_workspaces_bundle.test.id}" directory_id = "${aws_workspaces_directory.test.id}" + # NOTE: WorkSpaces API doesn't allow creating users in the directory. # However, "Administrator"" user is always present in a bare directory. user_name = "Administrator" @@ -474,6 +465,12 @@ resource "aws_workspaces_workspace" "test" { tags = { TerraformProviderAwsTest = true } + + depends_on = [ + # The role "workspaces_DefaultRole" requires the policy arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess + # to create and delete the ENI that the Workspaces service creates for the Workspace + aws_iam_role_policy_attachment.workspaces-default-service-access, + ] } `) } @@ -481,8 +478,9 @@ resource "aws_workspaces_workspace" "test" { func testAccWorkspacesWorkspaceConfig_validateUserVolumeSize() string { return testAccAwsWorkspacesWorkspaceConfig_Prerequisites() + fmt.Sprintf(` resource "aws_workspaces_workspace" "test" { - bundle_id = "${data.aws_workspaces_bundle.test.id}" + bundle_id = "${data.aws_workspaces_bundle.test.id}" directory_id = "${aws_workspaces_directory.test.id}" + # NOTE: WorkSpaces API doesn't allow creating users in the directory. # However, "Administrator"" user is always present in a bare directory. user_name = "Administrator" @@ -495,6 +493,12 @@ resource "aws_workspaces_workspace" "test" { tags = { TerraformProviderAwsTest = true } + + depends_on = [ + # The role "workspaces_DefaultRole" requires the policy arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess + # to create and delete the ENI that the Workspaces service creates for the Workspace + aws_iam_role_policy_attachment.workspaces-default-service-access, + ] } `) } diff --git a/website/docs/r/workspaces_workspace.html.markdown b/website/docs/r/workspaces_workspace.html.markdown index c1563a7db95..4cbf42b6e2e 100644 --- a/website/docs/r/workspaces_workspace.html.markdown +++ b/website/docs/r/workspaces_workspace.html.markdown @@ -10,6 +10,9 @@ description: |- Provides a workspace in [AWS Workspaces](https://docs.aws.amazon.com/workspaces/latest/adminguide/amazon-workspaces.html) Service +~> **NOTE:** During deletion of an `aws_workspaces_workspace` resource, the service role `workspaces_DefaultRole` must be attached to the +policy `arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess`, or it will leak the ENI that the Workspaces service creates for the Workspace. + ## Example Usage ```hcl From 4a531855cbad4e4ebb4e91bfd09adf5b338e73be Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Mon, 11 May 2020 22:00:20 -0700 Subject: [PATCH 119/475] Update CHANGELOG for #11608 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9a8e4d25f1..4ee9d4c9626 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## 2.62.0 (Unreleased) +FEATURES: + +* **New Resource:** `aws_workspaces_workspace` [GH-11608] + ENHANCEMENTS: * resource/aws_appsync_resolver: Add `cache_config` configuration block [GH-12747] From 798593ccfbf83219fdc9bad54abac6b620c0c69d Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Tue, 12 May 2020 10:31:56 -0400 Subject: [PATCH 120/475] resource/aws_iot_topic_rule: Finish dynamodbv2 implementation Output from acceptance testing: ``` --- PASS: TestAccAWSIoTTopicRule_dynamoDbv2 (15.11s) ``` --- aws/resource_aws_iot_topic_rule.go | 53 ++++++++++++++++++--- aws/resource_aws_iot_topic_rule_test.go | 11 ++--- aws/structure.go | 2 +- website/docs/r/iot_topic_rule.html.markdown | 3 +- 4 files changed, 55 insertions(+), 14 deletions(-) diff --git a/aws/resource_aws_iot_topic_rule.go b/aws/resource_aws_iot_topic_rule.go index 38e5fe3ca68..ac9b7a399fc 100644 --- a/aws/resource_aws_iot_topic_rule.go +++ b/aws/resource_aws_iot_topic_rule.go @@ -1,6 +1,7 @@ package aws import ( + "fmt" "log" "github.com/aws/aws-sdk-go/aws" @@ -152,15 +153,24 @@ func resourceAwsIotTopicRule() *schema.Resource { Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + "put_item": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "table_name": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, "role_arn": { Type: schema.TypeString, Required: true, ValidateFunc: validateArn, }, - "table_name": { - Type: schema.TypeString, - Required: true, - }, }, }, }, @@ -429,7 +439,7 @@ func createTopicRulePayload(d *schema.ResourceData) *iot.TopicRulePayload { raw := a.(map[string]interface{}) act := &iot.Action{ DynamoDBv2: &iot.DynamoDBv2Action{ - PutItem: &iot.PutItemInput{TableName: aws.String(raw["table_name"].(string))}, + PutItem: expandIotPutItemInput(raw["put_item"].([]interface{})), RoleArn: aws.String(raw["role_arn"].(string)), }, } @@ -606,7 +616,9 @@ func resourceAwsIotTopicRuleRead(d *schema.ResourceData, meta interface{}) error d.Set("cloudwatch_alarm", flattenIoTRuleCloudWatchAlarmActions(out.Rule.Actions)) d.Set("cloudwatch_metric", flattenIoTRuleCloudWatchMetricActions(out.Rule.Actions)) d.Set("dynamodb", flattenIoTRuleDynamoDbActions(out.Rule.Actions)) - d.Set("dynamodbv2", flattenIoTRuleDynamoDbv2Actions(out.Rule.Actions)) + if err := d.Set("dynamodbv2", flattenIoTRuleDynamoDbv2Actions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting dynamodbv2: %w", err) + } d.Set("elasticsearch", flattenIoTRuleElasticSearchActions(out.Rule.Actions)) d.Set("firehose", flattenIoTRuleFirehoseActions(out.Rule.Actions)) d.Set("kinesis", flattenIoTRuleKinesisActions(out.Rule.Actions)) @@ -647,3 +659,32 @@ func resourceAwsIotTopicRuleDelete(d *schema.ResourceData, meta interface{}) err return err } + +func expandIotPutItemInput(tfList []interface{}) *iot.PutItemInput { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &iot.PutItemInput{} + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["table_name"].(string); ok && v != "" { + apiObject.TableName = aws.String(v) + } + + return apiObject +} + +func flattenIotPutItemInput(apiObject *iot.PutItemInput) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.TableName; v != nil { + tfMap["table_name"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} diff --git a/aws/resource_aws_iot_topic_rule_test.go b/aws/resource_aws_iot_topic_rule_test.go index 3ccaaff1df4..7a953d3661a 100644 --- a/aws/resource_aws_iot_topic_rule_test.go +++ b/aws/resource_aws_iot_topic_rule_test.go @@ -544,10 +544,6 @@ resource "aws_iot_topic_rule" "rule" { func testAccAWSIoTTopicRule_dynamoDbv2(rName string) string { return fmt.Sprintf(testAccAWSIoTTopicRuleRole+` -data "aws_region" "current" { - current = true -} - resource "aws_iot_topic_rule" "rule" { name = "test_rule_%[1]s" description = "Example rule" @@ -556,8 +552,11 @@ resource "aws_iot_topic_rule" "rule" { sql_version = "2015-10-08" dynamodbv2 { - table_name = "${aws_iam_role.iot_role.arn}" - role_arn = "${aws_dynamodb_table.iot_table.arn}" + put_item { + table_name = "test" + } + + role_arn = aws_iam_role.iot_role.arn } } `, rName) diff --git a/aws/structure.go b/aws/structure.go index 25f48ea38b1..9320a5423f8 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -2861,7 +2861,7 @@ func flattenIoTRuleDynamoDbv2Actions(actions []*iot.Action) []map[string]interfa v := a.DynamoDBv2 if v != nil { result["role_arn"] = *v.RoleArn - result["table_name"] = *v.PutItem + result["put_item"] = flattenIotPutItemInput(v.PutItem) results = append(results, result) } } diff --git a/website/docs/r/iot_topic_rule.html.markdown b/website/docs/r/iot_topic_rule.html.markdown index b0b961f54ed..dd10a526afb 100644 --- a/website/docs/r/iot_topic_rule.html.markdown +++ b/website/docs/r/iot_topic_rule.html.markdown @@ -107,8 +107,9 @@ The `dynamodb` object takes the following arguments: The `dynamodbv2` object takes the following arguments: +* `put_item` - (Required) Configuration block with DynamoDB Table to which the message will be written. Nested arguments below. + * `table_name` - (Required) The name of the DynamoDB table. * `role_arn` - (Required) The ARN of the IAM role that grants access to the DynamoDB table. -* `table_name` - (Required) The name of the DynamoDB table. The `elasticsearch` object takes the following arguments: From 5b301ff3ca0b99f3436308de3dae94e8607d3a8b Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Tue, 12 May 2020 13:04:32 -0400 Subject: [PATCH 121/475] resource/aws_iot_topic_rule: Refactor for type safety, error checking, and preparation for top level action/error_action configuration blocks Reference: https://github.com/terraform-providers/terraform-provider-aws/issues/7147 Output from acceptance testing: ``` --- PASS: TestAccAWSIoTTopicRule_iot_events (16.31s) --- PASS: TestAccAWSIoTTopicRule_dynamoDbv2 (16.52s) --- PASS: TestAccAWSIoTTopicRule_iot_analytics (16.66s) --- PASS: TestAccAWSIoTTopicRule_basic (17.43s) --- PASS: TestAccAWSIoTTopicRule_lambda (17.95s) --- PASS: TestAccAWSIoTTopicRule_cloudwatchmetric (17.98s) --- PASS: TestAccAWSIoTTopicRule_republish (18.01s) --- PASS: TestAccAWSIoTTopicRule_firehose (18.06s) --- PASS: TestAccAWSIoTTopicRule_sns (18.21s) --- PASS: TestAccAWSIoTTopicRule_kinesis (18.45s) --- PASS: TestAccAWSIoTTopicRule_s3 (18.54s) --- PASS: TestAccAWSIoTTopicRule_sqs (18.72s) --- PASS: TestAccAWSIoTTopicRule_cloudwatchalarm (18.77s) --- PASS: TestAccAWSIoTTopicRule_elasticsearch (21.96s) --- PASS: TestAccAWSIoTTopicRule_firehose_separator (28.42s) --- PASS: TestAccAWSIoTTopicRule_dynamodb (28.75s) ``` --- aws/resource_aws_iot_topic_rule.go | 1610 ++++++++++++++++++----- aws/resource_aws_iot_topic_rule_test.go | 61 +- aws/structure.go | 281 ---- 3 files changed, 1303 insertions(+), 649 deletions(-) diff --git a/aws/resource_aws_iot_topic_rule.go b/aws/resource_aws_iot_topic_rule.go index 9425cddcc03..1ccee80e929 100644 --- a/aws/resource_aws_iot_topic_rule.go +++ b/aws/resource_aws_iot_topic_rule.go @@ -2,7 +2,6 @@ package aws import ( "fmt" - "log" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/iot" @@ -21,27 +20,9 @@ func resourceAwsIotTopicRule() *schema.Resource { }, Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validateIoTTopicRuleName, - }, - "description": { - Type: schema.TypeString, - Optional: true, - }, - "enabled": { - Type: schema.TypeBool, - Required: true, - }, - "sql": { - Type: schema.TypeString, - Required: true, - }, - "sql_version": { + "arn": { Type: schema.TypeString, - Required: true, + Computed: true, }, "cloudwatch_alarm": { Type: schema.TypeSet, @@ -103,6 +84,10 @@ func resourceAwsIotTopicRule() *schema.Resource { }, }, }, + "description": { + Type: schema.TypeString, + Optional: true, + }, "dynamodb": { Type: schema.TypeSet, Optional: true, @@ -204,6 +189,10 @@ func resourceAwsIotTopicRule() *schema.Resource { }, }, }, + "enabled": { + Type: schema.TypeBool, + Required: true, + }, "firehose": { Type: schema.TypeSet, Optional: true, @@ -226,6 +215,44 @@ func resourceAwsIotTopicRule() *schema.Resource { }, }, }, + "iot_analytics": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "channel_name": { + Type: schema.TypeString, + Required: true, + }, + "role_arn": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateArn, + }, + }, + }, + }, + "iot_events": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "input_name": { + Type: schema.TypeString, + Required: true, + }, + "message_id": { + Type: schema.TypeString, + Optional: true, + }, + "role_arn": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateArn, + }, + }, + }, + }, "kinesis": { Type: schema.TypeSet, Optional: true, @@ -260,6 +287,12 @@ func resourceAwsIotTopicRule() *schema.Resource { }, }, }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateIoTTopicRuleName, + }, "republish": { Type: schema.TypeSet, Optional: true, @@ -321,6 +354,14 @@ func resourceAwsIotTopicRule() *schema.Resource { }, }, }, + "sql": { + Type: schema.TypeString, + Required: true, + }, + "sql_version": { + Type: schema.TypeString, + Required: true, + }, "sqs": { Type: schema.TypeSet, Optional: true, @@ -342,362 +383,106 @@ func resourceAwsIotTopicRule() *schema.Resource { }, }, }, - "arn": { - Type: schema.TypeString, - Computed: true, - }, - "iot_analytics": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "channel_name": { - Type: schema.TypeString, - Required: true, - }, - "role_arn": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validateArn, - }, - }, - }, - }, - "iot_events": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "input_name": { - Type: schema.TypeString, - Required: true, - }, - "message_id": { - Type: schema.TypeString, - Optional: true, - }, - "role_arn": { - Type: schema.TypeString, - Required: true, - }, - }, - }, - }, }, } } -func createTopicRulePayload(d *schema.ResourceData) *iot.TopicRulePayload { - cloudwatchAlarmActions := d.Get("cloudwatch_alarm").(*schema.Set).List() - cloudwatchMetricActions := d.Get("cloudwatch_metric").(*schema.Set).List() - dynamoDbActions := d.Get("dynamodb").(*schema.Set).List() - dynamoDbv2Actions := d.Get("dynamodbv2").(*schema.Set).List() - elasticsearchActions := d.Get("elasticsearch").(*schema.Set).List() - firehoseActions := d.Get("firehose").(*schema.Set).List() - kinesisActions := d.Get("kinesis").(*schema.Set).List() - lambdaActions := d.Get("lambda").(*schema.Set).List() - republishActions := d.Get("republish").(*schema.Set).List() - s3Actions := d.Get("s3").(*schema.Set).List() - snsActions := d.Get("sns").(*schema.Set).List() - sqsActions := d.Get("sqs").(*schema.Set).List() - iotAnalyticsActions := d.Get("iot_analytics").(*schema.Set).List() - iotEventsActions := d.Get("iot_events").(*schema.Set).List() - - numActions := len(cloudwatchAlarmActions) + len(cloudwatchMetricActions) + - len(dynamoDbActions) + len(dynamoDbv2Actions) + len(elasticsearchActions) + - len(firehoseActions) + len(kinesisActions) + len(lambdaActions) + - len(republishActions) + len(s3Actions) + len(snsActions) + len(sqsActions) + len(iotAnalyticsActions) + len(iotEventsActions) - actions := make([]*iot.Action, numActions) - - i := 0 - // Add Cloudwatch Alarm actions - for _, a := range cloudwatchAlarmActions { - raw := a.(map[string]interface{}) - actions[i] = &iot.Action{ - CloudwatchAlarm: &iot.CloudwatchAlarmAction{ - AlarmName: aws.String(raw["alarm_name"].(string)), - RoleArn: aws.String(raw["role_arn"].(string)), - StateReason: aws.String(raw["state_reason"].(string)), - StateValue: aws.String(raw["state_value"].(string)), - }, - } - i++ - } - - // Add Cloudwatch Metric actions - for _, a := range cloudwatchMetricActions { - raw := a.(map[string]interface{}) - act := &iot.Action{ - CloudwatchMetric: &iot.CloudwatchMetricAction{ - MetricName: aws.String(raw["metric_name"].(string)), - MetricNamespace: aws.String(raw["metric_namespace"].(string)), - MetricUnit: aws.String(raw["metric_unit"].(string)), - MetricValue: aws.String(raw["metric_value"].(string)), - RoleArn: aws.String(raw["role_arn"].(string)), - }, - } - if v, ok := raw["metric_timestamp"].(string); ok && v != "" { - act.CloudwatchMetric.MetricTimestamp = aws.String(v) - } - actions[i] = act - i++ - } +func resourceAwsIotTopicRuleCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).iotconn - // Add DynamoDB actions - for _, a := range dynamoDbActions { - raw := a.(map[string]interface{}) - act := &iot.Action{ - DynamoDB: &iot.DynamoDBAction{ - HashKeyField: aws.String(raw["hash_key_field"].(string)), - HashKeyValue: aws.String(raw["hash_key_value"].(string)), - RoleArn: aws.String(raw["role_arn"].(string)), - TableName: aws.String(raw["table_name"].(string)), - }, - } - if v, ok := raw["hash_key_type"].(string); ok && v != "" { - act.DynamoDB.HashKeyType = aws.String(v) - } - if v, ok := raw["range_key_type"].(string); ok && v != "" { - act.DynamoDB.RangeKeyType = aws.String(v) - } - if v, ok := raw["range_key_field"].(string); ok && v != "" { - act.DynamoDB.RangeKeyField = aws.String(v) - } - if v, ok := raw["range_key_value"].(string); ok && v != "" { - act.DynamoDB.RangeKeyValue = aws.String(v) - } - if v, ok := raw["payload_field"].(string); ok && v != "" { - act.DynamoDB.PayloadField = aws.String(v) - } - actions[i] = act - i++ - } + ruleName := d.Get("name").(string) - // Add DynamoDBv2 actions - for _, a := range dynamoDbv2Actions { - raw := a.(map[string]interface{}) - act := &iot.Action{ - DynamoDBv2: &iot.DynamoDBv2Action{ - PutItem: expandIotPutItemInput(raw["put_item"].([]interface{})), - RoleArn: aws.String(raw["role_arn"].(string)), - }, - } - actions[i] = act - i++ + input := &iot.CreateTopicRuleInput{ + RuleName: aws.String(ruleName), + TopicRulePayload: expandIotTopicRulePayload(d), } - // Add Elasticsearch actions + _, err := conn.CreateTopicRule(input) - for _, a := range elasticsearchActions { - raw := a.(map[string]interface{}) - actions[i] = &iot.Action{ - Elasticsearch: &iot.ElasticsearchAction{ - Endpoint: aws.String(raw["endpoint"].(string)), - Id: aws.String(raw["id"].(string)), - Index: aws.String(raw["index"].(string)), - RoleArn: aws.String(raw["role_arn"].(string)), - Type: aws.String(raw["type"].(string)), - }, - } - i++ + if err != nil { + return fmt.Errorf("error creating IoT Topic Rule (%s): %w", ruleName, err) } - // Add Firehose actions + d.SetId(ruleName) - for _, a := range firehoseActions { - raw := a.(map[string]interface{}) - act := &iot.Action{ - Firehose: &iot.FirehoseAction{ - DeliveryStreamName: aws.String(raw["delivery_stream_name"].(string)), - RoleArn: aws.String(raw["role_arn"].(string)), - }, - } - if v, ok := raw["separator"].(string); ok && v != "" { - act.Firehose.Separator = aws.String(raw["separator"].(string)) - } - actions[i] = act - i++ - } + return resourceAwsIotTopicRuleRead(d, meta) +} - // Add Kinesis actions +func resourceAwsIotTopicRuleRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).iotconn - for _, a := range kinesisActions { - raw := a.(map[string]interface{}) - act := &iot.Action{ - Kinesis: &iot.KinesisAction{ - RoleArn: aws.String(raw["role_arn"].(string)), - StreamName: aws.String(raw["stream_name"].(string)), - }, - } - if v, ok := raw["partition_key"].(string); ok && v != "" { - act.Kinesis.PartitionKey = aws.String(v) - } - actions[i] = act - i++ + input := &iot.GetTopicRuleInput{ + RuleName: aws.String(d.Id()), } - // Add Lambda actions + out, err := conn.GetTopicRule(input) - for _, a := range lambdaActions { - raw := a.(map[string]interface{}) - actions[i] = &iot.Action{ - Lambda: &iot.LambdaAction{ - FunctionArn: aws.String(raw["function_arn"].(string)), - }, - } - i++ + if err != nil { + return fmt.Errorf("error getting IoT Topic Rule (%s): %w", d.Id(), err) } - // Add Republish actions + d.Set("arn", out.RuleArn) + d.Set("name", out.Rule.RuleName) + d.Set("description", out.Rule.Description) + d.Set("enabled", !aws.BoolValue(out.Rule.RuleDisabled)) + d.Set("sql", out.Rule.Sql) + d.Set("sql_version", out.Rule.AwsIotSqlVersion) - for _, a := range republishActions { - raw := a.(map[string]interface{}) - actions[i] = &iot.Action{ - Republish: &iot.RepublishAction{ - RoleArn: aws.String(raw["role_arn"].(string)), - Topic: aws.String(raw["topic"].(string)), - }, - } - i++ + if err := d.Set("cloudwatch_alarm", flattenIotCloudWatchAlarmActions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting cloudwatch_alarm: %w", err) } - // Add S3 actions - - for _, a := range s3Actions { - raw := a.(map[string]interface{}) - actions[i] = &iot.Action{ - S3: &iot.S3Action{ - BucketName: aws.String(raw["bucket_name"].(string)), - Key: aws.String(raw["key"].(string)), - RoleArn: aws.String(raw["role_arn"].(string)), - }, - } - i++ + if err := d.Set("cloudwatch_metric", flattenIotCloudWatchMetricActions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting cloudwatch_metric: %w", err) } - // Add SNS actions - - for _, a := range snsActions { - raw := a.(map[string]interface{}) - actions[i] = &iot.Action{ - Sns: &iot.SnsAction{ - RoleArn: aws.String(raw["role_arn"].(string)), - TargetArn: aws.String(raw["target_arn"].(string)), - MessageFormat: aws.String(raw["message_format"].(string)), - }, - } - i++ + if err := d.Set("dynamodb", flattenIotDynamoDbActions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting dynamodb: %w", err) } - // Add SQS actions - - for _, a := range sqsActions { - raw := a.(map[string]interface{}) - actions[i] = &iot.Action{ - Sqs: &iot.SqsAction{ - QueueUrl: aws.String(raw["queue_url"].(string)), - RoleArn: aws.String(raw["role_arn"].(string)), - UseBase64: aws.Bool(raw["use_base64"].(bool)), - }, - } - i++ + if err := d.Set("dynamodbv2", flattenIotDynamoDbv2Actions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting dynamodbv2: %w", err) } - // Add Analytic actions - - for _, a := range iotAnalyticsActions { - raw := a.(map[string]interface{}) - actions[i] = &iot.Action{ - IotAnalytics: &iot.IotAnalyticsAction{ - ChannelName: aws.String(raw["channel_name"].(string)), - RoleArn: aws.String(raw["role_arn"].(string)), - }, - } - i++ + if err := d.Set("elasticsearch", flattenIotElasticsearchActions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting elasticsearch: %w", err) } - // Add IoT Events actions - - for _, a := range iotEventsActions { - raw := a.(map[string]interface{}) - act := &iot.Action{ - IotEvents: &iot.IotEventsAction{ - InputName: aws.String(raw["input_name"].(string)), - RoleArn: aws.String(raw["role_arn"].(string)), - }, - } - if v, ok := raw["message_id"].(string); ok && v != "" { - act.IotEvents.MessageId = aws.String(raw["message_id"].(string)) - } - actions[i] = act - i++ + if err := d.Set("firehose", flattenIotFirehoseActions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting firehose: %w", err) } - return &iot.TopicRulePayload{ - Description: aws.String(d.Get("description").(string)), - RuleDisabled: aws.Bool(!d.Get("enabled").(bool)), - Sql: aws.String(d.Get("sql").(string)), - AwsIotSqlVersion: aws.String(d.Get("sql_version").(string)), - Actions: actions, + if err := d.Set("iot_analytics", flattenIotIotAnalyticsActions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting iot_analytics: %w", err) } -} - -func resourceAwsIotTopicRuleCreate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).iotconn - - ruleName := d.Get("name").(string) - params := &iot.CreateTopicRuleInput{ - RuleName: aws.String(ruleName), - TopicRulePayload: createTopicRulePayload(d), + if err := d.Set("iot_events", flattenIotIotEventsActions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting iot_events: %w", err) } - log.Printf("[DEBUG] Creating IoT Topic Rule: %s", params) - _, err := conn.CreateTopicRule(params) - if err != nil { - return err + if err := d.Set("kinesis", flattenIotKinesisActions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting kinesis: %w", err) } - d.SetId(ruleName) - - return resourceAwsIotTopicRuleRead(d, meta) -} + if err := d.Set("lambda", flattenIotLambdaActions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting lambda: %w", err) + } -func resourceAwsIotTopicRuleRead(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).iotconn + if err := d.Set("republish", flattenIotRepublishActions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting republish: %w", err) + } - params := &iot.GetTopicRuleInput{ - RuleName: aws.String(d.Id()), + if err := d.Set("s3", flattenIotS3Actions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting s3: %w", err) } - log.Printf("[DEBUG] Reading IoT Topic Rule: %s", params) - out, err := conn.GetTopicRule(params) - if err != nil { - return err + if err := d.Set("sns", flattenIotSnsActions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting sns: %w", err) } - d.Set("arn", out.RuleArn) - d.Set("name", out.Rule.RuleName) - d.Set("description", out.Rule.Description) - d.Set("enabled", !(*out.Rule.RuleDisabled)) - d.Set("sql", out.Rule.Sql) - d.Set("sql_version", out.Rule.AwsIotSqlVersion) - d.Set("cloudwatch_alarm", flattenIoTRuleCloudWatchAlarmActions(out.Rule.Actions)) - d.Set("cloudwatch_metric", flattenIoTRuleCloudWatchMetricActions(out.Rule.Actions)) - d.Set("dynamodb", flattenIoTRuleDynamoDbActions(out.Rule.Actions)) - if err := d.Set("dynamodbv2", flattenIoTRuleDynamoDbv2Actions(out.Rule.Actions)); err != nil { - return fmt.Errorf("error setting dynamodbv2: %w", err) + if err := d.Set("sqs", flattenIotSqsActions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting sqs: %w", err) } - d.Set("elasticsearch", flattenIoTRuleElasticSearchActions(out.Rule.Actions)) - d.Set("firehose", flattenIoTRuleFirehoseActions(out.Rule.Actions)) - d.Set("kinesis", flattenIoTRuleKinesisActions(out.Rule.Actions)) - d.Set("lambda", flattenIoTRuleLambdaActions(out.Rule.Actions)) - d.Set("republish", flattenIoTRuleRepublishActions(out.Rule.Actions)) - d.Set("s3", flattenIoTRuleS3Actions(out.Rule.Actions)) - d.Set("sns", flattenIoTRuleSnsActions(out.Rule.Actions)) - d.Set("sqs", flattenIoTRuleSqsActions(out.Rule.Actions)) - d.Set("iot_analytics", flattenIoTRuleIotAnalyticsActions(out.Rule.Actions)) - d.Set("iot_events", flattenIoTRuleIotEventsActions(out.Rule.Actions)) return nil } @@ -705,15 +490,15 @@ func resourceAwsIotTopicRuleRead(d *schema.ResourceData, meta interface{}) error func resourceAwsIotTopicRuleUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iotconn - params := &iot.ReplaceTopicRuleInput{ + input := &iot.ReplaceTopicRuleInput{ RuleName: aws.String(d.Get("name").(string)), - TopicRulePayload: createTopicRulePayload(d), + TopicRulePayload: expandIotTopicRulePayload(d), } - log.Printf("[DEBUG] Updating IoT Topic Rule: %s", params) - _, err := conn.ReplaceTopicRule(params) + + _, err := conn.ReplaceTopicRule(input) if err != nil { - return err + return fmt.Errorf("error updating IoT Topic Rule (%s): %w", d.Id(), err) } return resourceAwsIotTopicRuleRead(d, meta) @@ -722,13 +507,17 @@ func resourceAwsIotTopicRuleUpdate(d *schema.ResourceData, meta interface{}) err func resourceAwsIotTopicRuleDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iotconn - params := &iot.DeleteTopicRuleInput{ + input := &iot.DeleteTopicRuleInput{ RuleName: aws.String(d.Id()), } - log.Printf("[DEBUG] Deleting IoT Topic Rule: %s", params) - _, err := conn.DeleteTopicRule(params) - return err + _, err := conn.DeleteTopicRule(input) + + if err != nil { + return fmt.Errorf("error deleting IoT Topic Rule (%s): %w", d.Id(), err) + } + + return nil } func expandIotPutItemInput(tfList []interface{}) *iot.PutItemInput { @@ -746,15 +535,1144 @@ func expandIotPutItemInput(tfList []interface{}) *iot.PutItemInput { return apiObject } -func flattenIotPutItemInput(apiObject *iot.PutItemInput) []interface{} { - if apiObject == nil { +func expandIotCloudwatchAlarmAction(tfList []interface{}) *iot.CloudwatchAlarmAction { + if len(tfList) == 0 || tfList[0] == nil { return nil } - tfMap := make(map[string]interface{}) + apiObject := &iot.CloudwatchAlarmAction{} + tfMap := tfList[0].(map[string]interface{}) - if v := apiObject.TableName; v != nil { - tfMap["table_name"] = aws.StringValue(v) + if v, ok := tfMap["alarm_name"].(string); ok && v != "" { + apiObject.AlarmName = aws.String(v) + } + + if v, ok := tfMap["role_arn"].(string); ok && v != "" { + apiObject.RoleArn = aws.String(v) + } + + if v, ok := tfMap["state_reason"].(string); ok && v != "" { + apiObject.StateReason = aws.String(v) + } + + if v, ok := tfMap["state_value"].(string); ok && v != "" { + apiObject.StateValue = aws.String(v) + } + + return apiObject +} + +func expandIotCloudwatchMetricAction(tfList []interface{}) *iot.CloudwatchMetricAction { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &iot.CloudwatchMetricAction{} + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["metric_name"].(string); ok && v != "" { + apiObject.MetricName = aws.String(v) + } + + if v, ok := tfMap["metric_namespace"].(string); ok && v != "" { + apiObject.MetricNamespace = aws.String(v) + } + + if v, ok := tfMap["metric_timestamp"].(string); ok && v != "" { + apiObject.MetricTimestamp = aws.String(v) + } + + if v, ok := tfMap["metric_unit"].(string); ok && v != "" { + apiObject.MetricUnit = aws.String(v) + } + + if v, ok := tfMap["metric_value"].(string); ok && v != "" { + apiObject.MetricValue = aws.String(v) + } + + if v, ok := tfMap["role_arn"].(string); ok && v != "" { + apiObject.RoleArn = aws.String(v) + } + + return apiObject +} + +func expandIotDynamoDBAction(tfList []interface{}) *iot.DynamoDBAction { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &iot.DynamoDBAction{} + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["hash_key_field"].(string); ok && v != "" { + apiObject.HashKeyField = aws.String(v) + } + + if v, ok := tfMap["hash_key_type"].(string); ok && v != "" { + apiObject.HashKeyType = aws.String(v) + } + + if v, ok := tfMap["hash_key_value"].(string); ok && v != "" { + apiObject.HashKeyValue = aws.String(v) + } + + if v, ok := tfMap["payload_field"].(string); ok && v != "" { + apiObject.PayloadField = aws.String(v) + } + + if v, ok := tfMap["range_key_field"].(string); ok && v != "" { + apiObject.RangeKeyField = aws.String(v) + } + + if v, ok := tfMap["range_key_type"].(string); ok && v != "" { + apiObject.RangeKeyType = aws.String(v) + } + + if v, ok := tfMap["range_key_value"].(string); ok && v != "" { + apiObject.RangeKeyValue = aws.String(v) + } + + if v, ok := tfMap["role_arn"].(string); ok && v != "" { + apiObject.RoleArn = aws.String(v) + } + + if v, ok := tfMap["table_name"].(string); ok && v != "" { + apiObject.TableName = aws.String(v) + } + + return apiObject +} + +func expandIotDynamoDBv2Action(tfList []interface{}) *iot.DynamoDBv2Action { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &iot.DynamoDBv2Action{} + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["put_item"].([]interface{}); ok { + apiObject.PutItem = expandIotPutItemInput(v) + } + + if v, ok := tfMap["role_arn"].(string); ok && v != "" { + apiObject.RoleArn = aws.String(v) + } + + return apiObject +} + +func expandIotElasticsearchAction(tfList []interface{}) *iot.ElasticsearchAction { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &iot.ElasticsearchAction{} + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["endpoint"].(string); ok && v != "" { + apiObject.Endpoint = aws.String(v) + } + + if v, ok := tfMap["id"].(string); ok && v != "" { + apiObject.Id = aws.String(v) + } + + if v, ok := tfMap["index"].(string); ok && v != "" { + apiObject.Index = aws.String(v) + } + + if v, ok := tfMap["role_arn"].(string); ok && v != "" { + apiObject.RoleArn = aws.String(v) + } + + if v, ok := tfMap["type"].(string); ok && v != "" { + apiObject.Type = aws.String(v) + } + + return apiObject +} + +func expandIotFirehoseAction(tfList []interface{}) *iot.FirehoseAction { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &iot.FirehoseAction{} + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["delivery_stream_name"].(string); ok && v != "" { + apiObject.DeliveryStreamName = aws.String(v) + } + + if v, ok := tfMap["role_arn"].(string); ok && v != "" { + apiObject.RoleArn = aws.String(v) + } + + if v, ok := tfMap["separator"].(string); ok && v != "" { + apiObject.Separator = aws.String(v) + } + + return apiObject +} + +func expandIotIotAnalyticsAction(tfList []interface{}) *iot.IotAnalyticsAction { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &iot.IotAnalyticsAction{} + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["channel_name"].(string); ok && v != "" { + apiObject.ChannelName = aws.String(v) + } + + if v, ok := tfMap["role_arn"].(string); ok && v != "" { + apiObject.RoleArn = aws.String(v) + } + + return apiObject +} + +func expandIotIotEventsAction(tfList []interface{}) *iot.IotEventsAction { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &iot.IotEventsAction{} + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["input_name"].(string); ok && v != "" { + apiObject.InputName = aws.String(v) + } + + if v, ok := tfMap["message_id"].(string); ok && v != "" { + apiObject.MessageId = aws.String(v) + } + + if v, ok := tfMap["role_arn"].(string); ok && v != "" { + apiObject.RoleArn = aws.String(v) + } + + return apiObject +} + +func expandIotKinesisAction(tfList []interface{}) *iot.KinesisAction { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &iot.KinesisAction{} + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["partition_key"].(string); ok && v != "" { + apiObject.PartitionKey = aws.String(v) + } + + if v, ok := tfMap["role_arn"].(string); ok && v != "" { + apiObject.RoleArn = aws.String(v) + } + + if v, ok := tfMap["stream_name"].(string); ok && v != "" { + apiObject.StreamName = aws.String(v) + } + + return apiObject +} + +func expandIotLambdaAction(tfList []interface{}) *iot.LambdaAction { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &iot.LambdaAction{} + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["function_arn"].(string); ok && v != "" { + apiObject.FunctionArn = aws.String(v) + } + + return apiObject +} + +func expandIotRepublishAction(tfList []interface{}) *iot.RepublishAction { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &iot.RepublishAction{} + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["role_arn"].(string); ok && v != "" { + apiObject.RoleArn = aws.String(v) + } + + if v, ok := tfMap["topic"].(string); ok && v != "" { + apiObject.Topic = aws.String(v) + } + + return apiObject +} + +func expandIotS3Action(tfList []interface{}) *iot.S3Action { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &iot.S3Action{} + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["bucket_name"].(string); ok && v != "" { + apiObject.BucketName = aws.String(v) + } + + if v, ok := tfMap["key"].(string); ok && v != "" { + apiObject.Key = aws.String(v) + } + + if v, ok := tfMap["role_arn"].(string); ok && v != "" { + apiObject.RoleArn = aws.String(v) + } + + return apiObject +} + +func expandIotSnsAction(tfList []interface{}) *iot.SnsAction { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &iot.SnsAction{} + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["message_format"].(string); ok && v != "" { + apiObject.MessageFormat = aws.String(v) + } + + if v, ok := tfMap["role_arn"].(string); ok && v != "" { + apiObject.RoleArn = aws.String(v) + } + + if v, ok := tfMap["target_arn"].(string); ok && v != "" { + apiObject.TargetArn = aws.String(v) + } + + return apiObject +} +func expandIotSqsAction(tfList []interface{}) *iot.SqsAction { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &iot.SqsAction{} + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["queue_url"].(string); ok && v != "" { + apiObject.QueueUrl = aws.String(v) + } + + if v, ok := tfMap["role_arn"].(string); ok && v != "" { + apiObject.RoleArn = aws.String(v) + } + + if v, ok := tfMap["use_base64"].(bool); ok { + apiObject.UseBase64 = aws.Bool(v) + } + + return apiObject +} + +func expandIotTopicRulePayload(d *schema.ResourceData) *iot.TopicRulePayload { + var actions []*iot.Action + + // Legacy root attribute handling + for _, tfMapRaw := range d.Get("cloudwatch_alarm").(*schema.Set).List() { + action := expandIotCloudwatchAlarmAction([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + actions = append(actions, &iot.Action{CloudwatchAlarm: action}) + } + + // Legacy root attribute handling + for _, tfMapRaw := range d.Get("cloudwatch_metric").(*schema.Set).List() { + action := expandIotCloudwatchMetricAction([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + actions = append(actions, &iot.Action{CloudwatchMetric: action}) + } + + // Legacy root attribute handling + for _, tfMapRaw := range d.Get("dynamodb").(*schema.Set).List() { + action := expandIotDynamoDBAction([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + actions = append(actions, &iot.Action{DynamoDB: action}) + } + + // Legacy root attribute handling + for _, tfMapRaw := range d.Get("dynamodbv2").(*schema.Set).List() { + action := expandIotDynamoDBv2Action([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + actions = append(actions, &iot.Action{DynamoDBv2: action}) + } + + // Legacy root attribute handling + for _, tfMapRaw := range d.Get("elasticsearch").(*schema.Set).List() { + action := expandIotElasticsearchAction([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + actions = append(actions, &iot.Action{Elasticsearch: action}) + } + + // Legacy root attribute handling + for _, tfMapRaw := range d.Get("firehose").(*schema.Set).List() { + action := expandIotFirehoseAction([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + actions = append(actions, &iot.Action{Firehose: action}) + } + + // Legacy root attribute handling + for _, tfMapRaw := range d.Get("iot_analytics").(*schema.Set).List() { + action := expandIotIotAnalyticsAction([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + actions = append(actions, &iot.Action{IotAnalytics: action}) + } + + // Legacy root attribute handling + for _, tfMapRaw := range d.Get("iot_events").(*schema.Set).List() { + action := expandIotIotEventsAction([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + actions = append(actions, &iot.Action{IotEvents: action}) + } + + // Legacy root attribute handling + for _, tfMapRaw := range d.Get("kinesis").(*schema.Set).List() { + action := expandIotKinesisAction([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + actions = append(actions, &iot.Action{Kinesis: action}) + } + + // Legacy root attribute handling + for _, tfMapRaw := range d.Get("lambda").(*schema.Set).List() { + action := expandIotLambdaAction([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + actions = append(actions, &iot.Action{Lambda: action}) + } + + // Legacy root attribute handling + for _, tfMapRaw := range d.Get("republish").(*schema.Set).List() { + action := expandIotRepublishAction([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + actions = append(actions, &iot.Action{Republish: action}) + } + + // Legacy root attribute handling + for _, tfMapRaw := range d.Get("s3").(*schema.Set).List() { + action := expandIotS3Action([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + actions = append(actions, &iot.Action{S3: action}) + } + + // Legacy root attribute handling + for _, tfMapRaw := range d.Get("sns").(*schema.Set).List() { + action := expandIotSnsAction([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + actions = append(actions, &iot.Action{Sns: action}) + } + + // Legacy root attribute handling + for _, tfMapRaw := range d.Get("sqs").(*schema.Set).List() { + action := expandIotSqsAction([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + actions = append(actions, &iot.Action{Sqs: action}) + } + + // Prevent sending empty Actions: + // - missing required field, CreateTopicRuleInput.TopicRulePayload.Actions + if len(actions) == 0 { + actions = []*iot.Action{} + } + + return &iot.TopicRulePayload{ + Actions: actions, + AwsIotSqlVersion: aws.String(d.Get("sql_version").(string)), + Description: aws.String(d.Get("description").(string)), + RuleDisabled: aws.Bool(!d.Get("enabled").(bool)), + Sql: aws.String(d.Get("sql").(string)), + } +} + +func flattenIotCloudwatchAlarmAction(apiObject *iot.CloudwatchAlarmAction) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.AlarmName; v != nil { + tfMap["alarm_name"] = aws.StringValue(v) + } + + if v := apiObject.RoleArn; v != nil { + tfMap["role_arn"] = aws.StringValue(v) + } + + if v := apiObject.StateReason; v != nil { + tfMap["state_reason"] = aws.StringValue(v) + } + + if v := apiObject.StateValue; v != nil { + tfMap["state_value"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +// Legacy root attribute handling +func flattenIotCloudWatchAlarmActions(actions []*iot.Action) []interface{} { + results := make([]interface{}, 0) + + for _, action := range actions { + if action == nil { + continue + } + + if v := action.CloudwatchAlarm; v != nil { + results = append(results, flattenIotCloudwatchAlarmAction(v)...) + } + } + + return results +} + +func flattenIotCloudwatchMetricAction(apiObject *iot.CloudwatchMetricAction) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.MetricName; v != nil { + tfMap["metric_name"] = aws.StringValue(v) + } + + if v := apiObject.MetricNamespace; v != nil { + tfMap["metric_namespace"] = aws.StringValue(v) + } + + if v := apiObject.MetricTimestamp; v != nil { + tfMap["metric_timestamp"] = aws.StringValue(v) + } + + if v := apiObject.MetricUnit; v != nil { + tfMap["metric_unit"] = aws.StringValue(v) + } + + if v := apiObject.MetricValue; v != nil { + tfMap["metric_value"] = aws.StringValue(v) + } + + if v := apiObject.RoleArn; v != nil { + tfMap["role_arn"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +// Legacy root attribute handling +func flattenIotCloudWatchMetricActions(actions []*iot.Action) []interface{} { + results := make([]interface{}, 0) + + for _, action := range actions { + if action == nil { + continue + } + + if v := action.CloudwatchMetric; v != nil { + results = append(results, flattenIotCloudwatchMetricAction(v)...) + } + } + + return results +} + +func flattenIotCloudWatchMetricAction(apiObject *iot.CloudwatchMetricAction) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.MetricName; v != nil { + tfMap["metric_name"] = aws.StringValue(v) + } + + if v := apiObject.MetricNamespace; v != nil { + tfMap["metric_namespace"] = aws.StringValue(v) + } + + if v := apiObject.MetricTimestamp; v != nil { + tfMap["metric_timestamp"] = aws.StringValue(v) + } + + if v := apiObject.MetricUnit; v != nil { + tfMap["metric_unit"] = aws.StringValue(v) + } + + if v := apiObject.MetricValue; v != nil { + tfMap["metric_value"] = aws.StringValue(v) + } + + if v := apiObject.RoleArn; v != nil { + tfMap["role_arn"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +// Legacy root attribute handling +func flattenIotDynamoDbActions(actions []*iot.Action) []interface{} { + results := make([]interface{}, 0) + + for _, action := range actions { + if action == nil { + continue + } + + if v := action.DynamoDB; v != nil { + results = append(results, flattenIotDynamoDBAction(v)...) + } + } + + return results +} + +func flattenIotDynamoDBAction(apiObject *iot.DynamoDBAction) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.HashKeyField; v != nil { + tfMap["hash_key_field"] = aws.StringValue(v) + } + + if v := apiObject.HashKeyType; v != nil { + tfMap["hash_key_type"] = aws.StringValue(v) + } + + if v := apiObject.HashKeyValue; v != nil { + tfMap["hash_key_value"] = aws.StringValue(v) + } + + if v := apiObject.PayloadField; v != nil { + tfMap["payload_field"] = aws.StringValue(v) + } + + if v := apiObject.RangeKeyField; v != nil { + tfMap["range_key_field"] = aws.StringValue(v) + } + + if v := apiObject.RangeKeyType; v != nil { + tfMap["range_key_type"] = aws.StringValue(v) + } + + if v := apiObject.RangeKeyValue; v != nil { + tfMap["range_key_value"] = aws.StringValue(v) + } + + if v := apiObject.RoleArn; v != nil { + tfMap["role_arn"] = aws.StringValue(v) + } + + if v := apiObject.TableName; v != nil { + tfMap["table_name"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +// Legacy root attribute handling +func flattenIotDynamoDbv2Actions(actions []*iot.Action) []interface{} { + results := make([]interface{}, 0) + + for _, action := range actions { + if action == nil { + continue + } + + if v := action.DynamoDBv2; v != nil { + results = append(results, flattenIotDynamoDBv2Action(v)...) + } + } + + return results +} + +func flattenIotDynamoDBv2Action(apiObject *iot.DynamoDBv2Action) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.PutItem; v != nil { + tfMap["put_item"] = flattenIotPutItemInput(v) + } + + if v := apiObject.RoleArn; v != nil { + tfMap["role_arn"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +// Legacy root attribute handling +func flattenIotElasticsearchActions(actions []*iot.Action) []interface{} { + results := make([]interface{}, 0) + + for _, action := range actions { + if action == nil { + continue + } + + if v := action.Elasticsearch; v != nil { + results = append(results, flattenIotElasticsearchAction(v)...) + } + } + + return results +} + +func flattenIotElasticsearchAction(apiObject *iot.ElasticsearchAction) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.Endpoint; v != nil { + tfMap["endpoint"] = aws.StringValue(v) + } + + if v := apiObject.Id; v != nil { + tfMap["id"] = aws.StringValue(v) + } + + if v := apiObject.Index; v != nil { + tfMap["index"] = aws.StringValue(v) + } + + if v := apiObject.Type; v != nil { + tfMap["type"] = aws.StringValue(v) + } + + if v := apiObject.RoleArn; v != nil { + tfMap["role_arn"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +// Legacy root attribute handling +func flattenIotFirehoseActions(actions []*iot.Action) []interface{} { + results := make([]interface{}, 0) + + for _, action := range actions { + if action == nil { + continue + } + + if v := action.Firehose; v != nil { + results = append(results, flattenIotFirehoseAction(v)...) + } + } + + return results +} + +func flattenIotFirehoseAction(apiObject *iot.FirehoseAction) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.DeliveryStreamName; v != nil { + tfMap["delivery_stream_name"] = aws.StringValue(v) + } + + if v := apiObject.RoleArn; v != nil { + tfMap["role_arn"] = aws.StringValue(v) + } + + if v := apiObject.Separator; v != nil { + tfMap["separator"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +// Legacy root attribute handling +func flattenIotIotAnalyticsActions(actions []*iot.Action) []interface{} { + results := make([]interface{}, 0) + + for _, action := range actions { + if action == nil { + continue + } + + if v := action.IotAnalytics; v != nil { + results = append(results, flattenIotIotAnalyticsAction(v)...) + } + } + + return results +} + +func flattenIotIotAnalyticsAction(apiObject *iot.IotAnalyticsAction) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.ChannelName; v != nil { + tfMap["channel_name"] = aws.StringValue(v) + } + + if v := apiObject.RoleArn; v != nil { + tfMap["role_arn"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +// Legacy root attribute handling +func flattenIotIotEventsActions(actions []*iot.Action) []interface{} { + results := make([]interface{}, 0) + + for _, action := range actions { + if action == nil { + continue + } + + if v := action.IotEvents; v != nil { + results = append(results, flattenIotIotEventsAction(v)...) + } + } + + return results +} + +func flattenIotIotEventsAction(apiObject *iot.IotEventsAction) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.InputName; v != nil { + tfMap["input_name"] = aws.StringValue(v) + } + + if v := apiObject.MessageId; v != nil { + tfMap["message_id"] = aws.StringValue(v) + } + + if v := apiObject.RoleArn; v != nil { + tfMap["role_arn"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +// Legacy root attribute handling +func flattenIotKinesisActions(actions []*iot.Action) []interface{} { + results := make([]interface{}, 0) + + for _, action := range actions { + if action == nil { + continue + } + + if v := action.Kinesis; v != nil { + results = append(results, flattenIotKinesisAction(v)...) + } + } + + return results +} + +func flattenIotKinesisAction(apiObject *iot.KinesisAction) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.PartitionKey; v != nil { + tfMap["partition_key"] = aws.StringValue(v) + } + + if v := apiObject.RoleArn; v != nil { + tfMap["role_arn"] = aws.StringValue(v) + } + + if v := apiObject.StreamName; v != nil { + tfMap["stream_name"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +// Legacy root attribute handling +func flattenIotLambdaActions(actions []*iot.Action) []interface{} { + results := make([]interface{}, 0) + + for _, action := range actions { + if action == nil { + continue + } + + if v := action.Lambda; v != nil { + results = append(results, flattenIotLambdaAction(v)...) + } + } + + return results +} + +func flattenIotLambdaAction(apiObject *iot.LambdaAction) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.FunctionArn; v != nil { + tfMap["function_arn"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +func flattenIotPutItemInput(apiObject *iot.PutItemInput) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.TableName; v != nil { + tfMap["table_name"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +// Legacy root attribute handling +func flattenIotRepublishActions(actions []*iot.Action) []interface{} { + results := make([]interface{}, 0) + + for _, action := range actions { + if action == nil { + continue + } + + if v := action.Republish; v != nil { + results = append(results, flattenIotRepublishAction(v)...) + } + } + + return results +} + +func flattenIotRepublishAction(apiObject *iot.RepublishAction) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.RoleArn; v != nil { + tfMap["role_arn"] = aws.StringValue(v) + } + + if v := apiObject.Topic; v != nil { + tfMap["topic"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +// Legacy root attribute handling +func flattenIotS3Actions(actions []*iot.Action) []interface{} { + results := make([]interface{}, 0) + + for _, action := range actions { + if action == nil { + continue + } + + if v := action.S3; v != nil { + results = append(results, flattenIotS3Action(v)...) + } + } + + return results +} + +func flattenIotS3Action(apiObject *iot.S3Action) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.BucketName; v != nil { + tfMap["bucket_name"] = aws.StringValue(v) + } + + if v := apiObject.Key; v != nil { + tfMap["key"] = aws.StringValue(v) + } + + if v := apiObject.RoleArn; v != nil { + tfMap["role_arn"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +// Legacy root attribute handling +func flattenIotSnsActions(actions []*iot.Action) []interface{} { + results := make([]interface{}, 0) + + for _, action := range actions { + if action == nil { + continue + } + + if v := action.Sns; v != nil { + results = append(results, flattenIotSnsAction(v)...) + } + } + + return results +} + +func flattenIotSnsAction(apiObject *iot.SnsAction) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.MessageFormat; v != nil { + tfMap["message_format"] = aws.StringValue(v) + } + + if v := apiObject.RoleArn; v != nil { + tfMap["role_arn"] = aws.StringValue(v) + } + + if v := apiObject.TargetArn; v != nil { + tfMap["target_arn"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +// Legacy root attribute handling +func flattenIotSqsActions(actions []*iot.Action) []interface{} { + results := make([]interface{}, 0) + + for _, action := range actions { + if action == nil { + continue + } + + if v := action.Sqs; v != nil { + results = append(results, flattenIotSqsAction(v)...) + } + } + + return results +} + +func flattenIotSqsAction(apiObject *iot.SqsAction) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.QueueUrl; v != nil { + tfMap["queue_url"] = aws.StringValue(v) + } + + if v := apiObject.RoleArn; v != nil { + tfMap["role_arn"] = aws.StringValue(v) + } + + if v := apiObject.UseBase64; v != nil { + tfMap["use_base64"] = aws.BoolValue(v) } return []interface{}{tfMap} diff --git a/aws/resource_aws_iot_topic_rule_test.go b/aws/resource_aws_iot_topic_rule_test.go index 3ca96c9480e..702ca681554 100644 --- a/aws/resource_aws_iot_topic_rule_test.go +++ b/aws/resource_aws_iot_topic_rule_test.go @@ -79,7 +79,7 @@ func TestAccAWSIoTTopicRule_basic(t *testing.T) { { Config: testAccAWSIoTTopicRule_basic(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), resource.TestCheckResourceAttr("aws_iot_topic_rule.rule", "name", fmt.Sprintf("test_rule_%s", rName)), resource.TestCheckResourceAttr("aws_iot_topic_rule.rule", "description", "Example rule"), resource.TestCheckResourceAttr("aws_iot_topic_rule.rule", "enabled", "true"), @@ -108,7 +108,7 @@ func TestAccAWSIoTTopicRule_cloudwatchalarm(t *testing.T) { { Config: testAccAWSIoTTopicRule_cloudwatchalarm(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, { @@ -132,7 +132,7 @@ func TestAccAWSIoTTopicRule_cloudwatchmetric(t *testing.T) { { Config: testAccAWSIoTTopicRule_cloudwatchmetric(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, { @@ -156,7 +156,7 @@ func TestAccAWSIoTTopicRule_dynamodb(t *testing.T) { { Config: testAccAWSIoTTopicRule_dynamodb(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, { @@ -167,7 +167,7 @@ func TestAccAWSIoTTopicRule_dynamodb(t *testing.T) { { Config: testAccAWSIoTTopicRule_dynamodb_rangekeys(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, }, @@ -185,7 +185,7 @@ func TestAccAWSIoTTopicRule_dynamoDbv2(t *testing.T) { { Config: testAccAWSIoTTopicRule_dynamoDbv2(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, }, @@ -204,7 +204,7 @@ func TestAccAWSIoTTopicRule_elasticsearch(t *testing.T) { { Config: testAccAWSIoTTopicRule_elasticsearch(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, { @@ -228,7 +228,7 @@ func TestAccAWSIoTTopicRule_firehose(t *testing.T) { { Config: testAccAWSIoTTopicRule_firehose(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, { @@ -252,7 +252,7 @@ func TestAccAWSIoTTopicRule_firehose_separator(t *testing.T) { { Config: testAccAWSIoTTopicRule_firehose_separator(rName, "\n"), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, { @@ -263,7 +263,7 @@ func TestAccAWSIoTTopicRule_firehose_separator(t *testing.T) { { Config: testAccAWSIoTTopicRule_firehose_separator(rName, ","), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, }, @@ -282,7 +282,7 @@ func TestAccAWSIoTTopicRule_kinesis(t *testing.T) { { Config: testAccAWSIoTTopicRule_kinesis(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, { @@ -306,7 +306,7 @@ func TestAccAWSIoTTopicRule_lambda(t *testing.T) { { Config: testAccAWSIoTTopicRule_lambda(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, { @@ -330,7 +330,7 @@ func TestAccAWSIoTTopicRule_republish(t *testing.T) { { Config: testAccAWSIoTTopicRule_republish(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, { @@ -354,7 +354,7 @@ func TestAccAWSIoTTopicRule_s3(t *testing.T) { { Config: testAccAWSIoTTopicRule_s3(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, { @@ -378,7 +378,7 @@ func TestAccAWSIoTTopicRule_sns(t *testing.T) { { Config: testAccAWSIoTTopicRule_sns(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, { @@ -402,7 +402,7 @@ func TestAccAWSIoTTopicRule_sqs(t *testing.T) { { Config: testAccAWSIoTTopicRule_sqs(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, { @@ -425,7 +425,7 @@ func TestAccAWSIoTTopicRule_iot_analytics(t *testing.T) { { Config: testAccAWSIoTTopicRule_iot_analytics(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, }, @@ -443,7 +443,7 @@ func TestAccAWSIoTTopicRule_iot_events(t *testing.T) { { Config: testAccAWSIoTTopicRule_iot_events(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists_basic("aws_iot_topic_rule.rule"), + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), ), }, }, @@ -458,7 +458,9 @@ func testAccCheckAWSIoTTopicRuleDestroy(s *terraform.State) error { continue } - out, err := conn.ListTopicRules(&iot.ListTopicRulesInput{}) + input := &iot.ListTopicRulesInput{} + + out, err := conn.ListTopicRules(input) if err != nil { return err @@ -475,14 +477,29 @@ func testAccCheckAWSIoTTopicRuleDestroy(s *terraform.State) error { return nil } -func testAccCheckAWSIoTTopicRuleExists_basic(name string) resource.TestCheckFunc { +func testAccCheckAWSIoTTopicRuleExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { - _, ok := s.RootModule().Resources[name] + rs, ok := s.RootModule().Resources[name] if !ok { return fmt.Errorf("Not found: %s", name) } - return nil + conn := testAccProvider.Meta().(*AWSClient).iotconn + input := &iot.ListTopicRulesInput{} + + output, err := conn.ListTopicRules(input) + + if err != nil { + return err + } + + for _, rule := range output.Rules { + if aws.StringValue(rule.RuleName) == rs.Primary.ID { + return nil + } + } + + return fmt.Errorf("IoT Topic Rule (%s) not found", rs.Primary.ID) } } diff --git a/aws/structure.go b/aws/structure.go index 1e2dc6abc00..6ebb5317484 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -2771,287 +2771,6 @@ func flattenCognitoUserPoolUserPoolAddOns(s *cognitoidentityprovider.UserPoolAdd return []map[string]interface{}{config} } -func flattenIoTRuleCloudWatchAlarmActions(actions []*iot.Action) []map[string]interface{} { - results := make([]map[string]interface{}, 0) - - for _, a := range actions { - result := make(map[string]interface{}) - v := a.CloudwatchAlarm - if v != nil { - result["alarm_name"] = *v.AlarmName - result["role_arn"] = *v.RoleArn - result["state_reason"] = *v.StateReason - result["state_value"] = *v.StateValue - - results = append(results, result) - } - } - - return results -} - -func flattenIoTRuleCloudWatchMetricActions(actions []*iot.Action) []map[string]interface{} { - results := make([]map[string]interface{}, 0) - - for _, a := range actions { - result := make(map[string]interface{}) - v := a.CloudwatchMetric - if v != nil { - result["metric_name"] = *v.MetricName - result["role_arn"] = *v.RoleArn - result["metric_namespace"] = *v.MetricNamespace - result["metric_unit"] = *v.MetricUnit - result["metric_value"] = *v.MetricValue - - if v.MetricTimestamp != nil { - result["metric_timestamp"] = *v.MetricTimestamp - } - - results = append(results, result) - } - } - - return results -} - -func flattenIoTRuleDynamoDbActions(actions []*iot.Action) []map[string]interface{} { - items := make([]map[string]interface{}, 0, len(actions)) - - for _, a := range actions { - m := make(map[string]interface{}) - v := a.DynamoDB - if v != nil { - m["hash_key_field"] = aws.StringValue(v.HashKeyField) - m["hash_key_value"] = aws.StringValue(v.HashKeyValue) - m["role_arn"] = aws.StringValue(v.RoleArn) - m["table_name"] = aws.StringValue(v.TableName) - - if v.HashKeyType != nil { - m["hash_key_type"] = aws.StringValue(v.HashKeyType) - } - - if v.PayloadField != nil { - m["payload_field"] = aws.StringValue(v.PayloadField) - } - - if v.RangeKeyField != nil { - m["range_key_field"] = aws.StringValue(v.RangeKeyField) - } - - if v.RangeKeyType != nil { - m["range_key_type"] = aws.StringValue(v.RangeKeyType) - } - - if v.RangeKeyValue != nil { - m["range_key_value"] = aws.StringValue(v.RangeKeyValue) - } - - items = append(items, m) - } - } - - return items -} - -func flattenIoTRuleDynamoDbv2Actions(actions []*iot.Action) []map[string]interface{} { - results := make([]map[string]interface{}, 0) - - for _, a := range actions { - result := make(map[string]interface{}) - v := a.DynamoDBv2 - if v != nil { - result["role_arn"] = *v.RoleArn - result["put_item"] = flattenIotPutItemInput(v.PutItem) - results = append(results, result) - } - } - - return results -} - -func flattenIoTRuleElasticSearchActions(actions []*iot.Action) []map[string]interface{} { - results := make([]map[string]interface{}, 0) - - for _, a := range actions { - result := make(map[string]interface{}) - v := a.Elasticsearch - if v != nil { - result["role_arn"] = *v.RoleArn - result["endpoint"] = *v.Endpoint - result["id"] = *v.Id - result["index"] = *v.Index - result["type"] = *v.Type - - results = append(results, result) - } - } - - return results -} - -func flattenIoTRuleFirehoseActions(actions []*iot.Action) []map[string]interface{} { - results := make([]map[string]interface{}, 0) - - for _, a := range actions { - result := make(map[string]interface{}) - v := a.Firehose - if v != nil { - result["role_arn"] = aws.StringValue(v.RoleArn) - result["delivery_stream_name"] = aws.StringValue(v.DeliveryStreamName) - result["separator"] = aws.StringValue(v.Separator) - - results = append(results, result) - } - } - - return results -} - -func flattenIoTRuleKinesisActions(actions []*iot.Action) []map[string]interface{} { - results := make([]map[string]interface{}, 0) - - for _, a := range actions { - result := make(map[string]interface{}) - v := a.Kinesis - if v != nil { - result["role_arn"] = *v.RoleArn - result["stream_name"] = *v.StreamName - - if v.PartitionKey != nil { - result["partition_key"] = *v.PartitionKey - } - - results = append(results, result) - } - } - - return results -} - -func flattenIoTRuleLambdaActions(actions []*iot.Action) []map[string]interface{} { - results := make([]map[string]interface{}, 0) - - for _, a := range actions { - result := make(map[string]interface{}) - v := a.Lambda - if v != nil { - result["function_arn"] = *v.FunctionArn - - results = append(results, result) - } - } - - return results -} - -func flattenIoTRuleRepublishActions(actions []*iot.Action) []map[string]interface{} { - results := make([]map[string]interface{}, 0) - - for _, a := range actions { - result := make(map[string]interface{}) - v := a.Republish - if v != nil { - result["role_arn"] = *v.RoleArn - result["topic"] = *v.Topic - - results = append(results, result) - } - } - - return results -} - -func flattenIoTRuleS3Actions(actions []*iot.Action) []map[string]interface{} { - results := make([]map[string]interface{}, 0) - - for _, a := range actions { - result := make(map[string]interface{}) - v := a.S3 - if v != nil { - result["role_arn"] = *v.RoleArn - result["bucket_name"] = *v.BucketName - result["key"] = *v.Key - - results = append(results, result) - } - } - - return results -} - -func flattenIoTRuleSnsActions(actions []*iot.Action) []map[string]interface{} { - results := make([]map[string]interface{}, 0) - - for _, a := range actions { - result := make(map[string]interface{}) - v := a.Sns - if v != nil { - result["message_format"] = *v.MessageFormat - result["role_arn"] = *v.RoleArn - result["target_arn"] = *v.TargetArn - - results = append(results, result) - } - } - - return results -} - -func flattenIoTRuleSqsActions(actions []*iot.Action) []map[string]interface{} { - results := make([]map[string]interface{}, 0) - - for _, a := range actions { - result := make(map[string]interface{}) - v := a.Sqs - if v != nil { - result["role_arn"] = aws.StringValue(v.RoleArn) - result["use_base64"] = aws.BoolValue(v.UseBase64) - result["queue_url"] = aws.StringValue(v.QueueUrl) - - results = append(results, result) - } - } - - return results -} - -func flattenIoTRuleIotAnalyticsActions(actions []*iot.Action) []map[string]interface{} { - results := make([]map[string]interface{}, 0) - - for _, a := range actions { - result := make(map[string]interface{}) - v := a.IotAnalytics - if v != nil { - result["role_arn"] = aws.StringValue(v.RoleArn) - result["channel_name"] = aws.StringValue(v.ChannelName) - - results = append(results, result) - } - } - - return results -} - -func flattenIoTRuleIotEventsActions(actions []*iot.Action) []map[string]interface{} { - results := make([]map[string]interface{}, 0) - - for _, a := range actions { - result := make(map[string]interface{}) - v := a.IotEvents - if v != nil { - result["role_arn"] = aws.StringValue(v.RoleArn) - result["input_name"] = aws.StringValue(v.InputName) - if v.MessageId != nil { - result["message_id"] = aws.StringValue(v.MessageId) - } - - results = append(results, result) - } - } - - return results -} - func flattenCognitoUserPoolPasswordPolicy(s *cognitoidentityprovider.PasswordPolicyType) []map[string]interface{} { m := map[string]interface{}{} From 06890a03f5b6d15f5a9ff5deda0cac56718c1427 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Tue, 12 May 2020 13:58:52 -0400 Subject: [PATCH 122/475] resource/aws_iot_topic_rule: Remove unused function Output from acceptance testing: ``` --- PASS: TestAccAWSIoTTopicRule_iot_analytics (15.68s) --- PASS: TestAccAWSIoTTopicRule_dynamoDbv2 (15.75s) --- PASS: TestAccAWSIoTTopicRule_iot_events (15.78s) --- PASS: TestAccAWSIoTTopicRule_lambda (16.45s) --- PASS: TestAccAWSIoTTopicRule_basic (16.57s) --- PASS: TestAccAWSIoTTopicRule_kinesis (16.92s) --- PASS: TestAccAWSIoTTopicRule_republish (16.98s) --- PASS: TestAccAWSIoTTopicRule_s3 (17.13s) --- PASS: TestAccAWSIoTTopicRule_sns (17.18s) --- PASS: TestAccAWSIoTTopicRule_cloudwatchmetric (17.20s) --- PASS: TestAccAWSIoTTopicRule_sqs (17.33s) --- PASS: TestAccAWSIoTTopicRule_cloudwatchalarm (17.44s) --- PASS: TestAccAWSIoTTopicRule_firehose (17.46s) --- PASS: TestAccAWSIoTTopicRule_elasticsearch (20.91s) --- PASS: TestAccAWSIoTTopicRule_firehose_separator (26.71s) --- PASS: TestAccAWSIoTTopicRule_dynamodb (26.79s) ``` --- aws/resource_aws_iot_topic_rule.go | 40 +++--------------------------- 1 file changed, 3 insertions(+), 37 deletions(-) diff --git a/aws/resource_aws_iot_topic_rule.go b/aws/resource_aws_iot_topic_rule.go index ee1f20be346..a2a59b05f1f 100644 --- a/aws/resource_aws_iot_topic_rule.go +++ b/aws/resource_aws_iot_topic_rule.go @@ -442,7 +442,7 @@ func resourceAwsIotTopicRuleRead(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("error setting cloudwatch_alarm: %w", err) } - if err := d.Set("cloudwatch_metric", flattenIotCloudWatchMetricActions(out.Rule.Actions)); err != nil { + if err := d.Set("cloudwatch_metric", flattenIotCloudwatchMetricActions(out.Rule.Actions)); err != nil { return fmt.Errorf("error setting cloudwatch_metric: %w", err) } @@ -1113,42 +1113,8 @@ func flattenIotCloudWatchAlarmActions(actions []*iot.Action) []interface{} { return results } -func flattenIotCloudwatchMetricAction(apiObject *iot.CloudwatchMetricAction) []interface{} { - if apiObject == nil { - return nil - } - - tfMap := make(map[string]interface{}) - - if v := apiObject.MetricName; v != nil { - tfMap["metric_name"] = aws.StringValue(v) - } - - if v := apiObject.MetricNamespace; v != nil { - tfMap["metric_namespace"] = aws.StringValue(v) - } - - if v := apiObject.MetricTimestamp; v != nil { - tfMap["metric_timestamp"] = aws.StringValue(v) - } - - if v := apiObject.MetricUnit; v != nil { - tfMap["metric_unit"] = aws.StringValue(v) - } - - if v := apiObject.MetricValue; v != nil { - tfMap["metric_value"] = aws.StringValue(v) - } - - if v := apiObject.RoleArn; v != nil { - tfMap["role_arn"] = aws.StringValue(v) - } - - return []interface{}{tfMap} -} - // Legacy root attribute handling -func flattenIotCloudWatchMetricActions(actions []*iot.Action) []interface{} { +func flattenIotCloudwatchMetricActions(actions []*iot.Action) []interface{} { results := make([]interface{}, 0) for _, action := range actions { @@ -1164,7 +1130,7 @@ func flattenIotCloudWatchMetricActions(actions []*iot.Action) []interface{} { return results } -func flattenIotCloudWatchMetricAction(apiObject *iot.CloudwatchMetricAction) []interface{} { +func flattenIotCloudwatchMetricAction(apiObject *iot.CloudwatchMetricAction) []interface{} { if apiObject == nil { return nil } From f6fb08ba7e40199037e4044edb7553505a1a43d7 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Tue, 12 May 2020 14:00:35 -0400 Subject: [PATCH 123/475] Update CHANGELOG for #7469, #9859, #9890, and #12714 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ee9d4c9626..333425d8670 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ FEATURES: ENHANCEMENTS: * resource/aws_appsync_resolver: Add `cache_config` configuration block [GH-12747] +* resource/aws_iot_topic_rule: Add `dynamodbv2` configuration block [GH-7469] +* resource/aws_iot_topic_rule: Add `iot_analytics` configuration block [GH-9859] +* resource/aws_iot_topic_rule: Add `iot_events` configuration block [GH-9890] +* resource/aws_iot_topic_rule: Add `operation` argument to `dynamodb` configuration block [GH-12714] ## 2.61.0 (May 08, 2020) From 68a302dc51fcccdf7e8808938e7d7fbac89d1740 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Tue, 12 May 2020 14:17:54 -0400 Subject: [PATCH 124/475] Update CHANGELOG for #12869 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 333425d8670..47d4274891d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ENHANCEMENTS: * resource/aws_iot_topic_rule: Add `iot_analytics` configuration block [GH-9859] * resource/aws_iot_topic_rule: Add `iot_events` configuration block [GH-9890] * resource/aws_iot_topic_rule: Add `operation` argument to `dynamodb` configuration block [GH-12714] +* resource/aws_iot_topic_rule: Add `qos` argument `republish` configuration block [GH-12869] ## 2.61.0 (May 08, 2020) From e5754a567e2578d86c4e098ae29ceb7da21d4b86 Mon Sep 17 00:00:00 2001 From: Adam Surak Date: Wed, 13 May 2020 13:25:13 +0200 Subject: [PATCH 125/475] docs/resource/aws_lb_listener_rule: fix "-" to "_" (#13299) Fix for `query_string` and `http_header` --- website/docs/r/lb_listener_rule.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/r/lb_listener_rule.html.markdown b/website/docs/r/lb_listener_rule.html.markdown index c3939e4db73..ff9e2cf5ad9 100644 --- a/website/docs/r/lb_listener_rule.html.markdown +++ b/website/docs/r/lb_listener_rule.html.markdown @@ -249,9 +249,9 @@ Condition Blocks (for `condition`) support the following: * `host_header` - (Optional) Contains a single `values` item which is a list of host header patterns to match. The maximum size of each pattern is 128 characters. Comparison is case insensitive. Wildcard characters supported: * (matches 0 or more characters) and ? (matches exactly 1 character). Only one pattern needs to match for the condition to be satisfied. * `http_header` - (Optional) HTTP headers to match. [HTTP Header block](#http-header-blocks) fields documented below. * `http_request_method` - (Optional) Contains a single `values` item which is a list of HTTP request methods or verbs to match. Maximum size is 40 characters. Only allowed characters are A-Z, hyphen (-) and underscore (\_). Comparison is case sensitive. Wildcards are not supported. Only one needs to match for the condition to be satisfied. AWS recommends that GET and HEAD requests are routed in the same way because the response to a HEAD request may be cached. -* `path_pattern` - (Optional) Contains a single `values` item which is a list of path patterns to match against the request URL. Maximum size of each pattern is 128 characters. Comparison is case sensitive. Wildcard characters supported: * (matches 0 or more characters) and ? (matches exactly 1 character). Only one pattern needs to match for the condition to be satisfied. Path pattern is compared only to the path of the URL, not to its query string. To compare against the query string, use a `query-string` condition. +* `path_pattern` - (Optional) Contains a single `values` item which is a list of path patterns to match against the request URL. Maximum size of each pattern is 128 characters. Comparison is case sensitive. Wildcard characters supported: * (matches 0 or more characters) and ? (matches exactly 1 character). Only one pattern needs to match for the condition to be satisfied. Path pattern is compared only to the path of the URL, not to its query string. To compare against the query string, use a `query_string` condition. * `query_string` - (Optional) Query strings to match. [Query String block](#query-string-blocks) fields documented below. -* `source_ip` - (Optional) Contains a single `values` item which is a list of source IP CIDR notations to match. You can use both IPv4 and IPv6 addresses. Wildcards are not supported. Condition is satisfied if the source IP address of the request matches one of the CIDR blocks. Condition is not satisfied by the addresses in the `X-Forwarded-For` header, use `http-header` condition instead. +* `source_ip` - (Optional) Contains a single `values` item which is a list of source IP CIDR notations to match. You can use both IPv4 and IPv6 addresses. Wildcards are not supported. Condition is satisfied if the source IP address of the request matches one of the CIDR blocks. Condition is not satisfied by the addresses in the `X-Forwarded-For` header, use `http_header` condition instead. ~> **NOTE::** Exactly one of `field`, `host_header`, `http_header`, `http_request_method`, `path_pattern`, `query_string` or `source_ip` must be set per condition. From fff1d65fa8611fc8b151fb096287bcf00359696d Mon Sep 17 00:00:00 2001 From: jamiesonio Date: Wed, 13 May 2020 07:50:51 -0400 Subject: [PATCH 126/475] docs/resource/aws_nat_gateway: Fix for misleading subnet name (#13273) --- website/docs/r/nat_gateway.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/r/nat_gateway.html.markdown b/website/docs/r/nat_gateway.html.markdown index afd3c04f8bf..6c24f9055fb 100644 --- a/website/docs/r/nat_gateway.html.markdown +++ b/website/docs/r/nat_gateway.html.markdown @@ -15,7 +15,7 @@ Provides a resource to create a VPC NAT Gateway. ```hcl resource "aws_nat_gateway" "gw" { allocation_id = "${aws_eip.nat.id}" - subnet_id = "${aws_subnet.public.id}" + subnet_id = "${aws_subnet.example.id}" } ``` @@ -24,7 +24,7 @@ Usage with tags: ```hcl resource "aws_nat_gateway" "gw" { allocation_id = "${aws_eip.nat.id}" - subnet_id = "${aws_subnet.public.id}" + subnet_id = "${aws_subnet.example.id}" tags = { Name = "gw NAT" From 5e576da470b523d64a81dc125892113f957f3c22 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 13 May 2020 10:44:39 -0400 Subject: [PATCH 127/475] Fix Examples Check linting error (#13300) Error: Invalid resource name on main.tf line 40, in resource "aws_workspaces_workspace" "jhon.doe": 40: resource "aws_workspaces_workspace" "jhon.doe" { A name must start with a letter or underscore and may contain only letters, digits, underscores, and dashes. --- examples/workspaces/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/workspaces/main.tf b/examples/workspaces/main.tf index f552833303a..74f05db8649 100644 --- a/examples/workspaces/main.tf +++ b/examples/workspaces/main.tf @@ -37,7 +37,7 @@ data "aws_workspaces_bundle" "value_windows" { bundle_id = "wsb-bh8rsxt14" # Value with Windows 10 (English) } -resource "aws_workspaces_workspace" "jhon.doe" { +resource "aws_workspaces_workspace" "jhon_doe" { directory_id = "${aws_workspaces_directory.main.id}" bundle_id = "${data.aws_workspaces_bundle.value_windows.id}" user_name = "jhon.doe" From 69e357b9daae3a7c2bb451db0b8ca52274a8800f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 13 May 2020 10:57:26 -0400 Subject: [PATCH 128/475] tests/resource/aws_sns_topic: Add sweeper (#13167) Output from sweeper in AWS Commercial: ``` 2020/05/13 10:50:29 [DEBUG] Running Sweepers for region (us-west-2): 2020/05/13 10:50:29 [DEBUG] Running Sweeper (aws_ses_email_identity) in region (us-west-2) ... 2020/05/13 10:52:04 [INFO] Deleting SNS Topic: arn:aws:sns:us-west-2:--OMITTED--:user-updates-topic20200109135219738500000001 2020/05/13 10:52:04 Sweeper Tests ran successfully: - aws_autoscaling_group - aws_config_configuration_recorder - aws_config_delivery_channel - aws_db_event_subscription - aws_ses_domain_identity - aws_ses_email_identity - aws_elasticache_cluster - aws_glacier_vault - aws_s3_bucket_object - aws_ses_configuration_set - aws_sns_platform_application - aws_elasticache_replication_group - aws_redshift_event_subscription - aws_ses_receipt_rule_set - aws_sns_topic - aws_s3_bucket - aws_iot_topic_rule - aws_s3_access_point - aws_budgets_budget - aws_dax_cluster - aws_neptune_event_subscription 2020/05/13 10:52:04 [DEBUG] Running Sweepers for region (us-east-1): 2020/05/13 10:52:04 [DEBUG] Running Sweeper (aws_redshift_event_subscription) in region (us-east-1) ... 2020/05/13 10:52:17 [INFO] Deleting SNS Topic: arn:aws:sns:us-east-1:--OMITTED--:tf-acc-test-rds-event-subs-sns-topic-9207950827952522213 2020/05/13 10:52:17 Sweeper Tests ran successfully: - aws_s3_access_point - aws_sns_platform_application - aws_dax_cluster - aws_glacier_vault - aws_config_delivery_channel - aws_s3_bucket_object - aws_ses_configuration_set - aws_ses_domain_identity - aws_iot_topic_rule - aws_autoscaling_group - aws_config_configuration_recorder - aws_s3_bucket - aws_ses_email_identity - aws_ses_receipt_rule_set - aws_sns_topic - aws_redshift_event_subscription - aws_elasticache_replication_group - aws_elasticache_cluster - aws_neptune_event_subscription - aws_budgets_budget - aws_db_event_subscription ok github.com/terraform-providers/terraform-provider-aws/aws 110.192s ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/13 10:52:32 [DEBUG] Running Sweepers for region (us-gov-west-1): 2020/05/13 10:52:32 [DEBUG] Running Sweeper (aws_neptune_event_subscription) in region (us-gov-west-1) ... 2020/05/13 10:52:46 [DEBUG] Running Sweeper (aws_sns_topic) in region (us-gov-west-1) 2020/05/13 10:52:46 [INFO] Deleting SNS Topic: arn:aws-us-gov:sns:us-gov-west-1:--OMITTED--:foo-topic-ioyhd ... 2020/05/13 10:53:15 [INFO] Deleting SNS Topic: arn:aws-us-gov:sns:us-gov-west-1:--OMITTED--:user-updates-topic-f3ogm 2020/05/13 10:53:15 Sweeper Tests ran successfully: - aws_elasticache_replication_group - aws_elasticache_cluster - aws_iot_topic_rule - aws_neptune_event_subscription - aws_autoscaling_group - aws_s3_bucket - aws_ses_email_identity - aws_budgets_budget - aws_redshift_event_subscription - aws_config_configuration_recorder - aws_db_event_subscription - aws_sns_topic - aws_s3_bucket_object - aws_ses_configuration_set - aws_config_delivery_channel - aws_ses_domain_identity - aws_ses_receipt_rule_set - aws_s3_access_point - aws_dax_cluster - aws_glacier_vault - aws_sns_platform_application ok github.com/terraform-providers/terraform-provider-aws/aws 44.400s ``` --- aws/resource_aws_sns_topic_test.go | 73 +++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_sns_topic_test.go b/aws/resource_aws_sns_topic_test.go index 229b1125335..2f196e7fedc 100644 --- a/aws/resource_aws_sns_topic_test.go +++ b/aws/resource_aws_sns_topic_test.go @@ -2,18 +2,89 @@ package aws import ( "fmt" + "log" "regexp" "testing" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/sns" - multierror "github.com/hashicorp/go-multierror" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" awspolicy "github.com/jen20/awspolicyequivalence" ) +func init() { + resource.AddTestSweepers("aws_sns_topic", &resource.Sweeper{ + Name: "aws_sns_topic", + F: testSweepSnsTopics, + Dependencies: []string{ + "aws_autoscaling_group", + "aws_budgets_budget", + "aws_config_delivery_channel", + "aws_dax_cluster", + "aws_db_event_subscription", + "aws_elasticache_cluster", + "aws_elasticache_replication_group", + "aws_glacier_vault", + "aws_iot_topic_rule", + "aws_neptune_event_subscription", + "aws_redshift_event_subscription", + "aws_s3_bucket", + "aws_ses_configuration_set", + "aws_ses_domain_identity", + "aws_ses_email_identity", + "aws_ses_receipt_rule_set", + "aws_sns_platform_application", + }, + }) +} + +func testSweepSnsTopics(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).snsconn + var sweeperErrs *multierror.Error + + err = conn.ListTopicsPages(&sns.ListTopicsInput{}, func(page *sns.ListTopicsOutput, isLast bool) bool { + if page == nil { + return !isLast + } + + for _, topic := range page.Topics { + arn := aws.StringValue(topic.TopicArn) + + log.Printf("[INFO] Deleting SNS Topic: %s", arn) + _, err := conn.DeleteTopic(&sns.DeleteTopicInput{ + TopicArn: aws.String(arn), + }) + if isAWSErr(err, sns.ErrCodeNotFoundException, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error deleting SNS Topic (%s): %w", arn, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + return !isLast + }) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping SNS Topics sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving SNS Topics: %w", err)) + } + + return sweeperErrs.ErrorOrNil() +} + func TestAccAWSSNSTopic_basic(t *testing.T) { attributes := make(map[string]string) resourceName := "aws_sns_topic.test" From 8cf982166361b6079446778ea9218a05c57c65c1 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 13 May 2020 11:15:01 -0400 Subject: [PATCH 129/475] tests/resource/aws_sqs_queue: Add sweeper (#13244) Output from sweeper in AWS Commercial: ``` 2020/05/13 11:05:38 [DEBUG] Running Sweepers for region (us-west-2): 2020/05/13 11:05:38 [DEBUG] Running Sweeper (aws_dax_cluster) in region (us-west-2) ... 2020/05/13 11:06:56 [INFO] Deleting SQS Queue: https://sqs.us-west-2.amazonaws.com/--OMITTED--/tf_acc_stream_lambda_sqs_basic_1rkj4ge6 2020/05/13 11:06:56 Sweeper Tests ran successfully: - aws_config_configuration_recorder - aws_neptune_event_subscription - aws_ses_receipt_rule_set - aws_sqs_queue - aws_dax_cluster - aws_budgets_budget - aws_ses_email_identity - aws_lambda_function - aws_autoscaling_group - aws_redshift_event_subscription - aws_sns_platform_application - aws_ses_domain_identity - aws_s3_access_point - aws_s3_bucket_object - aws_glacier_vault - aws_cloudwatch_event_rule - aws_config_delivery_channel - aws_sns_topic - aws_iot_topic_rule - aws_db_event_subscription - aws_s3_bucket - aws_elastic_beanstalk_environment - aws_cloudwatch_event_target - aws_ses_configuration_set - aws_elasticache_replication_group - aws_elasticache_cluster 2020/05/13 11:06:56 [DEBUG] Running Sweepers for region (us-east-1): 2020/05/13 11:06:56 [DEBUG] Running Sweeper (aws_elasticache_replication_group) in region (us-east-1) ... 2020/05/13 11:07:07 [INFO] Deleting SQS Queue: https://sqs.us-east-1.amazonaws.com/--OMITTED--/tf_acc_test_-3506094436347960811_wrong 2020/05/13 11:07:07 Sweeper Tests ran successfully: - aws_s3_access_point - aws_elastic_beanstalk_environment - aws_glacier_vault - aws_ses_domain_identity - aws_sqs_queue - aws_elasticache_replication_group - aws_cloudwatch_event_target - aws_ses_configuration_set - aws_budgets_budget - aws_dax_cluster - aws_redshift_event_subscription - aws_sns_topic - aws_elasticache_cluster - aws_s3_bucket_object - aws_s3_bucket - aws_iot_topic_rule - aws_cloudwatch_event_rule - aws_config_delivery_channel - aws_db_event_subscription - aws_sns_platform_application - aws_ses_email_identity - aws_neptune_event_subscription - aws_lambda_function - aws_ses_receipt_rule_set - aws_autoscaling_group - aws_config_configuration_recorder ok github.com/terraform-providers/terraform-provider-aws/aws 90.904s ``` Output from sweeper in AWS GovCloud (US): ``` 2020/05/13 11:07:18 [DEBUG] Running Sweepers for region (us-gov-west-1): 2020/05/13 11:07:18 [DEBUG] Running Sweeper (aws_autoscaling_group) in region (us-gov-west-1) ... 2020/05/13 11:10:11 [INFO] Deleting SQS Queue: https://sqs.us-gov-west-1.amazonaws.com/--OMITTED--/tf_acc_test_-984412753739955459 2020/05/13 11:10:11 Sweeper Tests ran successfully: - aws_cloudwatch_event_rule - aws_elastic_beanstalk_environment - aws_s3_access_point - aws_sns_topic - aws_config_delivery_channel - aws_sns_platform_application - aws_autoscaling_group - aws_elasticache_replication_group - aws_iot_topic_rule - aws_ses_domain_identity - aws_cloudwatch_event_target - aws_s3_bucket_object - aws_redshift_event_subscription - aws_ses_configuration_set - aws_s3_bucket - aws_glacier_vault - aws_ses_receipt_rule_set - aws_sqs_queue - aws_neptune_event_subscription - aws_ses_email_identity - aws_elasticache_cluster - aws_dax_cluster - aws_db_event_subscription - aws_budgets_budget - aws_lambda_function - aws_config_configuration_recorder ok github.com/terraform-providers/terraform-provider-aws/aws 174.395s ``` --- aws/resource_aws_sqs_queue_test.go | 58 ++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/aws/resource_aws_sqs_queue_test.go b/aws/resource_aws_sqs_queue_test.go index 0e09388c28c..faf343599a0 100644 --- a/aws/resource_aws_sqs_queue_test.go +++ b/aws/resource_aws_sqs_queue_test.go @@ -2,18 +2,76 @@ package aws import ( "fmt" + "log" "regexp" "testing" "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/sqs" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/terraform" awspolicy "github.com/jen20/awspolicyequivalence" ) +func init() { + resource.AddTestSweepers("aws_sqs_queue", &resource.Sweeper{ + Name: "aws_sqs_queue", + F: testSweepSqsQueues, + Dependencies: []string{ + "aws_autoscaling_group", + "aws_cloudwatch_event_rule", + "aws_elastic_beanstalk_environment", + "aws_iot_topic_rule", + "aws_lambda_function", + "aws_s3_bucket", + "aws_sns_topic", + }, + }) +} + +func testSweepSqsQueues(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.(*AWSClient).sqsconn + input := &sqs.ListQueuesInput{} + var sweeperErrs *multierror.Error + + output, err := conn.ListQueues(input) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping SQS Queues sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving SQS Queues: %w", err)) + return sweeperErrs + } + + for _, queueUrl := range output.QueueUrls { + url := aws.StringValue(queueUrl) + + log.Printf("[INFO] Deleting SQS Queue: %s", url) + _, err := conn.DeleteQueue(&sqs.DeleteQueueInput{ + QueueUrl: aws.String(url), + }) + if isAWSErr(err, sqs.ErrCodeQueueDoesNotExist, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error deleting SQS Queue (%s): %w", url, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + return sweeperErrs.ErrorOrNil() +} + func TestAccAWSSQSQueue_basic(t *testing.T) { var queueAttributes map[string]*string From 2afecdcb451842a0c7c23715599d35d0a1083fc4 Mon Sep 17 00:00:00 2001 From: Pascal van Buijtene Date: Wed, 13 May 2020 22:03:55 +0200 Subject: [PATCH 130/475] Add extra error checking --- aws/resource_aws_wafv2_ip_set.go | 10 +++++++--- aws/resource_aws_wafv2_ip_set_test.go | 18 ++++++++---------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/aws/resource_aws_wafv2_ip_set.go b/aws/resource_aws_wafv2_ip_set.go index 1daebf2fc49..83e7c53dfd8 100644 --- a/aws/resource_aws_wafv2_ip_set.go +++ b/aws/resource_aws_wafv2_ip_set.go @@ -130,11 +130,11 @@ func resourceAwsWafv2IPSetCreate(d *schema.ResourceData, meta interface{}) error resp, err := conn.CreateIPSet(params) - if err != nil { + if err != nil || resp == nil || resp.Summary == nil { return fmt.Errorf("Error creating WAFv2 IPSet: %s", err) } - d.SetId(*resp.Summary.Id) + d.SetId(aws.StringValue(resp.Summary.Id)) return resourceAwsWafv2IPSetRead(d, meta) } @@ -160,6 +160,10 @@ func resourceAwsWafv2IPSetRead(d *schema.ResourceData, meta interface{}) error { return err } + if resp == nil || resp.IPSet == nil { + return fmt.Errorf("Error reading WAFv2 IPSet") + } + d.Set("name", resp.IPSet.Name) d.Set("description", resp.IPSet.Description) d.Set("ip_address_version", resp.IPSet.IPAddressVersion) @@ -170,7 +174,7 @@ func resourceAwsWafv2IPSetRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("Error setting addresses: %s", err) } - tags, err := keyvaluetags.Wafv2ListTags(conn, *resp.IPSet.ARN) + tags, err := keyvaluetags.Wafv2ListTags(conn, aws.StringValue(resp.IPSet.ARN)) if err != nil { return fmt.Errorf("Error listing tags for WAFv2 IpSet (%s): %s", *resp.IPSet.ARN, err) } diff --git a/aws/resource_aws_wafv2_ip_set_test.go b/aws/resource_aws_wafv2_ip_set_test.go index 4d12fb832f3..0787f145a8d 100644 --- a/aws/resource_aws_wafv2_ip_set_test.go +++ b/aws/resource_aws_wafv2_ip_set_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/wafv2" "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" @@ -251,16 +250,15 @@ func testAccCheckAWSWafv2IPSetDestroy(s *terraform.State) error { }) if err == nil { - if *resp.IPSet.Id == rs.Primary.ID { - return fmt.Errorf("WAFV2 IPSet %s still exists", rs.Primary.ID) + if aws.StringValue(resp.IPSet.Id) == rs.Primary.ID && resp != nil && resp.IPSet != nil { + return fmt.Errorf("WAFv2 IPSet %s still exists", rs.Primary.ID) } + return nil } // Return nil if the IPSet is already destroyed - if awsErr, ok := err.(awserr.Error); ok { - if awsErr.Code() == wafv2.ErrCodeWAFNonexistentItemException { - return nil - } + if isAWSErr(err, wafv2.ErrCodeWAFNonexistentItemException, "") { + return nil } return err @@ -277,7 +275,7 @@ func testAccCheckAWSWafv2IPSetExists(n string, v *wafv2.IPSet) resource.TestChec } if rs.Primary.ID == "" { - return fmt.Errorf("No WAFV2 IPSet ID is set") + return fmt.Errorf("No WAFv2 IPSet ID is set") } conn := testAccProvider.Meta().(*AWSClient).wafv2conn @@ -291,12 +289,12 @@ func testAccCheckAWSWafv2IPSetExists(n string, v *wafv2.IPSet) resource.TestChec return err } - if *resp.IPSet.Id == rs.Primary.ID { + if aws.StringValue(resp.IPSet.Id) == rs.Primary.ID && resp != nil && resp.IPSet != nil { *v = *resp.IPSet return nil } - return fmt.Errorf("WAFV2 IPSet (%s) not found", rs.Primary.ID) + return fmt.Errorf("WAFv2 IPSet (%s) not found", rs.Primary.ID) } } From e04396fdb98affa017618133bb3c251f319fa50b Mon Sep 17 00:00:00 2001 From: Simon Davis Date: Wed, 13 May 2020 13:16:17 -0700 Subject: [PATCH 131/475] add branch prefix section --- .../pullrequest-submission-and-lifecycle.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/contributing/pullrequest-submission-and-lifecycle.md b/docs/contributing/pullrequest-submission-and-lifecycle.md index 1608624805b..4b380826e26 100644 --- a/docs/contributing/pullrequest-submission-and-lifecycle.md +++ b/docs/contributing/pullrequest-submission-and-lifecycle.md @@ -1,6 +1,7 @@ # Pull Request Submission and Lifecycle - [Pull Request Lifecycle](#pull-request-lifecycle) +- [Branch Prefixes](#branch-prefixes) - [Common Review Items](#common-review-items) - [Go Coding Style](#go-coding-style) - [Resource Contribution Guidelines](#resource-contribution-guidelines) @@ -44,6 +45,18 @@ expect: 1. In some cases, we might decide that a PR should be closed without merging. We'll make sure to provide clear reasoning when this happens. +## Branch Prefixes + +We try to use a common set of branch name prefixes when submitting pull requests. Prefixes give us an idea of what the branch is for. For example, `td-staticcheck-st1008` would let us know the branch was created to fix a technical debt issue, and `f-aws_emr_instance_group-refactor` would indicate a feature request for the `aws_emr_instance_group` resource that’s being refactored. These are the prefixes we currently use: + +- f = feature +- b = bug fix +- d = documentation +- td = technical debt +- v = "vendoring"/dependencies + +Conventions across non-AWS providers varies so when working with other providers please check the names of previously created branches and conform to their standard practices. + ## Common Review Items The Terraform AWS Provider follows common practices to ensure consistent and From 8ddf33975df741d10a5b86e374b04e5207a5134e Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Tue, 12 May 2020 11:46:31 -0700 Subject: [PATCH 132/475] Enables AWSAT001 linter for ARN attribute checks in acceptance tests --- GNUmakefile | 1 + 1 file changed, 1 insertion(+) diff --git a/GNUmakefile b/GNUmakefile index feef8d3c111..53380af2ed3 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -67,6 +67,7 @@ lint: -AT006 \ -AT007 \ -AT008 \ + -AWSAT001 \ -AWSR001 \ -AWSR002 \ -R002 \ From ef570f02fd0b51be14d3065ea8499e955d6e0b07 Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Tue, 12 May 2020 11:51:24 -0700 Subject: [PATCH 133/475] Fixes indentation --- GNUmakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GNUmakefile b/GNUmakefile index 53380af2ed3..a4261d40c2f 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -67,7 +67,7 @@ lint: -AT006 \ -AT007 \ -AT008 \ - -AWSAT001 \ + -AWSAT001 \ -AWSR001 \ -AWSR002 \ -R002 \ From 607ee2939964679ea98911854185b5a74e24f0f3 Mon Sep 17 00:00:00 2001 From: raobystorm Date: Thu, 14 May 2020 07:45:31 +0900 Subject: [PATCH 134/475] resource/aws_codebuild_project: Support `git_submodules_config` with `GITHUB` and `GITHUB_ENTERPRISE` source types (#13285) Output from acceptance testing: ``` --- PASS: TestAccAWSCodeBuildProject_ARMContainer (38.85s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_ArtifactIdentifier (123.86s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_EncryptionDisabled (73.22s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_Location (66.05s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_Name (53.15s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_NamespaceType (104.99s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_OverrideArtifactName (63.90s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_Packaging (47.87s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_Path (76.47s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_Type (52.04s) --- PASS: TestAccAWSCodeBuildProject_BadgeEnabled (64.22s) --- PASS: TestAccAWSCodeBuildProject_basic (66.51s) --- PASS: TestAccAWSCodeBuildProject_BuildTimeout (142.70s) --- PASS: TestAccAWSCodeBuildProject_Cache (492.80s) --- PASS: TestAccAWSCodeBuildProject_Description (118.05s) --- PASS: TestAccAWSCodeBuildProject_EncryptionKey (24.36s) --- PASS: TestAccAWSCodeBuildProject_Environment_Certificate (35.56s) --- PASS: TestAccAWSCodeBuildProject_Environment_EnvironmentVariable (137.21s) --- PASS: TestAccAWSCodeBuildProject_Environment_EnvironmentVariable_Type (125.69s) --- PASS: TestAccAWSCodeBuildProject_Environment_RegistryCredential (42.96s) --- PASS: TestAccAWSCodeBuildProject_LogsConfig_CloudWatchLogs (114.15s) --- PASS: TestAccAWSCodeBuildProject_LogsConfig_S3Logs (127.95s) --- PASS: TestAccAWSCodeBuildProject_QueuedTimeout (59.77s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts (59.42s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_ArtifactIdentifier (121.77s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_EncryptionDisabled (59.14s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_Location (152.24s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_NamespaceType (43.80s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_OverrideArtifactName (57.07s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_Packaging (52.05s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_Path (47.08s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_Type (28.57s) --- PASS: TestAccAWSCodeBuildProject_SecondarySources_CodeCommit (42.53s) --- PASS: TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig_CodeCommit (43.31s) --- PASS: TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig_GitHub (49.07s) --- PASS: TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig_GitHubEnterprise (213.67s) --- PASS: TestAccAWSCodeBuildProject_Source_GitCloneDepth (51.10s) --- PASS: TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig_CodeCommit (75.27s) --- PASS: TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig_GitHub (132.44s) --- PASS: TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig_GitHubEnterprise (38.49s) --- PASS: TestAccAWSCodeBuildProject_Source_InsecureSSL (110.79s) --- PASS: TestAccAWSCodeBuildProject_Source_ReportBuildStatus_Bitbucket (112.36s) --- PASS: TestAccAWSCodeBuildProject_Source_ReportBuildStatus_GitHub (263.79s) --- PASS: TestAccAWSCodeBuildProject_Source_ReportBuildStatus_GitHubEnterprise (89.94s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_Bitbucket (63.16s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_CodeCommit (75.09s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_CodePipeline (134.04s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_GitHubEnterprise (68.32s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_NoSource (143.63s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_NoSourceInvalid (12.03s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_S3 (82.56s) --- PASS: TestAccAWSCodeBuildProject_SourceVersion (55.28s) --- PASS: TestAccAWSCodeBuildProject_Tags (59.02s) --- PASS: TestAccAWSCodeBuildProject_WindowsContainer (31.46s) ``` --- aws/resource_aws_codebuild_project.go | 4 +- aws/resource_aws_codebuild_project_test.go | 292 +++++++++++++++++- .../docs/r/codebuild_project.html.markdown | 4 +- 3 files changed, 288 insertions(+), 12 deletions(-) diff --git a/aws/resource_aws_codebuild_project.go b/aws/resource_aws_codebuild_project.go index 4fde4c0ee97..8de95e27432 100644 --- a/aws/resource_aws_codebuild_project.go +++ b/aws/resource_aws_codebuild_project.go @@ -1047,8 +1047,8 @@ func expandProjectSourceData(data map[string]interface{}) codebuild.ProjectSourc } } - // Only valid for CODECOMMIT source types. - if sourceType == codebuild.SourceTypeCodecommit { + // Only valid for CODECOMMIT, GITHUB, GITHUB_ENTERPRISE source types. + if sourceType == codebuild.SourceTypeCodecommit || sourceType == codebuild.SourceTypeGithub || sourceType == codebuild.SourceTypeGithubEnterprise { if v, ok := data["git_submodules_config"]; ok && len(v.([]interface{})) > 0 { config := v.([]interface{})[0].(map[string]interface{}) diff --git a/aws/resource_aws_codebuild_project_test.go b/aws/resource_aws_codebuild_project_test.go index 7ddf463f760..02399e29ad8 100644 --- a/aws/resource_aws_codebuild_project_test.go +++ b/aws/resource_aws_codebuild_project_test.go @@ -611,7 +611,7 @@ func TestAccAWSCodeBuildProject_Source_GitCloneDepth(t *testing.T) { }) } -func TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig(t *testing.T) { +func TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig_CodeCommit(t *testing.T) { var project codebuild.Project rName := acctest.RandomWithPrefix("tf-acc-test") resourceName := "aws_codebuild_project.test" @@ -623,7 +623,7 @@ func TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig(t *testing.T) { DisableBinaryDriver: true, Steps: []resource.TestStep{ { - Config: testAccAWSCodeBuildProjectConfig_Source_GitSubmodulesConfig(rName, true), + Config: testAccAWSCodeBuildProjectConfig_Source_GitSubmodulesConfig_CodeCommit(rName, true), Check: resource.ComposeTestCheckFunc( testAccCheckAWSCodeBuildProjectExists(resourceName, &project), resource.TestCheckResourceAttr(resourceName, "source.3389748318.git_submodules_config.#", "1"), @@ -636,7 +636,7 @@ func TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccAWSCodeBuildProjectConfig_Source_GitSubmodulesConfig(rName, false), + Config: testAccAWSCodeBuildProjectConfig_Source_GitSubmodulesConfig_CodeCommit(rName, false), Check: resource.ComposeTestCheckFunc( testAccCheckAWSCodeBuildProjectExists(resourceName, &project), resource.TestCheckResourceAttr(resourceName, "source.3338377709.git_submodules_config.#", "1"), @@ -647,7 +647,69 @@ func TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig(t *testing.T) { }) } -func TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig(t *testing.T) { +func TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig_GitHub(t *testing.T) { + var project codebuild.Project + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_codebuild_project.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSCodeBuild(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCodeBuildProjectDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCodeBuildProjectConfig_Source_GitSubmodulesConfig_GitHub(rName, true), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeBuildProjectExists(resourceName, &project), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSCodeBuildProjectConfig_Source_GitSubmodulesConfig_GitHub(rName, false), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeBuildProjectExists(resourceName, &project), + ), + }, + }, + }) +} + +func TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig_GitHubEnterprise(t *testing.T) { + var project codebuild.Project + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_codebuild_project.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSCodeBuild(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCodeBuildProjectDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCodeBuildProjectConfig_Source_GitSubmodulesConfig_GitHubEnterprise(rName, true), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeBuildProjectExists(resourceName, &project), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSCodeBuildProjectConfig_Source_GitSubmodulesConfig_GitHubEnterprise(rName, false), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeBuildProjectExists(resourceName, &project), + ), + }, + }, + }) +} + +func TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig_CodeCommit(t *testing.T) { var project codebuild.Project rName := acctest.RandomWithPrefix("tf-acc-test") resourceName := "aws_codebuild_project.test" @@ -659,7 +721,7 @@ func TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig(t *testing. DisableBinaryDriver: true, Steps: []resource.TestStep{ { - Config: testAccAWSCodeBuildProjectConfig_SecondarySources_GitSubmodulesConfig(rName, true), + Config: testAccAWSCodeBuildProjectConfig_SecondarySources_GitSubmodulesConfig_CodeCommit(rName, true), Check: resource.ComposeTestCheckFunc( testAccCheckAWSCodeBuildProjectExists(resourceName, &project), resource.TestCheckResourceAttr(resourceName, "secondary_sources.2336845252.git_submodules_config.#", "1"), @@ -674,7 +736,7 @@ func TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig(t *testing. ImportStateVerify: true, }, { - Config: testAccAWSCodeBuildProjectConfig_SecondarySources_GitSubmodulesConfig(rName, false), + Config: testAccAWSCodeBuildProjectConfig_SecondarySources_GitSubmodulesConfig_CodeCommit(rName, false), Check: resource.ComposeTestCheckFunc( testAccCheckAWSCodeBuildProjectExists(resourceName, &project), resource.TestCheckResourceAttr(resourceName, "secondary_sources.3511868825.git_submodules_config.#", "1"), @@ -687,6 +749,68 @@ func TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig(t *testing. }) } +func TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig_GitHub(t *testing.T) { + var project codebuild.Project + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_codebuild_project.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSCodeBuild(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCodeBuildProjectDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCodeBuildProjectConfig_SecondarySources_GitSubmodulesConfig_GitHub(rName, true), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeBuildProjectExists(resourceName, &project), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSCodeBuildProjectConfig_SecondarySources_GitSubmodulesConfig_GitHub(rName, false), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeBuildProjectExists(resourceName, &project), + ), + }, + }, + }) +} + +func TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig_GitHubEnterprise(t *testing.T) { + var project codebuild.Project + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_codebuild_project.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSCodeBuild(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCodeBuildProjectDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCodeBuildProjectConfig_SecondarySources_GitSubmodulesConfig_GitHubEnterprise(rName, true), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeBuildProjectExists(resourceName, &project), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSCodeBuildProjectConfig_SecondarySources_GitSubmodulesConfig_GitHubEnterprise(rName, false), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeBuildProjectExists(resourceName, &project), + ), + }, + }, + }) +} + func TestAccAWSCodeBuildProject_Source_InsecureSSL(t *testing.T) { var project codebuild.Project rName := acctest.RandomWithPrefix("tf-acc-test") @@ -2707,7 +2831,7 @@ resource "aws_codebuild_project" "test" { `, rName, gitCloneDepth) } -func testAccAWSCodeBuildProjectConfig_Source_GitSubmodulesConfig(rName string, fetchSubmodules bool) string { +func testAccAWSCodeBuildProjectConfig_Source_GitSubmodulesConfig_CodeCommit(rName string, fetchSubmodules bool) string { return testAccAWSCodeBuildProjectConfig_Base_ServiceRole(rName) + fmt.Sprintf(` resource "aws_codebuild_project" "test" { name = "%s" @@ -2735,7 +2859,63 @@ resource "aws_codebuild_project" "test" { `, rName, fetchSubmodules) } -func testAccAWSCodeBuildProjectConfig_SecondarySources_GitSubmodulesConfig(rName string, fetchSubmodules bool) string { +func testAccAWSCodeBuildProjectConfig_Source_GitSubmodulesConfig_GitHub(rName string, fetchSubmodules bool) string { + return testAccAWSCodeBuildProjectConfig_Base_ServiceRole(rName) + fmt.Sprintf(` +resource "aws_codebuild_project" "test" { + name = "%s" + service_role = "${aws_iam_role.test.arn}" + + artifacts { + type = "NO_ARTIFACTS" + } + + environment { + compute_type = "BUILD_GENERAL1_SMALL" + image = "2" + type = "LINUX_CONTAINER" + } + + source { + location = "https://github.com/hashicorp/packer.git" + type = "GITHUB" + + git_submodules_config { + fetch_submodules = %t + } + } +} +`, rName, fetchSubmodules) +} + +func testAccAWSCodeBuildProjectConfig_Source_GitSubmodulesConfig_GitHubEnterprise(rName string, fetchSubmodules bool) string { + return testAccAWSCodeBuildProjectConfig_Base_ServiceRole(rName) + fmt.Sprintf(` +resource "aws_codebuild_project" "test" { + name = "%s" + service_role = "${aws_iam_role.test.arn}" + + artifacts { + type = "NO_ARTIFACTS" + } + + environment { + compute_type = "BUILD_GENERAL1_SMALL" + image = "2" + type = "LINUX_CONTAINER" + } + + source { + location = "https://example.com/organization/repository.git" + type = "GITHUB_ENTERPRISE" + + git_submodules_config { + fetch_submodules = %t + } + } +} +`, rName, fetchSubmodules) +} + +func testAccAWSCodeBuildProjectConfig_SecondarySources_GitSubmodulesConfig_CodeCommit(rName string, fetchSubmodules bool) string { return testAccAWSCodeBuildProjectConfig_Base_ServiceRole(rName) + fmt.Sprintf(` resource "aws_codebuild_project" "test" { name = "%[1]s" @@ -2783,6 +2963,102 @@ resource "aws_codebuild_project" "test" { `, rName, fetchSubmodules) } +func testAccAWSCodeBuildProjectConfig_SecondarySources_GitSubmodulesConfig_GitHub(rName string, fetchSubmodules bool) string { + return testAccAWSCodeBuildProjectConfig_Base_ServiceRole(rName) + fmt.Sprintf(` +resource "aws_codebuild_project" "test" { + name = "%[1]s" + service_role = "${aws_iam_role.test.arn}" + + artifacts { + type = "NO_ARTIFACTS" + } + + environment { + compute_type = "BUILD_GENERAL1_SMALL" + image = "2" + type = "LINUX_CONTAINER" + } + + source { + location = "https://github.com/hashicorp/packer.git" + type = "GITHUB" + + git_submodules_config { + fetch_submodules = %[2]t + } + } + + secondary_sources { + location = "https://github.com/hashicorp/terraform.git" + type = "GITHUB" + source_identifier = "secondarySource1" + + git_submodules_config { + fetch_submodules = %[2]t + } + } + + secondary_sources { + location = "https://github.com/hashicorp/vault.git" + type = "GITHUB" + source_identifier = "secondarySource2" + + git_submodules_config { + fetch_submodules = %[2]t + } + } +} +`, rName, fetchSubmodules) +} + +func testAccAWSCodeBuildProjectConfig_SecondarySources_GitSubmodulesConfig_GitHubEnterprise(rName string, fetchSubmodules bool) string { + return testAccAWSCodeBuildProjectConfig_Base_ServiceRole(rName) + fmt.Sprintf(` +resource "aws_codebuild_project" "test" { + name = "%[1]s" + service_role = "${aws_iam_role.test.arn}" + + artifacts { + type = "NO_ARTIFACTS" + } + + environment { + compute_type = "BUILD_GENERAL1_SMALL" + image = "2" + type = "LINUX_CONTAINER" + } + + source { + location = "https://example.com/organization/repository-1.git" + type = "GITHUB_ENTERPRISE" + + git_submodules_config { + fetch_submodules = %[2]t + } + } + + secondary_sources { + location = "https://example.com/organization/repository-2.git" + type = "GITHUB_ENTERPRISE" + source_identifier = "secondarySource1" + + git_submodules_config { + fetch_submodules = %[2]t + } + } + + secondary_sources { + location = "https://example.com/organization/repository-3.git" + type = "GITHUB_ENTERPRISE" + source_identifier = "secondarySource2" + + git_submodules_config { + fetch_submodules = %[2]t + } + } +} +`, rName, fetchSubmodules) +} + func testAccAWSCodeBuildProjectConfig_Source_InsecureSSL(rName string, insecureSSL bool) string { return testAccAWSCodeBuildProjectConfig_Base_ServiceRole(rName) + fmt.Sprintf(` resource "aws_codebuild_project" "test" { diff --git a/website/docs/r/codebuild_project.html.markdown b/website/docs/r/codebuild_project.html.markdown index 8df9443a4da..838dc0060c1 100755 --- a/website/docs/r/codebuild_project.html.markdown +++ b/website/docs/r/codebuild_project.html.markdown @@ -298,7 +298,7 @@ The following arguments are supported: * `auth` - (Optional) Information about the authorization settings for AWS CodeBuild to access the source code to be built. Auth blocks are documented below. * `buildspec` - (Optional) The build spec declaration to use for this build project's related builds. This must be set when `type` is `NO_SOURCE`. * `git_clone_depth` - (Optional) Truncate git history to this many commits. -* `git_submodules_config` - (Optional) Information about the Git submodules configuration for an AWS CodeBuild build project. Git submodules config blocks are documented below. This option is only valid when the `type` is `CODECOMMIT`. +* `git_submodules_config` - (Optional) Information about the Git submodules configuration for an AWS CodeBuild build project. Git submodules config blocks are documented below. This option is only valid when the `type` is `CODECOMMIT`, `GITHUB` or `GITHUB_ENTERPRISE`. * `insecure_ssl` - (Optional) Ignore SSL warnings when connecting to source control. * `location` - (Optional) The location of the source code from git or s3. * `report_build_status` - (Optional) Set to `true` to report the status of a build's start and finish to your source provider. This option is only valid when the `type` is `BITBUCKET` or `GITHUB`. @@ -343,7 +343,7 @@ The following arguments are supported: * `auth` - (Optional) Information about the authorization settings for AWS CodeBuild to access the source code to be built. Auth blocks are documented below. * `buildspec` - (Optional) The build spec declaration to use for this build project's related builds. * `git_clone_depth` - (Optional) Truncate git history to this many commits. -* `git_submodules_config` - (Optional) Information about the Git submodules configuration for an AWS CodeBuild build project. Git submodules config blocks are documented below. This option is only valid when the `type` is `CODECOMMIT`. +* `git_submodules_config` - (Optional) Information about the Git submodules configuration for an AWS CodeBuild build project. Git submodules config blocks are documented below. This option is only valid when the `type` is `CODECOMMIT`, `GITHUB` or `GITHUB_ENTERPRISE`. * `insecure_ssl` - (Optional) Ignore SSL warnings when connecting to source control. * `location` - (Optional) The location of the source code from git or s3. * `report_build_status` - (Optional) Set to `true` to report the status of a build's start and finish to your source provider. This option is only valid when your source provider is `GITHUB`, `BITBUCKET`, or `GITHUB_ENTERPRISE`. From 101e5831e3ff083a96c8be2baaa59d5c8009fc9b Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Wed, 13 May 2020 18:48:40 -0400 Subject: [PATCH 135/475] Update CHANGELOG for #13285 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47d4274891d..b8a9533d146 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ FEATURES: ENHANCEMENTS: * resource/aws_appsync_resolver: Add `cache_config` configuration block [GH-12747] +* resource/aws_codebuild_project: Support `git_submodules_config` with `GITHUB` and `GITHUB_ENTERPRISE` source types [GH-13285] * resource/aws_iot_topic_rule: Add `dynamodbv2` configuration block [GH-7469] * resource/aws_iot_topic_rule: Add `iot_analytics` configuration block [GH-9859] * resource/aws_iot_topic_rule: Add `iot_events` configuration block [GH-9890] From a04a87ff508f1d9d35a5b7f359acca76b3fae46c Mon Sep 17 00:00:00 2001 From: Ilia Lazebnik Date: Thu, 14 May 2020 02:35:33 +0300 Subject: [PATCH 136/475] resource/code_build_project: Support `SECRETS_MANAGER` environment variable type (#12572) Output from acceptance testing: ``` --- PASS: TestAccAWSCodeBuildProject_ARMContainer (51.36s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_ArtifactIdentifier (59.59s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_EncryptionDisabled (50.31s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_Location (52.12s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_Name (55.52s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_NamespaceType (71.22s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_OverrideArtifactName (51.42s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_Packaging (66.88s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_Path (136.38s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_Type (57.44s) --- PASS: TestAccAWSCodeBuildProject_BadgeEnabled (139.30s) --- PASS: TestAccAWSCodeBuildProject_basic (213.92s) --- PASS: TestAccAWSCodeBuildProject_BuildTimeout (141.25s) --- PASS: TestAccAWSCodeBuildProject_Cache (131.13s) --- PASS: TestAccAWSCodeBuildProject_Description (255.64s) --- PASS: TestAccAWSCodeBuildProject_EncryptionKey (96.63s) --- PASS: TestAccAWSCodeBuildProject_Environment_Certificate (118.66s) --- PASS: TestAccAWSCodeBuildProject_Environment_EnvironmentVariable (96.55s) --- PASS: TestAccAWSCodeBuildProject_Environment_EnvironmentVariable_Type (89.49s) --- PASS: TestAccAWSCodeBuildProject_Environment_RegistryCredential (45.40s) --- PASS: TestAccAWSCodeBuildProject_LogsConfig_CloudWatchLogs (208.37s) --- PASS: TestAccAWSCodeBuildProject_LogsConfig_S3Logs (60.20s) --- PASS: TestAccAWSCodeBuildProject_QueuedTimeout (191.67s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts (107.20s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_ArtifactIdentifier (107.64s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_EncryptionDisabled (59.17s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_Location (58.55s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_NamespaceType (51.40s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_OverrideArtifactName (75.29s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_Packaging (60.88s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_Path (58.67s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_Type (37.54s) --- PASS: TestAccAWSCodeBuildProject_SecondarySources_CodeCommit (29.09s) --- PASS: TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig_CodeCommit (84.75s) --- PASS: TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig_GitHub (33.16s) --- PASS: TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig_GitHubEnterprise (99.87s) --- PASS: TestAccAWSCodeBuildProject_Source_GitCloneDepth (62.26s) --- PASS: TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig_CodeCommit (413.30s) --- PASS: TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig_GitHub (75.20s) --- PASS: TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig_GitHubEnterprise (84.41s) --- PASS: TestAccAWSCodeBuildProject_Source_InsecureSSL (65.06s) --- PASS: TestAccAWSCodeBuildProject_Source_ReportBuildStatus_Bitbucket (72.43s) --- PASS: TestAccAWSCodeBuildProject_Source_ReportBuildStatus_GitHub (93.92s) --- PASS: TestAccAWSCodeBuildProject_Source_ReportBuildStatus_GitHubEnterprise (49.30s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_Bitbucket (53.10s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_CodeCommit (59.52s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_CodePipeline (59.35s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_GitHubEnterprise (236.48s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_NoSource (29.16s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_NoSourceInvalid (12.59s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_S3 (155.73s) --- PASS: TestAccAWSCodeBuildProject_SourceVersion (60.28s) --- PASS: TestAccAWSCodeBuildProject_Tags (48.47s) --- PASS: TestAccAWSCodeBuildProject_WindowsContainer (69.49s) ``` --- aws/resource_aws_codebuild_project.go | 1 + aws/resource_aws_codebuild_project_test.go | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/aws/resource_aws_codebuild_project.go b/aws/resource_aws_codebuild_project.go index 8de95e27432..c79a09302b6 100644 --- a/aws/resource_aws_codebuild_project.go +++ b/aws/resource_aws_codebuild_project.go @@ -195,6 +195,7 @@ func resourceAwsCodeBuildProject() *schema.Resource { ValidateFunc: validation.StringInSlice([]string{ codebuild.EnvironmentVariableTypePlaintext, codebuild.EnvironmentVariableTypeParameterStore, + codebuild.EnvironmentVariableTypeSecretsManager, }, false), Default: codebuild.EnvironmentVariableTypePlaintext, }, diff --git a/aws/resource_aws_codebuild_project_test.go b/aws/resource_aws_codebuild_project_test.go index 02399e29ad8..9f2f0920233 100644 --- a/aws/resource_aws_codebuild_project_test.go +++ b/aws/resource_aws_codebuild_project_test.go @@ -423,6 +423,14 @@ func TestAccAWSCodeBuildProject_Environment_EnvironmentVariable_Type(t *testing. resource.TestCheckResourceAttr(resourceName, "environment.1701234421.environment_variable.1.type", "PARAMETER_STORE"), ), }, + { + Config: testAccAWSCodeBuildProjectConfig_Environment_EnvironmentVariable_Type(rName, "SECRETS_MANAGER"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeBuildProjectExists(resourceName, &project), + resource.TestCheckResourceAttr(resourceName, "environment.198523880.environment_variable.0.type", "PLAINTEXT"), + resource.TestCheckResourceAttr(resourceName, "environment.198523880.environment_variable.1.type", "SECRETS_MANAGER"), + ), + }, }, }) } From bb439fbb99d018005d8b4f8541a4f9cf4131245f Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Wed, 13 May 2020 19:37:55 -0400 Subject: [PATCH 137/475] Update CHANGELOG for #12572 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8a9533d146..6b440912838 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ENHANCEMENTS: * resource/aws_appsync_resolver: Add `cache_config` configuration block [GH-12747] * resource/aws_codebuild_project: Support `git_submodules_config` with `GITHUB` and `GITHUB_ENTERPRISE` source types [GH-13285] +* resource/aws_codebuild_project: Support `SECRETS_MANAGER` environment variable type [GH-12572] * resource/aws_iot_topic_rule: Add `dynamodbv2` configuration block [GH-7469] * resource/aws_iot_topic_rule: Add `iot_analytics` configuration block [GH-9859] * resource/aws_iot_topic_rule: Add `iot_events` configuration block [GH-9890] From 744813401342b117f12a81fc2c07db937f61b331 Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Tue, 12 May 2020 15:55:21 -0700 Subject: [PATCH 138/475] Fixes errors, adds README, and makes example easier to run out-of-the-box --- examples/workspaces/README.md | 20 ++++++ examples/workspaces/iam.tf | 25 ++++++++ examples/workspaces/main.tf | 102 +++++++++++++++++++++---------- examples/workspaces/variables.tf | 4 ++ 4 files changed, 118 insertions(+), 33 deletions(-) create mode 100644 examples/workspaces/README.md create mode 100644 examples/workspaces/iam.tf create mode 100644 examples/workspaces/variables.tf diff --git a/examples/workspaces/README.md b/examples/workspaces/README.md new file mode 100644 index 00000000000..021b75b46dd --- /dev/null +++ b/examples/workspaces/README.md @@ -0,0 +1,20 @@ +# AWS WorkSpaces Example + +This example demonstrates how to create a WorkSpace and WorkSpace directory using AWS WorkSpaces. + +## Note + +The AWS WorkSpaces service requires an IAM role named `workspaces_DefaultRole`. This example creates this role and attaches policies to it. This will cause an error if the role already exists in the AWS account. + +The IAM resources are defined in the Terraform source file [iam.tf](./iam.tf). If the role exists, remove the IAM resource file. The resources `aws_workspaces_directory.example` and `aws_workspaces_workspace.example` have dependencies on the IAM resources. The `depends_on` blocks can be removed from both. + +## Running this example + +This example can be run by calling + +```shell +terraform init +terraform apply +``` + +By default, resources are created in the `us-west-2` region. To override the region, set the variable `aws_region` to a different value. diff --git a/examples/workspaces/iam.tf b/examples/workspaces/iam.tf new file mode 100644 index 00000000000..a18efb674d5 --- /dev/null +++ b/examples/workspaces/iam.tf @@ -0,0 +1,25 @@ +resource "aws_iam_role" "workspaces-default" { + name = "workspaces_DefaultRole" + assume_role_policy = data.aws_iam_policy_document.workspaces.json +} + +data "aws_iam_policy_document" "workspaces" { + statement { + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["workspaces.amazonaws.com"] + } + } +} + +resource "aws_iam_role_policy_attachment" "workspaces-default-service-access" { + role = aws_iam_role.workspaces-default.name + policy_arn = "arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess" +} + +resource "aws_iam_role_policy_attachment" "workspaces-default-self-service-access" { + role = aws_iam_role.workspaces-default.name + policy_arn = "arn:aws:iam::aws:policy/AmazonWorkSpacesSelfServiceAccess" +} diff --git a/examples/workspaces/main.tf b/examples/workspaces/main.tf index 74f05db8649..0bbdb041c6a 100644 --- a/examples/workspaces/main.tf +++ b/examples/workspaces/main.tf @@ -1,50 +1,30 @@ provider "aws" { - region = "us-east-1" + region = "${var.aws_region}" } -resource "aws_vpc" "main" { - cidr_block = "10.0.0.0/16" -} - -resource "aws_subnet" "private-a" { - vpc_id = "${aws_vpc.main.id}" - availability_zone = "us-east-1a" - cidr_block = "10.0.1.0/24" -} - -resource "aws_subnet" "private-b" { - vpc_id = "${aws_vpc.main.id}" - availability_zone = "us-east-1b" - cidr_block = "10.0.2.0/24" -} - -resource "aws_directory_service_directory" "main" { - name = "tf-acctest.example.com" - password = "#S1ncerely" - size = "Small" - vpc_settings { - vpc_id = "${aws_vpc.main.id}" - subnet_ids = ["${aws_subnet.private-a.id}", "${aws_subnet.private-b.id}"] - } -} - -resource "aws_workspaces_directory" "main" { - directory_id = "${aws_directory_service_directory.main.id}" +resource "aws_workspaces_directory" "example" { + directory_id = "${aws_directory_service_directory.example.id}" subnet_ids = ["${aws_subnet.private-a.id}", "${aws_subnet.private-b.id}"] + + depends_on = [ + aws_iam_role.workspaces-default + ] } data "aws_workspaces_bundle" "value_windows" { bundle_id = "wsb-bh8rsxt14" # Value with Windows 10 (English) } -resource "aws_workspaces_workspace" "jhon_doe" { - directory_id = "${aws_workspaces_directory.main.id}" +resource "aws_workspaces_workspace" "example" { + directory_id = "${aws_workspaces_directory.example.id}" bundle_id = "${data.aws_workspaces_bundle.value_windows.id}" - user_name = "jhon.doe" + + # Administrator is always present in a new directory. + user_name = "Administrator" root_volume_encryption_enabled = true user_volume_encryption_enabled = true - volume_encryption_key = "aws/workspaces" + volume_encryption_key = data.aws_kms_key.workspaces_default.arn workspace_properties { compute_type_name = "VALUE" @@ -57,6 +37,12 @@ resource "aws_workspaces_workspace" "jhon_doe" { tags = { Department = "IT" } + + depends_on = [ + # The role "workspaces_DefaultRole" requires the policy arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess + # to create and delete the ENI that the Workspaces service creates for the Workspace + aws_iam_role_policy_attachment.workspaces-default-service-access, + ] } resource "aws_workspaces_ip_group" "main" { @@ -72,3 +58,53 @@ resource "aws_workspaces_ip_group" "main" { description = "Contractors" } } + +data "aws_region" "current" {} + +data "aws_availability_zones" "available" { + state = "available" + + filter { + name = "opt-in-status" + values = ["opt-in-not-required"] + } +} + +locals { + # Workspace instances are not supported in all AZs in some regions + region_workspaces_az_ids = { + "us-east-1" = formatlist("use1-az%d", [2, 4, 6]) + } + + workspaces_az_ids = lookup(local.region_workspaces_az_ids, data.aws_region.current.name, data.aws_availability_zones.available.zone_ids) +} + +resource "aws_vpc" "main" { + cidr_block = "10.0.0.0/16" +} + +resource "aws_subnet" "private-a" { + vpc_id = "${aws_vpc.main.id}" + availability_zone_id = "${local.workspaces_az_ids[0]}" + cidr_block = "10.0.1.0/24" +} + +resource "aws_subnet" "private-b" { + vpc_id = "${aws_vpc.main.id}" + availability_zone_id = "${local.workspaces_az_ids[1]}" + cidr_block = "10.0.2.0/24" +} + +resource "aws_directory_service_directory" "example" { + name = "workspaces.example.com" + password = "#S1ncerely" + size = "Small" + vpc_settings { + vpc_id = "${aws_vpc.main.id}" + subnet_ids = ["${aws_subnet.private-a.id}", "${aws_subnet.private-b.id}"] + } +} + +data "aws_kms_key" "workspaces_default" { + key_id = "alias/aws/workspaces" +} diff --git a/examples/workspaces/variables.tf b/examples/workspaces/variables.tf new file mode 100644 index 00000000000..3c91c693825 --- /dev/null +++ b/examples/workspaces/variables.tf @@ -0,0 +1,4 @@ +variable "aws_region" { + description = "The AWS region to use" + default = "us-west-2" +} From 5e75bda8d9f4ce4a529dcc2a60cd8b2bd2072630 Mon Sep 17 00:00:00 2001 From: Daryl Clarino Date: Thu, 14 May 2020 19:01:56 +0800 Subject: [PATCH 139/475] Update documentation for API gateway integration. --- website/docs/r/api_gateway_integration.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/api_gateway_integration.html.markdown b/website/docs/r/api_gateway_integration.html.markdown index f28ea2d885d..24c1bcf3f0b 100644 --- a/website/docs/r/api_gateway_integration.html.markdown +++ b/website/docs/r/api_gateway_integration.html.markdown @@ -219,7 +219,7 @@ The following arguments are supported: * `connection_id` - (Optional) The id of the VpcLink used for the integration. **Required** if `connection_type` is `VPC_LINK` * `uri` - (Optional) The input's URI. **Required** if `type` is `AWS`, `AWS_PROXY`, `HTTP` or `HTTP_PROXY`. For HTTP integrations, the URI must be a fully formed, encoded HTTP(S) URL according to the RFC-3986 specification . For AWS integrations, the URI should be of the form `arn:aws:apigateway:{region}:{subdomain.service|service}:{path|action}/{service_api}`. `region`, `subdomain` and `service` are used to determine the right endpoint. - e.g. `arn:aws:apigateway:eu-west-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-1:012345678901:function:my-func/invocations` + e.g. `arn:aws:apigateway:eu-west-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-1:012345678901:function:my-func/invocations`. For private integrations, the URI parameter is not used for routing requests to your endpoint, but is used for setting the Host header and for certificate validation. * `credentials` - (Optional) The credentials required for the integration. For `AWS` integrations, 2 options are available. To specify an IAM Role for Amazon API Gateway to assume, use the role's ARN. To require that the caller's identity be passed through from the request, specify the string `arn:aws:iam::\*:user/\*`. * `request_templates` - (Optional) A map of the integration's request templates. * `request_parameters` - (Optional) A map of request query string parameters and headers that should be passed to the backend responder. From 941de448465dd3619fbde6ced64ab4111b1d5fe2 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 14 May 2020 09:47:17 -0400 Subject: [PATCH 140/475] ROADMAP.md: Fix WAFv2 link (#13240) --- ROADMAP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ROADMAP.md b/ROADMAP.md index e52eb0cb9b1..c65b2f7cd12 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -22,7 +22,7 @@ We'll be updating the linked milestone as we work to finalize and complete v3.0. ### WAFv2 -Issue: [#11406](https://github.com/terraform-providers/terraform-provider-aws/issues/11406) +Issue: [#11046](https://github.com/terraform-providers/terraform-provider-aws/issues/11046) _AWS WAFv2 is a web application firewall that lets you monitor the HTTP and HTTPS requests that are forwarded to Amazon CloudFront, an Amazon API Gateway API, or an Application Load Balancer._ From 117eb58dbb2883b67581260d895dba84db04a177 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Thu, 14 May 2020 10:36:51 -0400 Subject: [PATCH 141/475] tests/resource/aws_codebuild_project: Add testing for empty value environment variables Output from acceptance testing: ``` --- PASS: TestAccAWSCodeBuildProject_ARMContainer (39.86s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_ArtifactIdentifier (81.65s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_EncryptionDisabled (70.59s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_Location (87.62s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_Name (91.10s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_NamespaceType (258.73s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_OverrideArtifactName (118.21s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_Packaging (70.05s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_Path (73.74s) --- PASS: TestAccAWSCodeBuildProject_Artifacts_Type (93.82s) --- PASS: TestAccAWSCodeBuildProject_BadgeEnabled (39.29s) --- PASS: TestAccAWSCodeBuildProject_basic (63.85s) --- PASS: TestAccAWSCodeBuildProject_BuildTimeout (59.79s) --- PASS: TestAccAWSCodeBuildProject_Cache (114.45s) --- PASS: TestAccAWSCodeBuildProject_Description (62.95s) --- PASS: TestAccAWSCodeBuildProject_EncryptionKey (35.11s) --- PASS: TestAccAWSCodeBuildProject_Environment_Certificate (42.82s) --- PASS: TestAccAWSCodeBuildProject_Environment_EnvironmentVariable (79.42s) --- PASS: TestAccAWSCodeBuildProject_Environment_EnvironmentVariable_Type (55.91s) --- PASS: TestAccAWSCodeBuildProject_Environment_EnvironmentVariable_Value (74.23s) --- PASS: TestAccAWSCodeBuildProject_Environment_RegistryCredential (73.93s) --- PASS: TestAccAWSCodeBuildProject_LogsConfig_CloudWatchLogs (140.78s) --- PASS: TestAccAWSCodeBuildProject_LogsConfig_S3Logs (95.25s) --- PASS: TestAccAWSCodeBuildProject_QueuedTimeout (52.16s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts (54.12s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_ArtifactIdentifier (73.72s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_EncryptionDisabled (108.53s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_Location (214.27s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_NamespaceType (254.34s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_OverrideArtifactName (83.88s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_Packaging (84.60s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_Path (116.28s) --- PASS: TestAccAWSCodeBuildProject_SecondaryArtifacts_Type (68.43s) --- PASS: TestAccAWSCodeBuildProject_SecondarySources_CodeCommit (67.24s) --- PASS: TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig_CodeCommit (83.27s) --- PASS: TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig_GitHub (60.29s) --- PASS: TestAccAWSCodeBuildProject_SecondarySources_GitSubmodulesConfig_GitHubEnterprise (147.52s) --- PASS: TestAccAWSCodeBuildProject_Source_GitCloneDepth (77.52s) --- PASS: TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig_CodeCommit (66.13s) --- PASS: TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig_GitHub (133.77s) --- PASS: TestAccAWSCodeBuildProject_Source_GitSubmodulesConfig_GitHubEnterprise (64.05s) --- PASS: TestAccAWSCodeBuildProject_Source_InsecureSSL (61.09s) --- PASS: TestAccAWSCodeBuildProject_Source_ReportBuildStatus_Bitbucket (95.29s) --- PASS: TestAccAWSCodeBuildProject_Source_ReportBuildStatus_GitHub (77.35s) --- PASS: TestAccAWSCodeBuildProject_Source_ReportBuildStatus_GitHubEnterprise (78.94s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_Bitbucket (49.18s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_CodeCommit (91.76s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_CodePipeline (106.13s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_GitHubEnterprise (46.19s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_NoSource (36.11s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_NoSourceInvalid (13.10s) --- PASS: TestAccAWSCodeBuildProject_Source_Type_S3 (43.01s) --- PASS: TestAccAWSCodeBuildProject_SourceVersion (42.91s) --- PASS: TestAccAWSCodeBuildProject_Tags (48.42s) --- PASS: TestAccAWSCodeBuildProject_WindowsContainer (35.04s) ``` --- aws/resource_aws_codebuild_project_test.go | 80 +++++++++++++++++----- 1 file changed, 62 insertions(+), 18 deletions(-) diff --git a/aws/resource_aws_codebuild_project_test.go b/aws/resource_aws_codebuild_project_test.go index 9f2f0920233..8f36d201484 100644 --- a/aws/resource_aws_codebuild_project_test.go +++ b/aws/resource_aws_codebuild_project_test.go @@ -346,16 +346,14 @@ func TestAccAWSCodeBuildProject_Environment_EnvironmentVariable(t *testing.T) { resourceName := "aws_codebuild_project.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSCodeBuild(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSCodeBuildProjectDestroy, - DisableBinaryDriver: true, + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSCodeBuild(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCodeBuildProjectDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSCodeBuildProjectConfig_Environment_EnvironmentVariable_One(rName), + Config: testAccAWSCodeBuildProjectConfig_Environment_EnvironmentVariable_One(rName, "KEY1", "VALUE1"), Check: resource.ComposeTestCheckFunc( testAccCheckAWSCodeBuildProjectExists(resourceName, &project1), - resource.TestCheckResourceAttr(resourceName, "environment.1380979031.environment_variable.#", "1"), ), }, { @@ -364,10 +362,9 @@ func TestAccAWSCodeBuildProject_Environment_EnvironmentVariable(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccAWSCodeBuildProjectConfig_Environment_EnvironmentVariable_Two(rName), + Config: testAccAWSCodeBuildProjectConfig_Environment_EnvironmentVariable_Two(rName, "KEY1", "VALUE1UPDATED", "KEY2", "VALUE2"), Check: resource.ComposeTestCheckFunc( testAccCheckAWSCodeBuildProjectExists(resourceName, &project2), - resource.TestCheckResourceAttr(resourceName, "environment.4178155002.environment_variable.#", "2"), ), }, { @@ -435,6 +432,53 @@ func TestAccAWSCodeBuildProject_Environment_EnvironmentVariable_Type(t *testing. }) } +func TestAccAWSCodeBuildProject_Environment_EnvironmentVariable_Value(t *testing.T) { + var project1, project2, project3 codebuild.Project + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_codebuild_project.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSCodeBuild(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSCodeBuildProjectDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCodeBuildProjectConfig_Environment_EnvironmentVariable_One(rName, "KEY1", ""), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeBuildProjectExists(resourceName, &project1), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSCodeBuildProjectConfig_Environment_EnvironmentVariable_One(rName, "KEY1", "VALUE1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeBuildProjectExists(resourceName, &project2), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSCodeBuildProjectConfig_Environment_EnvironmentVariable_One(rName, "KEY1", ""), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSCodeBuildProjectExists(resourceName, &project3), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAWSCodeBuildProject_Environment_Certificate(t *testing.T) { var project codebuild.Project rName := acctest.RandomWithPrefix("tf-acc-test") @@ -2488,7 +2532,7 @@ resource "aws_codebuild_project" "test" { `, rName) } -func testAccAWSCodeBuildProjectConfig_Environment_EnvironmentVariable_One(rName string) string { +func testAccAWSCodeBuildProjectConfig_Environment_EnvironmentVariable_One(rName, key1, value1 string) string { return testAccAWSCodeBuildProjectConfig_Base_ServiceRole(rName) + fmt.Sprintf(` resource "aws_codebuild_project" "test" { name = %[1]q @@ -2504,8 +2548,8 @@ resource "aws_codebuild_project" "test" { type = "LINUX_CONTAINER" environment_variable { - name = "SOME_KEY" - value = "SOME_VALUE" + name = %[2]q + value = %[3]q } } @@ -2514,10 +2558,10 @@ resource "aws_codebuild_project" "test" { location = "https://github.com/hashicorp/packer.git" } } -`, rName) +`, rName, key1, value1) } -func testAccAWSCodeBuildProjectConfig_Environment_EnvironmentVariable_Two(rName string) string { +func testAccAWSCodeBuildProjectConfig_Environment_EnvironmentVariable_Two(rName, key1, value1, key2, value2 string) string { return testAccAWSCodeBuildProjectConfig_Base_ServiceRole(rName) + fmt.Sprintf(` resource "aws_codebuild_project" "test" { name = %[1]q @@ -2533,13 +2577,13 @@ resource "aws_codebuild_project" "test" { type = "LINUX_CONTAINER" environment_variable { - name = "SOME_KEY" - value = "SOME_VALUE" + name = %[2]q + value = %[3]q } environment_variable { - name = "SOME_KEY2" - value = "SOME_VALUE2" + name = %[4]q + value = %[5]q } } @@ -2548,7 +2592,7 @@ resource "aws_codebuild_project" "test" { location = "https://github.com/hashicorp/packer.git" } } -`, rName) +`, rName, key1, value1, key2, value2) } func testAccAWSCodeBuildProjectConfig_Environment_EnvironmentVariable_Zero(rName string) string { From d8c44f598164699d7896507e3f6b1310dbb774f3 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Thu, 14 May 2020 10:40:09 -0400 Subject: [PATCH 142/475] Update CHANGELOG for #11572 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b440912838..5dc39ae3764 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ ENHANCEMENTS: * resource/aws_iot_topic_rule: Add `operation` argument to `dynamodb` configuration block [GH-12714] * resource/aws_iot_topic_rule: Add `qos` argument `republish` configuration block [GH-12869] +BUG FIXES: + +* resource/aws_codebuild_project: Allow empty value (`""`) environment variables [GH-11572] + ## 2.61.0 (May 08, 2020) FEATURES: From 338fe8bbe20c7e5dae459b54f6f5d0ec45a28826 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Thu, 14 May 2020 11:25:48 -0400 Subject: [PATCH 143/475] infrastructure/repository: Synchronize recent AWS service labels and bump GitHub provider to latest (#13226) Reference: https://github.com/aws/aws-sdk-go/tree/master/service Now that contributors can add these labels when submitting new services (as documented in the Contributing Guide), this manual bulk process should be less common. --- infrastructure/repository/labels-service.tf | 7 +++++++ infrastructure/repository/main.tf | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/infrastructure/repository/labels-service.tf b/infrastructure/repository/labels-service.tf index 079baf5d5cb..c5472d83e67 100644 --- a/infrastructure/repository/labels-service.tf +++ b/infrastructure/repository/labels-service.tf @@ -45,6 +45,7 @@ variable "service_labels" { "codegurureviewer", "codepipeline", "codestar", + "codestarconnections", "codestarnotifications", "cognito", "comprehend", @@ -53,11 +54,13 @@ variable "service_labels" { "configservice", "connect", "costandusagereportservice", + "costexplorer", "databasemigrationservice", "dataexchange", "datapipeline", "datasync", "dax", + "detective", "devicefarm", "directconnect", "directoryservice", @@ -98,6 +101,7 @@ variable "service_labels" { "iotanalytics", "iotevents", "iotsecuretunneling", + "iotsitewise", "iotthingsgraph", "kafka", "kendra", @@ -171,8 +175,11 @@ variable "service_labels" { "sts", "support", "swf", + "synthetics", + "textract", "transcribeservice", "transfer", + "translate", "waf", "wafv2", "workdocs", diff --git a/infrastructure/repository/main.tf b/infrastructure/repository/main.tf index f2768d87538..4a55664a872 100644 --- a/infrastructure/repository/main.tf +++ b/infrastructure/repository/main.tf @@ -4,7 +4,7 @@ terraform { } required_providers { - github = "2.1.0" + github = "2.7.0" } required_version = "~> 0.12.24" From 6e1e3c01eff21f7225b6f5bfdb2cfccbb7f8a016 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 14 May 2020 11:35:48 -0400 Subject: [PATCH 144/475] provider: Add Transit Gateway Network Manager service client and resource tagging (#13262) * Add Transit Gateway Network Manager service client. * internal/keyvaluetags: Support network manager * Add list-tags support for Network Manager. Co-authored-by: Omarimcblack --- .hashibot.hcl | 7 + aws/config.go | 3 + .../keyvaluetags/generators/listtags/main.go | 1 + .../generators/servicetags/main.go | 1 + .../generators/updatetags/main.go | 1 + aws/internal/keyvaluetags/list_tags_gen.go | 18 + .../service_generation_customizations.go | 5 + aws/internal/keyvaluetags/service_tags_gen.go | 28 + aws/internal/keyvaluetags/update_tags_gen.go | 37 + aws/provider.go | 1 + .../aws-sdk-go/service/networkmanager/api.go | 7093 +++++++++++++++++ .../aws-sdk-go/service/networkmanager/doc.go | 30 + .../service/networkmanager/errors.go | 63 + .../service/networkmanager/service.go | 104 + vendor/modules.txt | 1 + website/allowed-subcategories.txt | 1 + .../guides/custom-service-endpoints.html.md | 1 + 17 files changed, 7395 insertions(+) create mode 100644 vendor/github.com/aws/aws-sdk-go/service/networkmanager/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/networkmanager/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/networkmanager/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/networkmanager/service.go diff --git a/.hashibot.hcl b/.hashibot.hcl index 86dbb9baf67..d1bad0eb7ff 100644 --- a/.hashibot.hcl +++ b/.hashibot.hcl @@ -385,6 +385,9 @@ behavior "regexp_issue_labeler_v2" "service_labels" { "service/neptune" = [ "aws_neptune_", ], + "service/networkmanager" = [ + "aws_networkmanager_", + ], "service/opsworks" = [ "aws_opsworks_", ], @@ -1041,6 +1044,10 @@ behavior "pull_request_path_labeler" "service_labels" { "**/*_neptune_*", "**/neptune_*" ] + "service/networkmanager" = [ + "**/*_networkmanager_*", + "**/networkmanager_*" + ] "service/opsworks" = [ "**/*_opsworks_*", "**/opsworks_*" diff --git a/aws/config.go b/aws/config.go index 0348e71e5d0..fcdc8c6fc2a 100644 --- a/aws/config.go +++ b/aws/config.go @@ -105,6 +105,7 @@ import ( "github.com/aws/aws-sdk-go/service/mediastoredata" "github.com/aws/aws-sdk-go/service/mq" "github.com/aws/aws-sdk-go/service/neptune" + "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/aws/aws-sdk-go/service/opsworks" "github.com/aws/aws-sdk-go/service/organizations" "github.com/aws/aws-sdk-go/service/personalize" @@ -283,6 +284,7 @@ type AWSClient struct { mediastoredataconn *mediastoredata.MediaStoreData mqconn *mq.MQ neptuneconn *neptune.Neptune + networkmanagerconn *networkmanager.NetworkManager opsworksconn *opsworks.OpsWorks organizationsconn *organizations.Organizations partition string @@ -500,6 +502,7 @@ func (c *Config) Client() (interface{}, error) { mediastoredataconn: mediastoredata.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["mediastoredata"])})), mqconn: mq.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["mq"])})), neptuneconn: neptune.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["neptune"])})), + networkmanagerconn: networkmanager.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["networkmanager"])})), opsworksconn: opsworks.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["opsworks"])})), organizationsconn: organizations.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["organizations"])})), partition: partition, diff --git a/aws/internal/keyvaluetags/generators/listtags/main.go b/aws/internal/keyvaluetags/generators/listtags/main.go index d0b4f1cff54..a865a37f219 100644 --- a/aws/internal/keyvaluetags/generators/listtags/main.go +++ b/aws/internal/keyvaluetags/generators/listtags/main.go @@ -88,6 +88,7 @@ var serviceNames = []string{ "mediastore", "mq", "neptune", + "networkmanager", "opsworks", "organizations", "pinpoint", diff --git a/aws/internal/keyvaluetags/generators/servicetags/main.go b/aws/internal/keyvaluetags/generators/servicetags/main.go index 4382879b7a0..79a7a1743bb 100644 --- a/aws/internal/keyvaluetags/generators/servicetags/main.go +++ b/aws/internal/keyvaluetags/generators/servicetags/main.go @@ -71,6 +71,7 @@ var sliceServiceNames = []string{ "lightsail", "mediastore", "neptune", + "networkmanager", "organizations", "quicksight", "ram", diff --git a/aws/internal/keyvaluetags/generators/updatetags/main.go b/aws/internal/keyvaluetags/generators/updatetags/main.go index ee18203bf73..628f8ee646a 100644 --- a/aws/internal/keyvaluetags/generators/updatetags/main.go +++ b/aws/internal/keyvaluetags/generators/updatetags/main.go @@ -92,6 +92,7 @@ var serviceNames = []string{ "mediastore", "mq", "neptune", + "networkmanager", "opsworks", "organizations", "pinpoint", diff --git a/aws/internal/keyvaluetags/list_tags_gen.go b/aws/internal/keyvaluetags/list_tags_gen.go index 0aa7e650a53..5afc6631b3c 100644 --- a/aws/internal/keyvaluetags/list_tags_gen.go +++ b/aws/internal/keyvaluetags/list_tags_gen.go @@ -75,6 +75,7 @@ import ( "github.com/aws/aws-sdk-go/service/mediastore" "github.com/aws/aws-sdk-go/service/mq" "github.com/aws/aws-sdk-go/service/neptune" + "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/aws/aws-sdk-go/service/opsworks" "github.com/aws/aws-sdk-go/service/organizations" "github.com/aws/aws-sdk-go/service/pinpoint" @@ -1306,6 +1307,23 @@ func NeptuneListTags(conn *neptune.Neptune, identifier string) (KeyValueTags, er return NeptuneKeyValueTags(output.TagList), nil } +// NetworkmanagerListTags lists networkmanager service tags. +// The identifier is typically the Amazon Resource Name (ARN), although +// it may also be a different identifier depending on the service. +func NetworkmanagerListTags(conn *networkmanager.NetworkManager, identifier string) (KeyValueTags, error) { + input := &networkmanager.ListTagsForResourceInput{ + ResourceArn: aws.String(identifier), + } + + output, err := conn.ListTagsForResource(input) + + if err != nil { + return New(nil), err + } + + return NetworkmanagerKeyValueTags(output.TagList), nil +} + // OpsworksListTags lists opsworks service tags. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. diff --git a/aws/internal/keyvaluetags/service_generation_customizations.go b/aws/internal/keyvaluetags/service_generation_customizations.go index 071ce0d9b5b..c9a11053994 100644 --- a/aws/internal/keyvaluetags/service_generation_customizations.go +++ b/aws/internal/keyvaluetags/service_generation_customizations.go @@ -82,6 +82,7 @@ import ( "github.com/aws/aws-sdk-go/service/mediastore" "github.com/aws/aws-sdk-go/service/mq" "github.com/aws/aws-sdk-go/service/neptune" + "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/aws/aws-sdk-go/service/opsworks" "github.com/aws/aws-sdk-go/service/organizations" "github.com/aws/aws-sdk-go/service/pinpoint" @@ -268,6 +269,8 @@ func ServiceClientType(serviceName string) string { funcType = reflect.TypeOf(mq.New) case "neptune": funcType = reflect.TypeOf(neptune.New) + case "networkmanager": + funcType = reflect.TypeOf(networkmanager.New) case "opsworks": funcType = reflect.TypeOf(opsworks.New) case "organizations": @@ -462,6 +465,8 @@ func ServiceListTagsOutputTagsField(serviceName string) string { return "ResourceTags.Tags" case "neptune": return "TagList" + case "networkmanager": + return "TagList" case "pinpoint": return "TagsModel.Tags" case "rds": diff --git a/aws/internal/keyvaluetags/service_tags_gen.go b/aws/internal/keyvaluetags/service_tags_gen.go index d39d83a52b7..643fd0fc7c3 100644 --- a/aws/internal/keyvaluetags/service_tags_gen.go +++ b/aws/internal/keyvaluetags/service_tags_gen.go @@ -56,6 +56,7 @@ import ( "github.com/aws/aws-sdk-go/service/lightsail" "github.com/aws/aws-sdk-go/service/mediastore" "github.com/aws/aws-sdk-go/service/neptune" + "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/aws/aws-sdk-go/service/organizations" "github.com/aws/aws-sdk-go/service/quicksight" "github.com/aws/aws-sdk-go/service/ram" @@ -1852,6 +1853,33 @@ func NeptuneKeyValueTags(tags []*neptune.Tag) KeyValueTags { return New(m) } +// NetworkmanagerTags returns networkmanager service tags. +func (tags KeyValueTags) NetworkmanagerTags() []*networkmanager.Tag { + result := make([]*networkmanager.Tag, 0, len(tags)) + + for k, v := range tags.Map() { + tag := &networkmanager.Tag{ + Key: aws.String(k), + Value: aws.String(v), + } + + result = append(result, tag) + } + + return result +} + +// NetworkmanagerKeyValueTags creates KeyValueTags from networkmanager service tags. +func NetworkmanagerKeyValueTags(tags []*networkmanager.Tag) KeyValueTags { + m := make(map[string]*string, len(tags)) + + for _, tag := range tags { + m[aws.StringValue(tag.Key)] = tag.Value + } + + return New(m) +} + // OrganizationsTags returns organizations service tags. func (tags KeyValueTags) OrganizationsTags() []*organizations.Tag { result := make([]*organizations.Tag, 0, len(tags)) diff --git a/aws/internal/keyvaluetags/update_tags_gen.go b/aws/internal/keyvaluetags/update_tags_gen.go index ce0a1715fdc..68dc42f29ff 100644 --- a/aws/internal/keyvaluetags/update_tags_gen.go +++ b/aws/internal/keyvaluetags/update_tags_gen.go @@ -81,6 +81,7 @@ import ( "github.com/aws/aws-sdk-go/service/mediastore" "github.com/aws/aws-sdk-go/service/mq" "github.com/aws/aws-sdk-go/service/neptune" + "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/aws/aws-sdk-go/service/opsworks" "github.com/aws/aws-sdk-go/service/organizations" "github.com/aws/aws-sdk-go/service/pinpoint" @@ -2811,6 +2812,42 @@ func NeptuneUpdateTags(conn *neptune.Neptune, identifier string, oldTagsMap inte return nil } +// NetworkmanagerUpdateTags updates networkmanager service tags. +// The identifier is typically the Amazon Resource Name (ARN), although +// it may also be a different identifier depending on the service. +func NetworkmanagerUpdateTags(conn *networkmanager.NetworkManager, identifier string, oldTagsMap interface{}, newTagsMap interface{}) error { + oldTags := New(oldTagsMap) + newTags := New(newTagsMap) + + if removedTags := oldTags.Removed(newTags); len(removedTags) > 0 { + input := &networkmanager.UntagResourceInput{ + ResourceArn: aws.String(identifier), + TagKeys: aws.StringSlice(removedTags.IgnoreAws().Keys()), + } + + _, err := conn.UntagResource(input) + + if err != nil { + return fmt.Errorf("error untagging resource (%s): %w", identifier, err) + } + } + + if updatedTags := oldTags.Updated(newTags); len(updatedTags) > 0 { + input := &networkmanager.TagResourceInput{ + ResourceArn: aws.String(identifier), + Tags: updatedTags.IgnoreAws().NetworkmanagerTags(), + } + + _, err := conn.TagResource(input) + + if err != nil { + return fmt.Errorf("error tagging resource (%s): %w", identifier, err) + } + } + + return nil +} + // OpsworksUpdateTags updates opsworks service tags. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. diff --git a/aws/provider.go b/aws/provider.go index d55cf7bbc98..d7eaff110f5 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -1095,6 +1095,7 @@ func init() { "mediastoredata", "mq", "neptune", + "networkmanager", "opsworks", "organizations", "personalize", diff --git a/vendor/github.com/aws/aws-sdk-go/service/networkmanager/api.go b/vendor/github.com/aws/aws-sdk-go/service/networkmanager/api.go new file mode 100644 index 00000000000..dfc92232d59 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/networkmanager/api.go @@ -0,0 +1,7093 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package networkmanager + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" + "github.com/aws/aws-sdk-go/private/protocol/restjson" +) + +const opAssociateCustomerGateway = "AssociateCustomerGateway" + +// AssociateCustomerGatewayRequest generates a "aws/request.Request" representing the +// client's request for the AssociateCustomerGateway operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See AssociateCustomerGateway for more information on using the AssociateCustomerGateway +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the AssociateCustomerGatewayRequest method. +// req, resp := client.AssociateCustomerGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/AssociateCustomerGateway +func (c *NetworkManager) AssociateCustomerGatewayRequest(input *AssociateCustomerGatewayInput) (req *request.Request, output *AssociateCustomerGatewayOutput) { + op := &request.Operation{ + Name: opAssociateCustomerGateway, + HTTPMethod: "POST", + HTTPPath: "/global-networks/{globalNetworkId}/customer-gateway-associations", + } + + if input == nil { + input = &AssociateCustomerGatewayInput{} + } + + output = &AssociateCustomerGatewayOutput{} + req = c.newRequest(op, input, output) + return +} + +// AssociateCustomerGateway API operation for AWS Network Manager. +// +// Associates a customer gateway with a device and optionally, with a link. +// If you specify a link, it must be associated with the specified device. +// +// You can only associate customer gateways that are connected to a VPN attachment +// on a transit gateway. The transit gateway must be registered in your global +// network. When you register a transit gateway, customer gateways that are +// connected to the transit gateway are automatically included in the global +// network. To list customer gateways that are connected to a transit gateway, +// use the DescribeVpnConnections (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeVpnConnections.html) +// EC2 API and filter by transit-gateway-id. +// +// You cannot associate a customer gateway with more than one device and link. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation AssociateCustomerGateway for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * ServiceQuotaExceededException +// A service limit was exceeded. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/AssociateCustomerGateway +func (c *NetworkManager) AssociateCustomerGateway(input *AssociateCustomerGatewayInput) (*AssociateCustomerGatewayOutput, error) { + req, out := c.AssociateCustomerGatewayRequest(input) + return out, req.Send() +} + +// AssociateCustomerGatewayWithContext is the same as AssociateCustomerGateway with the addition of +// the ability to pass a context and additional request options. +// +// See AssociateCustomerGateway for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) AssociateCustomerGatewayWithContext(ctx aws.Context, input *AssociateCustomerGatewayInput, opts ...request.Option) (*AssociateCustomerGatewayOutput, error) { + req, out := c.AssociateCustomerGatewayRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opAssociateLink = "AssociateLink" + +// AssociateLinkRequest generates a "aws/request.Request" representing the +// client's request for the AssociateLink operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See AssociateLink for more information on using the AssociateLink +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the AssociateLinkRequest method. +// req, resp := client.AssociateLinkRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/AssociateLink +func (c *NetworkManager) AssociateLinkRequest(input *AssociateLinkInput) (req *request.Request, output *AssociateLinkOutput) { + op := &request.Operation{ + Name: opAssociateLink, + HTTPMethod: "POST", + HTTPPath: "/global-networks/{globalNetworkId}/link-associations", + } + + if input == nil { + input = &AssociateLinkInput{} + } + + output = &AssociateLinkOutput{} + req = c.newRequest(op, input, output) + return +} + +// AssociateLink API operation for AWS Network Manager. +// +// Associates a link to a device. A device can be associated to multiple links +// and a link can be associated to multiple devices. The device and link must +// be in the same global network and the same site. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation AssociateLink for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * ServiceQuotaExceededException +// A service limit was exceeded. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/AssociateLink +func (c *NetworkManager) AssociateLink(input *AssociateLinkInput) (*AssociateLinkOutput, error) { + req, out := c.AssociateLinkRequest(input) + return out, req.Send() +} + +// AssociateLinkWithContext is the same as AssociateLink with the addition of +// the ability to pass a context and additional request options. +// +// See AssociateLink for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) AssociateLinkWithContext(ctx aws.Context, input *AssociateLinkInput, opts ...request.Option) (*AssociateLinkOutput, error) { + req, out := c.AssociateLinkRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateDevice = "CreateDevice" + +// CreateDeviceRequest generates a "aws/request.Request" representing the +// client's request for the CreateDevice operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateDevice for more information on using the CreateDevice +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateDeviceRequest method. +// req, resp := client.CreateDeviceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/CreateDevice +func (c *NetworkManager) CreateDeviceRequest(input *CreateDeviceInput) (req *request.Request, output *CreateDeviceOutput) { + op := &request.Operation{ + Name: opCreateDevice, + HTTPMethod: "POST", + HTTPPath: "/global-networks/{globalNetworkId}/devices", + } + + if input == nil { + input = &CreateDeviceInput{} + } + + output = &CreateDeviceOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateDevice API operation for AWS Network Manager. +// +// Creates a new device in a global network. If you specify both a site ID and +// a location, the location of the site is used for visualization in the Network +// Manager console. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation CreateDevice for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * ServiceQuotaExceededException +// A service limit was exceeded. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/CreateDevice +func (c *NetworkManager) CreateDevice(input *CreateDeviceInput) (*CreateDeviceOutput, error) { + req, out := c.CreateDeviceRequest(input) + return out, req.Send() +} + +// CreateDeviceWithContext is the same as CreateDevice with the addition of +// the ability to pass a context and additional request options. +// +// See CreateDevice for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) CreateDeviceWithContext(ctx aws.Context, input *CreateDeviceInput, opts ...request.Option) (*CreateDeviceOutput, error) { + req, out := c.CreateDeviceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateGlobalNetwork = "CreateGlobalNetwork" + +// CreateGlobalNetworkRequest generates a "aws/request.Request" representing the +// client's request for the CreateGlobalNetwork operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateGlobalNetwork for more information on using the CreateGlobalNetwork +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateGlobalNetworkRequest method. +// req, resp := client.CreateGlobalNetworkRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/CreateGlobalNetwork +func (c *NetworkManager) CreateGlobalNetworkRequest(input *CreateGlobalNetworkInput) (req *request.Request, output *CreateGlobalNetworkOutput) { + op := &request.Operation{ + Name: opCreateGlobalNetwork, + HTTPMethod: "POST", + HTTPPath: "/global-networks", + } + + if input == nil { + input = &CreateGlobalNetworkInput{} + } + + output = &CreateGlobalNetworkOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateGlobalNetwork API operation for AWS Network Manager. +// +// Creates a new, empty global network. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation CreateGlobalNetwork for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * ServiceQuotaExceededException +// A service limit was exceeded. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/CreateGlobalNetwork +func (c *NetworkManager) CreateGlobalNetwork(input *CreateGlobalNetworkInput) (*CreateGlobalNetworkOutput, error) { + req, out := c.CreateGlobalNetworkRequest(input) + return out, req.Send() +} + +// CreateGlobalNetworkWithContext is the same as CreateGlobalNetwork with the addition of +// the ability to pass a context and additional request options. +// +// See CreateGlobalNetwork for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) CreateGlobalNetworkWithContext(ctx aws.Context, input *CreateGlobalNetworkInput, opts ...request.Option) (*CreateGlobalNetworkOutput, error) { + req, out := c.CreateGlobalNetworkRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateLink = "CreateLink" + +// CreateLinkRequest generates a "aws/request.Request" representing the +// client's request for the CreateLink operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateLink for more information on using the CreateLink +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateLinkRequest method. +// req, resp := client.CreateLinkRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/CreateLink +func (c *NetworkManager) CreateLinkRequest(input *CreateLinkInput) (req *request.Request, output *CreateLinkOutput) { + op := &request.Operation{ + Name: opCreateLink, + HTTPMethod: "POST", + HTTPPath: "/global-networks/{globalNetworkId}/links", + } + + if input == nil { + input = &CreateLinkInput{} + } + + output = &CreateLinkOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateLink API operation for AWS Network Manager. +// +// Creates a new link for a specified site. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation CreateLink for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * ServiceQuotaExceededException +// A service limit was exceeded. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/CreateLink +func (c *NetworkManager) CreateLink(input *CreateLinkInput) (*CreateLinkOutput, error) { + req, out := c.CreateLinkRequest(input) + return out, req.Send() +} + +// CreateLinkWithContext is the same as CreateLink with the addition of +// the ability to pass a context and additional request options. +// +// See CreateLink for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) CreateLinkWithContext(ctx aws.Context, input *CreateLinkInput, opts ...request.Option) (*CreateLinkOutput, error) { + req, out := c.CreateLinkRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateSite = "CreateSite" + +// CreateSiteRequest generates a "aws/request.Request" representing the +// client's request for the CreateSite operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateSite for more information on using the CreateSite +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateSiteRequest method. +// req, resp := client.CreateSiteRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/CreateSite +func (c *NetworkManager) CreateSiteRequest(input *CreateSiteInput) (req *request.Request, output *CreateSiteOutput) { + op := &request.Operation{ + Name: opCreateSite, + HTTPMethod: "POST", + HTTPPath: "/global-networks/{globalNetworkId}/sites", + } + + if input == nil { + input = &CreateSiteInput{} + } + + output = &CreateSiteOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateSite API operation for AWS Network Manager. +// +// Creates a new site in a global network. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation CreateSite for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * ServiceQuotaExceededException +// A service limit was exceeded. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/CreateSite +func (c *NetworkManager) CreateSite(input *CreateSiteInput) (*CreateSiteOutput, error) { + req, out := c.CreateSiteRequest(input) + return out, req.Send() +} + +// CreateSiteWithContext is the same as CreateSite with the addition of +// the ability to pass a context and additional request options. +// +// See CreateSite for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) CreateSiteWithContext(ctx aws.Context, input *CreateSiteInput, opts ...request.Option) (*CreateSiteOutput, error) { + req, out := c.CreateSiteRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteDevice = "DeleteDevice" + +// DeleteDeviceRequest generates a "aws/request.Request" representing the +// client's request for the DeleteDevice operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteDevice for more information on using the DeleteDevice +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteDeviceRequest method. +// req, resp := client.DeleteDeviceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DeleteDevice +func (c *NetworkManager) DeleteDeviceRequest(input *DeleteDeviceInput) (req *request.Request, output *DeleteDeviceOutput) { + op := &request.Operation{ + Name: opDeleteDevice, + HTTPMethod: "DELETE", + HTTPPath: "/global-networks/{globalNetworkId}/devices/{deviceId}", + } + + if input == nil { + input = &DeleteDeviceInput{} + } + + output = &DeleteDeviceOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteDevice API operation for AWS Network Manager. +// +// Deletes an existing device. You must first disassociate the device from any +// links and customer gateways. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation DeleteDevice for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DeleteDevice +func (c *NetworkManager) DeleteDevice(input *DeleteDeviceInput) (*DeleteDeviceOutput, error) { + req, out := c.DeleteDeviceRequest(input) + return out, req.Send() +} + +// DeleteDeviceWithContext is the same as DeleteDevice with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteDevice for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) DeleteDeviceWithContext(ctx aws.Context, input *DeleteDeviceInput, opts ...request.Option) (*DeleteDeviceOutput, error) { + req, out := c.DeleteDeviceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteGlobalNetwork = "DeleteGlobalNetwork" + +// DeleteGlobalNetworkRequest generates a "aws/request.Request" representing the +// client's request for the DeleteGlobalNetwork operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteGlobalNetwork for more information on using the DeleteGlobalNetwork +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteGlobalNetworkRequest method. +// req, resp := client.DeleteGlobalNetworkRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DeleteGlobalNetwork +func (c *NetworkManager) DeleteGlobalNetworkRequest(input *DeleteGlobalNetworkInput) (req *request.Request, output *DeleteGlobalNetworkOutput) { + op := &request.Operation{ + Name: opDeleteGlobalNetwork, + HTTPMethod: "DELETE", + HTTPPath: "/global-networks/{globalNetworkId}", + } + + if input == nil { + input = &DeleteGlobalNetworkInput{} + } + + output = &DeleteGlobalNetworkOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteGlobalNetwork API operation for AWS Network Manager. +// +// Deletes an existing global network. You must first delete all global network +// objects (devices, links, and sites) and deregister all transit gateways. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation DeleteGlobalNetwork for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DeleteGlobalNetwork +func (c *NetworkManager) DeleteGlobalNetwork(input *DeleteGlobalNetworkInput) (*DeleteGlobalNetworkOutput, error) { + req, out := c.DeleteGlobalNetworkRequest(input) + return out, req.Send() +} + +// DeleteGlobalNetworkWithContext is the same as DeleteGlobalNetwork with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteGlobalNetwork for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) DeleteGlobalNetworkWithContext(ctx aws.Context, input *DeleteGlobalNetworkInput, opts ...request.Option) (*DeleteGlobalNetworkOutput, error) { + req, out := c.DeleteGlobalNetworkRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteLink = "DeleteLink" + +// DeleteLinkRequest generates a "aws/request.Request" representing the +// client's request for the DeleteLink operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteLink for more information on using the DeleteLink +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteLinkRequest method. +// req, resp := client.DeleteLinkRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DeleteLink +func (c *NetworkManager) DeleteLinkRequest(input *DeleteLinkInput) (req *request.Request, output *DeleteLinkOutput) { + op := &request.Operation{ + Name: opDeleteLink, + HTTPMethod: "DELETE", + HTTPPath: "/global-networks/{globalNetworkId}/links/{linkId}", + } + + if input == nil { + input = &DeleteLinkInput{} + } + + output = &DeleteLinkOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteLink API operation for AWS Network Manager. +// +// Deletes an existing link. You must first disassociate the link from any devices +// and customer gateways. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation DeleteLink for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DeleteLink +func (c *NetworkManager) DeleteLink(input *DeleteLinkInput) (*DeleteLinkOutput, error) { + req, out := c.DeleteLinkRequest(input) + return out, req.Send() +} + +// DeleteLinkWithContext is the same as DeleteLink with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteLink for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) DeleteLinkWithContext(ctx aws.Context, input *DeleteLinkInput, opts ...request.Option) (*DeleteLinkOutput, error) { + req, out := c.DeleteLinkRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteSite = "DeleteSite" + +// DeleteSiteRequest generates a "aws/request.Request" representing the +// client's request for the DeleteSite operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteSite for more information on using the DeleteSite +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteSiteRequest method. +// req, resp := client.DeleteSiteRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DeleteSite +func (c *NetworkManager) DeleteSiteRequest(input *DeleteSiteInput) (req *request.Request, output *DeleteSiteOutput) { + op := &request.Operation{ + Name: opDeleteSite, + HTTPMethod: "DELETE", + HTTPPath: "/global-networks/{globalNetworkId}/sites/{siteId}", + } + + if input == nil { + input = &DeleteSiteInput{} + } + + output = &DeleteSiteOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteSite API operation for AWS Network Manager. +// +// Deletes an existing site. The site cannot be associated with any device or +// link. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation DeleteSite for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DeleteSite +func (c *NetworkManager) DeleteSite(input *DeleteSiteInput) (*DeleteSiteOutput, error) { + req, out := c.DeleteSiteRequest(input) + return out, req.Send() +} + +// DeleteSiteWithContext is the same as DeleteSite with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteSite for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) DeleteSiteWithContext(ctx aws.Context, input *DeleteSiteInput, opts ...request.Option) (*DeleteSiteOutput, error) { + req, out := c.DeleteSiteRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeregisterTransitGateway = "DeregisterTransitGateway" + +// DeregisterTransitGatewayRequest generates a "aws/request.Request" representing the +// client's request for the DeregisterTransitGateway operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeregisterTransitGateway for more information on using the DeregisterTransitGateway +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeregisterTransitGatewayRequest method. +// req, resp := client.DeregisterTransitGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DeregisterTransitGateway +func (c *NetworkManager) DeregisterTransitGatewayRequest(input *DeregisterTransitGatewayInput) (req *request.Request, output *DeregisterTransitGatewayOutput) { + op := &request.Operation{ + Name: opDeregisterTransitGateway, + HTTPMethod: "DELETE", + HTTPPath: "/global-networks/{globalNetworkId}/transit-gateway-registrations/{transitGatewayArn}", + } + + if input == nil { + input = &DeregisterTransitGatewayInput{} + } + + output = &DeregisterTransitGatewayOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeregisterTransitGateway API operation for AWS Network Manager. +// +// Deregisters a transit gateway from your global network. This action does +// not delete your transit gateway, or modify any of its attachments. This action +// removes any customer gateway associations. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation DeregisterTransitGateway for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DeregisterTransitGateway +func (c *NetworkManager) DeregisterTransitGateway(input *DeregisterTransitGatewayInput) (*DeregisterTransitGatewayOutput, error) { + req, out := c.DeregisterTransitGatewayRequest(input) + return out, req.Send() +} + +// DeregisterTransitGatewayWithContext is the same as DeregisterTransitGateway with the addition of +// the ability to pass a context and additional request options. +// +// See DeregisterTransitGateway for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) DeregisterTransitGatewayWithContext(ctx aws.Context, input *DeregisterTransitGatewayInput, opts ...request.Option) (*DeregisterTransitGatewayOutput, error) { + req, out := c.DeregisterTransitGatewayRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeGlobalNetworks = "DescribeGlobalNetworks" + +// DescribeGlobalNetworksRequest generates a "aws/request.Request" representing the +// client's request for the DescribeGlobalNetworks operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeGlobalNetworks for more information on using the DescribeGlobalNetworks +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeGlobalNetworksRequest method. +// req, resp := client.DescribeGlobalNetworksRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DescribeGlobalNetworks +func (c *NetworkManager) DescribeGlobalNetworksRequest(input *DescribeGlobalNetworksInput) (req *request.Request, output *DescribeGlobalNetworksOutput) { + op := &request.Operation{ + Name: opDescribeGlobalNetworks, + HTTPMethod: "GET", + HTTPPath: "/global-networks", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeGlobalNetworksInput{} + } + + output = &DescribeGlobalNetworksOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeGlobalNetworks API operation for AWS Network Manager. +// +// Describes one or more global networks. By default, all global networks are +// described. To describe the objects in your global network, you must use the +// appropriate Get* action. For example, to list the transit gateways in your +// global network, use GetTransitGatewayRegistrations. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation DescribeGlobalNetworks for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DescribeGlobalNetworks +func (c *NetworkManager) DescribeGlobalNetworks(input *DescribeGlobalNetworksInput) (*DescribeGlobalNetworksOutput, error) { + req, out := c.DescribeGlobalNetworksRequest(input) + return out, req.Send() +} + +// DescribeGlobalNetworksWithContext is the same as DescribeGlobalNetworks with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeGlobalNetworks for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) DescribeGlobalNetworksWithContext(ctx aws.Context, input *DescribeGlobalNetworksInput, opts ...request.Option) (*DescribeGlobalNetworksOutput, error) { + req, out := c.DescribeGlobalNetworksRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// DescribeGlobalNetworksPages iterates over the pages of a DescribeGlobalNetworks operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeGlobalNetworks method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeGlobalNetworks operation. +// pageNum := 0 +// err := client.DescribeGlobalNetworksPages(params, +// func(page *networkmanager.DescribeGlobalNetworksOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *NetworkManager) DescribeGlobalNetworksPages(input *DescribeGlobalNetworksInput, fn func(*DescribeGlobalNetworksOutput, bool) bool) error { + return c.DescribeGlobalNetworksPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// DescribeGlobalNetworksPagesWithContext same as DescribeGlobalNetworksPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) DescribeGlobalNetworksPagesWithContext(ctx aws.Context, input *DescribeGlobalNetworksInput, fn func(*DescribeGlobalNetworksOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *DescribeGlobalNetworksInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeGlobalNetworksRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*DescribeGlobalNetworksOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opDisassociateCustomerGateway = "DisassociateCustomerGateway" + +// DisassociateCustomerGatewayRequest generates a "aws/request.Request" representing the +// client's request for the DisassociateCustomerGateway operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DisassociateCustomerGateway for more information on using the DisassociateCustomerGateway +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DisassociateCustomerGatewayRequest method. +// req, resp := client.DisassociateCustomerGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DisassociateCustomerGateway +func (c *NetworkManager) DisassociateCustomerGatewayRequest(input *DisassociateCustomerGatewayInput) (req *request.Request, output *DisassociateCustomerGatewayOutput) { + op := &request.Operation{ + Name: opDisassociateCustomerGateway, + HTTPMethod: "DELETE", + HTTPPath: "/global-networks/{globalNetworkId}/customer-gateway-associations/{customerGatewayArn}", + } + + if input == nil { + input = &DisassociateCustomerGatewayInput{} + } + + output = &DisassociateCustomerGatewayOutput{} + req = c.newRequest(op, input, output) + return +} + +// DisassociateCustomerGateway API operation for AWS Network Manager. +// +// Disassociates a customer gateway from a device and a link. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation DisassociateCustomerGateway for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DisassociateCustomerGateway +func (c *NetworkManager) DisassociateCustomerGateway(input *DisassociateCustomerGatewayInput) (*DisassociateCustomerGatewayOutput, error) { + req, out := c.DisassociateCustomerGatewayRequest(input) + return out, req.Send() +} + +// DisassociateCustomerGatewayWithContext is the same as DisassociateCustomerGateway with the addition of +// the ability to pass a context and additional request options. +// +// See DisassociateCustomerGateway for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) DisassociateCustomerGatewayWithContext(ctx aws.Context, input *DisassociateCustomerGatewayInput, opts ...request.Option) (*DisassociateCustomerGatewayOutput, error) { + req, out := c.DisassociateCustomerGatewayRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDisassociateLink = "DisassociateLink" + +// DisassociateLinkRequest generates a "aws/request.Request" representing the +// client's request for the DisassociateLink operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DisassociateLink for more information on using the DisassociateLink +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DisassociateLinkRequest method. +// req, resp := client.DisassociateLinkRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DisassociateLink +func (c *NetworkManager) DisassociateLinkRequest(input *DisassociateLinkInput) (req *request.Request, output *DisassociateLinkOutput) { + op := &request.Operation{ + Name: opDisassociateLink, + HTTPMethod: "DELETE", + HTTPPath: "/global-networks/{globalNetworkId}/link-associations", + } + + if input == nil { + input = &DisassociateLinkInput{} + } + + output = &DisassociateLinkOutput{} + req = c.newRequest(op, input, output) + return +} + +// DisassociateLink API operation for AWS Network Manager. +// +// Disassociates an existing device from a link. You must first disassociate +// any customer gateways that are associated with the link. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation DisassociateLink for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/DisassociateLink +func (c *NetworkManager) DisassociateLink(input *DisassociateLinkInput) (*DisassociateLinkOutput, error) { + req, out := c.DisassociateLinkRequest(input) + return out, req.Send() +} + +// DisassociateLinkWithContext is the same as DisassociateLink with the addition of +// the ability to pass a context and additional request options. +// +// See DisassociateLink for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) DisassociateLinkWithContext(ctx aws.Context, input *DisassociateLinkInput, opts ...request.Option) (*DisassociateLinkOutput, error) { + req, out := c.DisassociateLinkRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetCustomerGatewayAssociations = "GetCustomerGatewayAssociations" + +// GetCustomerGatewayAssociationsRequest generates a "aws/request.Request" representing the +// client's request for the GetCustomerGatewayAssociations operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetCustomerGatewayAssociations for more information on using the GetCustomerGatewayAssociations +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetCustomerGatewayAssociationsRequest method. +// req, resp := client.GetCustomerGatewayAssociationsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/GetCustomerGatewayAssociations +func (c *NetworkManager) GetCustomerGatewayAssociationsRequest(input *GetCustomerGatewayAssociationsInput) (req *request.Request, output *GetCustomerGatewayAssociationsOutput) { + op := &request.Operation{ + Name: opGetCustomerGatewayAssociations, + HTTPMethod: "GET", + HTTPPath: "/global-networks/{globalNetworkId}/customer-gateway-associations", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &GetCustomerGatewayAssociationsInput{} + } + + output = &GetCustomerGatewayAssociationsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetCustomerGatewayAssociations API operation for AWS Network Manager. +// +// Gets the association information for customer gateways that are associated +// with devices and links in your global network. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation GetCustomerGatewayAssociations for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/GetCustomerGatewayAssociations +func (c *NetworkManager) GetCustomerGatewayAssociations(input *GetCustomerGatewayAssociationsInput) (*GetCustomerGatewayAssociationsOutput, error) { + req, out := c.GetCustomerGatewayAssociationsRequest(input) + return out, req.Send() +} + +// GetCustomerGatewayAssociationsWithContext is the same as GetCustomerGatewayAssociations with the addition of +// the ability to pass a context and additional request options. +// +// See GetCustomerGatewayAssociations for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) GetCustomerGatewayAssociationsWithContext(ctx aws.Context, input *GetCustomerGatewayAssociationsInput, opts ...request.Option) (*GetCustomerGatewayAssociationsOutput, error) { + req, out := c.GetCustomerGatewayAssociationsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// GetCustomerGatewayAssociationsPages iterates over the pages of a GetCustomerGatewayAssociations operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetCustomerGatewayAssociations method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetCustomerGatewayAssociations operation. +// pageNum := 0 +// err := client.GetCustomerGatewayAssociationsPages(params, +// func(page *networkmanager.GetCustomerGatewayAssociationsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *NetworkManager) GetCustomerGatewayAssociationsPages(input *GetCustomerGatewayAssociationsInput, fn func(*GetCustomerGatewayAssociationsOutput, bool) bool) error { + return c.GetCustomerGatewayAssociationsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// GetCustomerGatewayAssociationsPagesWithContext same as GetCustomerGatewayAssociationsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) GetCustomerGatewayAssociationsPagesWithContext(ctx aws.Context, input *GetCustomerGatewayAssociationsInput, fn func(*GetCustomerGatewayAssociationsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *GetCustomerGatewayAssociationsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.GetCustomerGatewayAssociationsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*GetCustomerGatewayAssociationsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opGetDevices = "GetDevices" + +// GetDevicesRequest generates a "aws/request.Request" representing the +// client's request for the GetDevices operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetDevices for more information on using the GetDevices +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetDevicesRequest method. +// req, resp := client.GetDevicesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/GetDevices +func (c *NetworkManager) GetDevicesRequest(input *GetDevicesInput) (req *request.Request, output *GetDevicesOutput) { + op := &request.Operation{ + Name: opGetDevices, + HTTPMethod: "GET", + HTTPPath: "/global-networks/{globalNetworkId}/devices", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &GetDevicesInput{} + } + + output = &GetDevicesOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetDevices API operation for AWS Network Manager. +// +// Gets information about one or more of your devices in a global network. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation GetDevices for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/GetDevices +func (c *NetworkManager) GetDevices(input *GetDevicesInput) (*GetDevicesOutput, error) { + req, out := c.GetDevicesRequest(input) + return out, req.Send() +} + +// GetDevicesWithContext is the same as GetDevices with the addition of +// the ability to pass a context and additional request options. +// +// See GetDevices for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) GetDevicesWithContext(ctx aws.Context, input *GetDevicesInput, opts ...request.Option) (*GetDevicesOutput, error) { + req, out := c.GetDevicesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// GetDevicesPages iterates over the pages of a GetDevices operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetDevices method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetDevices operation. +// pageNum := 0 +// err := client.GetDevicesPages(params, +// func(page *networkmanager.GetDevicesOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *NetworkManager) GetDevicesPages(input *GetDevicesInput, fn func(*GetDevicesOutput, bool) bool) error { + return c.GetDevicesPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// GetDevicesPagesWithContext same as GetDevicesPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) GetDevicesPagesWithContext(ctx aws.Context, input *GetDevicesInput, fn func(*GetDevicesOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *GetDevicesInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.GetDevicesRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*GetDevicesOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opGetLinkAssociations = "GetLinkAssociations" + +// GetLinkAssociationsRequest generates a "aws/request.Request" representing the +// client's request for the GetLinkAssociations operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetLinkAssociations for more information on using the GetLinkAssociations +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetLinkAssociationsRequest method. +// req, resp := client.GetLinkAssociationsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/GetLinkAssociations +func (c *NetworkManager) GetLinkAssociationsRequest(input *GetLinkAssociationsInput) (req *request.Request, output *GetLinkAssociationsOutput) { + op := &request.Operation{ + Name: opGetLinkAssociations, + HTTPMethod: "GET", + HTTPPath: "/global-networks/{globalNetworkId}/link-associations", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &GetLinkAssociationsInput{} + } + + output = &GetLinkAssociationsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetLinkAssociations API operation for AWS Network Manager. +// +// Gets the link associations for a device or a link. Either the device ID or +// the link ID must be specified. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation GetLinkAssociations for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/GetLinkAssociations +func (c *NetworkManager) GetLinkAssociations(input *GetLinkAssociationsInput) (*GetLinkAssociationsOutput, error) { + req, out := c.GetLinkAssociationsRequest(input) + return out, req.Send() +} + +// GetLinkAssociationsWithContext is the same as GetLinkAssociations with the addition of +// the ability to pass a context and additional request options. +// +// See GetLinkAssociations for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) GetLinkAssociationsWithContext(ctx aws.Context, input *GetLinkAssociationsInput, opts ...request.Option) (*GetLinkAssociationsOutput, error) { + req, out := c.GetLinkAssociationsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// GetLinkAssociationsPages iterates over the pages of a GetLinkAssociations operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetLinkAssociations method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetLinkAssociations operation. +// pageNum := 0 +// err := client.GetLinkAssociationsPages(params, +// func(page *networkmanager.GetLinkAssociationsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *NetworkManager) GetLinkAssociationsPages(input *GetLinkAssociationsInput, fn func(*GetLinkAssociationsOutput, bool) bool) error { + return c.GetLinkAssociationsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// GetLinkAssociationsPagesWithContext same as GetLinkAssociationsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) GetLinkAssociationsPagesWithContext(ctx aws.Context, input *GetLinkAssociationsInput, fn func(*GetLinkAssociationsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *GetLinkAssociationsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.GetLinkAssociationsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*GetLinkAssociationsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opGetLinks = "GetLinks" + +// GetLinksRequest generates a "aws/request.Request" representing the +// client's request for the GetLinks operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetLinks for more information on using the GetLinks +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetLinksRequest method. +// req, resp := client.GetLinksRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/GetLinks +func (c *NetworkManager) GetLinksRequest(input *GetLinksInput) (req *request.Request, output *GetLinksOutput) { + op := &request.Operation{ + Name: opGetLinks, + HTTPMethod: "GET", + HTTPPath: "/global-networks/{globalNetworkId}/links", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &GetLinksInput{} + } + + output = &GetLinksOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetLinks API operation for AWS Network Manager. +// +// Gets information about one or more links in a specified global network. +// +// If you specify the site ID, you cannot specify the type or provider in the +// same request. You can specify the type and provider in the same request. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation GetLinks for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/GetLinks +func (c *NetworkManager) GetLinks(input *GetLinksInput) (*GetLinksOutput, error) { + req, out := c.GetLinksRequest(input) + return out, req.Send() +} + +// GetLinksWithContext is the same as GetLinks with the addition of +// the ability to pass a context and additional request options. +// +// See GetLinks for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) GetLinksWithContext(ctx aws.Context, input *GetLinksInput, opts ...request.Option) (*GetLinksOutput, error) { + req, out := c.GetLinksRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// GetLinksPages iterates over the pages of a GetLinks operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetLinks method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetLinks operation. +// pageNum := 0 +// err := client.GetLinksPages(params, +// func(page *networkmanager.GetLinksOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *NetworkManager) GetLinksPages(input *GetLinksInput, fn func(*GetLinksOutput, bool) bool) error { + return c.GetLinksPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// GetLinksPagesWithContext same as GetLinksPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) GetLinksPagesWithContext(ctx aws.Context, input *GetLinksInput, fn func(*GetLinksOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *GetLinksInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.GetLinksRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*GetLinksOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opGetSites = "GetSites" + +// GetSitesRequest generates a "aws/request.Request" representing the +// client's request for the GetSites operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetSites for more information on using the GetSites +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetSitesRequest method. +// req, resp := client.GetSitesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/GetSites +func (c *NetworkManager) GetSitesRequest(input *GetSitesInput) (req *request.Request, output *GetSitesOutput) { + op := &request.Operation{ + Name: opGetSites, + HTTPMethod: "GET", + HTTPPath: "/global-networks/{globalNetworkId}/sites", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &GetSitesInput{} + } + + output = &GetSitesOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetSites API operation for AWS Network Manager. +// +// Gets information about one or more of your sites in a global network. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation GetSites for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/GetSites +func (c *NetworkManager) GetSites(input *GetSitesInput) (*GetSitesOutput, error) { + req, out := c.GetSitesRequest(input) + return out, req.Send() +} + +// GetSitesWithContext is the same as GetSites with the addition of +// the ability to pass a context and additional request options. +// +// See GetSites for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) GetSitesWithContext(ctx aws.Context, input *GetSitesInput, opts ...request.Option) (*GetSitesOutput, error) { + req, out := c.GetSitesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// GetSitesPages iterates over the pages of a GetSites operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetSites method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetSites operation. +// pageNum := 0 +// err := client.GetSitesPages(params, +// func(page *networkmanager.GetSitesOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *NetworkManager) GetSitesPages(input *GetSitesInput, fn func(*GetSitesOutput, bool) bool) error { + return c.GetSitesPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// GetSitesPagesWithContext same as GetSitesPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) GetSitesPagesWithContext(ctx aws.Context, input *GetSitesInput, fn func(*GetSitesOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *GetSitesInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.GetSitesRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*GetSitesOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opGetTransitGatewayRegistrations = "GetTransitGatewayRegistrations" + +// GetTransitGatewayRegistrationsRequest generates a "aws/request.Request" representing the +// client's request for the GetTransitGatewayRegistrations operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetTransitGatewayRegistrations for more information on using the GetTransitGatewayRegistrations +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetTransitGatewayRegistrationsRequest method. +// req, resp := client.GetTransitGatewayRegistrationsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/GetTransitGatewayRegistrations +func (c *NetworkManager) GetTransitGatewayRegistrationsRequest(input *GetTransitGatewayRegistrationsInput) (req *request.Request, output *GetTransitGatewayRegistrationsOutput) { + op := &request.Operation{ + Name: opGetTransitGatewayRegistrations, + HTTPMethod: "GET", + HTTPPath: "/global-networks/{globalNetworkId}/transit-gateway-registrations", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &GetTransitGatewayRegistrationsInput{} + } + + output = &GetTransitGatewayRegistrationsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetTransitGatewayRegistrations API operation for AWS Network Manager. +// +// Gets information about the transit gateway registrations in a specified global +// network. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation GetTransitGatewayRegistrations for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/GetTransitGatewayRegistrations +func (c *NetworkManager) GetTransitGatewayRegistrations(input *GetTransitGatewayRegistrationsInput) (*GetTransitGatewayRegistrationsOutput, error) { + req, out := c.GetTransitGatewayRegistrationsRequest(input) + return out, req.Send() +} + +// GetTransitGatewayRegistrationsWithContext is the same as GetTransitGatewayRegistrations with the addition of +// the ability to pass a context and additional request options. +// +// See GetTransitGatewayRegistrations for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) GetTransitGatewayRegistrationsWithContext(ctx aws.Context, input *GetTransitGatewayRegistrationsInput, opts ...request.Option) (*GetTransitGatewayRegistrationsOutput, error) { + req, out := c.GetTransitGatewayRegistrationsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// GetTransitGatewayRegistrationsPages iterates over the pages of a GetTransitGatewayRegistrations operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetTransitGatewayRegistrations method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetTransitGatewayRegistrations operation. +// pageNum := 0 +// err := client.GetTransitGatewayRegistrationsPages(params, +// func(page *networkmanager.GetTransitGatewayRegistrationsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *NetworkManager) GetTransitGatewayRegistrationsPages(input *GetTransitGatewayRegistrationsInput, fn func(*GetTransitGatewayRegistrationsOutput, bool) bool) error { + return c.GetTransitGatewayRegistrationsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// GetTransitGatewayRegistrationsPagesWithContext same as GetTransitGatewayRegistrationsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) GetTransitGatewayRegistrationsPagesWithContext(ctx aws.Context, input *GetTransitGatewayRegistrationsInput, fn func(*GetTransitGatewayRegistrationsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *GetTransitGatewayRegistrationsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.GetTransitGatewayRegistrationsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*GetTransitGatewayRegistrationsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opListTagsForResource = "ListTagsForResource" + +// ListTagsForResourceRequest generates a "aws/request.Request" representing the +// client's request for the ListTagsForResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListTagsForResource for more information on using the ListTagsForResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListTagsForResourceRequest method. +// req, resp := client.ListTagsForResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/ListTagsForResource +func (c *NetworkManager) ListTagsForResourceRequest(input *ListTagsForResourceInput) (req *request.Request, output *ListTagsForResourceOutput) { + op := &request.Operation{ + Name: opListTagsForResource, + HTTPMethod: "GET", + HTTPPath: "/tags/{resourceArn}", + } + + if input == nil { + input = &ListTagsForResourceInput{} + } + + output = &ListTagsForResourceOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListTagsForResource API operation for AWS Network Manager. +// +// Lists the tags for a specified resource. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation ListTagsForResource for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/ListTagsForResource +func (c *NetworkManager) ListTagsForResource(input *ListTagsForResourceInput) (*ListTagsForResourceOutput, error) { + req, out := c.ListTagsForResourceRequest(input) + return out, req.Send() +} + +// ListTagsForResourceWithContext is the same as ListTagsForResource with the addition of +// the ability to pass a context and additional request options. +// +// See ListTagsForResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) ListTagsForResourceWithContext(ctx aws.Context, input *ListTagsForResourceInput, opts ...request.Option) (*ListTagsForResourceOutput, error) { + req, out := c.ListTagsForResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opRegisterTransitGateway = "RegisterTransitGateway" + +// RegisterTransitGatewayRequest generates a "aws/request.Request" representing the +// client's request for the RegisterTransitGateway operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See RegisterTransitGateway for more information on using the RegisterTransitGateway +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the RegisterTransitGatewayRequest method. +// req, resp := client.RegisterTransitGatewayRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/RegisterTransitGateway +func (c *NetworkManager) RegisterTransitGatewayRequest(input *RegisterTransitGatewayInput) (req *request.Request, output *RegisterTransitGatewayOutput) { + op := &request.Operation{ + Name: opRegisterTransitGateway, + HTTPMethod: "POST", + HTTPPath: "/global-networks/{globalNetworkId}/transit-gateway-registrations", + } + + if input == nil { + input = &RegisterTransitGatewayInput{} + } + + output = &RegisterTransitGatewayOutput{} + req = c.newRequest(op, input, output) + return +} + +// RegisterTransitGateway API operation for AWS Network Manager. +// +// Registers a transit gateway in your global network. The transit gateway can +// be in any AWS Region, but it must be owned by the same AWS account that owns +// the global network. You cannot register a transit gateway in more than one +// global network. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation RegisterTransitGateway for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/RegisterTransitGateway +func (c *NetworkManager) RegisterTransitGateway(input *RegisterTransitGatewayInput) (*RegisterTransitGatewayOutput, error) { + req, out := c.RegisterTransitGatewayRequest(input) + return out, req.Send() +} + +// RegisterTransitGatewayWithContext is the same as RegisterTransitGateway with the addition of +// the ability to pass a context and additional request options. +// +// See RegisterTransitGateway for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) RegisterTransitGatewayWithContext(ctx aws.Context, input *RegisterTransitGatewayInput, opts ...request.Option) (*RegisterTransitGatewayOutput, error) { + req, out := c.RegisterTransitGatewayRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opTagResource = "TagResource" + +// TagResourceRequest generates a "aws/request.Request" representing the +// client's request for the TagResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See TagResource for more information on using the TagResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the TagResourceRequest method. +// req, resp := client.TagResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/TagResource +func (c *NetworkManager) TagResourceRequest(input *TagResourceInput) (req *request.Request, output *TagResourceOutput) { + op := &request.Operation{ + Name: opTagResource, + HTTPMethod: "POST", + HTTPPath: "/tags/{resourceArn}", + } + + if input == nil { + input = &TagResourceInput{} + } + + output = &TagResourceOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restjson.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// TagResource API operation for AWS Network Manager. +// +// Tags a specified resource. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation TagResource for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * ServiceQuotaExceededException +// A service limit was exceeded. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/TagResource +func (c *NetworkManager) TagResource(input *TagResourceInput) (*TagResourceOutput, error) { + req, out := c.TagResourceRequest(input) + return out, req.Send() +} + +// TagResourceWithContext is the same as TagResource with the addition of +// the ability to pass a context and additional request options. +// +// See TagResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) TagResourceWithContext(ctx aws.Context, input *TagResourceInput, opts ...request.Option) (*TagResourceOutput, error) { + req, out := c.TagResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUntagResource = "UntagResource" + +// UntagResourceRequest generates a "aws/request.Request" representing the +// client's request for the UntagResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UntagResource for more information on using the UntagResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UntagResourceRequest method. +// req, resp := client.UntagResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/UntagResource +func (c *NetworkManager) UntagResourceRequest(input *UntagResourceInput) (req *request.Request, output *UntagResourceOutput) { + op := &request.Operation{ + Name: opUntagResource, + HTTPMethod: "DELETE", + HTTPPath: "/tags/{resourceArn}", + } + + if input == nil { + input = &UntagResourceInput{} + } + + output = &UntagResourceOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restjson.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// UntagResource API operation for AWS Network Manager. +// +// Removes tags from a specified resource. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation UntagResource for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/UntagResource +func (c *NetworkManager) UntagResource(input *UntagResourceInput) (*UntagResourceOutput, error) { + req, out := c.UntagResourceRequest(input) + return out, req.Send() +} + +// UntagResourceWithContext is the same as UntagResource with the addition of +// the ability to pass a context and additional request options. +// +// See UntagResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) UntagResourceWithContext(ctx aws.Context, input *UntagResourceInput, opts ...request.Option) (*UntagResourceOutput, error) { + req, out := c.UntagResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateDevice = "UpdateDevice" + +// UpdateDeviceRequest generates a "aws/request.Request" representing the +// client's request for the UpdateDevice operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateDevice for more information on using the UpdateDevice +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateDeviceRequest method. +// req, resp := client.UpdateDeviceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/UpdateDevice +func (c *NetworkManager) UpdateDeviceRequest(input *UpdateDeviceInput) (req *request.Request, output *UpdateDeviceOutput) { + op := &request.Operation{ + Name: opUpdateDevice, + HTTPMethod: "PATCH", + HTTPPath: "/global-networks/{globalNetworkId}/devices/{deviceId}", + } + + if input == nil { + input = &UpdateDeviceInput{} + } + + output = &UpdateDeviceOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateDevice API operation for AWS Network Manager. +// +// Updates the details for an existing device. To remove information for any +// of the parameters, specify an empty string. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation UpdateDevice for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/UpdateDevice +func (c *NetworkManager) UpdateDevice(input *UpdateDeviceInput) (*UpdateDeviceOutput, error) { + req, out := c.UpdateDeviceRequest(input) + return out, req.Send() +} + +// UpdateDeviceWithContext is the same as UpdateDevice with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateDevice for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) UpdateDeviceWithContext(ctx aws.Context, input *UpdateDeviceInput, opts ...request.Option) (*UpdateDeviceOutput, error) { + req, out := c.UpdateDeviceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateGlobalNetwork = "UpdateGlobalNetwork" + +// UpdateGlobalNetworkRequest generates a "aws/request.Request" representing the +// client's request for the UpdateGlobalNetwork operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateGlobalNetwork for more information on using the UpdateGlobalNetwork +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateGlobalNetworkRequest method. +// req, resp := client.UpdateGlobalNetworkRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/UpdateGlobalNetwork +func (c *NetworkManager) UpdateGlobalNetworkRequest(input *UpdateGlobalNetworkInput) (req *request.Request, output *UpdateGlobalNetworkOutput) { + op := &request.Operation{ + Name: opUpdateGlobalNetwork, + HTTPMethod: "PATCH", + HTTPPath: "/global-networks/{globalNetworkId}", + } + + if input == nil { + input = &UpdateGlobalNetworkInput{} + } + + output = &UpdateGlobalNetworkOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateGlobalNetwork API operation for AWS Network Manager. +// +// Updates an existing global network. To remove information for any of the +// parameters, specify an empty string. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation UpdateGlobalNetwork for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/UpdateGlobalNetwork +func (c *NetworkManager) UpdateGlobalNetwork(input *UpdateGlobalNetworkInput) (*UpdateGlobalNetworkOutput, error) { + req, out := c.UpdateGlobalNetworkRequest(input) + return out, req.Send() +} + +// UpdateGlobalNetworkWithContext is the same as UpdateGlobalNetwork with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateGlobalNetwork for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) UpdateGlobalNetworkWithContext(ctx aws.Context, input *UpdateGlobalNetworkInput, opts ...request.Option) (*UpdateGlobalNetworkOutput, error) { + req, out := c.UpdateGlobalNetworkRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateLink = "UpdateLink" + +// UpdateLinkRequest generates a "aws/request.Request" representing the +// client's request for the UpdateLink operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateLink for more information on using the UpdateLink +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateLinkRequest method. +// req, resp := client.UpdateLinkRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/UpdateLink +func (c *NetworkManager) UpdateLinkRequest(input *UpdateLinkInput) (req *request.Request, output *UpdateLinkOutput) { + op := &request.Operation{ + Name: opUpdateLink, + HTTPMethod: "PATCH", + HTTPPath: "/global-networks/{globalNetworkId}/links/{linkId}", + } + + if input == nil { + input = &UpdateLinkInput{} + } + + output = &UpdateLinkOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateLink API operation for AWS Network Manager. +// +// Updates the details for an existing link. To remove information for any of +// the parameters, specify an empty string. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation UpdateLink for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * ServiceQuotaExceededException +// A service limit was exceeded. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/UpdateLink +func (c *NetworkManager) UpdateLink(input *UpdateLinkInput) (*UpdateLinkOutput, error) { + req, out := c.UpdateLinkRequest(input) + return out, req.Send() +} + +// UpdateLinkWithContext is the same as UpdateLink with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateLink for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) UpdateLinkWithContext(ctx aws.Context, input *UpdateLinkInput, opts ...request.Option) (*UpdateLinkOutput, error) { + req, out := c.UpdateLinkRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateSite = "UpdateSite" + +// UpdateSiteRequest generates a "aws/request.Request" representing the +// client's request for the UpdateSite operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateSite for more information on using the UpdateSite +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateSiteRequest method. +// req, resp := client.UpdateSiteRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/UpdateSite +func (c *NetworkManager) UpdateSiteRequest(input *UpdateSiteInput) (req *request.Request, output *UpdateSiteOutput) { + op := &request.Operation{ + Name: opUpdateSite, + HTTPMethod: "PATCH", + HTTPPath: "/global-networks/{globalNetworkId}/sites/{siteId}", + } + + if input == nil { + input = &UpdateSiteInput{} + } + + output = &UpdateSiteOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateSite API operation for AWS Network Manager. +// +// Updates the information for an existing site. To remove information for any +// of the parameters, specify an empty string. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Network Manager's +// API operation UpdateSite for usage and error information. +// +// Returned Error Types: +// * ValidationException +// The input fails to satisfy the constraints. +// +// * AccessDeniedException +// You do not have sufficient access to perform this action. +// +// * ResourceNotFoundException +// The specified resource could not be found. +// +// * ConflictException +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +// +// * ThrottlingException +// The request was denied due to request throttling. +// +// * InternalServerException +// The request has failed due to an internal error. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05/UpdateSite +func (c *NetworkManager) UpdateSite(input *UpdateSiteInput) (*UpdateSiteOutput, error) { + req, out := c.UpdateSiteRequest(input) + return out, req.Send() +} + +// UpdateSiteWithContext is the same as UpdateSite with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateSite for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *NetworkManager) UpdateSiteWithContext(ctx aws.Context, input *UpdateSiteInput, opts ...request.Option) (*UpdateSiteOutput, error) { + req, out := c.UpdateSiteRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// You do not have sufficient access to perform this action. +type AccessDeniedException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"Message" type:"string"` +} + +// String returns the string representation +func (s AccessDeniedException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AccessDeniedException) GoString() string { + return s.String() +} + +func newErrorAccessDeniedException(v protocol.ResponseMetadata) error { + return &AccessDeniedException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *AccessDeniedException) Code() string { + return "AccessDeniedException" +} + +// Message returns the exception's message. +func (s *AccessDeniedException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *AccessDeniedException) OrigErr() error { + return nil +} + +func (s *AccessDeniedException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *AccessDeniedException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *AccessDeniedException) RequestID() string { + return s.RespMetadata.RequestID +} + +type AssociateCustomerGatewayInput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the customer gateway. For more information, + // see Resources Defined by Amazon EC2 (https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazonec2.html#amazonec2-resources-for-iam-policies). + // + // CustomerGatewayArn is a required field + CustomerGatewayArn *string `type:"string" required:"true"` + + // The ID of the device. + // + // DeviceId is a required field + DeviceId *string `type:"string" required:"true"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The ID of the link. + LinkId *string `type:"string"` +} + +// String returns the string representation +func (s AssociateCustomerGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateCustomerGatewayInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssociateCustomerGatewayInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AssociateCustomerGatewayInput"} + if s.CustomerGatewayArn == nil { + invalidParams.Add(request.NewErrParamRequired("CustomerGatewayArn")) + } + if s.DeviceId == nil { + invalidParams.Add(request.NewErrParamRequired("DeviceId")) + } + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCustomerGatewayArn sets the CustomerGatewayArn field's value. +func (s *AssociateCustomerGatewayInput) SetCustomerGatewayArn(v string) *AssociateCustomerGatewayInput { + s.CustomerGatewayArn = &v + return s +} + +// SetDeviceId sets the DeviceId field's value. +func (s *AssociateCustomerGatewayInput) SetDeviceId(v string) *AssociateCustomerGatewayInput { + s.DeviceId = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *AssociateCustomerGatewayInput) SetGlobalNetworkId(v string) *AssociateCustomerGatewayInput { + s.GlobalNetworkId = &v + return s +} + +// SetLinkId sets the LinkId field's value. +func (s *AssociateCustomerGatewayInput) SetLinkId(v string) *AssociateCustomerGatewayInput { + s.LinkId = &v + return s +} + +type AssociateCustomerGatewayOutput struct { + _ struct{} `type:"structure"` + + // The customer gateway association. + CustomerGatewayAssociation *CustomerGatewayAssociation `type:"structure"` +} + +// String returns the string representation +func (s AssociateCustomerGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateCustomerGatewayOutput) GoString() string { + return s.String() +} + +// SetCustomerGatewayAssociation sets the CustomerGatewayAssociation field's value. +func (s *AssociateCustomerGatewayOutput) SetCustomerGatewayAssociation(v *CustomerGatewayAssociation) *AssociateCustomerGatewayOutput { + s.CustomerGatewayAssociation = v + return s +} + +type AssociateLinkInput struct { + _ struct{} `type:"structure"` + + // The ID of the device. + // + // DeviceId is a required field + DeviceId *string `type:"string" required:"true"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The ID of the link. + // + // LinkId is a required field + LinkId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s AssociateLinkInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateLinkInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssociateLinkInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AssociateLinkInput"} + if s.DeviceId == nil { + invalidParams.Add(request.NewErrParamRequired("DeviceId")) + } + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + if s.LinkId == nil { + invalidParams.Add(request.NewErrParamRequired("LinkId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDeviceId sets the DeviceId field's value. +func (s *AssociateLinkInput) SetDeviceId(v string) *AssociateLinkInput { + s.DeviceId = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *AssociateLinkInput) SetGlobalNetworkId(v string) *AssociateLinkInput { + s.GlobalNetworkId = &v + return s +} + +// SetLinkId sets the LinkId field's value. +func (s *AssociateLinkInput) SetLinkId(v string) *AssociateLinkInput { + s.LinkId = &v + return s +} + +type AssociateLinkOutput struct { + _ struct{} `type:"structure"` + + // The link association. + LinkAssociation *LinkAssociation `type:"structure"` +} + +// String returns the string representation +func (s AssociateLinkOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateLinkOutput) GoString() string { + return s.String() +} + +// SetLinkAssociation sets the LinkAssociation field's value. +func (s *AssociateLinkOutput) SetLinkAssociation(v *LinkAssociation) *AssociateLinkOutput { + s.LinkAssociation = v + return s +} + +// Describes bandwidth information. +type Bandwidth struct { + _ struct{} `type:"structure"` + + // Download speed in Mbps. + DownloadSpeed *int64 `type:"integer"` + + // Upload speed in Mbps. + UploadSpeed *int64 `type:"integer"` +} + +// String returns the string representation +func (s Bandwidth) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Bandwidth) GoString() string { + return s.String() +} + +// SetDownloadSpeed sets the DownloadSpeed field's value. +func (s *Bandwidth) SetDownloadSpeed(v int64) *Bandwidth { + s.DownloadSpeed = &v + return s +} + +// SetUploadSpeed sets the UploadSpeed field's value. +func (s *Bandwidth) SetUploadSpeed(v int64) *Bandwidth { + s.UploadSpeed = &v + return s +} + +// There was a conflict processing the request. Updating or deleting the resource +// can cause an inconsistent state. +type ConflictException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"Message" type:"string"` + + // The ID of the resource. + // + // ResourceId is a required field + ResourceId *string `type:"string" required:"true"` + + // The resource type. + // + // ResourceType is a required field + ResourceType *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ConflictException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ConflictException) GoString() string { + return s.String() +} + +func newErrorConflictException(v protocol.ResponseMetadata) error { + return &ConflictException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ConflictException) Code() string { + return "ConflictException" +} + +// Message returns the exception's message. +func (s *ConflictException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ConflictException) OrigErr() error { + return nil +} + +func (s *ConflictException) Error() string { + return fmt.Sprintf("%s: %s\n%s", s.Code(), s.Message(), s.String()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ConflictException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ConflictException) RequestID() string { + return s.RespMetadata.RequestID +} + +type CreateDeviceInput struct { + _ struct{} `type:"structure"` + + // A description of the device. + // + // Length Constraints: Maximum length of 256 characters. + Description *string `type:"string"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The location of the device. + Location *Location `type:"structure"` + + // The model of the device. + // + // Length Constraints: Maximum length of 128 characters. + Model *string `type:"string"` + + // The serial number of the device. + // + // Length Constraints: Maximum length of 128 characters. + SerialNumber *string `type:"string"` + + // The ID of the site. + SiteId *string `type:"string"` + + // The tags to apply to the resource during creation. + Tags []*Tag `type:"list"` + + // The type of the device. + Type *string `type:"string"` + + // The vendor of the device. + // + // Length Constraints: Maximum length of 128 characters. + Vendor *string `type:"string"` +} + +// String returns the string representation +func (s CreateDeviceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDeviceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateDeviceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateDeviceInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDescription sets the Description field's value. +func (s *CreateDeviceInput) SetDescription(v string) *CreateDeviceInput { + s.Description = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *CreateDeviceInput) SetGlobalNetworkId(v string) *CreateDeviceInput { + s.GlobalNetworkId = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *CreateDeviceInput) SetLocation(v *Location) *CreateDeviceInput { + s.Location = v + return s +} + +// SetModel sets the Model field's value. +func (s *CreateDeviceInput) SetModel(v string) *CreateDeviceInput { + s.Model = &v + return s +} + +// SetSerialNumber sets the SerialNumber field's value. +func (s *CreateDeviceInput) SetSerialNumber(v string) *CreateDeviceInput { + s.SerialNumber = &v + return s +} + +// SetSiteId sets the SiteId field's value. +func (s *CreateDeviceInput) SetSiteId(v string) *CreateDeviceInput { + s.SiteId = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateDeviceInput) SetTags(v []*Tag) *CreateDeviceInput { + s.Tags = v + return s +} + +// SetType sets the Type field's value. +func (s *CreateDeviceInput) SetType(v string) *CreateDeviceInput { + s.Type = &v + return s +} + +// SetVendor sets the Vendor field's value. +func (s *CreateDeviceInput) SetVendor(v string) *CreateDeviceInput { + s.Vendor = &v + return s +} + +type CreateDeviceOutput struct { + _ struct{} `type:"structure"` + + // Information about the device. + Device *Device `type:"structure"` +} + +// String returns the string representation +func (s CreateDeviceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDeviceOutput) GoString() string { + return s.String() +} + +// SetDevice sets the Device field's value. +func (s *CreateDeviceOutput) SetDevice(v *Device) *CreateDeviceOutput { + s.Device = v + return s +} + +type CreateGlobalNetworkInput struct { + _ struct{} `type:"structure"` + + // A description of the global network. + // + // Length Constraints: Maximum length of 256 characters. + Description *string `type:"string"` + + // The tags to apply to the resource during creation. + Tags []*Tag `type:"list"` +} + +// String returns the string representation +func (s CreateGlobalNetworkInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateGlobalNetworkInput) GoString() string { + return s.String() +} + +// SetDescription sets the Description field's value. +func (s *CreateGlobalNetworkInput) SetDescription(v string) *CreateGlobalNetworkInput { + s.Description = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateGlobalNetworkInput) SetTags(v []*Tag) *CreateGlobalNetworkInput { + s.Tags = v + return s +} + +type CreateGlobalNetworkOutput struct { + _ struct{} `type:"structure"` + + // Information about the global network object. + GlobalNetwork *GlobalNetwork `type:"structure"` +} + +// String returns the string representation +func (s CreateGlobalNetworkOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateGlobalNetworkOutput) GoString() string { + return s.String() +} + +// SetGlobalNetwork sets the GlobalNetwork field's value. +func (s *CreateGlobalNetworkOutput) SetGlobalNetwork(v *GlobalNetwork) *CreateGlobalNetworkOutput { + s.GlobalNetwork = v + return s +} + +type CreateLinkInput struct { + _ struct{} `type:"structure"` + + // The upload speed and download speed in Mbps. + // + // Bandwidth is a required field + Bandwidth *Bandwidth `type:"structure" required:"true"` + + // A description of the link. + // + // Length Constraints: Maximum length of 256 characters. + Description *string `type:"string"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The provider of the link. + // + // Constraints: Cannot include the following characters: | \ ^ + // + // Length Constraints: Maximum length of 128 characters. + Provider *string `type:"string"` + + // The ID of the site. + // + // SiteId is a required field + SiteId *string `type:"string" required:"true"` + + // The tags to apply to the resource during creation. + Tags []*Tag `type:"list"` + + // The type of the link. + // + // Constraints: Cannot include the following characters: | \ ^ + // + // Length Constraints: Maximum length of 128 characters. + Type *string `type:"string"` +} + +// String returns the string representation +func (s CreateLinkInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLinkInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateLinkInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateLinkInput"} + if s.Bandwidth == nil { + invalidParams.Add(request.NewErrParamRequired("Bandwidth")) + } + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + if s.SiteId == nil { + invalidParams.Add(request.NewErrParamRequired("SiteId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBandwidth sets the Bandwidth field's value. +func (s *CreateLinkInput) SetBandwidth(v *Bandwidth) *CreateLinkInput { + s.Bandwidth = v + return s +} + +// SetDescription sets the Description field's value. +func (s *CreateLinkInput) SetDescription(v string) *CreateLinkInput { + s.Description = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *CreateLinkInput) SetGlobalNetworkId(v string) *CreateLinkInput { + s.GlobalNetworkId = &v + return s +} + +// SetProvider sets the Provider field's value. +func (s *CreateLinkInput) SetProvider(v string) *CreateLinkInput { + s.Provider = &v + return s +} + +// SetSiteId sets the SiteId field's value. +func (s *CreateLinkInput) SetSiteId(v string) *CreateLinkInput { + s.SiteId = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateLinkInput) SetTags(v []*Tag) *CreateLinkInput { + s.Tags = v + return s +} + +// SetType sets the Type field's value. +func (s *CreateLinkInput) SetType(v string) *CreateLinkInput { + s.Type = &v + return s +} + +type CreateLinkOutput struct { + _ struct{} `type:"structure"` + + // Information about the link. + Link *Link `type:"structure"` +} + +// String returns the string representation +func (s CreateLinkOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLinkOutput) GoString() string { + return s.String() +} + +// SetLink sets the Link field's value. +func (s *CreateLinkOutput) SetLink(v *Link) *CreateLinkOutput { + s.Link = v + return s +} + +type CreateSiteInput struct { + _ struct{} `type:"structure"` + + // A description of your site. + // + // Length Constraints: Maximum length of 256 characters. + Description *string `type:"string"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The site location. This information is used for visualization in the Network + // Manager console. If you specify the address, the latitude and longitude are + // automatically calculated. + // + // * Address: The physical address of the site. + // + // * Latitude: The latitude of the site. + // + // * Longitude: The longitude of the site. + Location *Location `type:"structure"` + + // The tags to apply to the resource during creation. + Tags []*Tag `type:"list"` +} + +// String returns the string representation +func (s CreateSiteInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSiteInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateSiteInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateSiteInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDescription sets the Description field's value. +func (s *CreateSiteInput) SetDescription(v string) *CreateSiteInput { + s.Description = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *CreateSiteInput) SetGlobalNetworkId(v string) *CreateSiteInput { + s.GlobalNetworkId = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *CreateSiteInput) SetLocation(v *Location) *CreateSiteInput { + s.Location = v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateSiteInput) SetTags(v []*Tag) *CreateSiteInput { + s.Tags = v + return s +} + +type CreateSiteOutput struct { + _ struct{} `type:"structure"` + + // Information about the site. + Site *Site `type:"structure"` +} + +// String returns the string representation +func (s CreateSiteOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSiteOutput) GoString() string { + return s.String() +} + +// SetSite sets the Site field's value. +func (s *CreateSiteOutput) SetSite(v *Site) *CreateSiteOutput { + s.Site = v + return s +} + +// Describes the association between a customer gateway, a device, and a link. +type CustomerGatewayAssociation struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the customer gateway. + CustomerGatewayArn *string `type:"string"` + + // The ID of the device. + DeviceId *string `type:"string"` + + // The ID of the global network. + GlobalNetworkId *string `type:"string"` + + // The ID of the link. + LinkId *string `type:"string"` + + // The association state. + State *string `type:"string" enum:"CustomerGatewayAssociationState"` +} + +// String returns the string representation +func (s CustomerGatewayAssociation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CustomerGatewayAssociation) GoString() string { + return s.String() +} + +// SetCustomerGatewayArn sets the CustomerGatewayArn field's value. +func (s *CustomerGatewayAssociation) SetCustomerGatewayArn(v string) *CustomerGatewayAssociation { + s.CustomerGatewayArn = &v + return s +} + +// SetDeviceId sets the DeviceId field's value. +func (s *CustomerGatewayAssociation) SetDeviceId(v string) *CustomerGatewayAssociation { + s.DeviceId = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *CustomerGatewayAssociation) SetGlobalNetworkId(v string) *CustomerGatewayAssociation { + s.GlobalNetworkId = &v + return s +} + +// SetLinkId sets the LinkId field's value. +func (s *CustomerGatewayAssociation) SetLinkId(v string) *CustomerGatewayAssociation { + s.LinkId = &v + return s +} + +// SetState sets the State field's value. +func (s *CustomerGatewayAssociation) SetState(v string) *CustomerGatewayAssociation { + s.State = &v + return s +} + +type DeleteDeviceInput struct { + _ struct{} `type:"structure"` + + // The ID of the device. + // + // DeviceId is a required field + DeviceId *string `location:"uri" locationName:"deviceId" type:"string" required:"true"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteDeviceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDeviceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteDeviceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteDeviceInput"} + if s.DeviceId == nil { + invalidParams.Add(request.NewErrParamRequired("DeviceId")) + } + if s.DeviceId != nil && len(*s.DeviceId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("DeviceId", 1)) + } + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDeviceId sets the DeviceId field's value. +func (s *DeleteDeviceInput) SetDeviceId(v string) *DeleteDeviceInput { + s.DeviceId = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *DeleteDeviceInput) SetGlobalNetworkId(v string) *DeleteDeviceInput { + s.GlobalNetworkId = &v + return s +} + +type DeleteDeviceOutput struct { + _ struct{} `type:"structure"` + + // Information about the device. + Device *Device `type:"structure"` +} + +// String returns the string representation +func (s DeleteDeviceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDeviceOutput) GoString() string { + return s.String() +} + +// SetDevice sets the Device field's value. +func (s *DeleteDeviceOutput) SetDevice(v *Device) *DeleteDeviceOutput { + s.Device = v + return s +} + +type DeleteGlobalNetworkInput struct { + _ struct{} `type:"structure"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteGlobalNetworkInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteGlobalNetworkInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteGlobalNetworkInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteGlobalNetworkInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *DeleteGlobalNetworkInput) SetGlobalNetworkId(v string) *DeleteGlobalNetworkInput { + s.GlobalNetworkId = &v + return s +} + +type DeleteGlobalNetworkOutput struct { + _ struct{} `type:"structure"` + + // Information about the global network. + GlobalNetwork *GlobalNetwork `type:"structure"` +} + +// String returns the string representation +func (s DeleteGlobalNetworkOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteGlobalNetworkOutput) GoString() string { + return s.String() +} + +// SetGlobalNetwork sets the GlobalNetwork field's value. +func (s *DeleteGlobalNetworkOutput) SetGlobalNetwork(v *GlobalNetwork) *DeleteGlobalNetworkOutput { + s.GlobalNetwork = v + return s +} + +type DeleteLinkInput struct { + _ struct{} `type:"structure"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The ID of the link. + // + // LinkId is a required field + LinkId *string `location:"uri" locationName:"linkId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteLinkInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLinkInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteLinkInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteLinkInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + if s.LinkId == nil { + invalidParams.Add(request.NewErrParamRequired("LinkId")) + } + if s.LinkId != nil && len(*s.LinkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("LinkId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *DeleteLinkInput) SetGlobalNetworkId(v string) *DeleteLinkInput { + s.GlobalNetworkId = &v + return s +} + +// SetLinkId sets the LinkId field's value. +func (s *DeleteLinkInput) SetLinkId(v string) *DeleteLinkInput { + s.LinkId = &v + return s +} + +type DeleteLinkOutput struct { + _ struct{} `type:"structure"` + + // Information about the link. + Link *Link `type:"structure"` +} + +// String returns the string representation +func (s DeleteLinkOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLinkOutput) GoString() string { + return s.String() +} + +// SetLink sets the Link field's value. +func (s *DeleteLinkOutput) SetLink(v *Link) *DeleteLinkOutput { + s.Link = v + return s +} + +type DeleteSiteInput struct { + _ struct{} `type:"structure"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The ID of the site. + // + // SiteId is a required field + SiteId *string `location:"uri" locationName:"siteId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteSiteInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSiteInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteSiteInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteSiteInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + if s.SiteId == nil { + invalidParams.Add(request.NewErrParamRequired("SiteId")) + } + if s.SiteId != nil && len(*s.SiteId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("SiteId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *DeleteSiteInput) SetGlobalNetworkId(v string) *DeleteSiteInput { + s.GlobalNetworkId = &v + return s +} + +// SetSiteId sets the SiteId field's value. +func (s *DeleteSiteInput) SetSiteId(v string) *DeleteSiteInput { + s.SiteId = &v + return s +} + +type DeleteSiteOutput struct { + _ struct{} `type:"structure"` + + // Information about the site. + Site *Site `type:"structure"` +} + +// String returns the string representation +func (s DeleteSiteOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSiteOutput) GoString() string { + return s.String() +} + +// SetSite sets the Site field's value. +func (s *DeleteSiteOutput) SetSite(v *Site) *DeleteSiteOutput { + s.Site = v + return s +} + +type DeregisterTransitGatewayInput struct { + _ struct{} `type:"structure"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The Amazon Resource Name (ARN) of the transit gateway. + // + // TransitGatewayArn is a required field + TransitGatewayArn *string `location:"uri" locationName:"transitGatewayArn" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeregisterTransitGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeregisterTransitGatewayInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeregisterTransitGatewayInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeregisterTransitGatewayInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + if s.TransitGatewayArn == nil { + invalidParams.Add(request.NewErrParamRequired("TransitGatewayArn")) + } + if s.TransitGatewayArn != nil && len(*s.TransitGatewayArn) < 1 { + invalidParams.Add(request.NewErrParamMinLen("TransitGatewayArn", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *DeregisterTransitGatewayInput) SetGlobalNetworkId(v string) *DeregisterTransitGatewayInput { + s.GlobalNetworkId = &v + return s +} + +// SetTransitGatewayArn sets the TransitGatewayArn field's value. +func (s *DeregisterTransitGatewayInput) SetTransitGatewayArn(v string) *DeregisterTransitGatewayInput { + s.TransitGatewayArn = &v + return s +} + +type DeregisterTransitGatewayOutput struct { + _ struct{} `type:"structure"` + + // The transit gateway registration information. + TransitGatewayRegistration *TransitGatewayRegistration `type:"structure"` +} + +// String returns the string representation +func (s DeregisterTransitGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeregisterTransitGatewayOutput) GoString() string { + return s.String() +} + +// SetTransitGatewayRegistration sets the TransitGatewayRegistration field's value. +func (s *DeregisterTransitGatewayOutput) SetTransitGatewayRegistration(v *TransitGatewayRegistration) *DeregisterTransitGatewayOutput { + s.TransitGatewayRegistration = v + return s +} + +type DescribeGlobalNetworksInput struct { + _ struct{} `type:"structure"` + + // The IDs of one or more global networks. The maximum is 10. + GlobalNetworkIds []*string `location:"querystring" locationName:"globalNetworkIds" type:"list"` + + // The maximum number of results to return. + MaxResults *int64 `location:"querystring" locationName:"maxResults" min:"1" type:"integer"` + + // The token for the next page of results. + NextToken *string `location:"querystring" locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s DescribeGlobalNetworksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeGlobalNetworksInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeGlobalNetworksInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeGlobalNetworksInput"} + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalNetworkIds sets the GlobalNetworkIds field's value. +func (s *DescribeGlobalNetworksInput) SetGlobalNetworkIds(v []*string) *DescribeGlobalNetworksInput { + s.GlobalNetworkIds = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeGlobalNetworksInput) SetMaxResults(v int64) *DescribeGlobalNetworksInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeGlobalNetworksInput) SetNextToken(v string) *DescribeGlobalNetworksInput { + s.NextToken = &v + return s +} + +type DescribeGlobalNetworksOutput struct { + _ struct{} `type:"structure"` + + // Information about the global networks. + GlobalNetworks []*GlobalNetwork `type:"list"` + + // The token for the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeGlobalNetworksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeGlobalNetworksOutput) GoString() string { + return s.String() +} + +// SetGlobalNetworks sets the GlobalNetworks field's value. +func (s *DescribeGlobalNetworksOutput) SetGlobalNetworks(v []*GlobalNetwork) *DescribeGlobalNetworksOutput { + s.GlobalNetworks = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeGlobalNetworksOutput) SetNextToken(v string) *DescribeGlobalNetworksOutput { + s.NextToken = &v + return s +} + +// Describes a device. +type Device struct { + _ struct{} `type:"structure"` + + // The date and time that the site was created. + CreatedAt *time.Time `type:"timestamp"` + + // The description of the device. + Description *string `type:"string"` + + // The Amazon Resource Name (ARN) of the device. + DeviceArn *string `type:"string"` + + // The ID of the device. + DeviceId *string `type:"string"` + + // The ID of the global network. + GlobalNetworkId *string `type:"string"` + + // The site location. + Location *Location `type:"structure"` + + // The device model. + Model *string `type:"string"` + + // The device serial number. + SerialNumber *string `type:"string"` + + // The site ID. + SiteId *string `type:"string"` + + // The device state. + State *string `type:"string" enum:"DeviceState"` + + // The tags for the device. + Tags []*Tag `type:"list"` + + // The device type. + Type *string `type:"string"` + + // The device vendor. + Vendor *string `type:"string"` +} + +// String returns the string representation +func (s Device) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Device) GoString() string { + return s.String() +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *Device) SetCreatedAt(v time.Time) *Device { + s.CreatedAt = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *Device) SetDescription(v string) *Device { + s.Description = &v + return s +} + +// SetDeviceArn sets the DeviceArn field's value. +func (s *Device) SetDeviceArn(v string) *Device { + s.DeviceArn = &v + return s +} + +// SetDeviceId sets the DeviceId field's value. +func (s *Device) SetDeviceId(v string) *Device { + s.DeviceId = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *Device) SetGlobalNetworkId(v string) *Device { + s.GlobalNetworkId = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *Device) SetLocation(v *Location) *Device { + s.Location = v + return s +} + +// SetModel sets the Model field's value. +func (s *Device) SetModel(v string) *Device { + s.Model = &v + return s +} + +// SetSerialNumber sets the SerialNumber field's value. +func (s *Device) SetSerialNumber(v string) *Device { + s.SerialNumber = &v + return s +} + +// SetSiteId sets the SiteId field's value. +func (s *Device) SetSiteId(v string) *Device { + s.SiteId = &v + return s +} + +// SetState sets the State field's value. +func (s *Device) SetState(v string) *Device { + s.State = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *Device) SetTags(v []*Tag) *Device { + s.Tags = v + return s +} + +// SetType sets the Type field's value. +func (s *Device) SetType(v string) *Device { + s.Type = &v + return s +} + +// SetVendor sets the Vendor field's value. +func (s *Device) SetVendor(v string) *Device { + s.Vendor = &v + return s +} + +type DisassociateCustomerGatewayInput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the customer gateway. For more information, + // see Resources Defined by Amazon EC2 (https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazonec2.html#amazonec2-resources-for-iam-policies). + // + // CustomerGatewayArn is a required field + CustomerGatewayArn *string `location:"uri" locationName:"customerGatewayArn" type:"string" required:"true"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DisassociateCustomerGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisassociateCustomerGatewayInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DisassociateCustomerGatewayInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DisassociateCustomerGatewayInput"} + if s.CustomerGatewayArn == nil { + invalidParams.Add(request.NewErrParamRequired("CustomerGatewayArn")) + } + if s.CustomerGatewayArn != nil && len(*s.CustomerGatewayArn) < 1 { + invalidParams.Add(request.NewErrParamMinLen("CustomerGatewayArn", 1)) + } + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCustomerGatewayArn sets the CustomerGatewayArn field's value. +func (s *DisassociateCustomerGatewayInput) SetCustomerGatewayArn(v string) *DisassociateCustomerGatewayInput { + s.CustomerGatewayArn = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *DisassociateCustomerGatewayInput) SetGlobalNetworkId(v string) *DisassociateCustomerGatewayInput { + s.GlobalNetworkId = &v + return s +} + +type DisassociateCustomerGatewayOutput struct { + _ struct{} `type:"structure"` + + // Information about the customer gateway association. + CustomerGatewayAssociation *CustomerGatewayAssociation `type:"structure"` +} + +// String returns the string representation +func (s DisassociateCustomerGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisassociateCustomerGatewayOutput) GoString() string { + return s.String() +} + +// SetCustomerGatewayAssociation sets the CustomerGatewayAssociation field's value. +func (s *DisassociateCustomerGatewayOutput) SetCustomerGatewayAssociation(v *CustomerGatewayAssociation) *DisassociateCustomerGatewayOutput { + s.CustomerGatewayAssociation = v + return s +} + +type DisassociateLinkInput struct { + _ struct{} `type:"structure"` + + // The ID of the device. + // + // DeviceId is a required field + DeviceId *string `location:"querystring" locationName:"deviceId" type:"string" required:"true"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The ID of the link. + // + // LinkId is a required field + LinkId *string `location:"querystring" locationName:"linkId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DisassociateLinkInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisassociateLinkInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DisassociateLinkInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DisassociateLinkInput"} + if s.DeviceId == nil { + invalidParams.Add(request.NewErrParamRequired("DeviceId")) + } + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + if s.LinkId == nil { + invalidParams.Add(request.NewErrParamRequired("LinkId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDeviceId sets the DeviceId field's value. +func (s *DisassociateLinkInput) SetDeviceId(v string) *DisassociateLinkInput { + s.DeviceId = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *DisassociateLinkInput) SetGlobalNetworkId(v string) *DisassociateLinkInput { + s.GlobalNetworkId = &v + return s +} + +// SetLinkId sets the LinkId field's value. +func (s *DisassociateLinkInput) SetLinkId(v string) *DisassociateLinkInput { + s.LinkId = &v + return s +} + +type DisassociateLinkOutput struct { + _ struct{} `type:"structure"` + + // Information about the link association. + LinkAssociation *LinkAssociation `type:"structure"` +} + +// String returns the string representation +func (s DisassociateLinkOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisassociateLinkOutput) GoString() string { + return s.String() +} + +// SetLinkAssociation sets the LinkAssociation field's value. +func (s *DisassociateLinkOutput) SetLinkAssociation(v *LinkAssociation) *DisassociateLinkOutput { + s.LinkAssociation = v + return s +} + +type GetCustomerGatewayAssociationsInput struct { + _ struct{} `type:"structure"` + + // One or more customer gateway Amazon Resource Names (ARNs). For more information, + // see Resources Defined by Amazon EC2 (https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazonec2.html#amazonec2-resources-for-iam-policies). + // The maximum is 10. + CustomerGatewayArns []*string `location:"querystring" locationName:"customerGatewayArns" type:"list"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The maximum number of results to return. + MaxResults *int64 `location:"querystring" locationName:"maxResults" min:"1" type:"integer"` + + // The token for the next page of results. + NextToken *string `location:"querystring" locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s GetCustomerGatewayAssociationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCustomerGatewayAssociationsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetCustomerGatewayAssociationsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetCustomerGatewayAssociationsInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCustomerGatewayArns sets the CustomerGatewayArns field's value. +func (s *GetCustomerGatewayAssociationsInput) SetCustomerGatewayArns(v []*string) *GetCustomerGatewayAssociationsInput { + s.CustomerGatewayArns = v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *GetCustomerGatewayAssociationsInput) SetGlobalNetworkId(v string) *GetCustomerGatewayAssociationsInput { + s.GlobalNetworkId = &v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *GetCustomerGatewayAssociationsInput) SetMaxResults(v int64) *GetCustomerGatewayAssociationsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetCustomerGatewayAssociationsInput) SetNextToken(v string) *GetCustomerGatewayAssociationsInput { + s.NextToken = &v + return s +} + +type GetCustomerGatewayAssociationsOutput struct { + _ struct{} `type:"structure"` + + // The customer gateway associations. + CustomerGatewayAssociations []*CustomerGatewayAssociation `type:"list"` + + // The token for the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s GetCustomerGatewayAssociationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCustomerGatewayAssociationsOutput) GoString() string { + return s.String() +} + +// SetCustomerGatewayAssociations sets the CustomerGatewayAssociations field's value. +func (s *GetCustomerGatewayAssociationsOutput) SetCustomerGatewayAssociations(v []*CustomerGatewayAssociation) *GetCustomerGatewayAssociationsOutput { + s.CustomerGatewayAssociations = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetCustomerGatewayAssociationsOutput) SetNextToken(v string) *GetCustomerGatewayAssociationsOutput { + s.NextToken = &v + return s +} + +type GetDevicesInput struct { + _ struct{} `type:"structure"` + + // One or more device IDs. The maximum is 10. + DeviceIds []*string `location:"querystring" locationName:"deviceIds" type:"list"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The maximum number of results to return. + MaxResults *int64 `location:"querystring" locationName:"maxResults" min:"1" type:"integer"` + + // The token for the next page of results. + NextToken *string `location:"querystring" locationName:"nextToken" type:"string"` + + // The ID of the site. + SiteId *string `location:"querystring" locationName:"siteId" type:"string"` +} + +// String returns the string representation +func (s GetDevicesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDevicesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetDevicesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetDevicesInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDeviceIds sets the DeviceIds field's value. +func (s *GetDevicesInput) SetDeviceIds(v []*string) *GetDevicesInput { + s.DeviceIds = v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *GetDevicesInput) SetGlobalNetworkId(v string) *GetDevicesInput { + s.GlobalNetworkId = &v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *GetDevicesInput) SetMaxResults(v int64) *GetDevicesInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetDevicesInput) SetNextToken(v string) *GetDevicesInput { + s.NextToken = &v + return s +} + +// SetSiteId sets the SiteId field's value. +func (s *GetDevicesInput) SetSiteId(v string) *GetDevicesInput { + s.SiteId = &v + return s +} + +type GetDevicesOutput struct { + _ struct{} `type:"structure"` + + // The devices. + Devices []*Device `type:"list"` + + // The token for the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s GetDevicesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDevicesOutput) GoString() string { + return s.String() +} + +// SetDevices sets the Devices field's value. +func (s *GetDevicesOutput) SetDevices(v []*Device) *GetDevicesOutput { + s.Devices = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetDevicesOutput) SetNextToken(v string) *GetDevicesOutput { + s.NextToken = &v + return s +} + +type GetLinkAssociationsInput struct { + _ struct{} `type:"structure"` + + // The ID of the device. + DeviceId *string `location:"querystring" locationName:"deviceId" type:"string"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The ID of the link. + LinkId *string `location:"querystring" locationName:"linkId" type:"string"` + + // The maximum number of results to return. + MaxResults *int64 `location:"querystring" locationName:"maxResults" min:"1" type:"integer"` + + // The token for the next page of results. + NextToken *string `location:"querystring" locationName:"nextToken" type:"string"` +} + +// String returns the string representation +func (s GetLinkAssociationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLinkAssociationsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetLinkAssociationsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetLinkAssociationsInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDeviceId sets the DeviceId field's value. +func (s *GetLinkAssociationsInput) SetDeviceId(v string) *GetLinkAssociationsInput { + s.DeviceId = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *GetLinkAssociationsInput) SetGlobalNetworkId(v string) *GetLinkAssociationsInput { + s.GlobalNetworkId = &v + return s +} + +// SetLinkId sets the LinkId field's value. +func (s *GetLinkAssociationsInput) SetLinkId(v string) *GetLinkAssociationsInput { + s.LinkId = &v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *GetLinkAssociationsInput) SetMaxResults(v int64) *GetLinkAssociationsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetLinkAssociationsInput) SetNextToken(v string) *GetLinkAssociationsInput { + s.NextToken = &v + return s +} + +type GetLinkAssociationsOutput struct { + _ struct{} `type:"structure"` + + // The link associations. + LinkAssociations []*LinkAssociation `type:"list"` + + // The token for the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s GetLinkAssociationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLinkAssociationsOutput) GoString() string { + return s.String() +} + +// SetLinkAssociations sets the LinkAssociations field's value. +func (s *GetLinkAssociationsOutput) SetLinkAssociations(v []*LinkAssociation) *GetLinkAssociationsOutput { + s.LinkAssociations = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetLinkAssociationsOutput) SetNextToken(v string) *GetLinkAssociationsOutput { + s.NextToken = &v + return s +} + +type GetLinksInput struct { + _ struct{} `type:"structure"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // One or more link IDs. The maximum is 10. + LinkIds []*string `location:"querystring" locationName:"linkIds" type:"list"` + + // The maximum number of results to return. + MaxResults *int64 `location:"querystring" locationName:"maxResults" min:"1" type:"integer"` + + // The token for the next page of results. + NextToken *string `location:"querystring" locationName:"nextToken" type:"string"` + + // The link provider. + Provider *string `location:"querystring" locationName:"provider" type:"string"` + + // The ID of the site. + SiteId *string `location:"querystring" locationName:"siteId" type:"string"` + + // The link type. + Type *string `location:"querystring" locationName:"type" type:"string"` +} + +// String returns the string representation +func (s GetLinksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLinksInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetLinksInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetLinksInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *GetLinksInput) SetGlobalNetworkId(v string) *GetLinksInput { + s.GlobalNetworkId = &v + return s +} + +// SetLinkIds sets the LinkIds field's value. +func (s *GetLinksInput) SetLinkIds(v []*string) *GetLinksInput { + s.LinkIds = v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *GetLinksInput) SetMaxResults(v int64) *GetLinksInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetLinksInput) SetNextToken(v string) *GetLinksInput { + s.NextToken = &v + return s +} + +// SetProvider sets the Provider field's value. +func (s *GetLinksInput) SetProvider(v string) *GetLinksInput { + s.Provider = &v + return s +} + +// SetSiteId sets the SiteId field's value. +func (s *GetLinksInput) SetSiteId(v string) *GetLinksInput { + s.SiteId = &v + return s +} + +// SetType sets the Type field's value. +func (s *GetLinksInput) SetType(v string) *GetLinksInput { + s.Type = &v + return s +} + +type GetLinksOutput struct { + _ struct{} `type:"structure"` + + // The links. + Links []*Link `type:"list"` + + // The token for the next page of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s GetLinksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLinksOutput) GoString() string { + return s.String() +} + +// SetLinks sets the Links field's value. +func (s *GetLinksOutput) SetLinks(v []*Link) *GetLinksOutput { + s.Links = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetLinksOutput) SetNextToken(v string) *GetLinksOutput { + s.NextToken = &v + return s +} + +type GetSitesInput struct { + _ struct{} `type:"structure"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The maximum number of results to return. + MaxResults *int64 `location:"querystring" locationName:"maxResults" min:"1" type:"integer"` + + // The token for the next page of results. + NextToken *string `location:"querystring" locationName:"nextToken" type:"string"` + + // One or more site IDs. The maximum is 10. + SiteIds []*string `location:"querystring" locationName:"siteIds" type:"list"` +} + +// String returns the string representation +func (s GetSitesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSitesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetSitesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetSitesInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *GetSitesInput) SetGlobalNetworkId(v string) *GetSitesInput { + s.GlobalNetworkId = &v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *GetSitesInput) SetMaxResults(v int64) *GetSitesInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetSitesInput) SetNextToken(v string) *GetSitesInput { + s.NextToken = &v + return s +} + +// SetSiteIds sets the SiteIds field's value. +func (s *GetSitesInput) SetSiteIds(v []*string) *GetSitesInput { + s.SiteIds = v + return s +} + +type GetSitesOutput struct { + _ struct{} `type:"structure"` + + // The token for the next page of results. + NextToken *string `type:"string"` + + // The sites. + Sites []*Site `type:"list"` +} + +// String returns the string representation +func (s GetSitesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSitesOutput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *GetSitesOutput) SetNextToken(v string) *GetSitesOutput { + s.NextToken = &v + return s +} + +// SetSites sets the Sites field's value. +func (s *GetSitesOutput) SetSites(v []*Site) *GetSitesOutput { + s.Sites = v + return s +} + +type GetTransitGatewayRegistrationsInput struct { + _ struct{} `type:"structure"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The maximum number of results to return. + MaxResults *int64 `location:"querystring" locationName:"maxResults" min:"1" type:"integer"` + + // The token for the next page of results. + NextToken *string `location:"querystring" locationName:"nextToken" type:"string"` + + // The Amazon Resource Names (ARNs) of one or more transit gateways. The maximum + // is 10. + TransitGatewayArns []*string `location:"querystring" locationName:"transitGatewayArns" type:"list"` +} + +// String returns the string representation +func (s GetTransitGatewayRegistrationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetTransitGatewayRegistrationsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetTransitGatewayRegistrationsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetTransitGatewayRegistrationsInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *GetTransitGatewayRegistrationsInput) SetGlobalNetworkId(v string) *GetTransitGatewayRegistrationsInput { + s.GlobalNetworkId = &v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *GetTransitGatewayRegistrationsInput) SetMaxResults(v int64) *GetTransitGatewayRegistrationsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetTransitGatewayRegistrationsInput) SetNextToken(v string) *GetTransitGatewayRegistrationsInput { + s.NextToken = &v + return s +} + +// SetTransitGatewayArns sets the TransitGatewayArns field's value. +func (s *GetTransitGatewayRegistrationsInput) SetTransitGatewayArns(v []*string) *GetTransitGatewayRegistrationsInput { + s.TransitGatewayArns = v + return s +} + +type GetTransitGatewayRegistrationsOutput struct { + _ struct{} `type:"structure"` + + // The token for the next page of results. + NextToken *string `type:"string"` + + // The transit gateway registrations. + TransitGatewayRegistrations []*TransitGatewayRegistration `type:"list"` +} + +// String returns the string representation +func (s GetTransitGatewayRegistrationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetTransitGatewayRegistrationsOutput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *GetTransitGatewayRegistrationsOutput) SetNextToken(v string) *GetTransitGatewayRegistrationsOutput { + s.NextToken = &v + return s +} + +// SetTransitGatewayRegistrations sets the TransitGatewayRegistrations field's value. +func (s *GetTransitGatewayRegistrationsOutput) SetTransitGatewayRegistrations(v []*TransitGatewayRegistration) *GetTransitGatewayRegistrationsOutput { + s.TransitGatewayRegistrations = v + return s +} + +// Describes a global network. +type GlobalNetwork struct { + _ struct{} `type:"structure"` + + // The date and time that the global network was created. + CreatedAt *time.Time `type:"timestamp"` + + // The description of the global network. + Description *string `type:"string"` + + // The Amazon Resource Name (ARN) of the global network. + GlobalNetworkArn *string `type:"string"` + + // The ID of the global network. + GlobalNetworkId *string `type:"string"` + + // The state of the global network. + State *string `type:"string" enum:"GlobalNetworkState"` + + // The tags for the global network. + Tags []*Tag `type:"list"` +} + +// String returns the string representation +func (s GlobalNetwork) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GlobalNetwork) GoString() string { + return s.String() +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *GlobalNetwork) SetCreatedAt(v time.Time) *GlobalNetwork { + s.CreatedAt = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *GlobalNetwork) SetDescription(v string) *GlobalNetwork { + s.Description = &v + return s +} + +// SetGlobalNetworkArn sets the GlobalNetworkArn field's value. +func (s *GlobalNetwork) SetGlobalNetworkArn(v string) *GlobalNetwork { + s.GlobalNetworkArn = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *GlobalNetwork) SetGlobalNetworkId(v string) *GlobalNetwork { + s.GlobalNetworkId = &v + return s +} + +// SetState sets the State field's value. +func (s *GlobalNetwork) SetState(v string) *GlobalNetwork { + s.State = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *GlobalNetwork) SetTags(v []*Tag) *GlobalNetwork { + s.Tags = v + return s +} + +// The request has failed due to an internal error. +type InternalServerException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"Message" type:"string"` + + // Indicates when to retry the request. + RetryAfterSeconds *int64 `location:"header" locationName:"Retry-After" type:"integer"` +} + +// String returns the string representation +func (s InternalServerException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InternalServerException) GoString() string { + return s.String() +} + +func newErrorInternalServerException(v protocol.ResponseMetadata) error { + return &InternalServerException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *InternalServerException) Code() string { + return "InternalServerException" +} + +// Message returns the exception's message. +func (s *InternalServerException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *InternalServerException) OrigErr() error { + return nil +} + +func (s *InternalServerException) Error() string { + return fmt.Sprintf("%s: %s\n%s", s.Code(), s.Message(), s.String()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *InternalServerException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *InternalServerException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Describes a link. +type Link struct { + _ struct{} `type:"structure"` + + // The bandwidth for the link. + Bandwidth *Bandwidth `type:"structure"` + + // The date and time that the link was created. + CreatedAt *time.Time `type:"timestamp"` + + // The description of the link. + Description *string `type:"string"` + + // The ID of the global network. + GlobalNetworkId *string `type:"string"` + + // The Amazon Resource Name (ARN) of the link. + LinkArn *string `type:"string"` + + // The ID of the link. + LinkId *string `type:"string"` + + // The provider of the link. + Provider *string `type:"string"` + + // The ID of the site. + SiteId *string `type:"string"` + + // The state of the link. + State *string `type:"string" enum:"LinkState"` + + // The tags for the link. + Tags []*Tag `type:"list"` + + // The type of the link. + Type *string `type:"string"` +} + +// String returns the string representation +func (s Link) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Link) GoString() string { + return s.String() +} + +// SetBandwidth sets the Bandwidth field's value. +func (s *Link) SetBandwidth(v *Bandwidth) *Link { + s.Bandwidth = v + return s +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *Link) SetCreatedAt(v time.Time) *Link { + s.CreatedAt = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *Link) SetDescription(v string) *Link { + s.Description = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *Link) SetGlobalNetworkId(v string) *Link { + s.GlobalNetworkId = &v + return s +} + +// SetLinkArn sets the LinkArn field's value. +func (s *Link) SetLinkArn(v string) *Link { + s.LinkArn = &v + return s +} + +// SetLinkId sets the LinkId field's value. +func (s *Link) SetLinkId(v string) *Link { + s.LinkId = &v + return s +} + +// SetProvider sets the Provider field's value. +func (s *Link) SetProvider(v string) *Link { + s.Provider = &v + return s +} + +// SetSiteId sets the SiteId field's value. +func (s *Link) SetSiteId(v string) *Link { + s.SiteId = &v + return s +} + +// SetState sets the State field's value. +func (s *Link) SetState(v string) *Link { + s.State = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *Link) SetTags(v []*Tag) *Link { + s.Tags = v + return s +} + +// SetType sets the Type field's value. +func (s *Link) SetType(v string) *Link { + s.Type = &v + return s +} + +// Describes the association between a device and a link. +type LinkAssociation struct { + _ struct{} `type:"structure"` + + // The device ID for the link association. + DeviceId *string `type:"string"` + + // The ID of the global network. + GlobalNetworkId *string `type:"string"` + + // The state of the association. + LinkAssociationState *string `type:"string" enum:"LinkAssociationState"` + + // The ID of the link. + LinkId *string `type:"string"` +} + +// String returns the string representation +func (s LinkAssociation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LinkAssociation) GoString() string { + return s.String() +} + +// SetDeviceId sets the DeviceId field's value. +func (s *LinkAssociation) SetDeviceId(v string) *LinkAssociation { + s.DeviceId = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *LinkAssociation) SetGlobalNetworkId(v string) *LinkAssociation { + s.GlobalNetworkId = &v + return s +} + +// SetLinkAssociationState sets the LinkAssociationState field's value. +func (s *LinkAssociation) SetLinkAssociationState(v string) *LinkAssociation { + s.LinkAssociationState = &v + return s +} + +// SetLinkId sets the LinkId field's value. +func (s *LinkAssociation) SetLinkId(v string) *LinkAssociation { + s.LinkId = &v + return s +} + +type ListTagsForResourceInput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the resource. + // + // ResourceArn is a required field + ResourceArn *string `location:"uri" locationName:"resourceArn" type:"string" required:"true"` +} + +// String returns the string representation +func (s ListTagsForResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTagsForResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListTagsForResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListTagsForResourceInput"} + if s.ResourceArn == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceArn")) + } + if s.ResourceArn != nil && len(*s.ResourceArn) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceArn", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetResourceArn sets the ResourceArn field's value. +func (s *ListTagsForResourceInput) SetResourceArn(v string) *ListTagsForResourceInput { + s.ResourceArn = &v + return s +} + +type ListTagsForResourceOutput struct { + _ struct{} `type:"structure"` + + // The list of tags. + TagList []*Tag `type:"list"` +} + +// String returns the string representation +func (s ListTagsForResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTagsForResourceOutput) GoString() string { + return s.String() +} + +// SetTagList sets the TagList field's value. +func (s *ListTagsForResourceOutput) SetTagList(v []*Tag) *ListTagsForResourceOutput { + s.TagList = v + return s +} + +// Describes a location. +type Location struct { + _ struct{} `type:"structure"` + + // The physical address. + Address *string `type:"string"` + + // The latitude. + Latitude *string `type:"string"` + + // The longitude. + Longitude *string `type:"string"` +} + +// String returns the string representation +func (s Location) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Location) GoString() string { + return s.String() +} + +// SetAddress sets the Address field's value. +func (s *Location) SetAddress(v string) *Location { + s.Address = &v + return s +} + +// SetLatitude sets the Latitude field's value. +func (s *Location) SetLatitude(v string) *Location { + s.Latitude = &v + return s +} + +// SetLongitude sets the Longitude field's value. +func (s *Location) SetLongitude(v string) *Location { + s.Longitude = &v + return s +} + +type RegisterTransitGatewayInput struct { + _ struct{} `type:"structure"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The Amazon Resource Name (ARN) of the transit gateway. For more information, + // see Resources Defined by Amazon EC2 (https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazonec2.html#amazonec2-resources-for-iam-policies). + // + // TransitGatewayArn is a required field + TransitGatewayArn *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s RegisterTransitGatewayInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RegisterTransitGatewayInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RegisterTransitGatewayInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RegisterTransitGatewayInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + if s.TransitGatewayArn == nil { + invalidParams.Add(request.NewErrParamRequired("TransitGatewayArn")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *RegisterTransitGatewayInput) SetGlobalNetworkId(v string) *RegisterTransitGatewayInput { + s.GlobalNetworkId = &v + return s +} + +// SetTransitGatewayArn sets the TransitGatewayArn field's value. +func (s *RegisterTransitGatewayInput) SetTransitGatewayArn(v string) *RegisterTransitGatewayInput { + s.TransitGatewayArn = &v + return s +} + +type RegisterTransitGatewayOutput struct { + _ struct{} `type:"structure"` + + // Information about the transit gateway registration. + TransitGatewayRegistration *TransitGatewayRegistration `type:"structure"` +} + +// String returns the string representation +func (s RegisterTransitGatewayOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RegisterTransitGatewayOutput) GoString() string { + return s.String() +} + +// SetTransitGatewayRegistration sets the TransitGatewayRegistration field's value. +func (s *RegisterTransitGatewayOutput) SetTransitGatewayRegistration(v *TransitGatewayRegistration) *RegisterTransitGatewayOutput { + s.TransitGatewayRegistration = v + return s +} + +// The specified resource could not be found. +type ResourceNotFoundException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"Message" type:"string"` + + // The ID of the resource. + // + // ResourceId is a required field + ResourceId *string `type:"string" required:"true"` + + // The resource type. + // + // ResourceType is a required field + ResourceType *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ResourceNotFoundException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResourceNotFoundException) GoString() string { + return s.String() +} + +func newErrorResourceNotFoundException(v protocol.ResponseMetadata) error { + return &ResourceNotFoundException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ResourceNotFoundException) Code() string { + return "ResourceNotFoundException" +} + +// Message returns the exception's message. +func (s *ResourceNotFoundException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ResourceNotFoundException) OrigErr() error { + return nil +} + +func (s *ResourceNotFoundException) Error() string { + return fmt.Sprintf("%s: %s\n%s", s.Code(), s.Message(), s.String()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ResourceNotFoundException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ResourceNotFoundException) RequestID() string { + return s.RespMetadata.RequestID +} + +// A service limit was exceeded. +type ServiceQuotaExceededException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + // The limit code. + // + // LimitCode is a required field + LimitCode *string `type:"string" required:"true"` + + // The error message. + Message_ *string `locationName:"Message" type:"string"` + + // The ID of the resource. + ResourceId *string `type:"string"` + + // The resource type. + ResourceType *string `type:"string"` + + // The service code. + // + // ServiceCode is a required field + ServiceCode *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ServiceQuotaExceededException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ServiceQuotaExceededException) GoString() string { + return s.String() +} + +func newErrorServiceQuotaExceededException(v protocol.ResponseMetadata) error { + return &ServiceQuotaExceededException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ServiceQuotaExceededException) Code() string { + return "ServiceQuotaExceededException" +} + +// Message returns the exception's message. +func (s *ServiceQuotaExceededException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ServiceQuotaExceededException) OrigErr() error { + return nil +} + +func (s *ServiceQuotaExceededException) Error() string { + return fmt.Sprintf("%s: %s\n%s", s.Code(), s.Message(), s.String()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ServiceQuotaExceededException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ServiceQuotaExceededException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Describes a site. +type Site struct { + _ struct{} `type:"structure"` + + // The date and time that the site was created. + CreatedAt *time.Time `type:"timestamp"` + + // The description of the site. + Description *string `type:"string"` + + // The ID of the global network. + GlobalNetworkId *string `type:"string"` + + // The location of the site. + Location *Location `type:"structure"` + + // The Amazon Resource Name (ARN) of the site. + SiteArn *string `type:"string"` + + // The ID of the site. + SiteId *string `type:"string"` + + // The state of the site. + State *string `type:"string" enum:"SiteState"` + + // The tags for the site. + Tags []*Tag `type:"list"` +} + +// String returns the string representation +func (s Site) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Site) GoString() string { + return s.String() +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *Site) SetCreatedAt(v time.Time) *Site { + s.CreatedAt = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *Site) SetDescription(v string) *Site { + s.Description = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *Site) SetGlobalNetworkId(v string) *Site { + s.GlobalNetworkId = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *Site) SetLocation(v *Location) *Site { + s.Location = v + return s +} + +// SetSiteArn sets the SiteArn field's value. +func (s *Site) SetSiteArn(v string) *Site { + s.SiteArn = &v + return s +} + +// SetSiteId sets the SiteId field's value. +func (s *Site) SetSiteId(v string) *Site { + s.SiteId = &v + return s +} + +// SetState sets the State field's value. +func (s *Site) SetState(v string) *Site { + s.State = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *Site) SetTags(v []*Tag) *Site { + s.Tags = v + return s +} + +// Describes a tag. +type Tag struct { + _ struct{} `type:"structure"` + + // The tag key. + // + // Length Constraints: Maximum length of 128 characters. + Key *string `type:"string"` + + // The tag value. + // + // Length Constraints: Maximum length of 256 characters. + Value *string `type:"string"` +} + +// String returns the string representation +func (s Tag) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Tag) GoString() string { + return s.String() +} + +// SetKey sets the Key field's value. +func (s *Tag) SetKey(v string) *Tag { + s.Key = &v + return s +} + +// SetValue sets the Value field's value. +func (s *Tag) SetValue(v string) *Tag { + s.Value = &v + return s +} + +type TagResourceInput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the resource. + // + // ResourceArn is a required field + ResourceArn *string `location:"uri" locationName:"resourceArn" type:"string" required:"true"` + + // The tags to apply to the specified resource. + // + // Tags is a required field + Tags []*Tag `type:"list" required:"true"` +} + +// String returns the string representation +func (s TagResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TagResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *TagResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "TagResourceInput"} + if s.ResourceArn == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceArn")) + } + if s.ResourceArn != nil && len(*s.ResourceArn) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceArn", 1)) + } + if s.Tags == nil { + invalidParams.Add(request.NewErrParamRequired("Tags")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetResourceArn sets the ResourceArn field's value. +func (s *TagResourceInput) SetResourceArn(v string) *TagResourceInput { + s.ResourceArn = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *TagResourceInput) SetTags(v []*Tag) *TagResourceInput { + s.Tags = v + return s +} + +type TagResourceOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s TagResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TagResourceOutput) GoString() string { + return s.String() +} + +// The request was denied due to request throttling. +type ThrottlingException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"Message" type:"string"` + + // Indicates when to retry the request. + RetryAfterSeconds *int64 `location:"header" locationName:"Retry-After" type:"integer"` +} + +// String returns the string representation +func (s ThrottlingException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ThrottlingException) GoString() string { + return s.String() +} + +func newErrorThrottlingException(v protocol.ResponseMetadata) error { + return &ThrottlingException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ThrottlingException) Code() string { + return "ThrottlingException" +} + +// Message returns the exception's message. +func (s *ThrottlingException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ThrottlingException) OrigErr() error { + return nil +} + +func (s *ThrottlingException) Error() string { + return fmt.Sprintf("%s: %s\n%s", s.Code(), s.Message(), s.String()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ThrottlingException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ThrottlingException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Describes the registration of a transit gateway to a global network. +type TransitGatewayRegistration struct { + _ struct{} `type:"structure"` + + // The ID of the global network. + GlobalNetworkId *string `type:"string"` + + // The state of the transit gateway registration. + State *TransitGatewayRegistrationStateReason `type:"structure"` + + // The Amazon Resource Name (ARN) of the transit gateway. + TransitGatewayArn *string `type:"string"` +} + +// String returns the string representation +func (s TransitGatewayRegistration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TransitGatewayRegistration) GoString() string { + return s.String() +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *TransitGatewayRegistration) SetGlobalNetworkId(v string) *TransitGatewayRegistration { + s.GlobalNetworkId = &v + return s +} + +// SetState sets the State field's value. +func (s *TransitGatewayRegistration) SetState(v *TransitGatewayRegistrationStateReason) *TransitGatewayRegistration { + s.State = v + return s +} + +// SetTransitGatewayArn sets the TransitGatewayArn field's value. +func (s *TransitGatewayRegistration) SetTransitGatewayArn(v string) *TransitGatewayRegistration { + s.TransitGatewayArn = &v + return s +} + +// Describes the status of a transit gateway registration. +type TransitGatewayRegistrationStateReason struct { + _ struct{} `type:"structure"` + + // The code for the state reason. + Code *string `type:"string" enum:"TransitGatewayRegistrationState"` + + // The message for the state reason. + Message *string `type:"string"` +} + +// String returns the string representation +func (s TransitGatewayRegistrationStateReason) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TransitGatewayRegistrationStateReason) GoString() string { + return s.String() +} + +// SetCode sets the Code field's value. +func (s *TransitGatewayRegistrationStateReason) SetCode(v string) *TransitGatewayRegistrationStateReason { + s.Code = &v + return s +} + +// SetMessage sets the Message field's value. +func (s *TransitGatewayRegistrationStateReason) SetMessage(v string) *TransitGatewayRegistrationStateReason { + s.Message = &v + return s +} + +type UntagResourceInput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the resource. + // + // ResourceArn is a required field + ResourceArn *string `location:"uri" locationName:"resourceArn" type:"string" required:"true"` + + // The tag keys to remove from the specified resource. + // + // TagKeys is a required field + TagKeys []*string `location:"querystring" locationName:"tagKeys" type:"list" required:"true"` +} + +// String returns the string representation +func (s UntagResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UntagResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UntagResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UntagResourceInput"} + if s.ResourceArn == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceArn")) + } + if s.ResourceArn != nil && len(*s.ResourceArn) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceArn", 1)) + } + if s.TagKeys == nil { + invalidParams.Add(request.NewErrParamRequired("TagKeys")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetResourceArn sets the ResourceArn field's value. +func (s *UntagResourceInput) SetResourceArn(v string) *UntagResourceInput { + s.ResourceArn = &v + return s +} + +// SetTagKeys sets the TagKeys field's value. +func (s *UntagResourceInput) SetTagKeys(v []*string) *UntagResourceInput { + s.TagKeys = v + return s +} + +type UntagResourceOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s UntagResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UntagResourceOutput) GoString() string { + return s.String() +} + +type UpdateDeviceInput struct { + _ struct{} `type:"structure"` + + // A description of the device. + // + // Length Constraints: Maximum length of 256 characters. + Description *string `type:"string"` + + // The ID of the device. + // + // DeviceId is a required field + DeviceId *string `location:"uri" locationName:"deviceId" type:"string" required:"true"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // Describes a location. + Location *Location `type:"structure"` + + // The model of the device. + // + // Length Constraints: Maximum length of 128 characters. + Model *string `type:"string"` + + // The serial number of the device. + // + // Length Constraints: Maximum length of 128 characters. + SerialNumber *string `type:"string"` + + // The ID of the site. + SiteId *string `type:"string"` + + // The type of the device. + Type *string `type:"string"` + + // The vendor of the device. + // + // Length Constraints: Maximum length of 128 characters. + Vendor *string `type:"string"` +} + +// String returns the string representation +func (s UpdateDeviceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateDeviceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateDeviceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateDeviceInput"} + if s.DeviceId == nil { + invalidParams.Add(request.NewErrParamRequired("DeviceId")) + } + if s.DeviceId != nil && len(*s.DeviceId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("DeviceId", 1)) + } + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDescription sets the Description field's value. +func (s *UpdateDeviceInput) SetDescription(v string) *UpdateDeviceInput { + s.Description = &v + return s +} + +// SetDeviceId sets the DeviceId field's value. +func (s *UpdateDeviceInput) SetDeviceId(v string) *UpdateDeviceInput { + s.DeviceId = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *UpdateDeviceInput) SetGlobalNetworkId(v string) *UpdateDeviceInput { + s.GlobalNetworkId = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *UpdateDeviceInput) SetLocation(v *Location) *UpdateDeviceInput { + s.Location = v + return s +} + +// SetModel sets the Model field's value. +func (s *UpdateDeviceInput) SetModel(v string) *UpdateDeviceInput { + s.Model = &v + return s +} + +// SetSerialNumber sets the SerialNumber field's value. +func (s *UpdateDeviceInput) SetSerialNumber(v string) *UpdateDeviceInput { + s.SerialNumber = &v + return s +} + +// SetSiteId sets the SiteId field's value. +func (s *UpdateDeviceInput) SetSiteId(v string) *UpdateDeviceInput { + s.SiteId = &v + return s +} + +// SetType sets the Type field's value. +func (s *UpdateDeviceInput) SetType(v string) *UpdateDeviceInput { + s.Type = &v + return s +} + +// SetVendor sets the Vendor field's value. +func (s *UpdateDeviceInput) SetVendor(v string) *UpdateDeviceInput { + s.Vendor = &v + return s +} + +type UpdateDeviceOutput struct { + _ struct{} `type:"structure"` + + // Information about the device. + Device *Device `type:"structure"` +} + +// String returns the string representation +func (s UpdateDeviceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateDeviceOutput) GoString() string { + return s.String() +} + +// SetDevice sets the Device field's value. +func (s *UpdateDeviceOutput) SetDevice(v *Device) *UpdateDeviceOutput { + s.Device = v + return s +} + +type UpdateGlobalNetworkInput struct { + _ struct{} `type:"structure"` + + // A description of the global network. + // + // Length Constraints: Maximum length of 256 characters. + Description *string `type:"string"` + + // The ID of your global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` +} + +// String returns the string representation +func (s UpdateGlobalNetworkInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateGlobalNetworkInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateGlobalNetworkInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateGlobalNetworkInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDescription sets the Description field's value. +func (s *UpdateGlobalNetworkInput) SetDescription(v string) *UpdateGlobalNetworkInput { + s.Description = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *UpdateGlobalNetworkInput) SetGlobalNetworkId(v string) *UpdateGlobalNetworkInput { + s.GlobalNetworkId = &v + return s +} + +type UpdateGlobalNetworkOutput struct { + _ struct{} `type:"structure"` + + // Information about the global network object. + GlobalNetwork *GlobalNetwork `type:"structure"` +} + +// String returns the string representation +func (s UpdateGlobalNetworkOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateGlobalNetworkOutput) GoString() string { + return s.String() +} + +// SetGlobalNetwork sets the GlobalNetwork field's value. +func (s *UpdateGlobalNetworkOutput) SetGlobalNetwork(v *GlobalNetwork) *UpdateGlobalNetworkOutput { + s.GlobalNetwork = v + return s +} + +type UpdateLinkInput struct { + _ struct{} `type:"structure"` + + // The upload and download speed in Mbps. + Bandwidth *Bandwidth `type:"structure"` + + // A description of the link. + // + // Length Constraints: Maximum length of 256 characters. + Description *string `type:"string"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The ID of the link. + // + // LinkId is a required field + LinkId *string `location:"uri" locationName:"linkId" type:"string" required:"true"` + + // The provider of the link. + // + // Length Constraints: Maximum length of 128 characters. + Provider *string `type:"string"` + + // The type of the link. + // + // Length Constraints: Maximum length of 128 characters. + Type *string `type:"string"` +} + +// String returns the string representation +func (s UpdateLinkInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateLinkInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateLinkInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateLinkInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + if s.LinkId == nil { + invalidParams.Add(request.NewErrParamRequired("LinkId")) + } + if s.LinkId != nil && len(*s.LinkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("LinkId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBandwidth sets the Bandwidth field's value. +func (s *UpdateLinkInput) SetBandwidth(v *Bandwidth) *UpdateLinkInput { + s.Bandwidth = v + return s +} + +// SetDescription sets the Description field's value. +func (s *UpdateLinkInput) SetDescription(v string) *UpdateLinkInput { + s.Description = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *UpdateLinkInput) SetGlobalNetworkId(v string) *UpdateLinkInput { + s.GlobalNetworkId = &v + return s +} + +// SetLinkId sets the LinkId field's value. +func (s *UpdateLinkInput) SetLinkId(v string) *UpdateLinkInput { + s.LinkId = &v + return s +} + +// SetProvider sets the Provider field's value. +func (s *UpdateLinkInput) SetProvider(v string) *UpdateLinkInput { + s.Provider = &v + return s +} + +// SetType sets the Type field's value. +func (s *UpdateLinkInput) SetType(v string) *UpdateLinkInput { + s.Type = &v + return s +} + +type UpdateLinkOutput struct { + _ struct{} `type:"structure"` + + // Information about the link. + Link *Link `type:"structure"` +} + +// String returns the string representation +func (s UpdateLinkOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateLinkOutput) GoString() string { + return s.String() +} + +// SetLink sets the Link field's value. +func (s *UpdateLinkOutput) SetLink(v *Link) *UpdateLinkOutput { + s.Link = v + return s +} + +type UpdateSiteInput struct { + _ struct{} `type:"structure"` + + // A description of your site. + // + // Length Constraints: Maximum length of 256 characters. + Description *string `type:"string"` + + // The ID of the global network. + // + // GlobalNetworkId is a required field + GlobalNetworkId *string `location:"uri" locationName:"globalNetworkId" type:"string" required:"true"` + + // The site location: + // + // * Address: The physical address of the site. + // + // * Latitude: The latitude of the site. + // + // * Longitude: The longitude of the site. + Location *Location `type:"structure"` + + // The ID of your site. + // + // SiteId is a required field + SiteId *string `location:"uri" locationName:"siteId" type:"string" required:"true"` +} + +// String returns the string representation +func (s UpdateSiteInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateSiteInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateSiteInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateSiteInput"} + if s.GlobalNetworkId == nil { + invalidParams.Add(request.NewErrParamRequired("GlobalNetworkId")) + } + if s.GlobalNetworkId != nil && len(*s.GlobalNetworkId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GlobalNetworkId", 1)) + } + if s.SiteId == nil { + invalidParams.Add(request.NewErrParamRequired("SiteId")) + } + if s.SiteId != nil && len(*s.SiteId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("SiteId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDescription sets the Description field's value. +func (s *UpdateSiteInput) SetDescription(v string) *UpdateSiteInput { + s.Description = &v + return s +} + +// SetGlobalNetworkId sets the GlobalNetworkId field's value. +func (s *UpdateSiteInput) SetGlobalNetworkId(v string) *UpdateSiteInput { + s.GlobalNetworkId = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *UpdateSiteInput) SetLocation(v *Location) *UpdateSiteInput { + s.Location = v + return s +} + +// SetSiteId sets the SiteId field's value. +func (s *UpdateSiteInput) SetSiteId(v string) *UpdateSiteInput { + s.SiteId = &v + return s +} + +type UpdateSiteOutput struct { + _ struct{} `type:"structure"` + + // Information about the site. + Site *Site `type:"structure"` +} + +// String returns the string representation +func (s UpdateSiteOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateSiteOutput) GoString() string { + return s.String() +} + +// SetSite sets the Site field's value. +func (s *UpdateSiteOutput) SetSite(v *Site) *UpdateSiteOutput { + s.Site = v + return s +} + +// The input fails to satisfy the constraints. +type ValidationException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + // The fields that caused the error, if applicable. + Fields []*ValidationExceptionField `type:"list"` + + Message_ *string `locationName:"Message" type:"string"` + + // The reason for the error. + Reason *string `type:"string" enum:"ValidationExceptionReason"` +} + +// String returns the string representation +func (s ValidationException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ValidationException) GoString() string { + return s.String() +} + +func newErrorValidationException(v protocol.ResponseMetadata) error { + return &ValidationException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ValidationException) Code() string { + return "ValidationException" +} + +// Message returns the exception's message. +func (s *ValidationException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ValidationException) OrigErr() error { + return nil +} + +func (s *ValidationException) Error() string { + return fmt.Sprintf("%s: %s\n%s", s.Code(), s.Message(), s.String()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ValidationException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ValidationException) RequestID() string { + return s.RespMetadata.RequestID +} + +// Describes a validation exception for a field. +type ValidationExceptionField struct { + _ struct{} `type:"structure"` + + // The message for the field. + // + // Message is a required field + Message *string `type:"string" required:"true"` + + // The name of the field. + // + // Name is a required field + Name *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ValidationExceptionField) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ValidationExceptionField) GoString() string { + return s.String() +} + +// SetMessage sets the Message field's value. +func (s *ValidationExceptionField) SetMessage(v string) *ValidationExceptionField { + s.Message = &v + return s +} + +// SetName sets the Name field's value. +func (s *ValidationExceptionField) SetName(v string) *ValidationExceptionField { + s.Name = &v + return s +} + +const ( + // CustomerGatewayAssociationStatePending is a CustomerGatewayAssociationState enum value + CustomerGatewayAssociationStatePending = "PENDING" + + // CustomerGatewayAssociationStateAvailable is a CustomerGatewayAssociationState enum value + CustomerGatewayAssociationStateAvailable = "AVAILABLE" + + // CustomerGatewayAssociationStateDeleting is a CustomerGatewayAssociationState enum value + CustomerGatewayAssociationStateDeleting = "DELETING" + + // CustomerGatewayAssociationStateDeleted is a CustomerGatewayAssociationState enum value + CustomerGatewayAssociationStateDeleted = "DELETED" +) + +const ( + // DeviceStatePending is a DeviceState enum value + DeviceStatePending = "PENDING" + + // DeviceStateAvailable is a DeviceState enum value + DeviceStateAvailable = "AVAILABLE" + + // DeviceStateDeleting is a DeviceState enum value + DeviceStateDeleting = "DELETING" + + // DeviceStateUpdating is a DeviceState enum value + DeviceStateUpdating = "UPDATING" +) + +const ( + // GlobalNetworkStatePending is a GlobalNetworkState enum value + GlobalNetworkStatePending = "PENDING" + + // GlobalNetworkStateAvailable is a GlobalNetworkState enum value + GlobalNetworkStateAvailable = "AVAILABLE" + + // GlobalNetworkStateDeleting is a GlobalNetworkState enum value + GlobalNetworkStateDeleting = "DELETING" + + // GlobalNetworkStateUpdating is a GlobalNetworkState enum value + GlobalNetworkStateUpdating = "UPDATING" +) + +const ( + // LinkAssociationStatePending is a LinkAssociationState enum value + LinkAssociationStatePending = "PENDING" + + // LinkAssociationStateAvailable is a LinkAssociationState enum value + LinkAssociationStateAvailable = "AVAILABLE" + + // LinkAssociationStateDeleting is a LinkAssociationState enum value + LinkAssociationStateDeleting = "DELETING" + + // LinkAssociationStateDeleted is a LinkAssociationState enum value + LinkAssociationStateDeleted = "DELETED" +) + +const ( + // LinkStatePending is a LinkState enum value + LinkStatePending = "PENDING" + + // LinkStateAvailable is a LinkState enum value + LinkStateAvailable = "AVAILABLE" + + // LinkStateDeleting is a LinkState enum value + LinkStateDeleting = "DELETING" + + // LinkStateUpdating is a LinkState enum value + LinkStateUpdating = "UPDATING" +) + +const ( + // SiteStatePending is a SiteState enum value + SiteStatePending = "PENDING" + + // SiteStateAvailable is a SiteState enum value + SiteStateAvailable = "AVAILABLE" + + // SiteStateDeleting is a SiteState enum value + SiteStateDeleting = "DELETING" + + // SiteStateUpdating is a SiteState enum value + SiteStateUpdating = "UPDATING" +) + +const ( + // TransitGatewayRegistrationStatePending is a TransitGatewayRegistrationState enum value + TransitGatewayRegistrationStatePending = "PENDING" + + // TransitGatewayRegistrationStateAvailable is a TransitGatewayRegistrationState enum value + TransitGatewayRegistrationStateAvailable = "AVAILABLE" + + // TransitGatewayRegistrationStateDeleting is a TransitGatewayRegistrationState enum value + TransitGatewayRegistrationStateDeleting = "DELETING" + + // TransitGatewayRegistrationStateDeleted is a TransitGatewayRegistrationState enum value + TransitGatewayRegistrationStateDeleted = "DELETED" + + // TransitGatewayRegistrationStateFailed is a TransitGatewayRegistrationState enum value + TransitGatewayRegistrationStateFailed = "FAILED" +) + +const ( + // ValidationExceptionReasonUnknownOperation is a ValidationExceptionReason enum value + ValidationExceptionReasonUnknownOperation = "UnknownOperation" + + // ValidationExceptionReasonCannotParse is a ValidationExceptionReason enum value + ValidationExceptionReasonCannotParse = "CannotParse" + + // ValidationExceptionReasonFieldValidationFailed is a ValidationExceptionReason enum value + ValidationExceptionReasonFieldValidationFailed = "FieldValidationFailed" + + // ValidationExceptionReasonOther is a ValidationExceptionReason enum value + ValidationExceptionReasonOther = "Other" +) diff --git a/vendor/github.com/aws/aws-sdk-go/service/networkmanager/doc.go b/vendor/github.com/aws/aws-sdk-go/service/networkmanager/doc.go new file mode 100644 index 00000000000..65cd8cb7a9e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/networkmanager/doc.go @@ -0,0 +1,30 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package networkmanager provides the client and types for making API +// requests to AWS Network Manager. +// +// Transit Gateway Network Manager (Network Manager) enables you to create a +// global network, in which you can monitor your AWS and on-premises networks +// that are built around transit gateways. +// +// See https://docs.aws.amazon.com/goto/WebAPI/networkmanager-2019-07-05 for more information on this service. +// +// See networkmanager package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/networkmanager/ +// +// Using the Client +// +// To contact AWS Network Manager with the SDK use the New function to create +// a new service client. With that client you can make API requests to the service. +// These clients are safe to use concurrently. +// +// See the SDK's documentation for more information on how to use the SDK. +// https://docs.aws.amazon.com/sdk-for-go/api/ +// +// See aws.Config documentation for more information on configuring SDK clients. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// See the AWS Network Manager client NetworkManager for more +// information on creating client for this service. +// https://docs.aws.amazon.com/sdk-for-go/api/service/networkmanager/#New +package networkmanager diff --git a/vendor/github.com/aws/aws-sdk-go/service/networkmanager/errors.go b/vendor/github.com/aws/aws-sdk-go/service/networkmanager/errors.go new file mode 100644 index 00000000000..9e9c2bf05e6 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/networkmanager/errors.go @@ -0,0 +1,63 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package networkmanager + +import ( + "github.com/aws/aws-sdk-go/private/protocol" +) + +const ( + + // ErrCodeAccessDeniedException for service response error code + // "AccessDeniedException". + // + // You do not have sufficient access to perform this action. + ErrCodeAccessDeniedException = "AccessDeniedException" + + // ErrCodeConflictException for service response error code + // "ConflictException". + // + // There was a conflict processing the request. Updating or deleting the resource + // can cause an inconsistent state. + ErrCodeConflictException = "ConflictException" + + // ErrCodeInternalServerException for service response error code + // "InternalServerException". + // + // The request has failed due to an internal error. + ErrCodeInternalServerException = "InternalServerException" + + // ErrCodeResourceNotFoundException for service response error code + // "ResourceNotFoundException". + // + // The specified resource could not be found. + ErrCodeResourceNotFoundException = "ResourceNotFoundException" + + // ErrCodeServiceQuotaExceededException for service response error code + // "ServiceQuotaExceededException". + // + // A service limit was exceeded. + ErrCodeServiceQuotaExceededException = "ServiceQuotaExceededException" + + // ErrCodeThrottlingException for service response error code + // "ThrottlingException". + // + // The request was denied due to request throttling. + ErrCodeThrottlingException = "ThrottlingException" + + // ErrCodeValidationException for service response error code + // "ValidationException". + // + // The input fails to satisfy the constraints. + ErrCodeValidationException = "ValidationException" +) + +var exceptionFromCode = map[string]func(protocol.ResponseMetadata) error{ + "AccessDeniedException": newErrorAccessDeniedException, + "ConflictException": newErrorConflictException, + "InternalServerException": newErrorInternalServerException, + "ResourceNotFoundException": newErrorResourceNotFoundException, + "ServiceQuotaExceededException": newErrorServiceQuotaExceededException, + "ThrottlingException": newErrorThrottlingException, + "ValidationException": newErrorValidationException, +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/networkmanager/service.go b/vendor/github.com/aws/aws-sdk-go/service/networkmanager/service.go new file mode 100644 index 00000000000..56ce4f413be --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/networkmanager/service.go @@ -0,0 +1,104 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package networkmanager + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/signer/v4" + "github.com/aws/aws-sdk-go/private/protocol" + "github.com/aws/aws-sdk-go/private/protocol/restjson" +) + +// NetworkManager provides the API operation methods for making requests to +// AWS Network Manager. See this package's package overview docs +// for details on the service. +// +// NetworkManager methods are safe to use concurrently. It is not safe to +// modify mutate any of the struct's properties though. +type NetworkManager struct { + *client.Client +} + +// Used for custom client initialization logic +var initClient func(*client.Client) + +// Used for custom request initialization logic +var initRequest func(*request.Request) + +// Service information constants +const ( + ServiceName = "NetworkManager" // Name of service. + EndpointsID = "networkmanager" // ID to lookup a service endpoint with. + ServiceID = "NetworkManager" // ServiceID is a unique identifier of a specific service. +) + +// New creates a new instance of the NetworkManager client with a session. +// If additional configuration is needed for the client instance use the optional +// aws.Config parameter to add your extra config. +// +// Example: +// mySession := session.Must(session.NewSession()) +// +// // Create a NetworkManager client from just a session. +// svc := networkmanager.New(mySession) +// +// // Create a NetworkManager client with additional configuration +// svc := networkmanager.New(mySession, aws.NewConfig().WithRegion("us-west-2")) +func New(p client.ConfigProvider, cfgs ...*aws.Config) *NetworkManager { + c := p.ClientConfig(EndpointsID, cfgs...) + if c.SigningNameDerived || len(c.SigningName) == 0 { + c.SigningName = "networkmanager" + } + return newClient(*c.Config, c.Handlers, c.PartitionID, c.Endpoint, c.SigningRegion, c.SigningName) +} + +// newClient creates, initializes and returns a new service client instance. +func newClient(cfg aws.Config, handlers request.Handlers, partitionID, endpoint, signingRegion, signingName string) *NetworkManager { + svc := &NetworkManager{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: ServiceName, + ServiceID: ServiceID, + SigningName: signingName, + SigningRegion: signingRegion, + PartitionID: partitionID, + Endpoint: endpoint, + APIVersion: "2019-07-05", + }, + handlers, + ), + } + + // Handlers + svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) + svc.Handlers.Build.PushBackNamed(restjson.BuildHandler) + svc.Handlers.Unmarshal.PushBackNamed(restjson.UnmarshalHandler) + svc.Handlers.UnmarshalMeta.PushBackNamed(restjson.UnmarshalMetaHandler) + svc.Handlers.UnmarshalError.PushBackNamed( + protocol.NewUnmarshalErrorHandler(restjson.NewUnmarshalTypedError(exceptionFromCode)).NamedHandler(), + ) + + // Run custom client initialization if present + if initClient != nil { + initClient(svc.Client) + } + + return svc +} + +// newRequest creates a new request for a NetworkManager operation and runs any +// custom request initialization. +func (c *NetworkManager) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) + + // Run custom request initialization if present + if initRequest != nil { + initRequest(req) + } + + return req +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 3459394f6b1..ffdbe2c150a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -165,6 +165,7 @@ github.com/aws/aws-sdk-go/service/mediastore github.com/aws/aws-sdk-go/service/mediastoredata github.com/aws/aws-sdk-go/service/mq github.com/aws/aws-sdk-go/service/neptune +github.com/aws/aws-sdk-go/service/networkmanager github.com/aws/aws-sdk-go/service/opsworks github.com/aws/aws-sdk-go/service/organizations github.com/aws/aws-sdk-go/service/personalize diff --git a/website/allowed-subcategories.txt b/website/allowed-subcategories.txt index 6a995578b82..fbb7b427f17 100644 --- a/website/allowed-subcategories.txt +++ b/website/allowed-subcategories.txt @@ -103,6 +103,7 @@ SimpleDB Step Function (SFN) Storage Gateway Transfer +Transit Gateway Network Manager VPC WAF Regional WAF diff --git a/website/docs/guides/custom-service-endpoints.html.md b/website/docs/guides/custom-service-endpoints.html.md index cb46a8dd6a2..e186ac084c3 100644 --- a/website/docs/guides/custom-service-endpoints.html.md +++ b/website/docs/guides/custom-service-endpoints.html.md @@ -149,6 +149,7 @@ The Terraform AWS Provider allows the following endpoints to be customized:
  • mediastoredata
  • mq
  • neptune
  • +
  • networkmanager
  • opsworks
  • organizations
  • personalize
  • From 7020ac01484b8a65095d2d685cace6805374c83a Mon Sep 17 00:00:00 2001 From: angie pinilla Date: Thu, 14 May 2020 11:44:23 -0400 Subject: [PATCH 145/475] Update CHANGELOG for #11809 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dc39ae3764..ed7e5e79681 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ ENHANCEMENTS: BUG FIXES: * resource/aws_codebuild_project: Allow empty value (`""`) environment variables [GH-11572] +* resource/aws_security_group_rule: Prevent recreation when `source_security_group_id` refers to a security group across accounts [GH-11809] ## 2.61.0 (May 08, 2020) From 3dd120d57db515e58126b918c2cbdd7d713c4ba0 Mon Sep 17 00:00:00 2001 From: Pascal van Buijtene Date: Thu, 14 May 2020 22:32:08 +0200 Subject: [PATCH 146/475] Improve nil checks --- aws/resource_aws_wafv2_ip_set.go | 17 ++++++++++------- aws/resource_aws_wafv2_ip_set_test.go | 11 +++++++++-- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/aws/resource_aws_wafv2_ip_set.go b/aws/resource_aws_wafv2_ip_set.go index 83e7c53dfd8..2019da2293e 100644 --- a/aws/resource_aws_wafv2_ip_set.go +++ b/aws/resource_aws_wafv2_ip_set.go @@ -130,10 +130,14 @@ func resourceAwsWafv2IPSetCreate(d *schema.ResourceData, meta interface{}) error resp, err := conn.CreateIPSet(params) - if err != nil || resp == nil || resp.Summary == nil { + if err != nil { return fmt.Errorf("Error creating WAFv2 IPSet: %s", err) } + if resp == nil || resp.Summary == nil { + return fmt.Errorf("Error creating WAFv2 IPSet") + } + d.SetId(aws.StringValue(resp.Summary.Id)) return resourceAwsWafv2IPSetRead(d, meta) @@ -156,7 +160,6 @@ func resourceAwsWafv2IPSetRead(d *schema.ResourceData, meta interface{}) error { d.SetId("") return nil } - return err } @@ -164,11 +167,11 @@ func resourceAwsWafv2IPSetRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("Error reading WAFv2 IPSet") } - d.Set("name", resp.IPSet.Name) - d.Set("description", resp.IPSet.Description) - d.Set("ip_address_version", resp.IPSet.IPAddressVersion) - d.Set("arn", resp.IPSet.ARN) - d.Set("lock_token", resp.LockToken) + d.Set("name", aws.StringValue(resp.IPSet.Name)) + d.Set("description", aws.StringValue(resp.IPSet.Description)) + d.Set("ip_address_version", aws.StringValue(resp.IPSet.IPAddressVersion)) + d.Set("arn", aws.StringValue(resp.IPSet.ARN)) + d.Set("lock_token", aws.StringValue(resp.LockToken)) if err := d.Set("addresses", flattenStringSet(resp.IPSet.Addresses)); err != nil { return fmt.Errorf("Error setting addresses: %s", err) diff --git a/aws/resource_aws_wafv2_ip_set_test.go b/aws/resource_aws_wafv2_ip_set_test.go index 0787f145a8d..dacd0567f2a 100644 --- a/aws/resource_aws_wafv2_ip_set_test.go +++ b/aws/resource_aws_wafv2_ip_set_test.go @@ -250,7 +250,10 @@ func testAccCheckAWSWafv2IPSetDestroy(s *terraform.State) error { }) if err == nil { - if aws.StringValue(resp.IPSet.Id) == rs.Primary.ID && resp != nil && resp.IPSet != nil { + if resp == nil || resp.IPSet == nil { + return fmt.Errorf("Error getting WAFv2 IPSet") + } + if aws.StringValue(resp.IPSet.Id) == rs.Primary.ID { return fmt.Errorf("WAFv2 IPSet %s still exists", rs.Primary.ID) } return nil @@ -289,7 +292,11 @@ func testAccCheckAWSWafv2IPSetExists(n string, v *wafv2.IPSet) resource.TestChec return err } - if aws.StringValue(resp.IPSet.Id) == rs.Primary.ID && resp != nil && resp.IPSet != nil { + if resp == nil || resp.IPSet == nil { + return fmt.Errorf("Error getting WAFv2 IPSet") + } + + if aws.StringValue(resp.IPSet.Id) == rs.Primary.ID { *v = *resp.IPSet return nil } From 4a296f43be2996350187a0ef3a6afb3c2afe7a1e Mon Sep 17 00:00:00 2001 From: John Barnes Date: Thu, 14 May 2020 19:09:11 -0400 Subject: [PATCH 147/475] resource/aws_datasync_task: Support `ONLY_FILES_TRANSFERRED` value in `verify_mode` argument (#12897) Output from acceptance testing (test failures unrelated): ``` --- PASS: TestAccAWSDataSyncTask_CloudWatchLogGroupARN (232.83s) --- PASS: TestAccAWSDataSyncTask_disappears (248.46s) --- PASS: TestAccAWSDataSyncTask_basic (251.56s) --- PASS: TestAccAWSDataSyncTask_DefaultSyncOptions_AtimeMtime (259.19s) --- PASS: TestAccAWSDataSyncTask_DefaultSyncOptions_VerifyMode (271.49s) --- PASS: TestAccAWSDataSyncTask_DefaultSyncOptions_PreserveDevices (288.71s) --- PASS: TestAccAWSDataSyncTask_DefaultSyncOptions_BytesPerSecond (290.06s) --- PASS: TestAccAWSDataSyncTask_DefaultSyncOptions_Uid (290.59s) --- FAIL: TestAccAWSDataSyncTask_DefaultSyncOptions_PosixPermissions (293.54s) --- FAIL: TestAccAWSDataSyncTask_DefaultSyncOptions_PreserveDeletedFiles (296.27s) --- PASS: TestAccAWSDataSyncTask_DefaultSyncOptions_Gid (321.15s) ``` --- aws/resource_aws_datasync_task.go | 1 + aws/resource_aws_datasync_task_test.go | 11 ++++++++++- website/docs/r/datasync_task.html.markdown | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_datasync_task.go b/aws/resource_aws_datasync_task.go index 65405532107..9b5a76452a6 100644 --- a/aws/resource_aws_datasync_task.go +++ b/aws/resource_aws_datasync_task.go @@ -139,6 +139,7 @@ func resourceAwsDataSyncTask() *schema.Resource { ValidateFunc: validation.StringInSlice([]string{ datasync.VerifyModeNone, datasync.VerifyModePointInTimeConsistent, + datasync.VerifyModeOnlyFilesTransferred, }, false), }, }, diff --git a/aws/resource_aws_datasync_task_test.go b/aws/resource_aws_datasync_task_test.go index d1471807c44..1e406ed45d2 100644 --- a/aws/resource_aws_datasync_task_test.go +++ b/aws/resource_aws_datasync_task_test.go @@ -421,7 +421,7 @@ func TestAccAWSDataSyncTask_DefaultSyncOptions_Uid(t *testing.T) { } func TestAccAWSDataSyncTask_DefaultSyncOptions_VerifyMode(t *testing.T) { - var task1, task2 datasync.DescribeTaskOutput + var task1, task2, task3 datasync.DescribeTaskOutput rName := acctest.RandomWithPrefix("tf-acc-test") resourceName := "aws_datasync_task.test" @@ -452,6 +452,15 @@ func TestAccAWSDataSyncTask_DefaultSyncOptions_VerifyMode(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "options.0.verify_mode", "POINT_IN_TIME_CONSISTENT"), ), }, + { + Config: testAccAWSDataSyncTaskConfigDefaultSyncOptionsVerifyMode(rName, "ONLY_FILES_TRANSFERRED"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSDataSyncTaskExists(resourceName, &task3), + testAccCheckAWSDataSyncTaskNotRecreated(&task2, &task3), + resource.TestCheckResourceAttr(resourceName, "options.#", "1"), + resource.TestCheckResourceAttr(resourceName, "options.0.verify_mode", "ONLY_FILES_TRANSFERRED"), + ), + }, }, }) } diff --git a/website/docs/r/datasync_task.html.markdown b/website/docs/r/datasync_task.html.markdown index c12358e43b6..99e79f05885 100644 --- a/website/docs/r/datasync_task.html.markdown +++ b/website/docs/r/datasync_task.html.markdown @@ -49,7 +49,7 @@ The following arguments are supported inside the `options` configuration block: * `preserve_deleted_files` - (Optional) Whether files deleted in the source should be removed or preserved in the destination file system. Valid values: `PRESERVE`, `REMOVE`. Default: `PRESERVE`. * `preserve_devices` - (Optional) Whether the DataSync Task should preserve the metadata of block and character devices in the source files system, and recreate the files with that device name and metadata on the destination. The DataSync Task can’t sync the actual contents of such devices, because many of the devices are non-terminal and don’t return an end of file (EOF) marker. Valid values: `NONE`, `PRESERVE`. Default: `NONE` (ignore special devices). * `uid` - (Optional) User identifier of the file's owners. Valid values: `BOTH`, `INT_VALUE`, `NAME`, `NONE`. Default: `INT_VALUE` (preserve integer value of the ID). -* `verify_mode` - (Optional) Whether a data integrity verification should be performed at the end of a task execution after all data and metadata have been transferred. Valid values: `NONE`, `POINT_IN_TIME_CONSISTENT`. Default: `POINT_IN_TIME_CONSISTENT`. +* `verify_mode` - (Optional) Whether a data integrity verification should be performed at the end of a task execution after all data and metadata have been transferred. Valid values: `NONE`, `POINT_IN_TIME_CONSISTENT`, `ONLY_FILES_TRANSFERRED`. Default: `POINT_IN_TIME_CONSISTENT`. ## Attribute Reference From 56f5b0ceab959d6fbb0447f1c1337ed3695eae58 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Thu, 14 May 2020 19:10:23 -0400 Subject: [PATCH 148/475] Update CHANGELOG for #12897 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed7e5e79681..91a99ada950 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ENHANCEMENTS: * resource/aws_appsync_resolver: Add `cache_config` configuration block [GH-12747] * resource/aws_codebuild_project: Support `git_submodules_config` with `GITHUB` and `GITHUB_ENTERPRISE` source types [GH-13285] * resource/aws_codebuild_project: Support `SECRETS_MANAGER` environment variable type [GH-12572] +* resource/aws_datasync_task: Support `ONLY_FILES_TRANSFERRED` value in `verify_mode` argument [GH-12897] * resource/aws_iot_topic_rule: Add `dynamodbv2` configuration block [GH-7469] * resource/aws_iot_topic_rule: Add `iot_analytics` configuration block [GH-9859] * resource/aws_iot_topic_rule: Add `iot_events` configuration block [GH-9890] From 2152c63f8db245696c3d255e6b920b994cd2ac1c Mon Sep 17 00:00:00 2001 From: tf-release-bot Date: Fri, 15 May 2020 00:05:46 +0000 Subject: [PATCH 149/475] v2.62.0 --- CHANGELOG.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91a99ada950..f4079933a1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,25 +1,25 @@ -## 2.62.0 (Unreleased) +## 2.62.0 (May 15, 2020) FEATURES: -* **New Resource:** `aws_workspaces_workspace` [GH-11608] +* **New Resource:** `aws_workspaces_workspace` ([#11608](https://github.com/terraform-providers/terraform-provider-aws/issues/11608)) ENHANCEMENTS: -* resource/aws_appsync_resolver: Add `cache_config` configuration block [GH-12747] -* resource/aws_codebuild_project: Support `git_submodules_config` with `GITHUB` and `GITHUB_ENTERPRISE` source types [GH-13285] -* resource/aws_codebuild_project: Support `SECRETS_MANAGER` environment variable type [GH-12572] -* resource/aws_datasync_task: Support `ONLY_FILES_TRANSFERRED` value in `verify_mode` argument [GH-12897] -* resource/aws_iot_topic_rule: Add `dynamodbv2` configuration block [GH-7469] -* resource/aws_iot_topic_rule: Add `iot_analytics` configuration block [GH-9859] -* resource/aws_iot_topic_rule: Add `iot_events` configuration block [GH-9890] -* resource/aws_iot_topic_rule: Add `operation` argument to `dynamodb` configuration block [GH-12714] -* resource/aws_iot_topic_rule: Add `qos` argument `republish` configuration block [GH-12869] +* resource/aws_appsync_resolver: Add `cache_config` configuration block ([#12747](https://github.com/terraform-providers/terraform-provider-aws/issues/12747)) +* resource/aws_codebuild_project: Support `git_submodules_config` with `GITHUB` and `GITHUB_ENTERPRISE` source types ([#13285](https://github.com/terraform-providers/terraform-provider-aws/issues/13285)) +* resource/aws_codebuild_project: Support `SECRETS_MANAGER` environment variable type ([#12572](https://github.com/terraform-providers/terraform-provider-aws/issues/12572)) +* resource/aws_datasync_task: Support `ONLY_FILES_TRANSFERRED` value in `verify_mode` argument ([#12897](https://github.com/terraform-providers/terraform-provider-aws/issues/12897)) +* resource/aws_iot_topic_rule: Add `dynamodbv2` configuration block ([#7469](https://github.com/terraform-providers/terraform-provider-aws/issues/7469)) +* resource/aws_iot_topic_rule: Add `iot_analytics` configuration block ([#9859](https://github.com/terraform-providers/terraform-provider-aws/issues/9859)) +* resource/aws_iot_topic_rule: Add `iot_events` configuration block ([#9890](https://github.com/terraform-providers/terraform-provider-aws/issues/9890)) +* resource/aws_iot_topic_rule: Add `operation` argument to `dynamodb` configuration block ([#12714](https://github.com/terraform-providers/terraform-provider-aws/issues/12714)) +* resource/aws_iot_topic_rule: Add `qos` argument `republish` configuration block ([#12869](https://github.com/terraform-providers/terraform-provider-aws/issues/12869)) BUG FIXES: -* resource/aws_codebuild_project: Allow empty value (`""`) environment variables [GH-11572] -* resource/aws_security_group_rule: Prevent recreation when `source_security_group_id` refers to a security group across accounts [GH-11809] +* resource/aws_codebuild_project: Allow empty value (`""`) environment variables ([#11572](https://github.com/terraform-providers/terraform-provider-aws/issues/11572)) +* resource/aws_security_group_rule: Prevent recreation when `source_security_group_id` refers to a security group across accounts ([#11809](https://github.com/terraform-providers/terraform-provider-aws/issues/11809)) ## 2.61.0 (May 08, 2020) From 7fd165ff84fd05cce64bed17d20a69f0c684fd9e Mon Sep 17 00:00:00 2001 From: tf-release-bot Date: Fri, 15 May 2020 00:23:34 +0000 Subject: [PATCH 150/475] Cleanup after v2.62.0 release --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4079933a1a..cd7c7351153 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ +## 2.63.0 (Unreleased) ## 2.62.0 (May 15, 2020) FEATURES: From 0fb18da4e45f5be3e3a3f0f1a2975a5c81578222 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 15 May 2020 00:36:31 -0400 Subject: [PATCH 151/475] update to using typelist --- aws/provider.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/provider.go b/aws/provider.go index d7eaff110f5..e164c302d06 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -1168,7 +1168,7 @@ func providerConfigure(d *schema.ResourceData, terraformVersion string) (interfa } config.CredsFilename = credsPath - assumeRoleList := d.Get("assume_role").(*schema.Set).List() + assumeRoleList := d.Get("assume_role").([]interface{}) if len(assumeRoleList) == 1 { assumeRole := assumeRoleList[0].(map[string]interface{}) config.AssumeRoleARN = assumeRole["role_arn"].(string) @@ -1214,7 +1214,7 @@ var awsMutexKV = mutexkv.NewMutexKV() func assumeRoleSchema() *schema.Schema { return &schema.Schema{ - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, MaxItems: 1, Elem: &schema.Resource{ From a502a3970d2f5c310d62f89eb585e9e425794bd4 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 15 May 2020 00:44:29 -0400 Subject: [PATCH 152/475] enable linter --- aws/resource_aws_api_gateway_usage_plan.go | 18 +++++---------- ...esource_aws_api_gateway_usage_plan_test.go | 22 +++++++++---------- aws/resource_aws_api_gateway_vpc_link.go | 4 ++-- 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/aws/resource_aws_api_gateway_usage_plan.go b/aws/resource_aws_api_gateway_usage_plan.go index a3397dc5886..caa055e8d5c 100644 --- a/aws/resource_aws_api_gateway_usage_plan.go +++ b/aws/resource_aws_api_gateway_usage_plan.go @@ -55,7 +55,7 @@ func resourceAwsApiGatewayUsagePlan() *schema.Resource { }, "quota_settings": { - Type: schema.TypeSet, + Type: schema.TypeList, MaxItems: 1, Optional: true, Elem: &schema.Resource{ @@ -85,7 +85,7 @@ func resourceAwsApiGatewayUsagePlan() *schema.Resource { }, "throttle_settings": { - Type: schema.TypeSet, + Type: schema.TypeList, MaxItems: 1, Optional: true, Elem: &schema.Resource{ @@ -155,7 +155,7 @@ func resourceAwsApiGatewayUsagePlanCreate(d *schema.ResourceData, meta interface } if v, ok := d.GetOk("quota_settings"); ok { - settings := v.(*schema.Set).List() + settings := v.([]interface{}) q, ok := settings[0].(map[string]interface{}) if errors := validateApiGatewayUsagePlanQuotaSettings(q); len(errors) > 0 { @@ -184,7 +184,7 @@ func resourceAwsApiGatewayUsagePlanCreate(d *schema.ResourceData, meta interface } if v, ok := d.GetOk("throttle_settings"); ok { - settings := v.(*schema.Set).List() + settings := v.([]interface{}) q, ok := settings[0].(map[string]interface{}) if !ok { @@ -363,10 +363,7 @@ func resourceAwsApiGatewayUsagePlanUpdate(d *schema.ResourceData, meta interface if d.HasChange("throttle_settings") { o, n := d.GetChange("throttle_settings") - - os := o.(*schema.Set) - ns := n.(*schema.Set) - diff := ns.Difference(os).List() + diff := n.([]interface{}) // Handle Removal if len(diff) == 0 { @@ -411,10 +408,7 @@ func resourceAwsApiGatewayUsagePlanUpdate(d *schema.ResourceData, meta interface if d.HasChange("quota_settings") { o, n := d.GetChange("quota_settings") - - os := o.(*schema.Set) - ns := n.(*schema.Set) - diff := ns.Difference(os).List() + diff := n.([]interface{}) // Handle Removal if len(diff) == 0 { diff --git a/aws/resource_aws_api_gateway_usage_plan_test.go b/aws/resource_aws_api_gateway_usage_plan_test.go index c006ffd4be5..f3884c6f639 100644 --- a/aws/resource_aws_api_gateway_usage_plan_test.go +++ b/aws/resource_aws_api_gateway_usage_plan_test.go @@ -231,8 +231,8 @@ func TestAccAWSAPIGatewayUsagePlan_throttling(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckAWSAPIGatewayUsagePlanExists(resourceName, &conf), resource.TestCheckResourceAttr(resourceName, "name", rName), - resource.TestCheckResourceAttr(resourceName, "throttle_settings.4173790118.burst_limit", "2"), - resource.TestCheckResourceAttr(resourceName, "throttle_settings.4173790118.rate_limit", "5"), + resource.TestCheckResourceAttr(resourceName, "throttle_settings.0.burst_limit", "2"), + resource.TestCheckResourceAttr(resourceName, "throttle_settings.0.rate_limit", "5"), ), }, { @@ -240,8 +240,8 @@ func TestAccAWSAPIGatewayUsagePlan_throttling(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckAWSAPIGatewayUsagePlanExists(resourceName, &conf), resource.TestCheckResourceAttr(resourceName, "name", rName), - resource.TestCheckResourceAttr(resourceName, "throttle_settings.1779463053.burst_limit", "3"), - resource.TestCheckResourceAttr(resourceName, "throttle_settings.1779463053.rate_limit", "6"), + resource.TestCheckResourceAttr(resourceName, "throttle_settings.0.burst_limit", "3"), + resource.TestCheckResourceAttr(resourceName, "throttle_settings.0.rate_limit", "6"), ), }, { @@ -272,7 +272,7 @@ func TestAccAWSAPIGatewayUsagePlan_throttlingInitialRateLimit(t *testing.T) { Config: testAccAWSApiGatewayUsagePlanThrottlingConfig(rName), Check: resource.ComposeTestCheckFunc( testAccCheckAWSAPIGatewayUsagePlanExists(resourceName, &conf), - resource.TestCheckResourceAttr(resourceName, "throttle_settings.4173790118.rate_limit", "5"), + resource.TestCheckResourceAttr(resourceName, "throttle_settings.0.rate_limit", "5"), ), }, { @@ -313,9 +313,9 @@ func TestAccAWSAPIGatewayUsagePlan_quota(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckAWSAPIGatewayUsagePlanExists(resourceName, &conf), resource.TestCheckResourceAttr(resourceName, "name", rName), - resource.TestCheckResourceAttr(resourceName, "quota_settings.1956747625.limit", "100"), - resource.TestCheckResourceAttr(resourceName, "quota_settings.1956747625.offset", "6"), - resource.TestCheckResourceAttr(resourceName, "quota_settings.1956747625.period", "WEEK"), + resource.TestCheckResourceAttr(resourceName, "quota_settings.0.limit", "100"), + resource.TestCheckResourceAttr(resourceName, "quota_settings.0.offset", "6"), + resource.TestCheckResourceAttr(resourceName, "quota_settings.0.period", "WEEK"), ), }, { @@ -323,9 +323,9 @@ func TestAccAWSAPIGatewayUsagePlan_quota(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckAWSAPIGatewayUsagePlanExists(resourceName, &conf), resource.TestCheckResourceAttr(resourceName, "name", rName), - resource.TestCheckResourceAttr(resourceName, "quota_settings.3909168194.limit", "200"), - resource.TestCheckResourceAttr(resourceName, "quota_settings.3909168194.offset", "20"), - resource.TestCheckResourceAttr(resourceName, "quota_settings.3909168194.period", "MONTH"), + resource.TestCheckResourceAttr(resourceName, "quota_settings.0.limit", "200"), + resource.TestCheckResourceAttr(resourceName, "quota_settings.0.offset", "20"), + resource.TestCheckResourceAttr(resourceName, "quota_settings.0.period", "MONTH"), ), }, { diff --git a/aws/resource_aws_api_gateway_vpc_link.go b/aws/resource_aws_api_gateway_vpc_link.go index 473f59d7828..28720412ebb 100644 --- a/aws/resource_aws_api_gateway_vpc_link.go +++ b/aws/resource_aws_api_gateway_vpc_link.go @@ -33,7 +33,7 @@ func resourceAwsApiGatewayVpcLink() *schema.Resource { Optional: true, }, "target_arns": { - Type: schema.TypeSet, + Type: schema.TypeList, MaxItems: 1, Required: true, ForceNew: true, @@ -54,7 +54,7 @@ func resourceAwsApiGatewayVpcLinkCreate(d *schema.ResourceData, meta interface{} input := &apigateway.CreateVpcLinkInput{ Name: aws.String(d.Get("name").(string)), - TargetArns: expandStringList(d.Get("target_arns").(*schema.Set).List()), + TargetArns: expandStringList(d.Get("target_arns").([]interface{})), Tags: tags, } if v, ok := d.GetOk("description"); ok { From 4604d6098dd82786f2f5c77d105cf25d650ced3f Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 15 May 2020 00:46:59 -0400 Subject: [PATCH 153/475] enable linter --- aws/resource_aws_appmesh_virtual_node.go | 3 +-- aws/resource_aws_appmesh_virtual_router.go | 20 +------------------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/aws/resource_aws_appmesh_virtual_node.go b/aws/resource_aws_appmesh_virtual_node.go index e7ddc3b8263..77c3ba6f00a 100644 --- a/aws/resource_aws_appmesh_virtual_node.go +++ b/aws/resource_aws_appmesh_virtual_node.go @@ -86,7 +86,7 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource { }, "listener": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, MinItems: 0, MaxItems: 1, @@ -173,7 +173,6 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource { }, }, }, - Set: appmeshVirtualNodeListenerHash, }, "logging": { diff --git a/aws/resource_aws_appmesh_virtual_router.go b/aws/resource_aws_appmesh_virtual_router.go index a11d1d3eb51..3d3f9b90e78 100644 --- a/aws/resource_aws_appmesh_virtual_router.go +++ b/aws/resource_aws_appmesh_virtual_router.go @@ -1,7 +1,6 @@ package aws import ( - "bytes" "fmt" "log" "strings" @@ -9,7 +8,6 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/appmesh" - "github.com/hashicorp/terraform-plugin-sdk/helper/hashcode" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" @@ -59,7 +57,7 @@ func resourceAwsAppmeshVirtualRouter() *schema.Resource { }, "listener": { - Type: schema.TypeSet, + Type: schema.TypeList, Required: true, MinItems: 1, MaxItems: 1, @@ -91,7 +89,6 @@ func resourceAwsAppmeshVirtualRouter() *schema.Resource { }, }, }, - Set: appmeshVirtualRouterListenerHash, }, }, }, @@ -258,18 +255,3 @@ func resourceAwsAppmeshVirtualRouterImport(d *schema.ResourceData, meta interfac return []*schema.ResourceData{d}, nil } - -func appmeshVirtualRouterListenerHash(vListener interface{}) int { - var buf bytes.Buffer - mListener := vListener.(map[string]interface{}) - if vPortMapping, ok := mListener["port_mapping"].([]interface{}); ok && len(vPortMapping) > 0 && vPortMapping[0] != nil { - mPortMapping := vPortMapping[0].(map[string]interface{}) - if v, ok := mPortMapping["port"].(int); ok { - buf.WriteString(fmt.Sprintf("%d-", v)) - } - if v, ok := mPortMapping["protocol"].(string); ok { - buf.WriteString(fmt.Sprintf("%s-", v)) - } - } - return hashcode.String(buf.String()) -} From 8a681e135fd52bf932098ece18c4801ff4f076b8 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 15 May 2020 00:48:34 -0400 Subject: [PATCH 154/475] enable linter --- aws/resource_aws_cloudfront_distribution.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_cloudfront_distribution.go b/aws/resource_aws_cloudfront_distribution.go index 827b84b97aa..b55519209ee 100644 --- a/aws/resource_aws_cloudfront_distribution.go +++ b/aws/resource_aws_cloudfront_distribution.go @@ -68,13 +68,13 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { Optional: true, }, "forwarded_values": { - Type: schema.TypeSet, + Type: schema.TypeList, Required: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "cookies": { - Type: schema.TypeSet, + Type: schema.TypeList, Required: true, MaxItems: 1, Elem: &schema.Resource{ From a9814e2f829a26dc343e7e2df83a58cfebb7056a Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 15 May 2020 00:49:48 -0400 Subject: [PATCH 155/475] enable linter --- aws/resource_aws_ecs_service.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_ecs_service.go b/aws/resource_aws_ecs_service.go index 50f698a5970..ce8437752d4 100644 --- a/aws/resource_aws_ecs_service.go +++ b/aws/resource_aws_ecs_service.go @@ -342,7 +342,7 @@ func resourceAwsEcsService() *schema.Resource { }, "service_registries": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, ForceNew: true, MaxItems: 1, @@ -486,7 +486,7 @@ func resourceAwsEcsServiceCreate(d *schema.ResourceData, meta interface{}) error input.PlacementConstraints = pc } - serviceRegistries := d.Get("service_registries").(*schema.Set).List() + serviceRegistries := d.Get("service_registries").([]interface{}) if len(serviceRegistries) > 0 { srs := make([]*ecs.ServiceRegistry, 0, len(serviceRegistries)) for _, v := range serviceRegistries { From 3da8e17e9c9b14ed6e0943deb015c2325a519c0f Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 15 May 2020 00:51:00 -0400 Subject: [PATCH 156/475] enable linter --- aws/resource_aws_eks_node_group.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aws/resource_aws_eks_node_group.go b/aws/resource_aws_eks_node_group.go index 7c29f24f089..a646912cdaa 100644 --- a/aws/resource_aws_eks_node_group.go +++ b/aws/resource_aws_eks_node_group.go @@ -59,7 +59,7 @@ func resourceAwsEksNodeGroup() *schema.Resource { ForceNew: true, }, "instance_types": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Computed: true, ForceNew: true, @@ -201,8 +201,8 @@ func resourceAwsEksNodeGroupCreate(d *schema.ResourceData, meta interface{}) err input.DiskSize = aws.Int64(int64(v.(int))) } - if v := d.Get("instance_types").(*schema.Set); v.Len() > 0 { - input.InstanceTypes = expandStringSet(v) + if v := d.Get("instance_types").([]interface{}); len(v) > 0 { + input.InstanceTypes = expandStringList(v) } if v := d.Get("labels").(map[string]interface{}); len(v) > 0 { From 92db9489245ef540c234ddd616d67fa9d95eaeb6 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 15 May 2020 00:53:06 -0400 Subject: [PATCH 157/475] enable linter --- ...esource_aws_elastic_transcoder_pipeline.go | 26 +++++++------- aws/resource_aws_elastic_transcoder_preset.go | 36 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/aws/resource_aws_elastic_transcoder_pipeline.go b/aws/resource_aws_elastic_transcoder_pipeline.go index edd1d5c63af..a0aedfecf2b 100644 --- a/aws/resource_aws_elastic_transcoder_pipeline.go +++ b/aws/resource_aws_elastic_transcoder_pipeline.go @@ -35,7 +35,7 @@ func resourceAwsElasticTranscoderPipeline() *schema.Resource { // ContentConfig also requires ThumbnailConfig "content_config": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Computed: true, MaxItems: 1, @@ -102,7 +102,7 @@ func resourceAwsElasticTranscoderPipeline() *schema.Resource { }, "notifications": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, MaxItems: 1, Elem: &schema.Resource{ @@ -144,7 +144,7 @@ func resourceAwsElasticTranscoderPipeline() *schema.Resource { }, "thumbnail_config": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Computed: true, MaxItems: 1, @@ -235,22 +235,22 @@ func resourceAwsElasticTranscoderPipelineCreate(d *schema.ResourceData, meta int } func expandETNotifications(d *schema.ResourceData) *elastictranscoder.Notifications { - set, ok := d.GetOk("notifications") + list, ok := d.GetOk("notifications") if !ok { return nil } - s := set.(*schema.Set).List() - if len(s) == 0 { + l := list.([]interface{}) + if len(l) == 0 { return nil } - if s[0] == nil { - log.Printf("[ERR] First element of Notifications set is nil") + if l[0] == nil { + log.Printf("[ERR] First element of Notifications list is nil") return nil } - rN := s[0].(map[string]interface{}) + rN := l[0].(map[string]interface{}) return &elastictranscoder.Notifications{ Completed: aws.String(rN["completed"].(string)), @@ -290,17 +290,17 @@ func flattenETNotifications(n *elastictranscoder.Notifications) []map[string]int } func expandETPiplineOutputConfig(d *schema.ResourceData, key string) *elastictranscoder.PipelineOutputConfig { - set, ok := d.GetOk(key) + list, ok := d.GetOk(key) if !ok { return nil } - s := set.(*schema.Set) - if s == nil || s.Len() == 0 { + l := list.([]interface{}) + if len(l) == 0 { return nil } - cc := s.List()[0].(map[string]interface{}) + cc := l[0].(map[string]interface{}) cfg := &elastictranscoder.PipelineOutputConfig{ Bucket: aws.String(cc["bucket"].(string)), diff --git a/aws/resource_aws_elastic_transcoder_preset.go b/aws/resource_aws_elastic_transcoder_preset.go index ca57e63b119..dfe0777a36c 100644 --- a/aws/resource_aws_elastic_transcoder_preset.go +++ b/aws/resource_aws_elastic_transcoder_preset.go @@ -26,7 +26,7 @@ func resourceAwsElasticTranscoderPreset() *schema.Resource { }, "audio": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, ForceNew: true, MaxItems: 1, @@ -62,7 +62,7 @@ func resourceAwsElasticTranscoderPreset() *schema.Resource { }, }, "audio_codec_options": { - Type: schema.TypeSet, + Type: schema.TypeList, MaxItems: 1, Optional: true, ForceNew: true, @@ -112,7 +112,7 @@ func resourceAwsElasticTranscoderPreset() *schema.Resource { }, "thumbnails": { - Type: schema.TypeSet, + Type: schema.TypeList, MaxItems: 1, Optional: true, ForceNew: true, @@ -170,7 +170,7 @@ func resourceAwsElasticTranscoderPreset() *schema.Resource { }, "video": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, ForceNew: true, MaxItems: 1, @@ -355,16 +355,16 @@ func resourceAwsElasticTranscoderPresetCreate(d *schema.ResourceData, meta inter } func expandETThumbnails(d *schema.ResourceData) *elastictranscoder.Thumbnails { - set, ok := d.GetOk("thumbnails") + list, ok := d.GetOk("thumbnails") if !ok { return nil } - s := set.(*schema.Set) - if s == nil || s.Len() == 0 { + l := list.([]interface{}) + if len(l) == 0 { return nil } - t := s.List()[0].(map[string]interface{}) + t := l[0].(map[string]interface{}) thumbnails := &elastictranscoder.Thumbnails{} @@ -404,16 +404,16 @@ func expandETThumbnails(d *schema.ResourceData) *elastictranscoder.Thumbnails { } func expandETAudioParams(d *schema.ResourceData) *elastictranscoder.AudioParameters { - set, ok := d.GetOk("audio") + list, ok := d.GetOk("audio") if !ok { return nil } - s := set.(*schema.Set) - if s == nil || s.Len() == 0 { + l := list.([]interface{}) + if len(l) == 0 { return nil } - audio := s.List()[0].(map[string]interface{}) + audio := l[0].(map[string]interface{}) return &elastictranscoder.AudioParameters{ AudioPackingMode: aws.String(audio["audio_packing_mode"].(string)), @@ -426,12 +426,12 @@ func expandETAudioParams(d *schema.ResourceData) *elastictranscoder.AudioParamet } func expandETAudioCodecOptions(d *schema.ResourceData) *elastictranscoder.AudioCodecOptions { - s := d.Get("audio_codec_options").(*schema.Set) - if s == nil || s.Len() == 0 { + l := d.Get("audio_codec_options").([]interface{}) + if len(l) == 0 { return nil } - codec := s.List()[0].(map[string]interface{}) + codec := l[0].(map[string]interface{}) codecOpts := &elastictranscoder.AudioCodecOptions{} @@ -455,11 +455,11 @@ func expandETAudioCodecOptions(d *schema.ResourceData) *elastictranscoder.AudioC } func expandETVideoParams(d *schema.ResourceData) *elastictranscoder.VideoParameters { - s := d.Get("video").(*schema.Set) - if s == nil || s.Len() == 0 { + l := d.Get("video").([]interface{}) + if len(l) == 0 { return nil } - p := s.List()[0].(map[string]interface{}) + p := l[0].(map[string]interface{}) etVideoParams := &elastictranscoder.VideoParameters{ Watermarks: expandETVideoWatermarks(d), From 6d2e841dbea4ab7aec50e18b65d0c8071a247e88 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 15 May 2020 00:54:26 -0400 Subject: [PATCH 158/475] enable linter --- aws/resource_aws_fsx_lustre_file_system.go | 4 ++-- aws/resource_aws_fsx_windows_file_system.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/aws/resource_aws_fsx_lustre_file_system.go b/aws/resource_aws_fsx_lustre_file_system.go index 7ab2b555628..619b24dd1ba 100644 --- a/aws/resource_aws_fsx_lustre_file_system.go +++ b/aws/resource_aws_fsx_lustre_file_system.go @@ -87,7 +87,7 @@ func resourceAwsFsxLustreFileSystem() *schema.Resource { ValidateFunc: validation.IntAtLeast(1200), }, "subnet_ids": { - Type: schema.TypeSet, + Type: schema.TypeList, Required: true, ForceNew: true, MinItems: 1, @@ -119,7 +119,7 @@ func resourceAwsFsxLustreFileSystemCreate(d *schema.ResourceData, meta interface ClientRequestToken: aws.String(resource.UniqueId()), FileSystemType: aws.String(fsx.FileSystemTypeLustre), StorageCapacity: aws.Int64(int64(d.Get("storage_capacity").(int))), - SubnetIds: expandStringSet(d.Get("subnet_ids").(*schema.Set)), + SubnetIds: expandStringList(d.Get("subnet_ids").([]interface{})), } if v, ok := d.GetOk("export_path"); ok { diff --git a/aws/resource_aws_fsx_windows_file_system.go b/aws/resource_aws_fsx_windows_file_system.go index c7d3c8485c9..3c63d346747 100644 --- a/aws/resource_aws_fsx_windows_file_system.go +++ b/aws/resource_aws_fsx_windows_file_system.go @@ -147,7 +147,7 @@ func resourceAwsFsxWindowsFileSystem() *schema.Resource { ValidateFunc: validation.IntBetween(32, 65536), }, "subnet_ids": { - Type: schema.TypeSet, + Type: schema.TypeList, Required: true, ForceNew: true, MinItems: 1, @@ -185,7 +185,7 @@ func resourceAwsFsxWindowsFileSystemCreate(d *schema.ResourceData, meta interfac ClientRequestToken: aws.String(resource.UniqueId()), FileSystemType: aws.String(fsx.FileSystemTypeWindows), StorageCapacity: aws.Int64(int64(d.Get("storage_capacity").(int))), - SubnetIds: expandStringSet(d.Get("subnet_ids").(*schema.Set)), + SubnetIds: expandStringList(d.Get("subnet_ids").([]interface{})), WindowsConfiguration: &fsx.CreateFileSystemWindowsConfiguration{ AutomaticBackupRetentionDays: aws.Int64(int64(d.Get("automatic_backup_retention_days").(int))), CopyTagsToBackups: aws.Bool(d.Get("copy_tags_to_backups").(bool)), From 0c73a1a2fdb82f7075e9c5d08127df5ad97ffda7 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 15 May 2020 00:56:05 -0400 Subject: [PATCH 159/475] enable linter --- ...ce_aws_kinesis_firehose_delivery_stream.go | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/aws/resource_aws_kinesis_firehose_delivery_stream.go b/aws/resource_aws_kinesis_firehose_delivery_stream.go index 09b4b2e6fd4..786d203447a 100644 --- a/aws/resource_aws_kinesis_firehose_delivery_stream.go +++ b/aws/resource_aws_kinesis_firehose_delivery_stream.go @@ -1,7 +1,6 @@ package aws import ( - "bytes" "fmt" "log" "strings" @@ -10,7 +9,6 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/firehose" - "github.com/hashicorp/terraform-plugin-sdk/helper/hashcode" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" @@ -23,7 +21,7 @@ const ( func cloudWatchLoggingOptionsSchema() *schema.Schema { return &schema.Schema{ - Type: schema.TypeSet, + Type: schema.TypeList, MaxItems: 1, Optional: true, Computed: true, @@ -170,20 +168,9 @@ func processingConfigurationSchema() *schema.Schema { } } -func cloudwatchLoggingOptionsHash(v interface{}) int { - var buf bytes.Buffer - m := v.(map[string]interface{}) - buf.WriteString(fmt.Sprintf("%t-", m["enabled"].(bool))) - if m["enabled"].(bool) { - buf.WriteString(fmt.Sprintf("%s-", m["log_group_name"].(string))) - buf.WriteString(fmt.Sprintf("%s-", m["log_stream_name"].(string))) - } - return hashcode.String(buf.String()) -} - -func flattenCloudwatchLoggingOptions(clo *firehose.CloudWatchLoggingOptions) *schema.Set { +func flattenCloudwatchLoggingOptions(clo *firehose.CloudWatchLoggingOptions) []interface{} { if clo == nil { - return schema.NewSet(cloudwatchLoggingOptionsHash, []interface{}{}) + return []interface{}{} } cloudwatchLoggingOptions := map[string]interface{}{ @@ -193,7 +180,7 @@ func flattenCloudwatchLoggingOptions(clo *firehose.CloudWatchLoggingOptions) *sc cloudwatchLoggingOptions["log_group_name"] = aws.StringValue(clo.LogGroupName) cloudwatchLoggingOptions["log_stream_name"] = aws.StringValue(clo.LogStreamName) } - return schema.NewSet(cloudwatchLoggingOptionsHash, []interface{}{cloudwatchLoggingOptions}) + return []interface{}{cloudwatchLoggingOptions} } func flattenFirehoseElasticsearchConfiguration(description *firehose.ElasticsearchDestinationDescription) []map[string]interface{} { @@ -1804,7 +1791,7 @@ func extractEncryptionConfiguration(s3 map[string]interface{}) *firehose.Encrypt } func extractCloudWatchLoggingConfiguration(s3 map[string]interface{}) *firehose.CloudWatchLoggingOptions { - config := s3["cloudwatch_logging_options"].(*schema.Set).List() + config := s3["cloudwatch_logging_options"].([]interface{}) if len(config) == 0 { return nil } From 2cc6bb59d8d78e618daa966f0c7014bf690bdc23 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 15 May 2020 00:57:09 -0400 Subject: [PATCH 160/475] enable linter --- aws/resource_aws_ses_event_destination.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/aws/resource_aws_ses_event_destination.go b/aws/resource_aws_ses_event_destination.go index e82c806f04c..d9685bb09ca 100644 --- a/aws/resource_aws_ses_event_destination.go +++ b/aws/resource_aws_ses_event_destination.go @@ -90,7 +90,7 @@ func resourceAwsSesEventDestination() *schema.Resource { }, "kinesis_destination": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, ForceNew: true, MaxItems: 1, @@ -111,7 +111,7 @@ func resourceAwsSesEventDestination() *schema.Resource { }, "sns_destination": { - Type: schema.TypeSet, + Type: schema.TypeList, MaxItems: 1, Optional: true, ForceNew: true, @@ -155,7 +155,7 @@ func resourceAwsSesEventDestinationCreate(d *schema.ResourceData, meta interface } if v, ok := d.GetOk("kinesis_destination"); ok { - destination := v.(*schema.Set).List() + destination := v.([]interface{}) kinesis := destination[0].(map[string]interface{}) createOpts.EventDestination.KinesisFirehoseDestination = &ses.KinesisFirehoseDestination{ @@ -166,7 +166,7 @@ func resourceAwsSesEventDestinationCreate(d *schema.ResourceData, meta interface } if v, ok := d.GetOk("sns_destination"); ok { - destination := v.(*schema.Set).List() + destination := v.([]interface{}) sns := destination[0].(map[string]interface{}) createOpts.EventDestination.SNSDestination = &ses.SNSDestination{ TopicARN: aws.String(sns["topic_arn"].(string)), From f41e05f575288ca86c834a2e12d6f8cd035cffa9 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 15 May 2020 00:58:04 -0400 Subject: [PATCH 161/475] enable linter --- aws/resource_aws_vpc_peering_connection.go | 6 ++--- ...esource_aws_vpc_peering_connection_test.go | 24 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/aws/resource_aws_vpc_peering_connection.go b/aws/resource_aws_vpc_peering_connection.go index 8d5a5c431de..00675448631 100644 --- a/aws/resource_aws_vpc_peering_connection.go +++ b/aws/resource_aws_vpc_peering_connection.go @@ -197,8 +197,8 @@ func resourceAwsVpcPeeringConnectionModifyOptions(d *schema.ResourceData, meta i req := &ec2.ModifyVpcPeeringConnectionOptionsInput{ VpcPeeringConnectionId: aws.String(d.Id()), - AccepterPeeringConnectionOptions: expandVpcPeeringConnectionOptions(d.Get("accepter").(*schema.Set).List(), crossRegionPeering), - RequesterPeeringConnectionOptions: expandVpcPeeringConnectionOptions(d.Get("requester").(*schema.Set).List(), crossRegionPeering), + AccepterPeeringConnectionOptions: expandVpcPeeringConnectionOptions(d.Get("accepter").([]interface{}), crossRegionPeering), + RequesterPeeringConnectionOptions: expandVpcPeeringConnectionOptions(d.Get("requester").([]interface{}), crossRegionPeering), } log.Printf("[DEBUG] Modifying VPC Peering Connection options: %#v", req) @@ -325,7 +325,7 @@ func vpcPeeringConnectionRefreshState(conn *ec2.EC2, id string) resource.StateRe func vpcPeeringConnectionOptionsSchema() *schema.Schema { return &schema.Schema{ - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Computed: true, MaxItems: 1, diff --git a/aws/resource_aws_vpc_peering_connection_test.go b/aws/resource_aws_vpc_peering_connection_test.go index 47ac8a62361..61f47780f89 100644 --- a/aws/resource_aws_vpc_peering_connection_test.go +++ b/aws/resource_aws_vpc_peering_connection_test.go @@ -241,17 +241,17 @@ func TestAccAWSVPCPeeringConnection_options(t *testing.T) { ), resource.TestCheckResourceAttr( resourceName, - "requester.41753983.allow_remote_vpc_dns_resolution", + "requester.0.allow_remote_vpc_dns_resolution", "false", ), resource.TestCheckResourceAttr( resourceName, - "requester.41753983.allow_classic_link_to_remote_vpc", + "requester.0.allow_classic_link_to_remote_vpc", "true", ), resource.TestCheckResourceAttr( resourceName, - "requester.41753983.allow_vpc_to_remote_classic_link", + "requester.0.allow_vpc_to_remote_classic_link", "true", ), testAccCheckAWSVpcPeeringConnectionOptions( @@ -270,17 +270,17 @@ func TestAccAWSVPCPeeringConnection_options(t *testing.T) { ), resource.TestCheckResourceAttr( resourceName, - "accepter.1102046665.allow_remote_vpc_dns_resolution", + "accepter.0.allow_remote_vpc_dns_resolution", "true", ), resource.TestCheckResourceAttr( resourceName, - "accepter.1102046665.allow_classic_link_to_remote_vpc", + "accepter.0.allow_classic_link_to_remote_vpc", "false", ), resource.TestCheckResourceAttr( resourceName, - "accepter.1102046665.allow_vpc_to_remote_classic_link", + "accepter.0.allow_vpc_to_remote_classic_link", "false", ), testAccCheckAWSVpcPeeringConnectionOptions( @@ -318,17 +318,17 @@ func TestAccAWSVPCPeeringConnection_options(t *testing.T) { ), resource.TestCheckResourceAttr( resourceName, - "requester.41753983.allow_remote_vpc_dns_resolution", + "requester.0.allow_remote_vpc_dns_resolution", "false", ), resource.TestCheckResourceAttr( resourceName, - "requester.41753983.allow_classic_link_to_remote_vpc", + "requester.0.allow_classic_link_to_remote_vpc", "true", ), resource.TestCheckResourceAttr( resourceName, - "requester.41753983.allow_vpc_to_remote_classic_link", + "requester.0.allow_vpc_to_remote_classic_link", "true", ), testAccCheckAWSVpcPeeringConnectionOptions( @@ -347,17 +347,17 @@ func TestAccAWSVPCPeeringConnection_options(t *testing.T) { ), resource.TestCheckResourceAttr( resourceName, - "accepter.1102046665.allow_remote_vpc_dns_resolution", + "accepter.0.allow_remote_vpc_dns_resolution", "true", ), resource.TestCheckResourceAttr( resourceName, - "accepter.1102046665.allow_classic_link_to_remote_vpc", + "accepter.0.allow_classic_link_to_remote_vpc", "false", ), resource.TestCheckResourceAttr( resourceName, - "accepter.1102046665.allow_vpc_to_remote_classic_link", + "accepter.0.allow_vpc_to_remote_classic_link", "false", ), testAccCheckAWSVpcPeeringConnectionOptions( From d993420954e96aa4e13b65c9dee390962c963d2d Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 15 May 2020 01:05:05 -0400 Subject: [PATCH 162/475] enable linter --- aws/resource_aws_waf_sql_injection_match_set.go | 6 +++--- ...ource_aws_waf_sql_injection_match_set_test.go | 16 ++++++++-------- aws/resource_aws_waf_web_acl.go | 10 +++++----- aws/resource_aws_waf_web_acl_test.go | 16 ++++++++-------- aws/waf_helpers.go | 6 +++--- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/aws/resource_aws_waf_sql_injection_match_set.go b/aws/resource_aws_waf_sql_injection_match_set.go index 66aa8e399e0..693088cd68c 100644 --- a/aws/resource_aws_waf_sql_injection_match_set.go +++ b/aws/resource_aws_waf_sql_injection_match_set.go @@ -31,7 +31,7 @@ func resourceAwsWafSqlInjectionMatchSet() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "field_to_match": { - Type: schema.TypeSet, + Type: schema.TypeList, Required: true, MaxItems: 1, Elem: &schema.Resource{ @@ -198,7 +198,7 @@ func diffWafSqlInjectionMatchTuples(oldT, newT []interface{}) []*waf.SqlInjectio updates = append(updates, &waf.SqlInjectionMatchSetUpdate{ Action: aws.String(waf.ChangeActionDelete), SqlInjectionMatchTuple: &waf.SqlInjectionMatchTuple{ - FieldToMatch: expandFieldToMatch(tuple["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})), + FieldToMatch: expandFieldToMatch(tuple["field_to_match"].([]interface{})[0].(map[string]interface{})), TextTransformation: aws.String(tuple["text_transformation"].(string)), }, }) @@ -210,7 +210,7 @@ func diffWafSqlInjectionMatchTuples(oldT, newT []interface{}) []*waf.SqlInjectio updates = append(updates, &waf.SqlInjectionMatchSetUpdate{ Action: aws.String(waf.ChangeActionInsert), SqlInjectionMatchTuple: &waf.SqlInjectionMatchTuple{ - FieldToMatch: expandFieldToMatch(tuple["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})), + FieldToMatch: expandFieldToMatch(tuple["field_to_match"].([]interface{})[0].(map[string]interface{})), TextTransformation: aws.String(tuple["text_transformation"].(string)), }, }) diff --git a/aws/resource_aws_waf_sql_injection_match_set_test.go b/aws/resource_aws_waf_sql_injection_match_set_test.go index afd330ef8ab..59d3a70bcb4 100644 --- a/aws/resource_aws_waf_sql_injection_match_set_test.go +++ b/aws/resource_aws_waf_sql_injection_match_set_test.go @@ -29,10 +29,10 @@ func TestAccAWSWafSqlInjectionMatchSet_basic(t *testing.T) { testAccCheckAWSWafSqlInjectionMatchSetExists(resourceName, &v), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.#", "1"), - resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.3367958210.field_to_match.#", "1"), - resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.3367958210.field_to_match.2316364334.data", ""), - resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.3367958210.field_to_match.2316364334.type", "QUERY_STRING"), - resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.3367958210.text_transformation", "URL_DECODE"), + resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.2246477904.field_to_match.#", "1"), + resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.2246477904.field_to_match.0.data", ""), + resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.2246477904.field_to_match.0.type", "QUERY_STRING"), + resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.2246477904.text_transformation", "URL_DECODE"), ), }, { @@ -119,10 +119,10 @@ func TestAccAWSWafSqlInjectionMatchSet_changeTuples(t *testing.T) { testAccCheckAWSWafSqlInjectionMatchSetExists(resourceName, &before), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.#", "1"), - resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.3367958210.field_to_match.#", "1"), - resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.3367958210.field_to_match.2316364334.data", ""), - resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.3367958210.field_to_match.2316364334.type", "QUERY_STRING"), - resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.3367958210.text_transformation", "URL_DECODE"), + resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.2246477904.field_to_match.#", "1"), + resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.2246477904.field_to_match.0.data", ""), + resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.2246477904.field_to_match.0.type", "QUERY_STRING"), + resource.TestCheckResourceAttr(resourceName, "sql_injection_match_tuples.2246477904.text_transformation", "URL_DECODE"), ), }, { diff --git a/aws/resource_aws_waf_web_acl.go b/aws/resource_aws_waf_web_acl.go index aca664f62b9..313ff7b1f8b 100644 --- a/aws/resource_aws_waf_web_acl.go +++ b/aws/resource_aws_waf_web_acl.go @@ -33,7 +33,7 @@ func resourceAwsWafWebAcl() *schema.Resource { ForceNew: true, }, "default_action": { - Type: schema.TypeSet, + Type: schema.TypeList, Required: true, MaxItems: 1, Elem: &schema.Resource{ @@ -154,7 +154,7 @@ func resourceAwsWafWebAclCreate(d *schema.ResourceData, meta interface{}) error out, err := wr.RetryWithToken(func(token *string) (interface{}, error) { params := &waf.CreateWebACLInput{ ChangeToken: token, - DefaultAction: expandWafAction(d.Get("default_action").(*schema.Set).List()), + DefaultAction: expandWafAction(d.Get("default_action").([]interface{})), MetricName: aws.String(d.Get("metric_name").(string)), Name: aws.String(d.Get("name").(string)), } @@ -196,7 +196,7 @@ func resourceAwsWafWebAclCreate(d *schema.ResourceData, meta interface{}) error _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { req := &waf.UpdateWebACLInput{ ChangeToken: token, - DefaultAction: expandWafAction(d.Get("default_action").(*schema.Set).List()), + DefaultAction: expandWafAction(d.Get("default_action").([]interface{})), Updates: diffWafWebAclRules([]interface{}{}, rules), WebACLId: aws.String(d.Id()), } @@ -290,7 +290,7 @@ func resourceAwsWafWebAclUpdate(d *schema.ResourceData, meta interface{}) error _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { req := &waf.UpdateWebACLInput{ ChangeToken: token, - DefaultAction: expandWafAction(d.Get("default_action").(*schema.Set).List()), + DefaultAction: expandWafAction(d.Get("default_action").([]interface{})), Updates: diffWafWebAclRules(oldR, newR), WebACLId: aws.String(d.Id()), } @@ -347,7 +347,7 @@ func resourceAwsWafWebAclDelete(d *schema.ResourceData, meta interface{}) error _, err := wr.RetryWithToken(func(token *string) (interface{}, error) { req := &waf.UpdateWebACLInput{ ChangeToken: token, - DefaultAction: expandWafAction(d.Get("default_action").(*schema.Set).List()), + DefaultAction: expandWafAction(d.Get("default_action").([]interface{})), Updates: diffWafWebAclRules(rules, []interface{}{}), WebACLId: aws.String(d.Id()), } diff --git a/aws/resource_aws_waf_web_acl_test.go b/aws/resource_aws_waf_web_acl_test.go index 1309e31d38d..5285126fe4e 100644 --- a/aws/resource_aws_waf_web_acl_test.go +++ b/aws/resource_aws_waf_web_acl_test.go @@ -130,7 +130,7 @@ func TestAccAWSWafWebAcl_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckAWSWafWebAclExists(resourceName, &webACL), resource.TestCheckResourceAttr(resourceName, "default_action.#", "1"), - resource.TestCheckResourceAttr(resourceName, "default_action.4234791575.type", "ALLOW"), + resource.TestCheckResourceAttr(resourceName, "default_action.0.type", "ALLOW"), resource.TestCheckResourceAttr(resourceName, "metric_name", rName), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), @@ -164,7 +164,7 @@ func TestAccAWSWafWebAcl_changeNameForceNew(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckAWSWafWebAclExists(resourceName, &webACL), resource.TestCheckResourceAttr(resourceName, "default_action.#", "1"), - resource.TestCheckResourceAttr(resourceName, "default_action.4234791575.type", "ALLOW"), + resource.TestCheckResourceAttr(resourceName, "default_action.0.type", "ALLOW"), resource.TestCheckResourceAttr(resourceName, "metric_name", rName1), resource.TestCheckResourceAttr(resourceName, "name", rName1), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), @@ -176,7 +176,7 @@ func TestAccAWSWafWebAcl_changeNameForceNew(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckAWSWafWebAclExists(resourceName, &webACL), resource.TestCheckResourceAttr(resourceName, "default_action.#", "1"), - resource.TestCheckResourceAttr(resourceName, "default_action.4234791575.type", "ALLOW"), + resource.TestCheckResourceAttr(resourceName, "default_action.0.type", "ALLOW"), resource.TestCheckResourceAttr(resourceName, "metric_name", rName2), resource.TestCheckResourceAttr(resourceName, "name", rName2), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), @@ -208,7 +208,7 @@ func TestAccAWSWafWebAcl_DefaultAction(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckAWSWafWebAclExists(resourceName, &webACL), resource.TestCheckResourceAttr(resourceName, "default_action.#", "1"), - resource.TestCheckResourceAttr(resourceName, "default_action.4234791575.type", "ALLOW"), + resource.TestCheckResourceAttr(resourceName, "default_action.0.type", "ALLOW"), ), }, { @@ -216,7 +216,7 @@ func TestAccAWSWafWebAcl_DefaultAction(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckAWSWafWebAclExists(resourceName, &webACL), resource.TestCheckResourceAttr(resourceName, "default_action.#", "1"), - resource.TestCheckResourceAttr(resourceName, "default_action.2267395054.type", "BLOCK"), + resource.TestCheckResourceAttr(resourceName, "default_action.0.type", "BLOCK"), ), }, { @@ -360,7 +360,7 @@ func TestAccAWSWafWebAcl_Tags(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckAWSWafWebAclExists(resourceName, &webACL), resource.TestCheckResourceAttr(resourceName, "default_action.#", "1"), - resource.TestCheckResourceAttr(resourceName, "default_action.4234791575.type", "ALLOW"), + resource.TestCheckResourceAttr(resourceName, "default_action.0.type", "ALLOW"), resource.TestCheckResourceAttr(resourceName, "metric_name", rName), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), @@ -373,7 +373,7 @@ func TestAccAWSWafWebAcl_Tags(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckAWSWafWebAclExists(resourceName, &webACL), resource.TestCheckResourceAttr(resourceName, "default_action.#", "1"), - resource.TestCheckResourceAttr(resourceName, "default_action.4234791575.type", "ALLOW"), + resource.TestCheckResourceAttr(resourceName, "default_action.0.type", "ALLOW"), resource.TestCheckResourceAttr(resourceName, "metric_name", rName), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), @@ -387,7 +387,7 @@ func TestAccAWSWafWebAcl_Tags(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckAWSWafWebAclExists(resourceName, &webACL), resource.TestCheckResourceAttr(resourceName, "default_action.#", "1"), - resource.TestCheckResourceAttr(resourceName, "default_action.4234791575.type", "ALLOW"), + resource.TestCheckResourceAttr(resourceName, "default_action.0.type", "ALLOW"), resource.TestCheckResourceAttr(resourceName, "metric_name", rName), resource.TestCheckResourceAttr(resourceName, "name", rName), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), diff --git a/aws/waf_helpers.go b/aws/waf_helpers.go index 917f44f480f..221e5a33e37 100644 --- a/aws/waf_helpers.go +++ b/aws/waf_helpers.go @@ -28,7 +28,7 @@ func wafSizeConstraintSetSchema() map[string]*schema.Schema { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "field_to_match": { - Type: schema.TypeSet, + Type: schema.TypeList, Required: true, MaxItems: 1, Elem: &schema.Resource{ @@ -76,7 +76,7 @@ func diffWafSizeConstraints(oldS, newS []interface{}) []*waf.SizeConstraintSetUp updates = append(updates, &waf.SizeConstraintSetUpdate{ Action: aws.String(waf.ChangeActionDelete), SizeConstraint: &waf.SizeConstraint{ - FieldToMatch: expandFieldToMatch(constraint["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})), + FieldToMatch: expandFieldToMatch(constraint["field_to_match"].([]interface{})[0].(map[string]interface{})), ComparisonOperator: aws.String(constraint["comparison_operator"].(string)), Size: aws.Int64(int64(constraint["size"].(int))), TextTransformation: aws.String(constraint["text_transformation"].(string)), @@ -90,7 +90,7 @@ func diffWafSizeConstraints(oldS, newS []interface{}) []*waf.SizeConstraintSetUp updates = append(updates, &waf.SizeConstraintSetUpdate{ Action: aws.String(waf.ChangeActionInsert), SizeConstraint: &waf.SizeConstraint{ - FieldToMatch: expandFieldToMatch(constraint["field_to_match"].(*schema.Set).List()[0].(map[string]interface{})), + FieldToMatch: expandFieldToMatch(constraint["field_to_match"].([]interface{})[0].(map[string]interface{})), ComparisonOperator: aws.String(constraint["comparison_operator"].(string)), Size: aws.Int64(int64(constraint["size"].(int))), TextTransformation: aws.String(constraint["text_transformation"].(string)), From ac42d0cb6f6c0d4fb2fd5e6065ca38044bfd2360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20D=C4=85bek?= Date: Fri, 15 May 2020 13:43:38 +0200 Subject: [PATCH 163/475] Provide examples of placement strategy --- website/docs/r/placement_group.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/placement_group.html.markdown b/website/docs/r/placement_group.html.markdown index 3c81f79c2ff..d8bd6cfff63 100644 --- a/website/docs/r/placement_group.html.markdown +++ b/website/docs/r/placement_group.html.markdown @@ -25,7 +25,7 @@ resource "aws_placement_group" "web" { The following arguments are supported: * `name` - (Required) The name of the placement group. -* `strategy` - (Required) The placement strategy. +* `strategy` - (Required) The placement strategy. Can be `"cluster"`, `"partition"` or `"spread"`. * `tags` - (Optional) Key-value map of resource tags. From 3b81e607f5142cbe1af895122e1d8a58871bec2f Mon Sep 17 00:00:00 2001 From: Ilia Lazebnik Date: Fri, 15 May 2020 18:08:54 +0300 Subject: [PATCH 164/475] resource/aws_launch_template: Prevent downstream resource errors with unconfigured partition numbers (#13239) Output from acceptance testing: ``` --- PASS: TestAccAWSAutoScalingGroup_ALB_TargetGroups (171.95s) --- PASS: TestAccAWSAutoScalingGroup_ALB_TargetGroups_ELBCapacity (285.70s) --- PASS: TestAccAWSAutoScalingGroup_autoGeneratedName (118.21s) --- PASS: TestAccAWSAutoScalingGroup_basic (289.54s) --- PASS: TestAccAWSAutoScalingGroup_classicVpcZoneIdentifier (126.69s) --- PASS: TestAccAWSAutoScalingGroup_emptyAvailabilityZones (78.93s) --- PASS: TestAccAWSAutoScalingGroup_enablingMetrics (236.84s) --- PASS: TestAccAWSAutoScalingGroup_initialLifecycleHook (254.46s) --- PASS: TestAccAWSAutoScalingGroup_launchTemplate (39.84s) --- PASS: TestAccAWSAutoScalingGroup_LaunchTemplate_IAMInstanceProfile (63.24s) --- PASS: TestAccAWSAutoScalingGroup_launchTemplate_update (196.20s) --- PASS: TestAccAWSAutoScalingGroup_launchTempPartitionNum (170.82s) --- PASS: TestAccAWSAutoScalingGroup_LoadBalancers (693.58s) --- PASS: TestAccAWSAutoScalingGroup_MaxInstanceLifetime (79.29s) --- PASS: TestAccAWSAutoScalingGroup_MixedInstancesPolicy (49.05s) --- PASS: TestAccAWSAutoScalingGroup_MixedInstancesPolicy_InstancesDistribution_OnDemandAllocationStrategy (42.20s) --- PASS: TestAccAWSAutoScalingGroup_MixedInstancesPolicy_InstancesDistribution_OnDemandBaseCapacity (106.01s) --- PASS: TestAccAWSAutoScalingGroup_MixedInstancesPolicy_InstancesDistribution_OnDemandPercentageAboveBaseCapacity (51.32s) --- PASS: TestAccAWSAutoScalingGroup_MixedInstancesPolicy_InstancesDistribution_SpotAllocationStrategy (170.25s) --- PASS: TestAccAWSAutoScalingGroup_MixedInstancesPolicy_InstancesDistribution_SpotInstancePools (74.39s) --- PASS: TestAccAWSAutoScalingGroup_MixedInstancesPolicy_InstancesDistribution_SpotMaxPrice (49.26s) --- PASS: TestAccAWSAutoScalingGroup_MixedInstancesPolicy_LaunchTemplate_LaunchTemplateSpecification_LaunchTemplateName (48.53s) --- PASS: TestAccAWSAutoScalingGroup_MixedInstancesPolicy_LaunchTemplate_LaunchTemplateSpecification_Version (68.41s) --- PASS: TestAccAWSAutoScalingGroup_MixedInstancesPolicy_LaunchTemplate_Override_InstanceType (73.56s) --- PASS: TestAccAWSAutoScalingGroup_MixedInstancesPolicy_LaunchTemplate_Override_WeightedCapacity (142.65s) --- PASS: TestAccAWSAutoScalingGroup_namePrefix (47.08s) --- PASS: TestAccAWSAutoScalingGroup_serviceLinkedRoleARN (76.81s) --- PASS: TestAccAWSAutoScalingGroup_suspendingProcesses (237.62s) --- PASS: TestAccAWSAutoScalingGroup_tags (199.87s) --- PASS: TestAccAWSAutoScalingGroup_TargetGroupArns (341.68s) --- PASS: TestAccAWSAutoScalingGroup_terminationPolicies (114.77s) --- PASS: TestAccAWSAutoScalingGroup_VpcUpdates (78.67s) --- PASS: TestAccAWSAutoScalingGroup_WithLoadBalancer (642.03s) --- PASS: TestAccAWSAutoScalingGroup_WithLoadBalancer_ToTargetGroup (320.77s) --- PASS: TestAccAWSAutoScalingGroup_withMetrics (70.40s) --- PASS: TestAccAWSAutoScalingGroup_withPlacementGroup (166.42s) --- PASS: TestAccAWSLaunchTemplate_associatePublicIPAddress (26.93s) --- PASS: TestAccAWSLaunchTemplate_basic (7.90s) --- PASS: TestAccAWSLaunchTemplate_BlockDeviceMappings_EBS (43.93s) --- PASS: TestAccAWSLaunchTemplate_BlockDeviceMappings_EBS_DeleteOnTermination (70.32s) --- PASS: TestAccAWSLaunchTemplate_capacityReservation_preference (8.37s) --- PASS: TestAccAWSLaunchTemplate_capacityReservation_target (10.16s) --- PASS: TestAccAWSLaunchTemplate_cpuOptions (7.90s) --- PASS: TestAccAWSLaunchTemplate_creditSpecification_nonBurstable (8.79s) --- PASS: TestAccAWSLaunchTemplate_creditSpecification_t2 (8.45s) --- PASS: TestAccAWSLaunchTemplate_creditSpecification_t3 (8.57s) --- PASS: TestAccAWSLaunchTemplate_data (8.40s) --- PASS: TestAccAWSLaunchTemplate_description (13.69s) --- PASS: TestAccAWSLaunchTemplate_disappears (6.42s) --- PASS: TestAccAWSLaunchTemplate_EbsOptimized (30.29s) --- PASS: TestAccAWSLaunchTemplate_ElasticInferenceAccelerator (13.65s) --- PASS: TestAccAWSLaunchTemplate_hibernation (18.80s) --- PASS: TestAccAWSLaunchTemplate_IamInstanceProfile_EmptyConfigurationBlock (7.20s) --- PASS: TestAccAWSLaunchTemplate_instanceMarketOptions (51.48s) --- PASS: TestAccAWSLaunchTemplate_licenseSpecification (8.73s) --- PASS: TestAccAWSLaunchTemplate_metadataOptions (8.15s) --- PASS: TestAccAWSLaunchTemplate_networkInterface (12.63s) --- PASS: TestAccAWSLaunchTemplate_networkInterface_ipv6AddressCount (8.55s) --- PASS: TestAccAWSLaunchTemplate_networkInterface_ipv6Addresses (9.18s) --- PASS: TestAccAWSLaunchTemplate_networkInterfaceAddresses (12.71s) --- PASS: TestAccAWSLaunchTemplate_placement_partitionNum (14.94s) --- PASS: TestAccAWSLaunchTemplate_tags (13.82s) --- PASS: TestAccAWSLaunchTemplate_update (47.24s) --- PASS: TestAccAWSLaunchTemplateDataSource_associatePublicIPAddress (26.16s) --- PASS: TestAccAWSLaunchTemplateDataSource_basic (13.70s) --- PASS: TestAccAWSLaunchTemplateDataSource_filter_basic (13.86s) --- PASS: TestAccAWSLaunchTemplateDataSource_filter_tags (13.62s) --- PASS: TestAccAWSLaunchTemplateDataSource_metadataOptions (13.55s) ``` --- aws/resource_aws_autoscaling_group_test.go | 88 ++++++++++++++++++++++ aws/resource_aws_launch_template.go | 2 +- 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_autoscaling_group_test.go b/aws/resource_aws_autoscaling_group_test.go index cd8580eadb0..b19d7e5c018 100644 --- a/aws/resource_aws_autoscaling_group_test.go +++ b/aws/resource_aws_autoscaling_group_test.go @@ -2069,6 +2069,41 @@ func TestAccAWSAutoScalingGroup_MixedInstancesPolicy_LaunchTemplate_Override_Wei }) } +func TestAccAWSAutoScalingGroup_launchTempPartitionNum(t *testing.T) { + var group autoscaling.Group + + randName := fmt.Sprintf("terraform-test-%s", acctest.RandString(10)) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSAutoScalingGroupDestroy, + DisableBinaryDriver: true, + Steps: []resource.TestStep{ + { + Config: testAccAWSAutoScalingGroupPartitionConfig(randName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSAutoScalingGroupExists("aws_autoscaling_group.test", &group), + ), + }, + { + ResourceName: "aws_autoscaling_group.test", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "force_delete", + "initial_lifecycle_hook", + "name_prefix", + "tag", + "tags", + "wait_for_capacity_timeout", + "wait_for_elb_capacity", + }, + }, + }, + }) +} + const testAccAWSAutoScalingGroupConfig_autoGeneratedName = ` data "aws_ami" "test_ami" { most_recent = true @@ -4105,3 +4140,56 @@ resource "aws_autoscaling_group" "test" { } `, rName) } + +func testAccAWSAutoScalingGroupPartitionConfig(rName string) string { + return fmt.Sprintf(` +data "aws_availability_zones" "available" { + # t2.micro is not supported in us-west-2d + blacklisted_zone_ids = ["usw2-az4"] + state = "available" + + filter { + name = "opt-in-status" + values = ["opt-in-not-required"] + } +} + +data "aws_ami" "test_ami" { + most_recent = true + owners = ["amazon"] + + filter { + name = "name" + values = ["amzn-ami-hvm-*-x86_64-gp2"] + } +} + +resource "aws_launch_template" "this" { + name = %[1]q + image_id = data.aws_ami.test_ami.id + instance_type = "m5.large" + + placement { + tenancy = "default" + group_name = aws_placement_group.test.id + } +} + +resource "aws_placement_group" "test" { + name = %[1]q + strategy = "cluster" +} + +resource "aws_autoscaling_group" "test" { + name_prefix = "test" + availability_zones = ["${data.aws_availability_zones.available.names[0]}"] + min_size = 0 + max_size = 0 + + launch_template { + id = aws_launch_template.this.id + version = "$Latest" + } +} +`, rName) +} diff --git a/aws/resource_aws_launch_template.go b/aws/resource_aws_launch_template.go index 3856b416ef0..f1c725599ec 100644 --- a/aws/resource_aws_launch_template.go +++ b/aws/resource_aws_launch_template.go @@ -1707,7 +1707,7 @@ func readPlacementFromConfig(p map[string]interface{}) *ec2.LaunchTemplatePlacem placement.Tenancy = aws.String(v) } - if v, ok := p["partition_number"].(int); ok { + if v, ok := p["partition_number"].(int); ok && v != 0 { placement.PartitionNumber = aws.Int64(int64(v)) } From 0e07b5e36a88199915af1636326ddbdfafc4ff2c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 15 May 2020 11:11:50 -0400 Subject: [PATCH 165/475] Update module aws/aws-sdk-go to v1.30.28 (#13190) Co-authored-by: Renovate Bot --- go.mod | 2 +- go.sum | 4 +- .../aws/aws-sdk-go/aws/endpoints/defaults.go | 228 +++++- .../github.com/aws/aws-sdk-go/aws/version.go | 2 +- .../aws-sdk-go/service/cloudwatchlogs/api.go | 602 +++++++++++++++- .../service/cloudwatchlogs/errors.go | 2 +- .../aws/aws-sdk-go/service/codebuild/api.go | 569 ++++++++++++++- .../aws/aws-sdk-go/service/ec2/api.go | 183 ++++- .../aws/aws-sdk-go/service/elasticache/api.go | 105 +-- .../aws-sdk-go/service/elasticache/errors.go | 2 +- .../aws/aws-sdk-go/service/guardduty/api.go | 33 +- .../aws-sdk-go/service/imagebuilder/api.go | 47 ++ .../aws/aws-sdk-go/service/lightsail/api.go | 674 ++++++++++++------ .../aws/aws-sdk-go/service/route53/api.go | 9 + .../aws/aws-sdk-go/service/sagemaker/api.go | 131 ++-- .../aws/aws-sdk-go/service/ssm/api.go | 6 + .../aws/aws-sdk-go/service/workmail/api.go | 9 +- vendor/modules.txt | 2 +- 18 files changed, 2188 insertions(+), 422 deletions(-) diff --git a/go.mod b/go.mod index bb57dafcf6f..064d902dacc 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/terraform-providers/terraform-provider-aws go 1.13 require ( - github.com/aws/aws-sdk-go v1.30.21 + github.com/aws/aws-sdk-go v1.30.28 github.com/beevik/etree v1.1.0 github.com/bflad/tfproviderdocs v0.6.0 github.com/bflad/tfproviderlint v0.14.0 diff --git a/go.sum b/go.sum index ab0868d9339..9eb3b8a5b58 100644 --- a/go.sum +++ b/go.sum @@ -39,8 +39,8 @@ github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= github.com/aws/aws-sdk-go v1.25.3/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.30.21 h1:19EO1Jr80+jLwJyITzH8c79C/6EwY5mMyasqDbBiCuc= -github.com/aws/aws-sdk-go v1.30.21/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/aws-sdk-go v1.30.28 h1:SaPM7dlmp7h3Lj1nJ4jdzOkTdom08+g20k7AU5heZYg= +github.com/aws/aws-sdk-go v1.30.28/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go index 9b50e10b4bd..be3ad80e135 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go @@ -25,12 +25,12 @@ const ( ApSoutheast1RegionID = "ap-southeast-1" // Asia Pacific (Singapore). ApSoutheast2RegionID = "ap-southeast-2" // Asia Pacific (Sydney). CaCentral1RegionID = "ca-central-1" // Canada (Central). - EuCentral1RegionID = "eu-central-1" // EU (Frankfurt). - EuNorth1RegionID = "eu-north-1" // EU (Stockholm). + EuCentral1RegionID = "eu-central-1" // Europe (Frankfurt). + EuNorth1RegionID = "eu-north-1" // Europe (Stockholm). EuSouth1RegionID = "eu-south-1" // Europe (Milan). - EuWest1RegionID = "eu-west-1" // EU (Ireland). - EuWest2RegionID = "eu-west-2" // EU (London). - EuWest3RegionID = "eu-west-3" // EU (Paris). + EuWest1RegionID = "eu-west-1" // Europe (Ireland). + EuWest2RegionID = "eu-west-2" // Europe (London). + EuWest3RegionID = "eu-west-3" // Europe (Paris). MeSouth1RegionID = "me-south-1" // Middle East (Bahrain). SaEast1RegionID = "sa-east-1" // South America (Sao Paulo). UsEast1RegionID = "us-east-1" // US East (N. Virginia). @@ -48,7 +48,7 @@ const ( // AWS GovCloud (US) partition's regions. const ( UsGovEast1RegionID = "us-gov-east-1" // AWS GovCloud (US-East). - UsGovWest1RegionID = "us-gov-west-1" // AWS GovCloud (US). + UsGovWest1RegionID = "us-gov-west-1" // AWS GovCloud (US-West). ) // AWS ISO (US) partition's regions. @@ -134,22 +134,22 @@ var awsPartition = partition{ Description: "Canada (Central)", }, "eu-central-1": region{ - Description: "EU (Frankfurt)", + Description: "Europe (Frankfurt)", }, "eu-north-1": region{ - Description: "EU (Stockholm)", + Description: "Europe (Stockholm)", }, "eu-south-1": region{ Description: "Europe (Milan)", }, "eu-west-1": region{ - Description: "EU (Ireland)", + Description: "Europe (Ireland)", }, "eu-west-2": region{ - Description: "EU (London)", + Description: "Europe (London)", }, "eu-west-3": region{ - Description: "EU (Paris)", + Description: "Europe (Paris)", }, "me-south-1": region{ Description: "Middle East (Bahrain)", @@ -724,6 +724,7 @@ var awsPartition = partition{ Protocols: []string{"http", "https"}, }, Endpoints: endpoints{ + "ap-east-1": endpoint{}, "ap-northeast-1": endpoint{}, "ap-northeast-2": endpoint{}, "ap-south-1": endpoint{}, @@ -731,8 +732,12 @@ var awsPartition = partition{ "ap-southeast-2": endpoint{}, "ca-central-1": endpoint{}, "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, "us-west-1": endpoint{}, @@ -855,6 +860,7 @@ var awsPartition = partition{ "cloud9": service{ Endpoints: endpoints{ + "ap-east-1": endpoint{}, "ap-northeast-1": endpoint{}, "ap-northeast-2": endpoint{}, "ap-south-1": endpoint{}, @@ -865,8 +871,12 @@ var awsPartition = partition{ "eu-north-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, + "us-west-1": endpoint{}, "us-west-2": endpoint{}, }, }, @@ -1984,6 +1994,48 @@ var awsPartition = partition{ "us-west-2": endpoint{}, }, }, + "eks": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "fips-us-east-1": endpoint{ + Hostname: "fips.eks.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "fips-us-east-2": endpoint{ + Hostname: "fips.eks.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "fips-us-west-2": endpoint{ + Hostname: "fips.eks.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, "elasticache": service{ Endpoints: endpoints{ @@ -3221,6 +3273,7 @@ var awsPartition = partition{ "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, + "sa-east-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, "us-west-1": endpoint{}, @@ -3373,6 +3426,25 @@ var awsPartition = partition{ "us-east-1": endpoint{}, }, }, + "macie": service{ + + Endpoints: endpoints{ + "fips-us-east-1": endpoint{ + Hostname: "macie-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "fips-us-west-2": endpoint{ + Hostname: "macie-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, "managedblockchain": service{ Endpoints: endpoints{ @@ -3870,11 +3942,41 @@ var awsPartition = partition{ "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, "eu-west-3": endpoint{}, - "me-south-1": endpoint{}, - "us-east-1": endpoint{}, - "us-east-2": endpoint{}, - "us-west-1": endpoint{}, - "us-west-2": endpoint{}, + "fips-ca-central-1": endpoint{ + Hostname: "outposts-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + "fips-us-east-1": endpoint{ + Hostname: "outposts-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "fips-us-east-2": endpoint{ + Hostname: "outposts-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "fips-us-west-1": endpoint{ + Hostname: "outposts-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "fips-us-west-2": endpoint{ + Hostname: "outposts-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + "me-south-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, }, }, "pinpoint": service{ @@ -4632,6 +4734,7 @@ var awsPartition = partition{ "secretsmanager": service{ Endpoints: endpoints{ + "af-south-1": endpoint{}, "ap-east-1": endpoint{}, "ap-northeast-1": endpoint{}, "ap-northeast-2": endpoint{}, @@ -4641,6 +4744,7 @@ var awsPartition = partition{ "ca-central-1": endpoint{}, "eu-central-1": endpoint{}, "eu-north-1": endpoint{}, + "eu-south-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, "eu-west-3": endpoint{}, @@ -4679,6 +4783,7 @@ var awsPartition = partition{ "securityhub": service{ Endpoints: endpoints{ + "af-south-1": endpoint{}, "ap-east-1": endpoint{}, "ap-northeast-1": endpoint{}, "ap-northeast-2": endpoint{}, @@ -4688,6 +4793,7 @@ var awsPartition = partition{ "ca-central-1": endpoint{}, "eu-central-1": endpoint{}, "eu-north-1": endpoint{}, + "eu-south-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, "eu-west-3": endpoint{}, @@ -5254,6 +5360,7 @@ var awsPartition = partition{ "storagegateway": service{ Endpoints: endpoints{ + "af-south-1": endpoint{}, "ap-east-1": endpoint{}, "ap-northeast-1": endpoint{}, "ap-northeast-2": endpoint{}, @@ -5263,6 +5370,7 @@ var awsPartition = partition{ "ca-central-1": endpoint{}, "eu-central-1": endpoint{}, "eu-north-1": endpoint{}, + "eu-south-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, "eu-west-3": endpoint{}, @@ -6155,6 +6263,15 @@ var awscnPartition = partition{ "cn-northwest-1": endpoint{}, }, }, + "eks": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, "elasticache": service{ Endpoints: endpoints{ @@ -6612,7 +6729,7 @@ var awsusgovPartition = partition{ Description: "AWS GovCloud (US-East)", }, "us-gov-west-1": region{ - Description: "AWS GovCloud (US)", + Description: "AWS GovCloud (US-West)", }, }, Services: services{ @@ -6745,7 +6862,9 @@ var awsusgovPartition = partition{ "autoscaling": service{ Endpoints: endpoints{ - "us-gov-east-1": endpoint{}, + "us-gov-east-1": endpoint{ + Protocols: []string{"http", "https"}, + }, "us-gov-west-1": endpoint{ Protocols: []string{"http", "https"}, }, @@ -6812,8 +6931,18 @@ var awsusgovPartition = partition{ "cloudtrail": service{ Endpoints: endpoints{ - "us-gov-east-1": endpoint{}, - "us-gov-west-1": endpoint{}, + "us-gov-east-1": endpoint{ + Hostname: "cloudtrail.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + "us-gov-west-1": endpoint{ + Hostname: "cloudtrail.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, }, }, "codebuild": service{ @@ -7101,6 +7230,18 @@ var awsusgovPartition = partition{ "elasticmapreduce": service{ Endpoints: endpoints{ + "fips-us-gov-east-1": endpoint{ + Hostname: "elasticmapreduce.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + "fips-us-gov-west-1": endpoint{ + Hostname: "elasticmapreduce.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, "us-gov-east-1": endpoint{}, "us-gov-west-1": endpoint{ Protocols: []string{"https"}, @@ -7135,8 +7276,18 @@ var awsusgovPartition = partition{ "events": service{ Endpoints: endpoints{ - "us-gov-east-1": endpoint{}, - "us-gov-west-1": endpoint{}, + "us-gov-east-1": endpoint{ + Hostname: "events.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + "us-gov-west-1": endpoint{ + Hostname: "events.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, }, }, "firehose": service{ @@ -7267,6 +7418,13 @@ var awsusgovPartition = partition{ "us-gov-west-1": endpoint{}, }, }, + "kafka": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, "kinesis": service{ Endpoints: endpoints{ @@ -7401,8 +7559,18 @@ var awsusgovPartition = partition{ "outposts": service{ Endpoints: endpoints{ - "us-gov-east-1": endpoint{}, - "us-gov-west-1": endpoint{}, + "us-gov-east-1": endpoint{ + Hostname: "outposts.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + "us-gov-west-1": endpoint{ + Hostname: "outposts.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, }, }, "pinpoint": service{ @@ -7437,6 +7605,18 @@ var awsusgovPartition = partition{ "rds": service{ Endpoints: endpoints{ + "rds.us-gov-east-1": endpoint{ + Hostname: "rds.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + "rds.us-gov-west-1": endpoint{ + Hostname: "rds.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, "us-gov-east-1": endpoint{}, "us-gov-west-1": endpoint{}, }, diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go index 354ef69292d..d23e36e2da2 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/version.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -5,4 +5,4 @@ package aws const SDKName = "aws-sdk-go" // SDKVersion is the version of this SDK -const SDKVersion = "1.30.21" +const SDKVersion = "1.30.28" diff --git a/vendor/github.com/aws/aws-sdk-go/service/cloudwatchlogs/api.go b/vendor/github.com/aws/aws-sdk-go/service/cloudwatchlogs/api.go index b629ace9dd1..6ea344e5e52 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/cloudwatchlogs/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/cloudwatchlogs/api.go @@ -258,9 +258,10 @@ func (c *CloudWatchLogs) CreateExportTaskRequest(input *CreateExportTaskInput) ( // // This is an asynchronous call. If all the required information is provided, // this operation initiates an export task and responds with the ID of the task. -// After the task has started, you can use DescribeExportTasks to get the status -// of the export task. Each account can only have one active (RUNNING or PENDING) -// export task at a time. To cancel an export task, use CancelExportTask. +// After the task has started, you can use DescribeExportTasks (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeExportTasks.html) +// to get the status of the export task. Each account can only have one active +// (RUNNING or PENDING) export task at a time. To cancel an export task, use +// CancelExportTask (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CancelExportTask.html). // // You can export logs from multiple log groups or multiple time ranges to the // same S3 bucket. To separate out log data for each export task, you can specify @@ -896,6 +897,89 @@ func (c *CloudWatchLogs) DeleteMetricFilterWithContext(ctx aws.Context, input *D return out, req.Send() } +const opDeleteQueryDefinition = "DeleteQueryDefinition" + +// DeleteQueryDefinitionRequest generates a "aws/request.Request" representing the +// client's request for the DeleteQueryDefinition operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteQueryDefinition for more information on using the DeleteQueryDefinition +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteQueryDefinitionRequest method. +// req, resp := client.DeleteQueryDefinitionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteQueryDefinition +func (c *CloudWatchLogs) DeleteQueryDefinitionRequest(input *DeleteQueryDefinitionInput) (req *request.Request, output *DeleteQueryDefinitionOutput) { + op := &request.Operation{ + Name: opDeleteQueryDefinition, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteQueryDefinitionInput{} + } + + output = &DeleteQueryDefinitionOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteQueryDefinition API operation for Amazon CloudWatch Logs. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon CloudWatch Logs's +// API operation DeleteQueryDefinition for usage and error information. +// +// Returned Error Types: +// * InvalidParameterException +// A parameter is specified incorrectly. +// +// * ResourceNotFoundException +// The specified resource does not exist. +// +// * ServiceUnavailableException +// The service cannot complete the request. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DeleteQueryDefinition +func (c *CloudWatchLogs) DeleteQueryDefinition(input *DeleteQueryDefinitionInput) (*DeleteQueryDefinitionOutput, error) { + req, out := c.DeleteQueryDefinitionRequest(input) + return out, req.Send() +} + +// DeleteQueryDefinitionWithContext is the same as DeleteQueryDefinition with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteQueryDefinition for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CloudWatchLogs) DeleteQueryDefinitionWithContext(ctx aws.Context, input *DeleteQueryDefinitionInput, opts ...request.Option) (*DeleteQueryDefinitionOutput, error) { + req, out := c.DeleteQueryDefinitionRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDeleteResourcePolicy = "DeleteResourcePolicy" // DeleteResourcePolicyRequest generates a "aws/request.Request" representing the @@ -1914,6 +1998,86 @@ func (c *CloudWatchLogs) DescribeQueriesWithContext(ctx aws.Context, input *Desc return out, req.Send() } +const opDescribeQueryDefinitions = "DescribeQueryDefinitions" + +// DescribeQueryDefinitionsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeQueryDefinitions operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeQueryDefinitions for more information on using the DescribeQueryDefinitions +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeQueryDefinitionsRequest method. +// req, resp := client.DescribeQueryDefinitionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeQueryDefinitions +func (c *CloudWatchLogs) DescribeQueryDefinitionsRequest(input *DescribeQueryDefinitionsInput) (req *request.Request, output *DescribeQueryDefinitionsOutput) { + op := &request.Operation{ + Name: opDescribeQueryDefinitions, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DescribeQueryDefinitionsInput{} + } + + output = &DescribeQueryDefinitionsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeQueryDefinitions API operation for Amazon CloudWatch Logs. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon CloudWatch Logs's +// API operation DescribeQueryDefinitions for usage and error information. +// +// Returned Error Types: +// * InvalidParameterException +// A parameter is specified incorrectly. +// +// * ServiceUnavailableException +// The service cannot complete the request. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/DescribeQueryDefinitions +func (c *CloudWatchLogs) DescribeQueryDefinitions(input *DescribeQueryDefinitionsInput) (*DescribeQueryDefinitionsOutput, error) { + req, out := c.DescribeQueryDefinitionsRequest(input) + return out, req.Send() +} + +// DescribeQueryDefinitionsWithContext is the same as DescribeQueryDefinitions with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeQueryDefinitions for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CloudWatchLogs) DescribeQueryDefinitionsWithContext(ctx aws.Context, input *DescribeQueryDefinitionsInput, opts ...request.Option) (*DescribeQueryDefinitionsOutput, error) { + req, out := c.DescribeQueryDefinitionsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDescribeResourcePolicies = "DescribeResourcePolicies" // DescribeResourcePoliciesRequest generates a "aws/request.Request" representing the @@ -2589,7 +2753,9 @@ func (c *CloudWatchLogs) GetLogGroupFieldsRequest(input *GetLogGroupFieldsInput) // The search is limited to a time period that you specify. // // In the results, fields that start with @ are fields generated by CloudWatch -// Logs. For example, @timestamp is the timestamp of each log event. +// Logs. For example, @timestamp is the timestamp of each log event. For more +// information about the fields that are generated by CloudWatch logs, see Supported +// Logs and Discovered Fields (https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData-discoverable-fields.html). // // The response results are sorted by the frequency percentage, starting with // the highest percentage. @@ -2777,9 +2943,11 @@ func (c *CloudWatchLogs) GetQueryResultsRequest(input *GetQueryResultsInput) (re // // Only the fields requested in the query are returned, along with a @ptr field // which is the identifier for the log record. You can use the value of @ptr -// in a operation to get the full log record. +// in a GetLogRecord (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_GetLogRecord.html) +// operation to get the full log record. // -// GetQueryResults does not start a query execution. To run a query, use . +// GetQueryResults does not start a query execution. To run a query, use StartQuery +// (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_StartQuery.html). // // If the value of the Status field in the output is Running, this operation // returns only partial results. If you see a value of Scheduled or Running @@ -2955,12 +3123,13 @@ func (c *CloudWatchLogs) PutDestinationRequest(input *PutDestinationInput) (req // // A destination encapsulates a physical resource (such as an Amazon Kinesis // stream) and enables you to subscribe to a real-time stream of log events -// for a different account, ingested using PutLogEvents. +// for a different account, ingested using PutLogEvents (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html). // // Through an access policy, a destination controls what is written to it. By // default, PutDestination does not set any access policy with the destination, -// which means a cross-account user cannot call PutSubscriptionFilter against -// this destination. To enable this, the destination owner must call PutDestinationPolicy +// which means a cross-account user cannot call PutSubscriptionFilter (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutSubscriptionFilter.html) +// against this destination. To enable this, the destination owner must call +// PutDestinationPolicy (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutDestinationPolicy.html) // after PutDestination. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -3269,7 +3438,7 @@ func (c *CloudWatchLogs) PutMetricFilterRequest(input *PutMetricFilterInput) (re // // Creates or updates a metric filter and associates it with the specified log // group. Metric filters allow you to configure rules to extract metric data -// from log events ingested through PutLogEvents. +// from log events ingested through PutLogEvents (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html). // // The maximum number of metric filters that can be associated with a log group // is 100. @@ -3319,6 +3488,89 @@ func (c *CloudWatchLogs) PutMetricFilterWithContext(ctx aws.Context, input *PutM return out, req.Send() } +const opPutQueryDefinition = "PutQueryDefinition" + +// PutQueryDefinitionRequest generates a "aws/request.Request" representing the +// client's request for the PutQueryDefinition operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See PutQueryDefinition for more information on using the PutQueryDefinition +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the PutQueryDefinitionRequest method. +// req, resp := client.PutQueryDefinitionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutQueryDefinition +func (c *CloudWatchLogs) PutQueryDefinitionRequest(input *PutQueryDefinitionInput) (req *request.Request, output *PutQueryDefinitionOutput) { + op := &request.Operation{ + Name: opPutQueryDefinition, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PutQueryDefinitionInput{} + } + + output = &PutQueryDefinitionOutput{} + req = c.newRequest(op, input, output) + return +} + +// PutQueryDefinition API operation for Amazon CloudWatch Logs. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon CloudWatch Logs's +// API operation PutQueryDefinition for usage and error information. +// +// Returned Error Types: +// * InvalidParameterException +// A parameter is specified incorrectly. +// +// * ResourceNotFoundException +// The specified resource does not exist. +// +// * ServiceUnavailableException +// The service cannot complete the request. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/logs-2014-03-28/PutQueryDefinition +func (c *CloudWatchLogs) PutQueryDefinition(input *PutQueryDefinitionInput) (*PutQueryDefinitionOutput, error) { + req, out := c.PutQueryDefinitionRequest(input) + return out, req.Send() +} + +// PutQueryDefinitionWithContext is the same as PutQueryDefinition with the addition of +// the ability to pass a context and additional request options. +// +// See PutQueryDefinition for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CloudWatchLogs) PutQueryDefinitionWithContext(ctx aws.Context, input *PutQueryDefinitionInput, opts ...request.Option) (*PutQueryDefinitionOutput, error) { + req, out := c.PutQueryDefinitionRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opPutResourcePolicy = "PutResourcePolicy" // PutResourcePolicyRequest generates a "aws/request.Request" representing the @@ -3544,8 +3796,9 @@ func (c *CloudWatchLogs) PutSubscriptionFilterRequest(input *PutSubscriptionFilt // // Creates or updates a subscription filter and associates it with the specified // log group. Subscription filters allow you to subscribe to a real-time stream -// of log events ingested through PutLogEvents and have them delivered to a -// specific destination. Currently, the supported destinations are: +// of log events ingested through PutLogEvents (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html) +// and have them delivered to a specific destination. Currently, the supported +// destinations are: // // * An Amazon Kinesis stream belonging to the same account as the subscription // filter, for same-account delivery. @@ -3672,7 +3925,7 @@ func (c *CloudWatchLogs) StartQueryRequest(input *StartQueryInput) (req *request // Returned Error Types: // * MalformedQueryException // The query string is not valid. Details about this error are displayed in -// a QueryCompileError object. For more information, see . +// a QueryCompileError object. For more information, see QueryCompileError (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_QueryCompileError.html)"/>. // // For more information about valid query syntax, see CloudWatch Logs Insights // Query Syntax (https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html). @@ -3845,11 +4098,11 @@ func (c *CloudWatchLogs) TagLogGroupRequest(input *TagLogGroupInput) (req *reque // // Adds or updates the specified tags for the specified log group. // -// To list the tags for a log group, use ListTagsLogGroup. To remove tags, use -// UntagLogGroup. +// To list the tags for a log group, use ListTagsLogGroup (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_ListTagsLogGroup.html). +// To remove tags, use UntagLogGroup (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_UntagLogGroup.html). // // For more information about tags, see Tag Log Groups in Amazon CloudWatch -// Logs (https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/log-group-tagging.html) +// Logs (https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#log-group-tagging) // in the Amazon CloudWatch Logs User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -4019,8 +4272,8 @@ func (c *CloudWatchLogs) UntagLogGroupRequest(input *UntagLogGroupInput) (req *r // // Removes the specified tags from the specified log group. // -// To list the tags for a log group, use ListTagsLogGroup. To add tags, use -// UntagLogGroup. +// To list the tags for a log group, use ListTagsLogGroup (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_ListTagsLogGroup.html). +// To add tags, use TagLogGroup (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_TagLogGroup.html). // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -4793,6 +5046,64 @@ func (s DeleteMetricFilterOutput) GoString() string { return s.String() } +type DeleteQueryDefinitionInput struct { + _ struct{} `type:"structure"` + + // QueryDefinitionId is a required field + QueryDefinitionId *string `locationName:"queryDefinitionId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteQueryDefinitionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteQueryDefinitionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteQueryDefinitionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteQueryDefinitionInput"} + if s.QueryDefinitionId == nil { + invalidParams.Add(request.NewErrParamRequired("QueryDefinitionId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetQueryDefinitionId sets the QueryDefinitionId field's value. +func (s *DeleteQueryDefinitionInput) SetQueryDefinitionId(v string) *DeleteQueryDefinitionInput { + s.QueryDefinitionId = &v + return s +} + +type DeleteQueryDefinitionOutput struct { + _ struct{} `type:"structure"` + + Success *bool `locationName:"success" type:"boolean"` +} + +// String returns the string representation +func (s DeleteQueryDefinitionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteQueryDefinitionOutput) GoString() string { + return s.String() +} + +// SetSuccess sets the Success field's value. +func (s *DeleteQueryDefinitionOutput) SetSuccess(v bool) *DeleteQueryDefinitionOutput { + s.Success = &v + return s +} + type DeleteResourcePolicyInput struct { _ struct{} `type:"structure"` @@ -5631,6 +5942,97 @@ func (s *DescribeQueriesOutput) SetQueries(v []*QueryInfo) *DescribeQueriesOutpu return s } +type DescribeQueryDefinitionsInput struct { + _ struct{} `type:"structure"` + + MaxResults *int64 `locationName:"maxResults" min:"1" type:"integer"` + + // The token for the next set of items to return. The token expires after 24 + // hours. + NextToken *string `locationName:"nextToken" min:"1" type:"string"` + + QueryDefinitionNamePrefix *string `locationName:"queryDefinitionNamePrefix" min:"1" type:"string"` +} + +// String returns the string representation +func (s DescribeQueryDefinitionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeQueryDefinitionsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeQueryDefinitionsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeQueryDefinitionsInput"} + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + if s.NextToken != nil && len(*s.NextToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("NextToken", 1)) + } + if s.QueryDefinitionNamePrefix != nil && len(*s.QueryDefinitionNamePrefix) < 1 { + invalidParams.Add(request.NewErrParamMinLen("QueryDefinitionNamePrefix", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeQueryDefinitionsInput) SetMaxResults(v int64) *DescribeQueryDefinitionsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeQueryDefinitionsInput) SetNextToken(v string) *DescribeQueryDefinitionsInput { + s.NextToken = &v + return s +} + +// SetQueryDefinitionNamePrefix sets the QueryDefinitionNamePrefix field's value. +func (s *DescribeQueryDefinitionsInput) SetQueryDefinitionNamePrefix(v string) *DescribeQueryDefinitionsInput { + s.QueryDefinitionNamePrefix = &v + return s +} + +type DescribeQueryDefinitionsOutput struct { + _ struct{} `type:"structure"` + + // The token for the next set of items to return. The token expires after 24 + // hours. + NextToken *string `locationName:"nextToken" min:"1" type:"string"` + + QueryDefinitions []*QueryDefinition `locationName:"queryDefinitions" type:"list"` +} + +// String returns the string representation +func (s DescribeQueryDefinitionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeQueryDefinitionsOutput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeQueryDefinitionsOutput) SetNextToken(v string) *DescribeQueryDefinitionsOutput { + s.NextToken = &v + return s +} + +// SetQueryDefinitions sets the QueryDefinitions field's value. +func (s *DescribeQueryDefinitionsOutput) SetQueryDefinitions(v []*QueryDefinition) *DescribeQueryDefinitionsOutput { + s.QueryDefinitions = v + return s +} + type DescribeResourcePoliciesInput struct { _ struct{} `type:"structure"` @@ -7344,7 +7746,7 @@ func (s *LogStream) SetUploadSequenceToken(v string) *LogStream { } // The query string is not valid. Details about this error are displayed in -// a QueryCompileError object. For more information, see . +// a QueryCompileError object. For more information, see QueryCompileError (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_QueryCompileError.html)"/>. // // For more information about valid query syntax, see CloudWatch Logs Insights // Query Syntax (https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html). @@ -7528,7 +7930,9 @@ type MetricTransformation struct { // MetricName is a required field MetricName *string `locationName:"metricName" type:"string" required:"true"` - // The namespace of the CloudWatch metric. + // A custom namespace to contain your metric in CloudWatch. Use namespaces to + // group together metrics that are similar. For more information, see Namespaces + // (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#Namespace). // // MetricNamespace is a required field MetricNamespace *string `locationName:"metricNamespace" type:"string" required:"true"` @@ -7885,9 +8289,9 @@ type PutLogEventsInput struct { // The sequence token obtained from the response of the previous PutLogEvents // call. An upload in a newly created log stream does not require a sequence - // token. You can also get the sequence token using DescribeLogStreams. If you - // call PutLogEvents twice within a narrow time period using the same value - // for sequenceToken, both calls may be successful, or one may be rejected. + // token. You can also get the sequence token using DescribeLogStreams (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeLogStreams.html). + // If you call PutLogEvents twice within a narrow time period using the same + // value for sequenceToken, both calls may be successful, or one may be rejected. SequenceToken *string `locationName:"sequenceToken" min:"1" type:"string"` } @@ -8111,6 +8515,98 @@ func (s PutMetricFilterOutput) GoString() string { return s.String() } +type PutQueryDefinitionInput struct { + _ struct{} `type:"structure"` + + LogGroupNames []*string `locationName:"logGroupNames" type:"list"` + + // Name is a required field + Name *string `locationName:"name" min:"1" type:"string" required:"true"` + + QueryDefinitionId *string `locationName:"queryDefinitionId" type:"string"` + + // QueryString is a required field + QueryString *string `locationName:"queryString" min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s PutQueryDefinitionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutQueryDefinitionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PutQueryDefinitionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PutQueryDefinitionInput"} + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Name", 1)) + } + if s.QueryString == nil { + invalidParams.Add(request.NewErrParamRequired("QueryString")) + } + if s.QueryString != nil && len(*s.QueryString) < 1 { + invalidParams.Add(request.NewErrParamMinLen("QueryString", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetLogGroupNames sets the LogGroupNames field's value. +func (s *PutQueryDefinitionInput) SetLogGroupNames(v []*string) *PutQueryDefinitionInput { + s.LogGroupNames = v + return s +} + +// SetName sets the Name field's value. +func (s *PutQueryDefinitionInput) SetName(v string) *PutQueryDefinitionInput { + s.Name = &v + return s +} + +// SetQueryDefinitionId sets the QueryDefinitionId field's value. +func (s *PutQueryDefinitionInput) SetQueryDefinitionId(v string) *PutQueryDefinitionInput { + s.QueryDefinitionId = &v + return s +} + +// SetQueryString sets the QueryString field's value. +func (s *PutQueryDefinitionInput) SetQueryString(v string) *PutQueryDefinitionInput { + s.QueryString = &v + return s +} + +type PutQueryDefinitionOutput struct { + _ struct{} `type:"structure"` + + QueryDefinitionId *string `locationName:"queryDefinitionId" type:"string"` +} + +// String returns the string representation +func (s PutQueryDefinitionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutQueryDefinitionOutput) GoString() string { + return s.String() +} + +// SetQueryDefinitionId sets the QueryDefinitionId field's value. +func (s *PutQueryDefinitionOutput) SetQueryDefinitionId(v string) *PutQueryDefinitionOutput { + s.QueryDefinitionId = &v + return s +} + type PutResourcePolicyInput struct { _ struct{} `type:"structure"` @@ -8290,7 +8786,8 @@ type PutSubscriptionFilterInput struct { // A name for the subscription filter. If you are updating an existing filter, // you must specify the correct name in filterName. Otherwise, the call fails // because you cannot associate a second filter with a log group. To find the - // name of the filter currently associated with a log group, use DescribeSubscriptionFilters. + // name of the filter currently associated with a log group, use DescribeSubscriptionFilters + // (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeSubscriptionFilters.html). // // FilterName is a required field FilterName *string `locationName:"filterName" min:"1" type:"string" required:"true"` @@ -8472,6 +8969,60 @@ func (s *QueryCompileErrorLocation) SetStartCharOffset(v int64) *QueryCompileErr return s } +type QueryDefinition struct { + _ struct{} `type:"structure"` + + LastModified *int64 `locationName:"lastModified" type:"long"` + + LogGroupNames []*string `locationName:"logGroupNames" type:"list"` + + Name *string `locationName:"name" min:"1" type:"string"` + + QueryDefinitionId *string `locationName:"queryDefinitionId" type:"string"` + + QueryString *string `locationName:"queryString" min:"1" type:"string"` +} + +// String returns the string representation +func (s QueryDefinition) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s QueryDefinition) GoString() string { + return s.String() +} + +// SetLastModified sets the LastModified field's value. +func (s *QueryDefinition) SetLastModified(v int64) *QueryDefinition { + s.LastModified = &v + return s +} + +// SetLogGroupNames sets the LogGroupNames field's value. +func (s *QueryDefinition) SetLogGroupNames(v []*string) *QueryDefinition { + s.LogGroupNames = v + return s +} + +// SetName sets the Name field's value. +func (s *QueryDefinition) SetName(v string) *QueryDefinition { + s.Name = &v + return s +} + +// SetQueryDefinitionId sets the QueryDefinitionId field's value. +func (s *QueryDefinition) SetQueryDefinitionId(v string) *QueryDefinition { + s.QueryDefinitionId = &v + return s +} + +// SetQueryString sets the QueryString field's value. +func (s *QueryDefinition) SetQueryString(v string) *QueryDefinition { + s.QueryString = &v + return s +} + // Information about one CloudWatch Logs Insights query that matches the request // in a DescribeQueries operation. type QueryInfo struct { @@ -8778,6 +9329,9 @@ func (s *ResourcePolicy) SetPolicyName(v string) *ResourcePolicy { // Contains one field from one log event returned by a CloudWatch Logs Insights // query, along with the value of that field. +// +// For more information about the fields that are generated by CloudWatch logs, +// see Supported Logs and Discovered Fields (https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData-discoverable-fields.html). type ResultField struct { _ struct{} `type:"structure"` diff --git a/vendor/github.com/aws/aws-sdk-go/service/cloudwatchlogs/errors.go b/vendor/github.com/aws/aws-sdk-go/service/cloudwatchlogs/errors.go index c6e23336d00..39c9cd5eafe 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/cloudwatchlogs/errors.go +++ b/vendor/github.com/aws/aws-sdk-go/service/cloudwatchlogs/errors.go @@ -43,7 +43,7 @@ const ( // "MalformedQueryException". // // The query string is not valid. Details about this error are displayed in - // a QueryCompileError object. For more information, see . + // a QueryCompileError object. For more information, see QueryCompileError (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_QueryCompileError.html)"/>. // // For more information about valid query syntax, see CloudWatch Logs Insights // Query Syntax (https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html). diff --git a/vendor/github.com/aws/aws-sdk-go/service/codebuild/api.go b/vendor/github.com/aws/aws-sdk-go/service/codebuild/api.go index 48ec22795e9..0da13a3c1b1 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/codebuild/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/codebuild/api.go @@ -1205,6 +1205,12 @@ func (c *CodeBuild) DescribeTestCasesRequest(input *DescribeTestCasesInput) (req Name: opDescribeTestCases, HTTPMethod: "POST", HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"nextToken"}, + OutputTokens: []string{"nextToken"}, + LimitToken: "maxResults", + TruncationToken: "", + }, } if input == nil { @@ -1256,6 +1262,58 @@ func (c *CodeBuild) DescribeTestCasesWithContext(ctx aws.Context, input *Describ return out, req.Send() } +// DescribeTestCasesPages iterates over the pages of a DescribeTestCases operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeTestCases method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeTestCases operation. +// pageNum := 0 +// err := client.DescribeTestCasesPages(params, +// func(page *codebuild.DescribeTestCasesOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *CodeBuild) DescribeTestCasesPages(input *DescribeTestCasesInput, fn func(*DescribeTestCasesOutput, bool) bool) error { + return c.DescribeTestCasesPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// DescribeTestCasesPagesWithContext same as DescribeTestCasesPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CodeBuild) DescribeTestCasesPagesWithContext(ctx aws.Context, input *DescribeTestCasesInput, fn func(*DescribeTestCasesOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *DescribeTestCasesInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeTestCasesRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*DescribeTestCasesOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opGetResourcePolicy = "GetResourcePolicy" // GetResourcePolicyRequest generates a "aws/request.Request" representing the @@ -1539,6 +1597,12 @@ func (c *CodeBuild) ListBuildsRequest(input *ListBuildsInput) (req *request.Requ Name: opListBuilds, HTTPMethod: "POST", HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"nextToken"}, + OutputTokens: []string{"nextToken"}, + LimitToken: "", + TruncationToken: "", + }, } if input == nil { @@ -1587,6 +1651,58 @@ func (c *CodeBuild) ListBuildsWithContext(ctx aws.Context, input *ListBuildsInpu return out, req.Send() } +// ListBuildsPages iterates over the pages of a ListBuilds operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListBuilds method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListBuilds operation. +// pageNum := 0 +// err := client.ListBuildsPages(params, +// func(page *codebuild.ListBuildsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *CodeBuild) ListBuildsPages(input *ListBuildsInput, fn func(*ListBuildsOutput, bool) bool) error { + return c.ListBuildsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListBuildsPagesWithContext same as ListBuildsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CodeBuild) ListBuildsPagesWithContext(ctx aws.Context, input *ListBuildsInput, fn func(*ListBuildsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListBuildsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListBuildsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListBuildsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opListBuildsForProject = "ListBuildsForProject" // ListBuildsForProjectRequest generates a "aws/request.Request" representing the @@ -1618,6 +1734,12 @@ func (c *CodeBuild) ListBuildsForProjectRequest(input *ListBuildsForProjectInput Name: opListBuildsForProject, HTTPMethod: "POST", HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"nextToken"}, + OutputTokens: []string{"nextToken"}, + LimitToken: "", + TruncationToken: "", + }, } if input == nil { @@ -1670,6 +1792,58 @@ func (c *CodeBuild) ListBuildsForProjectWithContext(ctx aws.Context, input *List return out, req.Send() } +// ListBuildsForProjectPages iterates over the pages of a ListBuildsForProject operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListBuildsForProject method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListBuildsForProject operation. +// pageNum := 0 +// err := client.ListBuildsForProjectPages(params, +// func(page *codebuild.ListBuildsForProjectOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *CodeBuild) ListBuildsForProjectPages(input *ListBuildsForProjectInput, fn func(*ListBuildsForProjectOutput, bool) bool) error { + return c.ListBuildsForProjectPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListBuildsForProjectPagesWithContext same as ListBuildsForProjectPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CodeBuild) ListBuildsForProjectPagesWithContext(ctx aws.Context, input *ListBuildsForProjectInput, fn func(*ListBuildsForProjectOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListBuildsForProjectInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListBuildsForProjectRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListBuildsForProjectOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opListCuratedEnvironmentImages = "ListCuratedEnvironmentImages" // ListCuratedEnvironmentImagesRequest generates a "aws/request.Request" representing the @@ -1775,6 +1949,12 @@ func (c *CodeBuild) ListProjectsRequest(input *ListProjectsInput) (req *request. Name: opListProjects, HTTPMethod: "POST", HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"nextToken"}, + OutputTokens: []string{"nextToken"}, + LimitToken: "", + TruncationToken: "", + }, } if input == nil { @@ -1824,6 +2004,58 @@ func (c *CodeBuild) ListProjectsWithContext(ctx aws.Context, input *ListProjects return out, req.Send() } +// ListProjectsPages iterates over the pages of a ListProjects operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListProjects method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListProjects operation. +// pageNum := 0 +// err := client.ListProjectsPages(params, +// func(page *codebuild.ListProjectsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *CodeBuild) ListProjectsPages(input *ListProjectsInput, fn func(*ListProjectsOutput, bool) bool) error { + return c.ListProjectsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListProjectsPagesWithContext same as ListProjectsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CodeBuild) ListProjectsPagesWithContext(ctx aws.Context, input *ListProjectsInput, fn func(*ListProjectsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListProjectsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListProjectsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListProjectsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opListReportGroups = "ListReportGroups" // ListReportGroupsRequest generates a "aws/request.Request" representing the @@ -1855,6 +2087,12 @@ func (c *CodeBuild) ListReportGroupsRequest(input *ListReportGroupsInput) (req * Name: opListReportGroups, HTTPMethod: "POST", HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"nextToken"}, + OutputTokens: []string{"nextToken"}, + LimitToken: "maxResults", + TruncationToken: "", + }, } if input == nil { @@ -1903,6 +2141,58 @@ func (c *CodeBuild) ListReportGroupsWithContext(ctx aws.Context, input *ListRepo return out, req.Send() } +// ListReportGroupsPages iterates over the pages of a ListReportGroups operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListReportGroups method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListReportGroups operation. +// pageNum := 0 +// err := client.ListReportGroupsPages(params, +// func(page *codebuild.ListReportGroupsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *CodeBuild) ListReportGroupsPages(input *ListReportGroupsInput, fn func(*ListReportGroupsOutput, bool) bool) error { + return c.ListReportGroupsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListReportGroupsPagesWithContext same as ListReportGroupsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CodeBuild) ListReportGroupsPagesWithContext(ctx aws.Context, input *ListReportGroupsInput, fn func(*ListReportGroupsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListReportGroupsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListReportGroupsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListReportGroupsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opListReports = "ListReports" // ListReportsRequest generates a "aws/request.Request" representing the @@ -1934,6 +2224,12 @@ func (c *CodeBuild) ListReportsRequest(input *ListReportsInput) (req *request.Re Name: opListReports, HTTPMethod: "POST", HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"nextToken"}, + OutputTokens: []string{"nextToken"}, + LimitToken: "maxResults", + TruncationToken: "", + }, } if input == nil { @@ -1982,6 +2278,58 @@ func (c *CodeBuild) ListReportsWithContext(ctx aws.Context, input *ListReportsIn return out, req.Send() } +// ListReportsPages iterates over the pages of a ListReports operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListReports method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListReports operation. +// pageNum := 0 +// err := client.ListReportsPages(params, +// func(page *codebuild.ListReportsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *CodeBuild) ListReportsPages(input *ListReportsInput, fn func(*ListReportsOutput, bool) bool) error { + return c.ListReportsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListReportsPagesWithContext same as ListReportsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CodeBuild) ListReportsPagesWithContext(ctx aws.Context, input *ListReportsInput, fn func(*ListReportsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListReportsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListReportsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListReportsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opListReportsForReportGroup = "ListReportsForReportGroup" // ListReportsForReportGroupRequest generates a "aws/request.Request" representing the @@ -2013,6 +2361,12 @@ func (c *CodeBuild) ListReportsForReportGroupRequest(input *ListReportsForReport Name: opListReportsForReportGroup, HTTPMethod: "POST", HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"nextToken"}, + OutputTokens: []string{"nextToken"}, + LimitToken: "maxResults", + TruncationToken: "", + }, } if input == nil { @@ -2064,6 +2418,58 @@ func (c *CodeBuild) ListReportsForReportGroupWithContext(ctx aws.Context, input return out, req.Send() } +// ListReportsForReportGroupPages iterates over the pages of a ListReportsForReportGroup operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListReportsForReportGroup method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListReportsForReportGroup operation. +// pageNum := 0 +// err := client.ListReportsForReportGroupPages(params, +// func(page *codebuild.ListReportsForReportGroupOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *CodeBuild) ListReportsForReportGroupPages(input *ListReportsForReportGroupInput, fn func(*ListReportsForReportGroupOutput, bool) bool) error { + return c.ListReportsForReportGroupPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListReportsForReportGroupPagesWithContext same as ListReportsForReportGroupPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CodeBuild) ListReportsForReportGroupPagesWithContext(ctx aws.Context, input *ListReportsForReportGroupInput, fn func(*ListReportsForReportGroupOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListReportsForReportGroupInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListReportsForReportGroupRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListReportsForReportGroupOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opListSharedProjects = "ListSharedProjects" // ListSharedProjectsRequest generates a "aws/request.Request" representing the @@ -2095,6 +2501,12 @@ func (c *CodeBuild) ListSharedProjectsRequest(input *ListSharedProjectsInput) (r Name: opListSharedProjects, HTTPMethod: "POST", HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"nextToken"}, + OutputTokens: []string{"nextToken"}, + LimitToken: "maxResults", + TruncationToken: "", + }, } if input == nil { @@ -2143,6 +2555,58 @@ func (c *CodeBuild) ListSharedProjectsWithContext(ctx aws.Context, input *ListSh return out, req.Send() } +// ListSharedProjectsPages iterates over the pages of a ListSharedProjects operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListSharedProjects method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListSharedProjects operation. +// pageNum := 0 +// err := client.ListSharedProjectsPages(params, +// func(page *codebuild.ListSharedProjectsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *CodeBuild) ListSharedProjectsPages(input *ListSharedProjectsInput, fn func(*ListSharedProjectsOutput, bool) bool) error { + return c.ListSharedProjectsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListSharedProjectsPagesWithContext same as ListSharedProjectsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CodeBuild) ListSharedProjectsPagesWithContext(ctx aws.Context, input *ListSharedProjectsInput, fn func(*ListSharedProjectsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListSharedProjectsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListSharedProjectsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListSharedProjectsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opListSharedReportGroups = "ListSharedReportGroups" // ListSharedReportGroupsRequest generates a "aws/request.Request" representing the @@ -2174,6 +2638,12 @@ func (c *CodeBuild) ListSharedReportGroupsRequest(input *ListSharedReportGroupsI Name: opListSharedReportGroups, HTTPMethod: "POST", HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"nextToken"}, + OutputTokens: []string{"nextToken"}, + LimitToken: "maxResults", + TruncationToken: "", + }, } if input == nil { @@ -2222,6 +2692,58 @@ func (c *CodeBuild) ListSharedReportGroupsWithContext(ctx aws.Context, input *Li return out, req.Send() } +// ListSharedReportGroupsPages iterates over the pages of a ListSharedReportGroups operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListSharedReportGroups method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListSharedReportGroups operation. +// pageNum := 0 +// err := client.ListSharedReportGroupsPages(params, +// func(page *codebuild.ListSharedReportGroupsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *CodeBuild) ListSharedReportGroupsPages(input *ListSharedReportGroupsInput, fn func(*ListSharedReportGroupsOutput, bool) bool) error { + return c.ListSharedReportGroupsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListSharedReportGroupsPagesWithContext same as ListSharedReportGroupsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CodeBuild) ListSharedReportGroupsPagesWithContext(ctx aws.Context, input *ListSharedReportGroupsInput, fn func(*ListSharedReportGroupsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListSharedReportGroupsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListSharedReportGroupsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListSharedReportGroupsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opListSourceCredentials = "ListSourceCredentials" // ListSourceCredentialsRequest generates a "aws/request.Request" representing the @@ -5003,12 +5525,15 @@ type EnvironmentVariable struct { // The type of environment variable. Valid values include: // // * PARAMETER_STORE: An environment variable stored in Amazon EC2 Systems - // Manager Parameter Store. + // Manager Parameter Store. To learn how to specify a parameter store environment + // variable, see parameter store reference-key in the buildspec file (https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html#parameter-store-build-spec). // // * PLAINTEXT: An environment variable in plain text format. This is the // default value. // // * SECRETS_MANAGER: An environment variable stored in AWS Secrets Manager. + // To learn how to specify a secrets manager environment variable, see secrets + // manager reference-key in the buildspec file (https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html#secrets-manager-build-spec). Type *string `locationName:"type" type:"string" enum:"EnvironmentVariableType"` // The value of the environment variable. @@ -7379,16 +7904,16 @@ type ProjectEnvironment struct { // (Mumbai), Asia Pacific (Tokyo), Asia Pacific (Sydney), and EU (Frankfurt). // // * The environment type LINUX_CONTAINER with compute type build.general1.2xlarge - // is available only in regions US East (N. Virginia), US East (N. Virginia), - // US West (Oregon), Canada (Central), EU (Ireland), EU (London), EU (Frankfurt), + // is available only in regions US East (N. Virginia), US East (Ohio), US + // West (Oregon), Canada (Central), EU (Ireland), EU (London), EU (Frankfurt), // Asia Pacific (Tokyo), Asia Pacific (Seoul), Asia Pacific (Singapore), // Asia Pacific (Sydney), China (Beijing), and China (Ningxia). // // * The environment type LINUX_GPU_CONTAINER is available only in regions - // US East (N. Virginia), US East (N. Virginia), US West (Oregon), Canada - // (Central), EU (Ireland), EU (London), EU (Frankfurt), Asia Pacific (Tokyo), - // Asia Pacific (Seoul), Asia Pacific (Singapore), Asia Pacific (Sydney) - // , China (Beijing), and China (Ningxia). + // US East (N. Virginia), US East (Ohio), US West (Oregon), Canada (Central), + // EU (Ireland), EU (London), EU (Frankfurt), Asia Pacific (Tokyo), Asia + // Pacific (Seoul), Asia Pacific (Singapore), Asia Pacific (Sydney) , China + // (Beijing), and China (Ningxia). // // Type is a required field Type *string `locationName:"type" type:"string" required:"true" enum:"EnvironmentType"` @@ -8684,7 +9209,7 @@ type StartBuildInput struct { // A unique, case sensitive identifier you provide to ensure the idempotency // of the StartBuild request. The token is included in the StartBuild request - // and is valid for 12 hours. If you repeat the StartBuild request with the + // and is valid for 5 minutes. If you repeat the StartBuild request with the // same token, but change a parameter, AWS CodeBuild returns a parameter mismatch // error. IdempotencyToken *string `locationName:"idempotencyToken" type:"string"` @@ -10089,16 +10614,16 @@ type WebhookFilter struct { // Pattern is a required field Pattern *string `locationName:"pattern" type:"string" required:"true"` - // The type of webhook filter. There are five webhook filter types: EVENT, ACTOR_ACCOUNT_ID, - // HEAD_REF, BASE_REF, and FILE_PATH. + // The type of webhook filter. There are six webhook filter types: EVENT, ACTOR_ACCOUNT_ID, + // HEAD_REF, BASE_REF, FILE_PATH, and COMMIT_MESSAGE. // // EVENT // // A webhook event triggers a build when the provided pattern matches one of - // four event types: PUSH, PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED, and PULL_REQUEST_REOPENED. - // The EVENT patterns are specified as a comma-separated string. For example, - // PUSH, PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED filters all push, pull request - // created, and pull request updated events. + // five event types: PUSH, PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED, PULL_REQUEST_REOPENED, + // and PULL_REQUEST_MERGED. The EVENT patterns are specified as a comma-separated + // string. For example, PUSH, PULL_REQUEST_CREATED, PULL_REQUEST_UPDATED filters + // all push, pull request created, and pull request updated events. // // The PULL_REQUEST_REOPENED works with GitHub and GitHub Enterprise only. // @@ -10127,7 +10652,18 @@ type WebhookFilter struct { // A webhook triggers a build when the path of a changed file matches the regular // expression pattern. // - // Works with GitHub and GitHub Enterprise push events only. + // Works with GitHub and Bitbucket events push and pull requests events. Also + // works with GitHub Enterprise push events, but does not work with GitHub Enterprise + // pull request events. + // + // COMMIT_MESSAGE + // + // A webhook triggers a build when the head commit message matches the regular + // expression pattern. + // + // Works with GitHub and Bitbucket events push and pull requests events. Also + // works with GitHub Enterprise push events, but does not work with GitHub Enterprise + // pull request events. // // Type is a required field Type *string `locationName:"type" type:"string" required:"true" enum:"WebhookFilterType"` @@ -10517,4 +11053,7 @@ const ( // WebhookFilterTypeFilePath is a WebhookFilterType enum value WebhookFilterTypeFilePath = "FILE_PATH" + + // WebhookFilterTypeCommitMessage is a WebhookFilterType enum value + WebhookFilterTypeCommitMessage = "COMMIT_MESSAGE" ) diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go index 3f68867ee8b..d71efab9be8 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go @@ -4678,6 +4678,8 @@ func (c *EC2) CreateLaunchTemplateRequest(input *CreateLaunchTemplateInput) (req // Creates a launch template. A launch template contains the parameters to launch // an instance. When you launch an instance using RunInstances, you can specify // a launch template instead of providing the launch parameters in the request. +// For more information, see Launching an instance from a launch template (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-templates.html)in +// the Amazon Elastic Compute Cloud User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -4757,6 +4759,9 @@ func (c *EC2) CreateLaunchTemplateVersionRequest(input *CreateLaunchTemplateVers // Launch template versions are numbered in the order in which they are created. // You cannot specify, change, or replace the numbering of launch template versions. // +// For more information, see Managing launch template versions (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-templates.html#manage-launch-template-versions)in +// the Amazon Elastic Compute Cloud User Guide. +// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -46592,6 +46597,11 @@ type CreateLaunchTemplateOutput struct { // Information about the launch template. LaunchTemplate *LaunchTemplate `locationName:"launchTemplate" type:"structure"` + + // If the launch template contains parameters or parameter combinations that + // are not valid, an error code and an error message are returned for each issue + // that's found. + Warning *ValidationWarning `locationName:"warning" type:"structure"` } // String returns the string representation @@ -46610,6 +46620,12 @@ func (s *CreateLaunchTemplateOutput) SetLaunchTemplate(v *LaunchTemplate) *Creat return s } +// SetWarning sets the Warning field's value. +func (s *CreateLaunchTemplateOutput) SetWarning(v *ValidationWarning) *CreateLaunchTemplateOutput { + s.Warning = v + return s +} + type CreateLaunchTemplateVersionInput struct { _ struct{} `type:"structure"` @@ -46727,6 +46743,11 @@ type CreateLaunchTemplateVersionOutput struct { // Information about the launch template version. LaunchTemplateVersion *LaunchTemplateVersion `locationName:"launchTemplateVersion" type:"structure"` + + // If the new version of the launch template contains parameters or parameter + // combinations that are not valid, an error code and an error message are returned + // for each issue that's found. + Warning *ValidationWarning `locationName:"warning" type:"structure"` } // String returns the string representation @@ -46745,6 +46766,12 @@ func (s *CreateLaunchTemplateVersionOutput) SetLaunchTemplateVersion(v *LaunchTe return s } +// SetWarning sets the Warning field's value. +func (s *CreateLaunchTemplateVersionOutput) SetWarning(v *ValidationWarning) *CreateLaunchTemplateVersionOutput { + s.Warning = v + return s +} + type CreateLocalGatewayRouteInput struct { _ struct{} `type:"structure"` @@ -46861,6 +46888,9 @@ type CreateLocalGatewayRouteTableVpcAssociationInput struct { // LocalGatewayRouteTableId is a required field LocalGatewayRouteTableId *string `type:"string" required:"true"` + // The tags to assign to the local gateway route table VPC association. + TagSpecifications []*TagSpecification `locationName:"TagSpecification" locationNameList:"item" type:"list"` + // The ID of the VPC. // // VpcId is a required field @@ -46905,6 +46935,12 @@ func (s *CreateLocalGatewayRouteTableVpcAssociationInput) SetLocalGatewayRouteTa return s } +// SetTagSpecifications sets the TagSpecifications field's value. +func (s *CreateLocalGatewayRouteTableVpcAssociationInput) SetTagSpecifications(v []*TagSpecification) *CreateLocalGatewayRouteTableVpcAssociationInput { + s.TagSpecifications = v + return s +} + // SetVpcId sets the VpcId field's value. func (s *CreateLocalGatewayRouteTableVpcAssociationInput) SetVpcId(v string) *CreateLocalGatewayRouteTableVpcAssociationInput { s.VpcId = &v @@ -48403,7 +48439,8 @@ type CreateSubnetInput struct { // must use a /64 prefix length. Ipv6CidrBlock *string `type:"string"` - // The Amazon Resource Name (ARN) of the Outpost. + // The Amazon Resource Name (ARN) of the Outpost. If you specify an Outpost + // ARN, you must also specify the Availability Zone of the Outpost subnet. OutpostArn *string `type:"string"` // The ID of the VPC. @@ -61444,6 +61481,18 @@ type DescribeLocalGatewayRouteTableVirtualInterfaceGroupAssociationsInput struct DryRun *bool `type:"boolean"` // One or more filters. + // + // * local-gateway-id - The ID of a local gateway. + // + // * local-gateway-route-table-id - The ID of the local gateway route table. + // + // * local-gateway-route-table-virtual-interface-group-association-id - The + // ID of the association. + // + // * local-gateway-route-table-virtual-interface-group-id - The ID of the + // virtual interface group. + // + // * state - The state of the association. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` // The IDs of the associations. @@ -61553,6 +61602,16 @@ type DescribeLocalGatewayRouteTableVpcAssociationsInput struct { DryRun *bool `type:"boolean"` // One or more filters. + // + // * local-gateway-id - The ID of a local gateway. + // + // * local-gateway-route-table-id - The ID of the local gateway route table. + // + // * local-gateway-route-table-vpc-association-id - The ID of the association. + // + // * state - The state of the association. + // + // * vpc-id - The ID of the VPC. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` // The IDs of the associations. @@ -61662,6 +61721,14 @@ type DescribeLocalGatewayRouteTablesInput struct { DryRun *bool `type:"boolean"` // One or more filters. + // + // * local-gateway-id - The ID of a local gateway. + // + // * local-gateway-route-table-id - The ID of a local gateway route table. + // + // * outpost-arn - The Amazon Resource Name (ARN) of the Outpost. + // + // * state - The state of the local gateway route table. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` // The IDs of the local gateway route tables. @@ -61771,6 +61838,13 @@ type DescribeLocalGatewayVirtualInterfaceGroupsInput struct { DryRun *bool `type:"boolean"` // One or more filters. + // + // * local-gateway-id - The ID of a local gateway. + // + // * local-gateway-virtual-interface-id - The ID of the virtual interface. + // + // * local-gateway-virtual-interface-group-id - The ID of the virtual interface + // group. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` // The IDs of the virtual interface groups. @@ -61991,7 +62065,21 @@ type DescribeLocalGatewaysInput struct { // One or more filters. Filters []*Filter `locationName:"Filter" locationNameList:"Filter" type:"list"` - // The IDs of the local gateways. + // One or more filters. + // + // * local-gateway-id - The ID of a local gateway. + // + // * local-gateway-route-table-id - The ID of the local gateway route table. + // + // * local-gateway-route-table-virtual-interface-group-association-id - The + // ID of the association. + // + // * local-gateway-route-table-virtual-interface-group-id - The ID of the + // virtual interface group. + // + // * outpost-arn - The Amazon Resource Name (ARN) of the Outpost. + // + // * state - The state of the association. LocalGatewayIds []*string `locationName:"LocalGatewayId" locationNameList:"item" type:"list"` // The maximum number of results to return with a single call. To retrieve the @@ -107275,6 +107363,70 @@ func (s *VCpuInfo) SetValidThreadsPerCore(v []*int64) *VCpuInfo { return s } +// The error code and error message that is returned for a parameter or parameter +// combination that is not valid when a new launch template or new version of +// a launch template is created. +type ValidationError struct { + _ struct{} `type:"structure"` + + // The error code that indicates why the parameter or parameter combination + // is not valid. For more information about error codes, see Error Codes (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html.html). + Code *string `locationName:"code" type:"string"` + + // The error message that describes why the parameter or parameter combination + // is not valid. For more information about error messages, see Error Codes + // (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html.html). + Message *string `locationName:"message" type:"string"` +} + +// String returns the string representation +func (s ValidationError) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ValidationError) GoString() string { + return s.String() +} + +// SetCode sets the Code field's value. +func (s *ValidationError) SetCode(v string) *ValidationError { + s.Code = &v + return s +} + +// SetMessage sets the Message field's value. +func (s *ValidationError) SetMessage(v string) *ValidationError { + s.Message = &v + return s +} + +// The error codes and error messages that are returned for the parameters or +// parameter combinations that are not valid when a new launch template or new +// version of a launch template is created. +type ValidationWarning struct { + _ struct{} `type:"structure"` + + // The error codes and error messages. + Errors []*ValidationError `locationName:"errorSet" locationNameList:"item" type:"list"` +} + +// String returns the string representation +func (s ValidationWarning) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ValidationWarning) GoString() string { + return s.String() +} + +// SetErrors sets the Errors field's value. +func (s *ValidationWarning) SetErrors(v []*ValidationError) *ValidationWarning { + s.Errors = v + return s +} + // Describes telemetry for a VPN tunnel. type VgwTelemetry struct { _ struct{} `type:"structure"` @@ -111329,6 +111481,33 @@ const ( // InstanceTypeInf124xlarge is a InstanceType enum value InstanceTypeInf124xlarge = "inf1.24xlarge" + + // InstanceTypeM6gMetal is a InstanceType enum value + InstanceTypeM6gMetal = "m6g.metal" + + // InstanceTypeM6gMedium is a InstanceType enum value + InstanceTypeM6gMedium = "m6g.medium" + + // InstanceTypeM6gLarge is a InstanceType enum value + InstanceTypeM6gLarge = "m6g.large" + + // InstanceTypeM6gXlarge is a InstanceType enum value + InstanceTypeM6gXlarge = "m6g.xlarge" + + // InstanceTypeM6g2xlarge is a InstanceType enum value + InstanceTypeM6g2xlarge = "m6g.2xlarge" + + // InstanceTypeM6g4xlarge is a InstanceType enum value + InstanceTypeM6g4xlarge = "m6g.4xlarge" + + // InstanceTypeM6g8xlarge is a InstanceType enum value + InstanceTypeM6g8xlarge = "m6g.8xlarge" + + // InstanceTypeM6g12xlarge is a InstanceType enum value + InstanceTypeM6g12xlarge = "m6g.12xlarge" + + // InstanceTypeM6g16xlarge is a InstanceType enum value + InstanceTypeM6g16xlarge = "m6g.16xlarge" ) const ( diff --git a/vendor/github.com/aws/aws-sdk-go/service/elasticache/api.go b/vendor/github.com/aws/aws-sdk-go/service/elasticache/api.go index e1e52e34aed..259ff9518e1 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/elasticache/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/elasticache/api.go @@ -1089,7 +1089,7 @@ func (c *ElastiCache) CreateGlobalReplicationGroupRequest(input *CreateGlobalRep // reads and disaster recovery across regions. For more information, see Replication // Across Regions Using Global Datastore (/AmazonElastiCache/latest/red-ug/Redis-Global-Clusters.html). // -// * The GlobalReplicationGroupId is the name of the Global Datastore. +// * The GlobalReplicationGroupIdSuffix is the name of the Global Datastore. // // * The PrimaryReplicationGroupId represents the name of the primary cluster // that accepts writes and will replicate updates to the secondary cluster. @@ -1273,7 +1273,7 @@ func (c *ElastiCache) CreateReplicationGroupRequest(input *CreateReplicationGrou // The Global Datastore does not exist // // * ErrCodeInvalidGlobalReplicationGroupStateFault "InvalidGlobalReplicationGroupState" -// The Global Datastore is not available +// The Global Datastore is not available or in primary-only state. // // * ErrCodeInvalidParameterValueException "InvalidParameterValue" // The value for a parameter is invalid. @@ -1476,7 +1476,7 @@ func (c *ElastiCache) DecreaseNodeGroupsInGlobalReplicationGroupRequest(input *D // The Global Datastore does not exist // // * ErrCodeInvalidGlobalReplicationGroupStateFault "InvalidGlobalReplicationGroupState" -// The Global Datastore is not available +// The Global Datastore is not available or in primary-only state. // // * ErrCodeInvalidParameterValueException "InvalidParameterValue" // The value for a parameter is invalid. @@ -2078,8 +2078,6 @@ func (c *ElastiCache) DeleteGlobalReplicationGroupRequest(input *DeleteGlobalRep // immediately begins deleting the selected resources; you cannot cancel or // revert this operation. // -// This operation is valid for Redis only. -// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -2092,7 +2090,7 @@ func (c *ElastiCache) DeleteGlobalReplicationGroupRequest(input *DeleteGlobalRep // The Global Datastore does not exist // // * ErrCodeInvalidGlobalReplicationGroupStateFault "InvalidGlobalReplicationGroupState" -// The Global Datastore is not available +// The Global Datastore is not available or in primary-only state. // // * ErrCodeInvalidParameterValueException "InvalidParameterValue" // The value for a parameter is invalid. @@ -4559,7 +4557,7 @@ func (c *ElastiCache) DisassociateGlobalReplicationGroupRequest(input *Disassoci // The Global Datastore does not exist // // * ErrCodeInvalidGlobalReplicationGroupStateFault "InvalidGlobalReplicationGroupState" -// The Global Datastore is not available +// The Global Datastore is not available or in primary-only state. // // * ErrCodeInvalidParameterValueException "InvalidParameterValue" // The value for a parameter is invalid. @@ -4633,7 +4631,9 @@ func (c *ElastiCache) FailoverGlobalReplicationGroupRequest(input *FailoverGloba // FailoverGlobalReplicationGroup API operation for Amazon ElastiCache. // -// Used to failover the primary region to a selected secondary region. +// Used to failover the primary region to a selected secondary region. The selected +// secondary region will be come primary, and all other clusters will become +// secondary. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -4647,7 +4647,7 @@ func (c *ElastiCache) FailoverGlobalReplicationGroupRequest(input *FailoverGloba // The Global Datastore does not exist // // * ErrCodeInvalidGlobalReplicationGroupStateFault "InvalidGlobalReplicationGroupState" -// The Global Datastore is not available +// The Global Datastore is not available or in primary-only state. // // * ErrCodeInvalidParameterValueException "InvalidParameterValue" // The value for a parameter is invalid. @@ -4735,7 +4735,7 @@ func (c *ElastiCache) IncreaseNodeGroupsInGlobalReplicationGroupRequest(input *I // The Global Datastore does not exist // // * ErrCodeInvalidGlobalReplicationGroupStateFault "InvalidGlobalReplicationGroupState" -// The Global Datastore is not available +// The Global Datastore is not available or in primary-only state. // // * ErrCodeInvalidParameterValueException "InvalidParameterValue" // The value for a parameter is invalid. @@ -5258,7 +5258,7 @@ func (c *ElastiCache) ModifyCacheParameterGroupRequest(input *ModifyCacheParamet // Two or more incompatible parameters were specified. // // * ErrCodeInvalidGlobalReplicationGroupStateFault "InvalidGlobalReplicationGroupState" -// The Global Datastore is not available +// The Global Datastore is not available or in primary-only state. // // See also, https://docs.aws.amazon.com/goto/WebAPI/elasticache-2015-02-02/ModifyCacheParameterGroup func (c *ElastiCache) ModifyCacheParameterGroup(input *ModifyCacheParameterGroupInput) (*CacheParameterGroupNameMessage, error) { @@ -5430,7 +5430,7 @@ func (c *ElastiCache) ModifyGlobalReplicationGroupRequest(input *ModifyGlobalRep // The Global Datastore does not exist // // * ErrCodeInvalidGlobalReplicationGroupStateFault "InvalidGlobalReplicationGroupState" -// The Global Datastore is not available +// The Global Datastore is not available or in primary-only state. // // * ErrCodeInvalidParameterValueException "InvalidParameterValue" // The value for a parameter is invalid. @@ -5503,10 +5503,6 @@ func (c *ElastiCache) ModifyReplicationGroupRequest(input *ModifyReplicationGrou // // Modifies the settings for a replication group. // -// For Redis (cluster mode enabled) clusters, this operation cannot be used -// to change a cluster's node type or engine version. For more information, -// see: -// // * Scaling for Amazon ElastiCache for Redis (cluster mode enabled) (https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/scaling-redis-cluster-mode-enabled.html) // in the ElastiCache User Guide // @@ -5841,7 +5837,7 @@ func (c *ElastiCache) RebalanceSlotsInGlobalReplicationGroupRequest(input *Rebal // RebalanceSlotsInGlobalReplicationGroup API operation for Amazon ElastiCache. // -// Redistribute slots to ensure unifirom distribution across existing shards +// Redistribute slots to ensure uniform distribution across existing shards // in the cluster. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -5856,7 +5852,7 @@ func (c *ElastiCache) RebalanceSlotsInGlobalReplicationGroupRequest(input *Rebal // The Global Datastore does not exist // // * ErrCodeInvalidGlobalReplicationGroupStateFault "InvalidGlobalReplicationGroupState" -// The Global Datastore is not available +// The Global Datastore is not available or in primary-only state. // // * ErrCodeInvalidParameterValueException "InvalidParameterValue" // The value for a parameter is invalid. @@ -6141,7 +6137,7 @@ func (c *ElastiCache) ResetCacheParameterGroupRequest(input *ResetCacheParameter // Two or more incompatible parameters were specified. // // * ErrCodeInvalidGlobalReplicationGroupStateFault "InvalidGlobalReplicationGroupState" -// The Global Datastore is not available +// The Global Datastore is not available or in primary-only state. // // See also, https://docs.aws.amazon.com/goto/WebAPI/elasticache-2015-02-02/ResetCacheParameterGroup func (c *ElastiCache) ResetCacheParameterGroup(input *ResetCacheParameterGroupInput) (*CacheParameterGroupNameMessage, error) { @@ -8858,8 +8854,8 @@ type CreateGlobalReplicationGroupInput struct { // Provides details of the Global Datastore GlobalReplicationGroupDescription *string `type:"string"` - // The suffix for name of a Global Datastore. The suffix guarantees uniqueness - // of the Global Datastore name across multiple regions. + // The suffix name of a Global Datastore. The suffix guarantees uniqueness of + // the Global Datastore name across multiple regions. // // GlobalReplicationGroupIdSuffix is a required field GlobalReplicationGroupIdSuffix *string `type:"string" required:"true"` @@ -8923,8 +8919,8 @@ type CreateGlobalReplicationGroupOutput struct { // only reads. The primary cluster automatically replicates updates to the secondary // cluster. // - // * The GlobalReplicationGroupId represents the name of the Global Datastore, - // which is what you use to associate a secondary cluster. + // * The GlobalReplicationGroupIdSuffix represents the name of the Global + // Datastore, which is what you use to associate a secondary cluster. GlobalReplicationGroup *GlobalReplicationGroup `type:"structure"` } @@ -9099,10 +9095,10 @@ type CreateReplicationGroupInput struct { // // If you're creating a Redis (cluster mode disabled) or a Redis (cluster mode // enabled) replication group, you can use this parameter to individually configure - // each node group (shard), or you can omit this parameter. However, when seeding - // a Redis (cluster mode enabled) cluster from a S3 rdb file, you must configure - // each node group (shard) using this parameter because you must specify the - // slots for each node group. + // each node group (shard), or you can omit this parameter. However, it is required + // when seeding a Redis (cluster mode enabled) cluster from a S3 rdb file. You + // must configure each node group (shard) using this parameter because you must + // specify the slots for each node group. NodeGroupConfiguration []*NodeGroupConfiguration `locationNameList:"NodeGroupConfiguration" type:"list"` // The Amazon Resource Name (ARN) of the Amazon Simple Notification Service @@ -9740,8 +9736,8 @@ type DecreaseNodeGroupsInGlobalReplicationGroupOutput struct { // only reads. The primary cluster automatically replicates updates to the secondary // cluster. // - // * The GlobalReplicationGroupId represents the name of the Global Datastore, - // which is what you use to associate a secondary cluster. + // * The GlobalReplicationGroupIdSuffix represents the name of the Global + // Datastore, which is what you use to associate a secondary cluster. GlobalReplicationGroup *GlobalReplicationGroup `type:"structure"` } @@ -10136,8 +10132,7 @@ type DeleteGlobalReplicationGroupInput struct { // GlobalReplicationGroupId is a required field GlobalReplicationGroupId *string `type:"string" required:"true"` - // If set to true, the primary replication is retained as a standalone replication - // group. + // The primary replication group is retained as a standalone replication group. // // RetainPrimaryReplicationGroup is a required field RetainPrimaryReplicationGroup *bool `type:"boolean" required:"true"` @@ -10189,8 +10184,8 @@ type DeleteGlobalReplicationGroupOutput struct { // only reads. The primary cluster automatically replicates updates to the secondary // cluster. // - // * The GlobalReplicationGroupId represents the name of the Global Datastore, - // which is what you use to associate a secondary cluster. + // * The GlobalReplicationGroupIdSuffix represents the name of the Global + // Datastore, which is what you use to associate a secondary cluster. GlobalReplicationGroup *GlobalReplicationGroup `type:"structure"` } @@ -12127,8 +12122,8 @@ type DisassociateGlobalReplicationGroupOutput struct { // only reads. The primary cluster automatically replicates updates to the secondary // cluster. // - // * The GlobalReplicationGroupId represents the name of the Global Datastore, - // which is what you use to associate a secondary cluster. + // * The GlobalReplicationGroupIdSuffix represents the name of the Global + // Datastore, which is what you use to associate a secondary cluster. GlobalReplicationGroup *GlobalReplicationGroup `type:"structure"` } @@ -12409,8 +12404,8 @@ type FailoverGlobalReplicationGroupOutput struct { // only reads. The primary cluster automatically replicates updates to the secondary // cluster. // - // * The GlobalReplicationGroupId represents the name of the Global Datastore, - // which is what you use to associate a secondary cluster. + // * The GlobalReplicationGroupIdSuffix represents the name of the Global + // Datastore, which is what you use to associate a secondary cluster. GlobalReplicationGroup *GlobalReplicationGroup `type:"structure"` } @@ -12468,8 +12463,8 @@ func (s *GlobalNodeGroup) SetSlots(v string) *GlobalNodeGroup { // only reads. The primary cluster automatically replicates updates to the secondary // cluster. // -// * The GlobalReplicationGroupId represents the name of the Global Datastore, -// which is what you use to associate a secondary cluster. +// * The GlobalReplicationGroupIdSuffix represents the name of the Global +// Datastore, which is what you use to associate a secondary cluster. type GlobalReplicationGroup struct { _ struct{} `type:"structure"` @@ -12495,7 +12490,7 @@ type GlobalReplicationGroup struct { // A flag that indicates whether the Global Datastore is cluster enabled. ClusterEnabled *bool `type:"boolean"` - // The Elasticache engine. For preview, it is Redis only. + // The Elasticache engine. For Redis only. Engine *string `type:"string"` // The Elasticache Redis engine version. For preview, it is Redis version 5.0.5 @@ -12797,8 +12792,8 @@ type IncreaseNodeGroupsInGlobalReplicationGroupOutput struct { // only reads. The primary cluster automatically replicates updates to the secondary // cluster. // - // * The GlobalReplicationGroupId represents the name of the Global Datastore, - // which is what you use to associate a secondary cluster. + // * The GlobalReplicationGroupIdSuffix represents the name of the Global + // Datastore, which is what you use to associate a secondary cluster. GlobalReplicationGroup *GlobalReplicationGroup `type:"structure"` } @@ -13603,12 +13598,9 @@ func (s *ModifyCacheSubnetGroupOutput) SetCacheSubnetGroup(v *CacheSubnetGroup) type ModifyGlobalReplicationGroupInput struct { _ struct{} `type:"structure"` - // If true, this parameter causes the modifications in this request and any - // pending modifications to be applied, asynchronously and as soon as possible, - // regardless of the PreferredMaintenanceWindow setting for the replication - // group. If false, changes to the nodes in the replication group are applied - // on the next maintenance reboot, or the next failure reboot, whichever occurs - // first. + // This parameter causes the modifications in this request and any pending modifications + // to be applied, asynchronously and as soon as possible. Modifications to Global + // Replication Groups cannot be requested to be applied in PreferredMaintenceWindow. // // ApplyImmediately is a required field ApplyImmediately *bool `type:"boolean" required:"true"` @@ -13703,8 +13695,8 @@ type ModifyGlobalReplicationGroupOutput struct { // only reads. The primary cluster automatically replicates updates to the secondary // cluster. // - // * The GlobalReplicationGroupId represents the name of the Global Datastore, - // which is what you use to associate a secondary cluster. + // * The GlobalReplicationGroupIdSuffix represents the name of the Global + // Datastore, which is what you use to associate a secondary cluster. GlobalReplicationGroup *GlobalReplicationGroup `type:"structure"` } @@ -15078,8 +15070,8 @@ type RebalanceSlotsInGlobalReplicationGroupOutput struct { // only reads. The primary cluster automatically replicates updates to the secondary // cluster. // - // * The GlobalReplicationGroupId represents the name of the Global Datastore, - // which is what you use to associate a secondary cluster. + // * The GlobalReplicationGroupIdSuffix represents the name of the Global + // Datastore, which is what you use to associate a secondary cluster. GlobalReplicationGroup *GlobalReplicationGroup `type:"structure"` } @@ -17365,4 +17357,13 @@ const ( // UpdateActionStatusComplete is a UpdateActionStatus enum value UpdateActionStatusComplete = "complete" + + // UpdateActionStatusScheduling is a UpdateActionStatus enum value + UpdateActionStatusScheduling = "scheduling" + + // UpdateActionStatusScheduled is a UpdateActionStatus enum value + UpdateActionStatusScheduled = "scheduled" + + // UpdateActionStatusNotApplicable is a UpdateActionStatus enum value + UpdateActionStatusNotApplicable = "not-applicable" ) diff --git a/vendor/github.com/aws/aws-sdk-go/service/elasticache/errors.go b/vendor/github.com/aws/aws-sdk-go/service/elasticache/errors.go index e68e0121ffb..4e78aa9320e 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/elasticache/errors.go +++ b/vendor/github.com/aws/aws-sdk-go/service/elasticache/errors.go @@ -165,7 +165,7 @@ const ( // ErrCodeInvalidGlobalReplicationGroupStateFault for service response error code // "InvalidGlobalReplicationGroupState". // - // The Global Datastore is not available + // The Global Datastore is not available or in primary-only state. ErrCodeInvalidGlobalReplicationGroupStateFault = "InvalidGlobalReplicationGroupState" // ErrCodeInvalidKMSKeyFault for service response error code diff --git a/vendor/github.com/aws/aws-sdk-go/service/guardduty/api.go b/vendor/github.com/aws/aws-sdk-go/service/guardduty/api.go index b1e8e563acc..5eb039eeb01 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/guardduty/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/guardduty/api.go @@ -1646,8 +1646,8 @@ func (c *GuardDuty) DisableOrganizationAdminAccountRequest(input *DisableOrganiz // DisableOrganizationAdminAccount API operation for Amazon GuardDuty. // -// Disables GuardDuty administrator permissions for an AWS account within the -// Organization. +// Disables an AWS account within the Organization as the GuardDuty delegated +// administrator. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -1896,8 +1896,8 @@ func (c *GuardDuty) EnableOrganizationAdminAccountRequest(input *EnableOrganizat // EnableOrganizationAdminAccount API operation for Amazon GuardDuty. // -// Enables GuardDuty administrator permissions for an AWS account within the -// organization. +// Enables an AWS account within the organization as the GuardDuty delegated +// administrator. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -3655,7 +3655,7 @@ func (c *GuardDuty) ListOrganizationAdminAccountsRequest(input *ListOrganization // ListOrganizationAdminAccounts API operation for Amazon GuardDuty. // -// Lists the accounts configured as AWS Organization delegated administrators. +// Lists the accounts configured as GuardDuty delegated administrators. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -5977,6 +5977,8 @@ type CreateFilterInput struct { // // * service.action.networkConnectionAction.protocol // + // * service.action.networkConnectionAction.localIpDetails.ipAddressV4 + // // * service.action.networkConnectionAction.remoteIpDetails.city.cityName // // * service.action.networkConnectionAction.remoteIpDetails.country.countryName @@ -6160,7 +6162,7 @@ type CreateIPSetInput struct { // Format is a required field Format *string `locationName:"format" min:"1" type:"string" required:"true" enum:"IpSetFormat"` - // The URI of the file that contains the IPSet. For example: https://s3.us-west-2.amazonaws.com/my-bucket/my-object-key. + // The URI of the file that contains the IPSet. For example: . // // Location is a required field Location *string `locationName:"location" min:"1" type:"string" required:"true"` @@ -6585,7 +6587,7 @@ type CreateThreatIntelSetInput struct { // Format is a required field Format *string `locationName:"format" min:"1" type:"string" required:"true" enum:"ThreatIntelSetFormat"` - // The URI of the file that contains the ThreatIntelSet. For example: https://s3.us-west-2.amazonaws.com/my-bucket/my-object-key. + // The URI of the file that contains the ThreatIntelSet. For example: . // // Location is a required field Location *string `locationName:"location" min:"1" type:"string" required:"true"` @@ -7579,7 +7581,7 @@ func (s *DestinationProperties) SetKmsKeyArn(v string) *DestinationProperties { type DisableOrganizationAdminAccountInput struct { _ struct{} `type:"structure"` - // The AWS Account ID for the Organizations account to be disabled as a GuardDuty + // The AWS Account ID for the organizations account to be disabled as a GuardDuty // delegated administrator. // // AdminAccountId is a required field @@ -7821,7 +7823,7 @@ func (s *DomainDetails) SetDomain(v string) *DomainDetails { type EnableOrganizationAdminAccountInput struct { _ struct{} `type:"structure"` - // The AWS Account ID for the Organizations account to be enabled as a GuardDuty + // The AWS Account ID for the organization account to be enabled as a GuardDuty // delegated administrator. // // AdminAccountId is a required field @@ -8642,7 +8644,7 @@ type GetIPSetOutput struct { // Format is a required field Format *string `locationName:"format" min:"1" type:"string" required:"true" enum:"IpSetFormat"` - // The URI of the file that contains the IPSet. For example: https://s3.us-west-2.amazonaws.com/my-bucket/my-object-key. + // The URI of the file that contains the IPSet. For example: . // // Location is a required field Location *string `locationName:"location" min:"1" type:"string" required:"true"` @@ -8966,7 +8968,7 @@ type GetThreatIntelSetOutput struct { // Format is a required field Format *string `locationName:"format" min:"1" type:"string" required:"true" enum:"ThreatIntelSetFormat"` - // The URI of the file that contains the ThreatIntelSet. For example: https://s3.us-west-2.amazonaws.com/my-bucket/my-object-key. + // The URI of the file that contains the ThreatIntelSet. For example: . // // Location is a required field Location *string `locationName:"location" min:"1" type:"string" required:"true"` @@ -9630,6 +9632,8 @@ type ListFindingsInput struct { // // * resource.instanceDetails.instanceId // + // * resource.instanceDetails.outpostArn + // // * resource.instanceDetails.networkInterfaces.ipv6Addresses // // * resource.instanceDetails.networkInterfaces.privateIpAddresses.privateIpAddress @@ -9680,6 +9684,8 @@ type ListFindingsInput struct { // // * service.action.networkConnectionAction.protocol // + // * service.action.networkConnectionAction.localIpDetails.ipAddressV4 + // // * service.action.networkConnectionAction.remoteIpDetails.city.cityName // // * service.action.networkConnectionAction.remoteIpDetails.country.countryName @@ -12147,7 +12153,7 @@ type UpdateIPSetInput struct { // IpSetId is a required field IpSetId *string `location:"uri" locationName:"ipSetId" type:"string" required:"true"` - // The updated URI of the file that contains the IPSet. For example: https://s3.us-west-2.amazonaws.com/my-bucket/my-object-key. + // The updated URI of the file that contains the IPSet. For example: . Location *string `locationName:"location" min:"1" type:"string"` // The unique ID that specifies the IPSet that you want to update. @@ -12400,8 +12406,7 @@ type UpdateThreatIntelSetInput struct { // DetectorId is a required field DetectorId *string `location:"uri" locationName:"detectorId" min:"1" type:"string" required:"true"` - // The updated URI of the file that contains the ThreateIntelSet. For example: - // https://s3.us-west-2.amazonaws.com/my-bucket/my-object-key. + // The updated URI of the file that contains the ThreateIntelSet. For example: . Location *string `locationName:"location" min:"1" type:"string"` // The unique ID that specifies the ThreatIntelSet that you want to update. diff --git a/vendor/github.com/aws/aws-sdk-go/service/imagebuilder/api.go b/vendor/github.com/aws/aws-sdk-go/service/imagebuilder/api.go index 10a6d1a9a06..94d810886bf 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/imagebuilder/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/imagebuilder/api.go @@ -5135,6 +5135,11 @@ type Component struct { // The platform of the component. Platform *string `locationName:"platform" type:"string" enum:"Platform"` + // The operating system (OS) version supported by the component. If the OS information + // is available, a prefix match is performed against the parent image OS version + // during image recipe creation. + SupportedOsVersions []*string `locationName:"supportedOsVersions" min:"1" type:"list"` + // The tags associated with the component. Tags map[string]*string `locationName:"tags" min:"1" type:"map"` @@ -5216,6 +5221,12 @@ func (s *Component) SetPlatform(v string) *Component { return s } +// SetSupportedOsVersions sets the SupportedOsVersions field's value. +func (s *Component) SetSupportedOsVersions(v []*string) *Component { + s.SupportedOsVersions = v + return s +} + // SetTags sets the Tags field's value. func (s *Component) SetTags(v map[string]*string) *Component { s.Tags = v @@ -5298,6 +5309,11 @@ type ComponentSummary struct { // The platform of the component. Platform *string `locationName:"platform" type:"string" enum:"Platform"` + // The operating system (OS) version supported by the component. If the OS information + // is available, a prefix match is performed against the parent image OS version + // during image recipe creation. + SupportedOsVersions []*string `locationName:"supportedOsVersions" min:"1" type:"list"` + // The tags associated with the component. Tags map[string]*string `locationName:"tags" min:"1" type:"map"` @@ -5361,6 +5377,12 @@ func (s *ComponentSummary) SetPlatform(v string) *ComponentSummary { return s } +// SetSupportedOsVersions sets the SupportedOsVersions field's value. +func (s *ComponentSummary) SetSupportedOsVersions(v []*string) *ComponentSummary { + s.SupportedOsVersions = v + return s +} + // SetTags sets the Tags field's value. func (s *ComponentSummary) SetTags(v map[string]*string) *ComponentSummary { s.Tags = v @@ -5401,6 +5423,11 @@ type ComponentVersion struct { // The platform of the component. Platform *string `locationName:"platform" type:"string" enum:"Platform"` + // The operating system (OS) version supported by the component. If the OS information + // is available, a prefix match is performed against the parent image OS version + // during image recipe creation. + SupportedOsVersions []*string `locationName:"supportedOsVersions" min:"1" type:"list"` + // The type of the component denotes whether the component is used to build // the image or only to test it. Type *string `locationName:"type" type:"string" enum:"ComponentType"` @@ -5455,6 +5482,12 @@ func (s *ComponentVersion) SetPlatform(v string) *ComponentVersion { return s } +// SetSupportedOsVersions sets the SupportedOsVersions field's value. +func (s *ComponentVersion) SetSupportedOsVersions(v []*string) *ComponentVersion { + s.SupportedOsVersions = v + return s +} + // SetType sets the Type field's value. func (s *ComponentVersion) SetType(v string) *ComponentVersion { s.Type = &v @@ -5505,6 +5538,11 @@ type CreateComponentInput struct { // SemanticVersion is a required field SemanticVersion *string `locationName:"semanticVersion" type:"string" required:"true"` + // The operating system (OS) version supported by the component. If the OS information + // is available, a prefix match is performed against the parent image OS version + // during image recipe creation. + SupportedOsVersions []*string `locationName:"supportedOsVersions" min:"1" type:"list"` + // The tags of the component. Tags map[string]*string `locationName:"tags" min:"1" type:"map"` @@ -5552,6 +5590,9 @@ func (s *CreateComponentInput) Validate() error { if s.SemanticVersion == nil { invalidParams.Add(request.NewErrParamRequired("SemanticVersion")) } + if s.SupportedOsVersions != nil && len(s.SupportedOsVersions) < 1 { + invalidParams.Add(request.NewErrParamMinLen("SupportedOsVersions", 1)) + } if s.Tags != nil && len(s.Tags) < 1 { invalidParams.Add(request.NewErrParamMinLen("Tags", 1)) } @@ -5610,6 +5651,12 @@ func (s *CreateComponentInput) SetSemanticVersion(v string) *CreateComponentInpu return s } +// SetSupportedOsVersions sets the SupportedOsVersions field's value. +func (s *CreateComponentInput) SetSupportedOsVersions(v []*string) *CreateComponentInput { + s.SupportedOsVersions = v + return s +} + // SetTags sets the Tags field's value. func (s *CreateComponentInput) SetTags(v map[string]*string) *CreateComponentInput { s.Tags = v diff --git a/vendor/github.com/aws/aws-sdk-go/service/lightsail/api.go b/vendor/github.com/aws/aws-sdk-go/service/lightsail/api.go index 1aacad6e2d3..320025d3071 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/lightsail/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/lightsail/api.go @@ -599,11 +599,11 @@ func (c *Lightsail) CloseInstancePublicPortsRequest(input *CloseInstancePublicPo // CloseInstancePublicPorts API operation for Amazon Lightsail. // -// Closes the public ports on a specific Amazon Lightsail instance. +// Closes ports for a specific Amazon Lightsail instance. // -// The close instance public ports operation supports tag-based access control -// via resource tags applied to the resource identified by instance name. For -// more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// The CloseInstancePublicPorts action supports tag-based access control via +// resource tags applied to the resource identified by instanceName. For more +// information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -6762,7 +6762,9 @@ func (c *Lightsail) GetInstancePortStatesRequest(input *GetInstancePortStatesInp // GetInstancePortStates API operation for Amazon Lightsail. // -// Returns the port states for a specific virtual private server, or instance. +// Returns the firewall port states for a specific Amazon Lightsail instance, +// the IP addresses allowed to connect to the instance through the ports, and +// the protocol. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -10020,11 +10022,12 @@ func (c *Lightsail) OpenInstancePublicPortsRequest(input *OpenInstancePublicPort // OpenInstancePublicPorts API operation for Amazon Lightsail. // -// Adds public ports to an Amazon Lightsail instance. +// Opens ports for a specific Amazon Lightsail instance, and specifies the IP +// addresses allowed to connect to the instance through the ports, and the protocol. // -// The open instance public ports operation supports tag-based access control -// via resource tags applied to the resource identified by instance name. For -// more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// The OpenInstancePublicPorts action supports tag-based access control via +// resource tags applied to the resource identified by instanceName. For more +// information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -10345,12 +10348,16 @@ func (c *Lightsail) PutInstancePublicPortsRequest(input *PutInstancePublicPortsI // PutInstancePublicPorts API operation for Amazon Lightsail. // -// Sets the specified open ports for an Amazon Lightsail instance, and closes -// all ports for every protocol not included in the current request. +// Opens ports for a specific Amazon Lightsail instance, and specifies the IP +// addresses allowed to connect to the instance through the ports, and the protocol. +// This action also closes all currently open ports that are not included in +// the request. Include all of the ports and the protocols you want to open +// in your PutInstancePublicPortsrequest. Or use the OpenInstancePublicPorts +// action to open ports without closing currently open ports. // -// The put instance public ports operation supports tag-based access control -// via resource tags applied to the resource identified by instance name. For -// more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// The PutInstancePublicPorts action supports tag-based access control via resource +// tags applied to the resource identified by instanceName. For more information, +// see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -10774,8 +10781,8 @@ func (c *Lightsail) SendContactMethodVerificationRequest(input *SendContactMetho // SendContactMethodVerification API operation for Amazon Lightsail. // -// Sends a verification request to an email contact method to ensure it’s -// owned by the requester. SMS contact methods don’t need to be verified. +// Sends a verification request to an email contact method to ensure it's owned +// by the requester. SMS contact methods don't need to be verified. // // A contact method is used to send you notifications about your Amazon Lightsail // resources. You can add one email address and one mobile phone number contact @@ -12459,35 +12466,35 @@ type Alarm struct { // // An alarm has the following possible states: // - // * ALARM — The metric is outside of the defined threshold. + // * ALARM - The metric is outside of the defined threshold. // - // * INSUFFICIENT_DATA — The alarm has just started, the metric is not - // available, or not enough data is available for the metric to determine - // the alarm state. + // * INSUFFICIENT_DATA - The alarm has just started, the metric is not available, + // or not enough data is available for the metric to determine the alarm + // state. // - // * OK — The metric is within the defined threshold. + // * OK - The metric is within the defined threshold. State *string `locationName:"state" type:"string" enum:"AlarmState"` // The statistic for the metric associated with the alarm. // // The following statistics are available: // - // * Minimum — The lowest value observed during the specified period. Use + // * Minimum - The lowest value observed during the specified period. Use // this value to determine low volumes of activity for your application. // - // * Maximum — The highest value observed during the specified period. - // Use this value to determine high volumes of activity for your application. + // * Maximum - The highest value observed during the specified period. Use + // this value to determine high volumes of activity for your application. // - // * Sum — All values submitted for the matching metric added together. - // You can use this statistic to determine the total volume of a metric. + // * Sum - All values submitted for the matching metric added together. You + // can use this statistic to determine the total volume of a metric. // - // * Average — The value of Sum / SampleCount during the specified period. + // * Average - The value of Sum / SampleCount during the specified period. // By comparing this statistic with the Minimum and Maximum values, you can // determine the full scope of a metric and how close the average use is // to the Minimum and Maximum values. This comparison helps you to know when // to increase or decrease your resources. // - // * SampleCount — The count, or number, of data points used for the statistical + // * SampleCount - The count, or number, of data points used for the statistical // calculation. Statistic *string `locationName:"statistic" type:"string" enum:"MetricStatistic"` @@ -12503,16 +12510,16 @@ type Alarm struct { // // An alarm can treat missing data in the following ways: // - // * breaching — Assume the missing data is not within the threshold. Missing + // * breaching - Assume the missing data is not within the threshold. Missing // data counts towards the number of times the metric is not within the threshold. // - // * notBreaching — Assume the missing data is within the threshold. Missing + // * notBreaching - Assume the missing data is within the threshold. Missing // data does not count towards the number of times the metric is not within // the threshold. // - // * ignore — Ignore the missing data. Maintains the current alarm state. + // * ignore - Ignore the missing data. Maintains the current alarm state. // - // * missing — Missing data is treated as missing. + // * missing - Missing data is treated as missing. TreatMissingData *string `locationName:"treatMissingData" type:"string" enum:"TreatMissingData"` // The unit of the metric associated with the alarm. @@ -12691,7 +12698,7 @@ type AllocateStaticIpOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -12783,7 +12790,7 @@ type AttachDiskOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -12867,7 +12874,7 @@ type AttachInstancesToLoadBalancerOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -12945,7 +12952,7 @@ type AttachLoadBalancerTlsCertificateOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. // // These SSL/TLS certificates are only usable by Lightsail load balancers. You @@ -13025,7 +13032,7 @@ type AttachStaticIpOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -13484,12 +13491,12 @@ func (s *Bundle) SetTransferPerMonthInGb(v int64) *Bundle { type CloseInstancePublicPortsInput struct { _ struct{} `type:"structure"` - // The name of the instance on which you're attempting to close the public ports. + // The name of the instance for which to close ports. // // InstanceName is a required field InstanceName *string `locationName:"instanceName" type:"string" required:"true"` - // Information about the public port you are trying to close. + // An object to describe the ports to close for the specified instance. // // PortInfo is a required field PortInfo *PortInfo `locationName:"portInfo" type:"structure" required:"true"` @@ -13514,6 +13521,11 @@ func (s *CloseInstancePublicPortsInput) Validate() error { if s.PortInfo == nil { invalidParams.Add(request.NewErrParamRequired("PortInfo")) } + if s.PortInfo != nil { + if err := s.PortInfo.Validate(); err != nil { + invalidParams.AddNested("PortInfo", err.(request.ErrInvalidParams)) + } + } if invalidParams.Len() > 0 { return invalidParams @@ -13536,9 +13548,9 @@ func (s *CloseInstancePublicPortsInput) SetPortInfo(v *PortInfo) *CloseInstanceP type CloseInstancePublicPortsOutput struct { _ struct{} `type:"structure"` - // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected - // by the request. + // An object that describes the result of the action, such as the status of + // the request, the timestamp of the request, and the resources affected by + // the request. Operation *Operation `locationName:"operation" type:"structure"` } @@ -13729,12 +13741,12 @@ type ContactMethod struct { // // A contact method has the following possible status: // - // * PendingVerification — The contact method has not yet been verified, + // * PendingVerification - The contact method has not yet been verified, // and the verification has not yet expired. // - // * Valid — The contact method has been verified. + // * Valid - The contact method has been verified. // - // * InValid — An attempt was made to verify the contact method, but the + // * InValid - An attempt was made to verify the contact method, but the // verification has expired. Status *string `locationName:"status" type:"string" enum:"ContactMethodStatus"` @@ -13933,7 +13945,7 @@ type CopySnapshotOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -14009,7 +14021,7 @@ type CreateCloudFormationStackOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -14041,7 +14053,7 @@ type CreateContactMethodInput struct { // Phone numbers that follow this format can have a maximum of 15 digits, and // they are prefixed with the plus character (+) and the country code. For example, // a U.S. phone number in E.164 format would be specified as +1XXX5550100. For - // more information, see E.164 (https://en.wikipedia.org/wiki/E.164) in Wikipedia. + // more information, see E.164 (https://en.wikipedia.org/wiki/E.164) on Wikipedia. // // ContactEndpoint is a required field ContactEndpoint *string `locationName:"contactEndpoint" min:"1" type:"string" required:"true"` @@ -14119,7 +14131,7 @@ type CreateContactMethodOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -14320,7 +14332,7 @@ type CreateDiskFromSnapshotOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -14446,7 +14458,7 @@ type CreateDiskOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -14546,7 +14558,7 @@ type CreateDiskSnapshotOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -14625,7 +14637,7 @@ type CreateDomainEntryOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operation *Operation `locationName:"operation" type:"structure"` } @@ -14704,7 +14716,7 @@ type CreateDomainOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operation *Operation `locationName:"operation" type:"structure"` } @@ -14792,7 +14804,7 @@ type CreateInstanceSnapshotOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -15028,7 +15040,7 @@ type CreateInstancesFromSnapshotOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -15214,7 +15226,7 @@ type CreateInstancesOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -15292,7 +15304,7 @@ type CreateKeyPairOutput struct { KeyPair *KeyPair `locationName:"keyPair" type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operation *Operation `locationName:"operation" type:"structure"` @@ -15397,6 +15409,9 @@ func (s *CreateLoadBalancerInput) Validate() error { if s.InstancePort == nil { invalidParams.Add(request.NewErrParamRequired("InstancePort")) } + if s.InstancePort != nil && *s.InstancePort < -1 { + invalidParams.Add(request.NewErrParamMinValue("InstancePort", -1)) + } if s.LoadBalancerName == nil { invalidParams.Add(request.NewErrParamRequired("LoadBalancerName")) } @@ -15453,7 +15468,7 @@ type CreateLoadBalancerOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -15572,7 +15587,7 @@ type CreateLoadBalancerTlsCertificateOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -15747,7 +15762,7 @@ type CreateRelationalDatabaseFromSnapshotOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -15999,7 +16014,7 @@ type CreateRelationalDatabaseOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -16093,7 +16108,7 @@ type CreateRelationalDatabaseSnapshotOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -16156,7 +16171,7 @@ type DeleteAlarmOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -16236,7 +16251,7 @@ type DeleteAutoSnapshotOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -16302,7 +16317,7 @@ type DeleteContactMethodOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -16375,7 +16390,7 @@ type DeleteDiskOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -16438,7 +16453,7 @@ type DeleteDiskSnapshotOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -16515,7 +16530,7 @@ type DeleteDomainEntryOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operation *Operation `locationName:"operation" type:"structure"` } @@ -16578,7 +16593,7 @@ type DeleteDomainOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operation *Operation `locationName:"operation" type:"structure"` } @@ -16651,7 +16666,7 @@ type DeleteInstanceOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -16714,7 +16729,7 @@ type DeleteInstanceSnapshotOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -16777,7 +16792,7 @@ type DeleteKeyPairOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operation *Operation `locationName:"operation" type:"structure"` } @@ -16840,7 +16855,7 @@ type DeleteKnownHostKeysOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -16903,7 +16918,7 @@ type DeleteLoadBalancerOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -16993,7 +17008,7 @@ type DeleteLoadBalancerTlsCertificateOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -17091,7 +17106,7 @@ type DeleteRelationalDatabaseOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -17154,7 +17169,7 @@ type DeleteRelationalDatabaseSnapshotOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -17251,7 +17266,7 @@ type DetachDiskOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -17329,7 +17344,7 @@ type DetachInstancesFromLoadBalancerOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -17392,7 +17407,7 @@ type DetachStaticIpOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -17469,7 +17484,7 @@ type DisableAddOnOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -18235,7 +18250,7 @@ type EnableAddOnOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -18298,7 +18313,7 @@ type ExportSnapshotOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -19556,44 +19571,43 @@ type GetInstanceMetricDataInput struct { // Valid instance metric names are listed below, along with the most useful // statistics to include in your request, and the published unit value. // - // * CPUUtilization — The percentage of allocated compute units that are + // * CPUUtilization - The percentage of allocated compute units that are // currently in use on the instance. This metric identifies the processing // power to run the applications on the instance. Tools in your operating // system can show a lower percentage than Lightsail when the instance is // not allocated a full processor core. Statistics: The most useful statistics // are Maximum and Average. Unit: The published unit is Percent. // - // * NetworkIn — The number of bytes received on all network interfaces - // by the instance. This metric identifies the volume of incoming network - // traffic to the instance. The number reported is the number of bytes received - // during the period. Because this metric is reported in 5-minute intervals, - // divide the reported number by 300 to find Bytes/second. Statistics: The - // most useful statistic is Sum. Unit: The published unit is Bytes. + // * NetworkIn - The number of bytes received on all network interfaces by + // the instance. This metric identifies the volume of incoming network traffic + // to the instance. The number reported is the number of bytes received during + // the period. Because this metric is reported in 5-minute intervals, divide + // the reported number by 300 to find Bytes/second. Statistics: The most + // useful statistic is Sum. Unit: The published unit is Bytes. // - // * NetworkOut — The number of bytes sent out on all network interfaces + // * NetworkOut - The number of bytes sent out on all network interfaces // by the instance. This metric identifies the volume of outgoing network // traffic from the instance. The number reported is the number of bytes // sent during the period. Because this metric is reported in 5-minute intervals, // divide the reported number by 300 to find Bytes/second. Statistics: The // most useful statistic is Sum. Unit: The published unit is Bytes. // - // * StatusCheckFailed — Reports whether the instance passed or failed - // both the instance status check and the system status check. This metric - // can be either 0 (passed) or 1 (failed). This metric data is available - // in 1-minute (60 seconds) granularity. Statistics: The most useful statistic - // is Sum. Unit: The published unit is Count. + // * StatusCheckFailed - Reports whether the instance passed or failed both + // the instance status check and the system status check. This metric can + // be either 0 (passed) or 1 (failed). This metric data is available in 1-minute + // (60 seconds) granularity. Statistics: The most useful statistic is Sum. + // Unit: The published unit is Count. // - // * StatusCheckFailed_Instance — Reports whether the instance passed or + // * StatusCheckFailed_Instance - Reports whether the instance passed or // failed the instance status check. This metric can be either 0 (passed) // or 1 (failed). This metric data is available in 1-minute (60 seconds) // granularity. Statistics: The most useful statistic is Sum. Unit: The published // unit is Count. // - // * StatusCheckFailed_System — Reports whether the instance passed or - // failed the system status check. This metric can be either 0 (passed) or - // 1 (failed). This metric data is available in 1-minute (60 seconds) granularity. - // Statistics: The most useful statistic is Sum. Unit: The published unit - // is Count. + // * StatusCheckFailed_System - Reports whether the instance passed or failed + // the system status check. This metric can be either 0 (passed) or 1 (failed). + // This metric data is available in 1-minute (60 seconds) granularity. Statistics: + // The most useful statistic is Sum. Unit: The published unit is Count. // // MetricName is a required field MetricName *string `locationName:"metricName" type:"string" required:"true" enum:"InstanceMetricName"` @@ -19616,30 +19630,30 @@ type GetInstanceMetricDataInput struct { // // The following statistics are available: // - // * Minimum — The lowest value observed during the specified period. Use + // * Minimum - The lowest value observed during the specified period. Use // this value to determine low volumes of activity for your application. // - // * Maximum — The highest value observed during the specified period. - // Use this value to determine high volumes of activity for your application. + // * Maximum - The highest value observed during the specified period. Use + // this value to determine high volumes of activity for your application. // - // * Sum — All values submitted for the matching metric added together. - // You can use this statistic to determine the total volume of a metric. + // * Sum - All values submitted for the matching metric added together. You + // can use this statistic to determine the total volume of a metric. // - // * Average — The value of Sum / SampleCount during the specified period. + // * Average - The value of Sum / SampleCount during the specified period. // By comparing this statistic with the Minimum and Maximum values, you can // determine the full scope of a metric and how close the average use is // to the Minimum and Maximum values. This comparison helps you to know when // to increase or decrease your resources. // - // * SampleCount — The count, or number, of data points used for the statistical + // * SampleCount - The count, or number, of data points used for the statistical // calculation. // // Statistics is a required field Statistics []*string `locationName:"statistics" type:"list" required:"true"` // The unit for the metric data request. Valid units depend on the metric data - // being required. For the valid units with each available metric, see the metricName - // parameter. + // being requested. For the valid units to specify with each available metric, + // see the metricName parameter. // // Unit is a required field Unit *string `locationName:"unit" type:"string" required:"true" enum:"MetricUnit"` @@ -19790,7 +19804,7 @@ func (s *GetInstanceOutput) SetInstance(v *Instance) *GetInstanceOutput { type GetInstancePortStatesInput struct { _ struct{} `type:"structure"` - // The name of the instance. + // The name of the instance for which to return firewall port states. // // InstanceName is a required field InstanceName *string `locationName:"instanceName" type:"string" required:"true"` @@ -19828,7 +19842,8 @@ func (s *GetInstancePortStatesInput) SetInstanceName(v string) *GetInstancePortS type GetInstancePortStatesOutput struct { _ struct{} `type:"structure"` - // Information about the port states resulting from your request. + // An array of objects that describe the firewall port states for the specified + // instance. PortStates []*InstancePortState `locationName:"portStates" type:"list"` } @@ -20281,73 +20296,73 @@ type GetLoadBalancerMetricDataInput struct { // Valid load balancer metric names are listed below, along with the most useful // statistics to include in your request, and the published unit value. // - // * ClientTLSNegotiationErrorCount — The number of TLS connections initiated + // * ClientTLSNegotiationErrorCount - The number of TLS connections initiated // by the client that did not establish a session with the load balancer // due to a TLS error generated by the load balancer. Possible causes include // a mismatch of ciphers or protocols. Statistics: The most useful statistic // is Sum. Unit: The published unit is Count. // - // * HealthyHostCount — The number of target instances that are considered + // * HealthyHostCount - The number of target instances that are considered // healthy. Statistics: The most useful statistic are Average, Minimum, and // Maximum. Unit: The published unit is Count. // - // * HTTPCode_Instance_2XX_Count — The number of HTTP 2XX response codes + // * HTTPCode_Instance_2XX_Count - The number of HTTP 2XX response codes // generated by the target instances. This does not include any response // codes generated by the load balancer. Statistics: The most useful statistic // is Sum. Note that Minimum, Maximum, and Average all return 1. Unit: The // published unit is Count. // - // * HTTPCode_Instance_3XX_Count — The number of HTTP 3XX response codes + // * HTTPCode_Instance_3XX_Count - The number of HTTP 3XX response codes // generated by the target instances. This does not include any response // codes generated by the load balancer. Statistics: The most useful statistic // is Sum. Note that Minimum, Maximum, and Average all return 1. Unit: The // published unit is Count. // - // * HTTPCode_Instance_4XX_Count — The number of HTTP 4XX response codes + // * HTTPCode_Instance_4XX_Count - The number of HTTP 4XX response codes // generated by the target instances. This does not include any response // codes generated by the load balancer. Statistics: The most useful statistic // is Sum. Note that Minimum, Maximum, and Average all return 1. Unit: The // published unit is Count. // - // * HTTPCode_Instance_5XX_Count — The number of HTTP 5XX response codes + // * HTTPCode_Instance_5XX_Count - The number of HTTP 5XX response codes // generated by the target instances. This does not include any response // codes generated by the load balancer. Statistics: The most useful statistic // is Sum. Note that Minimum, Maximum, and Average all return 1. Unit: The // published unit is Count. // - // * HTTPCode_LB_4XX_Count — The number of HTTP 4XX client error codes - // that originated from the load balancer. Client errors are generated when - // requests are malformed or incomplete. These requests were not received - // by the target instance. This count does not include response codes generated - // by the target instances. Statistics: The most useful statistic is Sum. - // Note that Minimum, Maximum, and Average all return 1. Unit: The published - // unit is Count. + // * HTTPCode_LB_4XX_Count - The number of HTTP 4XX client error codes that + // originated from the load balancer. Client errors are generated when requests + // are malformed or incomplete. These requests were not received by the target + // instance. This count does not include response codes generated by the + // target instances. Statistics: The most useful statistic is Sum. Note that + // Minimum, Maximum, and Average all return 1. Unit: The published unit is + // Count. // - // * HTTPCode_LB_5XX_Count — The number of HTTP 5XX server error codes - // that originated from the load balancer. This does not include any response + // * HTTPCode_LB_5XX_Count - The number of HTTP 5XX server error codes that + // originated from the load balancer. This does not include any response // codes generated by the target instance. This metric is reported if there // are no healthy instances attached to the load balancer, or if the request // rate exceeds the capacity of the instances (spillover) or the load balancer. // Statistics: The most useful statistic is Sum. Note that Minimum, Maximum, // and Average all return 1. Unit: The published unit is Count. // - // * InstanceResponseTime — The time elapsed, in seconds, after the request + // * InstanceResponseTime - The time elapsed, in seconds, after the request // leaves the load balancer until a response from the target instance is // received. Statistics: The most useful statistic is Average. Unit: The // published unit is Seconds. // - // * RejectedConnectionCount — The number of connections that were rejected + // * RejectedConnectionCount - The number of connections that were rejected // because the load balancer had reached its maximum number of connections. // Statistics: The most useful statistic is Sum. Unit: The published unit // is Count. // - // * RequestCount — The number of requests processed over IPv4. This count + // * RequestCount - The number of requests processed over IPv4. This count // includes only the requests with a response generated by a target instance // of the load balancer. Statistics: The most useful statistic is Sum. Note // that Minimum, Maximum, and Average all return 1. Unit: The published unit // is Count. // - // * UnhealthyHostCount — The number of target instances that are considered + // * UnhealthyHostCount - The number of target instances that are considered // unhealthy. Statistics: The most useful statistic are Average, Minimum, // and Maximum. Unit: The published unit is Count. // @@ -20368,22 +20383,22 @@ type GetLoadBalancerMetricDataInput struct { // // The following statistics are available: // - // * Minimum — The lowest value observed during the specified period. Use + // * Minimum - The lowest value observed during the specified period. Use // this value to determine low volumes of activity for your application. // - // * Maximum — The highest value observed during the specified period. - // Use this value to determine high volumes of activity for your application. + // * Maximum - The highest value observed during the specified period. Use + // this value to determine high volumes of activity for your application. // - // * Sum — All values submitted for the matching metric added together. - // You can use this statistic to determine the total volume of a metric. + // * Sum - All values submitted for the matching metric added together. You + // can use this statistic to determine the total volume of a metric. // - // * Average — The value of Sum / SampleCount during the specified period. + // * Average - The value of Sum / SampleCount during the specified period. // By comparing this statistic with the Minimum and Maximum values, you can // determine the full scope of a metric and how close the average use is // to the Minimum and Maximum values. This comparison helps you to know when // to increase or decrease your resources. // - // * SampleCount — The count, or number, of data points used for the statistical + // * SampleCount - The count, or number, of data points used for the statistical // calculation. // // Statistics is a required field @@ -20765,7 +20780,7 @@ type GetOperationOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operation *Operation `locationName:"operation" type:"structure"` } @@ -20857,7 +20872,7 @@ type GetOperationsForResourceOutput struct { NextPageToken *string `locationName:"nextPageToken" type:"string"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -20929,7 +20944,7 @@ type GetOperationsOutput struct { NextPageToken *string `locationName:"nextPageToken" type:"string"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -21617,27 +21632,27 @@ type GetRelationalDatabaseMetricDataInput struct { // All relational database metric data is available in 1-minute (60 seconds) // granularity. // - // * CPUUtilization — The percentage of CPU utilization currently in use + // * CPUUtilization - The percentage of CPU utilization currently in use // on the database. Statistics: The most useful statistics are Maximum and // Average. Unit: The published unit is Percent. // - // * DatabaseConnections — The number of database connections in use. Statistics: + // * DatabaseConnections - The number of database connections in use. Statistics: // The most useful statistics are Maximum and Sum. Unit: The published unit // is Count. // - // * DiskQueueDepth — The number of outstanding IOs (read/write requests) + // * DiskQueueDepth - The number of outstanding IOs (read/write requests) // that are waiting to access the disk. Statistics: The most useful statistic // is Sum. Unit: The published unit is Count. // - // * FreeStorageSpace — The amount of available storage space. Statistics: + // * FreeStorageSpace - The amount of available storage space. Statistics: // The most useful statistic is Sum. Unit: The published unit is Bytes. // - // * NetworkReceiveThroughput — The incoming (Receive) network traffic - // on the database, including both customer database traffic and AWS traffic + // * NetworkReceiveThroughput - The incoming (Receive) network traffic on + // the database, including both customer database traffic and AWS traffic // used for monitoring and replication. Statistics: The most useful statistic // is Average. Unit: The published unit is Bytes/Second. // - // * NetworkTransmitThroughput — The outgoing (Transmit) network traffic + // * NetworkTransmitThroughput - The outgoing (Transmit) network traffic // on the database, including both customer database traffic and AWS traffic // used for monitoring and replication. Statistics: The most useful statistic // is Average. Unit: The published unit is Bytes/Second. @@ -21675,22 +21690,22 @@ type GetRelationalDatabaseMetricDataInput struct { // // The following statistics are available: // - // * Minimum — The lowest value observed during the specified period. Use + // * Minimum - The lowest value observed during the specified period. Use // this value to determine low volumes of activity for your application. // - // * Maximum — The highest value observed during the specified period. - // Use this value to determine high volumes of activity for your application. + // * Maximum - The highest value observed during the specified period. Use + // this value to determine high volumes of activity for your application. // - // * Sum — All values submitted for the matching metric added together. - // You can use this statistic to determine the total volume of a metric. + // * Sum - All values submitted for the matching metric added together. You + // can use this statistic to determine the total volume of a metric. // - // * Average — The value of Sum / SampleCount during the specified period. + // * Average - The value of Sum / SampleCount during the specified period. // By comparing this statistic with the Minimum and Maximum values, you can // determine the full scope of a metric and how close the average use is // to the Minimum and Maximum values. This comparison helps you to know when // to increase or decrease your resources. // - // * SampleCount — The count, or number, of data points used for the statistical + // * SampleCount - The count, or number, of data points used for the statistical // calculation. // // Statistics is a required field @@ -22401,7 +22416,7 @@ type ImportKeyPairOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operation *Operation `locationName:"operation" type:"structure"` } @@ -22763,13 +22778,20 @@ type InstanceEntry struct { // // The following configuration options are available: // - // * DEFAULT — Use the default firewall settings from the image. + // * DEFAULT - Use the default firewall settings from the Lightsail instance + // blueprint. + // + // * INSTANCE - Use the configured firewall settings from the source Lightsail + // instance. // - // * INSTANCE — Use the firewall settings from the source Lightsail instance. + // * NONE - Use the default Amazon EC2 security group. // - // * NONE — Default to Amazon EC2. + // * CLOSED - All ports closed. // - // * CLOSED — All ports closed. + // If you configured lightsail-connect as a cidrListAliases on your instance, + // or if you chose to allow the Lightsail browser-based SSH or RDP clients to + // connect to your instance, that configuration is not carried over to your + // new Amazon EC2 instance. // // PortInfoSource is a required field PortInfoSource *string `locationName:"portInfoSource" type:"string" required:"true" enum:"PortInfoSourceType"` @@ -23019,26 +23041,55 @@ func (s *InstanceNetworking) SetPorts(v []*InstancePortInfo) *InstanceNetworking return s } -// Describes information about the instance ports. +// Describes information about ports for an Amazon Lightsail instance. type InstancePortInfo struct { _ struct{} `type:"structure"` // The access direction (inbound or outbound). + // + // Lightsail currently supports only inbound access direction. AccessDirection *string `locationName:"accessDirection" type:"string" enum:"AccessDirection"` - // The location from which access is allowed (e.g., Anywhere (0.0.0.0/0)). + // The location from which access is allowed. For example, Anywhere (0.0.0.0/0), + // or Custom if a specific IP address or range of IP addresses is allowed. AccessFrom *string `locationName:"accessFrom" type:"string"` // The type of access (Public or Private). AccessType *string `locationName:"accessType" type:"string" enum:"PortAccessType"` - // The common name. + // An alias that defines access for a preconfigured range of IP addresses. + // + // The only alias currently supported is lightsail-connect, which allows IP + // addresses of the browser-based RDP/SSH client in the Lightsail console to + // connect to your instance. + CidrListAliases []*string `locationName:"cidrListAliases" type:"list"` + + // The IP address, or range of IP addresses in CIDR notation, that are allowed + // to connect to an instance through the ports, and the protocol. Lightsail + // supports IPv4 addresses. + // + // For more information about CIDR block notation, see Classless Inter-Domain + // Routing (https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation) + // on Wikipedia. + Cidrs []*string `locationName:"cidrs" type:"list"` + + // The common name of the port information. CommonName *string `locationName:"commonName" type:"string"` - // The first port in the range. + // The first port in a range of open ports on an instance. + // + // Allowed ports: + // + // * TCP and UDP - 0 to 65535 + // + // * ICMP - 8 (to configure Ping) Ping is the only communication supported + // through the ICMP protocol in Lightsail. To configure ping, specify the + // fromPort parameter as 8, and the toPort parameter as -1. FromPort *int64 `locationName:"fromPort" type:"integer"` - // The protocol being used. Can be one of the following. + // The IP protocol name. + // + // The name can be one of the following: // // * tcp - Transmission Control Protocol (TCP) provides reliable, ordered, // and error-checked delivery of streamed data between applications running @@ -23056,9 +23107,24 @@ type InstancePortInfo struct { // can use UDP, which provides a connectionless datagram service that emphasizes // reduced latency over reliability. If you do require reliable data stream // service, use TCP instead. + // + // * icmp - Internet Control Message Protocol (ICMP) is used to send error + // messages and operational information indicating success or failure when + // communicating with an instance. For example, an error is indicated when + // an instance could not be reached. Ping is the only communication supported + // through the ICMP protocol in Lightsail. To configure ping, specify the + // fromPort parameter as 8, and the toPort parameter as -1. Protocol *string `locationName:"protocol" type:"string" enum:"NetworkProtocol"` - // The last port in the range. + // The last port in a range of open ports on an instance. + // + // Allowed ports: + // + // * TCP and UDP - 0 to 65535 + // + // * ICMP - -1 (to configure Ping) Ping is the only communication supported + // through the ICMP protocol in Lightsail. To configure ping, specify the + // fromPort parameter as 8, and the toPort parameter as -1. ToPort *int64 `locationName:"toPort" type:"integer"` } @@ -23090,6 +23156,18 @@ func (s *InstancePortInfo) SetAccessType(v string) *InstancePortInfo { return s } +// SetCidrListAliases sets the CidrListAliases field's value. +func (s *InstancePortInfo) SetCidrListAliases(v []*string) *InstancePortInfo { + s.CidrListAliases = v + return s +} + +// SetCidrs sets the Cidrs field's value. +func (s *InstancePortInfo) SetCidrs(v []*string) *InstancePortInfo { + s.Cidrs = v + return s +} + // SetCommonName sets the CommonName field's value. func (s *InstancePortInfo) SetCommonName(v string) *InstancePortInfo { s.CommonName = &v @@ -23114,14 +23192,41 @@ func (s *InstancePortInfo) SetToPort(v int64) *InstancePortInfo { return s } -// Describes the port state. +// Describes open ports on an instance, the IP addresses allowed to connect +// to the instance through the ports, and the protocol. type InstancePortState struct { _ struct{} `type:"structure"` - // The first port in the range. + // An alias that defines access for a preconfigured range of IP addresses. + // + // The only alias currently supported is lightsail-connect, which allows IP + // addresses of the browser-based RDP/SSH client in the Lightsail console to + // connect to your instance. + CidrListAliases []*string `locationName:"cidrListAliases" type:"list"` + + // The IP address, or range of IP addresses in CIDR notation, that are allowed + // to connect to an instance through the ports, and the protocol. Lightsail + // supports IPv4 addresses. + // + // For more information about CIDR block notation, see Classless Inter-Domain + // Routing (https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation) + // on Wikipedia. + Cidrs []*string `locationName:"cidrs" type:"list"` + + // The first port in a range of open ports on an instance. + // + // Allowed ports: + // + // * TCP and UDP - 0 to 65535 + // + // * ICMP - 8 (to configure Ping) Ping is the only communication supported + // through the ICMP protocol in Lightsail. To configure ping, specify the + // fromPort parameter as 8, and the toPort parameter as -1. FromPort *int64 `locationName:"fromPort" type:"integer"` - // The protocol being used. Can be one of the following. + // The IP protocol name. + // + // The name can be one of the following: // // * tcp - Transmission Control Protocol (TCP) provides reliable, ordered, // and error-checked delivery of streamed data between applications running @@ -23139,12 +23244,29 @@ type InstancePortState struct { // can use UDP, which provides a connectionless datagram service that emphasizes // reduced latency over reliability. If you do require reliable data stream // service, use TCP instead. + // + // * icmp - Internet Control Message Protocol (ICMP) is used to send error + // messages and operational information indicating success or failure when + // communicating with an instance. For example, an error is indicated when + // an instance could not be reached. Ping is the only communication supported + // through the ICMP protocol in Lightsail. To configure ping, specify the + // fromPort parameter as 8, and the toPort parameter as -1. Protocol *string `locationName:"protocol" type:"string" enum:"NetworkProtocol"` // Specifies whether the instance port is open or closed. + // + // The port state for Lightsail instances is always open. State *string `locationName:"state" type:"string" enum:"PortState"` - // The last port in the range. + // The last port in a range of open ports on an instance. + // + // Allowed ports: + // + // * TCP and UDP - 0 to 65535 + // + // * ICMP - -1 (to configure Ping) Ping is the only communication supported + // through the ICMP protocol in Lightsail. To configure ping, specify the + // fromPort parameter as 8, and the toPort parameter as -1. ToPort *int64 `locationName:"toPort" type:"integer"` } @@ -23158,6 +23280,18 @@ func (s InstancePortState) GoString() string { return s.String() } +// SetCidrListAliases sets the CidrListAliases field's value. +func (s *InstancePortState) SetCidrListAliases(v []*string) *InstancePortState { + s.CidrListAliases = v + return s +} + +// SetCidrs sets the Cidrs field's value. +func (s *InstancePortState) SetCidrs(v []*string) *InstancePortState { + s.Cidrs = v + return s +} + // SetFromPort sets the FromPort field's value. func (s *InstancePortState) SetFromPort(v int64) *InstancePortState { s.FromPort = &v @@ -24477,12 +24611,12 @@ func (s *NotFoundException) RequestID() string { type OpenInstancePublicPortsInput struct { _ struct{} `type:"structure"` - // The name of the instance for which you want to open the public ports. + // The name of the instance for which to open ports. // // InstanceName is a required field InstanceName *string `locationName:"instanceName" type:"string" required:"true"` - // An array of key-value pairs containing information about the port mappings. + // An object to describe the ports to open for the specified instance. // // PortInfo is a required field PortInfo *PortInfo `locationName:"portInfo" type:"structure" required:"true"` @@ -24507,6 +24641,11 @@ func (s *OpenInstancePublicPortsInput) Validate() error { if s.PortInfo == nil { invalidParams.Add(request.NewErrParamRequired("PortInfo")) } + if s.PortInfo != nil { + if err := s.PortInfo.Validate(); err != nil { + invalidParams.AddNested("PortInfo", err.(request.ErrInvalidParams)) + } + } if invalidParams.Len() > 0 { return invalidParams @@ -24530,7 +24669,7 @@ type OpenInstancePublicPortsOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operation *Operation `locationName:"operation" type:"structure"` } @@ -24806,7 +24945,7 @@ type PeerVpcOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operation *Operation `locationName:"operation" type:"structure"` } @@ -24911,18 +25050,82 @@ func (s *PendingModifiedRelationalDatabaseValues) SetMasterUserPassword(v string return s } -// Describes information about the ports on your virtual private server (or -// instance). +// Describes ports to open on an instance, the IP addresses allowed to connect +// to the instance through the ports, and the protocol. type PortInfo struct { _ struct{} `type:"structure"` - // The first port in the range. + // An alias that defines access for a preconfigured range of IP addresses. + // + // The only alias currently supported is lightsail-connect, which allows IP + // addresses of the browser-based RDP/SSH client in the Lightsail console to + // connect to your instance. + CidrListAliases []*string `locationName:"cidrListAliases" type:"list"` + + // The IP address, or range of IP addresses in CIDR notation, that are allowed + // to connect to an instance through the ports, and the protocol. Lightsail + // supports IPv4 addresses. + // + // Examples: + // + // * To allow the IP address 192.0.2.44, specify 192.0.2.44 or 192.0.2.44/32. + // + // * To allow the IP addresses 192.0.2.0 to 192.0.2.255, specify 192.0.2.0/24. + // + // For more information about CIDR block notation, see Classless Inter-Domain + // Routing (https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation) + // on Wikipedia. + Cidrs []*string `locationName:"cidrs" type:"list"` + + // The first port in a range of open ports on an instance. + // + // Allowed ports: + // + // * TCP and UDP - 0 to 65535 + // + // * ICMP - 8 (to configure Ping) Ping is the only communication supported + // through the ICMP protocol in Lightsail. To configure ping, specify the + // fromPort parameter as 8, and the toPort parameter as -1. FromPort *int64 `locationName:"fromPort" type:"integer"` - // The protocol. + // The IP protocol name. + // + // The name can be one of the following: + // + // * tcp - Transmission Control Protocol (TCP) provides reliable, ordered, + // and error-checked delivery of streamed data between applications running + // on hosts communicating by an IP network. If you have an application that + // doesn't require reliable data stream service, use UDP instead. + // + // * all - All transport layer protocol types. For more general information, + // see Transport layer (https://en.wikipedia.org/wiki/Transport_layer) on + // Wikipedia. + // + // * udp - With User Datagram Protocol (UDP), computer applications can send + // messages (or datagrams) to other hosts on an Internet Protocol (IP) network. + // Prior communications are not required to set up transmission channels + // or data paths. Applications that don't require reliable data stream service + // can use UDP, which provides a connectionless datagram service that emphasizes + // reduced latency over reliability. If you do require reliable data stream + // service, use TCP instead. + // + // * icmp - Internet Control Message Protocol (ICMP) is used to send error + // messages and operational information indicating success or failure when + // communicating with an instance. For example, an error is indicated when + // an instance could not be reached. Ping is the only communication supported + // through the ICMP protocol in Lightsail. To configure ping, specify the + // fromPort parameter as 8, and the toPort parameter as -1. Protocol *string `locationName:"protocol" type:"string" enum:"NetworkProtocol"` - // The last port in the range. + // The last port in a range of open ports on an instance. + // + // Allowed ports: + // + // * TCP and UDP - 0 to 65535 + // + // * ICMP - -1 (to configure Ping) Ping is the only communication supported + // through the ICMP protocol in Lightsail. To configure ping, specify the + // fromPort parameter as 8, and the toPort parameter as -1. ToPort *int64 `locationName:"toPort" type:"integer"` } @@ -24936,6 +25139,34 @@ func (s PortInfo) GoString() string { return s.String() } +// Validate inspects the fields of the type to determine if they are valid. +func (s *PortInfo) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PortInfo"} + if s.FromPort != nil && *s.FromPort < -1 { + invalidParams.Add(request.NewErrParamMinValue("FromPort", -1)) + } + if s.ToPort != nil && *s.ToPort < -1 { + invalidParams.Add(request.NewErrParamMinValue("ToPort", -1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCidrListAliases sets the CidrListAliases field's value. +func (s *PortInfo) SetCidrListAliases(v []*string) *PortInfo { + s.CidrListAliases = v + return s +} + +// SetCidrs sets the Cidrs field's value. +func (s *PortInfo) SetCidrs(v []*string) *PortInfo { + s.Cidrs = v + return s +} + // SetFromPort sets the FromPort field's value. func (s *PortInfo) SetFromPort(v int64) *PortInfo { s.FromPort = &v @@ -25042,13 +25273,13 @@ type PutAlarmInput struct { // // An alarm has the following possible states: // - // * ALARM — The metric is outside of the defined threshold. + // * ALARM - The metric is outside of the defined threshold. // - // * INSUFFICIENT_DATA — The alarm has just started, the metric is not - // available, or not enough data is available for the metric to determine - // the alarm state. + // * INSUFFICIENT_DATA - The alarm has just started, the metric is not available, + // or not enough data is available for the metric to determine the alarm + // state. // - // * OK — The metric is within the defined threshold. + // * OK - The metric is within the defined threshold. // // When you specify a notification trigger, the ALARM state must be specified. // The INSUFFICIENT_DATA and OK states can be specified in addition to the ALARM @@ -25074,16 +25305,16 @@ type PutAlarmInput struct { // // An alarm can treat missing data in the following ways: // - // * breaching — Assume the missing data is not within the threshold. Missing + // * breaching - Assume the missing data is not within the threshold. Missing // data counts towards the number of times the metric is not within the threshold. // - // * notBreaching — Assume the missing data is within the threshold. Missing + // * notBreaching - Assume the missing data is within the threshold. Missing // data does not count towards the number of times the metric is not within // the threshold. // - // * ignore — Ignore the missing data. Maintains the current alarm state. + // * ignore - Ignore the missing data. Maintains the current alarm state. // - // * missing — Missing data is treated as missing. + // * missing - Missing data is treated as missing. // // If treatMissingData is not specified, the default behavior of missing is // used. @@ -25198,7 +25429,7 @@ type PutAlarmOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -25222,12 +25453,12 @@ func (s *PutAlarmOutput) SetOperations(v []*Operation) *PutAlarmOutput { type PutInstancePublicPortsInput struct { _ struct{} `type:"structure"` - // The Lightsail instance name of the public port(s) you are setting. + // The name of the instance for which to open ports. // // InstanceName is a required field InstanceName *string `locationName:"instanceName" type:"string" required:"true"` - // Specifies information about the public port(s). + // An array of objects to describe the ports to open for the specified instance. // // PortInfos is a required field PortInfos []*PortInfo `locationName:"portInfos" type:"list" required:"true"` @@ -25252,6 +25483,16 @@ func (s *PutInstancePublicPortsInput) Validate() error { if s.PortInfos == nil { invalidParams.Add(request.NewErrParamRequired("PortInfos")) } + if s.PortInfos != nil { + for i, v := range s.PortInfos { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PortInfos", i), err.(request.ErrInvalidParams)) + } + } + } if invalidParams.Len() > 0 { return invalidParams @@ -25275,7 +25516,7 @@ type PutInstancePublicPortsOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operation *Operation `locationName:"operation" type:"structure"` } @@ -25338,7 +25579,7 @@ type RebootInstanceOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -25401,7 +25642,7 @@ type RebootRelationalDatabaseOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -26336,7 +26577,7 @@ type ReleaseStaticIpOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -26432,7 +26673,7 @@ type SendContactMethodVerificationOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -26557,7 +26798,7 @@ type StartInstanceOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -26620,7 +26861,7 @@ type StartRelationalDatabaseOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -26795,7 +27036,7 @@ type StopInstanceOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -26868,7 +27109,7 @@ type StopRelationalDatabaseOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -26997,7 +27238,7 @@ type TagResourceOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -27030,13 +27271,13 @@ type TestAlarmInput struct { // // An alarm has the following possible states that can be tested: // - // * ALARM — The metric is outside of the defined threshold. + // * ALARM - The metric is outside of the defined threshold. // - // * INSUFFICIENT_DATA — The alarm has just started, the metric is not - // available, or not enough data is available for the metric to determine - // the alarm state. + // * INSUFFICIENT_DATA - The alarm has just started, the metric is not available, + // or not enough data is available for the metric to determine the alarm + // state. // - // * OK — The metric is within the defined threshold. + // * OK - The metric is within the defined threshold. // // State is a required field State *string `locationName:"state" type:"string" required:"true" enum:"AlarmState"` @@ -27084,7 +27325,7 @@ type TestAlarmOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -27185,7 +27426,7 @@ type UnpeerVpcOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operation *Operation `locationName:"operation" type:"structure"` } @@ -27272,7 +27513,7 @@ type UntagResourceOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -27349,7 +27590,7 @@ type UpdateDomainEntryOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -27443,7 +27684,7 @@ type UpdateLoadBalancerAttributeOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -27636,7 +27877,7 @@ type UpdateRelationalDatabaseOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -27713,7 +27954,7 @@ type UpdateRelationalDatabaseParametersOutput struct { _ struct{} `type:"structure"` // An array of objects that describe the result of the action, such as the status - // of the request, the time stamp of the request, and the resources affected + // of the request, the timestamp of the request, and the resources affected // by the request. Operations []*Operation `locationName:"operations" type:"list"` } @@ -28318,6 +28559,9 @@ const ( // NetworkProtocolUdp is a NetworkProtocol enum value NetworkProtocolUdp = "udp" + + // NetworkProtocolIcmp is a NetworkProtocol enum value + NetworkProtocolIcmp = "icmp" ) const ( diff --git a/vendor/github.com/aws/aws-sdk-go/service/route53/api.go b/vendor/github.com/aws/aws-sdk-go/service/route53/api.go index 38b6207b0bd..6a1693133e0 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/route53/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/route53/api.go @@ -15194,6 +15194,9 @@ const ( // CloudWatchRegionAfSouth1 is a CloudWatchRegion enum value CloudWatchRegionAfSouth1 = "af-south-1" + // CloudWatchRegionEuSouth1 is a CloudWatchRegion enum value + CloudWatchRegionEuSouth1 = "eu-south-1" + // CloudWatchRegionUsGovWest1 is a CloudWatchRegion enum value CloudWatchRegionUsGovWest1 = "us-gov-west-1" @@ -15415,6 +15418,9 @@ const ( // ResourceRecordSetRegionAfSouth1 is a ResourceRecordSetRegion enum value ResourceRecordSetRegionAfSouth1 = "af-south-1" + + // ResourceRecordSetRegionEuSouth1 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionEuSouth1 = "eu-south-1" ) const ( @@ -15522,4 +15528,7 @@ const ( // VPCRegionAfSouth1 is a VPCRegion enum value VPCRegionAfSouth1 = "af-south-1" + + // VPCRegionEuSouth1 is a VPCRegion enum value + VPCRegionEuSouth1 = "eu-south-1" ) diff --git a/vendor/github.com/aws/aws-sdk-go/service/sagemaker/api.go b/vendor/github.com/aws/aws-sdk-go/service/sagemaker/api.go index 0a749943fc0..9a7070b9b55 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/sagemaker/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/sagemaker/api.go @@ -306,10 +306,10 @@ func (c *SageMaker) CreateAppRequest(input *CreateAppInput) (req *request.Reques // CreateApp API operation for Amazon SageMaker Service. // -// Creates a running App for the specified UserProfile. Supported Apps are JupyterServer -// and KernelGateway. This operation is automatically invoked by Amazon SageMaker -// Amazon SageMaker Studio (Studio) upon access to the associated Studio Domain, -// and when new kernel configurations are selected by the user. A user may have +// Creates a running App for the specified UserProfile. Supported Apps are JupyterServer, +// KernelGateway, and TensorBoard. This operation is automatically invoked by +// Amazon SageMaker Studio upon access to the associated Studio Domain, and +// when new kernel configurations are selected by the user. A user may have // multiple Apps active simultaneously. Apps will automatically terminate and // be deleted when stopped from within Studio, or when the DeleteApp API is // manually called. UserProfiles are limited to 5 concurrently running Apps @@ -678,15 +678,15 @@ func (c *SageMaker) CreateDomainRequest(input *CreateDomainInput) (req *request. // CreateDomain API operation for Amazon SageMaker Service. // -// Creates a Domain for Amazon SageMaker Amazon SageMaker Studio (Studio), which -// can be accessed by end-users in a web browser. A Domain has an associated -// directory, list of authorized users, and a variety of security, application, -// policies, and Amazon Virtual Private Cloud configurations. An AWS account -// is limited to one Domain, per region. Users within a domain can share notebook -// files and other artifacts with each other. When a Domain is created, an Amazon -// Elastic File System (EFS) is also created for use by all of the users within -// the Domain. Each user receives a private home directory within the EFS for -// notebooks, Git repositories, and data files. +// Creates a Domain for Amazon SageMaker Studio, which can be accessed by end-users +// in a web browser. A Domain has an associated directory, list of authorized +// users, and a variety of security, application, policies, and Amazon Virtual +// Private Cloud configurations. An AWS account is limited to one Domain, per +// region. Users within a domain can share notebook files and other artifacts +// with each other. When a Domain is created, an Amazon Elastic File System +// (EFS) is also created for use by all of the users within the Domain. Each +// user receives a private home directory within the EFS for notebooks, Git +// repositories, and data files. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -1941,9 +1941,9 @@ func (c *SageMaker) CreatePresignedDomainUrlRequest(input *CreatePresignedDomain // // Creates a URL for a specified UserProfile in a Domain. When accessed in a // web browser, the user will be automatically signed in to Amazon SageMaker -// Amazon SageMaker Studio (Studio), and granted access to all of the Apps and -// files associated with that Amazon Elastic File System (EFS). This operation -// can only be called when AuthMode equals IAM. +// Studio, and granted access to all of the Apps and files associated with that +// Amazon Elastic File System (EFS). This operation can only be called when +// AuthMode equals IAM. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -2631,13 +2631,15 @@ func (c *SageMaker) CreateUserProfileRequest(input *CreateUserProfileInput) (req // CreateUserProfile API operation for Amazon SageMaker Service. // -// Creates a new user profile. A user profile represents a single user within -// a Domain, and is the main way to reference a "person" for the purposes of -// sharing, reporting and other user-oriented features. This entity is created -// during on-boarding. If an administrator invites a person by email or imports -// them from SSO, a new UserProfile is automatically created. This entity is -// the primary holder of settings for an individual user and has a reference -// to the user's private Amazon Elastic File System (EFS) home directory. +// Creates a user profile. A user profile represents a single user within a +// Domain, and is the main way to reference a "person" for the purposes of sharing, +// reporting and other user-oriented features. This entity is created during +// on-boarding to Amazon SageMaker Studio. If an administrator invites a person +// by email or imports them from SSO, a UserProfile is automatically created. +// +// This entity is the primary holder of settings for an individual user and, +// through the domain, has a reference to the user's private Amazon Elastic +// File System (EFS) home directory. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -3041,9 +3043,8 @@ func (c *SageMaker) DeleteDomainRequest(input *DeleteDomainInput) (req *request. // DeleteDomain API operation for Amazon SageMaker Service. // -// Used to delete a domain. If you on-boarded with IAM mode, you will need to -// delete your domain to on-board again using SSO. Use with caution. All of -// the members of the domain will lose access to their EFS volume, including +// Used to delete a domain. Use with caution. If RetentionPolicy is set to Delete, +// all of the members of the domain will lose access to their EFS volume, including // data, notebooks, and other artifacts. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -15820,7 +15821,8 @@ type CreateAppInput struct { // DomainId is a required field DomainId *string `type:"string" required:"true"` - // The instance type and quantity. + // The instance type and the Amazon Resource Name (ARN) of the SageMaker image + // created on the instance. ResourceSpec *ResourceSpec `type:"structure"` // Each tag consists of a key and an optional value. Tag keys must be unique @@ -16404,7 +16406,8 @@ type CreateDomainInput struct { // DomainName is a required field DomainName *string `type:"string" required:"true"` - // The AWS Key Management Service encryption key ID. + // The AWS Key Management Service (KMS) encryption key ID. Encryption with a + // customer master key (CMK) is not supported. HomeEfsFileSystemKmsKeyId *string `type:"string"` // Security setting to limit to a set of subnets. @@ -20788,7 +20791,7 @@ type DeleteDomainInput struct { // DomainId is a required field DomainId *string `type:"string" required:"true"` - // The retention policy for this domain, which specifies which resources will + // The retention policy for this domain, which specifies whether resources will // be retained after the Domain is deleted. By default, all resources are retained // (not automatically deleted). RetentionPolicy *RetentionPolicy `type:"structure"` @@ -21987,7 +21990,8 @@ type DescribeAppOutput struct { // The timestamp of the last user's activity. LastUserActivityTimestamp *time.Time `type:"timestamp"` - // The instance type and quantity. + // The instance type and the Amazon Resource Name (ARN) of the SageMaker image + // created on the instance. ResourceSpec *ResourceSpec `type:"structure"` // The status. @@ -26300,7 +26304,7 @@ type DescribeUserProfileOutput struct { // The failure reason. FailureReason *string `type:"string"` - // The homa Amazon Elastic File System (EFS) Uid. + // The home Amazon Elastic File System (EFS) Uid. HomeEfsFileSystemUid *string `type:"string"` // The last modified time. @@ -28817,11 +28821,6 @@ func (s *HumanTaskConfig) Validate() error { invalidParams.AddNested("AnnotationConsolidationConfig", err.(request.ErrInvalidParams)) } } - if s.UiConfig != nil { - if err := s.UiConfig.Validate(); err != nil { - invalidParams.AddNested("UiConfig", err.(request.ErrInvalidParams)) - } - } if invalidParams.Len() > 0 { return invalidParams @@ -30392,7 +30391,8 @@ func (s *IntegerParameterRangeSpecification) SetMinValue(v string) *IntegerParam type JupyterServerAppSettings struct { _ struct{} `type:"structure"` - // The instance type and quantity. + // The default instance type and the Amazon Resource Name (ARN) of the SageMaker + // image created on the instance. DefaultResourceSpec *ResourceSpec `type:"structure"` } @@ -30416,7 +30416,8 @@ func (s *JupyterServerAppSettings) SetDefaultResourceSpec(v *ResourceSpec) *Jupy type KernelGatewayAppSettings struct { _ struct{} `type:"structure"` - // The instance type and quantity. + // The default instance type and the Amazon Resource Name (ARN) of the SageMaker + // image created on the instance. DefaultResourceSpec *ResourceSpec `type:"structure"` } @@ -37134,6 +37135,11 @@ func (s *NestedFilters) SetNestedPropertyName(v string) *NestedFilters { type NetworkConfig struct { _ struct{} `type:"structure"` + // Whether to encrypt all communications between distributed processing jobs. + // Choose True to encrypt communications. Encryption provides greater security + // for distributed processing jobs, but the processing might take longer. + EnableInterContainerTrafficEncryption *bool `type:"boolean"` + // Whether to allow inbound and outbound network calls to and from the containers // used for the processing job. EnableNetworkIsolation *bool `type:"boolean"` @@ -37171,6 +37177,12 @@ func (s *NetworkConfig) Validate() error { return nil } +// SetEnableInterContainerTrafficEncryption sets the EnableInterContainerTrafficEncryption field's value. +func (s *NetworkConfig) SetEnableInterContainerTrafficEncryption(v bool) *NetworkConfig { + s.EnableInterContainerTrafficEncryption = &v + return s +} + // SetEnableNetworkIsolation sets the EnableNetworkIsolation field's value. func (s *NetworkConfig) SetEnableNetworkIsolation(v bool) *NetworkConfig { s.EnableNetworkIsolation = &v @@ -39216,9 +39228,7 @@ type RenderUiTemplateInput struct { Task *RenderableTask `type:"structure" required:"true"` // A Template object containing the worker UI template to render. - // - // UiTemplate is a required field - UiTemplate *UiTemplate `type:"structure" required:"true"` + UiTemplate *UiTemplate `type:"structure"` } // String returns the string representation @@ -39243,9 +39253,6 @@ func (s *RenderUiTemplateInput) Validate() error { if s.Task == nil { invalidParams.Add(request.NewErrParamRequired("Task")) } - if s.UiTemplate == nil { - invalidParams.Add(request.NewErrParamRequired("UiTemplate")) - } if s.Task != nil { if err := s.Task.Validate(); err != nil { invalidParams.AddNested("Task", err.(request.ErrInvalidParams)) @@ -39795,16 +39802,16 @@ func (s *ResourceNotFound) RequestID() string { return s.RespMetadata.RequestID } -// The instance type and the Amazon Resource Name (ARN) of the image created -// on the instance. The ARN is stored as metadata in Amazon SageMaker Studio -// notebooks. +// The instance type and the Amazon Resource Name (ARN) of the SageMaker image +// created on the instance. The ARN is stored as metadata in Amazon SageMaker +// Studio notebooks. type ResourceSpec struct { _ struct{} `type:"structure"` // The instance type. InstanceType *string `type:"string" enum:"AppInstanceType"` - // The Amazon Resource Name (ARN) of the image created on the instance. + // The Amazon Resource Name (ARN) of the SageMaker image created on the instance. SageMakerImageArn *string `type:"string"` } @@ -39830,11 +39837,15 @@ func (s *ResourceSpec) SetSageMakerImageArn(v string) *ResourceSpec { return s } -// The retention policy. +// The retention policy for data stored on an Amazon Elastic File System (EFS) +// volume. type RetentionPolicy struct { _ struct{} `type:"structure"` - // The home Amazon Elastic File System (EFS). + // The default is Retain, which specifies to keep the data stored on the EFS + // volume. + // + // Specify Delete to delete the data stored on the EFS volume. HomeEfsFileSystem *string `type:"string" enum:"RetentionType"` } @@ -41574,7 +41585,8 @@ func (s *Tag) SetValue(v string) *Tag { type TensorBoardAppSettings struct { _ struct{} `type:"structure"` - // The instance type and quantity. + // The default instance type and the Amazon Resource Name (ARN) of the SageMaker + // image created on the instance. DefaultResourceSpec *ResourceSpec `type:"structure"` } @@ -44128,9 +44140,7 @@ type UiConfig struct { // The Amazon S3 bucket location of the UI template. For more information about // the contents of a UI template, see Creating Your Custom Labeling Task Template // (https://docs.aws.amazon.com/sagemaker/latest/dg/sms-custom-templates-step2.html). - // - // UiTemplateS3Uri is a required field - UiTemplateS3Uri *string `type:"string" required:"true"` + UiTemplateS3Uri *string `type:"string"` } // String returns the string representation @@ -44143,19 +44153,6 @@ func (s UiConfig) GoString() string { return s.String() } -// Validate inspects the fields of the type to determine if they are valid. -func (s *UiConfig) Validate() error { - invalidParams := request.ErrInvalidParams{Context: "UiConfig"} - if s.UiTemplateS3Uri == nil { - invalidParams.Add(request.NewErrParamRequired("UiTemplateS3Uri")) - } - - if invalidParams.Len() > 0 { - return invalidParams - } - return nil -} - // SetUiTemplateS3Uri sets the UiTemplateS3Uri field's value. func (s *UiConfig) SetUiTemplateS3Uri(v string) *UiConfig { s.UiTemplateS3Uri = &v diff --git a/vendor/github.com/aws/aws-sdk-go/service/ssm/api.go b/vendor/github.com/aws/aws-sdk-go/service/ssm/api.go index d8bb7c631f2..e02de1a4b05 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ssm/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ssm/api.go @@ -45713,6 +45713,12 @@ const ( // OperatingSystemCentos is a OperatingSystem enum value OperatingSystemCentos = "CENTOS" + + // OperatingSystemOracleLinux is a OperatingSystem enum value + OperatingSystemOracleLinux = "ORACLE_LINUX" + + // OperatingSystemDebian is a OperatingSystem enum value + OperatingSystemDebian = "DEBIAN" ) const ( diff --git a/vendor/github.com/aws/aws-sdk-go/service/workmail/api.go b/vendor/github.com/aws/aws-sdk-go/service/workmail/api.go index 24766b693f2..709ad5ea41c 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/workmail/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/workmail/api.go @@ -2786,7 +2786,7 @@ func (c *WorkMail) ListOrganizationsRequest(input *ListOrganizationsInput) (req // ListOrganizations API operation for Amazon WorkMail. // -// Returns summaries of the customer's non-deleted organizations. +// Returns summaries of the customer's organizations. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -5071,7 +5071,9 @@ type DeleteAccessControlRuleInput struct { Name *string `min:"1" type:"string" required:"true"` // The identifier for the organization. - OrganizationId *string `type:"string"` + // + // OrganizationId is a required field + OrganizationId *string `type:"string" required:"true"` } // String returns the string representation @@ -5093,6 +5095,9 @@ func (s *DeleteAccessControlRuleInput) Validate() error { if s.Name != nil && len(*s.Name) < 1 { invalidParams.Add(request.NewErrParamMinLen("Name", 1)) } + if s.OrganizationId == nil { + invalidParams.Add(request.NewErrParamRequired("OrganizationId")) + } if invalidParams.Len() > 0 { return invalidParams diff --git a/vendor/modules.txt b/vendor/modules.txt index ffdbe2c150a..ed4f920a8a3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -25,7 +25,7 @@ github.com/apparentlymart/go-cidr/cidr github.com/apparentlymart/go-textseg/textseg # github.com/armon/go-radix v1.0.0 github.com/armon/go-radix -# github.com/aws/aws-sdk-go v1.30.21 +# github.com/aws/aws-sdk-go v1.30.28 github.com/aws/aws-sdk-go/aws github.com/aws/aws-sdk-go/aws/arn github.com/aws/aws-sdk-go/aws/awserr From 9a89bc74b5275a2f624c9087c87b8ad09d68274d Mon Sep 17 00:00:00 2001 From: Ilia Lazebnik Date: Fri, 15 May 2020 19:12:04 +0300 Subject: [PATCH 166/475] service/synthetics: Add service client (#13186) --- .hashibot.hcl | 7 + aws/config.go | 3 + .../generators/servicetags/main.go | 1 + .../generators/updatetags/main.go | 1 + .../service_generation_customizations.go | 3 + aws/internal/keyvaluetags/service_tags_gen.go | 10 + aws/internal/keyvaluetags/update_tags_gen.go | 37 + aws/provider.go | 1 + .../aws/aws-sdk-go/service/synthetics/api.go | 3792 +++++++++++++++++ .../aws/aws-sdk-go/service/synthetics/doc.go | 42 + .../aws-sdk-go/service/synthetics/errors.go | 41 + .../aws-sdk-go/service/synthetics/service.go | 104 + vendor/modules.txt | 1 + .../guides/custom-service-endpoints.html.md | 1 + 14 files changed, 4044 insertions(+) create mode 100644 vendor/github.com/aws/aws-sdk-go/service/synthetics/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/synthetics/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/synthetics/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/synthetics/service.go diff --git a/.hashibot.hcl b/.hashibot.hcl index 0e9ac1d9dc8..28ec3a4d82d 100644 --- a/.hashibot.hcl +++ b/.hashibot.hcl @@ -497,6 +497,9 @@ behavior "regexp_issue_labeler_v2" "service_labels" { "service/swf" = [ "aws_swf_", ], + "service/synthetics" = [ + "aws_synthetics_", + ], "service/transfer" = [ "aws_transfer_", ], @@ -1199,6 +1202,10 @@ behavior "pull_request_path_labeler" "service_labels" { "**/*_swf_*", "**/swf_*" ] + "service/synthetics" = [ + "**/*_synthetics_*", + "**/synthetics_*" + ] "service/transfer" = [ "**/*_transfer_*", "**/transfer_*" diff --git a/aws/config.go b/aws/config.go index fcdc8c6fc2a..123dc179068 100644 --- a/aws/config.go +++ b/aws/config.go @@ -139,6 +139,7 @@ import ( "github.com/aws/aws-sdk-go/service/storagegateway" "github.com/aws/aws-sdk-go/service/sts" "github.com/aws/aws-sdk-go/service/swf" + "github.com/aws/aws-sdk-go/service/synthetics" "github.com/aws/aws-sdk-go/service/transfer" "github.com/aws/aws-sdk-go/service/waf" "github.com/aws/aws-sdk-go/service/wafregional" @@ -322,6 +323,7 @@ type AWSClient struct { stsconn *sts.STS supportedplatforms []string swfconn *swf.SWF + syntheticsconn *synthetics.Synthetics terraformVersion string transferconn *transfer.Transfer wafconn *waf.WAF @@ -535,6 +537,7 @@ func (c *Config) Client() (interface{}, error) { storagegatewayconn: storagegateway.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["storagegateway"])})), stsconn: sts.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["sts"])})), swfconn: swf.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["swf"])})), + syntheticsconn: synthetics.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["synthetics"])})), terraformVersion: c.terraformVersion, transferconn: transfer.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["transfer"])})), wafconn: waf.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["waf"])})), diff --git a/aws/internal/keyvaluetags/generators/servicetags/main.go b/aws/internal/keyvaluetags/generators/servicetags/main.go index 79a7a1743bb..0717922fd87 100644 --- a/aws/internal/keyvaluetags/generators/servicetags/main.go +++ b/aws/internal/keyvaluetags/generators/servicetags/main.go @@ -132,6 +132,7 @@ var mapServiceNames = []string{ "resourcegroups", "securityhub", "sqs", + "synthetics", } type TemplateData struct { diff --git a/aws/internal/keyvaluetags/generators/updatetags/main.go b/aws/internal/keyvaluetags/generators/updatetags/main.go index 628f8ee646a..05caa30f048 100644 --- a/aws/internal/keyvaluetags/generators/updatetags/main.go +++ b/aws/internal/keyvaluetags/generators/updatetags/main.go @@ -113,6 +113,7 @@ var serviceNames = []string{ "ssm", "storagegateway", "swf", + "synthetics", "transfer", "waf", "wafregional", diff --git a/aws/internal/keyvaluetags/service_generation_customizations.go b/aws/internal/keyvaluetags/service_generation_customizations.go index c9a11053994..cd798080c68 100644 --- a/aws/internal/keyvaluetags/service_generation_customizations.go +++ b/aws/internal/keyvaluetags/service_generation_customizations.go @@ -103,6 +103,7 @@ import ( "github.com/aws/aws-sdk-go/service/ssm" "github.com/aws/aws-sdk-go/service/storagegateway" "github.com/aws/aws-sdk-go/service/swf" + "github.com/aws/aws-sdk-go/service/synthetics" "github.com/aws/aws-sdk-go/service/transfer" "github.com/aws/aws-sdk-go/service/waf" "github.com/aws/aws-sdk-go/service/wafregional" @@ -311,6 +312,8 @@ func ServiceClientType(serviceName string) string { funcType = reflect.TypeOf(storagegateway.New) case "swf": funcType = reflect.TypeOf(swf.New) + case "synthetics": + funcType = reflect.TypeOf(synthetics.New) case "transfer": funcType = reflect.TypeOf(transfer.New) case "waf": diff --git a/aws/internal/keyvaluetags/service_tags_gen.go b/aws/internal/keyvaluetags/service_tags_gen.go index 643fd0fc7c3..627f72f21fc 100644 --- a/aws/internal/keyvaluetags/service_tags_gen.go +++ b/aws/internal/keyvaluetags/service_tags_gen.go @@ -432,6 +432,16 @@ func SqsKeyValueTags(tags map[string]*string) KeyValueTags { return New(tags) } +// SyntheticsTags returns synthetics service tags. +func (tags KeyValueTags) SyntheticsTags() map[string]*string { + return aws.StringMap(tags.Map()) +} + +// SyntheticsKeyValueTags creates KeyValueTags from synthetics service tags. +func SyntheticsKeyValueTags(tags map[string]*string) KeyValueTags { + return New(tags) +} + // []*SERVICE.Tag handling // AcmTags returns acm service tags. diff --git a/aws/internal/keyvaluetags/update_tags_gen.go b/aws/internal/keyvaluetags/update_tags_gen.go index 68dc42f29ff..e987e0ad9a2 100644 --- a/aws/internal/keyvaluetags/update_tags_gen.go +++ b/aws/internal/keyvaluetags/update_tags_gen.go @@ -102,6 +102,7 @@ import ( "github.com/aws/aws-sdk-go/service/ssm" "github.com/aws/aws-sdk-go/service/storagegateway" "github.com/aws/aws-sdk-go/service/swf" + "github.com/aws/aws-sdk-go/service/synthetics" "github.com/aws/aws-sdk-go/service/transfer" "github.com/aws/aws-sdk-go/service/waf" "github.com/aws/aws-sdk-go/service/wafregional" @@ -3570,6 +3571,42 @@ func SwfUpdateTags(conn *swf.SWF, identifier string, oldTagsMap interface{}, new return nil } +// SyntheticsUpdateTags updates synthetics service tags. +// The identifier is typically the Amazon Resource Name (ARN), although +// it may also be a different identifier depending on the service. +func SyntheticsUpdateTags(conn *synthetics.Synthetics, identifier string, oldTagsMap interface{}, newTagsMap interface{}) error { + oldTags := New(oldTagsMap) + newTags := New(newTagsMap) + + if removedTags := oldTags.Removed(newTags); len(removedTags) > 0 { + input := &synthetics.UntagResourceInput{ + ResourceArn: aws.String(identifier), + TagKeys: aws.StringSlice(removedTags.IgnoreAws().Keys()), + } + + _, err := conn.UntagResource(input) + + if err != nil { + return fmt.Errorf("error untagging resource (%s): %w", identifier, err) + } + } + + if updatedTags := oldTags.Updated(newTags); len(updatedTags) > 0 { + input := &synthetics.TagResourceInput{ + ResourceArn: aws.String(identifier), + Tags: updatedTags.IgnoreAws().SyntheticsTags(), + } + + _, err := conn.TagResource(input) + + if err != nil { + return fmt.Errorf("error tagging resource (%s): %w", identifier, err) + } + } + + return nil +} + // TransferUpdateTags updates transfer service tags. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. diff --git a/aws/provider.go b/aws/provider.go index d7eaff110f5..0273b116f54 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -1130,6 +1130,7 @@ func init() { "storagegateway", "sts", "swf", + "synthetics", "transfer", "waf", "wafregional", diff --git a/vendor/github.com/aws/aws-sdk-go/service/synthetics/api.go b/vendor/github.com/aws/aws-sdk-go/service/synthetics/api.go new file mode 100644 index 00000000000..8b2d759c486 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/synthetics/api.go @@ -0,0 +1,3792 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package synthetics + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" + "github.com/aws/aws-sdk-go/private/protocol/restjson" +) + +const opCreateCanary = "CreateCanary" + +// CreateCanaryRequest generates a "aws/request.Request" representing the +// client's request for the CreateCanary operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateCanary for more information on using the CreateCanary +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateCanaryRequest method. +// req, resp := client.CreateCanaryRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/CreateCanary +func (c *Synthetics) CreateCanaryRequest(input *CreateCanaryInput) (req *request.Request, output *CreateCanaryOutput) { + op := &request.Operation{ + Name: opCreateCanary, + HTTPMethod: "POST", + HTTPPath: "/canary", + } + + if input == nil { + input = &CreateCanaryInput{} + } + + output = &CreateCanaryOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateCanary API operation for Synthetics. +// +// Creates a canary. Canaries are scripts that monitor your endpoints and APIs +// from the outside-in. Canaries help you check the availability and latency +// of your web services and troubleshoot anomalies by investigating load time +// data, screenshots of the UI, logs, and metrics. You can set up a canary to +// run continuously or just once. +// +// Do not use CreateCanary to modify an existing canary. Use UpdateCanary instead. +// +// To create canaries, you must have the CloudWatchSyntheticsFullAccess policy. +// If you are creating a new IAM role for the canary, you also need the the +// iam:CreateRole, iam:CreatePolicy and iam:AttachRolePolicy permissions. For +// more information, see Necessary Roles and Permissions (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Roles). +// +// Do not include secrets or proprietary information in your canary names. The +// canary name makes up part of the Amazon Resource Name (ARN) for the canary, +// and the ARN is included in outbound calls over the internet. For more information, +// see Security Considerations for Synthetics Canaries (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/servicelens_canaries_security.html). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Synthetics's +// API operation CreateCanary for usage and error information. +// +// Returned Error Types: +// * InternalServerException +// An unknown internal error occurred. +// +// * ValidationException +// A parameter could not be validated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/CreateCanary +func (c *Synthetics) CreateCanary(input *CreateCanaryInput) (*CreateCanaryOutput, error) { + req, out := c.CreateCanaryRequest(input) + return out, req.Send() +} + +// CreateCanaryWithContext is the same as CreateCanary with the addition of +// the ability to pass a context and additional request options. +// +// See CreateCanary for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) CreateCanaryWithContext(ctx aws.Context, input *CreateCanaryInput, opts ...request.Option) (*CreateCanaryOutput, error) { + req, out := c.CreateCanaryRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteCanary = "DeleteCanary" + +// DeleteCanaryRequest generates a "aws/request.Request" representing the +// client's request for the DeleteCanary operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteCanary for more information on using the DeleteCanary +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteCanaryRequest method. +// req, resp := client.DeleteCanaryRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/DeleteCanary +func (c *Synthetics) DeleteCanaryRequest(input *DeleteCanaryInput) (req *request.Request, output *DeleteCanaryOutput) { + op := &request.Operation{ + Name: opDeleteCanary, + HTTPMethod: "DELETE", + HTTPPath: "/canary/{name}", + } + + if input == nil { + input = &DeleteCanaryInput{} + } + + output = &DeleteCanaryOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restjson.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// DeleteCanary API operation for Synthetics. +// +// Permanently deletes the specified canary. +// +// When you delete a canary, resources used and created by the canary are not +// automatically deleted. After you delete a canary that you do not intend to +// use again, you should also delete the following: +// +// * The Lambda functions and layers used by this canary. These have the +// prefix cwsyn-MyCanaryName . +// +// * The CloudWatch alarms created for this canary. These alarms have a name +// of Synthetics-SharpDrop-Alarm-MyCanaryName . +// +// * Amazon S3 objects and buckets, such as the canary's artifact location. +// +// * IAM roles created for the canary. If they were created in the console, +// these roles have the name role/service-role/CloudWatchSyntheticsRole-MyCanaryName . +// +// * CloudWatch Logs log groups created for the canary. These logs groups +// have the name /aws/lambda/cwsyn-MyCanaryName . +// +// Before you delete a canary, you might want to use GetCanary to display the +// information about this canary. Make note of the information returned by this +// operation so that you can delete these resources after you delete the canary. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Synthetics's +// API operation DeleteCanary for usage and error information. +// +// Returned Error Types: +// * InternalServerException +// An unknown internal error occurred. +// +// * ValidationException +// A parameter could not be validated. +// +// * ResourceNotFoundException +// One of the specified resources was not found. +// +// * ConflictException +// A conflicting operation is already in progress. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/DeleteCanary +func (c *Synthetics) DeleteCanary(input *DeleteCanaryInput) (*DeleteCanaryOutput, error) { + req, out := c.DeleteCanaryRequest(input) + return out, req.Send() +} + +// DeleteCanaryWithContext is the same as DeleteCanary with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteCanary for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) DeleteCanaryWithContext(ctx aws.Context, input *DeleteCanaryInput, opts ...request.Option) (*DeleteCanaryOutput, error) { + req, out := c.DeleteCanaryRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDescribeCanaries = "DescribeCanaries" + +// DescribeCanariesRequest generates a "aws/request.Request" representing the +// client's request for the DescribeCanaries operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeCanaries for more information on using the DescribeCanaries +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeCanariesRequest method. +// req, resp := client.DescribeCanariesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/DescribeCanaries +func (c *Synthetics) DescribeCanariesRequest(input *DescribeCanariesInput) (req *request.Request, output *DescribeCanariesOutput) { + op := &request.Operation{ + Name: opDescribeCanaries, + HTTPMethod: "POST", + HTTPPath: "/canaries", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeCanariesInput{} + } + + output = &DescribeCanariesOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeCanaries API operation for Synthetics. +// +// This operation returns a list of the canaries in your account, along with +// full details about each canary. +// +// This operation does not have resource-level authorization, so if a user is +// able to use DescribeCanaries, the user can see all of the canaries in the +// account. A deny policy can only be used to restrict access to all canaries. +// It cannot be used on specific resources. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Synthetics's +// API operation DescribeCanaries for usage and error information. +// +// Returned Error Types: +// * InternalServerException +// An unknown internal error occurred. +// +// * ValidationException +// A parameter could not be validated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/DescribeCanaries +func (c *Synthetics) DescribeCanaries(input *DescribeCanariesInput) (*DescribeCanariesOutput, error) { + req, out := c.DescribeCanariesRequest(input) + return out, req.Send() +} + +// DescribeCanariesWithContext is the same as DescribeCanaries with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeCanaries for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) DescribeCanariesWithContext(ctx aws.Context, input *DescribeCanariesInput, opts ...request.Option) (*DescribeCanariesOutput, error) { + req, out := c.DescribeCanariesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// DescribeCanariesPages iterates over the pages of a DescribeCanaries operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeCanaries method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeCanaries operation. +// pageNum := 0 +// err := client.DescribeCanariesPages(params, +// func(page *synthetics.DescribeCanariesOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *Synthetics) DescribeCanariesPages(input *DescribeCanariesInput, fn func(*DescribeCanariesOutput, bool) bool) error { + return c.DescribeCanariesPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// DescribeCanariesPagesWithContext same as DescribeCanariesPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) DescribeCanariesPagesWithContext(ctx aws.Context, input *DescribeCanariesInput, fn func(*DescribeCanariesOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *DescribeCanariesInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeCanariesRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*DescribeCanariesOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opDescribeCanariesLastRun = "DescribeCanariesLastRun" + +// DescribeCanariesLastRunRequest generates a "aws/request.Request" representing the +// client's request for the DescribeCanariesLastRun operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeCanariesLastRun for more information on using the DescribeCanariesLastRun +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeCanariesLastRunRequest method. +// req, resp := client.DescribeCanariesLastRunRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/DescribeCanariesLastRun +func (c *Synthetics) DescribeCanariesLastRunRequest(input *DescribeCanariesLastRunInput) (req *request.Request, output *DescribeCanariesLastRunOutput) { + op := &request.Operation{ + Name: opDescribeCanariesLastRun, + HTTPMethod: "POST", + HTTPPath: "/canaries/last-run", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeCanariesLastRunInput{} + } + + output = &DescribeCanariesLastRunOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeCanariesLastRun API operation for Synthetics. +// +// Use this operation to see information from the most recent run of each canary +// that you have created. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Synthetics's +// API operation DescribeCanariesLastRun for usage and error information. +// +// Returned Error Types: +// * InternalServerException +// An unknown internal error occurred. +// +// * ValidationException +// A parameter could not be validated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/DescribeCanariesLastRun +func (c *Synthetics) DescribeCanariesLastRun(input *DescribeCanariesLastRunInput) (*DescribeCanariesLastRunOutput, error) { + req, out := c.DescribeCanariesLastRunRequest(input) + return out, req.Send() +} + +// DescribeCanariesLastRunWithContext is the same as DescribeCanariesLastRun with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeCanariesLastRun for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) DescribeCanariesLastRunWithContext(ctx aws.Context, input *DescribeCanariesLastRunInput, opts ...request.Option) (*DescribeCanariesLastRunOutput, error) { + req, out := c.DescribeCanariesLastRunRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// DescribeCanariesLastRunPages iterates over the pages of a DescribeCanariesLastRun operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeCanariesLastRun method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeCanariesLastRun operation. +// pageNum := 0 +// err := client.DescribeCanariesLastRunPages(params, +// func(page *synthetics.DescribeCanariesLastRunOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *Synthetics) DescribeCanariesLastRunPages(input *DescribeCanariesLastRunInput, fn func(*DescribeCanariesLastRunOutput, bool) bool) error { + return c.DescribeCanariesLastRunPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// DescribeCanariesLastRunPagesWithContext same as DescribeCanariesLastRunPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) DescribeCanariesLastRunPagesWithContext(ctx aws.Context, input *DescribeCanariesLastRunInput, fn func(*DescribeCanariesLastRunOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *DescribeCanariesLastRunInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeCanariesLastRunRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*DescribeCanariesLastRunOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opDescribeRuntimeVersions = "DescribeRuntimeVersions" + +// DescribeRuntimeVersionsRequest generates a "aws/request.Request" representing the +// client's request for the DescribeRuntimeVersions operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeRuntimeVersions for more information on using the DescribeRuntimeVersions +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeRuntimeVersionsRequest method. +// req, resp := client.DescribeRuntimeVersionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/DescribeRuntimeVersions +func (c *Synthetics) DescribeRuntimeVersionsRequest(input *DescribeRuntimeVersionsInput) (req *request.Request, output *DescribeRuntimeVersionsOutput) { + op := &request.Operation{ + Name: opDescribeRuntimeVersions, + HTTPMethod: "POST", + HTTPPath: "/runtime-versions", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &DescribeRuntimeVersionsInput{} + } + + output = &DescribeRuntimeVersionsOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeRuntimeVersions API operation for Synthetics. +// +// Returns a list of Synthetics canary runtime versions. For more information, +// see Canary Runtime Versions (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Synthetics's +// API operation DescribeRuntimeVersions for usage and error information. +// +// Returned Error Types: +// * InternalServerException +// An unknown internal error occurred. +// +// * ValidationException +// A parameter could not be validated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/DescribeRuntimeVersions +func (c *Synthetics) DescribeRuntimeVersions(input *DescribeRuntimeVersionsInput) (*DescribeRuntimeVersionsOutput, error) { + req, out := c.DescribeRuntimeVersionsRequest(input) + return out, req.Send() +} + +// DescribeRuntimeVersionsWithContext is the same as DescribeRuntimeVersions with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeRuntimeVersions for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) DescribeRuntimeVersionsWithContext(ctx aws.Context, input *DescribeRuntimeVersionsInput, opts ...request.Option) (*DescribeRuntimeVersionsOutput, error) { + req, out := c.DescribeRuntimeVersionsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// DescribeRuntimeVersionsPages iterates over the pages of a DescribeRuntimeVersions operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeRuntimeVersions method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeRuntimeVersions operation. +// pageNum := 0 +// err := client.DescribeRuntimeVersionsPages(params, +// func(page *synthetics.DescribeRuntimeVersionsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *Synthetics) DescribeRuntimeVersionsPages(input *DescribeRuntimeVersionsInput, fn func(*DescribeRuntimeVersionsOutput, bool) bool) error { + return c.DescribeRuntimeVersionsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// DescribeRuntimeVersionsPagesWithContext same as DescribeRuntimeVersionsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) DescribeRuntimeVersionsPagesWithContext(ctx aws.Context, input *DescribeRuntimeVersionsInput, fn func(*DescribeRuntimeVersionsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *DescribeRuntimeVersionsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeRuntimeVersionsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*DescribeRuntimeVersionsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opGetCanary = "GetCanary" + +// GetCanaryRequest generates a "aws/request.Request" representing the +// client's request for the GetCanary operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetCanary for more information on using the GetCanary +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetCanaryRequest method. +// req, resp := client.GetCanaryRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/GetCanary +func (c *Synthetics) GetCanaryRequest(input *GetCanaryInput) (req *request.Request, output *GetCanaryOutput) { + op := &request.Operation{ + Name: opGetCanary, + HTTPMethod: "GET", + HTTPPath: "/canary/{name}", + } + + if input == nil { + input = &GetCanaryInput{} + } + + output = &GetCanaryOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetCanary API operation for Synthetics. +// +// Retrieves complete information about one canary. You must specify the name +// of the canary that you want. To get a list of canaries and their names, use +// DescribeCanaries (https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_DescribeCanaries.html). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Synthetics's +// API operation GetCanary for usage and error information. +// +// Returned Error Types: +// * InternalServerException +// An unknown internal error occurred. +// +// * ValidationException +// A parameter could not be validated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/GetCanary +func (c *Synthetics) GetCanary(input *GetCanaryInput) (*GetCanaryOutput, error) { + req, out := c.GetCanaryRequest(input) + return out, req.Send() +} + +// GetCanaryWithContext is the same as GetCanary with the addition of +// the ability to pass a context and additional request options. +// +// See GetCanary for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) GetCanaryWithContext(ctx aws.Context, input *GetCanaryInput, opts ...request.Option) (*GetCanaryOutput, error) { + req, out := c.GetCanaryRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetCanaryRuns = "GetCanaryRuns" + +// GetCanaryRunsRequest generates a "aws/request.Request" representing the +// client's request for the GetCanaryRuns operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetCanaryRuns for more information on using the GetCanaryRuns +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetCanaryRunsRequest method. +// req, resp := client.GetCanaryRunsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/GetCanaryRuns +func (c *Synthetics) GetCanaryRunsRequest(input *GetCanaryRunsInput) (req *request.Request, output *GetCanaryRunsOutput) { + op := &request.Operation{ + Name: opGetCanaryRuns, + HTTPMethod: "POST", + HTTPPath: "/canary/{name}/runs", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &GetCanaryRunsInput{} + } + + output = &GetCanaryRunsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetCanaryRuns API operation for Synthetics. +// +// Retrieves a list of runs for a specified canary. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Synthetics's +// API operation GetCanaryRuns for usage and error information. +// +// Returned Error Types: +// * InternalServerException +// An unknown internal error occurred. +// +// * ValidationException +// A parameter could not be validated. +// +// * ResourceNotFoundException +// One of the specified resources was not found. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/GetCanaryRuns +func (c *Synthetics) GetCanaryRuns(input *GetCanaryRunsInput) (*GetCanaryRunsOutput, error) { + req, out := c.GetCanaryRunsRequest(input) + return out, req.Send() +} + +// GetCanaryRunsWithContext is the same as GetCanaryRuns with the addition of +// the ability to pass a context and additional request options. +// +// See GetCanaryRuns for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) GetCanaryRunsWithContext(ctx aws.Context, input *GetCanaryRunsInput, opts ...request.Option) (*GetCanaryRunsOutput, error) { + req, out := c.GetCanaryRunsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// GetCanaryRunsPages iterates over the pages of a GetCanaryRuns operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetCanaryRuns method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetCanaryRuns operation. +// pageNum := 0 +// err := client.GetCanaryRunsPages(params, +// func(page *synthetics.GetCanaryRunsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *Synthetics) GetCanaryRunsPages(input *GetCanaryRunsInput, fn func(*GetCanaryRunsOutput, bool) bool) error { + return c.GetCanaryRunsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// GetCanaryRunsPagesWithContext same as GetCanaryRunsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) GetCanaryRunsPagesWithContext(ctx aws.Context, input *GetCanaryRunsInput, fn func(*GetCanaryRunsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *GetCanaryRunsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.GetCanaryRunsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*GetCanaryRunsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + +const opListTagsForResource = "ListTagsForResource" + +// ListTagsForResourceRequest generates a "aws/request.Request" representing the +// client's request for the ListTagsForResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListTagsForResource for more information on using the ListTagsForResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListTagsForResourceRequest method. +// req, resp := client.ListTagsForResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/ListTagsForResource +func (c *Synthetics) ListTagsForResourceRequest(input *ListTagsForResourceInput) (req *request.Request, output *ListTagsForResourceOutput) { + op := &request.Operation{ + Name: opListTagsForResource, + HTTPMethod: "GET", + HTTPPath: "/tags/{resourceArn}", + } + + if input == nil { + input = &ListTagsForResourceInput{} + } + + output = &ListTagsForResourceOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListTagsForResource API operation for Synthetics. +// +// Displays the tags associated with a canary. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Synthetics's +// API operation ListTagsForResource for usage and error information. +// +// Returned Error Types: +// * InternalServerException +// An unknown internal error occurred. +// +// * ResourceNotFoundException +// One of the specified resources was not found. +// +// * ValidationException +// A parameter could not be validated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/ListTagsForResource +func (c *Synthetics) ListTagsForResource(input *ListTagsForResourceInput) (*ListTagsForResourceOutput, error) { + req, out := c.ListTagsForResourceRequest(input) + return out, req.Send() +} + +// ListTagsForResourceWithContext is the same as ListTagsForResource with the addition of +// the ability to pass a context and additional request options. +// +// See ListTagsForResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) ListTagsForResourceWithContext(ctx aws.Context, input *ListTagsForResourceInput, opts ...request.Option) (*ListTagsForResourceOutput, error) { + req, out := c.ListTagsForResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opStartCanary = "StartCanary" + +// StartCanaryRequest generates a "aws/request.Request" representing the +// client's request for the StartCanary operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See StartCanary for more information on using the StartCanary +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the StartCanaryRequest method. +// req, resp := client.StartCanaryRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/StartCanary +func (c *Synthetics) StartCanaryRequest(input *StartCanaryInput) (req *request.Request, output *StartCanaryOutput) { + op := &request.Operation{ + Name: opStartCanary, + HTTPMethod: "POST", + HTTPPath: "/canary/{name}/start", + } + + if input == nil { + input = &StartCanaryInput{} + } + + output = &StartCanaryOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restjson.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// StartCanary API operation for Synthetics. +// +// Use this operation to run a canary that has already been created. The frequency +// of the canary runs is determined by the value of the canary's Schedule. To +// see a canary's schedule, use GetCanary (https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_GetCanary.html). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Synthetics's +// API operation StartCanary for usage and error information. +// +// Returned Error Types: +// * InternalServerException +// An unknown internal error occurred. +// +// * ValidationException +// A parameter could not be validated. +// +// * ResourceNotFoundException +// One of the specified resources was not found. +// +// * ConflictException +// A conflicting operation is already in progress. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/StartCanary +func (c *Synthetics) StartCanary(input *StartCanaryInput) (*StartCanaryOutput, error) { + req, out := c.StartCanaryRequest(input) + return out, req.Send() +} + +// StartCanaryWithContext is the same as StartCanary with the addition of +// the ability to pass a context and additional request options. +// +// See StartCanary for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) StartCanaryWithContext(ctx aws.Context, input *StartCanaryInput, opts ...request.Option) (*StartCanaryOutput, error) { + req, out := c.StartCanaryRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opStopCanary = "StopCanary" + +// StopCanaryRequest generates a "aws/request.Request" representing the +// client's request for the StopCanary operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See StopCanary for more information on using the StopCanary +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the StopCanaryRequest method. +// req, resp := client.StopCanaryRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/StopCanary +func (c *Synthetics) StopCanaryRequest(input *StopCanaryInput) (req *request.Request, output *StopCanaryOutput) { + op := &request.Operation{ + Name: opStopCanary, + HTTPMethod: "POST", + HTTPPath: "/canary/{name}/stop", + } + + if input == nil { + input = &StopCanaryInput{} + } + + output = &StopCanaryOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restjson.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// StopCanary API operation for Synthetics. +// +// Stops the canary to prevent all future runs. If the canary is currently running, +// Synthetics stops waiting for the current run of the specified canary to complete. +// The run that is in progress completes on its own, publishes metrics, and +// uploads artifacts, but it is not recorded in Synthetics as a completed run. +// +// You can use StartCanary to start it running again with the canary’s current +// schedule at any point in the future. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Synthetics's +// API operation StopCanary for usage and error information. +// +// Returned Error Types: +// * InternalServerException +// An unknown internal error occurred. +// +// * ValidationException +// A parameter could not be validated. +// +// * ResourceNotFoundException +// One of the specified resources was not found. +// +// * ConflictException +// A conflicting operation is already in progress. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/StopCanary +func (c *Synthetics) StopCanary(input *StopCanaryInput) (*StopCanaryOutput, error) { + req, out := c.StopCanaryRequest(input) + return out, req.Send() +} + +// StopCanaryWithContext is the same as StopCanary with the addition of +// the ability to pass a context and additional request options. +// +// See StopCanary for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) StopCanaryWithContext(ctx aws.Context, input *StopCanaryInput, opts ...request.Option) (*StopCanaryOutput, error) { + req, out := c.StopCanaryRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opTagResource = "TagResource" + +// TagResourceRequest generates a "aws/request.Request" representing the +// client's request for the TagResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See TagResource for more information on using the TagResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the TagResourceRequest method. +// req, resp := client.TagResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/TagResource +func (c *Synthetics) TagResourceRequest(input *TagResourceInput) (req *request.Request, output *TagResourceOutput) { + op := &request.Operation{ + Name: opTagResource, + HTTPMethod: "POST", + HTTPPath: "/tags/{resourceArn}", + } + + if input == nil { + input = &TagResourceInput{} + } + + output = &TagResourceOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restjson.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// TagResource API operation for Synthetics. +// +// Assigns one or more tags (key-value pairs) to the specified canary. +// +// Tags can help you organize and categorize your resources. You can also use +// them to scope user permissions, by granting a user permission to access or +// change only resources with certain tag values. +// +// Tags don't have any semantic meaning to AWS and are interpreted strictly +// as strings of characters. +// +// You can use the TagResource action with a canary that already has tags. If +// you specify a new tag key for the alarm, this tag is appended to the list +// of tags associated with the alarm. If you specify a tag key that is already +// associated with the alarm, the new tag value that you specify replaces the +// previous value for that tag. +// +// You can associate as many as 50 tags with a canary. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Synthetics's +// API operation TagResource for usage and error information. +// +// Returned Error Types: +// * InternalServerException +// An unknown internal error occurred. +// +// * ResourceNotFoundException +// One of the specified resources was not found. +// +// * ValidationException +// A parameter could not be validated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/TagResource +func (c *Synthetics) TagResource(input *TagResourceInput) (*TagResourceOutput, error) { + req, out := c.TagResourceRequest(input) + return out, req.Send() +} + +// TagResourceWithContext is the same as TagResource with the addition of +// the ability to pass a context and additional request options. +// +// See TagResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) TagResourceWithContext(ctx aws.Context, input *TagResourceInput, opts ...request.Option) (*TagResourceOutput, error) { + req, out := c.TagResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUntagResource = "UntagResource" + +// UntagResourceRequest generates a "aws/request.Request" representing the +// client's request for the UntagResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UntagResource for more information on using the UntagResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UntagResourceRequest method. +// req, resp := client.UntagResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/UntagResource +func (c *Synthetics) UntagResourceRequest(input *UntagResourceInput) (req *request.Request, output *UntagResourceOutput) { + op := &request.Operation{ + Name: opUntagResource, + HTTPMethod: "DELETE", + HTTPPath: "/tags/{resourceArn}", + } + + if input == nil { + input = &UntagResourceInput{} + } + + output = &UntagResourceOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restjson.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// UntagResource API operation for Synthetics. +// +// Removes one or more tags from the specified canary. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Synthetics's +// API operation UntagResource for usage and error information. +// +// Returned Error Types: +// * InternalServerException +// An unknown internal error occurred. +// +// * ResourceNotFoundException +// One of the specified resources was not found. +// +// * ValidationException +// A parameter could not be validated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/UntagResource +func (c *Synthetics) UntagResource(input *UntagResourceInput) (*UntagResourceOutput, error) { + req, out := c.UntagResourceRequest(input) + return out, req.Send() +} + +// UntagResourceWithContext is the same as UntagResource with the addition of +// the ability to pass a context and additional request options. +// +// See UntagResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) UntagResourceWithContext(ctx aws.Context, input *UntagResourceInput, opts ...request.Option) (*UntagResourceOutput, error) { + req, out := c.UntagResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateCanary = "UpdateCanary" + +// UpdateCanaryRequest generates a "aws/request.Request" representing the +// client's request for the UpdateCanary operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateCanary for more information on using the UpdateCanary +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateCanaryRequest method. +// req, resp := client.UpdateCanaryRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/UpdateCanary +func (c *Synthetics) UpdateCanaryRequest(input *UpdateCanaryInput) (req *request.Request, output *UpdateCanaryOutput) { + op := &request.Operation{ + Name: opUpdateCanary, + HTTPMethod: "PATCH", + HTTPPath: "/canary/{name}", + } + + if input == nil { + input = &UpdateCanaryInput{} + } + + output = &UpdateCanaryOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restjson.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// UpdateCanary API operation for Synthetics. +// +// Use this operation to change the settings of a canary that has already been +// created. +// +// You can't use this operation to update the tags of an existing canary. To +// change the tags of an existing canary, use TagResource (https://docs.aws.amazon.com/AmazonSynthetics/latest/APIReference/API_TagResource.html). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Synthetics's +// API operation UpdateCanary for usage and error information. +// +// Returned Error Types: +// * InternalServerException +// An unknown internal error occurred. +// +// * ValidationException +// A parameter could not be validated. +// +// * ResourceNotFoundException +// One of the specified resources was not found. +// +// * ConflictException +// A conflicting operation is already in progress. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11/UpdateCanary +func (c *Synthetics) UpdateCanary(input *UpdateCanaryInput) (*UpdateCanaryOutput, error) { + req, out := c.UpdateCanaryRequest(input) + return out, req.Send() +} + +// UpdateCanaryWithContext is the same as UpdateCanary with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateCanary for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Synthetics) UpdateCanaryWithContext(ctx aws.Context, input *UpdateCanaryInput, opts ...request.Option) (*UpdateCanaryOutput, error) { + req, out := c.UpdateCanaryRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// This structure contains all information about one canary in your account. +type Canary struct { + _ struct{} `type:"structure"` + + // The location in Amazon S3 where Synthetics stores artifacts from the runs + // of this canary. Artifacts include the log file, screenshots, and HAR files. + ArtifactS3Location *string `min:"1" type:"string"` + + // This structure contains information about the canary's Lambda handler and + // where its code is stored by CloudWatch Synthetics. + Code *CanaryCodeOutput `type:"structure"` + + // The ARN of the Lambda function that is used as your canary's engine. For + // more information about Lambda ARN format, see Resources and Conditions for + // Lambda Actions (https://docs.aws.amazon.com/lambda/latest/dg/lambda-api-permissions-ref.html). + EngineArn *string `type:"string"` + + // The ARN of the IAM role used to run the canary. This role must include lambda.amazonaws.com + // as a principal in the trust policy. + ExecutionRoleArn *string `type:"string"` + + // The number of days to retain data about failed runs of this canary. + FailureRetentionPeriodInDays *int64 `min:"1" type:"integer"` + + // The unique ID of this canary. + Id *string `type:"string"` + + // The name of the canary. + Name *string `min:"1" type:"string"` + + // A structure that contains information for a canary run. + RunConfig *CanaryRunConfigOutput `type:"structure"` + + // Specifies the runtime version to use for the canary. Currently, the only + // valid value is syn-1.0. For more information about runtime versions, see + // Canary Runtime Versions (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html). + RuntimeVersion *string `min:"1" type:"string"` + + // A structure that contains information about how often the canary is to run, + // and when these runs are to stop. + Schedule *CanaryScheduleOutput `type:"structure"` + + // A structure that contains information about the canary's status. + Status *CanaryStatus `type:"structure"` + + // The number of days to retain data about successful runs of this canary. + SuccessRetentionPeriodInDays *int64 `min:"1" type:"integer"` + + // The list of key-value pairs that are associated with the canary. + Tags map[string]*string `min:"1" type:"map"` + + // A structure that contains information about when the canary was created, + // modified, and most recently run. + Timeline *CanaryTimeline `type:"structure"` + + // If this canary is to test an endpoint in a VPC, this structure contains information + // about the subnets and security groups of the VPC endpoint. For more information, + // see Running a Canary in a VPC (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_VPC.html). + VpcConfig *VpcConfigOutput `type:"structure"` +} + +// String returns the string representation +func (s Canary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Canary) GoString() string { + return s.String() +} + +// SetArtifactS3Location sets the ArtifactS3Location field's value. +func (s *Canary) SetArtifactS3Location(v string) *Canary { + s.ArtifactS3Location = &v + return s +} + +// SetCode sets the Code field's value. +func (s *Canary) SetCode(v *CanaryCodeOutput) *Canary { + s.Code = v + return s +} + +// SetEngineArn sets the EngineArn field's value. +func (s *Canary) SetEngineArn(v string) *Canary { + s.EngineArn = &v + return s +} + +// SetExecutionRoleArn sets the ExecutionRoleArn field's value. +func (s *Canary) SetExecutionRoleArn(v string) *Canary { + s.ExecutionRoleArn = &v + return s +} + +// SetFailureRetentionPeriodInDays sets the FailureRetentionPeriodInDays field's value. +func (s *Canary) SetFailureRetentionPeriodInDays(v int64) *Canary { + s.FailureRetentionPeriodInDays = &v + return s +} + +// SetId sets the Id field's value. +func (s *Canary) SetId(v string) *Canary { + s.Id = &v + return s +} + +// SetName sets the Name field's value. +func (s *Canary) SetName(v string) *Canary { + s.Name = &v + return s +} + +// SetRunConfig sets the RunConfig field's value. +func (s *Canary) SetRunConfig(v *CanaryRunConfigOutput) *Canary { + s.RunConfig = v + return s +} + +// SetRuntimeVersion sets the RuntimeVersion field's value. +func (s *Canary) SetRuntimeVersion(v string) *Canary { + s.RuntimeVersion = &v + return s +} + +// SetSchedule sets the Schedule field's value. +func (s *Canary) SetSchedule(v *CanaryScheduleOutput) *Canary { + s.Schedule = v + return s +} + +// SetStatus sets the Status field's value. +func (s *Canary) SetStatus(v *CanaryStatus) *Canary { + s.Status = v + return s +} + +// SetSuccessRetentionPeriodInDays sets the SuccessRetentionPeriodInDays field's value. +func (s *Canary) SetSuccessRetentionPeriodInDays(v int64) *Canary { + s.SuccessRetentionPeriodInDays = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *Canary) SetTags(v map[string]*string) *Canary { + s.Tags = v + return s +} + +// SetTimeline sets the Timeline field's value. +func (s *Canary) SetTimeline(v *CanaryTimeline) *Canary { + s.Timeline = v + return s +} + +// SetVpcConfig sets the VpcConfig field's value. +func (s *Canary) SetVpcConfig(v *VpcConfigOutput) *Canary { + s.VpcConfig = v + return s +} + +// Use this structure to input your script code for the canary. This structure +// contains the Lambda handler with the location where the canary should start +// running the script. If the script is stored in an S3 bucket, the bucket name, +// key, and version are also included. If the script was passed into the canary +// directly, the script code is contained in the value of Zipfile. +type CanaryCodeInput struct { + _ struct{} `type:"structure"` + + // The entry point to use for the source code when running the canary. This + // value must end with the string .handler. + // + // Handler is a required field + Handler *string `min:"1" type:"string" required:"true"` + + // If your canary script is located in S3, specify the full bucket name here. + // The bucket must already exist. Specify the full bucket name, including s3:// + // as the start of the bucket name. + S3Bucket *string `min:"1" type:"string"` + + // The S3 key of your script. For more information, see Working with Amazon + // S3 Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingObjects.html). + S3Key *string `min:"1" type:"string"` + + // The S3 version ID of your script. + S3Version *string `min:"1" type:"string"` + + // If you input your canary script directly into the canary instead of referring + // to an S3 location, the value of this parameter is the .zip file that contains + // the script. It can be up to 5 MB. + // + // ZipFile is automatically base64 encoded/decoded by the SDK. + ZipFile []byte `min:"1" type:"blob"` +} + +// String returns the string representation +func (s CanaryCodeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CanaryCodeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CanaryCodeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CanaryCodeInput"} + if s.Handler == nil { + invalidParams.Add(request.NewErrParamRequired("Handler")) + } + if s.Handler != nil && len(*s.Handler) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Handler", 1)) + } + if s.S3Bucket != nil && len(*s.S3Bucket) < 1 { + invalidParams.Add(request.NewErrParamMinLen("S3Bucket", 1)) + } + if s.S3Key != nil && len(*s.S3Key) < 1 { + invalidParams.Add(request.NewErrParamMinLen("S3Key", 1)) + } + if s.S3Version != nil && len(*s.S3Version) < 1 { + invalidParams.Add(request.NewErrParamMinLen("S3Version", 1)) + } + if s.ZipFile != nil && len(s.ZipFile) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ZipFile", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetHandler sets the Handler field's value. +func (s *CanaryCodeInput) SetHandler(v string) *CanaryCodeInput { + s.Handler = &v + return s +} + +// SetS3Bucket sets the S3Bucket field's value. +func (s *CanaryCodeInput) SetS3Bucket(v string) *CanaryCodeInput { + s.S3Bucket = &v + return s +} + +// SetS3Key sets the S3Key field's value. +func (s *CanaryCodeInput) SetS3Key(v string) *CanaryCodeInput { + s.S3Key = &v + return s +} + +// SetS3Version sets the S3Version field's value. +func (s *CanaryCodeInput) SetS3Version(v string) *CanaryCodeInput { + s.S3Version = &v + return s +} + +// SetZipFile sets the ZipFile field's value. +func (s *CanaryCodeInput) SetZipFile(v []byte) *CanaryCodeInput { + s.ZipFile = v + return s +} + +// This structure contains information about the canary's Lambda handler and +// where its code is stored by CloudWatch Synthetics. +type CanaryCodeOutput struct { + _ struct{} `type:"structure"` + + // The entry point to use for the source code when running the canary. + Handler *string `min:"1" type:"string"` + + // The ARN of the Lambda layer where Synthetics stores the canary script code. + SourceLocationArn *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s CanaryCodeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CanaryCodeOutput) GoString() string { + return s.String() +} + +// SetHandler sets the Handler field's value. +func (s *CanaryCodeOutput) SetHandler(v string) *CanaryCodeOutput { + s.Handler = &v + return s +} + +// SetSourceLocationArn sets the SourceLocationArn field's value. +func (s *CanaryCodeOutput) SetSourceLocationArn(v string) *CanaryCodeOutput { + s.SourceLocationArn = &v + return s +} + +// This structure contains information about the most recent run of a single +// canary. +type CanaryLastRun struct { + _ struct{} `type:"structure"` + + // The name of the canary. + CanaryName *string `min:"1" type:"string"` + + // The results from this canary's most recent run. + LastRun *CanaryRun `type:"structure"` +} + +// String returns the string representation +func (s CanaryLastRun) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CanaryLastRun) GoString() string { + return s.String() +} + +// SetCanaryName sets the CanaryName field's value. +func (s *CanaryLastRun) SetCanaryName(v string) *CanaryLastRun { + s.CanaryName = &v + return s +} + +// SetLastRun sets the LastRun field's value. +func (s *CanaryLastRun) SetLastRun(v *CanaryRun) *CanaryLastRun { + s.LastRun = v + return s +} + +// This structure contains the details about one run of one canary. +type CanaryRun struct { + _ struct{} `type:"structure"` + + // The location where the canary stored artifacts from the run. Artifacts include + // the log file, screenshots, and HAR files. + ArtifactS3Location *string `min:"1" type:"string"` + + // The name of the canary. + Name *string `min:"1" type:"string"` + + // The status of this run. + Status *CanaryRunStatus `type:"structure"` + + // A structure that contains the start and end times of this run. + Timeline *CanaryRunTimeline `type:"structure"` +} + +// String returns the string representation +func (s CanaryRun) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CanaryRun) GoString() string { + return s.String() +} + +// SetArtifactS3Location sets the ArtifactS3Location field's value. +func (s *CanaryRun) SetArtifactS3Location(v string) *CanaryRun { + s.ArtifactS3Location = &v + return s +} + +// SetName sets the Name field's value. +func (s *CanaryRun) SetName(v string) *CanaryRun { + s.Name = &v + return s +} + +// SetStatus sets the Status field's value. +func (s *CanaryRun) SetStatus(v *CanaryRunStatus) *CanaryRun { + s.Status = v + return s +} + +// SetTimeline sets the Timeline field's value. +func (s *CanaryRun) SetTimeline(v *CanaryRunTimeline) *CanaryRun { + s.Timeline = v + return s +} + +// A structure that contains input information for a canary run. +type CanaryRunConfigInput struct { + _ struct{} `type:"structure"` + + // How long the canary is allowed to run before it must stop. If you omit this + // field, the frequency of the canary is used as this value, up to a maximum + // of 14 minutes. + // + // TimeoutInSeconds is a required field + TimeoutInSeconds *int64 `min:"60" type:"integer" required:"true"` +} + +// String returns the string representation +func (s CanaryRunConfigInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CanaryRunConfigInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CanaryRunConfigInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CanaryRunConfigInput"} + if s.TimeoutInSeconds == nil { + invalidParams.Add(request.NewErrParamRequired("TimeoutInSeconds")) + } + if s.TimeoutInSeconds != nil && *s.TimeoutInSeconds < 60 { + invalidParams.Add(request.NewErrParamMinValue("TimeoutInSeconds", 60)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetTimeoutInSeconds sets the TimeoutInSeconds field's value. +func (s *CanaryRunConfigInput) SetTimeoutInSeconds(v int64) *CanaryRunConfigInput { + s.TimeoutInSeconds = &v + return s +} + +// A structure that contains information for a canary run. +type CanaryRunConfigOutput struct { + _ struct{} `type:"structure"` + + // How long the canary is allowed to run before it must stop. + TimeoutInSeconds *int64 `min:"60" type:"integer"` +} + +// String returns the string representation +func (s CanaryRunConfigOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CanaryRunConfigOutput) GoString() string { + return s.String() +} + +// SetTimeoutInSeconds sets the TimeoutInSeconds field's value. +func (s *CanaryRunConfigOutput) SetTimeoutInSeconds(v int64) *CanaryRunConfigOutput { + s.TimeoutInSeconds = &v + return s +} + +// This structure contains the status information about a canary run. +type CanaryRunStatus struct { + _ struct{} `type:"structure"` + + // The current state of the run. + State *string `type:"string" enum:"CanaryRunState"` + + // If run of the canary failed, this field contains the reason for the error. + StateReason *string `min:"1" type:"string"` + + // If this value is CANARY_FAILURE, an exception occurred in the canary code. + // If this value is EXECUTION_FAILURE, an exception occurred in CloudWatch Synthetics. + StateReasonCode *string `type:"string" enum:"CanaryRunStateReasonCode"` +} + +// String returns the string representation +func (s CanaryRunStatus) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CanaryRunStatus) GoString() string { + return s.String() +} + +// SetState sets the State field's value. +func (s *CanaryRunStatus) SetState(v string) *CanaryRunStatus { + s.State = &v + return s +} + +// SetStateReason sets the StateReason field's value. +func (s *CanaryRunStatus) SetStateReason(v string) *CanaryRunStatus { + s.StateReason = &v + return s +} + +// SetStateReasonCode sets the StateReasonCode field's value. +func (s *CanaryRunStatus) SetStateReasonCode(v string) *CanaryRunStatus { + s.StateReasonCode = &v + return s +} + +// This structure contains the start and end times of a single canary run. +type CanaryRunTimeline struct { + _ struct{} `type:"structure"` + + // The end time of the run. + Completed *time.Time `type:"timestamp"` + + // The start time of the run. + Started *time.Time `type:"timestamp"` +} + +// String returns the string representation +func (s CanaryRunTimeline) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CanaryRunTimeline) GoString() string { + return s.String() +} + +// SetCompleted sets the Completed field's value. +func (s *CanaryRunTimeline) SetCompleted(v time.Time) *CanaryRunTimeline { + s.Completed = &v + return s +} + +// SetStarted sets the Started field's value. +func (s *CanaryRunTimeline) SetStarted(v time.Time) *CanaryRunTimeline { + s.Started = &v + return s +} + +// This structure specifies how often a canary is to make runs and the date +// and time when it should stop making runs. +type CanaryScheduleInput struct { + _ struct{} `type:"structure"` + + // How long, in seconds, for the canary to continue making regular runs according + // to the schedule in the Expression value. If you specify 0, the canary continues + // making runs until you stop it. If you omit this field, the default of 0 is + // used. + DurationInSeconds *int64 `type:"long"` + + // A rate expression that defines how often the canary is to run. The syntax + // is rate(number unit). unit can be minute, minutes, or hour. + // + // For example, rate(1 minute) runs the canary once a minute, rate(10 minutes) + // runs it once every 10 minutes, and rate(1 hour) runs it once every hour. + // You can specify a frequency between rate(1 minute) and rate(1 hour). + // + // Specifying rate(0 minute) or rate(0 hour) is a special value that causes + // the canary to run only once when it is started. + // + // Expression is a required field + Expression *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s CanaryScheduleInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CanaryScheduleInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CanaryScheduleInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CanaryScheduleInput"} + if s.Expression == nil { + invalidParams.Add(request.NewErrParamRequired("Expression")) + } + if s.Expression != nil && len(*s.Expression) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Expression", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDurationInSeconds sets the DurationInSeconds field's value. +func (s *CanaryScheduleInput) SetDurationInSeconds(v int64) *CanaryScheduleInput { + s.DurationInSeconds = &v + return s +} + +// SetExpression sets the Expression field's value. +func (s *CanaryScheduleInput) SetExpression(v string) *CanaryScheduleInput { + s.Expression = &v + return s +} + +// How long, in seconds, for the canary to continue making regular runs according +// to the schedule in the Expression value. +type CanaryScheduleOutput struct { + _ struct{} `type:"structure"` + + // How long, in seconds, for the canary to continue making regular runs after + // it was created. The runs are performed according to the schedule in the Expression + // value. + DurationInSeconds *int64 `type:"long"` + + // A rate expression that defines how often the canary is to run. The syntax + // is rate(number unit). unit can be minute, minutes, or hour. + // + // For example, rate(1 minute) runs the canary once a minute, rate(10 minutes) + // runs it once every 10 minutes, and rate(1 hour) runs it once every hour. + // + // Specifying rate(0 minute) or rate(0 hour) is a special value that causes + // the canary to run only once when it is started. + Expression *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s CanaryScheduleOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CanaryScheduleOutput) GoString() string { + return s.String() +} + +// SetDurationInSeconds sets the DurationInSeconds field's value. +func (s *CanaryScheduleOutput) SetDurationInSeconds(v int64) *CanaryScheduleOutput { + s.DurationInSeconds = &v + return s +} + +// SetExpression sets the Expression field's value. +func (s *CanaryScheduleOutput) SetExpression(v string) *CanaryScheduleOutput { + s.Expression = &v + return s +} + +// A structure that contains the current state of the canary. +type CanaryStatus struct { + _ struct{} `type:"structure"` + + // The current state of the canary. + State *string `type:"string" enum:"CanaryState"` + + // If the canary has insufficient permissions to run, this field provides more + // details. + StateReason *string `min:"1" type:"string"` + + // If the canary cannot run or has failed, this field displays the reason. + StateReasonCode *string `type:"string" enum:"CanaryStateReasonCode"` +} + +// String returns the string representation +func (s CanaryStatus) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CanaryStatus) GoString() string { + return s.String() +} + +// SetState sets the State field's value. +func (s *CanaryStatus) SetState(v string) *CanaryStatus { + s.State = &v + return s +} + +// SetStateReason sets the StateReason field's value. +func (s *CanaryStatus) SetStateReason(v string) *CanaryStatus { + s.StateReason = &v + return s +} + +// SetStateReasonCode sets the StateReasonCode field's value. +func (s *CanaryStatus) SetStateReasonCode(v string) *CanaryStatus { + s.StateReasonCode = &v + return s +} + +// This structure contains information about when the canary was created and +// modified. +type CanaryTimeline struct { + _ struct{} `type:"structure"` + + // The date and time the canary was created. + Created *time.Time `type:"timestamp"` + + // The date and time the canary was most recently modified. + LastModified *time.Time `type:"timestamp"` + + // The date and time that the canary's most recent run started. + LastStarted *time.Time `type:"timestamp"` + + // The date and time that the canary's most recent run ended. + LastStopped *time.Time `type:"timestamp"` +} + +// String returns the string representation +func (s CanaryTimeline) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CanaryTimeline) GoString() string { + return s.String() +} + +// SetCreated sets the Created field's value. +func (s *CanaryTimeline) SetCreated(v time.Time) *CanaryTimeline { + s.Created = &v + return s +} + +// SetLastModified sets the LastModified field's value. +func (s *CanaryTimeline) SetLastModified(v time.Time) *CanaryTimeline { + s.LastModified = &v + return s +} + +// SetLastStarted sets the LastStarted field's value. +func (s *CanaryTimeline) SetLastStarted(v time.Time) *CanaryTimeline { + s.LastStarted = &v + return s +} + +// SetLastStopped sets the LastStopped field's value. +func (s *CanaryTimeline) SetLastStopped(v time.Time) *CanaryTimeline { + s.LastStopped = &v + return s +} + +// A conflicting operation is already in progress. +type ConflictException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"Message" type:"string"` +} + +// String returns the string representation +func (s ConflictException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ConflictException) GoString() string { + return s.String() +} + +func newErrorConflictException(v protocol.ResponseMetadata) error { + return &ConflictException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ConflictException) Code() string { + return "ConflictException" +} + +// Message returns the exception's message. +func (s *ConflictException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ConflictException) OrigErr() error { + return nil +} + +func (s *ConflictException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ConflictException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ConflictException) RequestID() string { + return s.RespMetadata.RequestID +} + +type CreateCanaryInput struct { + _ struct{} `type:"structure"` + + // The location in Amazon S3 where Synthetics stores artifacts from the test + // runs of this canary. Artifacts include the log file, screenshots, and HAR + // files. + // + // ArtifactS3Location is a required field + ArtifactS3Location *string `min:"1" type:"string" required:"true"` + + // A structure that includes the entry point from which the canary should start + // running your script. If the script is stored in an S3 bucket, the bucket + // name, key, and version are also included. + // + // Code is a required field + Code *CanaryCodeInput `type:"structure" required:"true"` + + // The ARN of the IAM role to be used to run the canary. This role must already + // exist, and must include lambda.amazonaws.com as a principal in the trust + // policy. The role must also have the following permissions: + // + // * s3:PutObject + // + // * s3:GetBucketLocation + // + // * s3:ListAllMyBuckets + // + // * cloudwatch:PutMetricData + // + // * logs:CreateLogGroup + // + // * logs:CreateLogStream + // + // * logs:CreateLogStream + // + // ExecutionRoleArn is a required field + ExecutionRoleArn *string `type:"string" required:"true"` + + // The number of days to retain data about failed runs of this canary. If you + // omit this field, the default of 31 days is used. The valid range is 1 to + // 455 days. + FailureRetentionPeriodInDays *int64 `min:"1" type:"integer"` + + // The name for this canary. Be sure to give it a descriptive name that distinguishes + // it from other canaries in your account. + // + // Do not include secrets or proprietary information in your canary names. The + // canary name makes up part of the canary ARN, and the ARN is included in outbound + // calls over the internet. For more information, see Security Considerations + // for Synthetics Canaries (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/servicelens_canaries_security.html). + // + // Name is a required field + Name *string `min:"1" type:"string" required:"true"` + + // A structure that contains the configuration for individual canary runs, such + // as timeout value. + RunConfig *CanaryRunConfigInput `type:"structure"` + + // Specifies the runtime version to use for the canary. Currently, the only + // valid value is syn-1.0. For more information about runtime versions, see + // Canary Runtime Versions (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html). + // + // RuntimeVersion is a required field + RuntimeVersion *string `min:"1" type:"string" required:"true"` + + // A structure that contains information about how often the canary is to run + // and when these test runs are to stop. + // + // Schedule is a required field + Schedule *CanaryScheduleInput `type:"structure" required:"true"` + + // The number of days to retain data about successful runs of this canary. If + // you omit this field, the default of 31 days is used. The valid range is 1 + // to 455 days. + SuccessRetentionPeriodInDays *int64 `min:"1" type:"integer"` + + // A list of key-value pairs to associate with the canary. You can associate + // as many as 50 tags with a canary. + // + // Tags can help you organize and categorize your resources. You can also use + // them to scope user permissions, by granting a user permission to access or + // change only the resources that have certain tag values. + Tags map[string]*string `min:"1" type:"map"` + + // If this canary is to test an endpoint in a VPC, this structure contains information + // about the subnet and security groups of the VPC endpoint. For more information, + // see Running a Canary in a VPC (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_VPC.html). + VpcConfig *VpcConfigInput `type:"structure"` +} + +// String returns the string representation +func (s CreateCanaryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateCanaryInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateCanaryInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateCanaryInput"} + if s.ArtifactS3Location == nil { + invalidParams.Add(request.NewErrParamRequired("ArtifactS3Location")) + } + if s.ArtifactS3Location != nil && len(*s.ArtifactS3Location) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ArtifactS3Location", 1)) + } + if s.Code == nil { + invalidParams.Add(request.NewErrParamRequired("Code")) + } + if s.ExecutionRoleArn == nil { + invalidParams.Add(request.NewErrParamRequired("ExecutionRoleArn")) + } + if s.FailureRetentionPeriodInDays != nil && *s.FailureRetentionPeriodInDays < 1 { + invalidParams.Add(request.NewErrParamMinValue("FailureRetentionPeriodInDays", 1)) + } + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Name", 1)) + } + if s.RuntimeVersion == nil { + invalidParams.Add(request.NewErrParamRequired("RuntimeVersion")) + } + if s.RuntimeVersion != nil && len(*s.RuntimeVersion) < 1 { + invalidParams.Add(request.NewErrParamMinLen("RuntimeVersion", 1)) + } + if s.Schedule == nil { + invalidParams.Add(request.NewErrParamRequired("Schedule")) + } + if s.SuccessRetentionPeriodInDays != nil && *s.SuccessRetentionPeriodInDays < 1 { + invalidParams.Add(request.NewErrParamMinValue("SuccessRetentionPeriodInDays", 1)) + } + if s.Tags != nil && len(s.Tags) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Tags", 1)) + } + if s.Code != nil { + if err := s.Code.Validate(); err != nil { + invalidParams.AddNested("Code", err.(request.ErrInvalidParams)) + } + } + if s.RunConfig != nil { + if err := s.RunConfig.Validate(); err != nil { + invalidParams.AddNested("RunConfig", err.(request.ErrInvalidParams)) + } + } + if s.Schedule != nil { + if err := s.Schedule.Validate(); err != nil { + invalidParams.AddNested("Schedule", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetArtifactS3Location sets the ArtifactS3Location field's value. +func (s *CreateCanaryInput) SetArtifactS3Location(v string) *CreateCanaryInput { + s.ArtifactS3Location = &v + return s +} + +// SetCode sets the Code field's value. +func (s *CreateCanaryInput) SetCode(v *CanaryCodeInput) *CreateCanaryInput { + s.Code = v + return s +} + +// SetExecutionRoleArn sets the ExecutionRoleArn field's value. +func (s *CreateCanaryInput) SetExecutionRoleArn(v string) *CreateCanaryInput { + s.ExecutionRoleArn = &v + return s +} + +// SetFailureRetentionPeriodInDays sets the FailureRetentionPeriodInDays field's value. +func (s *CreateCanaryInput) SetFailureRetentionPeriodInDays(v int64) *CreateCanaryInput { + s.FailureRetentionPeriodInDays = &v + return s +} + +// SetName sets the Name field's value. +func (s *CreateCanaryInput) SetName(v string) *CreateCanaryInput { + s.Name = &v + return s +} + +// SetRunConfig sets the RunConfig field's value. +func (s *CreateCanaryInput) SetRunConfig(v *CanaryRunConfigInput) *CreateCanaryInput { + s.RunConfig = v + return s +} + +// SetRuntimeVersion sets the RuntimeVersion field's value. +func (s *CreateCanaryInput) SetRuntimeVersion(v string) *CreateCanaryInput { + s.RuntimeVersion = &v + return s +} + +// SetSchedule sets the Schedule field's value. +func (s *CreateCanaryInput) SetSchedule(v *CanaryScheduleInput) *CreateCanaryInput { + s.Schedule = v + return s +} + +// SetSuccessRetentionPeriodInDays sets the SuccessRetentionPeriodInDays field's value. +func (s *CreateCanaryInput) SetSuccessRetentionPeriodInDays(v int64) *CreateCanaryInput { + s.SuccessRetentionPeriodInDays = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateCanaryInput) SetTags(v map[string]*string) *CreateCanaryInput { + s.Tags = v + return s +} + +// SetVpcConfig sets the VpcConfig field's value. +func (s *CreateCanaryInput) SetVpcConfig(v *VpcConfigInput) *CreateCanaryInput { + s.VpcConfig = v + return s +} + +type CreateCanaryOutput struct { + _ struct{} `type:"structure"` + + // The full details about the canary you have created. + Canary *Canary `type:"structure"` +} + +// String returns the string representation +func (s CreateCanaryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateCanaryOutput) GoString() string { + return s.String() +} + +// SetCanary sets the Canary field's value. +func (s *CreateCanaryOutput) SetCanary(v *Canary) *CreateCanaryOutput { + s.Canary = v + return s +} + +type DeleteCanaryInput struct { + _ struct{} `type:"structure"` + + // The name of the canary that you want to delete. To find the names of your + // canaries, use DescribeCanaries. + // + // Name is a required field + Name *string `location:"uri" locationName:"name" min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteCanaryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteCanaryInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteCanaryInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteCanaryInput"} + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Name", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetName sets the Name field's value. +func (s *DeleteCanaryInput) SetName(v string) *DeleteCanaryInput { + s.Name = &v + return s +} + +type DeleteCanaryOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteCanaryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteCanaryOutput) GoString() string { + return s.String() +} + +type DescribeCanariesInput struct { + _ struct{} `type:"structure"` + + // Specify this parameter to limit how many canaries are returned each time + // you use the DescribeCanaries operation. If you omit this parameter, the default + // of 100 is used. + MaxResults *int64 `min:"1" type:"integer"` + + // A token that indicates that there is more data available. You can use this + // token in a subsequent operation to retrieve the next set of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeCanariesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeCanariesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeCanariesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeCanariesInput"} + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeCanariesInput) SetMaxResults(v int64) *DescribeCanariesInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeCanariesInput) SetNextToken(v string) *DescribeCanariesInput { + s.NextToken = &v + return s +} + +type DescribeCanariesLastRunInput struct { + _ struct{} `type:"structure"` + + // Specify this parameter to limit how many runs are returned each time you + // use the DescribeLastRun operation. If you omit this parameter, the default + // of 100 is used. + MaxResults *int64 `min:"1" type:"integer"` + + // A token that indicates that there is more data available. You can use this + // token in a subsequent DescribeCanaries operation to retrieve the next set + // of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeCanariesLastRunInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeCanariesLastRunInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeCanariesLastRunInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeCanariesLastRunInput"} + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeCanariesLastRunInput) SetMaxResults(v int64) *DescribeCanariesLastRunInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeCanariesLastRunInput) SetNextToken(v string) *DescribeCanariesLastRunInput { + s.NextToken = &v + return s +} + +type DescribeCanariesLastRunOutput struct { + _ struct{} `type:"structure"` + + // An array that contains the information from the most recent run of each canary. + CanariesLastRun []*CanaryLastRun `type:"list"` + + // A token that indicates that there is more data available. You can use this + // token in a subsequent DescribeCanariesLastRun operation to retrieve the next + // set of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeCanariesLastRunOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeCanariesLastRunOutput) GoString() string { + return s.String() +} + +// SetCanariesLastRun sets the CanariesLastRun field's value. +func (s *DescribeCanariesLastRunOutput) SetCanariesLastRun(v []*CanaryLastRun) *DescribeCanariesLastRunOutput { + s.CanariesLastRun = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeCanariesLastRunOutput) SetNextToken(v string) *DescribeCanariesLastRunOutput { + s.NextToken = &v + return s +} + +type DescribeCanariesOutput struct { + _ struct{} `type:"structure"` + + // Returns an array. Each item in the array contains the full information about + // one canary. + Canaries []*Canary `type:"list"` + + // A token that indicates that there is more data available. You can use this + // token in a subsequent DescribeCanaries operation to retrieve the next set + // of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeCanariesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeCanariesOutput) GoString() string { + return s.String() +} + +// SetCanaries sets the Canaries field's value. +func (s *DescribeCanariesOutput) SetCanaries(v []*Canary) *DescribeCanariesOutput { + s.Canaries = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeCanariesOutput) SetNextToken(v string) *DescribeCanariesOutput { + s.NextToken = &v + return s +} + +type DescribeRuntimeVersionsInput struct { + _ struct{} `type:"structure"` + + // Specify this parameter to limit how many runs are returned each time you + // use the DescribeRuntimeVersions operation. If you omit this parameter, the + // default of 100 is used. + MaxResults *int64 `min:"1" type:"integer"` + + // A token that indicates that there is more data available. You can use this + // token in a subsequent DescribeRuntimeVersions operation to retrieve the next + // set of results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s DescribeRuntimeVersionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeRuntimeVersionsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeRuntimeVersionsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeRuntimeVersionsInput"} + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetMaxResults sets the MaxResults field's value. +func (s *DescribeRuntimeVersionsInput) SetMaxResults(v int64) *DescribeRuntimeVersionsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeRuntimeVersionsInput) SetNextToken(v string) *DescribeRuntimeVersionsInput { + s.NextToken = &v + return s +} + +type DescribeRuntimeVersionsOutput struct { + _ struct{} `type:"structure"` + + // A token that indicates that there is more data available. You can use this + // token in a subsequent DescribeRuntimeVersions operation to retrieve the next + // set of results. + NextToken *string `type:"string"` + + // An array of objects that display the details about each Synthetics canary + // runtime version. + RuntimeVersions []*RuntimeVersion `type:"list"` +} + +// String returns the string representation +func (s DescribeRuntimeVersionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeRuntimeVersionsOutput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *DescribeRuntimeVersionsOutput) SetNextToken(v string) *DescribeRuntimeVersionsOutput { + s.NextToken = &v + return s +} + +// SetRuntimeVersions sets the RuntimeVersions field's value. +func (s *DescribeRuntimeVersionsOutput) SetRuntimeVersions(v []*RuntimeVersion) *DescribeRuntimeVersionsOutput { + s.RuntimeVersions = v + return s +} + +type GetCanaryInput struct { + _ struct{} `type:"structure"` + + // The name of the canary that you want details for. + // + // Name is a required field + Name *string `location:"uri" locationName:"name" min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetCanaryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCanaryInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetCanaryInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetCanaryInput"} + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Name", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetName sets the Name field's value. +func (s *GetCanaryInput) SetName(v string) *GetCanaryInput { + s.Name = &v + return s +} + +type GetCanaryOutput struct { + _ struct{} `type:"structure"` + + // A strucure that contains the full information about the canary. + Canary *Canary `type:"structure"` +} + +// String returns the string representation +func (s GetCanaryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCanaryOutput) GoString() string { + return s.String() +} + +// SetCanary sets the Canary field's value. +func (s *GetCanaryOutput) SetCanary(v *Canary) *GetCanaryOutput { + s.Canary = v + return s +} + +type GetCanaryRunsInput struct { + _ struct{} `type:"structure"` + + // Specify this parameter to limit how many runs are returned each time you + // use the GetCanaryRuns operation. If you omit this parameter, the default + // of 100 is used. + MaxResults *int64 `min:"1" type:"integer"` + + // The name of the canary that you want to see runs for. + // + // Name is a required field + Name *string `location:"uri" locationName:"name" min:"1" type:"string" required:"true"` + + // A token that indicates that there is more data available. You can use this + // token in a subsequent GetCanaryRuns operation to retrieve the next set of + // results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s GetCanaryRunsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCanaryRunsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetCanaryRunsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetCanaryRunsInput"} + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Name", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetMaxResults sets the MaxResults field's value. +func (s *GetCanaryRunsInput) SetMaxResults(v int64) *GetCanaryRunsInput { + s.MaxResults = &v + return s +} + +// SetName sets the Name field's value. +func (s *GetCanaryRunsInput) SetName(v string) *GetCanaryRunsInput { + s.Name = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetCanaryRunsInput) SetNextToken(v string) *GetCanaryRunsInput { + s.NextToken = &v + return s +} + +type GetCanaryRunsOutput struct { + _ struct{} `type:"structure"` + + // An array of structures. Each structure contains the details of one of the + // retrieved canary runs. + CanaryRuns []*CanaryRun `type:"list"` + + // A token that indicates that there is more data available. You can use this + // token in a subsequent GetCanaryRuns operation to retrieve the next set of + // results. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s GetCanaryRunsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCanaryRunsOutput) GoString() string { + return s.String() +} + +// SetCanaryRuns sets the CanaryRuns field's value. +func (s *GetCanaryRunsOutput) SetCanaryRuns(v []*CanaryRun) *GetCanaryRunsOutput { + s.CanaryRuns = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetCanaryRunsOutput) SetNextToken(v string) *GetCanaryRunsOutput { + s.NextToken = &v + return s +} + +// An unknown internal error occurred. +type InternalServerException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"Message" type:"string"` +} + +// String returns the string representation +func (s InternalServerException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InternalServerException) GoString() string { + return s.String() +} + +func newErrorInternalServerException(v protocol.ResponseMetadata) error { + return &InternalServerException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *InternalServerException) Code() string { + return "InternalServerException" +} + +// Message returns the exception's message. +func (s *InternalServerException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *InternalServerException) OrigErr() error { + return nil +} + +func (s *InternalServerException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *InternalServerException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *InternalServerException) RequestID() string { + return s.RespMetadata.RequestID +} + +type ListTagsForResourceInput struct { + _ struct{} `type:"structure"` + + // The ARN of the canary that you want to view tags for. + // + // The ARN format of a canary is arn:aws:synthetics:Region:account-id:canary:canary-name . + // + // ResourceArn is a required field + ResourceArn *string `location:"uri" locationName:"resourceArn" type:"string" required:"true"` +} + +// String returns the string representation +func (s ListTagsForResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTagsForResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListTagsForResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListTagsForResourceInput"} + if s.ResourceArn == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceArn")) + } + if s.ResourceArn != nil && len(*s.ResourceArn) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceArn", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetResourceArn sets the ResourceArn field's value. +func (s *ListTagsForResourceInput) SetResourceArn(v string) *ListTagsForResourceInput { + s.ResourceArn = &v + return s +} + +type ListTagsForResourceOutput struct { + _ struct{} `type:"structure"` + + // The list of tag keys and values associated with the canary that you specified. + Tags map[string]*string `min:"1" type:"map"` +} + +// String returns the string representation +func (s ListTagsForResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTagsForResourceOutput) GoString() string { + return s.String() +} + +// SetTags sets the Tags field's value. +func (s *ListTagsForResourceOutput) SetTags(v map[string]*string) *ListTagsForResourceOutput { + s.Tags = v + return s +} + +// One of the specified resources was not found. +type ResourceNotFoundException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"Message" type:"string"` +} + +// String returns the string representation +func (s ResourceNotFoundException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResourceNotFoundException) GoString() string { + return s.String() +} + +func newErrorResourceNotFoundException(v protocol.ResponseMetadata) error { + return &ResourceNotFoundException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ResourceNotFoundException) Code() string { + return "ResourceNotFoundException" +} + +// Message returns the exception's message. +func (s *ResourceNotFoundException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ResourceNotFoundException) OrigErr() error { + return nil +} + +func (s *ResourceNotFoundException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ResourceNotFoundException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ResourceNotFoundException) RequestID() string { + return s.RespMetadata.RequestID +} + +// This structure contains information about one canary runtime version. For +// more information about runtime versions, see Canary Runtime Versions (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html). +type RuntimeVersion struct { + _ struct{} `type:"structure"` + + // If this runtime version is deprecated, this value is the date of deprecation. + DeprecationDate *time.Time `type:"timestamp"` + + // A description of the runtime version, created by Amazon. + Description *string `min:"1" type:"string"` + + // The date that the runtime version was released. + ReleaseDate *time.Time `type:"timestamp"` + + // The name of the runtime version. Currently, the only valid value is syn-1.0. + // + // Specifies the runtime version to use for the canary. Currently, the only + // valid value is syn-1.0. + VersionName *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s RuntimeVersion) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RuntimeVersion) GoString() string { + return s.String() +} + +// SetDeprecationDate sets the DeprecationDate field's value. +func (s *RuntimeVersion) SetDeprecationDate(v time.Time) *RuntimeVersion { + s.DeprecationDate = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *RuntimeVersion) SetDescription(v string) *RuntimeVersion { + s.Description = &v + return s +} + +// SetReleaseDate sets the ReleaseDate field's value. +func (s *RuntimeVersion) SetReleaseDate(v time.Time) *RuntimeVersion { + s.ReleaseDate = &v + return s +} + +// SetVersionName sets the VersionName field's value. +func (s *RuntimeVersion) SetVersionName(v string) *RuntimeVersion { + s.VersionName = &v + return s +} + +type StartCanaryInput struct { + _ struct{} `type:"structure"` + + // The name of the canary that you want to run. To find canary names, use DescribeCanaries. + // + // Name is a required field + Name *string `location:"uri" locationName:"name" min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s StartCanaryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StartCanaryInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *StartCanaryInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "StartCanaryInput"} + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Name", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetName sets the Name field's value. +func (s *StartCanaryInput) SetName(v string) *StartCanaryInput { + s.Name = &v + return s +} + +type StartCanaryOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s StartCanaryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StartCanaryOutput) GoString() string { + return s.String() +} + +type StopCanaryInput struct { + _ struct{} `type:"structure"` + + // The name of the canary that you want to stop. To find the names of your canaries, + // use DescribeCanaries. + // + // Name is a required field + Name *string `location:"uri" locationName:"name" min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s StopCanaryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StopCanaryInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *StopCanaryInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "StopCanaryInput"} + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Name", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetName sets the Name field's value. +func (s *StopCanaryInput) SetName(v string) *StopCanaryInput { + s.Name = &v + return s +} + +type StopCanaryOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s StopCanaryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StopCanaryOutput) GoString() string { + return s.String() +} + +type TagResourceInput struct { + _ struct{} `type:"structure"` + + // The ARN of the canary that you're adding tags to. + // + // The ARN format of a canary is arn:aws:synthetics:Region:account-id:canary:canary-name . + // + // ResourceArn is a required field + ResourceArn *string `location:"uri" locationName:"resourceArn" type:"string" required:"true"` + + // The list of key-value pairs to associate with the canary. + // + // Tags is a required field + Tags map[string]*string `min:"1" type:"map" required:"true"` +} + +// String returns the string representation +func (s TagResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TagResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *TagResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "TagResourceInput"} + if s.ResourceArn == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceArn")) + } + if s.ResourceArn != nil && len(*s.ResourceArn) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceArn", 1)) + } + if s.Tags == nil { + invalidParams.Add(request.NewErrParamRequired("Tags")) + } + if s.Tags != nil && len(s.Tags) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Tags", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetResourceArn sets the ResourceArn field's value. +func (s *TagResourceInput) SetResourceArn(v string) *TagResourceInput { + s.ResourceArn = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *TagResourceInput) SetTags(v map[string]*string) *TagResourceInput { + s.Tags = v + return s +} + +type TagResourceOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s TagResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TagResourceOutput) GoString() string { + return s.String() +} + +type UntagResourceInput struct { + _ struct{} `type:"structure"` + + // The ARN of the canary that you're removing tags from. + // + // The ARN format of a canary is arn:aws:synthetics:Region:account-id:canary:canary-name . + // + // ResourceArn is a required field + ResourceArn *string `location:"uri" locationName:"resourceArn" type:"string" required:"true"` + + // The list of tag keys to remove from the resource. + // + // TagKeys is a required field + TagKeys []*string `location:"querystring" locationName:"tagKeys" min:"1" type:"list" required:"true"` +} + +// String returns the string representation +func (s UntagResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UntagResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UntagResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UntagResourceInput"} + if s.ResourceArn == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceArn")) + } + if s.ResourceArn != nil && len(*s.ResourceArn) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceArn", 1)) + } + if s.TagKeys == nil { + invalidParams.Add(request.NewErrParamRequired("TagKeys")) + } + if s.TagKeys != nil && len(s.TagKeys) < 1 { + invalidParams.Add(request.NewErrParamMinLen("TagKeys", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetResourceArn sets the ResourceArn field's value. +func (s *UntagResourceInput) SetResourceArn(v string) *UntagResourceInput { + s.ResourceArn = &v + return s +} + +// SetTagKeys sets the TagKeys field's value. +func (s *UntagResourceInput) SetTagKeys(v []*string) *UntagResourceInput { + s.TagKeys = v + return s +} + +type UntagResourceOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s UntagResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UntagResourceOutput) GoString() string { + return s.String() +} + +type UpdateCanaryInput struct { + _ struct{} `type:"structure"` + + // A structure that includes the entry point from which the canary should start + // running your script. If the script is stored in an S3 bucket, the bucket + // name, key, and version are also included. + Code *CanaryCodeInput `type:"structure"` + + // The ARN of the IAM role to be used to run the canary. This role must already + // exist, and must include lambda.amazonaws.com as a principal in the trust + // policy. The role must also have the following permissions: + // + // * s3:PutObject + // + // * s3:GetBucketLocation + // + // * s3:ListAllMyBuckets + // + // * cloudwatch:PutMetricData + // + // * logs:CreateLogGroup + // + // * logs:CreateLogStream + // + // * logs:CreateLogStream + ExecutionRoleArn *string `type:"string"` + + // The number of days to retain data about failed runs of this canary. + FailureRetentionPeriodInDays *int64 `min:"1" type:"integer"` + + // The name of the canary that you want to update. To find the names of your + // canaries, use DescribeCanaries. + // + // You cannot change the name of a canary that has already been created. + // + // Name is a required field + Name *string `location:"uri" locationName:"name" min:"1" type:"string" required:"true"` + + // A structure that contains the timeout value that is used for each individual + // run of the canary. + RunConfig *CanaryRunConfigInput `type:"structure"` + + // Specifies the runtime version to use for the canary. Currently, the only + // valid value is syn-1.0. For more information about runtime versions, see + // Canary Runtime Versions (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_Library.html). + RuntimeVersion *string `min:"1" type:"string"` + + // A structure that contains information about how often the canary is to run, + // and when these runs are to stop. + Schedule *CanaryScheduleInput `type:"structure"` + + // The number of days to retain data about successful runs of this canary. + SuccessRetentionPeriodInDays *int64 `min:"1" type:"integer"` + + // If this canary is to test an endpoint in a VPC, this structure contains information + // about the subnet and security groups of the VPC endpoint. For more information, + // see Running a Canary in a VPC (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_VPC.html). + VpcConfig *VpcConfigInput `type:"structure"` +} + +// String returns the string representation +func (s UpdateCanaryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateCanaryInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateCanaryInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateCanaryInput"} + if s.FailureRetentionPeriodInDays != nil && *s.FailureRetentionPeriodInDays < 1 { + invalidParams.Add(request.NewErrParamMinValue("FailureRetentionPeriodInDays", 1)) + } + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Name", 1)) + } + if s.RuntimeVersion != nil && len(*s.RuntimeVersion) < 1 { + invalidParams.Add(request.NewErrParamMinLen("RuntimeVersion", 1)) + } + if s.SuccessRetentionPeriodInDays != nil && *s.SuccessRetentionPeriodInDays < 1 { + invalidParams.Add(request.NewErrParamMinValue("SuccessRetentionPeriodInDays", 1)) + } + if s.Code != nil { + if err := s.Code.Validate(); err != nil { + invalidParams.AddNested("Code", err.(request.ErrInvalidParams)) + } + } + if s.RunConfig != nil { + if err := s.RunConfig.Validate(); err != nil { + invalidParams.AddNested("RunConfig", err.(request.ErrInvalidParams)) + } + } + if s.Schedule != nil { + if err := s.Schedule.Validate(); err != nil { + invalidParams.AddNested("Schedule", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCode sets the Code field's value. +func (s *UpdateCanaryInput) SetCode(v *CanaryCodeInput) *UpdateCanaryInput { + s.Code = v + return s +} + +// SetExecutionRoleArn sets the ExecutionRoleArn field's value. +func (s *UpdateCanaryInput) SetExecutionRoleArn(v string) *UpdateCanaryInput { + s.ExecutionRoleArn = &v + return s +} + +// SetFailureRetentionPeriodInDays sets the FailureRetentionPeriodInDays field's value. +func (s *UpdateCanaryInput) SetFailureRetentionPeriodInDays(v int64) *UpdateCanaryInput { + s.FailureRetentionPeriodInDays = &v + return s +} + +// SetName sets the Name field's value. +func (s *UpdateCanaryInput) SetName(v string) *UpdateCanaryInput { + s.Name = &v + return s +} + +// SetRunConfig sets the RunConfig field's value. +func (s *UpdateCanaryInput) SetRunConfig(v *CanaryRunConfigInput) *UpdateCanaryInput { + s.RunConfig = v + return s +} + +// SetRuntimeVersion sets the RuntimeVersion field's value. +func (s *UpdateCanaryInput) SetRuntimeVersion(v string) *UpdateCanaryInput { + s.RuntimeVersion = &v + return s +} + +// SetSchedule sets the Schedule field's value. +func (s *UpdateCanaryInput) SetSchedule(v *CanaryScheduleInput) *UpdateCanaryInput { + s.Schedule = v + return s +} + +// SetSuccessRetentionPeriodInDays sets the SuccessRetentionPeriodInDays field's value. +func (s *UpdateCanaryInput) SetSuccessRetentionPeriodInDays(v int64) *UpdateCanaryInput { + s.SuccessRetentionPeriodInDays = &v + return s +} + +// SetVpcConfig sets the VpcConfig field's value. +func (s *UpdateCanaryInput) SetVpcConfig(v *VpcConfigInput) *UpdateCanaryInput { + s.VpcConfig = v + return s +} + +type UpdateCanaryOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s UpdateCanaryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateCanaryOutput) GoString() string { + return s.String() +} + +// A parameter could not be validated. +type ValidationException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + Message_ *string `locationName:"Message" type:"string"` +} + +// String returns the string representation +func (s ValidationException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ValidationException) GoString() string { + return s.String() +} + +func newErrorValidationException(v protocol.ResponseMetadata) error { + return &ValidationException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *ValidationException) Code() string { + return "ValidationException" +} + +// Message returns the exception's message. +func (s *ValidationException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *ValidationException) OrigErr() error { + return nil +} + +func (s *ValidationException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *ValidationException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *ValidationException) RequestID() string { + return s.RespMetadata.RequestID +} + +// If this canary is to test an endpoint in a VPC, this structure contains information +// about the subnets and security groups of the VPC endpoint. For more information, +// see Running a Canary in a VPC (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_VPC.html). +type VpcConfigInput struct { + _ struct{} `type:"structure"` + + // The IDs of the security groups for this canary. + SecurityGroupIds []*string `type:"list"` + + // The IDs of the subnets where this canary is to run. + SubnetIds []*string `type:"list"` +} + +// String returns the string representation +func (s VpcConfigInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcConfigInput) GoString() string { + return s.String() +} + +// SetSecurityGroupIds sets the SecurityGroupIds field's value. +func (s *VpcConfigInput) SetSecurityGroupIds(v []*string) *VpcConfigInput { + s.SecurityGroupIds = v + return s +} + +// SetSubnetIds sets the SubnetIds field's value. +func (s *VpcConfigInput) SetSubnetIds(v []*string) *VpcConfigInput { + s.SubnetIds = v + return s +} + +// If this canary is to test an endpoint in a VPC, this structure contains information +// about the subnets and security groups of the VPC endpoint. For more information, +// see Running a Canary in a VPC (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_VPC.html). +type VpcConfigOutput struct { + _ struct{} `type:"structure"` + + // The IDs of the security groups for this canary. + SecurityGroupIds []*string `type:"list"` + + // The IDs of the subnets where this canary is to run. + SubnetIds []*string `type:"list"` + + // The IDs of the VPC where this canary is to run. + VpcId *string `type:"string"` +} + +// String returns the string representation +func (s VpcConfigOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VpcConfigOutput) GoString() string { + return s.String() +} + +// SetSecurityGroupIds sets the SecurityGroupIds field's value. +func (s *VpcConfigOutput) SetSecurityGroupIds(v []*string) *VpcConfigOutput { + s.SecurityGroupIds = v + return s +} + +// SetSubnetIds sets the SubnetIds field's value. +func (s *VpcConfigOutput) SetSubnetIds(v []*string) *VpcConfigOutput { + s.SubnetIds = v + return s +} + +// SetVpcId sets the VpcId field's value. +func (s *VpcConfigOutput) SetVpcId(v string) *VpcConfigOutput { + s.VpcId = &v + return s +} + +const ( + // CanaryRunStateRunning is a CanaryRunState enum value + CanaryRunStateRunning = "RUNNING" + + // CanaryRunStatePassed is a CanaryRunState enum value + CanaryRunStatePassed = "PASSED" + + // CanaryRunStateFailed is a CanaryRunState enum value + CanaryRunStateFailed = "FAILED" +) + +const ( + // CanaryRunStateReasonCodeCanaryFailure is a CanaryRunStateReasonCode enum value + CanaryRunStateReasonCodeCanaryFailure = "CANARY_FAILURE" + + // CanaryRunStateReasonCodeExecutionFailure is a CanaryRunStateReasonCode enum value + CanaryRunStateReasonCodeExecutionFailure = "EXECUTION_FAILURE" +) + +const ( + // CanaryStateCreating is a CanaryState enum value + CanaryStateCreating = "CREATING" + + // CanaryStateReady is a CanaryState enum value + CanaryStateReady = "READY" + + // CanaryStateStarting is a CanaryState enum value + CanaryStateStarting = "STARTING" + + // CanaryStateRunning is a CanaryState enum value + CanaryStateRunning = "RUNNING" + + // CanaryStateUpdating is a CanaryState enum value + CanaryStateUpdating = "UPDATING" + + // CanaryStateStopping is a CanaryState enum value + CanaryStateStopping = "STOPPING" + + // CanaryStateStopped is a CanaryState enum value + CanaryStateStopped = "STOPPED" + + // CanaryStateError is a CanaryState enum value + CanaryStateError = "ERROR" + + // CanaryStateDeleting is a CanaryState enum value + CanaryStateDeleting = "DELETING" +) + +const ( + // CanaryStateReasonCodeInvalidPermissions is a CanaryStateReasonCode enum value + CanaryStateReasonCodeInvalidPermissions = "INVALID_PERMISSIONS" +) diff --git a/vendor/github.com/aws/aws-sdk-go/service/synthetics/doc.go b/vendor/github.com/aws/aws-sdk-go/service/synthetics/doc.go new file mode 100644 index 00000000000..8a25de917d0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/synthetics/doc.go @@ -0,0 +1,42 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package synthetics provides the client and types for making API +// requests to Synthetics. +// +// You can use Amazon CloudWatch Synthetics to continually monitor your services. +// You can create and manage canaries, which are modular, lightweight scripts +// that monitor your endpoints and APIs from the outside-in. You can set up +// your canaries to run 24 hours a day, once per minute. The canaries help you +// check the availability and latency of your web services and troubleshoot +// anomalies by investigating load time data, screenshots of the UI, logs, and +// metrics. The canaries seamlessly integrate with CloudWatch ServiceLens to +// help you trace the causes of impacted nodes in your applications. For more +// information, see Using ServiceLens to Monitor the Health of Your Applications +// (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ServiceLens.html) +// in the Amazon CloudWatch User Guide. +// +// Before you create and manage canaries, be aware of the security considerations. +// For more information, see Security Considerations for Synthetics Canaries +// (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/servicelens_canaries_security.html). +// +// See https://docs.aws.amazon.com/goto/WebAPI/synthetics-2017-10-11 for more information on this service. +// +// See synthetics package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/synthetics/ +// +// Using the Client +// +// To contact Synthetics with the SDK use the New function to create +// a new service client. With that client you can make API requests to the service. +// These clients are safe to use concurrently. +// +// See the SDK's documentation for more information on how to use the SDK. +// https://docs.aws.amazon.com/sdk-for-go/api/ +// +// See aws.Config documentation for more information on configuring SDK clients. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// See the Synthetics client Synthetics for more +// information on creating client for this service. +// https://docs.aws.amazon.com/sdk-for-go/api/service/synthetics/#New +package synthetics diff --git a/vendor/github.com/aws/aws-sdk-go/service/synthetics/errors.go b/vendor/github.com/aws/aws-sdk-go/service/synthetics/errors.go new file mode 100644 index 00000000000..28559807882 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/synthetics/errors.go @@ -0,0 +1,41 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package synthetics + +import ( + "github.com/aws/aws-sdk-go/private/protocol" +) + +const ( + + // ErrCodeConflictException for service response error code + // "ConflictException". + // + // A conflicting operation is already in progress. + ErrCodeConflictException = "ConflictException" + + // ErrCodeInternalServerException for service response error code + // "InternalServerException". + // + // An unknown internal error occurred. + ErrCodeInternalServerException = "InternalServerException" + + // ErrCodeResourceNotFoundException for service response error code + // "ResourceNotFoundException". + // + // One of the specified resources was not found. + ErrCodeResourceNotFoundException = "ResourceNotFoundException" + + // ErrCodeValidationException for service response error code + // "ValidationException". + // + // A parameter could not be validated. + ErrCodeValidationException = "ValidationException" +) + +var exceptionFromCode = map[string]func(protocol.ResponseMetadata) error{ + "ConflictException": newErrorConflictException, + "InternalServerException": newErrorInternalServerException, + "ResourceNotFoundException": newErrorResourceNotFoundException, + "ValidationException": newErrorValidationException, +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/synthetics/service.go b/vendor/github.com/aws/aws-sdk-go/service/synthetics/service.go new file mode 100644 index 00000000000..e957283a593 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/synthetics/service.go @@ -0,0 +1,104 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package synthetics + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/signer/v4" + "github.com/aws/aws-sdk-go/private/protocol" + "github.com/aws/aws-sdk-go/private/protocol/restjson" +) + +// Synthetics provides the API operation methods for making requests to +// Synthetics. See this package's package overview docs +// for details on the service. +// +// Synthetics methods are safe to use concurrently. It is not safe to +// modify mutate any of the struct's properties though. +type Synthetics struct { + *client.Client +} + +// Used for custom client initialization logic +var initClient func(*client.Client) + +// Used for custom request initialization logic +var initRequest func(*request.Request) + +// Service information constants +const ( + ServiceName = "synthetics" // Name of service. + EndpointsID = ServiceName // ID to lookup a service endpoint with. + ServiceID = "synthetics" // ServiceID is a unique identifier of a specific service. +) + +// New creates a new instance of the Synthetics client with a session. +// If additional configuration is needed for the client instance use the optional +// aws.Config parameter to add your extra config. +// +// Example: +// mySession := session.Must(session.NewSession()) +// +// // Create a Synthetics client from just a session. +// svc := synthetics.New(mySession) +// +// // Create a Synthetics client with additional configuration +// svc := synthetics.New(mySession, aws.NewConfig().WithRegion("us-west-2")) +func New(p client.ConfigProvider, cfgs ...*aws.Config) *Synthetics { + c := p.ClientConfig(EndpointsID, cfgs...) + if c.SigningNameDerived || len(c.SigningName) == 0 { + c.SigningName = "synthetics" + } + return newClient(*c.Config, c.Handlers, c.PartitionID, c.Endpoint, c.SigningRegion, c.SigningName) +} + +// newClient creates, initializes and returns a new service client instance. +func newClient(cfg aws.Config, handlers request.Handlers, partitionID, endpoint, signingRegion, signingName string) *Synthetics { + svc := &Synthetics{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: ServiceName, + ServiceID: ServiceID, + SigningName: signingName, + SigningRegion: signingRegion, + PartitionID: partitionID, + Endpoint: endpoint, + APIVersion: "2017-10-11", + }, + handlers, + ), + } + + // Handlers + svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) + svc.Handlers.Build.PushBackNamed(restjson.BuildHandler) + svc.Handlers.Unmarshal.PushBackNamed(restjson.UnmarshalHandler) + svc.Handlers.UnmarshalMeta.PushBackNamed(restjson.UnmarshalMetaHandler) + svc.Handlers.UnmarshalError.PushBackNamed( + protocol.NewUnmarshalErrorHandler(restjson.NewUnmarshalTypedError(exceptionFromCode)).NamedHandler(), + ) + + // Run custom client initialization if present + if initClient != nil { + initClient(svc.Client) + } + + return svc +} + +// newRequest creates a new request for a Synthetics operation and runs any +// custom request initialization. +func (c *Synthetics) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) + + // Run custom request initialization if present + if initRequest != nil { + initRequest(req) + } + + return req +} diff --git a/vendor/modules.txt b/vendor/modules.txt index ed4f920a8a3..68fe7d51316 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -201,6 +201,7 @@ github.com/aws/aws-sdk-go/service/storagegateway github.com/aws/aws-sdk-go/service/sts github.com/aws/aws-sdk-go/service/sts/stsiface github.com/aws/aws-sdk-go/service/swf +github.com/aws/aws-sdk-go/service/synthetics github.com/aws/aws-sdk-go/service/transfer github.com/aws/aws-sdk-go/service/waf github.com/aws/aws-sdk-go/service/wafregional diff --git a/website/docs/guides/custom-service-endpoints.html.md b/website/docs/guides/custom-service-endpoints.html.md index e186ac084c3..9fd1283d101 100644 --- a/website/docs/guides/custom-service-endpoints.html.md +++ b/website/docs/guides/custom-service-endpoints.html.md @@ -184,6 +184,7 @@ The Terraform AWS Provider allows the following endpoints to be customized:
  • storagegateway
  • sts
  • swf
  • +
  • synthetics
  • transfer
  • waf
  • wafregional
  • From 14c139d67eb1129c790d2bcd516ef7e40b440eac Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Fri, 15 May 2020 12:13:53 -0400 Subject: [PATCH 167/475] website: Add Synthetics to allowed subcategories --- website/allowed-subcategories.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/website/allowed-subcategories.txt b/website/allowed-subcategories.txt index fbb7b427f17..a2c24398725 100644 --- a/website/allowed-subcategories.txt +++ b/website/allowed-subcategories.txt @@ -102,6 +102,7 @@ Shield SimpleDB Step Function (SFN) Storage Gateway +Synthetics Transfer Transit Gateway Network Manager VPC From 9eb4e157ec9cbf919685657e62f56ccfc15b9e94 Mon Sep 17 00:00:00 2001 From: Pascal van Buijtene Date: Fri, 15 May 2020 18:27:51 +0200 Subject: [PATCH 168/475] Apply review changes --- aws/resource_aws_wafv2_ip_set.go | 5 +++-- website/docs/r/wafv2_ip_set.html.markdown | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/aws/resource_aws_wafv2_ip_set.go b/aws/resource_aws_wafv2_ip_set.go index 2019da2293e..da0f648e772 100644 --- a/aws/resource_aws_wafv2_ip_set.go +++ b/aws/resource_aws_wafv2_ip_set.go @@ -177,9 +177,10 @@ func resourceAwsWafv2IPSetRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("Error setting addresses: %s", err) } - tags, err := keyvaluetags.Wafv2ListTags(conn, aws.StringValue(resp.IPSet.ARN)) + arn := aws.StringValue(resp.IPSet.ARN) + tags, err := keyvaluetags.Wafv2ListTags(conn, arn) if err != nil { - return fmt.Errorf("Error listing tags for WAFv2 IpSet (%s): %s", *resp.IPSet.ARN, err) + return fmt.Errorf("Error listing tags for WAFv2 IpSet (%s): %s", arn, err) } if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { diff --git a/website/docs/r/wafv2_ip_set.html.markdown b/website/docs/r/wafv2_ip_set.html.markdown index 7b36423fee2..10fa926bbe6 100644 --- a/website/docs/r/wafv2_ip_set.html.markdown +++ b/website/docs/r/wafv2_ip_set.html.markdown @@ -47,7 +47,7 @@ In addition to all arguments above, the following attributes are exported: ## Import -WAFv2 IP Sets can be imported using their ID, Name and Scope e.g. +WAFv2 IP Sets can be imported using `ID/name/scope` ``` $ terraform import aws_wafv2_ip_set.example a1b2c3d4-d5f6-7777-8888-9999aaaabbbbcccc/example/REGIONAL From 748f9428c9707e8a48de3e03bc76d3dd1668a735 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 15 May 2020 13:36:55 -0400 Subject: [PATCH 169/475] move assume_role test to provider testing --- aws/data_source_aws_caller_identity_test.go | 26 --------------------- aws/provider.go | 24 +++++++++++-------- aws/provider_test.go | 24 +++++++++++++++++++ 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/aws/data_source_aws_caller_identity_test.go b/aws/data_source_aws_caller_identity_test.go index 5d065d3ca90..d9857323574 100644 --- a/aws/data_source_aws_caller_identity_test.go +++ b/aws/data_source_aws_caller_identity_test.go @@ -23,23 +23,6 @@ func TestAccAWSCallerIdentity_basic(t *testing.T) { }) } -// Protects against a panic in the AWS Provider configuration. -// See https://github.com/terraform-providers/terraform-provider-aws/pull/1227 -func TestAccAWSCallerIdentity_basic_panic(t *testing.T) { - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: []resource.TestStep{ - { - Config: testAccCheckAwsCallerIdentityConfig_basic_panic, - Check: resource.ComposeTestCheckFunc( - testAccCheckAwsCallerIdentityAccountId("data.aws_caller_identity.current"), - ), - }, - }, - }) -} - func testAccCheckAwsCallerIdentityAccountId(n string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -71,12 +54,3 @@ func testAccCheckAwsCallerIdentityAccountId(n string) resource.TestCheckFunc { const testAccCheckAwsCallerIdentityConfig_basic = ` data "aws_caller_identity" "current" { } ` - -const testAccCheckAwsCallerIdentityConfig_basic_panic = ` -provider "aws" { - assume_role { - } -} - -data "aws_caller_identity" "current" {} -` diff --git a/aws/provider.go b/aws/provider.go index e164c302d06..b9ff82490d7 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -1170,17 +1170,21 @@ func providerConfigure(d *schema.ResourceData, terraformVersion string) (interfa assumeRoleList := d.Get("assume_role").([]interface{}) if len(assumeRoleList) == 1 { - assumeRole := assumeRoleList[0].(map[string]interface{}) - config.AssumeRoleARN = assumeRole["role_arn"].(string) - config.AssumeRoleSessionName = assumeRole["session_name"].(string) - config.AssumeRoleExternalID = assumeRole["external_id"].(string) - - if v := assumeRole["policy"].(string); v != "" { - config.AssumeRolePolicy = v + if assumeRoleList[0] != nil { + assumeRole := assumeRoleList[0].(map[string]interface{}) + config.AssumeRoleARN = assumeRole["role_arn"].(string) + config.AssumeRoleSessionName = assumeRole["session_name"].(string) + config.AssumeRoleExternalID = assumeRole["external_id"].(string) + + if v := assumeRole["policy"].(string); v != "" { + config.AssumeRolePolicy = v + } + + log.Printf("[INFO] assume_role configuration set: (ARN: %q, SessionID: %q, ExternalID: %q, Policy: %q)", + config.AssumeRoleARN, config.AssumeRoleSessionName, config.AssumeRoleExternalID, config.AssumeRolePolicy) + } else { + log.Printf("[INFO] Empty assume_role block read from configuration") } - - log.Printf("[INFO] assume_role configuration set: (ARN: %q, SessionID: %q, ExternalID: %q, Policy: %q)", - config.AssumeRoleARN, config.AssumeRoleSessionName, config.AssumeRoleExternalID, config.AssumeRolePolicy) } else { log.Printf("[INFO] No assume_role block read from configuration") } diff --git a/aws/provider_test.go b/aws/provider_test.go index cb69efd2e09..4b6f03b4621 100644 --- a/aws/provider_test.go +++ b/aws/provider_test.go @@ -943,6 +943,21 @@ func TestAccAWSProvider_Region_AwsGovCloudUs(t *testing.T) { }) } +func TestAccAWSProvider_AssumeRole_Empty(t *testing.T) { + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccCheckAWSProviderConfigAssumeRoleEmpty, + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsCallerIdentityAccountId("data.aws_caller_identity.current"), + ), + }, + }, + }) +} + func testAccCheckAWSProviderDnsSuffix(providers *[]*schema.Provider, expectedDnsSuffix string) resource.TestCheckFunc { return func(s *terraform.State) error { if providers == nil { @@ -1465,6 +1480,15 @@ provider "aws" { `, os.Getenv("TF_ACC_ASSUME_ROLE_ARN"), policy) } +const testAccCheckAWSProviderConfigAssumeRoleEmpty = ` +provider "aws" { + assume_role { + } +} + +data "aws_caller_identity" "current" {} +` + // composeConfig can be called to concatenate multiple strings to build test configurations func composeConfig(config ...string) string { var str strings.Builder From bde53b2986ab166ef52f594f54b61c7c6cd42e20 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 15 May 2020 14:07:27 -0400 Subject: [PATCH 170/475] add missing attributes to testcheck --- aws/provider_test.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/aws/provider_test.go b/aws/provider_test.go index 4b6f03b4621..ec8c76203b3 100644 --- a/aws/provider_test.go +++ b/aws/provider_test.go @@ -944,9 +944,12 @@ func TestAccAWSProvider_Region_AwsGovCloudUs(t *testing.T) { } func TestAccAWSProvider_AssumeRole_Empty(t *testing.T) { + var providers []*schema.Provider + resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: testAccProviderFactories(&providers), + CheckDestroy: nil, Steps: []resource.TestStep{ { Config: testAccCheckAWSProviderConfigAssumeRoleEmpty, From 012864647ddbd4c05361335cda9e370a86fb4d26 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 7 Feb 2020 18:34:53 +0200 Subject: [PATCH 171/475] add support for efs iam policy --- aws/resource_aws_efs_file_system.go | 57 +++++++++++++++ aws/resource_aws_efs_file_system_test.go | 73 ++++++++++++++++++++ website/docs/r/efs_file_system.html.markdown | 34 +++++++++ 3 files changed, 164 insertions(+) diff --git a/aws/resource_aws_efs_file_system.go b/aws/resource_aws_efs_file_system.go index edb5027f5ef..85a5facb2e3 100644 --- a/aws/resource_aws_efs_file_system.go +++ b/aws/resource_aws_efs_file_system.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "log" + "strings" "time" "github.com/aws/aws-sdk-go/aws" @@ -115,6 +116,12 @@ func resourceAwsEfsFileSystem() *schema.Resource { }, }, }, + "policy": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.ValidateJsonString, + DiffSuppressFunc: suppressEquivalentJsonDiffs, + }, }, } } @@ -195,6 +202,16 @@ func resourceAwsEfsFileSystemCreate(d *schema.ResourceData, meta interface{}) er } } + if v, ok := d.GetOk("policy"); ok && v.(string) != "" { + _, err := conn.PutFileSystemPolicy(&efs.PutFileSystemPolicyInput{ + FileSystemId: aws.String(d.Id()), + Policy: aws.String(v.(string)), + }) + if err != nil { + return fmt.Errorf("Error creating policy for EFS file system %q: %s", d.Id(), err.Error()) + } + } + return resourceAwsEfsFileSystemRead(d, meta) } @@ -253,6 +270,27 @@ func resourceAwsEfsFileSystemUpdate(d *schema.ResourceData, meta interface{}) er } } + if d.HasChange("policy") { + _, n := d.GetChange("policy") + + if n.(string) != "" { + _, err := conn.PutFileSystemPolicy(&efs.PutFileSystemPolicyInput{ + FileSystemId: aws.String(d.Id()), + Policy: aws.String(d.Get("policy").(string)), + }) + if err != nil { + return fmt.Errorf("Error updating policy for EFS file system %q: %s", d.Id(), err.Error()) + } + } else { + _, err := conn.DeleteFileSystemPolicy(&efs.DeleteFileSystemPolicyInput{ + FileSystemId: aws.String(d.Id()), + }) + if err != nil { + return fmt.Errorf("Error removing policy for EFS file system %q: %s", d.Id(), err.Error()) + } + } + } + if d.HasChange("tags") { o, n := d.GetChange("tags") @@ -331,6 +369,25 @@ func resourceAwsEfsFileSystemRead(d *schema.ResourceData, meta interface{}) erro return fmt.Errorf("error setting lifecycle_policy: %s", err) } + var policyRes *efs.DescribeFileSystemPolicyOutput + policyRes, err = conn.DescribeFileSystemPolicy(&efs.DescribeFileSystemPolicyInput{ + FileSystemId: fs.FileSystemId, + }) + if err != nil { + if isAWSErr(err, efs.ErrCodePolicyNotFound, "") { + d.Set("policy", "") + } else { + return fmt.Errorf("Error describing policy for EFS file system (%s): %s", + aws.StringValue(fs.FileSystemId), err) + } + } else { + correctedPolicy := strings.Replace(aws.StringValue(policyRes.Policy), + fmt.Sprintf("\"Resource\" : \"%s\",", fsARN), "", 1) + if err := d.Set("policy", correctedPolicy); err != nil { + return err + } + } + return nil } diff --git a/aws/resource_aws_efs_file_system_test.go b/aws/resource_aws_efs_file_system_test.go index 87e02b8b9a0..ba45739c15d 100644 --- a/aws/resource_aws_efs_file_system_test.go +++ b/aws/resource_aws_efs_file_system_test.go @@ -431,6 +431,47 @@ func TestAccAWSEFSFileSystem_lifecyclePolicy_removal(t *testing.T) { }) } +func TestAccAWSEFSFileSystem_policy(t *testing.T) { + var desc efs.FileSystemDescription + resourceName := "aws_efs_file_system.test" + rName := acctest.RandomWithPrefix("tf-acc") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckEfsFileSystemDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSEFSFileSystemConfigWPolicy(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckEfsFileSystem(resourceName, &desc), + resource.TestCheckResourceAttrSet(resourceName, "policy"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"creation_token"}, + }, + { + Config: testAccAWSEFSFileSystemConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckEfsFileSystem("aws_efs_file_system.test", &desc), + resource.TestCheckResourceAttr(resourceName, "policy", ""), + ), + }, + { + Config: testAccAWSEFSFileSystemConfigWPolicy(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckEfsFileSystem(resourceName, &desc), + resource.TestCheckResourceAttrSet(resourceName, "policy"), + ), + }, + }, + }) +} + func TestAccAWSEFSFileSystem_disappears(t *testing.T) { var desc efs.FileSystemDescription resourceName := "aws_efs_file_system.test" @@ -630,6 +671,38 @@ resource "aws_efs_file_system" "test" { `, rName) } +func testAccAWSEFSFileSystemConfigWPolicy(rName string) string { + return fmt.Sprintf(` +resource "aws_efs_file_system" "test" { + creation_token = %q + policy = < Date: Fri, 7 Feb 2020 19:07:07 +0200 Subject: [PATCH 172/475] efs file system data source - add support for policy --- aws/data_source_aws_efs_file_system.go | 24 ++++++++++++++++++++ aws/data_source_aws_efs_file_system_test.go | 2 ++ website/docs/d/efs_file_system.html.markdown | 1 + 3 files changed, 27 insertions(+) diff --git a/aws/data_source_aws_efs_file_system.go b/aws/data_source_aws_efs_file_system.go index e7cf6e66165..8e858f006b2 100644 --- a/aws/data_source_aws_efs_file_system.go +++ b/aws/data_source_aws_efs_file_system.go @@ -3,6 +3,7 @@ package aws import ( "fmt" "log" + "strings" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" @@ -73,6 +74,10 @@ func dataSourceAwsEfsFileSystem() *schema.Resource { }, }, }, + "policy": { + Type: schema.TypeString, + Computed: true, + }, }, } } @@ -152,6 +157,25 @@ func dataSourceAwsEfsFileSystemRead(d *schema.ResourceData, meta interface{}) er return fmt.Errorf("error setting lifecycle_policy: %s", err) } + var policyRes *efs.DescribeFileSystemPolicyOutput + policyRes, err = efsconn.DescribeFileSystemPolicy(&efs.DescribeFileSystemPolicyInput{ + FileSystemId: fs.FileSystemId, + }) + if err != nil { + if isAWSErr(err, efs.ErrCodePolicyNotFound, "") { + d.Set("policy", "") + } else { + return fmt.Errorf("Error describing policy for EFS file system (%s): %s", + aws.StringValue(fs.FileSystemId), err) + } + } else { + correctedPolicy := strings.Replace(aws.StringValue(policyRes.Policy), + fmt.Sprintf("\"Resource\" : \"%s\",", fsARN), "", 1) + if err := d.Set("policy", correctedPolicy); err != nil { + return err + } + } + d.Set("dns_name", meta.(*AWSClient).RegionalHostname(fmt.Sprintf("%s.efs", aws.StringValue(fs.FileSystemId)))) return nil diff --git a/aws/data_source_aws_efs_file_system_test.go b/aws/data_source_aws_efs_file_system_test.go index f0dd41d7c47..c253e550cfd 100644 --- a/aws/data_source_aws_efs_file_system_test.go +++ b/aws/data_source_aws_efs_file_system_test.go @@ -32,6 +32,7 @@ func TestAccDataSourceAwsEfsFileSystem_id(t *testing.T) { resource.TestCheckResourceAttrPair(dataSourceName, "throughput_mode", resourceName, "throughput_mode"), resource.TestCheckResourceAttrPair(dataSourceName, "lifecycle_policy", resourceName, "lifecycle_policy"), resource.TestMatchResourceAttr(dataSourceName, "size_in_bytes", regexp.MustCompile(`^\d+$`)), + resource.TestCheckResourceAttrPair(dataSourceName, "policy", resourceName, "policy"), ), }, }, @@ -60,6 +61,7 @@ func TestAccDataSourceAwsEfsFileSystem_name(t *testing.T) { resource.TestCheckResourceAttrPair(dataSourceName, "provisioned_throughput_in_mibps", resourceName, "provisioned_throughput_in_mibps"), resource.TestCheckResourceAttrPair(dataSourceName, "throughput_mode", resourceName, "throughput_mode"), resource.TestCheckResourceAttrPair(dataSourceName, "lifecycle_policy", resourceName, "lifecycle_policy"), + resource.TestCheckResourceAttrPair(dataSourceName, "policy", resourceName, "policy"), resource.TestMatchResourceAttr(dataSourceName, "size_in_bytes", regexp.MustCompile(`^\d+$`)), ), }, diff --git a/website/docs/d/efs_file_system.html.markdown b/website/docs/d/efs_file_system.html.markdown index 75da4112e39..eef0a8f8c47 100644 --- a/website/docs/d/efs_file_system.html.markdown +++ b/website/docs/d/efs_file_system.html.markdown @@ -44,3 +44,4 @@ In addition to all arguments above, the following attributes are exported: * `tags` -A map of tags to assign to the file system. * `throughput_mode` - Throughput mode for the file system. * `size_in_bytes` - The current byte count used by the file system. +* `policy` - The JSON formatted file system policy for the EFS file system. From 4314130035cd1816c76dea43dfd264ba6ea00e1f Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Tue, 14 Apr 2020 19:48:21 +0300 Subject: [PATCH 173/475] fmt --- website/docs/r/efs_file_system.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/efs_file_system.html.markdown b/website/docs/r/efs_file_system.html.markdown index f9901b998a8..c5661a46864 100644 --- a/website/docs/r/efs_file_system.html.markdown +++ b/website/docs/r/efs_file_system.html.markdown @@ -42,7 +42,7 @@ resource "aws_efs_file_system" "foo_with_lifecyle_policy" { resource "aws_efs_file_system" "foo_with_lifecyle_policy" { creation_token = "my-product" - policy = < Date: Fri, 15 May 2020 17:41:20 +0300 Subject: [PATCH 174/475] split efs policy to its own resource --- aws/data_source_aws_efs_file_system.go | 24 ------- aws/data_source_aws_efs_file_system_test.go | 2 - aws/provider.go | 1 + aws/resource_aws_efs_file_system.go | 57 ---------------- aws/resource_aws_efs_file_system_test.go | 73 --------------------- 5 files changed, 1 insertion(+), 156 deletions(-) diff --git a/aws/data_source_aws_efs_file_system.go b/aws/data_source_aws_efs_file_system.go index 8e858f006b2..e7cf6e66165 100644 --- a/aws/data_source_aws_efs_file_system.go +++ b/aws/data_source_aws_efs_file_system.go @@ -3,7 +3,6 @@ package aws import ( "fmt" "log" - "strings" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" @@ -74,10 +73,6 @@ func dataSourceAwsEfsFileSystem() *schema.Resource { }, }, }, - "policy": { - Type: schema.TypeString, - Computed: true, - }, }, } } @@ -157,25 +152,6 @@ func dataSourceAwsEfsFileSystemRead(d *schema.ResourceData, meta interface{}) er return fmt.Errorf("error setting lifecycle_policy: %s", err) } - var policyRes *efs.DescribeFileSystemPolicyOutput - policyRes, err = efsconn.DescribeFileSystemPolicy(&efs.DescribeFileSystemPolicyInput{ - FileSystemId: fs.FileSystemId, - }) - if err != nil { - if isAWSErr(err, efs.ErrCodePolicyNotFound, "") { - d.Set("policy", "") - } else { - return fmt.Errorf("Error describing policy for EFS file system (%s): %s", - aws.StringValue(fs.FileSystemId), err) - } - } else { - correctedPolicy := strings.Replace(aws.StringValue(policyRes.Policy), - fmt.Sprintf("\"Resource\" : \"%s\",", fsARN), "", 1) - if err := d.Set("policy", correctedPolicy); err != nil { - return err - } - } - d.Set("dns_name", meta.(*AWSClient).RegionalHostname(fmt.Sprintf("%s.efs", aws.StringValue(fs.FileSystemId)))) return nil diff --git a/aws/data_source_aws_efs_file_system_test.go b/aws/data_source_aws_efs_file_system_test.go index c253e550cfd..f0dd41d7c47 100644 --- a/aws/data_source_aws_efs_file_system_test.go +++ b/aws/data_source_aws_efs_file_system_test.go @@ -32,7 +32,6 @@ func TestAccDataSourceAwsEfsFileSystem_id(t *testing.T) { resource.TestCheckResourceAttrPair(dataSourceName, "throughput_mode", resourceName, "throughput_mode"), resource.TestCheckResourceAttrPair(dataSourceName, "lifecycle_policy", resourceName, "lifecycle_policy"), resource.TestMatchResourceAttr(dataSourceName, "size_in_bytes", regexp.MustCompile(`^\d+$`)), - resource.TestCheckResourceAttrPair(dataSourceName, "policy", resourceName, "policy"), ), }, }, @@ -61,7 +60,6 @@ func TestAccDataSourceAwsEfsFileSystem_name(t *testing.T) { resource.TestCheckResourceAttrPair(dataSourceName, "provisioned_throughput_in_mibps", resourceName, "provisioned_throughput_in_mibps"), resource.TestCheckResourceAttrPair(dataSourceName, "throughput_mode", resourceName, "throughput_mode"), resource.TestCheckResourceAttrPair(dataSourceName, "lifecycle_policy", resourceName, "lifecycle_policy"), - resource.TestCheckResourceAttrPair(dataSourceName, "policy", resourceName, "policy"), resource.TestMatchResourceAttr(dataSourceName, "size_in_bytes", regexp.MustCompile(`^\d+$`)), ), }, diff --git a/aws/provider.go b/aws/provider.go index 0273b116f54..f3c34c613f8 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -551,6 +551,7 @@ func Provider() terraform.ResourceProvider { "aws_ecs_service": resourceAwsEcsService(), "aws_ecs_task_definition": resourceAwsEcsTaskDefinition(), "aws_efs_file_system": resourceAwsEfsFileSystem(), + "aws_efs_file_system_policy": resourceAwsEfsFileSystemPolicy(), "aws_efs_mount_target": resourceAwsEfsMountTarget(), "aws_egress_only_internet_gateway": resourceAwsEgressOnlyInternetGateway(), "aws_eip": resourceAwsEip(), diff --git a/aws/resource_aws_efs_file_system.go b/aws/resource_aws_efs_file_system.go index 85a5facb2e3..edb5027f5ef 100644 --- a/aws/resource_aws_efs_file_system.go +++ b/aws/resource_aws_efs_file_system.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "log" - "strings" "time" "github.com/aws/aws-sdk-go/aws" @@ -116,12 +115,6 @@ func resourceAwsEfsFileSystem() *schema.Resource { }, }, }, - "policy": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.ValidateJsonString, - DiffSuppressFunc: suppressEquivalentJsonDiffs, - }, }, } } @@ -202,16 +195,6 @@ func resourceAwsEfsFileSystemCreate(d *schema.ResourceData, meta interface{}) er } } - if v, ok := d.GetOk("policy"); ok && v.(string) != "" { - _, err := conn.PutFileSystemPolicy(&efs.PutFileSystemPolicyInput{ - FileSystemId: aws.String(d.Id()), - Policy: aws.String(v.(string)), - }) - if err != nil { - return fmt.Errorf("Error creating policy for EFS file system %q: %s", d.Id(), err.Error()) - } - } - return resourceAwsEfsFileSystemRead(d, meta) } @@ -270,27 +253,6 @@ func resourceAwsEfsFileSystemUpdate(d *schema.ResourceData, meta interface{}) er } } - if d.HasChange("policy") { - _, n := d.GetChange("policy") - - if n.(string) != "" { - _, err := conn.PutFileSystemPolicy(&efs.PutFileSystemPolicyInput{ - FileSystemId: aws.String(d.Id()), - Policy: aws.String(d.Get("policy").(string)), - }) - if err != nil { - return fmt.Errorf("Error updating policy for EFS file system %q: %s", d.Id(), err.Error()) - } - } else { - _, err := conn.DeleteFileSystemPolicy(&efs.DeleteFileSystemPolicyInput{ - FileSystemId: aws.String(d.Id()), - }) - if err != nil { - return fmt.Errorf("Error removing policy for EFS file system %q: %s", d.Id(), err.Error()) - } - } - } - if d.HasChange("tags") { o, n := d.GetChange("tags") @@ -369,25 +331,6 @@ func resourceAwsEfsFileSystemRead(d *schema.ResourceData, meta interface{}) erro return fmt.Errorf("error setting lifecycle_policy: %s", err) } - var policyRes *efs.DescribeFileSystemPolicyOutput - policyRes, err = conn.DescribeFileSystemPolicy(&efs.DescribeFileSystemPolicyInput{ - FileSystemId: fs.FileSystemId, - }) - if err != nil { - if isAWSErr(err, efs.ErrCodePolicyNotFound, "") { - d.Set("policy", "") - } else { - return fmt.Errorf("Error describing policy for EFS file system (%s): %s", - aws.StringValue(fs.FileSystemId), err) - } - } else { - correctedPolicy := strings.Replace(aws.StringValue(policyRes.Policy), - fmt.Sprintf("\"Resource\" : \"%s\",", fsARN), "", 1) - if err := d.Set("policy", correctedPolicy); err != nil { - return err - } - } - return nil } diff --git a/aws/resource_aws_efs_file_system_test.go b/aws/resource_aws_efs_file_system_test.go index ba45739c15d..87e02b8b9a0 100644 --- a/aws/resource_aws_efs_file_system_test.go +++ b/aws/resource_aws_efs_file_system_test.go @@ -431,47 +431,6 @@ func TestAccAWSEFSFileSystem_lifecyclePolicy_removal(t *testing.T) { }) } -func TestAccAWSEFSFileSystem_policy(t *testing.T) { - var desc efs.FileSystemDescription - resourceName := "aws_efs_file_system.test" - rName := acctest.RandomWithPrefix("tf-acc") - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckEfsFileSystemDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSEFSFileSystemConfigWPolicy(rName), - Check: resource.ComposeTestCheckFunc( - testAccCheckEfsFileSystem(resourceName, &desc), - resource.TestCheckResourceAttrSet(resourceName, "policy"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"creation_token"}, - }, - { - Config: testAccAWSEFSFileSystemConfig(rName), - Check: resource.ComposeTestCheckFunc( - testAccCheckEfsFileSystem("aws_efs_file_system.test", &desc), - resource.TestCheckResourceAttr(resourceName, "policy", ""), - ), - }, - { - Config: testAccAWSEFSFileSystemConfigWPolicy(rName), - Check: resource.ComposeTestCheckFunc( - testAccCheckEfsFileSystem(resourceName, &desc), - resource.TestCheckResourceAttrSet(resourceName, "policy"), - ), - }, - }, - }) -} - func TestAccAWSEFSFileSystem_disappears(t *testing.T) { var desc efs.FileSystemDescription resourceName := "aws_efs_file_system.test" @@ -671,38 +630,6 @@ resource "aws_efs_file_system" "test" { `, rName) } -func testAccAWSEFSFileSystemConfigWPolicy(rName string) string { - return fmt.Sprintf(` -resource "aws_efs_file_system" "test" { - creation_token = %q - policy = < Date: Fri, 15 May 2020 17:50:30 +0300 Subject: [PATCH 175/475] split efs policy to its own resource --- aws/resource_aws_efs_file_system_policy.go | 106 +++++++++++++ ...esource_aws_efs_file_system_policy_test.go | 149 ++++++++++++++++++ 2 files changed, 255 insertions(+) create mode 100644 aws/resource_aws_efs_file_system_policy.go create mode 100644 aws/resource_aws_efs_file_system_policy_test.go diff --git a/aws/resource_aws_efs_file_system_policy.go b/aws/resource_aws_efs_file_system_policy.go new file mode 100644 index 00000000000..00a8f535c7e --- /dev/null +++ b/aws/resource_aws_efs_file_system_policy.go @@ -0,0 +1,106 @@ +package aws + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/efs" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" +) + +func resourceAwsEfsFileSystemPolicy() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsEfsFileSystemPolicyPut, + Read: resourceAwsEfsFileSystemPolicyRead, + Update: resourceAwsEfsFileSystemPolicyPut, + Delete: resourceAwsEfsFileSystemPolicyDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "file_system_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "policy": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsJSON, + DiffSuppressFunc: suppressEquivalentJsonDiffs, + }, + }, + } +} + +func resourceAwsEfsFileSystemPolicyPut(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).efsconn + + fsId := d.Get("file_system_id").(string) + input := &efs.PutFileSystemPolicyInput{ + FileSystemId: aws.String(fsId), + Policy: aws.String(d.Get("policy").(string)), + } + log.Printf("[DEBUG] Adding EFS File System Policy: %#v", input) + _, err := conn.PutFileSystemPolicy(input) + if err != nil { + return fmt.Errorf("error creating EFS File System Policy %q: %s", d.Id(), err.Error()) + } + + d.SetId(fsId) + + return resourceAwsEfsFileSystemPolicyRead(d, meta) +} + +func resourceAwsEfsFileSystemPolicyRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).efsconn + + var policyRes *efs.DescribeFileSystemPolicyOutput + policyRes, err := conn.DescribeFileSystemPolicy(&efs.DescribeFileSystemPolicyInput{ + FileSystemId: aws.String(d.Id()), + }) + if err != nil { + if isAWSErr(err, efs.ErrCodeFileSystemNotFound, "") { + log.Printf("[WARN] EFS File System (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + if isAWSErr(err, efs.ErrCodePolicyNotFound, "") { + log.Printf("[WARN] EFS File System Policy (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + return fmt.Errorf("error describing policy for EFS file system (%s): %s", d.Id(), err) + } + + d.Set("file_system_id", policyRes.FileSystemId) + d.Set("policy", policyRes.Policy) + + //correctedPolicy := strings.Replace(aws.StringValue(policyRes.Policy), + // fmt.Sprintf("\"Resource\" : \"%s\",", fsARN), "", 1) + //if err := d.Set("policy", correctedPolicy); err != nil { + // return err + //} + + return nil +} + +func resourceAwsEfsFileSystemPolicyDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).efsconn + + log.Printf("[DEBUG] Deleting EFS File System Policy: %s", d.Id()) + _, err := conn.DeleteFileSystemPolicy(&efs.DeleteFileSystemPolicyInput{ + FileSystemId: aws.String(d.Id()), + }) + if err != nil { + return fmt.Errorf("error deleting EFS File System Policy: %s with err %s", d.Id(), err.Error()) + } + + log.Printf("[DEBUG] EFS File System Policy %q deleted.", d.Id()) + + return nil +} diff --git a/aws/resource_aws_efs_file_system_policy_test.go b/aws/resource_aws_efs_file_system_policy_test.go new file mode 100644 index 00000000000..d04a934da4f --- /dev/null +++ b/aws/resource_aws_efs_file_system_policy_test.go @@ -0,0 +1,149 @@ +package aws + +import ( + "fmt" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/efs" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccAWSEFSFileSystemPolicy_basic(t *testing.T) { + var desc efs.DescribeFileSystemPolicyOutput + resourceName := "aws_efs_file_system_policy.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckEfsFileSystemDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSEFSFileSystemPolicyConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckEfsFileSystemPolicy(resourceName, &desc), + resource.TestCheckResourceAttrSet(resourceName, "policy"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSEFSFileSystemPolicy_disappears(t *testing.T) { + var desc efs.DescribeFileSystemPolicyOutput + resourceName := "aws_efs_file_system_policy.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckEfsFileSystemPolicyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSEFSFileSystemPolicyConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckEfsFileSystemPolicy(resourceName, &desc), + testAccCheckResourceDisappears(testAccProvider, resourceAwsEfsFileSystemPolicy(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccCheckEfsFileSystemPolicyDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).efsconn + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_efs_file_system_policy" { + continue + } + + resp, err := conn.DescribeFileSystemPolicy(&efs.DescribeFileSystemPolicyInput{ + FileSystemId: aws.String(rs.Primary.ID), + }) + if err != nil { + if isAWSErr(err, efs.ErrCodeFileSystemNotFound, "") || + isAWSErr(err, efs.ErrCodePolicyNotFound, "") { + return nil + } + return fmt.Errorf("error describing EFS file system policy in tests: %s", err) + } + if resp != nil { + return fmt.Errorf("EFS file system policy %q still exists", rs.Primary.ID) + } + } + + return nil +} + +func testAccCheckEfsFileSystemPolicy(resourceID string, efsFsPolicy *efs.DescribeFileSystemPolicyOutput) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceID] + if !ok { + return fmt.Errorf("Not found: %s", resourceID) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).efsconn + fs, err := conn.DescribeFileSystemPolicy(&efs.DescribeFileSystemPolicyInput{ + FileSystemId: aws.String(rs.Primary.ID), + }) + + if err != nil { + return err + } + + *efsFsPolicy = *fs + + return nil + } +} + +func testAccAWSEFSFileSystemPolicyConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_efs_file_system" "test" { + creation_token = %q +} + +resource "aws_efs_file_system_policy" "test" { + file_system_id = "{aws_efs_file_system.test.id}" + + policy = < Date: Fri, 15 May 2020 14:53:54 -0700 Subject: [PATCH 176/475] Adds acceptance test functions for cross-account resources --- aws/provider_test.go | 58 ++++++++++++++++++- ...esource_aws_ram_resource_share_accepter.go | 2 +- ...ce_aws_ram_resource_share_accepter_test.go | 8 +-- 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/aws/provider_test.go b/aws/provider_test.go index c59e7a202e8..b4411dbbd7e 100644 --- a/aws/provider_test.go +++ b/aws/provider_test.go @@ -21,6 +21,7 @@ import ( ) const rfc3339RegexPattern = `^[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\.[0-9]+)?([Zz]|([+-]([01][0-9]|2[0-3]):[0-5][0-9]))$` +const uuidRegexPattern = `[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[ab89][a-f0-9]{3}-[a-f0-9]{12}` var testAccProviders map[string]terraform.ResourceProvider var testAccProviderFactories func(providers *[]*schema.Provider) map[string]terraform.ResourceProviderFactory @@ -73,6 +74,21 @@ func testAccPreCheck(t *testing.T) { } } +// testAccAlternateAccountProvider returns the schema.Provider for the alternate account +// Must be used within a resource.TestCheckFunc +func testAccAlternateAccountProvider(providers *[]*schema.Provider) (result *schema.Provider) { + primaryAccountID := testAccGetAccountID() + + for _, provider := range *providers { + accountID := testAccAwsProviderAccountID(provider) + if accountID != "" && accountID != primaryAccountID { + result = provider + } + } + + return +} + // testAccAwsProviderAccountID returns the account ID of an AWS provider func testAccAwsProviderAccountID(provider *schema.Provider) string { if provider == nil { @@ -98,6 +114,15 @@ func testAccCheckResourceAttrAccountID(resourceName, attributeName string) resou } } +// testAccCheckResourceAttrAlternateAccountID ensures the Terraform state exactly matches the alternate account ID +func testAccCheckResourceAttrAlternateAccountID(resourceName, attributeName string, providers *[]*schema.Provider) resource.TestCheckFunc { + return func(s *terraform.State) error { + provider := testAccAlternateAccountProvider(providers) + + return resource.TestCheckResourceAttr(resourceName, attributeName, testAccAwsProviderAccountID(provider))(s) + } +} + // testAccCheckResourceAttrRegionalARN ensures the Terraform state exactly matches a formatted ARN with region func testAccCheckResourceAttrRegionalARN(resourceName, attributeName, arnService, arnResource string) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -180,6 +205,37 @@ func testAccMatchResourceAttrRegionalARNNoAccount(resourceName, attributeName, a } } +// testAccMatchResourceAttrRegionalARNAccountID ensures the Terraform state regexp matches a formatted ARN with region and specific account ID +func testAccMatchResourceAttrRegionalARNAccountID(resourceName, attributeName, accountID, arnService string, arnResourceRegexp *regexp.Regexp) resource.TestCheckFunc { + return func(s *terraform.State) error { + arnRegexp := arn.ARN{ + AccountID: accountID, + Partition: testAccGetPartition(), + Region: testAccGetRegion(), + Resource: arnResourceRegexp.String(), + Service: arnService, + }.String() + + attributeMatch, err := regexp.Compile(arnRegexp) + + if err != nil { + return fmt.Errorf("Unable to compile ARN regexp (%s): %s", arnRegexp, err) + } + + return resource.TestMatchResourceAttr(resourceName, attributeName, attributeMatch)(s) + } +} + +// testAccMatchResourceAttrRegionalARNAlternateAccount ensures the Terraform state regexp matches a formatted ARN with region in the alternate account +// assumes the regions for the primary and alternate accounts are the same +func testAccMatchResourceAttrRegionalARNAlternateAccount(resourceName, attributeName string, providers *[]*schema.Provider, arnService string, arnResourceRegexp *regexp.Regexp) resource.TestCheckFunc { + return func(s *terraform.State) error { + provider := testAccAlternateAccountProvider(providers) + + return testAccMatchResourceAttrRegionalARNAccountID(resourceName, attributeName, testAccAwsProviderAccountID(provider), "ram", arnResourceRegexp)(s) + } +} + // testAccMatchResourceAttrRegionalHostname ensures the Terraform state regexp matches a formatted DNS hostname with region and partition DNS suffix func testAccMatchResourceAttrRegionalHostname(resourceName, attributeName, serviceName string, hostnamePrefixRegexp *regexp.Regexp) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -339,7 +395,7 @@ func primaryInstanceState(s *terraform.State, name string) (*terraform.InstanceS } // testAccGetAccountID returns the account ID of testAccProvider -// Must be used returned within a resource.TestCheckFunc +// Must be used within a resource.TestCheckFunc func testAccGetAccountID() string { return testAccAwsProviderAccountID(testAccProvider) } diff --git a/aws/resource_aws_ram_resource_share_accepter.go b/aws/resource_aws_ram_resource_share_accepter.go index 8a15023255a..e7dbbdfb17a 100644 --- a/aws/resource_aws_ram_resource_share_accepter.go +++ b/aws/resource_aws_ram_resource_share_accepter.go @@ -151,7 +151,7 @@ func resourceAwsRamResourceShareAccepterRead(d *schema.ResourceData, meta interf shares, err := conn.GetResourceShares(listResourceSharesInput) if err != nil { - return fmt.Errorf("Error retrieving resource shares: %s", err) + return fmt.Errorf("error retrieving resource shares: %w", err) } if len(shares.ResourceShares) != 1 { diff --git a/aws/resource_aws_ram_resource_share_accepter_test.go b/aws/resource_aws_ram_resource_share_accepter_test.go index 36fe5cd318a..3340c01b4ca 100644 --- a/aws/resource_aws_ram_resource_share_accepter_test.go +++ b/aws/resource_aws_ram_resource_share_accepter_test.go @@ -34,11 +34,11 @@ func TestAccAwsRamResourceShareAccepter_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckAwsRamResourceShareAccepterExists(resourceName), resource.TestCheckResourceAttrPair(resourceName, "share_arn", principalAssociationResourceName, "resource_share_arn"), - testAccMatchResourceAttrRegionalARN(resourceName, "invitation_arn", "ram", regexp.MustCompile("resource-share-invitation/.+$")), - resource.TestMatchResourceAttr(resourceName, "share_id", regexp.MustCompile(`^rs-.+$`)), + testAccMatchResourceAttrRegionalARNAlternateAccount(resourceName, "invitation_arn", &providers, "ram", regexp.MustCompile(fmt.Sprintf("resource-share-invitation/%s$", uuidRegexPattern))), + resource.TestMatchResourceAttr(resourceName, "share_id", regexp.MustCompile(fmt.Sprintf(`^rs-%s$`, uuidRegexPattern))), resource.TestCheckResourceAttr(resourceName, "status", ram.ResourceShareStatusActive), - resource.TestMatchResourceAttr(resourceName, "receiver_account_id", regexp.MustCompile(`\d{12}`)), - resource.TestMatchResourceAttr(resourceName, "sender_account_id", regexp.MustCompile(`\d{12}`)), + testAccCheckResourceAttrAccountID(resourceName, "receiver_account_id"), + testAccCheckResourceAttrAlternateAccountID(resourceName, "sender_account_id", &providers), resource.TestCheckResourceAttr(resourceName, "share_name", shareName), resource.TestCheckResourceAttr(resourceName, "resources.%", "0"), ), From b80bcf59fcc1945307ef6482bdea5113d7efaec6 Mon Sep 17 00:00:00 2001 From: Graham Davison Date: Fri, 15 May 2020 14:55:03 -0700 Subject: [PATCH 177/475] Adds custom KMS key and makes example Terraform v0.11-friendly --- examples/workspaces/iam.tf | 6 +++--- examples/workspaces/main.tf | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/workspaces/iam.tf b/examples/workspaces/iam.tf index a18efb674d5..e3800f308ab 100644 --- a/examples/workspaces/iam.tf +++ b/examples/workspaces/iam.tf @@ -1,6 +1,6 @@ resource "aws_iam_role" "workspaces-default" { name = "workspaces_DefaultRole" - assume_role_policy = data.aws_iam_policy_document.workspaces.json + assume_role_policy = "${data.aws_iam_policy_document.workspaces.json}" } data "aws_iam_policy_document" "workspaces" { @@ -15,11 +15,11 @@ data "aws_iam_policy_document" "workspaces" { } resource "aws_iam_role_policy_attachment" "workspaces-default-service-access" { - role = aws_iam_role.workspaces-default.name + role = "${aws_iam_role.workspaces-default.name}" policy_arn = "arn:aws:iam::aws:policy/AmazonWorkSpacesServiceAccess" } resource "aws_iam_role_policy_attachment" "workspaces-default-self-service-access" { - role = aws_iam_role.workspaces-default.name + role = "${aws_iam_role.workspaces-default.name}" policy_arn = "arn:aws:iam::aws:policy/AmazonWorkSpacesSelfServiceAccess" } diff --git a/examples/workspaces/main.tf b/examples/workspaces/main.tf index 0bbdb041c6a..5479598a2f7 100644 --- a/examples/workspaces/main.tf +++ b/examples/workspaces/main.tf @@ -24,7 +24,7 @@ resource "aws_workspaces_workspace" "example" { root_volume_encryption_enabled = true user_volume_encryption_enabled = true - volume_encryption_key = data.aws_kms_key.workspaces_default.arn + volume_encryption_key = "${aws_kms_key.example.arn}" workspace_properties { compute_type_name = "VALUE" @@ -73,10 +73,10 @@ data "aws_availability_zones" "available" { locals { # Workspace instances are not supported in all AZs in some regions region_workspaces_az_ids = { - "us-east-1" = formatlist("use1-az%d", [2, 4, 6]) + "us-east-1" = "${formatlist("use1-az%d", [2, 4, 6])}" } - workspaces_az_ids = lookup(local.region_workspaces_az_ids, data.aws_region.current.name, data.aws_availability_zones.available.zone_ids) + workspaces_az_ids = "${lookup(local.region_workspaces_az_ids, data.aws_region.current.name, data.aws_availability_zones.available.zone_ids)}" } resource "aws_vpc" "main" { @@ -105,6 +105,6 @@ resource "aws_directory_service_directory" "example" { } } -data "aws_kms_key" "workspaces_default" { - key_id = "alias/aws/workspaces" +resource "aws_kms_key" "example" { + description = "WorkSpaces example key" } From 3d7c3f3b61c40be47fdd4a95da6c05f57b76eea3 Mon Sep 17 00:00:00 2001 From: Kevin Tham Date: Fri, 15 May 2020 19:14:44 -0700 Subject: [PATCH 178/475] Fix aws_security_group_rule description field overwritten to nil on TF state refresh --- aws/resource_aws_security_group_rule.go | 27 ++++++++++++-------- aws/resource_aws_security_group_rule_test.go | 1 + 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/aws/resource_aws_security_group_rule.go b/aws/resource_aws_security_group_rule.go index 41009bf2071..7135869e11b 100644 --- a/aws/resource_aws_security_group_rule.go +++ b/aws/resource_aws_security_group_rule.go @@ -842,20 +842,25 @@ func descriptionFromIPPerm(d *schema.ResourceData, rule *ec2.IpPermission) strin } } - // probe UserIdGroupPairs - groupIds := make(map[string]bool) if raw, ok := d.GetOk("source_security_group_id"); ok { - groupIds[raw.(string)] = true - } + components := strings.Split(raw.(string), "/") - if len(groupIds) > 0 { - for _, gp := range rule.UserIdGroupPairs { - if _, ok := groupIds[*gp.GroupId]; !ok { - continue - } + switch len(components) { + case 2: + userId := components[0] + groupId := components[1] - if desc := aws.StringValue(gp.Description); desc != "" { - return desc + for _, gp := range rule.UserIdGroupPairs { + if *gp.GroupId == groupId && *gp.UserId == userId { + return aws.StringValue(gp.Description) + } + } + case 1: + groupId := components[0] + for _, gp := range rule.UserIdGroupPairs { + if *gp.GroupId == groupId { + return aws.StringValue(gp.Description) + } } } } diff --git a/aws/resource_aws_security_group_rule_test.go b/aws/resource_aws_security_group_rule_test.go index 12faae390ad..64af4d47fbe 100644 --- a/aws/resource_aws_security_group_rule_test.go +++ b/aws/resource_aws_security_group_rule_test.go @@ -2089,6 +2089,7 @@ resource "aws_security_group_rule" "allow_self" { from_port = 0 to_port = 0 protocol = "-1" + description = "some description" security_group_id = "${aws_security_group.web.id}" source_security_group_id = "${data.aws_caller_identity.current.account_id}/${aws_security_group.web.id}" } From 8cfd92714094a17280f946af95c27ce9832a1b9f Mon Sep 17 00:00:00 2001 From: Kevin Tham Date: Fri, 15 May 2020 19:39:15 -0700 Subject: [PATCH 179/475] fix --- aws/resource_aws_security_group_rule.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/aws/resource_aws_security_group_rule.go b/aws/resource_aws_security_group_rule.go index 7135869e11b..509ba4a45c5 100644 --- a/aws/resource_aws_security_group_rule.go +++ b/aws/resource_aws_security_group_rule.go @@ -851,15 +851,24 @@ func descriptionFromIPPerm(d *schema.ResourceData, rule *ec2.IpPermission) strin groupId := components[1] for _, gp := range rule.UserIdGroupPairs { + if *gp.GroupId != groupId || *gp.UserId != userId { + continue + } if *gp.GroupId == groupId && *gp.UserId == userId { - return aws.StringValue(gp.Description) + if desc := aws.StringValue(gp.Description); desc != "" { + return desc + } } } case 1: groupId := components[0] for _, gp := range rule.UserIdGroupPairs { - if *gp.GroupId == groupId { - return aws.StringValue(gp.Description) + if *gp.GroupId != groupId { + continue + } + + if desc := aws.StringValue(gp.Description); desc != "" { + return desc } } } From 489690bbe352a609dc440014e201bf7969d54eb2 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Sat, 16 May 2020 18:14:33 +0300 Subject: [PATCH 180/475] take remove custom arn handling --- aws/resource_aws_efs_file_system_policy.go | 6 --- ...esource_aws_efs_file_system_policy_test.go | 46 ++++++++++++++++++- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/aws/resource_aws_efs_file_system_policy.go b/aws/resource_aws_efs_file_system_policy.go index 00a8f535c7e..5bb677ea172 100644 --- a/aws/resource_aws_efs_file_system_policy.go +++ b/aws/resource_aws_efs_file_system_policy.go @@ -80,12 +80,6 @@ func resourceAwsEfsFileSystemPolicyRead(d *schema.ResourceData, meta interface{} d.Set("file_system_id", policyRes.FileSystemId) d.Set("policy", policyRes.Policy) - //correctedPolicy := strings.Replace(aws.StringValue(policyRes.Policy), - // fmt.Sprintf("\"Resource\" : \"%s\",", fsARN), "", 1) - //if err := d.Set("policy", correctedPolicy); err != nil { - // return err - //} - return nil } diff --git a/aws/resource_aws_efs_file_system_policy_test.go b/aws/resource_aws_efs_file_system_policy_test.go index d04a934da4f..819ec05784b 100644 --- a/aws/resource_aws_efs_file_system_policy_test.go +++ b/aws/resource_aws_efs_file_system_policy_test.go @@ -33,6 +33,13 @@ func TestAccAWSEFSFileSystemPolicy_basic(t *testing.T) { ImportState: true, ImportStateVerify: true, }, + { + Config: testAccAWSEFSFileSystemPolicyConfigUpdated(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckEfsFileSystemPolicy(resourceName, &desc), + resource.TestCheckResourceAttrSet(resourceName, "policy"), + ), + }, }, }) } @@ -117,7 +124,7 @@ resource "aws_efs_file_system" "test" { } resource "aws_efs_file_system_policy" "test" { - file_system_id = "{aws_efs_file_system.test.id}" + file_system_id = "${aws_efs_file_system.test.id}" policy = < Date: Sat, 16 May 2020 18:23:48 +0300 Subject: [PATCH 181/475] add docs --- ...esource_aws_efs_file_system_policy_test.go | 44 ------------ website/docs/r/efs_file_system.html.markdown | 34 --------- .../r/efs_file_system_policy.html.markdown | 70 +++++++++++++++++++ 3 files changed, 70 insertions(+), 78 deletions(-) create mode 100644 website/docs/r/efs_file_system_policy.html.markdown diff --git a/aws/resource_aws_efs_file_system_policy_test.go b/aws/resource_aws_efs_file_system_policy_test.go index 819ec05784b..066efbfb986 100644 --- a/aws/resource_aws_efs_file_system_policy_test.go +++ b/aws/resource_aws_efs_file_system_policy_test.go @@ -33,13 +33,6 @@ func TestAccAWSEFSFileSystemPolicy_basic(t *testing.T) { ImportState: true, ImportStateVerify: true, }, - { - Config: testAccAWSEFSFileSystemPolicyConfigUpdated(rName), - Check: resource.ComposeTestCheckFunc( - testAccCheckEfsFileSystemPolicy(resourceName, &desc), - resource.TestCheckResourceAttrSet(resourceName, "policy"), - ), - }, }, }) } @@ -154,40 +147,3 @@ POLICY } `, rName) } - -func testAccAWSEFSFileSystemPolicyConfigUpdated(rName string) string { - return fmt.Sprintf(` -resource "aws_efs_file_system" "test" { - creation_token = %q -} - -resource "aws_efs_file_system_policy" "test" { - file_system_id = "${aws_efs_file_system.test.id}" - - policy = < Date: Sat, 16 May 2020 18:53:34 +0300 Subject: [PATCH 182/475] add update case --- ...esource_aws_efs_file_system_policy_test.go | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/aws/resource_aws_efs_file_system_policy_test.go b/aws/resource_aws_efs_file_system_policy_test.go index 066efbfb986..442f12b7fa9 100644 --- a/aws/resource_aws_efs_file_system_policy_test.go +++ b/aws/resource_aws_efs_file_system_policy_test.go @@ -33,6 +33,13 @@ func TestAccAWSEFSFileSystemPolicy_basic(t *testing.T) { ImportState: true, ImportStateVerify: true, }, + { + Config: testAccAWSEFSFileSystemPolicyConfigUpdated(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckEfsFileSystemPolicy(resourceName, &desc), + resource.TestCheckResourceAttrSet(resourceName, "policy"), + ), + }, }, }) } @@ -147,3 +154,38 @@ POLICY } `, rName) } + +func testAccAWSEFSFileSystemPolicyConfigUpdated(rName string) string { + return fmt.Sprintf(` +resource "aws_efs_file_system" "test" { + creation_token = %q +} + +resource "aws_efs_file_system_policy" "test" { + file_system_id = "${aws_efs_file_system.test.id}" + + policy = < Date: Sat, 16 May 2020 18:59:28 +0300 Subject: [PATCH 183/475] Update efs_file_system.html.markdown --- website/docs/d/efs_file_system.html.markdown | 1 - 1 file changed, 1 deletion(-) diff --git a/website/docs/d/efs_file_system.html.markdown b/website/docs/d/efs_file_system.html.markdown index eef0a8f8c47..75da4112e39 100644 --- a/website/docs/d/efs_file_system.html.markdown +++ b/website/docs/d/efs_file_system.html.markdown @@ -44,4 +44,3 @@ In addition to all arguments above, the following attributes are exported: * `tags` -A map of tags to assign to the file system. * `throughput_mode` - Throughput mode for the file system. * `size_in_bytes` - The current byte count used by the file system. -* `policy` - The JSON formatted file system policy for the EFS file system. From 84c0a62c7a731e1766f93955a2c743aaad55722c Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Sat, 16 May 2020 19:31:50 +0300 Subject: [PATCH 184/475] add docs --- website/aws.erb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/aws.erb b/website/aws.erb index b1952514534..b15303dac57 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -1378,6 +1378,9 @@
  • aws_efs_file_system
  • +
  • + aws_efs_file_system_policy +
  • aws_efs_mount_target
  • From 4f4cae49cd52aa09af0d9ee4990b4698c1856803 Mon Sep 17 00:00:00 2001 From: Andrew Perry Date: Sat, 16 May 2020 22:29:15 +0100 Subject: [PATCH 185/475] style: Add spacing between principal blocks Updates the example Terraform code so that it matches the rest of the examples. --- website/docs/d/iam_policy_document.html.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/website/docs/d/iam_policy_document.html.markdown b/website/docs/d/iam_policy_document.html.markdown index a6a83b4a9db..1ae073dbc1a 100644 --- a/website/docs/d/iam_policy_document.html.markdown +++ b/website/docs/d/iam_policy_document.html.markdown @@ -186,6 +186,7 @@ data "aws_iam_policy_document" "event_stream_bucket_role_assume_role_policy" { type = "AWS" identifiers = ["${var.trusted_role_arn}"] } + principals { type = "Federated" identifiers = ["arn:aws:iam::${var.account_id}:saml-provider/${var.provider_name}", "cognito-identity.amazonaws.com"] From 5cce2de939bb1429be5dc0dd49f2f7c761fdb426 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Sun, 17 May 2020 18:36:12 -0400 Subject: [PATCH 186/475] docs/contributing: Initial Resource and Data Source Acceptance Testing sections (#13332) These sections are designed to document the Terraform AWS Provider "best practices" around writing acceptance testing for resources and data sources. The goal is to remove the current ambiguity of these practices for contributors of all levels since the codebase contains many older style generations of testing. These practices will likely change over time as we optimize the experience and updates to this documentation can help highlight those simplifications in those future refactoring proposals. --- .../running-and-writing-acceptance-tests.md | 463 ++++++++++++++++-- 1 file changed, 431 insertions(+), 32 deletions(-) diff --git a/docs/contributing/running-and-writing-acceptance-tests.md b/docs/contributing/running-and-writing-acceptance-tests.md index 7d419488676..25cde2dbaed 100644 --- a/docs/contributing/running-and-writing-acceptance-tests.md +++ b/docs/contributing/running-and-writing-acceptance-tests.md @@ -1,11 +1,25 @@ # Running and Writing Acceptance Tests - - [Acceptance Tests Often Cost Money to Run](#acceptance-tests-often-cost-money-to-run) - - [Running an Acceptance Test](#running-an-acceptance-test) - - [Writing an Acceptance Test](#writing-an-acceptance-test) - - [Writing and running Cross-Account Acceptance Tests](#writing-and-running-cross-account-acceptance-tests) - - [Writing and running Cross-Region Acceptance Tests](#writing-and-running-cross-region-acceptance-tests) - - [Acceptance Test Checklist](#acceptance-test-checklist) +- [Acceptance Tests Often Cost Money to Run](#acceptance-tests-often-cost-money-to-run) +- [Running an Acceptance Test](#running-an-acceptance-test) + - [Running Cross-Account Tests](#running-cross-account-tests) + - [Running Cross-Region Tests](#running-cross-region-tests) +- [Writing an Acceptance Test](#writing-an-acceptance-test) + - [Anatomy of an Acceptance Test](#anatomy-of-an-acceptance-test) + - [Resource Acceptance Testing](#resource-acceptance-testing) + - [Test Configurations](#test-configurations) + - [Combining Test Configurations](#combining-test-configurations) + - [Base Test Configurations](#base-test-configurations) + - [Available Common Test Configurations](#available-common-test-configurations) + - [Randomized Naming](#randomized-naming) + - [Other Recommended Variables](#other-recommended-variables) + - [Basic Acceptance Tests](#basic-acceptance-tests) + - [Disappears Acceptance Tests](#disappears-acceptance-tests) + - [Per Attribute Acceptance Tests](#per-attribute-acceptance-tests) + - [Cross-Account Acceptance Tests](#cross-account-acceptance-tests) + - [Cross-Region Acceptance Tests](#cross-region-acceptance-tests) + - [Data Source Acceptance Testing](#data-source-acceptance-testing) +- [Acceptance Test Checklist](#acceptance-test-checklist) Terraform includes an acceptance test harness that does most of the repetitive work involved in testing a resource. For additional information about testing @@ -84,13 +98,54 @@ ok github.com/terraform-providers/terraform-provider-aws/aws 55.619s Please Note: On macOS 10.14 and later (and some Linux distributions), the default user open file limit is 256. This may cause unexpected issues when running the acceptance testing since this can prevent various operations from occurring such as opening network connections to AWS. To view this limit, the `ulimit -n` command can be run. To update this limit, run `ulimit -n 1024` (or higher). +### Running Cross-Account Tests + +Certain testing requires multiple AWS accounts. This additional setup is not typically required and the testing will return an error (shown below) if your current setup does not have the secondary AWS configuration: + +```console +$ make testacc TEST=./aws TESTARGS='-run=TestAccAWSDBInstance_DbSubnetGroupName_RamShared' +=== RUN TestAccAWSDBInstance_DbSubnetGroupName_RamShared +=== PAUSE TestAccAWSDBInstance_DbSubnetGroupName_RamShared +=== CONT TestAccAWSDBInstance_DbSubnetGroupName_RamShared + TestAccAWSDBInstance_DbSubnetGroupName_RamShared: provider_test.go:386: AWS_ALTERNATE_ACCESS_KEY_ID or AWS_ALTERNATE_PROFILE must be set for acceptance tests +--- FAIL: TestAccAWSDBInstance_DbSubnetGroupName_RamShared (2.22s) +FAIL +FAIL github.com/terraform-providers/terraform-provider-aws/aws 4.305s +FAIL +``` + +Running these acceptance tests is the same as before, except the following additional AWS credential information is required: + +```sh +# Using a profile +export AWS_ALTERNATE_PROFILE=... +# Otherwise +export AWS_ALTERNATE_ACCESS_KEY_ID=... +export AWS_ALTERNATE_SECRET_ACCESS_KEY=... +``` + +### Running Cross-Region Tests + +Certain testing requires multiple AWS regions. Additional setup is not typically required because the testing defaults the alternate AWS region to `us-east-1`. + +Running these acceptance tests is the same as before, but if you wish to override the alternate region: + +```sh +export AWS_ALTERNATE_REGION=... +``` + ## Writing an Acceptance Test Terraform has a framework for writing acceptance tests which minimises the -amount of boilerplate code necessary to use common testing patterns. The entry -point to the framework is the `resource.ParallelTest()` function. +amount of boilerplate code necessary to use common testing patterns. This guide is meant to augment the general [Extending Terraform documentation](https://www.terraform.io/docs/extend/testing/acceptance-tests/index.html) with Terraform AWS Provider specific conventions and helpers. + +### Anatomy of an Acceptance Test -Tests are divided into `TestStep`s. Each `TestStep` proceeds by applying some +This section describes in detail how the Terraform acceptance testing framework operates with respect to the Terraform AWS Provider. We recommend those unfamiliar with this provider, or Terraform resource testing in general, take a look here first to generally understand how we interact with AWS and the resource code to verify functionality. + +The entry point to the framework is the `resource.ParallelTest()` function. This wraps our testing to work with the standard Go testing framework, while also preventing unexpected usage of AWS by requiring the `TF_ACC=1` environment variable. This function accepts a `TestCase` parameter, which has all the details about the test itself. For example, this includes the test steps (`TestSteps`) and how to verify resource deletion in the API after all steps have been run (`CheckDestroy`). + +Each `TestStep` proceeds by applying some Terraform configuration using the provider under test, and then verifying that results are as expected by making assertions using the provider API. It is common for a single test function to exercise both the creation of and updates @@ -102,7 +157,7 @@ to a single resource. Most tests follow a similar structure. to running acceptance tests. This is common to all tests exercising a single provider. -Each `TestStep` is defined in the call to `resource.ParallelTest()`. Most assertion +Most assertion functions are defined out of band with the tests. This keeps the tests readable, and allows reuse of assertion functions across different tests of the same type of resource. The definition of a complete test looks like this: @@ -193,10 +248,10 @@ When executing the test, the following steps are taken for each `TestStep`: resource.TestCheckResourceAttr("aws_cloudwatch_dashboard.foobar", "dashboard_name", testAccAWSCloudWatchDashboardName(rInt)), ``` -2. The resources created by the test are destroyed. This step happens +1. The resources created by the test are destroyed. This step happens automatically, and is the equivalent of calling `terraform destroy`. -3. Assertions are made against the provider API to verify that the resources +1. Assertions are made against the provider API to verify that the resources have indeed been removed. If these checks fail, the test fails and reports "dangling resources". The code to ensure that the `aws_cloudwatch_dashboard` shown above has been destroyed looks like this: @@ -229,7 +284,317 @@ When executing the test, the following steps are taken for each `TestStep`: These functions usually test only for the resource directly under test. -## Writing and running Cross-Account Acceptance Tests +### Resource Acceptance Testing + +Most resources that implement standard Create, Read, Update, and Delete functionality should follow the pattern below. Each test type has a section that describes them in more detail: + +- **basic**: This represents the bare minimum verification that the resource can be created, read, deleted, and optionally imported. +- **disappears**: A test that verifies Terraform will offer to recreate a resource if it is deleted outside of Terraform (e.g. via the Console) instead of returning an error that it cannot be found. +- **Per Attribute**: A test that verifies the resource with a single additional argument can be created, read, optionally updated (or force resource recreation), deleted, and optionally imported. + +The leading sections below highlight additional recommended patterns. + +#### Test Configurations + +Most of the existing test configurations you will find in the Terraform AWS Provider are written in the following function-based style: + +```go +func TestAccAwsExampleThing_basic(t *testing.T) { + // ... omitted for brevity ... + + resource.ParallelTest(t, resource.TestCase{ + // ... omitted for brevity ... + Steps: []resource.TestStep{ + { + Config: testAccAwsExampleThingConfig(), + // ... omitted for brevity ... + }, + }, + }) +} + +func testAccAwsExampleThingConfig() string { + return ` +resource "aws_example_thing" "test" { + # ... omitted for brevity ... +} +` +} +``` + +Even when no values need to be passed in to the test configuration, we have found this setup to be the most flexible for allowing that to be easily implemented. Any configurable values are handled via `fmt.Sprintf()`. Using `text/template` or other templating styles is explicitly forbidden. + +For consistency, resources in the test configuration should be named `resource "..." "test"` unless multiple of that resource are necessary. + +We discourage re-using test configurations across test files (except for some common configuration helpers we provide) as it is much harder to discover potential testing regressions. + +Please also note that the newline on the first line of the configuration (before `resource`) and the newline after the last line of configuration (after `}`) are important to allow test configurations to be easily combined without generating Terraform configuration language syntax errors. + +#### Combining Test Configurations + +We include a helper function, `composeConfig()` for iteratively building and chaining test configurations together. It accepts any number of configurations to combine them. This simplifies a single resource's testing by allowing the creation of a "base" test configuration for all the other test configurations (if necessary) and also allows the maintainers to curate common configurations. Each of these is described in more detail in below sections. + +Please note that we do discourage _excessive_ chaining of configurations such as implementing multiple layers of "base" configurations. Usually these configurations are harder for maintainers and other future readers to understand due to the multiple levels of indirection. + +##### Base Test Configurations + +If a resource requires the same Terraform configuration as a prerequisite for all test configurations, then a common pattern is implementing a "base" test configuration that is combined with each test configuration. + +For example: + +```go +func testAccAwsExampleThingConfigBase() string { + return ` +resource "aws_iam_role" "test" { + # ... omitted for brevity ... +} + +resource "aws_iam_role_policy" "test" { + # ... omitted for brevity ... +} +` +} + +func testAccAwsExampleThingConfig() string { + return composeConfig( + testAccAwsExampleThingConfigBase(), + ` +resource "aws_example_thing" "test" { + # ... omitted for brevity ... +} +`) +} +``` + +##### Available Common Test Configurations + +These test configurations are typical implementations we have found or allow testing to implement best practices easier, since the Terraform AWS Provider testing is expected to run against various AWS Regions and Partitions. + +- `testAccAvailableEc2InstanceTypeForRegion("type1", "type2", ...)`: Typically used to replace hardcoded EC2 Instance Types. Uses `aws_ec2_instance_type_offering` data source to return an available EC2 Instance Type in preferred ordering. Reference the instance type via: `data.aws_ec2_instance_type_offering.available.instance_type` +- `testAccLatestAmazonLinuxHvmEbsAmiConfig()`: Typically used to replace hardcoded EC2 Image IDs (`ami-12345678`). Uses `aws_ami` data source to find the latest Amazon Linux image. Reference the AMI ID via: `data.aws_ami.amzn-ami-minimal-hvm-ebs.id` + +#### Randomized Naming + +For AWS resources that require unique naming, the tests should implement a randomized name, typically coded as a `rName` variable in the test and passed as a parameter to creating the test configuration. + +For example: + +```go +func TestAccAwsExampleThing_basic(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + // ... omitted for brevity ... + + resource.ParallelTest(t, resource.TestCase{ + // ... omitted for brevity ... + Steps: []resource.TestStep{ + { + Config: testAccAwsExampleThingConfigName(rName), + // ... omitted for brevity ... + }, + }, + }) +} + +func testAccAwsExampleThingConfigName(rName string) string { + return fmt.Sprintf(` +resource "aws_example_thing" "test" { + name = %[1]q +} +`, rName) +} +``` + +Typically the `rName` is always the first argument to the test configuration function, if used, for consistency. + +#### Other Recommended Variables + +We also typically recommend saving a `resourceName` variable in the test that contains the resource reference, e.g. `aws_example_thing.test`, which is repeatedly used in the checks. + +For example: + +```go +func TestAccAwsExampleThing_basic(t *testing.T) { + // ... omitted for brevity ... + resourceName := "aws_example_thing.test" + + resource.ParallelTest(t, resource.TestCase{ + // ... omitted for brevity ... + Steps: []resource.TestStep{ + { + // ... omitted for brevity ... + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsExampleThingExists(resourceName), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "example", fmt.Sprintf("thing/%s", rName)), + resource.TestCheckResourceAttr(resourceName, "description", ""), + resource.TestCheckResourceAttr(resourceName, "name", rName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +// below all TestAcc functions + +func testAccAwsExampleThingConfigName(rName string) string { + return fmt.Sprintf(` +resource "aws_example_thing" "test" { + name = %[1]q +} +`, rName) +} +``` + +#### Basic Acceptance Tests + +Usually this test is implemented first. The test configuration should contain only required arguments (`Required: true` attributes) and it should check the values of all read-only attributes (`Computed: true` without `Optional: true`). If the resource supports it, it verifies import. It should _NOT_ perform other `TestStep` such as updates or verify recreation. + +These are typically named `TestAccAws{SERVICE}{THING}_basic`, e.g. `TestAccAwsCloudWatchDashboard_basic` + +For example: + +```go +func TestAccAwsExampleThing_basic(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_example_thing.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsExampleThingDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsExampleThingConfigName(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsExampleThingExists(resourceName), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "example", fmt.Sprintf("thing/%s", rName)), + resource.TestCheckResourceAttr(resourceName, "description", ""), + resource.TestCheckResourceAttr(resourceName, "name", rName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +// below all TestAcc functions + +func testAccAwsExampleThingConfigName(rName string) string { + return fmt.Sprintf(` +resource "aws_example_thing" "test" { + name = %[1]q +} +`, rName) +} +``` + +#### Disappears Acceptance Tests + +This test is generally implemented second. It is straightforward to setup once the basic test is passing since it can reuse that test configuration. It prevents a common bug report with Terraform resources that error when they can not be found (e.g. deleted outside Terraform). + +These are typically named `TestAccAws{SERVICE}{THING}_disappears`, e.g. `TestAccAwsCloudWatchDashboard_disappears` + +For example: + +```go +func TestAccAwsExampleThing_disappears(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_example_thing.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsExampleThingDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsExampleThingConfigName(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsExampleThingExists(resourceName, &job), + testAccCheckResourceDisappears(testAccProvider, resourceAwsExampleThing(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} +``` + +If this test does fail, the fix for this is generally adding error handling immediately after the `Read` API call that catches the error and tells Terraform to remove the resource before returning the error: + +```go +output, err := conn.GetThing(input) + +if isAWSErr(err, example.ErrCodeResourceNotFound, "") { + log.Printf("[WARN] Example Thing (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil +} + +if err != nil { + return fmt.Errorf("error reading Example Thing (%s): %w", d.Id(), err) +} +``` + +#### Per Attribute Acceptance Tests + +These are typically named `TestAccAws{SERVICE}{THING}_{ATTRIBUTE}`, e.g. `TestAccAwsCloudWatchDashboard_Name` + +For example: + +```go +func TestAccAwsExampleThing_Description(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_example_thing.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsExampleThingDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsExampleThingConfigDescription(rName, "description1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsExampleThingExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "description1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAwsExampleThingConfigDescription(rName, "description2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsExampleThingExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "description2"), + ), + }, + }, + }) +} + +// below all TestAcc functions + +func testAccAwsExampleThingConfigDescription(rName string, description string) string { + return fmt.Sprintf(` +resource "aws_example_thing" "test" { + description = %[2]q + name = %[1]q +} +`, rName, description) +} +``` + +#### Cross-Account Acceptance Tests When testing requires AWS infrastructure in a second AWS account, the below changes to the normal setup will allow the management or reference of resources and data sources across accounts: @@ -292,17 +657,7 @@ resource "aws_example" "test" { Searching for usage of `testAccAlternateAccountPreCheck` in the codebase will yield real world examples of this setup in action. -Running these acceptance tests is the same as before, except the following additional credential information is required: - -```sh -# Using a profile -export AWS_ALTERNATE_PROFILE=... -# Otherwise -export AWS_ALTERNATE_ACCESS_KEY_ID=... -export AWS_ALTERNATE_SECRET_ACCESS_KEY=... -``` - -## Writing and running Cross-Region Acceptance Tests +#### Cross-Region Acceptance Tests When testing requires AWS infrastructure in a second AWS region, the below changes to the normal setup will allow the management or reference of resources and data sources across regions: @@ -366,16 +721,60 @@ resource "aws_example" "test" { Searching for usage of `testAccAlternateRegionPreCheck` in the codebase will yield real world examples of this setup in action. -Running these acceptance tests is the same as before, except if an AWS region other than the default alternate region - `us-east-1` - is required, -in which case the following additional configuration information is required: +### Data Source Acceptance Testing -```sh -export AWS_ALTERNATE_REGION=... -``` +Writing acceptance testing for data sources is similar to resources, with the biggest changes being: + +- Adding `DataSource` to the test and configuration naming, such as `TestAccAwsExampleThingDataSource_Filter` +- The basic test _may_ be named after the easiest lookup attribute instead, e.g. `TestAccAwsExampleThingDataSource_Name` +- No disappears testing +- Almost all checks should be done with [`resource.TestCheckResourceAttrPair()`](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-sdk/helper/resource?tab=doc#TestCheckResourceAttrPair) to compare the data source attributes to the resource attributes +- The usage of an additional `dataSourceName` variable to store a data source reference, e.g. `data.aws_example_thing.test` + +Data sources testing should still utilize the `CheckDestroy` function of the resource, just to continue verifying that there are no dangling AWS resources after a test is ran. + +Please note that we do not recommend re-using test configurations between resources and their associated data source as it is harder to discover testing regressions. Authors are encouraged to potentially implement similar "base" configurations though. + +For example: + +```go +func TestAccAwsExampleThingDataSource_Name(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + dataSourceName := "data.aws_example_thing.test" + resourceName := "aws_example_thing.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsExampleThingDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsExampleThingDataSourceConfigName(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsExampleThingExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "arn", dataSourceName, "arn"), + resource.TestCheckResourceAttrPair(resourceName, "description", dataSourceName, "description"), + resource.TestCheckResourceAttrPair(resourceName, "name", dataSourceName, "name"), + ), + }, + }, + }) +} + +// below all TestAcc functions + +func testAccAwsExampleThingDataSourceConfigName(rName string) string { + return fmt.Sprintf(` +resource "aws_example_thing" "test" { + name = %[1]q +} -[website]: https://github.com/terraform-providers/terraform-provider-aws/tree/master/website -[acctests]: https://github.com/hashicorp/terraform#acceptance-tests -[ml]: https://groups.google.com/group/terraform-tool +data "aws_example_thing" "test" { + name = aws_example_thing.test.name +} +`, rName) +} +``` ## Acceptance Test Checklist From 0f5fbb4d5262055d764087b800873ad02b6fb624 Mon Sep 17 00:00:00 2001 From: appilon Date: Sun, 17 May 2020 22:27:38 -0400 Subject: [PATCH 187/475] Disable binary driver for missed tests (#13359) These tests were missed in the original sweep of tests that use TypeSet addresses --- aws/resource_aws_security_group_test.go | 7 ++++--- aws/resource_aws_vpc_peering_connection_options_test.go | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/aws/resource_aws_security_group_test.go b/aws/resource_aws_security_group_test.go index 839d0a3eb9c..9898f784a70 100644 --- a/aws/resource_aws_security_group_test.go +++ b/aws/resource_aws_security_group_test.go @@ -808,9 +808,10 @@ func TestAccAWSSecurityGroup_ruleGathering(t *testing.T) { resourceName := "aws_security_group.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSecurityGroupDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSecurityGroupDestroy, + DisableBinaryDriver: true, Steps: []resource.TestStep{ { Config: testAccAWSSecurityGroupConfig_ruleGathering(sgName), diff --git a/aws/resource_aws_vpc_peering_connection_options_test.go b/aws/resource_aws_vpc_peering_connection_options_test.go index 8621e38cece..a9552c49721 100644 --- a/aws/resource_aws_vpc_peering_connection_options_test.go +++ b/aws/resource_aws_vpc_peering_connection_options_test.go @@ -202,8 +202,9 @@ func TestAccAWSVpcPeeringConnectionOptions_sameRegionDifferentAccount(t *testing testAccPreCheck(t) testAccAlternateAccountPreCheck(t) }, - ProviderFactories: testAccProviderFactories(&providers), - CheckDestroy: testAccCheckAWSVpcPeeringConnectionDestroy, + ProviderFactories: testAccProviderFactories(&providers), + CheckDestroy: testAccCheckAWSVpcPeeringConnectionDestroy, + DisableBinaryDriver: true, Steps: []resource.TestStep{ { Config: testAccVpcPeeringConnectionOptionsConfig_sameRegion_differentAccount(rName), From 40099de47e3707e3891e4c00d7cfa0532b16fa01 Mon Sep 17 00:00:00 2001 From: Kerim Satirli Date: Mon, 18 May 2020 17:33:06 +0200 Subject: [PATCH 188/475] docs/provider: Various documentation updates for aws_cloudfront_distribution and codecommit (#13319) * changes `ARN` to `ID` * adds highlighting * Removes outdated warning * removes outdated warning * Update website/docs/r/acm_certificate.html.markdown Co-authored-by: Brian Flad Co-authored-by: Brian Flad --- website/docs/r/cloudfront_distribution.html.markdown | 2 +- website/docs/r/codecommit_repository.html.markdown | 4 ---- website/docs/r/codecommit_trigger.html.markdown | 4 ---- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/website/docs/r/cloudfront_distribution.html.markdown b/website/docs/r/cloudfront_distribution.html.markdown index 1e85553e2e3..bba0c985ff7 100644 --- a/website/docs/r/cloudfront_distribution.html.markdown +++ b/website/docs/r/cloudfront_distribution.html.markdown @@ -520,7 +520,7 @@ In addition to all arguments above, the following attributes are exported: * `id` - The identifier for the distribution. For example: `EDFDVBD632BHDS5`. - * `arn` - The ARN (Amazon Resource Name) for the distribution. For example: arn:aws:cloudfront::123456789012:distribution/EDFDVBD632BHDS5, where 123456789012 is your AWS account ID. + * `arn` - The ARN (Amazon Resource Name) for the distribution. For example: `arn:aws:cloudfront::123456789012:distribution/EDFDVBD632BHDS5`, where `123456789012` is your AWS account ID. * `caller_reference` - Internal value used by CloudFront to allow future updates to the distribution configuration. diff --git a/website/docs/r/codecommit_repository.html.markdown b/website/docs/r/codecommit_repository.html.markdown index cf6f065c4ec..30ef0d92ead 100644 --- a/website/docs/r/codecommit_repository.html.markdown +++ b/website/docs/r/codecommit_repository.html.markdown @@ -10,10 +10,6 @@ description: |- Provides a CodeCommit Repository Resource. -~> **NOTE on CodeCommit Availability**: The CodeCommit is not yet rolled out -in all regions - available regions are listed -[the AWS Docs](https://docs.aws.amazon.com/general/latest/gr/rande.html#codecommit_region). - ## Example Usage ```hcl diff --git a/website/docs/r/codecommit_trigger.html.markdown b/website/docs/r/codecommit_trigger.html.markdown index bdb2c373f50..fed21d68bd1 100644 --- a/website/docs/r/codecommit_trigger.html.markdown +++ b/website/docs/r/codecommit_trigger.html.markdown @@ -10,10 +10,6 @@ description: |- Provides a CodeCommit Trigger Resource. -~> **NOTE on CodeCommit**: The CodeCommit is not yet rolled out -in all regions - available regions are listed -[the AWS Docs](https://docs.aws.amazon.com/general/latest/gr/rande.html#codecommit_region). - ## Example Usage ```hcl From 8dde7804da66772b0e903c6c1cb148c89a650771 Mon Sep 17 00:00:00 2001 From: angie pinilla Date: Mon, 18 May 2020 15:20:54 -0400 Subject: [PATCH 189/475] Update CHANGELOG for #12119 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd7c7351153..d8832d1120f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ ## 2.63.0 (Unreleased) + +FEATURES: + +* **New Resource:** `aws_wafv2_ip_set` [GH-12119] + ## 2.62.0 (May 15, 2020) FEATURES: From f4dfa90bf7910267bcb92d56baec720f12bb6a85 Mon Sep 17 00:00:00 2001 From: Kevin Tham Date: Mon, 18 May 2020 16:57:52 -0700 Subject: [PATCH 190/475] pr feedback --- aws/resource_aws_security_group_rule.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/aws/resource_aws_security_group_rule.go b/aws/resource_aws_security_group_rule.go index 509ba4a45c5..ffcf6cffe42 100644 --- a/aws/resource_aws_security_group_rule.go +++ b/aws/resource_aws_security_group_rule.go @@ -842,6 +842,7 @@ func descriptionFromIPPerm(d *schema.ResourceData, rule *ec2.IpPermission) strin } } + // probe UserIdGroupPairs if raw, ok := d.GetOk("source_security_group_id"); ok { components := strings.Split(raw.(string), "/") @@ -851,19 +852,18 @@ func descriptionFromIPPerm(d *schema.ResourceData, rule *ec2.IpPermission) strin groupId := components[1] for _, gp := range rule.UserIdGroupPairs { - if *gp.GroupId != groupId || *gp.UserId != userId { + if aws.StringValue(gp.GroupId) != groupId || aws.StringValue(gp.UserId) != userId { continue } - if *gp.GroupId == groupId && *gp.UserId == userId { - if desc := aws.StringValue(gp.Description); desc != "" { - return desc - } + + if desc := aws.StringValue(gp.Description); desc != "" { + return desc } } case 1: groupId := components[0] for _, gp := range rule.UserIdGroupPairs { - if *gp.GroupId != groupId { + if aws.StringValue(gp.GroupId) != groupId { continue } From 50de3fe22ac603652d9e85e99de876752246fcab Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Mon, 18 May 2020 23:35:50 -0400 Subject: [PATCH 191/475] remove DisableBinaryDriver refs in tests --- aws/resource_aws_api_gateway_usage_plan_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/aws/resource_aws_api_gateway_usage_plan_test.go b/aws/resource_aws_api_gateway_usage_plan_test.go index f3884c6f639..6c1abd687af 100644 --- a/aws/resource_aws_api_gateway_usage_plan_test.go +++ b/aws/resource_aws_api_gateway_usage_plan_test.go @@ -211,7 +211,6 @@ func TestAccAWSAPIGatewayUsagePlan_throttling(t *testing.T) { PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSAPIGatewayUsagePlanDestroy, - DisableBinaryDriver: true, Steps: []resource.TestStep{ { Config: testAccAWSApiGatewayUsagePlanBasicConfig(rName), @@ -266,7 +265,6 @@ func TestAccAWSAPIGatewayUsagePlan_throttlingInitialRateLimit(t *testing.T) { PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSAPIGatewayUsagePlanDestroy, - DisableBinaryDriver: true, Steps: []resource.TestStep{ { Config: testAccAWSApiGatewayUsagePlanThrottlingConfig(rName), @@ -293,7 +291,6 @@ func TestAccAWSAPIGatewayUsagePlan_quota(t *testing.T) { PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSAPIGatewayUsagePlanDestroy, - DisableBinaryDriver: true, Steps: []resource.TestStep{ { Config: testAccAWSApiGatewayUsagePlanBasicConfig(rName), From 212b746745effd9df8f46a2a5ead251002edf648 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Mon, 18 May 2020 23:43:39 -0400 Subject: [PATCH 192/475] run go fmt --- ...resource_aws_api_gateway_usage_plan_test.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/aws/resource_aws_api_gateway_usage_plan_test.go b/aws/resource_aws_api_gateway_usage_plan_test.go index 6c1abd687af..e766f11d7be 100644 --- a/aws/resource_aws_api_gateway_usage_plan_test.go +++ b/aws/resource_aws_api_gateway_usage_plan_test.go @@ -208,9 +208,9 @@ func TestAccAWSAPIGatewayUsagePlan_throttling(t *testing.T) { resourceName := "aws_api_gateway_usage_plan.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSAPIGatewayUsagePlanDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSAPIGatewayUsagePlanDestroy, Steps: []resource.TestStep{ { Config: testAccAWSApiGatewayUsagePlanBasicConfig(rName), @@ -262,9 +262,9 @@ func TestAccAWSAPIGatewayUsagePlan_throttlingInitialRateLimit(t *testing.T) { resourceName := "aws_api_gateway_usage_plan.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSAPIGatewayUsagePlanDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSAPIGatewayUsagePlanDestroy, Steps: []resource.TestStep{ { Config: testAccAWSApiGatewayUsagePlanThrottlingConfig(rName), @@ -288,9 +288,9 @@ func TestAccAWSAPIGatewayUsagePlan_quota(t *testing.T) { resourceName := "aws_api_gateway_usage_plan.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSAPIGatewayUsagePlanDestroy, + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSAPIGatewayUsagePlanDestroy, Steps: []resource.TestStep{ { Config: testAccAWSApiGatewayUsagePlanBasicConfig(rName), From 45bf57207f417e0f53ed8d26232686012c7b64f4 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Mon, 18 May 2020 23:51:42 -0400 Subject: [PATCH 193/475] run go fmt --- aws/resource_aws_cloudfront_distribution_test.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/aws/resource_aws_cloudfront_distribution_test.go b/aws/resource_aws_cloudfront_distribution_test.go index cf4ba8e625c..87f341a1c0c 100644 --- a/aws/resource_aws_cloudfront_distribution_test.go +++ b/aws/resource_aws_cloudfront_distribution_test.go @@ -323,10 +323,9 @@ func TestAccAWSCloudFrontDistribution_noOptionalItemsConfig(t *testing.T) { var distribution cloudfront.Distribution resourceName := "aws_cloudfront_distribution.no_optional_items" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSCloudFront(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckCloudFrontDistributionDestroy, - DisableBinaryDriver: true, + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSCloudFront(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudFrontDistributionDestroy, Steps: []resource.TestStep{ { Config: testAccAWSCloudFrontDistributionNoOptionalItemsConfig, @@ -1080,10 +1079,9 @@ func TestAccAWSCloudFrontDistribution_OriginGroups(t *testing.T) { ri := acctest.RandInt() testConfig := fmt.Sprintf(testAccAWSCloudFrontDistributionOriginGroupsConfig, ri, originBucket, backupBucket, testAccAWSCloudFrontDistributionRetainConfig()) resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSCloudFront(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckCloudFrontDistributionDestroy, - DisableBinaryDriver: true, + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSCloudFront(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudFrontDistributionDestroy, Steps: []resource.TestStep{ { Config: testConfig, From e36f9c9accc6eba00e993b5ba629911f7212aee1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 May 2020 09:18:28 -0400 Subject: [PATCH 194/475] Update module aws/aws-sdk-go to v1.31.0 (#13358) Co-authored-by: Renovate Bot --- go.mod | 2 +- go.sum | 4 +- .../aws/aws-sdk-go/aws/endpoints/defaults.go | 124 +- .../github.com/aws/aws-sdk-go/aws/version.go | 2 +- .../aws-sdk-go/service/cloudformation/api.go | 366 ++++++ .../service/cloudformation/waiters.go | 66 + .../aws/aws-sdk-go/service/dynamodb/api.go | 40 +- .../aws/aws-sdk-go/service/ec2/api.go | 2 +- .../aws/aws-sdk-go/service/ecr/api.go | 45 +- .../aws/aws-sdk-go/service/ecr/errors.go | 3 +- .../aws/aws-sdk-go/service/ecs/api.go | 142 ++- .../aws/aws-sdk-go/service/glue/api.go | 242 +++- .../aws/aws-sdk-go/service/glue/errors.go | 7 + .../aws/aws-sdk-go/service/qldb/api.go | 1120 ++++++++++++++++- .../aws/aws-sdk-go/service/sts/api.go | 4 +- vendor/modules.txt | 2 +- 16 files changed, 2100 insertions(+), 71 deletions(-) diff --git a/go.mod b/go.mod index 064d902dacc..573f3a61b1f 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/terraform-providers/terraform-provider-aws go 1.13 require ( - github.com/aws/aws-sdk-go v1.30.28 + github.com/aws/aws-sdk-go v1.31.0 github.com/beevik/etree v1.1.0 github.com/bflad/tfproviderdocs v0.6.0 github.com/bflad/tfproviderlint v0.14.0 diff --git a/go.sum b/go.sum index 9eb3b8a5b58..ad5339e2676 100644 --- a/go.sum +++ b/go.sum @@ -39,8 +39,8 @@ github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= github.com/aws/aws-sdk-go v1.25.3/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.30.28 h1:SaPM7dlmp7h3Lj1nJ4jdzOkTdom08+g20k7AU5heZYg= -github.com/aws/aws-sdk-go v1.30.28/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/aws-sdk-go v1.31.0 h1:ITLZ0oy7IOB1NGt2Ee75bLevBaH1jaAXE2eyGbPRbCg= +github.com/aws/aws-sdk-go v1.31.0/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go index be3ad80e135..b976086aba7 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go @@ -1641,8 +1641,10 @@ var awsPartition = partition{ "discovery": service{ Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "eu-central-1": endpoint{}, + "us-east-1": endpoint{}, "us-west-2": endpoint{}, }, }, @@ -2119,6 +2121,7 @@ var awsPartition = partition{ "elasticfilesystem": service{ Endpoints: endpoints{ + "af-south-1": endpoint{}, "ap-east-1": endpoint{}, "ap-northeast-1": endpoint{}, "ap-northeast-2": endpoint{}, @@ -2131,6 +2134,12 @@ var awsPartition = partition{ "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, "eu-west-3": endpoint{}, + "fips-af-south-1": endpoint{ + Hostname: "elasticfilesystem-fips.af-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "af-south-1", + }, + }, "fips-ap-east-1": endpoint{ Hostname: "elasticfilesystem-fips.ap-east-1.amazonaws.com", CredentialScope: credentialScope{ @@ -3586,8 +3595,10 @@ var awsPartition = partition{ "mgh": service{ Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "eu-central-1": endpoint{}, + "us-east-1": endpoint{}, "us-west-2": endpoint{}, }, }, @@ -4951,20 +4962,21 @@ var awsPartition = partition{ }, }, "shield": service{ - IsRegionalized: boxedFalse, + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, Defaults: endpoint{ SSLCommonName: "shield.us-east-1.amazonaws.com", Protocols: []string{"https"}, }, Endpoints: endpoints{ - "fips-us-east-1": endpoint{ - Hostname: "shield-fips.us-east-1.amazonaws.com", + "aws-global": endpoint{ + Hostname: "shield.us-east-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-east-1", }, }, - "us-east-1": endpoint{ - Hostname: "shield.us-east-1.amazonaws.com", + "fips-aws-global": endpoint{ + Hostname: "shield-fips.us-east-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-east-1", }, @@ -6506,6 +6518,19 @@ var awscnPartition = partition{ "cn-northwest-1": endpoint{}, }, }, + "route53": service{ + PartitionEndpoint: "aws-cn-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-cn-global": endpoint{ + Hostname: "route53.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, "runtime.sagemaker": service{ Endpoints: endpoints{ @@ -6907,8 +6932,18 @@ var awsusgovPartition = partition{ "cloudformation": service{ Endpoints: endpoints{ - "us-gov-east-1": endpoint{}, - "us-gov-west-1": endpoint{}, + "us-gov-east-1": endpoint{ + Hostname: "cloudformation.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + "us-gov-west-1": endpoint{ + Hostname: "cloudformation.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, }, }, "cloudhsm": service{ @@ -7008,6 +7043,24 @@ var awsusgovPartition = partition{ "us-gov-west-1": endpoint{}, }, }, + "cognito-identity": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "cognito-idp": service{ + + Endpoints: endpoints{ + "fips-us-gov-west-1": endpoint{ + Hostname: "cognito-idp-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + "us-gov-west-1": endpoint{}, + }, + }, "comprehend": service{ Defaults: endpoint{ Protocols: []string{"https"}, @@ -7169,6 +7222,15 @@ var awsusgovPartition = partition{ "us-gov-west-1": endpoint{}, }, }, + "eks": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, "elasticache": service{ Endpoints: endpoints{ @@ -7352,7 +7414,12 @@ var awsusgovPartition = partition{ Protocols: []string{"https"}, }, Endpoints: endpoints{ - "us-gov-west-1": endpoint{}, + "us-gov-west-1": endpoint{ + Hostname: "greengrass.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, }, }, "guardduty": service{ @@ -7854,16 +7921,49 @@ var awsusgovPartition = partition{ "sqs": service{ Endpoints: endpoints{ - "us-gov-east-1": endpoint{}, + "us-gov-east-1": endpoint{ + Hostname: "sqs.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, "us-gov-west-1": endpoint{ + Hostname: "sqs.us-gov-west-1.amazonaws.com", SSLCommonName: "{region}.queue.{dnsSuffix}", Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, }, }, }, "ssm": service{ Endpoints: endpoints{ + "fips-us-gov-east-1": endpoint{ + Hostname: "ssm.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + "fips-us-gov-west-1": endpoint{ + Hostname: "ssm.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + "ssm-facade-fips-us-gov-east-1": endpoint{ + Hostname: "ssm-facade.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + "ssm-facade-fips-us-gov-west-1": endpoint{ + Hostname: "ssm-facade.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, "us-gov-east-1": endpoint{}, "us-gov-west-1": endpoint{}, }, @@ -8208,6 +8308,12 @@ var awsisoPartition = partition{ }, }, }, + "es": service{ + + Endpoints: endpoints{ + "us-iso-east-1": endpoint{}, + }, + }, "events": service{ Endpoints: endpoints{ diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go index d23e36e2da2..8b19a543464 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/version.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -5,4 +5,4 @@ package aws const SDKName = "aws-sdk-go" // SDKVersion is the version of this SDK -const SDKVersion = "1.30.28" +const SDKVersion = "1.31.0" diff --git a/vendor/github.com/aws/aws-sdk-go/service/cloudformation/api.go b/vendor/github.com/aws/aws-sdk-go/service/cloudformation/api.go index d92ee2227bc..a5761751c29 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/cloudformation/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/cloudformation/api.go @@ -1055,6 +1055,12 @@ func (c *CloudFormation) DescribeAccountLimitsRequest(input *DescribeAccountLimi Name: opDescribeAccountLimits, HTTPMethod: "POST", HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "", + TruncationToken: "", + }, } if input == nil { @@ -1101,6 +1107,58 @@ func (c *CloudFormation) DescribeAccountLimitsWithContext(ctx aws.Context, input return out, req.Send() } +// DescribeAccountLimitsPages iterates over the pages of a DescribeAccountLimits operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See DescribeAccountLimits method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a DescribeAccountLimits operation. +// pageNum := 0 +// err := client.DescribeAccountLimitsPages(params, +// func(page *cloudformation.DescribeAccountLimitsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *CloudFormation) DescribeAccountLimitsPages(input *DescribeAccountLimitsInput, fn func(*DescribeAccountLimitsOutput, bool) bool) error { + return c.DescribeAccountLimitsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// DescribeAccountLimitsPagesWithContext same as DescribeAccountLimitsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CloudFormation) DescribeAccountLimitsPagesWithContext(ctx aws.Context, input *DescribeAccountLimitsInput, fn func(*DescribeAccountLimitsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *DescribeAccountLimitsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeAccountLimitsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*DescribeAccountLimitsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opDescribeChangeSet = "DescribeChangeSet" // DescribeChangeSetRequest generates a "aws/request.Request" representing the @@ -3038,6 +3096,12 @@ func (c *CloudFormation) ListChangeSetsRequest(input *ListChangeSetsInput) (req Name: opListChangeSets, HTTPMethod: "POST", HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "", + TruncationToken: "", + }, } if input == nil { @@ -3083,6 +3147,58 @@ func (c *CloudFormation) ListChangeSetsWithContext(ctx aws.Context, input *ListC return out, req.Send() } +// ListChangeSetsPages iterates over the pages of a ListChangeSets operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListChangeSets method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListChangeSets operation. +// pageNum := 0 +// err := client.ListChangeSetsPages(params, +// func(page *cloudformation.ListChangeSetsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *CloudFormation) ListChangeSetsPages(input *ListChangeSetsInput, fn func(*ListChangeSetsOutput, bool) bool) error { + return c.ListChangeSetsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListChangeSetsPagesWithContext same as ListChangeSetsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CloudFormation) ListChangeSetsPagesWithContext(ctx aws.Context, input *ListChangeSetsInput, fn func(*ListChangeSetsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListChangeSetsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListChangeSetsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListChangeSetsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opListExports = "ListExports" // ListExportsRequest generates a "aws/request.Request" representing the @@ -3389,6 +3505,12 @@ func (c *CloudFormation) ListStackInstancesRequest(input *ListStackInstancesInpu Name: opListStackInstances, HTTPMethod: "POST", HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, } if input == nil { @@ -3439,6 +3561,58 @@ func (c *CloudFormation) ListStackInstancesWithContext(ctx aws.Context, input *L return out, req.Send() } +// ListStackInstancesPages iterates over the pages of a ListStackInstances operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListStackInstances method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListStackInstances operation. +// pageNum := 0 +// err := client.ListStackInstancesPages(params, +// func(page *cloudformation.ListStackInstancesOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *CloudFormation) ListStackInstancesPages(input *ListStackInstancesInput, fn func(*ListStackInstancesOutput, bool) bool) error { + return c.ListStackInstancesPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListStackInstancesPagesWithContext same as ListStackInstancesPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CloudFormation) ListStackInstancesPagesWithContext(ctx aws.Context, input *ListStackInstancesInput, fn func(*ListStackInstancesOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListStackInstancesInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListStackInstancesRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListStackInstancesOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opListStackResources = "ListStackResources" // ListStackResourcesRequest generates a "aws/request.Request" representing the @@ -3605,6 +3779,12 @@ func (c *CloudFormation) ListStackSetOperationResultsRequest(input *ListStackSet Name: opListStackSetOperationResults, HTTPMethod: "POST", HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, } if input == nil { @@ -3656,6 +3836,58 @@ func (c *CloudFormation) ListStackSetOperationResultsWithContext(ctx aws.Context return out, req.Send() } +// ListStackSetOperationResultsPages iterates over the pages of a ListStackSetOperationResults operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListStackSetOperationResults method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListStackSetOperationResults operation. +// pageNum := 0 +// err := client.ListStackSetOperationResultsPages(params, +// func(page *cloudformation.ListStackSetOperationResultsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *CloudFormation) ListStackSetOperationResultsPages(input *ListStackSetOperationResultsInput, fn func(*ListStackSetOperationResultsOutput, bool) bool) error { + return c.ListStackSetOperationResultsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListStackSetOperationResultsPagesWithContext same as ListStackSetOperationResultsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CloudFormation) ListStackSetOperationResultsPagesWithContext(ctx aws.Context, input *ListStackSetOperationResultsInput, fn func(*ListStackSetOperationResultsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListStackSetOperationResultsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListStackSetOperationResultsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListStackSetOperationResultsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opListStackSetOperations = "ListStackSetOperations" // ListStackSetOperationsRequest generates a "aws/request.Request" representing the @@ -3687,6 +3919,12 @@ func (c *CloudFormation) ListStackSetOperationsRequest(input *ListStackSetOperat Name: opListStackSetOperations, HTTPMethod: "POST", HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, } if input == nil { @@ -3735,6 +3973,58 @@ func (c *CloudFormation) ListStackSetOperationsWithContext(ctx aws.Context, inpu return out, req.Send() } +// ListStackSetOperationsPages iterates over the pages of a ListStackSetOperations operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListStackSetOperations method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListStackSetOperations operation. +// pageNum := 0 +// err := client.ListStackSetOperationsPages(params, +// func(page *cloudformation.ListStackSetOperationsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *CloudFormation) ListStackSetOperationsPages(input *ListStackSetOperationsInput, fn func(*ListStackSetOperationsOutput, bool) bool) error { + return c.ListStackSetOperationsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListStackSetOperationsPagesWithContext same as ListStackSetOperationsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CloudFormation) ListStackSetOperationsPagesWithContext(ctx aws.Context, input *ListStackSetOperationsInput, fn func(*ListStackSetOperationsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListStackSetOperationsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListStackSetOperationsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListStackSetOperationsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opListStackSets = "ListStackSets" // ListStackSetsRequest generates a "aws/request.Request" representing the @@ -3766,6 +4056,12 @@ func (c *CloudFormation) ListStackSetsRequest(input *ListStackSetsInput) (req *r Name: opListStackSets, HTTPMethod: "POST", HTTPPath: "/", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, } if input == nil { @@ -3810,6 +4106,58 @@ func (c *CloudFormation) ListStackSetsWithContext(ctx aws.Context, input *ListSt return out, req.Send() } +// ListStackSetsPages iterates over the pages of a ListStackSets operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListStackSets method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListStackSets operation. +// pageNum := 0 +// err := client.ListStackSetsPages(params, +// func(page *cloudformation.ListStackSetsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *CloudFormation) ListStackSetsPages(input *ListStackSetsInput, fn func(*ListStackSetsOutput, bool) bool) error { + return c.ListStackSetsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListStackSetsPagesWithContext same as ListStackSetsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CloudFormation) ListStackSetsPagesWithContext(ctx aws.Context, input *ListStackSetsInput, fn func(*ListStackSetsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListStackSetsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListStackSetsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListStackSetsOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opListStacks = "ListStacks" // ListStacksRequest generates a "aws/request.Request" representing the @@ -8851,6 +9199,9 @@ type DescribeTypeOutput struct { // role to provide your resource type with the appropriate credentials. ExecutionRoleArn *string `min:"1" type:"string"` + // Whether the specified type version is set as the default version. + IsDefaultVersion *bool `type:"boolean"` + // When the specified type version was registered. LastUpdated *time.Time `type:"timestamp"` @@ -8952,6 +9303,12 @@ func (s *DescribeTypeOutput) SetExecutionRoleArn(v string) *DescribeTypeOutput { return s } +// SetIsDefaultVersion sets the IsDefaultVersion field's value. +func (s *DescribeTypeOutput) SetIsDefaultVersion(v bool) *DescribeTypeOutput { + s.IsDefaultVersion = &v + return s +} + // SetLastUpdated sets the LastUpdated field's value. func (s *DescribeTypeOutput) SetLastUpdated(v time.Time) *DescribeTypeOutput { s.LastUpdated = &v @@ -15424,6 +15781,9 @@ type TypeVersionSummary struct { // The description of the type version. Description *string `min:"1" type:"string"` + // Whether the specified type version is set as the default version. + IsDefaultVersion *bool `type:"boolean"` + // When the version was registered. TimeCreated *time.Time `type:"timestamp"` @@ -15461,6 +15821,12 @@ func (s *TypeVersionSummary) SetDescription(v string) *TypeVersionSummary { return s } +// SetIsDefaultVersion sets the IsDefaultVersion field's value. +func (s *TypeVersionSummary) SetIsDefaultVersion(v bool) *TypeVersionSummary { + s.IsDefaultVersion = &v + return s +} + // SetTimeCreated sets the TimeCreated field's value. func (s *TypeVersionSummary) SetTimeCreated(v time.Time) *TypeVersionSummary { s.TimeCreated = &v diff --git a/vendor/github.com/aws/aws-sdk-go/service/cloudformation/waiters.go b/vendor/github.com/aws/aws-sdk-go/service/cloudformation/waiters.go index 0dbdc6c2353..183720d485a 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/cloudformation/waiters.go +++ b/vendor/github.com/aws/aws-sdk-go/service/cloudformation/waiters.go @@ -349,6 +349,72 @@ func (c *CloudFormation) WaitUntilStackImportCompleteWithContext(ctx aws.Context return w.WaitWithContext(ctx) } +// WaitUntilStackRollbackComplete uses the AWS CloudFormation API operation +// DescribeStacks to wait for a condition to be met before returning. +// If the condition is not met within the max attempt window, an error will +// be returned. +func (c *CloudFormation) WaitUntilStackRollbackComplete(input *DescribeStacksInput) error { + return c.WaitUntilStackRollbackCompleteWithContext(aws.BackgroundContext(), input) +} + +// WaitUntilStackRollbackCompleteWithContext is an extended version of WaitUntilStackRollbackComplete. +// With the support for passing in a context and options to configure the +// Waiter and the underlying request options. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *CloudFormation) WaitUntilStackRollbackCompleteWithContext(ctx aws.Context, input *DescribeStacksInput, opts ...request.WaiterOption) error { + w := request.Waiter{ + Name: "WaitUntilStackRollbackComplete", + MaxAttempts: 120, + Delay: request.ConstantWaiterDelay(30 * time.Second), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.PathAllWaiterMatch, Argument: "Stacks[].StackStatus", + Expected: "UPDATE_ROLLBACK_COMPLETE", + }, + { + State: request.FailureWaiterState, + Matcher: request.PathAnyWaiterMatch, Argument: "Stacks[].StackStatus", + Expected: "UPDATE_FAILED", + }, + { + State: request.FailureWaiterState, + Matcher: request.PathAnyWaiterMatch, Argument: "Stacks[].StackStatus", + Expected: "UPDATE_ROLLBACK_FAILED", + }, + { + State: request.FailureWaiterState, + Matcher: request.PathAnyWaiterMatch, Argument: "Stacks[].StackStatus", + Expected: "DELETE_FAILED", + }, + { + State: request.FailureWaiterState, + Matcher: request.ErrorWaiterMatch, + Expected: "ValidationError", + }, + }, + Logger: c.Config.Logger, + NewRequest: func(opts []request.Option) (*request.Request, error) { + var inCpy *DescribeStacksInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.DescribeStacksRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + w.ApplyOptions(opts...) + + return w.WaitWithContext(ctx) +} + // WaitUntilStackUpdateComplete uses the AWS CloudFormation API operation // DescribeStacks to wait for a condition to be met before returning. // If the condition is not met within the max attempt window, an error will diff --git a/vendor/github.com/aws/aws-sdk-go/service/dynamodb/api.go b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/api.go index e7983fa8e3d..ea2ca2c3350 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/dynamodb/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/dynamodb/api.go @@ -670,7 +670,7 @@ func (c *DynamoDB) CreateGlobalTableRequest(input *CreateGlobalTableInput) (req // relationship between two or more DynamoDB tables with the same table name // in the provided Regions. // -// This method only applies to Version 2017.11.29 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html) +// This operation only applies to Version 2017.11.29 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html) // of global tables. // // If you want to add a new replica table to a global table, each of the following @@ -693,6 +693,14 @@ func (c *DynamoDB) CreateGlobalTableRequest(input *CreateGlobalTableInput) (req // * The global secondary indexes must have the same hash key and sort key // (if present). // +// If local secondary indexes are specified, then the following conditions must +// also be met: +// +// * The local secondary indexes must have the same name. +// +// * The local secondary indexes must have the same hash key and sort key +// (if present). +// // Write capacity settings should be set consistently across your replica tables // and secondary indexes. DynamoDB strongly recommends enabling auto scaling // to manage the write capacity settings for all of your global tables replicas @@ -1839,8 +1847,10 @@ func (c *DynamoDB) DescribeGlobalTableRequest(input *DescribeGlobalTableInput) ( // // Returns information about the specified global table. // -// This method only applies to Version 2017.11.29 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html) -// of global tables. +// This operation only applies to Version 2017.11.29 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html) +// of global tables. If you are using global tables Version 2019.11.21 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V2.html) +// you can use DescribeTable (https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) +// instead. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about @@ -1949,7 +1959,7 @@ func (c *DynamoDB) DescribeGlobalTableSettingsRequest(input *DescribeGlobalTable // // Describes Region-specific settings for a global table. // -// This method only applies to Version 2017.11.29 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html) +// This operation only applies to Version 2017.11.29 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html) // of global tables. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -2311,7 +2321,7 @@ func (c *DynamoDB) DescribeTableReplicaAutoScalingRequest(input *DescribeTableRe // // Describes auto scaling settings across replicas of the global table at once. // -// This method only applies to Version 2019.11.21 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V2.html) +// This operation only applies to Version 2019.11.21 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V2.html) // of global tables. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -2912,7 +2922,7 @@ func (c *DynamoDB) ListGlobalTablesRequest(input *ListGlobalTablesInput) (req *r // // Lists all global tables that have a replica in the specified Region. // -// This method only applies to Version 2017.11.29 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html) +// This operation only applies to Version 2017.11.29 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html) // of global tables. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -3325,9 +3335,15 @@ func (c *DynamoDB) PutItemRequest(input *PutItemInput) (req *request.Request, ou // * PutItem in the AWS SDK for Ruby V2 (http://docs.aws.amazon.com/goto/SdkForRubyV2/dynamodb-2012-08-10/PutItem) // // When you add an item, the primary key attributes are the only required attributes. -// Attribute values cannot be null. String and Binary type attributes must have -// lengths greater than zero. Set type attributes cannot be empty. Requests -// with empty values will be rejected with a ValidationException exception. +// Attribute values cannot be null. +// +// Empty String and Binary attribute values are allowed. Attribute values of +// type String and Binary must have a length greater than zero if the attribute +// is used as a key attribute for a table or index. Set type attributes cannot +// be empty. +// +// Invalid Requests with empty values will be rejected with a ValidationException +// exception. // // To prevent a new item from replacing an existing item, use a conditional // expression that contains the attribute_not_exists function with the name @@ -5709,7 +5725,7 @@ func (c *DynamoDB) UpdateTableReplicaAutoScalingRequest(input *UpdateTableReplic // // Updates auto scaling settings on your global tables at once. // -// This method only applies to Version 2019.11.21 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V2.html) +// This operation only applies to Version 2019.11.21 (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V2.html) // of global tables. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -13564,6 +13580,10 @@ type PutItemInput struct { // types for those attributes must match those of the schema in the table's // attribute definition. // + // Empty String and Binary attribute values are allowed. Attribute values of + // type String and Binary must have a length greater than zero if the attribute + // is used as a key attribute for a table or index. + // // For more information about primary keys, see Primary Key (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey) // in the Amazon DynamoDB Developer Guide. // diff --git a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go index d71efab9be8..33af5505174 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ec2/api.go @@ -98233,7 +98233,7 @@ type RunInstancesInput struct { // For more information, see Ensuring Idempotency (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html). // // Constraints: Maximum 64 ASCII characters - ClientToken *string `locationName:"clientToken" type:"string"` + ClientToken *string `locationName:"clientToken" type:"string" idempotencyToken:"true"` // The CPU options for the instance. For more information, see Optimizing CPU // Options (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-optimize-cpu.html) diff --git a/vendor/github.com/aws/aws-sdk-go/service/ecr/api.go b/vendor/github.com/aws/aws-sdk-go/service/ecr/api.go index 91e36f08d1c..12e2e1bd6a6 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ecr/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ecr/api.go @@ -483,8 +483,7 @@ func (c *ECR) CreateRepositoryRequest(input *CreateRepositoryInput) (req *reques // // * LimitExceededException // The operation did not succeed because it would have exceeded a service limit -// for your account. For more information, see Amazon ECR Default Service Limits -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service_limits.html) +// for your account. For more information, see Amazon ECR Service Quotas (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service-quotas.html) // in the Amazon Elastic Container Registry User Guide. // // See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CreateRepository @@ -2178,8 +2177,7 @@ func (c *ECR) PutImageRequest(input *PutImageInput) (req *request.Request, outpu // // * LimitExceededException // The operation did not succeed because it would have exceeded a service limit -// for your account. For more information, see Amazon ECR Default Service Limits -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service_limits.html) +// for your account. For more information, see Amazon ECR Service Quotas (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service-quotas.html) // in the Amazon Elastic Container Registry User Guide. // // * ImageTagAlreadyExistsException @@ -2517,7 +2515,7 @@ func (c *ECR) SetRepositoryPolicyRequest(input *SetRepositoryPolicyInput) (req * // SetRepositoryPolicy API operation for Amazon EC2 Container Registry. // // Applies a repository policy to the specified repository to control access -// permissions. For more information, see Amazon ECR Repository Policies (https://docs.aws.amazon.com/AmazonECR/latest/userguide/RepositoryPolicies.html) +// permissions. For more information, see Amazon ECR Repository Policies (https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html) // in the Amazon Elastic Container Registry User Guide. // // Returns awserr.Error for service API and SDK errors. Use runtime type assertions @@ -2630,8 +2628,7 @@ func (c *ECR) StartImageScanRequest(input *StartImageScanInput) (req *request.Re // // * LimitExceededException // The operation did not succeed because it would have exceeded a service limit -// for your account. For more information, see Amazon ECR Default Service Limits -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service_limits.html) +// for your account. For more information, see Amazon ECR Service Quotas (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service-quotas.html) // in the Amazon Elastic Container Registry User Guide. // // * RepositoryNotFoundException @@ -3037,8 +3034,7 @@ func (c *ECR) UploadLayerPartRequest(input *UploadLayerPartInput) (req *request. // // * LimitExceededException // The operation did not succeed because it would have exceeded a service limit -// for your account. For more information, see Amazon ECR Default Service Limits -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service_limits.html) +// for your account. For more information, see Amazon ECR Service Quotas (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service-quotas.html) // in the Amazon Elastic Container Registry User Guide. // // See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/UploadLayerPart @@ -5080,6 +5076,9 @@ type Image struct { // The image manifest associated with the image. ImageManifest *string `locationName:"imageManifest" min:"1" type:"string"` + // The media type associated with the image manifest. + ImageManifestMediaType *string `locationName:"imageManifestMediaType" type:"string"` + // The AWS account ID associated with the registry containing the image. RegistryId *string `locationName:"registryId" type:"string"` @@ -5109,6 +5108,12 @@ func (s *Image) SetImageManifest(v string) *Image { return s } +// SetImageManifestMediaType sets the ImageManifestMediaType field's value. +func (s *Image) SetImageManifestMediaType(v string) *Image { + s.ImageManifestMediaType = &v + return s +} + // SetRegistryId sets the RegistryId field's value. func (s *Image) SetRegistryId(v string) *Image { s.RegistryId = &v @@ -6647,8 +6652,7 @@ func (s *LifecyclePolicyRuleAction) SetType(v string) *LifecyclePolicyRuleAction } // The operation did not succeed because it would have exceeded a service limit -// for your account. For more information, see Amazon ECR Default Service Limits -// (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service_limits.html) +// for your account. For more information, see Amazon ECR Service Quotas (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service-quotas.html) // in the Amazon Elastic Container Registry User Guide. type LimitExceededException struct { _ struct{} `type:"structure"` @@ -6930,6 +6934,11 @@ type PutImageInput struct { // ImageManifest is a required field ImageManifest *string `locationName:"imageManifest" min:"1" type:"string" required:"true"` + // The media type of the image manifest. If you push an image manifest that + // does not contain the mediaType field, you must specify the imageManifestMediaType + // in the request. + ImageManifestMediaType *string `locationName:"imageManifestMediaType" type:"string"` + // The tag to associate with the image. This parameter is required for images // that use the Docker Image Manifest V2 Schema 2 or OCI formats. ImageTag *string `locationName:"imageTag" min:"1" type:"string"` @@ -6986,6 +6995,12 @@ func (s *PutImageInput) SetImageManifest(v string) *PutImageInput { return s } +// SetImageManifestMediaType sets the ImageManifestMediaType field's value. +func (s *PutImageInput) SetImageManifestMediaType(v string) *PutImageInput { + s.ImageManifestMediaType = &v + return s +} + // SetImageTag sets the ImageTag field's value. func (s *PutImageInput) SetImageTag(v string) *PutImageInput { s.ImageTag = &v @@ -7847,7 +7862,7 @@ type SetRepositoryPolicyInput struct { Force *bool `locationName:"force" type:"boolean"` // The JSON repository policy text to apply to the repository. For more information, - // see Amazon ECR Repository Policy Examples (https://docs.aws.amazon.com/AmazonECR/latest/userguide/RepositoryPolicyExamples.html) + // see Amazon ECR Repository Policies (https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policy-examples.html) // in the Amazon Elastic Container Registry User Guide. // // PolicyText is a required field @@ -8489,12 +8504,14 @@ type UploadLayerPartInput struct { // LayerPartBlob is a required field LayerPartBlob []byte `locationName:"layerPartBlob" type:"blob" required:"true"` - // The integer value of the first byte of the layer part. + // The position of the first byte of the layer part witin the overall image + // layer. // // PartFirstByte is a required field PartFirstByte *int64 `locationName:"partFirstByte" type:"long" required:"true"` - // The integer value of the last byte of the layer part. + // The position of the last byte of the layer part within the overall image + // layer. // // PartLastByte is a required field PartLastByte *int64 `locationName:"partLastByte" type:"long" required:"true"` diff --git a/vendor/github.com/aws/aws-sdk-go/service/ecr/errors.go b/vendor/github.com/aws/aws-sdk-go/service/ecr/errors.go index c4e9b4013b4..bf44256bd1c 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ecr/errors.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ecr/errors.go @@ -112,8 +112,7 @@ const ( // "LimitExceededException". // // The operation did not succeed because it would have exceeded a service limit - // for your account. For more information, see Amazon ECR Default Service Limits - // (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service_limits.html) + // for your account. For more information, see Amazon ECR Service Quotas (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service-quotas.html) // in the Amazon Elastic Container Registry User Guide. ErrCodeLimitExceededException = "LimitExceededException" diff --git a/vendor/github.com/aws/aws-sdk-go/service/ecs/api.go b/vendor/github.com/aws/aws-sdk-go/service/ecs/api.go index 533e5460c24..8a85c7cd85e 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/ecs/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/ecs/api.go @@ -7060,6 +7060,27 @@ type ContainerDefinition struct { // such as credential data. Environment []*KeyValuePair `locationName:"environment" type:"list"` + // A list of files containing the environment variables to pass to a container. + // This parameter maps to the --env-file option to docker run (https://docs.docker.com/engine/reference/run/). + // + // You can specify up to ten environment files. The file must have a .env file + // extension. Each line in an environment file should contain an environment + // variable in VARIABLE=VALUE format. Lines beginning with # are treated as + // comments and are ignored. For more information on the environment variable + // file syntax, see Declare default environment variables in file (https://docs.docker.com/compose/env-file/). + // + // If there are environment variables specified using the environment parameter + // in a container definition, they take precedence over the variables contained + // within an environment file. If multiple environment files are specified that + // contain the same variable, they are processed from the top down. It is recommended + // to use unique variable names. For more information, see Specifying Environment + // Variables (https://docs.aws.amazon.com/AmazonECS/latest/developerguide/taskdef-envfiles.html) + // in the Amazon Elastic Container Service Developer Guide. + // + // This field is not valid for containers in tasks using the Fargate launch + // type. + EnvironmentFiles []*EnvironmentFile `locationName:"environmentFiles" type:"list"` + // If the essential parameter of a container is marked as true, and that container // fails or stops for any reason, all other containers that are part of the // task are stopped. If the essential parameter of a container is marked as @@ -7472,6 +7493,16 @@ func (s *ContainerDefinition) Validate() error { } } } + if s.EnvironmentFiles != nil { + for i, v := range s.EnvironmentFiles { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "EnvironmentFiles", i), err.(request.ErrInvalidParams)) + } + } + } if s.ExtraHosts != nil { for i, v := range s.ExtraHosts { if v == nil { @@ -7604,6 +7635,12 @@ func (s *ContainerDefinition) SetEnvironment(v []*KeyValuePair) *ContainerDefini return s } +// SetEnvironmentFiles sets the EnvironmentFiles field's value. +func (s *ContainerDefinition) SetEnvironmentFiles(v []*EnvironmentFile) *ContainerDefinition { + s.EnvironmentFiles = v + return s +} + // SetEssential sets the Essential field's value. func (s *ContainerDefinition) SetEssential(v bool) *ContainerDefinition { s.Essential = &v @@ -8119,6 +8156,10 @@ type ContainerOverride struct { // You must also specify a container name. Environment []*KeyValuePair `locationName:"environment" type:"list"` + // A list of files containing the environment variables to pass to a container, + // instead of the value from the container definition. + EnvironmentFiles []*EnvironmentFile `locationName:"environmentFiles" type:"list"` + // The hard limit (in MiB) of memory to present to the container, instead of // the default value from the task definition. If your container attempts to // exceed the memory specified here, the container is killed. You must also @@ -8153,6 +8194,16 @@ func (s ContainerOverride) GoString() string { // Validate inspects the fields of the type to determine if they are valid. func (s *ContainerOverride) Validate() error { invalidParams := request.ErrInvalidParams{Context: "ContainerOverride"} + if s.EnvironmentFiles != nil { + for i, v := range s.EnvironmentFiles { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "EnvironmentFiles", i), err.(request.ErrInvalidParams)) + } + } + } if s.ResourceRequirements != nil { for i, v := range s.ResourceRequirements { if v == nil { @@ -8188,6 +8239,12 @@ func (s *ContainerOverride) SetEnvironment(v []*KeyValuePair) *ContainerOverride return s } +// SetEnvironmentFiles sets the EnvironmentFiles field's value. +func (s *ContainerOverride) SetEnvironmentFiles(v []*EnvironmentFile) *ContainerOverride { + s.EnvironmentFiles = v + return s +} + // SetMemory sets the Memory field's value. func (s *ContainerOverride) SetMemory(v int64) *ContainerOverride { s.Memory = &v @@ -11219,6 +11276,76 @@ func (s *EFSVolumeConfiguration) SetTransitEncryptionPort(v int64) *EFSVolumeCon return s } +// A list of files containing the environment variables to pass to a container. +// You can specify up to ten environment files. The file must have a .env file +// extension. Each line in an environment file should contain an environment +// variable in VARIABLE=VALUE format. Lines beginning with # are treated as +// comments and are ignored. For more information on the environment variable +// file syntax, see Declare default environment variables in file (https://docs.docker.com/compose/env-file/). +// +// If there are environment variables specified using the environment parameter +// in a container definition, they take precedence over the variables contained +// within an environment file. If multiple environment files are specified that +// contain the same variable, they are processed from the top down. It is recommended +// to use unique variable names. For more information, see Specifying Environment +// Variables (https://docs.aws.amazon.com/AmazonECS/latest/developerguide/taskdef-envfiles.html) +// in the Amazon Elastic Container Service Developer Guide. +// +// This field is not valid for containers in tasks using the Fargate launch +// type. +type EnvironmentFile struct { + _ struct{} `type:"structure"` + + // The file type to use. The only supported value is s3. + // + // Type is a required field + Type *string `locationName:"type" type:"string" required:"true" enum:"EnvironmentFileType"` + + // The Amazon Resource Name (ARN) of the Amazon S3 object containing the environment + // variable file. + // + // Value is a required field + Value *string `locationName:"value" type:"string" required:"true"` +} + +// String returns the string representation +func (s EnvironmentFile) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EnvironmentFile) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *EnvironmentFile) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "EnvironmentFile"} + if s.Type == nil { + invalidParams.Add(request.NewErrParamRequired("Type")) + } + if s.Value == nil { + invalidParams.Add(request.NewErrParamRequired("Value")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetType sets the Type field's value. +func (s *EnvironmentFile) SetType(v string) *EnvironmentFile { + s.Type = &v + return s +} + +// SetValue sets the Value field's value. +func (s *EnvironmentFile) SetValue(v string) *EnvironmentFile { + s.Value = &v + return s +} + // A failed resource. type Failure struct { _ struct{} `type:"structure"` @@ -11715,8 +11842,9 @@ type KernelCapabilities struct { // section of the Docker Remote API (https://docs.docker.com/engine/api/v1.35/) // and the --cap-add option to docker run (https://docs.docker.com/engine/reference/run/). // - // If you are using tasks that use the Fargate launch type, the add parameter - // is not supported. + // The SYS_PTRACE capability is supported for tasks that use the Fargate launch + // type if they are also using platform version 1.4.0. The other capabilities + // are not supported for any platform versions. // // Valid values: "ALL" | "AUDIT_CONTROL" | "AUDIT_WRITE" | "BLOCK_SUSPEND" | // "CHOWN" | "DAC_OVERRIDE" | "DAC_READ_SEARCH" | "FOWNER" | "FSETID" | "IPC_LOCK" @@ -11865,8 +11993,9 @@ type LinuxParameters struct { // The Linux capabilities for the container that are added to or dropped from // the default configuration provided by Docker. // - // If you are using tasks that use the Fargate launch type, capabilities is - // supported but the add parameter is not supported. + // For tasks that use the Fargate launch type, capabilities is supported for + // all platform versions but the add parameter is only supported if using platform + // version 1.4.0 or later. Capabilities *KernelCapabilities `locationName:"capabilities" type:"structure"` // Any host devices to expose to the container. This parameter maps to Devices @@ -20024,6 +20153,11 @@ const ( EFSTransitEncryptionDisabled = "DISABLED" ) +const ( + // EnvironmentFileTypeS3 is a EnvironmentFileType enum value + EnvironmentFileTypeS3 = "s3" +) + const ( // FirelensConfigurationTypeFluentd is a FirelensConfigurationType enum value FirelensConfigurationTypeFluentd = "fluentd" diff --git a/vendor/github.com/aws/aws-sdk-go/service/glue/api.go b/vendor/github.com/aws/aws-sdk-go/service/glue/api.go index 965e0382e61..58312d39b23 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/glue/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/glue/api.go @@ -11279,6 +11279,98 @@ func (c *Glue) StopTriggerWithContext(ctx aws.Context, input *StopTriggerInput, return out, req.Send() } +const opStopWorkflowRun = "StopWorkflowRun" + +// StopWorkflowRunRequest generates a "aws/request.Request" representing the +// client's request for the StopWorkflowRun operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See StopWorkflowRun for more information on using the StopWorkflowRun +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the StopWorkflowRunRequest method. +// req, resp := client.StopWorkflowRunRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/glue-2017-03-31/StopWorkflowRun +func (c *Glue) StopWorkflowRunRequest(input *StopWorkflowRunInput) (req *request.Request, output *StopWorkflowRunOutput) { + op := &request.Operation{ + Name: opStopWorkflowRun, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &StopWorkflowRunInput{} + } + + output = &StopWorkflowRunOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(jsonrpc.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// StopWorkflowRun API operation for AWS Glue. +// +// Stops the execution of the specified workflow run. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Glue's +// API operation StopWorkflowRun for usage and error information. +// +// Returned Error Types: +// * InvalidInputException +// The input provided was not valid. +// +// * EntityNotFoundException +// A specified entity does not exist +// +// * InternalServiceException +// An internal service error occurred. +// +// * OperationTimeoutException +// The operation timed out. +// +// * IllegalWorkflowStateException +// The workflow is in an invalid state to perform a requested operation. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/glue-2017-03-31/StopWorkflowRun +func (c *Glue) StopWorkflowRun(input *StopWorkflowRunInput) (*StopWorkflowRunOutput, error) { + req, out := c.StopWorkflowRunRequest(input) + return out, req.Send() +} + +// StopWorkflowRunWithContext is the same as StopWorkflowRun with the addition of +// the ability to pass a context and additional request options. +// +// See StopWorkflowRun for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Glue) StopWorkflowRunWithContext(ctx aws.Context, input *StopWorkflowRunInput, opts ...request.Option) (*StopWorkflowRunOutput, error) { + req, out := c.StopWorkflowRunRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opTagResource = "TagResource" // TagResourceRequest generates a "aws/request.Request" representing the @@ -14843,8 +14935,9 @@ type Condition struct { // A logical operator. LogicalOperator *string `type:"string" enum:"LogicalOperator"` - // The condition state. Currently, the values supported are SUCCEEDED, STOPPED, - // TIMEOUT, and FAILED. + // The condition state. Currently, the only job states that a trigger can listen + // for are SUCCEEDED, STOPPED, FAILED, and TIMEOUT. The only crawler states + // that a trigger can listen for are SUCCEEDED, FAILED, and CANCELLED. State *string `type:"string" enum:"JobRunState"` } @@ -25095,6 +25188,63 @@ func (s *IdempotentParameterMismatchException) RequestID() string { return s.RespMetadata.RequestID } +// The workflow is in an invalid state to perform a requested operation. +type IllegalWorkflowStateException struct { + _ struct{} `type:"structure"` + RespMetadata protocol.ResponseMetadata `json:"-" xml:"-"` + + // A message describing the problem. + Message_ *string `locationName:"Message" type:"string"` +} + +// String returns the string representation +func (s IllegalWorkflowStateException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s IllegalWorkflowStateException) GoString() string { + return s.String() +} + +func newErrorIllegalWorkflowStateException(v protocol.ResponseMetadata) error { + return &IllegalWorkflowStateException{ + RespMetadata: v, + } +} + +// Code returns the exception type name. +func (s *IllegalWorkflowStateException) Code() string { + return "IllegalWorkflowStateException" +} + +// Message returns the exception's message. +func (s *IllegalWorkflowStateException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *IllegalWorkflowStateException) OrigErr() error { + return nil +} + +func (s *IllegalWorkflowStateException) Error() string { + return fmt.Sprintf("%s: %s", s.Code(), s.Message()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *IllegalWorkflowStateException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *IllegalWorkflowStateException) RequestID() string { + return s.RespMetadata.RequestID +} + type ImportCatalogToGlueInput struct { _ struct{} `type:"structure"` @@ -25833,7 +25983,8 @@ type JobRun struct { // The name of the job definition being used in this run. JobName *string `min:"1" type:"string"` - // The current state of the job run. + // The current state of the job run. For more information about the statuses + // of jobs that have terminated abnormally, see AWS Glue Job Run Statuses (https://docs.aws.amazon.com/glue/latest/dg/job-run-statuses.html). JobRunState *string `type:"string" enum:"JobRunState"` // The last time that this job run was modified. @@ -30302,6 +30453,78 @@ func (s *StopTriggerOutput) SetName(v string) *StopTriggerOutput { return s } +type StopWorkflowRunInput struct { + _ struct{} `type:"structure"` + + // The name of the workflow to stop. + // + // Name is a required field + Name *string `min:"1" type:"string" required:"true"` + + // The ID of the workflow run to stop. + // + // RunId is a required field + RunId *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s StopWorkflowRunInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StopWorkflowRunInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *StopWorkflowRunInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "StopWorkflowRunInput"} + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Name", 1)) + } + if s.RunId == nil { + invalidParams.Add(request.NewErrParamRequired("RunId")) + } + if s.RunId != nil && len(*s.RunId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("RunId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetName sets the Name field's value. +func (s *StopWorkflowRunInput) SetName(v string) *StopWorkflowRunInput { + s.Name = &v + return s +} + +// SetRunId sets the RunId field's value. +func (s *StopWorkflowRunInput) SetRunId(v string) *StopWorkflowRunInput { + s.RunId = &v + return s +} + +type StopWorkflowRunOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s StopWorkflowRunOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StopWorkflowRunOutput) GoString() string { + return s.String() +} + // Describes the physical storage of table data. type StorageDescriptor struct { _ struct{} `type:"structure"` @@ -34291,12 +34514,15 @@ const ( // CrawlStateRunning is a CrawlState enum value CrawlStateRunning = "RUNNING" - // CrawlStateSucceeded is a CrawlState enum value - CrawlStateSucceeded = "SUCCEEDED" + // CrawlStateCancelling is a CrawlState enum value + CrawlStateCancelling = "CANCELLING" // CrawlStateCancelled is a CrawlState enum value CrawlStateCancelled = "CANCELLED" + // CrawlStateSucceeded is a CrawlState enum value + CrawlStateSucceeded = "SUCCEEDED" + // CrawlStateFailed is a CrawlState enum value CrawlStateFailed = "FAILED" ) @@ -34654,4 +34880,10 @@ const ( // WorkflowRunStatusCompleted is a WorkflowRunStatus enum value WorkflowRunStatusCompleted = "COMPLETED" + + // WorkflowRunStatusStopping is a WorkflowRunStatus enum value + WorkflowRunStatusStopping = "STOPPING" + + // WorkflowRunStatusStopped is a WorkflowRunStatus enum value + WorkflowRunStatusStopped = "STOPPED" ) diff --git a/vendor/github.com/aws/aws-sdk-go/service/glue/errors.go b/vendor/github.com/aws/aws-sdk-go/service/glue/errors.go index dc5ad7afd38..95a992b0233 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/glue/errors.go +++ b/vendor/github.com/aws/aws-sdk-go/service/glue/errors.go @@ -74,6 +74,12 @@ const ( // The same unique identifier was associated with two different records. ErrCodeIdempotentParameterMismatchException = "IdempotentParameterMismatchException" + // ErrCodeIllegalWorkflowStateException for service response error code + // "IllegalWorkflowStateException". + // + // The workflow is in an invalid state to perform a requested operation. + ErrCodeIllegalWorkflowStateException = "IllegalWorkflowStateException" + // ErrCodeInternalServiceException for service response error code // "InternalServiceException". // @@ -153,6 +159,7 @@ var exceptionFromCode = map[string]func(protocol.ResponseMetadata) error{ "GlueEncryptionException": newErrorEncryptionException, "EntityNotFoundException": newErrorEntityNotFoundException, "IdempotentParameterMismatchException": newErrorIdempotentParameterMismatchException, + "IllegalWorkflowStateException": newErrorIllegalWorkflowStateException, "InternalServiceException": newErrorInternalServiceException, "InvalidInputException": newErrorInvalidInputException, "MLTransformNotReadyException": newErrorMLTransformNotReadyException, diff --git a/vendor/github.com/aws/aws-sdk-go/service/qldb/api.go b/vendor/github.com/aws/aws-sdk-go/service/qldb/api.go index 8a4e4d98b1d..7f80514590a 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/qldb/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/qldb/api.go @@ -13,6 +13,96 @@ import ( "github.com/aws/aws-sdk-go/private/protocol/restjson" ) +const opCancelJournalKinesisStream = "CancelJournalKinesisStream" + +// CancelJournalKinesisStreamRequest generates a "aws/request.Request" representing the +// client's request for the CancelJournalKinesisStream operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CancelJournalKinesisStream for more information on using the CancelJournalKinesisStream +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CancelJournalKinesisStreamRequest method. +// req, resp := client.CancelJournalKinesisStreamRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/qldb-2019-01-02/CancelJournalKinesisStream +func (c *QLDB) CancelJournalKinesisStreamRequest(input *CancelJournalKinesisStreamInput) (req *request.Request, output *CancelJournalKinesisStreamOutput) { + op := &request.Operation{ + Name: opCancelJournalKinesisStream, + HTTPMethod: "DELETE", + HTTPPath: "/ledgers/{name}/journal-kinesis-streams/{streamId}", + } + + if input == nil { + input = &CancelJournalKinesisStreamInput{} + } + + output = &CancelJournalKinesisStreamOutput{} + req = c.newRequest(op, input, output) + return +} + +// CancelJournalKinesisStream API operation for Amazon QLDB. +// +// Ends a given Amazon QLDB journal stream. Before a stream can be canceled, +// its current status must be ACTIVE. +// +// You can't restart a stream after you cancel it. Canceled QLDB stream resources +// are subject to a 7-day retention period, so they are automatically deleted +// after this limit expires. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon QLDB's +// API operation CancelJournalKinesisStream for usage and error information. +// +// Returned Error Types: +// * InvalidParameterException +// One or more parameters in the request aren't valid. +// +// * ResourceNotFoundException +// The specified resource doesn't exist. +// +// * ResourcePreconditionNotMetException +// The operation failed because a condition wasn't satisfied in advance. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/qldb-2019-01-02/CancelJournalKinesisStream +func (c *QLDB) CancelJournalKinesisStream(input *CancelJournalKinesisStreamInput) (*CancelJournalKinesisStreamOutput, error) { + req, out := c.CancelJournalKinesisStreamRequest(input) + return out, req.Send() +} + +// CancelJournalKinesisStreamWithContext is the same as CancelJournalKinesisStream with the addition of +// the ability to pass a context and additional request options. +// +// See CancelJournalKinesisStream for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *QLDB) CancelJournalKinesisStreamWithContext(ctx aws.Context, input *CancelJournalKinesisStreamInput, opts ...request.Option) (*CancelJournalKinesisStreamOutput, error) { + req, out := c.CancelJournalKinesisStreamRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opCreateLedger = "CreateLedger" // CreateLedgerRequest generates a "aws/request.Request" representing the @@ -196,6 +286,93 @@ func (c *QLDB) DeleteLedgerWithContext(ctx aws.Context, input *DeleteLedgerInput return out, req.Send() } +const opDescribeJournalKinesisStream = "DescribeJournalKinesisStream" + +// DescribeJournalKinesisStreamRequest generates a "aws/request.Request" representing the +// client's request for the DescribeJournalKinesisStream operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DescribeJournalKinesisStream for more information on using the DescribeJournalKinesisStream +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DescribeJournalKinesisStreamRequest method. +// req, resp := client.DescribeJournalKinesisStreamRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/qldb-2019-01-02/DescribeJournalKinesisStream +func (c *QLDB) DescribeJournalKinesisStreamRequest(input *DescribeJournalKinesisStreamInput) (req *request.Request, output *DescribeJournalKinesisStreamOutput) { + op := &request.Operation{ + Name: opDescribeJournalKinesisStream, + HTTPMethod: "GET", + HTTPPath: "/ledgers/{name}/journal-kinesis-streams/{streamId}", + } + + if input == nil { + input = &DescribeJournalKinesisStreamInput{} + } + + output = &DescribeJournalKinesisStreamOutput{} + req = c.newRequest(op, input, output) + return +} + +// DescribeJournalKinesisStream API operation for Amazon QLDB. +// +// Returns detailed information about a given Amazon QLDB journal stream. The +// output includes the Amazon Resource Name (ARN), stream name, current status, +// creation time, and the parameters of your original stream creation request. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon QLDB's +// API operation DescribeJournalKinesisStream for usage and error information. +// +// Returned Error Types: +// * InvalidParameterException +// One or more parameters in the request aren't valid. +// +// * ResourceNotFoundException +// The specified resource doesn't exist. +// +// * ResourcePreconditionNotMetException +// The operation failed because a condition wasn't satisfied in advance. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/qldb-2019-01-02/DescribeJournalKinesisStream +func (c *QLDB) DescribeJournalKinesisStream(input *DescribeJournalKinesisStreamInput) (*DescribeJournalKinesisStreamOutput, error) { + req, out := c.DescribeJournalKinesisStreamRequest(input) + return out, req.Send() +} + +// DescribeJournalKinesisStreamWithContext is the same as DescribeJournalKinesisStream with the addition of +// the ability to pass a context and additional request options. +// +// See DescribeJournalKinesisStream for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *QLDB) DescribeJournalKinesisStreamWithContext(ctx aws.Context, input *DescribeJournalKinesisStreamInput, opts ...request.Option) (*DescribeJournalKinesisStreamOutput, error) { + req, out := c.DescribeJournalKinesisStreamRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opDescribeJournalS3Export = "DescribeJournalS3Export" // DescribeJournalS3ExportRequest generates a "aws/request.Request" representing the @@ -244,6 +421,10 @@ func (c *QLDB) DescribeJournalS3ExportRequest(input *DescribeJournalS3ExportInpu // export ID, when it was created, current status, and its start and end time // export parameters. // +// This action does not return any expired export jobs. For more information, +// see Export Job Expiration (https://docs.aws.amazon.com/qldb/latest/developerguide/export-journal.request.html#export-journal.request.expiration) +// in the Amazon QLDB Developer Guide. +// // If the export job with the given ExportId doesn't exist, then throws ResourceNotFoundException. // // If the ledger with the given Name doesn't exist, then throws ResourceNotFoundException. @@ -720,6 +901,155 @@ func (c *QLDB) GetRevisionWithContext(ctx aws.Context, input *GetRevisionInput, return out, req.Send() } +const opListJournalKinesisStreamsForLedger = "ListJournalKinesisStreamsForLedger" + +// ListJournalKinesisStreamsForLedgerRequest generates a "aws/request.Request" representing the +// client's request for the ListJournalKinesisStreamsForLedger operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListJournalKinesisStreamsForLedger for more information on using the ListJournalKinesisStreamsForLedger +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListJournalKinesisStreamsForLedgerRequest method. +// req, resp := client.ListJournalKinesisStreamsForLedgerRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/qldb-2019-01-02/ListJournalKinesisStreamsForLedger +func (c *QLDB) ListJournalKinesisStreamsForLedgerRequest(input *ListJournalKinesisStreamsForLedgerInput) (req *request.Request, output *ListJournalKinesisStreamsForLedgerOutput) { + op := &request.Operation{ + Name: opListJournalKinesisStreamsForLedger, + HTTPMethod: "GET", + HTTPPath: "/ledgers/{name}/journal-kinesis-streams", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "MaxResults", + TruncationToken: "", + }, + } + + if input == nil { + input = &ListJournalKinesisStreamsForLedgerInput{} + } + + output = &ListJournalKinesisStreamsForLedgerOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListJournalKinesisStreamsForLedger API operation for Amazon QLDB. +// +// Returns an array of all Amazon QLDB journal stream descriptors for a given +// ledger. The output of each stream descriptor includes the same details that +// are returned by DescribeJournalKinesisStream. +// +// This action returns a maximum of MaxResults items. It is paginated so that +// you can retrieve all the items by calling ListJournalKinesisStreamsForLedger +// multiple times. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon QLDB's +// API operation ListJournalKinesisStreamsForLedger for usage and error information. +// +// Returned Error Types: +// * InvalidParameterException +// One or more parameters in the request aren't valid. +// +// * ResourceNotFoundException +// The specified resource doesn't exist. +// +// * ResourcePreconditionNotMetException +// The operation failed because a condition wasn't satisfied in advance. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/qldb-2019-01-02/ListJournalKinesisStreamsForLedger +func (c *QLDB) ListJournalKinesisStreamsForLedger(input *ListJournalKinesisStreamsForLedgerInput) (*ListJournalKinesisStreamsForLedgerOutput, error) { + req, out := c.ListJournalKinesisStreamsForLedgerRequest(input) + return out, req.Send() +} + +// ListJournalKinesisStreamsForLedgerWithContext is the same as ListJournalKinesisStreamsForLedger with the addition of +// the ability to pass a context and additional request options. +// +// See ListJournalKinesisStreamsForLedger for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *QLDB) ListJournalKinesisStreamsForLedgerWithContext(ctx aws.Context, input *ListJournalKinesisStreamsForLedgerInput, opts ...request.Option) (*ListJournalKinesisStreamsForLedgerOutput, error) { + req, out := c.ListJournalKinesisStreamsForLedgerRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// ListJournalKinesisStreamsForLedgerPages iterates over the pages of a ListJournalKinesisStreamsForLedger operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListJournalKinesisStreamsForLedger method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListJournalKinesisStreamsForLedger operation. +// pageNum := 0 +// err := client.ListJournalKinesisStreamsForLedgerPages(params, +// func(page *qldb.ListJournalKinesisStreamsForLedgerOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *QLDB) ListJournalKinesisStreamsForLedgerPages(input *ListJournalKinesisStreamsForLedgerInput, fn func(*ListJournalKinesisStreamsForLedgerOutput, bool) bool) error { + return c.ListJournalKinesisStreamsForLedgerPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListJournalKinesisStreamsForLedgerPagesWithContext same as ListJournalKinesisStreamsForLedgerPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *QLDB) ListJournalKinesisStreamsForLedgerPagesWithContext(ctx aws.Context, input *ListJournalKinesisStreamsForLedgerInput, fn func(*ListJournalKinesisStreamsForLedgerOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListJournalKinesisStreamsForLedgerInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListJournalKinesisStreamsForLedgerRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + for p.Next() { + if !fn(p.Page().(*ListJournalKinesisStreamsForLedgerOutput), !p.HasNextPage()) { + break + } + } + + return p.Err() +} + const opListJournalS3Exports = "ListJournalS3Exports" // ListJournalS3ExportsRequest generates a "aws/request.Request" representing the @@ -776,6 +1106,10 @@ func (c *QLDB) ListJournalS3ExportsRequest(input *ListJournalS3ExportsInput) (re // This action returns a maximum of MaxResults items, and is paginated so that // you can retrieve all the items by calling ListJournalS3Exports multiple times. // +// This action does not return any expired export jobs. For more information, +// see Export Job Expiration (https://docs.aws.amazon.com/qldb/latest/developerguide/export-journal.request.html#export-journal.request.expiration) +// in the Amazon QLDB Developer Guide. +// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -912,6 +1246,10 @@ func (c *QLDB) ListJournalS3ExportsForLedgerRequest(input *ListJournalS3ExportsF // you can retrieve all the items by calling ListJournalS3ExportsForLedger multiple // times. // +// This action does not return any expired export jobs. For more information, +// see Export Job Expiration (https://docs.aws.amazon.com/qldb/latest/developerguide/export-journal.request.html#export-journal.request.expiration) +// in the Amazon QLDB Developer Guide. +// // Returns awserr.Error for service API and SDK errors. Use runtime type assertions // with awserr.Error's Code and Message methods to get detailed information about // the error. @@ -1210,6 +1548,94 @@ func (c *QLDB) ListTagsForResourceWithContext(ctx aws.Context, input *ListTagsFo return out, req.Send() } +const opStreamJournalToKinesis = "StreamJournalToKinesis" + +// StreamJournalToKinesisRequest generates a "aws/request.Request" representing the +// client's request for the StreamJournalToKinesis operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See StreamJournalToKinesis for more information on using the StreamJournalToKinesis +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the StreamJournalToKinesisRequest method. +// req, resp := client.StreamJournalToKinesisRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/qldb-2019-01-02/StreamJournalToKinesis +func (c *QLDB) StreamJournalToKinesisRequest(input *StreamJournalToKinesisInput) (req *request.Request, output *StreamJournalToKinesisOutput) { + op := &request.Operation{ + Name: opStreamJournalToKinesis, + HTTPMethod: "POST", + HTTPPath: "/ledgers/{name}/journal-kinesis-streams", + } + + if input == nil { + input = &StreamJournalToKinesisInput{} + } + + output = &StreamJournalToKinesisOutput{} + req = c.newRequest(op, input, output) + return +} + +// StreamJournalToKinesis API operation for Amazon QLDB. +// +// Creates a stream for a given Amazon QLDB ledger that delivers the journal +// data to a specified Amazon Kinesis Data Streams resource. The stream captures +// every document revision that is committed to your journal and sends it to +// the Kinesis data stream. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon QLDB's +// API operation StreamJournalToKinesis for usage and error information. +// +// Returned Error Types: +// * InvalidParameterException +// One or more parameters in the request aren't valid. +// +// * ResourceNotFoundException +// The specified resource doesn't exist. +// +// * ResourcePreconditionNotMetException +// The operation failed because a condition wasn't satisfied in advance. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/qldb-2019-01-02/StreamJournalToKinesis +func (c *QLDB) StreamJournalToKinesis(input *StreamJournalToKinesisInput) (*StreamJournalToKinesisOutput, error) { + req, out := c.StreamJournalToKinesisRequest(input) + return out, req.Send() +} + +// StreamJournalToKinesisWithContext is the same as StreamJournalToKinesis with the addition of +// the ability to pass a context and additional request options. +// +// See StreamJournalToKinesis for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *QLDB) StreamJournalToKinesisWithContext(ctx aws.Context, input *StreamJournalToKinesisInput, opts ...request.Option) (*StreamJournalToKinesisOutput, error) { + req, out := c.StreamJournalToKinesisRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + const opTagResource = "TagResource" // TagResourceRequest generates a "aws/request.Request" representing the @@ -1462,6 +1888,87 @@ func (c *QLDB) UpdateLedgerWithContext(ctx aws.Context, input *UpdateLedgerInput return out, req.Send() } +type CancelJournalKinesisStreamInput struct { + _ struct{} `type:"structure"` + + // The name of the ledger. + // + // LedgerName is a required field + LedgerName *string `location:"uri" locationName:"name" min:"1" type:"string" required:"true"` + + // The unique ID that QLDB assigns to each QLDB journal stream. + // + // StreamId is a required field + StreamId *string `location:"uri" locationName:"streamId" min:"22" type:"string" required:"true"` +} + +// String returns the string representation +func (s CancelJournalKinesisStreamInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelJournalKinesisStreamInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CancelJournalKinesisStreamInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CancelJournalKinesisStreamInput"} + if s.LedgerName == nil { + invalidParams.Add(request.NewErrParamRequired("LedgerName")) + } + if s.LedgerName != nil && len(*s.LedgerName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("LedgerName", 1)) + } + if s.StreamId == nil { + invalidParams.Add(request.NewErrParamRequired("StreamId")) + } + if s.StreamId != nil && len(*s.StreamId) < 22 { + invalidParams.Add(request.NewErrParamMinLen("StreamId", 22)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetLedgerName sets the LedgerName field's value. +func (s *CancelJournalKinesisStreamInput) SetLedgerName(v string) *CancelJournalKinesisStreamInput { + s.LedgerName = &v + return s +} + +// SetStreamId sets the StreamId field's value. +func (s *CancelJournalKinesisStreamInput) SetStreamId(v string) *CancelJournalKinesisStreamInput { + s.StreamId = &v + return s +} + +type CancelJournalKinesisStreamOutput struct { + _ struct{} `type:"structure"` + + // The unique ID that QLDB assigns to each QLDB journal stream. + StreamId *string `min:"22" type:"string"` +} + +// String returns the string representation +func (s CancelJournalKinesisStreamOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CancelJournalKinesisStreamOutput) GoString() string { + return s.String() +} + +// SetStreamId sets the StreamId field's value. +func (s *CancelJournalKinesisStreamOutput) SetStreamId(v string) *CancelJournalKinesisStreamOutput { + s.StreamId = &v + return s +} + type CreateLedgerInput struct { _ struct{} `type:"structure"` @@ -1667,6 +2174,88 @@ func (s DeleteLedgerOutput) GoString() string { return s.String() } +type DescribeJournalKinesisStreamInput struct { + _ struct{} `type:"structure"` + + // The name of the ledger. + // + // LedgerName is a required field + LedgerName *string `location:"uri" locationName:"name" min:"1" type:"string" required:"true"` + + // The unique ID that QLDB assigns to each QLDB journal stream. + // + // StreamId is a required field + StreamId *string `location:"uri" locationName:"streamId" min:"22" type:"string" required:"true"` +} + +// String returns the string representation +func (s DescribeJournalKinesisStreamInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeJournalKinesisStreamInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DescribeJournalKinesisStreamInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DescribeJournalKinesisStreamInput"} + if s.LedgerName == nil { + invalidParams.Add(request.NewErrParamRequired("LedgerName")) + } + if s.LedgerName != nil && len(*s.LedgerName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("LedgerName", 1)) + } + if s.StreamId == nil { + invalidParams.Add(request.NewErrParamRequired("StreamId")) + } + if s.StreamId != nil && len(*s.StreamId) < 22 { + invalidParams.Add(request.NewErrParamMinLen("StreamId", 22)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetLedgerName sets the LedgerName field's value. +func (s *DescribeJournalKinesisStreamInput) SetLedgerName(v string) *DescribeJournalKinesisStreamInput { + s.LedgerName = &v + return s +} + +// SetStreamId sets the StreamId field's value. +func (s *DescribeJournalKinesisStreamInput) SetStreamId(v string) *DescribeJournalKinesisStreamInput { + s.StreamId = &v + return s +} + +type DescribeJournalKinesisStreamOutput struct { + _ struct{} `type:"structure"` + + // Information about the QLDB journal stream returned by a DescribeJournalS3Export + // request. + Stream *JournalKinesisStreamDescription `type:"structure"` +} + +// String returns the string representation +func (s DescribeJournalKinesisStreamOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DescribeJournalKinesisStreamOutput) GoString() string { + return s.String() +} + +// SetStream sets the Stream field's value. +func (s *DescribeJournalKinesisStreamOutput) SetStream(v *JournalKinesisStreamDescription) *DescribeJournalKinesisStreamOutput { + s.Stream = v + return s +} + type DescribeJournalS3ExportInput struct { _ struct{} `type:"structure"` @@ -2378,31 +2967,166 @@ func (s *InvalidParameterException) Code() string { return "InvalidParameterException" } -// Message returns the exception's message. -func (s *InvalidParameterException) Message() string { - if s.Message_ != nil { - return *s.Message_ - } - return "" +// Message returns the exception's message. +func (s *InvalidParameterException) Message() string { + if s.Message_ != nil { + return *s.Message_ + } + return "" +} + +// OrigErr always returns nil, satisfies awserr.Error interface. +func (s *InvalidParameterException) OrigErr() error { + return nil +} + +func (s *InvalidParameterException) Error() string { + return fmt.Sprintf("%s: %s\n%s", s.Code(), s.Message(), s.String()) +} + +// Status code returns the HTTP status code for the request's response error. +func (s *InvalidParameterException) StatusCode() int { + return s.RespMetadata.StatusCode +} + +// RequestID returns the service's response RequestID for request. +func (s *InvalidParameterException) RequestID() string { + return s.RespMetadata.RequestID +} + +// The information about an Amazon QLDB journal stream, including the Amazon +// Resource Name (ARN), stream name, creation time, current status, and the +// parameters of your original stream creation request. +type JournalKinesisStreamDescription struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the QLDB journal stream. + Arn *string `min:"20" type:"string"` + + // The date and time, in epoch time format, when the QLDB journal stream was + // created. (Epoch time format is the number of seconds elapsed since 12:00:00 + // AM January 1, 1970 UTC.) + CreationTime *time.Time `type:"timestamp"` + + // The error message that describes the reason that a stream has a status of + // IMPAIRED or FAILED. This is not applicable to streams that have other status + // values. + ErrorCause *string `type:"string" enum:"ErrorCause"` + + // The exclusive date and time that specifies when the stream ends. If this + // parameter is blank, the stream runs indefinitely until you cancel it. + ExclusiveEndTime *time.Time `type:"timestamp"` + + // The inclusive start date and time from which to start streaming journal data. + InclusiveStartTime *time.Time `type:"timestamp"` + + // The configuration settings of the Amazon Kinesis Data Streams destination + // for your QLDB journal stream. + // + // KinesisConfiguration is a required field + KinesisConfiguration *KinesisConfiguration `type:"structure" required:"true"` + + // The name of the ledger. + // + // LedgerName is a required field + LedgerName *string `min:"1" type:"string" required:"true"` + + // The Amazon Resource Name (ARN) of the IAM role that grants QLDB permissions + // for a journal stream to write data records to a Kinesis Data Streams resource. + // + // RoleArn is a required field + RoleArn *string `min:"20" type:"string" required:"true"` + + // The current state of the QLDB journal stream. + // + // Status is a required field + Status *string `type:"string" required:"true" enum:"StreamStatus"` + + // The unique ID that QLDB assigns to each QLDB journal stream. + // + // StreamId is a required field + StreamId *string `min:"22" type:"string" required:"true"` + + // The user-defined name of the QLDB journal stream. + // + // StreamName is a required field + StreamName *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s JournalKinesisStreamDescription) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s JournalKinesisStreamDescription) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *JournalKinesisStreamDescription) SetArn(v string) *JournalKinesisStreamDescription { + s.Arn = &v + return s +} + +// SetCreationTime sets the CreationTime field's value. +func (s *JournalKinesisStreamDescription) SetCreationTime(v time.Time) *JournalKinesisStreamDescription { + s.CreationTime = &v + return s +} + +// SetErrorCause sets the ErrorCause field's value. +func (s *JournalKinesisStreamDescription) SetErrorCause(v string) *JournalKinesisStreamDescription { + s.ErrorCause = &v + return s +} + +// SetExclusiveEndTime sets the ExclusiveEndTime field's value. +func (s *JournalKinesisStreamDescription) SetExclusiveEndTime(v time.Time) *JournalKinesisStreamDescription { + s.ExclusiveEndTime = &v + return s +} + +// SetInclusiveStartTime sets the InclusiveStartTime field's value. +func (s *JournalKinesisStreamDescription) SetInclusiveStartTime(v time.Time) *JournalKinesisStreamDescription { + s.InclusiveStartTime = &v + return s +} + +// SetKinesisConfiguration sets the KinesisConfiguration field's value. +func (s *JournalKinesisStreamDescription) SetKinesisConfiguration(v *KinesisConfiguration) *JournalKinesisStreamDescription { + s.KinesisConfiguration = v + return s +} + +// SetLedgerName sets the LedgerName field's value. +func (s *JournalKinesisStreamDescription) SetLedgerName(v string) *JournalKinesisStreamDescription { + s.LedgerName = &v + return s } -// OrigErr always returns nil, satisfies awserr.Error interface. -func (s *InvalidParameterException) OrigErr() error { - return nil +// SetRoleArn sets the RoleArn field's value. +func (s *JournalKinesisStreamDescription) SetRoleArn(v string) *JournalKinesisStreamDescription { + s.RoleArn = &v + return s } -func (s *InvalidParameterException) Error() string { - return fmt.Sprintf("%s: %s\n%s", s.Code(), s.Message(), s.String()) +// SetStatus sets the Status field's value. +func (s *JournalKinesisStreamDescription) SetStatus(v string) *JournalKinesisStreamDescription { + s.Status = &v + return s } -// Status code returns the HTTP status code for the request's response error. -func (s *InvalidParameterException) StatusCode() int { - return s.RespMetadata.StatusCode +// SetStreamId sets the StreamId field's value. +func (s *JournalKinesisStreamDescription) SetStreamId(v string) *JournalKinesisStreamDescription { + s.StreamId = &v + return s } -// RequestID returns the service's response RequestID for request. -func (s *InvalidParameterException) RequestID() string { - return s.RespMetadata.RequestID +// SetStreamName sets the StreamName field's value. +func (s *JournalKinesisStreamDescription) SetStreamName(v string) *JournalKinesisStreamDescription { + s.StreamName = &v + return s } // The information about a journal export job, including the ledger name, export @@ -2521,6 +3245,60 @@ func (s *JournalS3ExportDescription) SetStatus(v string) *JournalS3ExportDescrip return s } +// The configuration settings of the Amazon Kinesis Data Streams destination +// for your Amazon QLDB journal stream. +type KinesisConfiguration struct { + _ struct{} `type:"structure"` + + // Enables QLDB to publish multiple stream records in a single Kinesis Data + // Streams record. To learn more, see KPL Key Concepts (https://docs.aws.amazon.com/streams/latest/dev/kinesis-kpl-concepts.html) + // in the Amazon Kinesis Data Streams Developer Guide. + AggregationEnabled *bool `type:"boolean"` + + // The Amazon Resource Name (ARN) of the Kinesis data stream resource. + // + // StreamArn is a required field + StreamArn *string `min:"20" type:"string" required:"true"` +} + +// String returns the string representation +func (s KinesisConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s KinesisConfiguration) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *KinesisConfiguration) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "KinesisConfiguration"} + if s.StreamArn == nil { + invalidParams.Add(request.NewErrParamRequired("StreamArn")) + } + if s.StreamArn != nil && len(*s.StreamArn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("StreamArn", 20)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAggregationEnabled sets the AggregationEnabled field's value. +func (s *KinesisConfiguration) SetAggregationEnabled(v bool) *KinesisConfiguration { + s.AggregationEnabled = &v + return s +} + +// SetStreamArn sets the StreamArn field's value. +func (s *KinesisConfiguration) SetStreamArn(v string) *KinesisConfiguration { + s.StreamArn = &v + return s +} + // Information about a ledger, including its name, state, and when it was created. type LedgerSummary struct { _ struct{} `type:"structure"` @@ -2624,6 +3402,113 @@ func (s *LimitExceededException) RequestID() string { return s.RespMetadata.RequestID } +type ListJournalKinesisStreamsForLedgerInput struct { + _ struct{} `type:"structure"` + + // The name of the ledger. + // + // LedgerName is a required field + LedgerName *string `location:"uri" locationName:"name" min:"1" type:"string" required:"true"` + + // The maximum number of results to return in a single ListJournalKinesisStreamsForLedger + // request. (The actual number of results returned might be fewer.) + MaxResults *int64 `location:"querystring" locationName:"max_results" min:"1" type:"integer"` + + // A pagination token, indicating that you want to retrieve the next page of + // results. If you received a value for NextToken in the response from a previous + // ListJournalKinesisStreamsForLedger call, you should use that value as input + // here. + NextToken *string `location:"querystring" locationName:"next_token" min:"4" type:"string"` +} + +// String returns the string representation +func (s ListJournalKinesisStreamsForLedgerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListJournalKinesisStreamsForLedgerInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListJournalKinesisStreamsForLedgerInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListJournalKinesisStreamsForLedgerInput"} + if s.LedgerName == nil { + invalidParams.Add(request.NewErrParamRequired("LedgerName")) + } + if s.LedgerName != nil && len(*s.LedgerName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("LedgerName", 1)) + } + if s.MaxResults != nil && *s.MaxResults < 1 { + invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1)) + } + if s.NextToken != nil && len(*s.NextToken) < 4 { + invalidParams.Add(request.NewErrParamMinLen("NextToken", 4)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetLedgerName sets the LedgerName field's value. +func (s *ListJournalKinesisStreamsForLedgerInput) SetLedgerName(v string) *ListJournalKinesisStreamsForLedgerInput { + s.LedgerName = &v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *ListJournalKinesisStreamsForLedgerInput) SetMaxResults(v int64) *ListJournalKinesisStreamsForLedgerInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *ListJournalKinesisStreamsForLedgerInput) SetNextToken(v string) *ListJournalKinesisStreamsForLedgerInput { + s.NextToken = &v + return s +} + +type ListJournalKinesisStreamsForLedgerOutput struct { + _ struct{} `type:"structure"` + + // * If NextToken is empty, the last page of results has been processed and + // there are no more results to be retrieved. + // + // * If NextToken is not empty, more results are available. To retrieve the + // next page of results, use the value of NextToken in a subsequent ListJournalKinesisStreamsForLedger + // call. + NextToken *string `min:"4" type:"string"` + + // The array of QLDB journal stream descriptors that are associated with the + // given ledger. + Streams []*JournalKinesisStreamDescription `type:"list"` +} + +// String returns the string representation +func (s ListJournalKinesisStreamsForLedgerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListJournalKinesisStreamsForLedgerOutput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *ListJournalKinesisStreamsForLedgerOutput) SetNextToken(v string) *ListJournalKinesisStreamsForLedgerOutput { + s.NextToken = &v + return s +} + +// SetStreams sets the Streams field's value. +func (s *ListJournalKinesisStreamsForLedgerOutput) SetStreams(v []*JournalKinesisStreamDescription) *ListJournalKinesisStreamsForLedgerOutput { + s.Streams = v + return s +} + type ListJournalS3ExportsForLedgerInput struct { _ struct{} `type:"structure"` @@ -3230,8 +4115,9 @@ func (s *ResourcePreconditionNotMetException) RequestID() string { type S3EncryptionConfiguration struct { _ struct{} `type:"structure"` - // The Amazon Resource Name (ARN) for a customer master key (CMK) in AWS Key - // Management Service (AWS KMS). + // The Amazon Resource Name (ARN) for a symmetric customer master key (CMK) + // in AWS Key Management Service (AWS KMS). Amazon QLDB does not support asymmetric + // CMKs. // // You must provide a KmsKeyArn if you specify SSE_KMS as the ObjectEncryptionType. // @@ -3381,6 +4267,177 @@ func (s *S3ExportConfiguration) SetPrefix(v string) *S3ExportConfiguration { return s } +type StreamJournalToKinesisInput struct { + _ struct{} `type:"structure"` + + // The exclusive date and time that specifies when the stream ends. If you keep + // this parameter blank, the stream runs indefinitely until you cancel it. + // + // The ExclusiveEndTime must be in ISO 8601 date and time format and in Universal + // Coordinated Time (UTC). For example: 2019-06-13T21:36:34Z + ExclusiveEndTime *time.Time `type:"timestamp"` + + // The inclusive start date and time from which to start streaming journal data. + // This parameter must be in ISO 8601 date and time format and in Universal + // Coordinated Time (UTC). For example: 2019-06-13T21:36:34Z + // + // The InclusiveStartTime cannot be in the future and must be before ExclusiveEndTime. + // + // If you provide an InclusiveStartTime that is before the ledger's CreationDateTime, + // QLDB effectively defaults it to the ledger's CreationDateTime. + // + // InclusiveStartTime is a required field + InclusiveStartTime *time.Time `type:"timestamp" required:"true"` + + // The configuration settings of the Kinesis Data Streams destination for your + // stream request. + // + // KinesisConfiguration is a required field + KinesisConfiguration *KinesisConfiguration `type:"structure" required:"true"` + + // The name of the ledger. + // + // LedgerName is a required field + LedgerName *string `location:"uri" locationName:"name" min:"1" type:"string" required:"true"` + + // The Amazon Resource Name (ARN) of the IAM role that grants QLDB permissions + // for a journal stream to write data records to a Kinesis Data Streams resource. + // + // RoleArn is a required field + RoleArn *string `min:"20" type:"string" required:"true"` + + // The name that you want to assign to the QLDB journal stream. User-defined + // names can help identify and indicate the purpose of a stream. + // + // Your stream name must be unique among other active streams for a given ledger. + // If you try to create a stream with the same name and configuration of an + // active, existing stream for the same ledger, QLDB simply returns the existing + // stream. Stream names have the same naming constraints as ledger names, as + // defined in Quotas in Amazon QLDB (https://docs.aws.amazon.com/qldb/latest/developerguide/limits.html#limits.naming) + // in the Amazon QLDB Developer Guide. + // + // StreamName is a required field + StreamName *string `min:"1" type:"string" required:"true"` + + // The key-value pairs to add as tags to the stream that you want to create. + // Tag keys are case sensitive. Tag values are case sensitive and can be null. + Tags map[string]*string `type:"map"` +} + +// String returns the string representation +func (s StreamJournalToKinesisInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StreamJournalToKinesisInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *StreamJournalToKinesisInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "StreamJournalToKinesisInput"} + if s.InclusiveStartTime == nil { + invalidParams.Add(request.NewErrParamRequired("InclusiveStartTime")) + } + if s.KinesisConfiguration == nil { + invalidParams.Add(request.NewErrParamRequired("KinesisConfiguration")) + } + if s.LedgerName == nil { + invalidParams.Add(request.NewErrParamRequired("LedgerName")) + } + if s.LedgerName != nil && len(*s.LedgerName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("LedgerName", 1)) + } + if s.RoleArn == nil { + invalidParams.Add(request.NewErrParamRequired("RoleArn")) + } + if s.RoleArn != nil && len(*s.RoleArn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20)) + } + if s.StreamName == nil { + invalidParams.Add(request.NewErrParamRequired("StreamName")) + } + if s.StreamName != nil && len(*s.StreamName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("StreamName", 1)) + } + if s.KinesisConfiguration != nil { + if err := s.KinesisConfiguration.Validate(); err != nil { + invalidParams.AddNested("KinesisConfiguration", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetExclusiveEndTime sets the ExclusiveEndTime field's value. +func (s *StreamJournalToKinesisInput) SetExclusiveEndTime(v time.Time) *StreamJournalToKinesisInput { + s.ExclusiveEndTime = &v + return s +} + +// SetInclusiveStartTime sets the InclusiveStartTime field's value. +func (s *StreamJournalToKinesisInput) SetInclusiveStartTime(v time.Time) *StreamJournalToKinesisInput { + s.InclusiveStartTime = &v + return s +} + +// SetKinesisConfiguration sets the KinesisConfiguration field's value. +func (s *StreamJournalToKinesisInput) SetKinesisConfiguration(v *KinesisConfiguration) *StreamJournalToKinesisInput { + s.KinesisConfiguration = v + return s +} + +// SetLedgerName sets the LedgerName field's value. +func (s *StreamJournalToKinesisInput) SetLedgerName(v string) *StreamJournalToKinesisInput { + s.LedgerName = &v + return s +} + +// SetRoleArn sets the RoleArn field's value. +func (s *StreamJournalToKinesisInput) SetRoleArn(v string) *StreamJournalToKinesisInput { + s.RoleArn = &v + return s +} + +// SetStreamName sets the StreamName field's value. +func (s *StreamJournalToKinesisInput) SetStreamName(v string) *StreamJournalToKinesisInput { + s.StreamName = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *StreamJournalToKinesisInput) SetTags(v map[string]*string) *StreamJournalToKinesisInput { + s.Tags = v + return s +} + +type StreamJournalToKinesisOutput struct { + _ struct{} `type:"structure"` + + // The unique ID that QLDB assigns to each QLDB journal stream. + StreamId *string `min:"22" type:"string"` +} + +// String returns the string representation +func (s StreamJournalToKinesisOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StreamJournalToKinesisOutput) GoString() string { + return s.String() +} + +// SetStreamId sets the StreamId field's value. +func (s *StreamJournalToKinesisOutput) SetStreamId(v string) *StreamJournalToKinesisOutput { + s.StreamId = &v + return s +} + type TagResourceInput struct { _ struct{} `type:"structure"` @@ -3689,6 +4746,14 @@ func (s *ValueHolder) SetIonText(v string) *ValueHolder { return s } +const ( + // ErrorCauseKinesisStreamNotFound is a ErrorCause enum value + ErrorCauseKinesisStreamNotFound = "KINESIS_STREAM_NOT_FOUND" + + // ErrorCauseIamPermissionRevoked is a ErrorCause enum value + ErrorCauseIamPermissionRevoked = "IAM_PERMISSION_REVOKED" +) + const ( // ExportStatusInProgress is a ExportStatus enum value ExportStatusInProgress = "IN_PROGRESS" @@ -3729,3 +4794,20 @@ const ( // S3ObjectEncryptionTypeNoEncryption is a S3ObjectEncryptionType enum value S3ObjectEncryptionTypeNoEncryption = "NO_ENCRYPTION" ) + +const ( + // StreamStatusActive is a StreamStatus enum value + StreamStatusActive = "ACTIVE" + + // StreamStatusCompleted is a StreamStatus enum value + StreamStatusCompleted = "COMPLETED" + + // StreamStatusCanceled is a StreamStatus enum value + StreamStatusCanceled = "CANCELED" + + // StreamStatusFailed is a StreamStatus enum value + StreamStatusFailed = "FAILED" + + // StreamStatusImpaired is a StreamStatus enum value + StreamStatusImpaired = "IMPAIRED" +) diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go index 7f60d4aa185..550b5f687f9 100644 --- a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go @@ -1788,7 +1788,7 @@ type AssumeRoleWithSAMLInput struct { // in the IAM User Guide. // // SAMLAssertion is a required field - SAMLAssertion *string `min:"4" type:"string" required:"true"` + SAMLAssertion *string `min:"4" type:"string" required:"true" sensitive:"true"` } // String returns the string representation @@ -2100,7 +2100,7 @@ type AssumeRoleWithWebIdentityInput struct { // the application makes an AssumeRoleWithWebIdentity call. // // WebIdentityToken is a required field - WebIdentityToken *string `min:"4" type:"string" required:"true"` + WebIdentityToken *string `min:"4" type:"string" required:"true" sensitive:"true"` } // String returns the string representation diff --git a/vendor/modules.txt b/vendor/modules.txt index 68fe7d51316..7d6434710d2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -25,7 +25,7 @@ github.com/apparentlymart/go-cidr/cidr github.com/apparentlymart/go-textseg/textseg # github.com/armon/go-radix v1.0.0 github.com/armon/go-radix -# github.com/aws/aws-sdk-go v1.30.28 +# github.com/aws/aws-sdk-go v1.31.0 github.com/aws/aws-sdk-go/aws github.com/aws/aws-sdk-go/aws/arn github.com/aws/aws-sdk-go/aws/awserr From 8fd7e168b2cf0c1e823401dc3d1b4c763cf0513d Mon Sep 17 00:00:00 2001 From: Pascal van Buijtene Date: Tue, 7 Apr 2020 22:39:11 +0200 Subject: [PATCH 195/475] Add aws_wafv2_ip_set data source --- aws/data_source_aws_wafv2_ip_set.go | 77 ++++++++++++++++++++++++ aws/data_source_aws_wafv2_ip_set_test.go | 67 +++++++++++++++++++++ aws/provider.go | 1 + 3 files changed, 145 insertions(+) create mode 100644 aws/data_source_aws_wafv2_ip_set.go create mode 100644 aws/data_source_aws_wafv2_ip_set_test.go diff --git a/aws/data_source_aws_wafv2_ip_set.go b/aws/data_source_aws_wafv2_ip_set.go new file mode 100644 index 00000000000..5c9721a751e --- /dev/null +++ b/aws/data_source_aws_wafv2_ip_set.go @@ -0,0 +1,77 @@ +package aws + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/wafv2" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" +) + +func dataSourceAwsWafv2IPSet() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsWafv2IPSetRead, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "scope": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + wafv2.ScopeCloudfront, + wafv2.ScopeRegional, + }, false), + }, + }, + } +} + +func dataSourceAwsWafv2IPSetRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).wafv2conn + name := d.Get("name").(string) + + var foundIpSet *wafv2.IPSetSummary + input := &wafv2.ListIPSetsInput{ + Scope: aws.String(d.Get("scope").(string)), + } + for { + output, err := conn.ListIPSets(input) + if err != nil { + return fmt.Errorf("Error reading WAFV2 IPSets: %s", err) + } + + for _, ipSet := range output.IPSets { + if aws.StringValue(ipSet.Name) == name { + foundIpSet = ipSet + break + } + } + + if output.NextMarker == nil || foundIpSet != nil { + break + } + input.NextMarker = output.NextMarker + } + + if foundIpSet == nil { + return fmt.Errorf("WAFV2 IPSet not found for name: %s", name) + } + + d.SetId(aws.StringValue(foundIpSet.Id)) + d.Set("arn", aws.StringValue(foundIpSet.ARN)) + d.Set("description", aws.StringValue(foundIpSet.Description)) + + return nil +} diff --git a/aws/data_source_aws_wafv2_ip_set_test.go b/aws/data_source_aws_wafv2_ip_set_test.go new file mode 100644 index 00000000000..1e794c4656a --- /dev/null +++ b/aws/data_source_aws_wafv2_ip_set_test.go @@ -0,0 +1,67 @@ +package aws + +import ( + "fmt" + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccDataSourceAwsWafv2IPSet_Basic(t *testing.T) { + name := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_wafv2_ip_set.test" + datasourceName := "data.aws_wafv2_ip_set.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsWafv2IPSet_NonExistent(name), + ExpectError: regexp.MustCompile(`WAFV2 IPSet not found`), + }, + { + Config: testAccDataSourceAwsWafv2IPSet_Name(name), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair(datasourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(datasourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(datasourceName, "id", resourceName, "id"), + resource.TestCheckResourceAttrPair(datasourceName, "name", resourceName, "name"), + resource.TestCheckResourceAttrPair(datasourceName, "scope", resourceName, "scope"), + ), + }, + }, + }) +} + +func testAccDataSourceAwsWafv2IPSet_Name(name string) string { + return fmt.Sprintf(` +resource "aws_wafv2_ip_set" "test" { + name = "%s" + scope = "REGIONAL" + ip_address_version = "IPV4" +} + +data "aws_wafv2_ip_set" "test" { + name = aws_wafv2_ip_set.test.name + scope = "REGIONAL" +} +`, name) +} + +func testAccDataSourceAwsWafv2IPSet_NonExistent(name string) string { + return fmt.Sprintf(` +resource "aws_wafv2_ip_set" "test" { + name = "%s" + scope = "REGIONAL" + ip_address_version = "IPV4" +} + +data "aws_wafv2_ip_set" "test" { + name = "tf-acc-test-does-not-exist" + scope = "REGIONAL" +} +`, name) +} diff --git a/aws/provider.go b/aws/provider.go index e407448316c..1ba0ed481c8 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -333,6 +333,7 @@ func Provider() terraform.ResourceProvider { "aws_wafregional_rule": dataSourceAwsWafRegionalRule(), "aws_wafregional_rate_based_rule": dataSourceAwsWafRegionalRateBasedRule(), "aws_wafregional_web_acl": dataSourceAwsWafRegionalWebAcl(), + "aws_wafv2_ip_set": dataSourceAwsWafv2IPSet(), "aws_workspaces_bundle": dataSourceAwsWorkspaceBundle(), // Adding the Aliases for the ALB -> LB Rename From b71796e4acb1416c90def2167a27b507d3e47365 Mon Sep 17 00:00:00 2001 From: Pascal van Buijtene Date: Thu, 9 Apr 2020 21:39:19 +0200 Subject: [PATCH 196/475] Add documentation --- website/aws.erb | 13 +++++++++ website/docs/d/wafv2_ip_set.html.markdown | 35 +++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 website/docs/d/wafv2_ip_set.html.markdown diff --git a/website/aws.erb b/website/aws.erb index 6d77c4a5d6d..afdc2788414 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -3561,6 +3561,19 @@ +
  • + WAFv2 + +
  • WorkLink