Skip to content

Commit af62308

Browse files
authored
Merge pull request #45467 from hashicorp/f-lambda_capacity_provider_list
r/lambda_capacity_provider: add list resource
2 parents e65e689 + 3cfa41c commit af62308

File tree

11 files changed

+763
-0
lines changed

11 files changed

+763
-0
lines changed

.changelog/45467.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:new-list-resource
2+
aws_lambda_capacity_provider
3+
```

internal/framework/with_list.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,18 @@
44
package framework
55

66
import (
7+
"context"
8+
"fmt"
9+
"slices"
10+
11+
"github.com/hashicorp/terraform-plugin-framework/attr"
12+
"github.com/hashicorp/terraform-plugin-framework/diag"
13+
"github.com/hashicorp/terraform-plugin-framework/list"
14+
"github.com/hashicorp/terraform-plugin-framework/path"
15+
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
716
"github.com/hashicorp/terraform-provider-aws/internal/provider/framework/listresource"
17+
tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices"
18+
"github.com/hashicorp/terraform-provider-aws/names"
819
)
920

1021
type Lister interface {
@@ -24,3 +35,56 @@ func (w *WithList) AppendResultInterceptor(interceptor listresource.ListResultIn
2435
func (w WithList) ResultInterceptors() []listresource.ListResultInterceptor {
2536
return w.interceptors
2637
}
38+
39+
func (w *WithList) RunResultInterceptors(ctx context.Context, when listresource.When, params listresource.InterceptorParams) diag.Diagnostics {
40+
var diags diag.Diagnostics
41+
switch when {
42+
case listresource.Before:
43+
params.When = listresource.Before
44+
for interceptor := range slices.Values(w.interceptors) {
45+
diags.Append(interceptor.Read(ctx, params)...)
46+
}
47+
return diags
48+
case listresource.After:
49+
params.When = listresource.After
50+
for interceptor := range tfslices.BackwardValues(w.interceptors) {
51+
diags.Append(interceptor.Read(ctx, params)...)
52+
}
53+
return diags
54+
}
55+
56+
return diags
57+
}
58+
59+
func (w *WithList) ListResourceTagsInit(ctx context.Context, result list.ListResult) basetypes.MapValue {
60+
typ, _ := result.Resource.Schema.TypeAtPath(ctx, path.Root(names.AttrTags))
61+
tagsType := typ.(attr.TypeWithElementType)
62+
63+
return basetypes.NewMapNull(tagsType.ElementType())
64+
}
65+
66+
func (w *WithList) ListResourceTimeoutInit(ctx context.Context, result list.ListResult) (basetypes.ObjectValue, diag.Diagnostics) {
67+
timeoutsType, _ := result.Resource.Schema.TypeAtPath(ctx, path.Root(names.AttrTimeouts))
68+
69+
return newNullObject(timeoutsType)
70+
}
71+
72+
func newNullObject(typ attr.Type) (obj basetypes.ObjectValue, diags diag.Diagnostics) {
73+
i, ok := typ.(attr.TypeWithAttributeTypes)
74+
if !ok {
75+
diags.AddError(
76+
"Internal Error",
77+
"An unexpected error occurred. "+
78+
"This is always an error in the provider. "+
79+
"Please report the following to the provider developer:\n\n"+
80+
fmt.Sprintf("Expected value type to implement attr.TypeWithAttributeTypes, got: %T", typ),
81+
)
82+
return
83+
}
84+
85+
attrTypes := i.AttributeTypes()
86+
87+
obj = basetypes.NewObjectNull(attrTypes)
88+
89+
return obj, diags
90+
}

internal/provider/framework/listresource/list_result_intercept.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import (
2626
// Multiple values can be ORed together.
2727
type when uint16
2828

29+
type When = when
30+
2931
const (
3032
Before when = 1 << iota // Interceptor is invoked before call to method in schema
3133
After // Interceptor is invoked after successful call to method in schema

internal/service/lambda/capacity_provider.go

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,21 @@ package lambda
66
import (
77
"context"
88
"errors"
9+
"fmt"
10+
"iter"
11+
"strings"
912
"time"
1013

1114
"github.com/YakDriver/smarterr"
1215
"github.com/aws/aws-sdk-go-v2/aws"
16+
"github.com/aws/aws-sdk-go-v2/aws/arn"
1317
"github.com/aws/aws-sdk-go-v2/service/lambda"
1418
awstypes "github.com/aws/aws-sdk-go-v2/service/lambda/types"
1519
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
1620
"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
21+
"github.com/hashicorp/terraform-plugin-framework/diag"
22+
"github.com/hashicorp/terraform-plugin-framework/list"
23+
listschema "github.com/hashicorp/terraform-plugin-framework/list/schema"
1724
"github.com/hashicorp/terraform-plugin-framework/path"
1825
"github.com/hashicorp/terraform-plugin-framework/resource"
1926
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
@@ -30,6 +37,7 @@ import (
3037
"github.com/hashicorp/terraform-provider-aws/internal/framework"
3138
"github.com/hashicorp/terraform-provider-aws/internal/framework/flex"
3239
fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types"
40+
"github.com/hashicorp/terraform-provider-aws/internal/provider/framework/listresource"
3341
"github.com/hashicorp/terraform-provider-aws/internal/retry"
3442
"github.com/hashicorp/terraform-provider-aws/internal/smerr"
3543
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
@@ -54,6 +62,11 @@ func newResourceCapacityProvider(_ context.Context) (resource.ResourceWithConfig
5462
return r, nil
5563
}
5664

65+
// @FrameworkListResource("aws_lambda_capacity_provider")
66+
func capacityProviderResourceAsListResource() list.ListResourceWithConfigure {
67+
return &resourceCapacityProvider{}
68+
}
69+
5770
const (
5871
capacityProviderNamePrefix = "CapacityProvider"
5972
ResNameCapacityProvider = "Capacity Provider"
@@ -63,6 +76,7 @@ type resourceCapacityProvider struct {
6376
framework.ResourceWithModel[resourceCapacityProviderModel]
6477
framework.WithTimeouts
6578
framework.WithImportByIdentity
79+
framework.WithList
6680
}
6781

6882
func (r *resourceCapacityProvider) Schema(ctx context.Context, _ resource.SchemaRequest, response *resource.SchemaResponse) {
@@ -460,3 +474,133 @@ type scalingPoliciesModel struct {
460474
PredefinedMetricType fwtypes.StringEnum[awstypes.CapacityProviderPredefinedMetricType] `tfsdk:"predefined_metric_type"`
461475
TargetValue types.Float64 `tfsdk:"target_value"`
462476
}
477+
478+
var _ list.ListResource = &resourceCapacityProvider{}
479+
480+
func listCapacityProviders(ctx context.Context, conn *lambda.Client, input *lambda.ListCapacityProvidersInput) iter.Seq2[awstypes.CapacityProvider, error] {
481+
return func(yield func(awstypes.CapacityProvider, error) bool) {
482+
pages := lambda.NewListCapacityProvidersPaginator(conn, input)
483+
for pages.HasMorePages() {
484+
page, err := pages.NextPage(ctx)
485+
if err != nil {
486+
yield(awstypes.CapacityProvider{}, fmt.Errorf("listing Lambda Capacity Providers: %w", err))
487+
return
488+
}
489+
490+
for _, cp := range page.CapacityProviders {
491+
if !yield(cp, nil) {
492+
return
493+
}
494+
}
495+
}
496+
}
497+
}
498+
499+
func (r *resourceCapacityProvider) ListResourceConfigSchema(ctx context.Context, _ list.ListResourceSchemaRequest, response *list.ListResourceSchemaResponse) {
500+
response.Schema = listschema.Schema{
501+
Attributes: map[string]listschema.Attribute{},
502+
}
503+
}
504+
505+
func (r *resourceCapacityProvider) List(ctx context.Context, request list.ListRequest, stream *list.ListResultsStream) {
506+
var query capacityProviderListModel
507+
508+
if request.Config.Raw.IsKnown() && !request.Config.Raw.IsNull() {
509+
if diags := request.Config.Get(ctx, &query); diags.HasError() {
510+
stream.Results = list.ListResultsStreamDiagnostics(diags)
511+
return
512+
}
513+
}
514+
515+
awsClient := r.Meta()
516+
conn := awsClient.LambdaClient(ctx)
517+
518+
stream.Results = func(yield func(list.ListResult) bool) {
519+
result := request.NewListResult(ctx)
520+
var input lambda.ListCapacityProvidersInput
521+
for capacityProvider, err := range listCapacityProviders(ctx, conn, &input) {
522+
if err != nil {
523+
result = list.ListResult{
524+
Diagnostics: diag.Diagnostics{
525+
diag.NewErrorDiagnostic(
526+
"Error Listing Remote Resources",
527+
fmt.Sprintf("Error: %s", err),
528+
),
529+
},
530+
}
531+
yield(result)
532+
return
533+
}
534+
535+
ctx = tftags.NewContext(ctx, awsClient.DefaultTagsConfig(ctx), awsClient.IgnoreTagsConfig(ctx), awsClient.TagPolicyConfig(ctx))
536+
var data resourceCapacityProviderModel
537+
timeoutObject, d := r.ListResourceTimeoutInit(ctx, result)
538+
result.Diagnostics.Append(d...)
539+
if result.Diagnostics.HasError() {
540+
result = list.ListResult{Diagnostics: result.Diagnostics}
541+
yield(result)
542+
return
543+
}
544+
545+
data.Timeouts.Object = timeoutObject
546+
data.Tags.MapValue = r.ListResourceTagsInit(ctx, result)
547+
data.TagsAll.MapValue = r.ListResourceTagsInit(ctx, result)
548+
549+
params := listresource.InterceptorParams{
550+
C: awsClient,
551+
Result: &result,
552+
}
553+
554+
if diags := r.RunResultInterceptors(ctx, listresource.Before, params); diags.HasError() {
555+
result.Diagnostics.Append(diags...)
556+
yield(result)
557+
return
558+
}
559+
560+
if diags := flex.Flatten(ctx, capacityProvider, &data, flex.WithFieldNamePrefix(capacityProviderNamePrefix)); diags.HasError() {
561+
result.Diagnostics.Append(diags...)
562+
yield(result)
563+
return
564+
}
565+
566+
cpARN, err := arn.Parse(data.ARN.ValueString())
567+
if err != nil {
568+
result = list.ListResult{
569+
Diagnostics: diag.Diagnostics{
570+
diag.NewErrorDiagnostic(
571+
"Error Listing Remote Resources",
572+
fmt.Sprintf("Error: %s", err),
573+
),
574+
},
575+
}
576+
yield(result)
577+
return
578+
}
579+
580+
name := strings.TrimPrefix(cpARN.Resource, "capacity-provider:")
581+
data.Name = flex.StringValueToFramework(ctx, name)
582+
583+
if diags := result.Resource.Set(ctx, &data); diags.HasError() {
584+
result.Diagnostics.Append(diags...)
585+
yield(result)
586+
return
587+
}
588+
589+
result.DisplayName = name
590+
591+
if diags := r.RunResultInterceptors(ctx, listresource.After, params); diags.HasError() {
592+
result.Diagnostics.Append(diags...)
593+
yield(result)
594+
return
595+
}
596+
597+
if !yield(result) {
598+
return
599+
}
600+
}
601+
}
602+
}
603+
604+
type capacityProviderListModel struct {
605+
framework.WithRegionModel
606+
}

0 commit comments

Comments
 (0)