Skip to content

Commit

Permalink
Merge pull request #28309 from taharah/backup-reports
Browse files Browse the repository at this point in the history
r/aws_backup_report_plan: add additional properties
  • Loading branch information
ewbankkit authored Apr 25, 2023
2 parents 9771af1 + 1e97cf4 commit 9fe696f
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 16 deletions.
7 changes: 7 additions & 0 deletions .changelog/28309.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/aws_backup_report_plan: Add `accounts`, `organization_units` and `regions` attributes to the `report_setting` block
```

```release-note:enhancement
data-source/aws_backup_report_plan: Add `accounts`, `organization_units` and `regions` attributes to the `report_setting` block
```
45 changes: 45 additions & 0 deletions internal/service/backup/report_plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ func ResourceReportPlan() *schema.Resource {
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"accounts": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"framework_arns": {
Type: schema.TypeSet,
Optional: true,
Expand All @@ -101,6 +108,20 @@ func ResourceReportPlan() *schema.Resource {
Type: schema.TypeInt,
Optional: true,
},
"organization_units": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"regions": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
// A report plan template cannot be updated
"report_template": {
Type: schema.TypeString,
Expand Down Expand Up @@ -272,6 +293,10 @@ func expandReportSetting(reportSetting []interface{}) *backup.ReportSetting {
ReportTemplate: aws.String(tfMap["report_template"].(string)),
}

if v, ok := tfMap["accounts"]; ok && v.(*schema.Set).Len() > 0 {
result.Accounts = flex.ExpandStringSet(v.(*schema.Set))
}

if v, ok := tfMap["framework_arns"]; ok && v.(*schema.Set).Len() > 0 {
result.FrameworkArns = flex.ExpandStringSet(v.(*schema.Set))
}
Expand All @@ -280,6 +305,14 @@ func expandReportSetting(reportSetting []interface{}) *backup.ReportSetting {
result.NumberOfFrameworks = aws.Int64(int64(v))
}

if v, ok := tfMap["organization_units"]; ok && v.(*schema.Set).Len() > 0 {
result.OrganizationUnits = flex.ExpandStringSet(v.(*schema.Set))
}

if v, ok := tfMap["regions"]; ok && v.(*schema.Set).Len() > 0 {
result.Regions = flex.ExpandStringSet(v.(*schema.Set))
}

return result
}

Expand Down Expand Up @@ -312,6 +345,10 @@ func flattenReportSetting(reportSetting *backup.ReportSetting) []interface{} {
"report_template": aws.StringValue(reportSetting.ReportTemplate),
}

if reportSetting.Accounts != nil && len(reportSetting.Accounts) > 0 {
values["accounts"] = flex.FlattenStringSet(reportSetting.Accounts)
}

if reportSetting.FrameworkArns != nil && len(reportSetting.FrameworkArns) > 0 {
values["framework_arns"] = flex.FlattenStringSet(reportSetting.FrameworkArns)
}
Expand All @@ -320,6 +357,14 @@ func flattenReportSetting(reportSetting *backup.ReportSetting) []interface{} {
values["number_of_frameworks"] = aws.Int64Value(reportSetting.NumberOfFrameworks)
}

if reportSetting.OrganizationUnits != nil && len(reportSetting.OrganizationUnits) > 0 {
values["organization_units"] = flex.FlattenStringSet(reportSetting.OrganizationUnits)
}

if reportSetting.Regions != nil && len(reportSetting.Regions) > 0 {
values["regions"] = flex.FlattenStringSet(reportSetting.Regions)
}

return []interface{}{values}
}

Expand Down
21 changes: 21 additions & 0 deletions internal/service/backup/report_plan_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ func DataSourceReportPlan() *schema.Resource {
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"accounts": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"framework_arns": {
Type: schema.TypeSet,
Computed: true,
Expand All @@ -77,6 +84,20 @@ func DataSourceReportPlan() *schema.Resource {
Type: schema.TypeInt,
Computed: true,
},
"organization_units": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"regions": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"report_template": {
Type: schema.TypeString,
Computed: true,
Expand Down
68 changes: 52 additions & 16 deletions internal/service/backup/report_plan_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestAccBackupReportPlanDataSource_basic(t *testing.T) {
Steps: []resource.TestStep{
{
Config: testAccReportPlanDataSourceConfig_nonExistent,
ExpectError: regexp.MustCompile(`error reading Backup Report Plan`),
ExpectError: regexp.MustCompile(`reading Backup Report Plan`),
},
{
Config: testAccReportPlanDataSourceConfig_basic(rName, rName2),
Expand All @@ -49,28 +49,54 @@ func TestAccBackupReportPlanDataSource_basic(t *testing.T) {
})
}

func TestAccBackupReportPlanDataSource_reportSettings(t *testing.T) {
ctx := acctest.Context(t)
datasourceName := "data.aws_backup_report_plan.test"
resourceName := "aws_backup_report_plan.test"
rName := sdkacctest.RandomWithPrefix("tf-test-bucket")
rName2 := fmt.Sprintf("tf_acc_test_%s", sdkacctest.RandString(7))

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); testAccReportPlanPreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, backup.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccReportPlanDataSourceConfig_reportSettings(rName, rName2),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(datasourceName, "arn", resourceName, "arn"),
resource.TestCheckResourceAttrPair(datasourceName, "creation_time", resourceName, "creation_time"),
resource.TestCheckResourceAttrSet(datasourceName, "deployment_status"), // CREATE_IN_PROGRESS | UPDATE_IN_PROGRESS | DELETE_IN_PROGRESS | COMPLETED
resource.TestCheckResourceAttrPair(datasourceName, "name", resourceName, "name"),
resource.TestCheckResourceAttrPair(datasourceName, "report_delivery_channel.#", resourceName, "report_delivery_channel.#"),
resource.TestCheckResourceAttrPair(datasourceName, "report_delivery_channel.0.formats.#", resourceName, "report_delivery_channel.0.formats.#"),
resource.TestCheckResourceAttrPair(datasourceName, "report_delivery_channel.0.formats.0", resourceName, "report_delivery_channel.0.formats.0"),
resource.TestCheckResourceAttrPair(datasourceName, "report_delivery_channel.0.s3_bucket_name", resourceName, "report_delivery_channel.0.s3_bucket_name"),
resource.TestCheckResourceAttrPair(datasourceName, "report_setting.#", resourceName, "report_setting.#"),
resource.TestCheckResourceAttr(resourceName, "report_setting.0.accounts.#", "1"),
resource.TestCheckResourceAttrPair(resourceName, "report_setting.0.accounts.0", "data.aws_caller_identity.current", "id"),
resource.TestCheckResourceAttr(resourceName, "report_setting.0.regions.#", "1"),
resource.TestCheckResourceAttrPair(resourceName, "report_setting.0.regions.0", "data.aws_region.current", "name"),
resource.TestCheckResourceAttrPair(datasourceName, "report_setting.0.report_template", resourceName, "report_setting.0.report_template"),
resource.TestCheckResourceAttrPair(datasourceName, "tags.%", resourceName, "tags.%"),
resource.TestCheckResourceAttrPair(datasourceName, "tags.Name", resourceName, "tags.Name"),
resource.TestCheckResourceAttrPair(datasourceName, "tags.Key2", resourceName, "tags.Key2"),
),
},
},
})
}

const testAccReportPlanDataSourceConfig_nonExistent = `
data "aws_backup_report_plan" "test" {
name = "tf_acc_test_does_not_exist"
}
`

func testAccReportPlanDataSourceConfig_basic(rName, rName2 string) string {
return fmt.Sprintf(`
resource "aws_s3_bucket" "test" {
bucket = %[1]q
}
resource "aws_s3_bucket_public_access_block" "test" {
bucket = aws_s3_bucket.test.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
return acctest.ConfigCompose(testAccReportPlanBaseConfig(rName), fmt.Sprintf(`
resource "aws_backup_report_plan" "test" {
name = %[2]q
name = %[1]q
description = "Test report plan data source"
report_delivery_channel {
Expand All @@ -93,5 +119,15 @@ resource "aws_backup_report_plan" "test" {
data "aws_backup_report_plan" "test" {
name = aws_backup_report_plan.test.name
}
`, rName, rName2)
`, rName2))
}

func testAccReportPlanDataSourceConfig_reportSettings(rName, rName2 string) string {
return acctest.ConfigCompose(
testAccReportPlanConfig_reportSettings(rName, rName2, "Test report plan data source"),
`
data "aws_backup_report_plan" "test" {
name = aws_backup_report_plan.test.name
}
`)
}
99 changes: 99 additions & 0 deletions internal/service/backup/report_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,71 @@ func TestAccBackupReportPlan_updateReportDeliveryChannel(t *testing.T) {
})
}

func TestAccBackupReportPlan_updateReportSettings(t *testing.T) {
ctx := acctest.Context(t)
var reportPlan backup.ReportPlan
rName := sdkacctest.RandomWithPrefix("tf-test-bucket")
rName2 := fmt.Sprintf("tf_acc_test_%s", sdkacctest.RandString(7))
description := "example description"
resourceName := "aws_backup_report_plan.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); testAccReportPlanPreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, backup.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckReportPlanDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccReportPlanConfig_basic(rName, rName2, description),
Check: resource.ComposeTestCheckFunc(
testAccCheckReportPlanExists(ctx, resourceName, &reportPlan),
resource.TestCheckResourceAttrSet(resourceName, "arn"),
resource.TestCheckResourceAttrSet(resourceName, "creation_time"),
resource.TestCheckResourceAttrSet(resourceName, "deployment_status"),
resource.TestCheckResourceAttr(resourceName, "description", description),
resource.TestCheckResourceAttr(resourceName, "report_delivery_channel.#", "1"),
resource.TestCheckResourceAttr(resourceName, "report_delivery_channel.0.formats.#", "1"),
resource.TestCheckResourceAttr(resourceName, "report_delivery_channel.0.formats.0", "CSV"),
resource.TestCheckResourceAttrPair(resourceName, "report_delivery_channel.0.s3_bucket_name", "aws_s3_bucket.test", "id"),
resource.TestCheckResourceAttr(resourceName, "report_setting.#", "1"),
resource.TestCheckNoResourceAttr(resourceName, "report_setting.0.accounts"),
resource.TestCheckNoResourceAttr(resourceName, "report_setting.0.regions"),
resource.TestCheckResourceAttr(resourceName, "report_setting.0.report_template", "RESTORE_JOB_REPORT"),
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(resourceName, "tags.Name", "Test Report Plan"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccReportPlanConfig_reportSettings(rName, rName2, description),
Check: resource.ComposeTestCheckFunc(
testAccCheckReportPlanExists(ctx, resourceName, &reportPlan),
resource.TestCheckResourceAttrSet(resourceName, "arn"),
resource.TestCheckResourceAttrSet(resourceName, "creation_time"),
resource.TestCheckResourceAttrSet(resourceName, "deployment_status"),
resource.TestCheckResourceAttr(resourceName, "description", description),
resource.TestCheckResourceAttr(resourceName, "report_delivery_channel.#", "1"),
resource.TestCheckResourceAttr(resourceName, "report_delivery_channel.0.formats.#", "1"),
resource.TestCheckResourceAttr(resourceName, "report_delivery_channel.0.formats.0", "CSV"),
resource.TestCheckResourceAttrPair(resourceName, "report_delivery_channel.0.s3_bucket_name", "aws_s3_bucket.test", "id"),
resource.TestCheckResourceAttr(resourceName, "report_setting.#", "1"),
resource.TestCheckResourceAttr(resourceName, "report_setting.0.accounts.#", "1"),
resource.TestCheckResourceAttrPair(resourceName, "report_setting.0.accounts.0", "data.aws_caller_identity.current", "id"),
resource.TestCheckResourceAttr(resourceName, "report_setting.0.regions.#", "1"),
resource.TestCheckResourceAttrPair(resourceName, "report_setting.0.regions.0", "data.aws_region.current", "name"),
resource.TestCheckResourceAttr(resourceName, "report_setting.0.report_template", "RESTORE_JOB_REPORT"),
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(resourceName, "tags.Name", "Test Report Plan"),
),
},
},
})
}

func TestAccBackupReportPlan_disappears(t *testing.T) {
ctx := acctest.Context(t)
var reportPlan backup.ReportPlan
Expand Down Expand Up @@ -313,6 +378,10 @@ func testAccCheckReportPlanExists(ctx context.Context, n string, v *backup.Repor

func testAccReportPlanBaseConfig(bucketName string) string {
return fmt.Sprintf(`
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}
resource "aws_s3_bucket" "test" {
bucket = %[1]q
}
Expand Down Expand Up @@ -426,3 +495,33 @@ resource "aws_backup_report_plan" "test" {
}
`, rName2, label))
}

func testAccReportPlanConfig_reportSettings(rName, rName2, label string) string {
return acctest.ConfigCompose(testAccReportPlanBaseConfig(rName), fmt.Sprintf(`
resource "aws_backup_report_plan" "test" {
name = %[1]q
description = %[2]q
report_delivery_channel {
formats = [
"CSV"
]
s3_bucket_name = aws_s3_bucket.test.id
}
report_setting {
accounts = [
data.aws_caller_identity.current.id
]
regions = [
data.aws_region.current.name
]
report_template = "RESTORE_JOB_REPORT"
}
tags = {
"Name" = "Test Report Plan"
}
}
`, rName2, label))
}
3 changes: 3 additions & 0 deletions website/docs/d/backup_report_plan.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ For **report_delivery_channel** the following attributes are supported:

For **report_setting** the following attributes are supported:

* `accounts` - (Optional) Specifies the list of accounts a report covers.
* `framework_arns` - ARNs of the frameworks a report covers.
* `number_of_frameworks` - Specifies the number of frameworks a report covers.
* `organization_units` - (Optional) Specifies the list of Organizational Units a report covers.
* `regions` - (Optional) Specifies the list of regions a report covers.
* `report_template` - Identifies the report template for the report. Reports are built using a report template.
3 changes: 3 additions & 0 deletions website/docs/r/backup_report_plan.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,11 @@ For **report_delivery_channel** the following attributes are supported:

For **report_setting** the following attributes are supported:

* `accounts` - (Optional) Specifies the list of accounts a report covers.
* `framework_arns` - (Optional) Specifies the Amazon Resource Names (ARNs) of the frameworks a report covers.
* `number_of_frameworks` - (Optional) Specifies the number of frameworks a report covers.
* `organization_units` - (Optional) Specifies the list of Organizational Units a report covers.
* `regions` - (Optional) Specifies the list of regions a report covers.
* `report_template` - (Required) Identifies the report template for the report. Reports are built using a report template. The report templates are: `RESOURCE_COMPLIANCE_REPORT` | `CONTROL_COMPLIANCE_REPORT` | `BACKUP_JOB_REPORT` | `COPY_JOB_REPORT` | `RESTORE_JOB_REPORT`.

## Attributes Reference
Expand Down

0 comments on commit 9fe696f

Please sign in to comment.