From 8b0464c835f9ba8adaacac6448a0acbc5726a9b4 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 12 Sep 2024 11:50:05 -0400 Subject: [PATCH 1/5] r/aws_sesv2_account_suppression_attributes: New resource. --- .changelog/#####.txt | 3 + .../sesv2/account_suppression_attributes.go | 158 ++++++++++++++++++ internal/service/sesv2/service_package_gen.go | 7 +- ...count_suppression_attributes.html.markdown | 46 +++++ 4 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 .changelog/#####.txt create mode 100644 internal/service/sesv2/account_suppression_attributes.go create mode 100644 website/docs/r/sesv2_account_suppression_attributes.html.markdown diff --git a/.changelog/#####.txt b/.changelog/#####.txt new file mode 100644 index 00000000000..470001e3d3b --- /dev/null +++ b/.changelog/#####.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_sesv2_account_suppression_attributes +``` \ No newline at end of file diff --git a/internal/service/sesv2/account_suppression_attributes.go b/internal/service/sesv2/account_suppression_attributes.go new file mode 100644 index 00000000000..3a01bd0bd72 --- /dev/null +++ b/internal/service/sesv2/account_suppression_attributes.go @@ -0,0 +1,158 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package sesv2 + +import ( + "context" + "fmt" + + "github.com/aws/aws-sdk-go-v2/service/sesv2" + awstypes "github.com/aws/aws-sdk-go-v2/service/sesv2/types" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/errs/fwdiag" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + fwflex "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// @FrameworkResource(name="Account Suppression Attributes") +func newAccountSuppressionAttributesResource(context.Context) (resource.ResourceWithConfigure, error) { + r := &accountSuppressionAttributesResource{} + + return r, nil +} + +type accountSuppressionAttributesResource struct { + framework.ResourceWithConfigure + framework.WithNoOpDelete + framework.WithImportByID +} + +func (*accountSuppressionAttributesResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { + response.TypeName = "aws_sesv2_account_suppression_attributes" +} + +func (r *accountSuppressionAttributesResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) { + response.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + names.AttrID: framework.IDAttribute(), + "suppressed_reasons": schema.SetAttribute{ + CustomType: fwtypes.NewSetTypeOf[fwtypes.StringEnum[awstypes.SuppressionListReason]](ctx), + Required: true, + ElementType: fwtypes.StringEnumType[awstypes.SuppressionListReason](), + }, + }, + } +} + +func (r *accountSuppressionAttributesResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { + var data accountSuppressionAttributesResourceModel + response.Diagnostics.Append(request.Plan.Get(ctx, &data)...) + if response.Diagnostics.HasError() { + return + } + + conn := r.Meta().SESV2Client(ctx) + + id := r.Meta().AccountID + input := &sesv2.PutAccountSuppressionAttributesInput{} + response.Diagnostics.Append(fwflex.Expand(ctx, data, input)...) + if response.Diagnostics.HasError() { + return + } + + _, err := conn.PutAccountSuppressionAttributes(ctx, input) + + if err != nil { + response.Diagnostics.AddError(fmt.Sprintf("creating SESv2 Account Suppression Attributes (%s)", id), err.Error()) + + return + } + + // Set values for unknowns. + data.ID = fwflex.StringValueToFramework(ctx, id) + + response.Diagnostics.Append(response.State.Set(ctx, &data)...) +} + +func (r *accountSuppressionAttributesResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { + var data accountSuppressionAttributesResourceModel + response.Diagnostics.Append(request.State.Get(ctx, &data)...) + if response.Diagnostics.HasError() { + return + } + + conn := r.Meta().SESV2Client(ctx) + + suppressionAttributes, err := findAccountSuppressionAttributes(ctx, conn) + + if tfresource.NotFound(err) { + response.Diagnostics.Append(fwdiag.NewResourceNotFoundWarningDiagnostic(err)) + response.State.RemoveResource(ctx) + + return + } + + if err != nil { + response.Diagnostics.AddError(fmt.Sprintf("reading SESv2 Account Suppression Attributes (%s)", data.ID.ValueString()), err.Error()) + + return + } + + response.Diagnostics.Append(fwflex.Flatten(ctx, suppressionAttributes, &data)...) + if response.Diagnostics.HasError() { + return + } + + response.Diagnostics.Append(response.State.Set(ctx, &data)...) +} + +func (r *accountSuppressionAttributesResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { + var new accountSuppressionAttributesResourceModel + response.Diagnostics.Append(request.Plan.Get(ctx, &new)...) + if response.Diagnostics.HasError() { + return + } + + conn := r.Meta().SESV2Client(ctx) + + input := &sesv2.PutAccountSuppressionAttributesInput{} + response.Diagnostics.Append(fwflex.Expand(ctx, new, input)...) + if response.Diagnostics.HasError() { + return + } + + _, err := conn.PutAccountSuppressionAttributes(ctx, input) + + if err != nil { + response.Diagnostics.AddError(fmt.Sprintf("updating SESv2 Account Suppression Attributes (%s)", new.ID.ValueString()), err.Error()) + + return + } + + response.Diagnostics.Append(response.State.Set(ctx, &new)...) +} + +func findAccountSuppressionAttributes(ctx context.Context, conn *sesv2.Client) (*awstypes.SuppressionAttributes, error) { + output, err := findAccount(ctx, conn) + + if err != nil { + return nil, err + } + + if output.SuppressionAttributes == nil { + return nil, tfresource.NewEmptyResultError(nil) + } + + return output.SuppressionAttributes, nil +} + +type accountSuppressionAttributesResourceModel struct { + ID types.String `tfsdk:"id"` + SuppressedReasons fwtypes.SetValueOf[fwtypes.StringEnum[awstypes.SuppressionListReason]] `tfsdk:"suppressed_reasons"` +} diff --git a/internal/service/sesv2/service_package_gen.go b/internal/service/sesv2/service_package_gen.go index 9bcfb7b9064..715e4a92740 100644 --- a/internal/service/sesv2/service_package_gen.go +++ b/internal/service/sesv2/service_package_gen.go @@ -19,7 +19,12 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.Serv } func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.ServicePackageFrameworkResource { - return []*types.ServicePackageFrameworkResource{} + return []*types.ServicePackageFrameworkResource{ + { + Factory: newAccountSuppressionAttributesResource, + Name: "Account Suppression Attributes", + }, + } } func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePackageSDKDataSource { diff --git a/website/docs/r/sesv2_account_suppression_attributes.html.markdown b/website/docs/r/sesv2_account_suppression_attributes.html.markdown new file mode 100644 index 00000000000..42ddaa3f5cc --- /dev/null +++ b/website/docs/r/sesv2_account_suppression_attributes.html.markdown @@ -0,0 +1,46 @@ +--- +subcategory: "SESv2 (Simple Email V2)" +layout: "aws" +page_title: "AWS: aws_sesv2_account_suppression_attributes" +description: |- + Manages AWS SESv2 (Simple Email V2) account-level suppression attributes. +--- + +# Resource: aws_sesv2_account_suppression_attributes + +Manages AWS SESv2 (Simple Email V2) account-level suppression attributes. + +## Example Usage + +```terraform +resource "aws_sesv2_account_suppression_attributes" "example" { + suppressed_reasons = ["COMPLAINT"] +} +``` + +## Argument Reference + +The following arguments are required: + +* `suppressed_reasons` - (Required) A list that contains the reasons that email addresses will be automatically added to the suppression list for your account. Valid values: `COMPLAINT`, `BOUNCE`. + +## Attribute Reference + +This data source exports no additional attributes. + +## Import + +In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import account-level suppression attributes using the account ID. For example: + +```terraform +import { + to = aws_sesv2_account_suppression_attributes.example + id = "123456789012" +} +``` + +Using `terraform import`, import account-level suppression attributes using the account ID. For example: + +```console +% terraform import aws_sesv2_account_suppression_attributes.example 123456789012 +``` From 2a3443f4790c5443fc730af13434870e3cf57df5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 12 Sep 2024 15:20:40 -0400 Subject: [PATCH 2/5] r/aws_sesv2_account_suppression_attributes: Initial acceptance test. --- .../account_suppression_attributes_test.go | 85 +++++++++++++++++++ internal/service/sesv2/exports_test.go | 1 + 2 files changed, 86 insertions(+) create mode 100644 internal/service/sesv2/account_suppression_attributes_test.go diff --git a/internal/service/sesv2/account_suppression_attributes_test.go b/internal/service/sesv2/account_suppression_attributes_test.go new file mode 100644 index 00000000000..161a5a08925 --- /dev/null +++ b/internal/service/sesv2/account_suppression_attributes_test.go @@ -0,0 +1,85 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package sesv2_test + +import ( + "context" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go-v2/service/sesv2/types" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/knownvalue" + "github.com/hashicorp/terraform-plugin-testing/statecheck" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tfsesv2 "github.com/hashicorp/terraform-provider-aws/internal/service/sesv2" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccSESV2AccountSuppressionAttributes_serial(t *testing.T) { + t.Parallel() + + testCases := map[string]func(t *testing.T){ + acctest.CtBasic: testAccAccountSuppressionAttributes_basic, + } + + acctest.RunSerialTests1Level(t, testCases, 0) +} + +func testAccAccountSuppressionAttributes_basic(t *testing.T) { + ctx := acctest.Context(t) + resourceName := "aws_sesv2_account_suppression_attributes.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.SESV2ServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: acctest.CheckDestroyNoop, + Steps: []resource.TestStep{ + { + Config: testAccAccountSuppressionAttributesConfig_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckAccountSuppressionAttributesExists(ctx, resourceName), + ), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("suppressed_reasons"), knownvalue.SetSizeExact(1)), + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("suppressed_reasons"), knownvalue.SetExact( + []knownvalue.Check{ + knownvalue.StringExact(string(types.SuppressionListReasonComplaint)), + }), + ), + }, + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckAccountSuppressionAttributesExists(ctx context.Context, n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + _, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).SESV2Client(ctx) + + _, err := tfsesv2.FindAccountSuppressionAttributes(ctx, conn) + + return err + } +} + +const testAccAccountSuppressionAttributesConfig_basic = ` +resource "aws_sesv2_account_suppression_attributes" "test" { + suppressed_reasons = ["COMPLAINT"] +} +` diff --git a/internal/service/sesv2/exports_test.go b/internal/service/sesv2/exports_test.go index 82cc43d99ab..e2aabe98e6f 100644 --- a/internal/service/sesv2/exports_test.go +++ b/internal/service/sesv2/exports_test.go @@ -16,6 +16,7 @@ var ( ResourceEmailIdentityMailFromAttributes = resourceEmailIdentityMailFromAttributes ResourceEmailIdentityPolicy = resourceEmailIdentityPolicy + FindAccountSuppressionAttributes = findAccountSuppressionAttributes FindAccountVDMAttributes = findAccountVDMAttributes FindConfigurationSetByID = findConfigurationSetByID FindConfigurationSetEventDestinationByTwoPartKey = findConfigurationSetEventDestinationByTwoPartKey From 083cc13cd25b2444916cfaa72d7b6a6b5b1cb9e9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 13 Sep 2024 14:10:27 -0400 Subject: [PATCH 3/5] Add 'testAccAccountSuppressionAttributes_update'. --- .../account_suppression_attributes_test.go | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/internal/service/sesv2/account_suppression_attributes_test.go b/internal/service/sesv2/account_suppression_attributes_test.go index 161a5a08925..dd0f5624e08 100644 --- a/internal/service/sesv2/account_suppression_attributes_test.go +++ b/internal/service/sesv2/account_suppression_attributes_test.go @@ -25,6 +25,7 @@ func TestAccSESV2AccountSuppressionAttributes_serial(t *testing.T) { testCases := map[string]func(t *testing.T){ acctest.CtBasic: testAccAccountSuppressionAttributes_basic, + "update": testAccAccountSuppressionAttributes_update, } acctest.RunSerialTests1Level(t, testCases, 0) @@ -63,6 +64,43 @@ func testAccAccountSuppressionAttributes_basic(t *testing.T) { }) } +func testAccAccountSuppressionAttributes_update(t *testing.T) { + ctx := acctest.Context(t) + resourceName := "aws_sesv2_account_suppression_attributes.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.SESV2ServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: acctest.CheckDestroyNoop, + Steps: []resource.TestStep{ + { + Config: testAccAccountSuppressionAttributesConfig_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckAccountSuppressionAttributesExists(ctx, resourceName), + ), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("suppressed_reasons"), knownvalue.SetSizeExact(1)), + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("suppressed_reasons"), knownvalue.SetExact( + []knownvalue.Check{ + knownvalue.StringExact(string(types.SuppressionListReasonComplaint)), + }), + ), + }, + }, + { + Config: testAccAccountSuppressionAttributesConfig_updated, + Check: resource.ComposeTestCheckFunc( + testAccCheckAccountSuppressionAttributesExists(ctx, resourceName), + ), + ConfigStateChecks: []statecheck.StateCheck{ + statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("suppressed_reasons"), knownvalue.SetSizeExact(0)), + }, + }, + }, + }) +} + func testAccCheckAccountSuppressionAttributesExists(ctx context.Context, n string) resource.TestCheckFunc { return func(s *terraform.State) error { _, ok := s.RootModule().Resources[n] @@ -83,3 +121,9 @@ resource "aws_sesv2_account_suppression_attributes" "test" { suppressed_reasons = ["COMPLAINT"] } ` + +const testAccAccountSuppressionAttributesConfig_updated = ` +resource "aws_sesv2_account_suppression_attributes" "test" { + suppressed_reasons = [] +} +` From 8a006f77747a7f94b68d9ee1ad83e8c14b23cae2 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 13 Sep 2024 14:12:32 -0400 Subject: [PATCH 4/5] Correct CHANGELOG entry file name. --- .changelog/{#####.txt => 39325.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .changelog/{#####.txt => 39325.txt} (100%) diff --git a/.changelog/#####.txt b/.changelog/39325.txt similarity index 100% rename from .changelog/#####.txt rename to .changelog/39325.txt From 6974f494f49df7dc51407a91272268374dbceaaf Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 13 Sep 2024 14:13:44 -0400 Subject: [PATCH 5/5] Update sesv2_account_suppression_attributes.html.markdown --- .../docs/r/sesv2_account_suppression_attributes.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/sesv2_account_suppression_attributes.html.markdown b/website/docs/r/sesv2_account_suppression_attributes.html.markdown index 42ddaa3f5cc..072f49dd115 100644 --- a/website/docs/r/sesv2_account_suppression_attributes.html.markdown +++ b/website/docs/r/sesv2_account_suppression_attributes.html.markdown @@ -26,7 +26,7 @@ The following arguments are required: ## Attribute Reference -This data source exports no additional attributes. +This resource exports no additional attributes. ## Import