Skip to content

Commit

Permalink
Merge pull request #39661 from hashicorp/f/r53-add-tags
Browse files Browse the repository at this point in the history
r/aws_route53profiles_association: add tags
  • Loading branch information
nam054 authored Oct 10, 2024
2 parents 2d0d06b + abc1f24 commit 7964acb
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 14 deletions.
73 changes: 59 additions & 14 deletions internal/service/route53profiles/association.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ package route53profiles
import (
"context"
"errors"
"fmt"
"time"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/route53profiles"
awstypes "github.com/aws/aws-sdk-go-v2/service/route53profiles/types"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
Expand All @@ -25,11 +27,13 @@ import (
"github.com/hashicorp/terraform-provider-aws/internal/framework"
"github.com/hashicorp/terraform-provider-aws/internal/framework/flex"
fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
"github.com/hashicorp/terraform-provider-aws/names"
)

// @FrameworkResource("aws_route53profiles_association", name="Association")
// @Tags(identifierAttribute="arn")
func newResourceAssociation(_ context.Context) (resource.ResourceWithConfigure, error) {
r := &resourceAssociation{}

Expand All @@ -46,7 +50,7 @@ const (

type resourceAssociation struct {
framework.ResourceWithConfigure
framework.WithNoUpdate
framework.WithNoOpUpdate[associationResourceModel]
framework.WithTimeouts
framework.WithImportByID
}
Expand All @@ -58,7 +62,8 @@ func (r *resourceAssociation) Metadata(_ context.Context, req resource.MetadataR
func (r *resourceAssociation) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
names.AttrID: framework.IDAttribute(),
names.AttrARN: framework.ARNAttributeComputedOnly(),
names.AttrID: framework.IDAttribute(),
names.AttrName: schema.StringAttribute{
Required: true,
PlanModifiers: []planmodifier.String{
Expand All @@ -67,6 +72,9 @@ func (r *resourceAssociation) Schema(ctx context.Context, req resource.SchemaReq
},
names.AttrOwnerID: schema.StringAttribute{
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
"profile_id": schema.StringAttribute{
Required: true,
Expand All @@ -83,10 +91,18 @@ func (r *resourceAssociation) Schema(ctx context.Context, req resource.SchemaReq
names.AttrStatus: schema.StringAttribute{
CustomType: fwtypes.StringEnumType[awstypes.ProfileStatus](),
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
names.AttrStatusMessage: schema.StringAttribute{
Computed: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
names.AttrTags: tftags.TagsAttribute(),
names.AttrTagsAll: tftags.TagsAttributeComputedOnly(),
},
Blocks: map[string]schema.Block{
names.AttrTimeouts: timeouts.Block(ctx, timeouts.Opts{
Expand All @@ -101,49 +117,62 @@ func (r *resourceAssociation) Schema(ctx context.Context, req resource.SchemaReq
func (r *resourceAssociation) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
conn := r.Meta().Route53ProfilesClient(ctx)

var state associationResourceModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &state)...)
var data associationResourceModel
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}

input := &route53profiles.AssociateProfileInput{}
resp.Diagnostics.Append(flex.Expand(ctx, state, input)...)
input := &route53profiles.AssociateProfileInput{
Name: data.Name.ValueStringPointer(),
Tags: getTagsInSlice(ctx),
}
resp.Diagnostics.Append(flex.Expand(ctx, data, input)...)

out, err := conn.AssociateProfile(ctx, input)
if err != nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.Route53Profiles, create.ErrActionCreating, ResNameAssociation, state.Name.String(), err),
create.ProblemStandardMessage(names.Route53Profiles, create.ErrActionCreating, ResNameAssociation, data.Name.String(), err),
err.Error(),
)
return
}
if out == nil || out.ProfileAssociation == nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.Route53Profiles, create.ErrActionCreating, ResNameAssociation, state.Name.String(), nil),
create.ProblemStandardMessage(names.Route53Profiles, create.ErrActionCreating, ResNameAssociation, data.Name.String(), nil),
errors.New("empty output").Error(),
)
return
}

state.ID = flex.StringToFramework(ctx, out.ProfileAssociation.Id)
data.ID = flex.StringToFramework(ctx, out.ProfileAssociation.Id)

associationArn := arn.ARN{
Partition: r.Meta().Partition,
Service: "route53profiles",
Region: r.Meta().Region,
AccountID: r.Meta().AccountID,
Resource: fmt.Sprintf("profile-association/%s", aws.ToString(out.ProfileAssociation.Id)),
}.String()

data.ARN = flex.StringValueToFramework(ctx, associationArn)

createTimeout := r.CreateTimeout(ctx, state.Timeouts)
profileAssociation, err := waitAssociationCreated(ctx, conn, state.ID.ValueString(), createTimeout)
createTimeout := r.CreateTimeout(ctx, data.Timeouts)
profileAssociation, err := waitAssociationCreated(ctx, conn, data.ID.ValueString(), createTimeout)
if err != nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.Route53Profiles, create.ErrActionWaitingForCreation, ResNameAssociation, state.Name.String(), err),
create.ProblemStandardMessage(names.Route53Profiles, create.ErrActionWaitingForCreation, ResNameAssociation, data.Name.String(), err),
err.Error(),
)
return
}

resp.Diagnostics.Append(flex.Flatten(ctx, profileAssociation, &state)...)
resp.Diagnostics.Append(flex.Flatten(ctx, profileAssociation, &data)...)
if resp.Diagnostics.HasError() {
return
}

resp.Diagnostics.Append(resp.State.Set(ctx, state)...)
resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
}

func (r *resourceAssociation) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
Expand All @@ -168,6 +197,15 @@ func (r *resourceAssociation) Read(ctx context.Context, req resource.ReadRequest
return
}

associationArn := arn.ARN{
Partition: r.Meta().Partition,
Service: "route53profiles",
Region: r.Meta().Region,
AccountID: r.Meta().AccountID,
Resource: fmt.Sprintf("profile-association/%s", aws.ToString(out.Id)),
}.String()
state.ARN = flex.StringValueToFramework(ctx, associationArn)

resp.Diagnostics.Append(flex.Flatten(ctx, out, &state)...)
if resp.Diagnostics.HasError() {
return
Expand Down Expand Up @@ -266,6 +304,10 @@ func statusAssociation(ctx context.Context, conn *route53profiles.Client, id str
}
}

func (r *resourceAssociation) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
r.SetTagsAll(ctx, req, resp)
}

func findAssociationByID(ctx context.Context, conn *route53profiles.Client, id string) (*awstypes.ProfileAssociation, error) {
in := &route53profiles.GetProfileAssociationInput{
ProfileAssociationId: aws.String(id),
Expand All @@ -291,12 +333,15 @@ func findAssociationByID(ctx context.Context, conn *route53profiles.Client, id s
}

type associationResourceModel struct {
ARN types.String `tfsdk:"arn"`
ID types.String `tfsdk:"id"`
ResourceID types.String `tfsdk:"resource_id"`
ProfileID types.String `tfsdk:"profile_id"`
Name types.String `tfsdk:"name"`
OwnerId types.String `tfsdk:"owner_id"`
Status fwtypes.StringEnum[awstypes.ProfileStatus] `tfsdk:"status"`
StatusMessage types.String `tfsdk:"status_message"`
Tags tftags.Map `tfsdk:"tags"`
TagsAll tftags.Map `tfsdk:"tags_all"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
}
94 changes: 94 additions & 0 deletions internal/service/route53profiles/association_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,54 @@ func TestAccRoute53ProfilesAssociation_basic(t *testing.T) {
})
}

func TestAccRoute53ProfilesAssociation_tags(t *testing.T) {
ctx := acctest.Context(t)
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_route53profiles_association.test"
var v awstypes.ProfileAssociation

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, names.Route53ProfilesServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckAssociationDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccAssociationConfig_tags1(rName, acctest.CtKey1, acctest.CtValue1),
Check: resource.ComposeTestCheckFunc(
testAccCheckAssociationExists(ctx, resourceName, &v),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, acctest.CtValue1),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccAssociationConfig_tags2(rName, acctest.CtKey1, acctest.CtValue1Updated, acctest.CtKey2, acctest.CtValue2),
Check: resource.ComposeTestCheckFunc(
testAccCheckAssociationExists(ctx, resourceName, &v),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, acctest.Ct2),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, acctest.CtValue1Updated),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, acctest.CtValue2),
),
},
{
Config: testAccAssociationConfig_tags1(rName, acctest.CtKey2, acctest.CtValue2),
Check: resource.ComposeTestCheckFunc(
testAccCheckAssociationExists(ctx, resourceName, &v),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, acctest.CtValue2),
),
},
},
})
}

func TestAccRoute53ProfilesAssociation_disappears(t *testing.T) {
ctx := acctest.Context(t)
if testing.Short() {
Expand Down Expand Up @@ -156,3 +204,49 @@ resource "aws_route53profiles_association" "test" {
}
`, rName)
}

func testAccAssociationConfig_tags1(rName, tagKey1, tagValue1 string) string {
return fmt.Sprintf(`
resource "aws_route53profiles_profile" "test" {
name = %[1]q
}
resource "aws_vpc" "test" {
cidr_block = "10.0.0.0/16"
}
resource "aws_route53profiles_association" "test" {
name = %[1]q
profile_id = aws_route53profiles_profile.test.id
resource_id = aws_vpc.test.id
tags = {
%[2]q = %[3]q
}
}
`, rName, tagKey1, tagValue1)
}

func testAccAssociationConfig_tags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string {
return fmt.Sprintf(`
resource "aws_route53profiles_profile" "test" {
name = %[1]q
}
resource "aws_vpc" "test" {
cidr_block = "10.0.0.0/16"
}
resource "aws_route53profiles_association" "test" {
name = %[1]q
profile_id = aws_route53profiles_profile.test.id
resource_id = aws_vpc.test.id
tags = {
%[2]q = %[3]q
%[4]q = %[5]q
}
}
`, rName, tagKey1, tagValue1, tagKey2, tagValue2)
}
3 changes: 3 additions & 0 deletions internal/service/route53profiles/service_package_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7964acb

Please sign in to comment.