Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WORKING: f-aws-computeoptimizer-recommendation-preferences new resource #35349

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
073118a
Initial Resource Commit
tomhunte Mar 27, 2024
ba52b5e
Generated the service package
tomhunte Mar 27, 2024
8f7d685
Created the recommendation preferences resource.
tomhunte Mar 27, 2024
cc325f7
Staging current changes
tomhunte Apr 1, 2024
4440a64
Updated changes with //ISSUES labeled.
tomhunte May 28, 2024
b9d0ea2
Revert "Updated changes with //ISSUES labeled."
ewbankkit Sep 6, 2024
9b9f25b
Revert "Staging current changes"
ewbankkit Sep 6, 2024
f0f40ee
Revert "Created the recommendation preferences resource."
ewbankkit Sep 6, 2024
47c63bd
Revert "Generated the service package"
ewbankkit Sep 6, 2024
ec9c6a2
Revert "Initial Resource Commit"
ewbankkit Sep 6, 2024
be0a068
Merge branch 'main' into HEAD
ewbankkit Sep 6, 2024
71495c4
r/aws_computeoptimizer_enrollment_status: New resource.
ewbankkit Sep 9, 2024
65a2238
Acceptance test output:
ewbankkit Sep 9, 2024
edb0b4a
Add 'testAccEnrollmentStatus_includeMemberAccounts'.
ewbankkit Sep 9, 2024
07aff55
Acceptance test output:
ewbankkit Sep 9, 2024
e102f54
r/aws_computeoptimizer_recommendation_preferences: New resource.
ewbankkit Sep 10, 2024
97f03ad
r/aws_computeoptimizer_recommendation_preferences: 'scope' is Required.
ewbankkit Sep 10, 2024
9fc0159
r/aws_computeoptimizer_recommendation_preferences: Initial acceptance…
ewbankkit Sep 10, 2024
4b94d01
r/aws_computeoptimizer_recommendation_preferences: Initial documentat…
ewbankkit Sep 10, 2024
48e616a
r/aws_computeoptimizer_recommendation_preferences: 'look_back_period'…
ewbankkit Sep 10, 2024
2d83940
r/aws_computeoptimizer_recommendation_preferences: Another example.
ewbankkit Sep 10, 2024
518066f
Add 'testAccRecommendationPreferences_disappears'.
ewbankkit Sep 10, 2024
3704d57
Run 'make fix-constants PKG=computeoptimizer'.
ewbankkit Sep 10, 2024
3db7f2c
Fix markdown-lint 'MD047/single-trailing-newline Files should end wit…
ewbankkit Sep 10, 2024
e61c8c4
Fix markdown-lint 'MD009/no-trailing-spaces Trailing spaces [Expected…
ewbankkit Sep 10, 2024
cbfb42b
Run 'testAccRecommendationPreferences_preferredResources'.
ewbankkit Sep 10, 2024
bd504f8
Add 'testAccRecommendationPreferences_utilizationPreferences'.
ewbankkit Sep 10, 2024
2a4fc86
Run 'make fix-constants PKG=computeoptimizer'.
ewbankkit Sep 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changelog/35349.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:new-resource
aws_computeoptimizer_enrollment_status
```

```release-note:new-resource
aws_computeoptimizer_recommendation_preferences
```
51 changes: 51 additions & 0 deletions internal/service/computeoptimizer/computeoptimizer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package computeoptimizer_test

import (
"context"
"testing"

awstypes "github.com/aws/aws-sdk-go-v2/service/computeoptimizer/types"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tfcomputeoptimizer "github.com/hashicorp/terraform-provider-aws/internal/service/computeoptimizer"
)

func TestAccComputeOptimizer_serial(t *testing.T) {
t.Parallel()

testCases := map[string]map[string]func(t *testing.T){
"EnrollmentStatus": {
acctest.CtBasic: testAccEnrollmentStatus_basic,
"includeMemberAccounts": testAccEnrollmentStatus_includeMemberAccounts,
},
"RecommendationPreferences": {
acctest.CtBasic: testAccRecommendationPreferences_basic,
acctest.CtDisappears: testAccRecommendationPreferences_disappears,
"preferredResources": testAccRecommendationPreferences_preferredResources,
"utilizationPreferences": testAccRecommendationPreferences_utilizationPreferences,
},
}

acctest.RunSerialTests2Levels(t, testCases, 0)
}

func testAccPreCheckEnrollmentStatus(ctx context.Context, t *testing.T, want awstypes.Status) {
conn := acctest.Provider.Meta().(*conns.AWSClient).ComputeOptimizerClient(ctx)

output, err := tfcomputeoptimizer.FindEnrollmentStatus(ctx, conn)

if acctest.PreCheckSkipError(err) {
t.Skipf("skipping acceptance testing: %s", err)
}

if err != nil {
t.Fatalf("unexpected PreCheck error: %s", err)
}

if got := output.Status; got != want {
t.Fatalf("Compute Optimizer enrollment status: %s", got)
}
}
246 changes: 246 additions & 0 deletions internal/service/computeoptimizer/enrollment_status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package computeoptimizer

import (
"context"
"errors"
"fmt"
"time"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/computeoptimizer"
awstypes "github.com/aws/aws-sdk-go-v2/service/computeoptimizer/types"
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-provider-aws/internal/enum"
"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"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
"github.com/hashicorp/terraform-provider-aws/names"
)

// @FrameworkResource(name="Enrollment Status")
func newEnrollmentStatusResource(context.Context) (resource.ResourceWithConfigure, error) {
r := &enrollmentStatusResource{}

r.SetDefaultCreateTimeout(5 * time.Minute)
r.SetDefaultUpdateTimeout(5 * time.Minute)

return r, nil
}

type enrollmentStatusResource struct {
framework.ResourceWithConfigure
framework.WithTimeouts
framework.WithNoOpDelete
framework.WithImportByID
}

func (*enrollmentStatusResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) {
response.TypeName = "aws_computeoptimizer_enrollment_status"
}

func (r *enrollmentStatusResource) Schema(ctx context.Context, request resource.SchemaRequest, response *resource.SchemaResponse) {
response.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
names.AttrID: framework.IDAttribute(),
"include_member_accounts": schema.BoolAttribute{
Optional: true,
Computed: true,
Default: booldefault.StaticBool(false),
PlanModifiers: []planmodifier.Bool{
boolplanmodifier.UseStateForUnknown(),
},
},
"number_of_member_accounts_opted_in": schema.Int64Attribute{
Computed: true,
},
names.AttrStatus: schema.StringAttribute{
Required: true,
Validators: []validator.String{
stringvalidator.OneOf("Active", "Inactive"),
},
},
},
Blocks: map[string]schema.Block{
names.AttrTimeouts: timeouts.Block(ctx, timeouts.Opts{
Create: true,
Update: true,
}),
},
}
}

func (r *enrollmentStatusResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) {
var data enrollmentStatusResourceModel
response.Diagnostics.Append(request.Plan.Get(ctx, &data)...)
if response.Diagnostics.HasError() {
return
}

conn := r.Meta().ComputeOptimizerClient(ctx)

input := &computeoptimizer.UpdateEnrollmentStatusInput{
IncludeMemberAccounts: fwflex.BoolValueFromFramework(ctx, data.MemberAccountsEnrolled),
Status: awstypes.Status(fwflex.StringValueFromFramework(ctx, data.Status)),
}

_, err := conn.UpdateEnrollmentStatus(ctx, input)

if err != nil {
response.Diagnostics.AddError("creating Compute Optimizer Enrollment Status", err.Error())

return
}

// Set values for unknowns.
data.ID = fwflex.StringValueToFramework(ctx, r.Meta().AccountID)

output, err := waitEnrollmentStatusUpdated(ctx, conn, string(input.Status), r.CreateTimeout(ctx, data.Timeouts))

if err != nil {
response.Diagnostics.AddError(fmt.Sprintf("waiting for Compute Optimizer Enrollment Status (%s) create", data.ID.ValueString()), err.Error())

return
}

data.NumberOfMemberAccountsOptedIn = fwflex.Int32ToFramework(ctx, output.NumberOfMemberAccountsOptedIn)

response.Diagnostics.Append(response.State.Set(ctx, &data)...)
}

func (r *enrollmentStatusResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) {
var data enrollmentStatusResourceModel
response.Diagnostics.Append(request.State.Get(ctx, &data)...)
if response.Diagnostics.HasError() {
return
}

conn := r.Meta().ComputeOptimizerClient(ctx)

output, err := findEnrollmentStatus(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 Compute Optimizer Enrollment Status (%s)", data.ID.ValueString()), err.Error())

return
}

response.Diagnostics.Append(fwflex.Flatten(ctx, output, &data)...)
if response.Diagnostics.HasError() {
return
}

response.Diagnostics.Append(response.State.Set(ctx, &data)...)
}

func (r *enrollmentStatusResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) {
var new enrollmentStatusResourceModel
response.Diagnostics.Append(request.Plan.Get(ctx, &new)...)
if response.Diagnostics.HasError() {
return
}

conn := r.Meta().ComputeOptimizerClient(ctx)

input := &computeoptimizer.UpdateEnrollmentStatusInput{
Status: awstypes.Status(fwflex.StringValueFromFramework(ctx, new.Status)),
}

_, err := conn.UpdateEnrollmentStatus(ctx, input)

if err != nil {
response.Diagnostics.AddError("updating Compute Optimizer Enrollment Status", err.Error())

return
}

output, err := waitEnrollmentStatusUpdated(ctx, conn, string(input.Status), r.CreateTimeout(ctx, new.Timeouts))

if err != nil {
response.Diagnostics.AddError(fmt.Sprintf("waiting for Compute Optimizer Enrollment Status (%s) update", new.ID.ValueString()), err.Error())

return
}

new.NumberOfMemberAccountsOptedIn = fwflex.Int32ToFramework(ctx, output.NumberOfMemberAccountsOptedIn)

response.Diagnostics.Append(response.State.Set(ctx, &new)...)
}

func findEnrollmentStatus(ctx context.Context, conn *computeoptimizer.Client) (*computeoptimizer.GetEnrollmentStatusOutput, error) {
input := &computeoptimizer.GetEnrollmentStatusInput{}

output, err := conn.GetEnrollmentStatus(ctx, input)

if err != nil {
return nil, err
}

if output == nil {
return nil, tfresource.NewEmptyResultError(input)
}

return output, nil
}

func statusEnrollmentStatus(ctx context.Context, conn *computeoptimizer.Client) retry.StateRefreshFunc {
return func() (interface{}, string, error) {
output, err := findEnrollmentStatus(ctx, conn)

if tfresource.NotFound(err) {
return nil, "", nil
}

if err != nil {
return nil, "", err
}

return output, string(output.Status), nil
}
}

func waitEnrollmentStatusUpdated(ctx context.Context, conn *computeoptimizer.Client, targetStatus string, timeout time.Duration) (*computeoptimizer.GetEnrollmentStatusOutput, error) {
stateConf := &retry.StateChangeConf{
Pending: enum.Slice(awstypes.StatusPending),
Target: []string{targetStatus},
Refresh: statusEnrollmentStatus(ctx, conn),
Timeout: timeout,
}

outputRaw, err := stateConf.WaitForStateContext(ctx)

if output, ok := outputRaw.(*computeoptimizer.GetEnrollmentStatusOutput); ok {
tfresource.SetLastError(err, errors.New(aws.ToString(output.StatusReason)))

return output, err
}

return nil, err
}

type enrollmentStatusResourceModel struct {
ID types.String `tfsdk:"id"`
MemberAccountsEnrolled types.Bool `tfsdk:"include_member_accounts"`
NumberOfMemberAccountsOptedIn types.Int64 `tfsdk:"number_of_member_accounts_opted_in"`
Status types.String `tfsdk:"status"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
}
Loading
Loading