From 73afde8cae239648918cdff707e705f5b749bf39 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 14 Apr 2024 16:42:24 -0400 Subject: [PATCH 01/35] Use AWS SDK for Go v2 for events service. --- names/data/names_data.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/names/data/names_data.csv b/names/data/names_data.csv index 08754f2f0c8..6368a1fb2b0 100644 --- a/names/data/names_data.csv +++ b/names/data/names_data.csv @@ -159,7 +159,7 @@ emr,emr,emr,emr,,emr,,,EMR,EMR,,1,2,,aws_emr_,,emr_,EMR,Amazon,,,,,,,EMR,ListClu emr-containers,emrcontainers,emrcontainers,emrcontainers,,emrcontainers,,,EMRContainers,EMRContainers,,1,,,aws_emrcontainers_,,emrcontainers_,EMR Containers,Amazon,,,,,,,EMR containers,ListVirtualClusters,, emr-serverless,emrserverless,emrserverless,emrserverless,,emrserverless,,,EMRServerless,EMRServerless,,,2,,aws_emrserverless_,,emrserverless_,EMR Serverless,Amazon,,,,,,,EMR Serverless,ListApplications,, ,,,,,,,,,,,,,,,,,End-of-Support Migration Program (EMP) for Windows Server,AWS,x,,,,,,,,,No SDK support -events,events,eventbridge,eventbridge,,events,,eventbridge;cloudwatchevents,Events,EventBridge,,1,,aws_cloudwatch_event_,aws_events_,,cloudwatch_event_,EventBridge,Amazon,,,,,,,EventBridge,ListEventBuses,, +events,events,eventbridge,eventbridge,,events,,eventbridge;cloudwatchevents,Events,EventBridge,,,2,aws_cloudwatch_event_,aws_events_,,cloudwatch_event_,EventBridge,Amazon,,,,,,,EventBridge,ListEventBuses,, schemas,schemas,schemas,schemas,,schemas,,,Schemas,Schemas,,1,,,aws_schemas_,,schemas_,EventBridge Schemas,Amazon,,,,,,,schemas,ListRegistries,, fis,fis,fis,fis,,fis,,,FIS,FIS,,,2,,aws_fis_,,fis_,FIS (Fault Injection Simulator),AWS,,,,,,,fis,ListExperiments,, finspace,finspace,finspace,finspace,,finspace,,,FinSpace,Finspace,,,2,,aws_finspace_,,finspace_,FinSpace,Amazon,,,,,,,finspace,ListEnvironments,, From 1a534f573620c6c8a8e0054cc6c9d1c931198773 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 14 Apr 2024 16:46:03 -0400 Subject: [PATCH 02/35] Add 'names.EventsEndpointID'. --- names/names.go | 1 + 1 file changed, 1 insertion(+) diff --git a/names/names.go b/names/names.go index 2f0d70adf6e..19abeef4483 100644 --- a/names/names.go +++ b/names/names.go @@ -54,6 +54,7 @@ const ( ECREndpointID = "api.ecr" EKSEndpointID = "eks" EMREndpointID = "elasticmapreduce" + EventsEndpointID = "events" EvidentlyEndpointID = "evidently" FMSEndpointID = "fms" IdentityStoreEndpointID = "identitystore" From d76b166d29c4d95065b717c28a9c6f5b849098d0 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 14 Apr 2024 16:48:11 -0400 Subject: [PATCH 03/35] events: Generate AWS SDK for Go v2 tagging code. --- internal/service/events/generate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/events/generate.go b/internal/service/events/generate.go index 9861732aef1..d193e6abab0 100644 --- a/internal/service/events/generate.go +++ b/internal/service/events/generate.go @@ -2,7 +2,7 @@ // SPDX-License-Identifier: MPL-2.0 //go:generate go run ../../generate/listpages/main.go -ListOps=ListEventBuses,ListRules,ListTargetsByRule -//go:generate go run ../../generate/tags/main.go -ListTags -ListTagsInIDElem=ResourceARN -ServiceTagsSlice -TagInIDElem=ResourceARN -UpdateTags -CreateTags +//go:generate go run ../../generate/tags/main.go -AWSSDKVersion=2 -ListTags -ListTagsInIDElem=ResourceARN -ServiceTagsSlice -TagInIDElem=ResourceARN -UpdateTags -CreateTags //go:generate go run ../../generate/servicepackage/main.go // ONLY generate directives and package declaration! Do not add anything else to this file. From 0c04edb546a7beeaf9d8e54201be177d302d779a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 14 Apr 2024 16:49:19 -0400 Subject: [PATCH 04/35] Run 'make gen'. --- internal/conns/awsclient_gen.go | 6 +-- .../events/service_endpoints_gen_test.go | 40 ++++++++++++------- .../service/events/service_package_gen.go | 17 ++++---- internal/service/events/tags_gen.go | 38 +++++++++--------- 4 files changed, 57 insertions(+), 44 deletions(-) diff --git a/internal/conns/awsclient_gen.go b/internal/conns/awsclient_gen.go index 5214e62945a..ad4fe435f1b 100644 --- a/internal/conns/awsclient_gen.go +++ b/internal/conns/awsclient_gen.go @@ -74,6 +74,7 @@ import ( elasticloadbalancingv2_sdkv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" emr_sdkv2 "github.com/aws/aws-sdk-go-v2/service/emr" emrserverless_sdkv2 "github.com/aws/aws-sdk-go-v2/service/emrserverless" + eventbridge_sdkv2 "github.com/aws/aws-sdk-go-v2/service/eventbridge" evidently_sdkv2 "github.com/aws/aws-sdk-go-v2/service/evidently" finspace_sdkv2 "github.com/aws/aws-sdk-go-v2/service/finspace" firehose_sdkv2 "github.com/aws/aws-sdk-go-v2/service/firehose" @@ -192,7 +193,6 @@ import ( elbv2_sdkv1 "github.com/aws/aws-sdk-go/service/elbv2" emr_sdkv1 "github.com/aws/aws-sdk-go/service/emr" emrcontainers_sdkv1 "github.com/aws/aws-sdk-go/service/emrcontainers" - eventbridge_sdkv1 "github.com/aws/aws-sdk-go/service/eventbridge" fsx_sdkv1 "github.com/aws/aws-sdk-go/service/fsx" gamelift_sdkv1 "github.com/aws/aws-sdk-go/service/gamelift" globalaccelerator_sdkv1 "github.com/aws/aws-sdk-go/service/globalaccelerator" @@ -662,8 +662,8 @@ func (c *AWSClient) ElasticsearchConn(ctx context.Context) *elasticsearchservice return errs.Must(conn[*elasticsearchservice_sdkv1.ElasticsearchService](ctx, c, names.Elasticsearch, make(map[string]any))) } -func (c *AWSClient) EventsConn(ctx context.Context) *eventbridge_sdkv1.EventBridge { - return errs.Must(conn[*eventbridge_sdkv1.EventBridge](ctx, c, names.Events, make(map[string]any))) +func (c *AWSClient) EventsClient(ctx context.Context) *eventbridge_sdkv2.Client { + return errs.Must(client[*eventbridge_sdkv2.Client](ctx, c, names.Events, make(map[string]any))) } func (c *AWSClient) EvidentlyClient(ctx context.Context) *evidently_sdkv2.Client { diff --git a/internal/service/events/service_endpoints_gen_test.go b/internal/service/events/service_endpoints_gen_test.go index 693ac79c339..eb4bdfeefb8 100644 --- a/internal/service/events/service_endpoints_gen_test.go +++ b/internal/service/events/service_endpoints_gen_test.go @@ -4,17 +4,17 @@ package events_test import ( "context" + "errors" "fmt" "maps" - "net/url" "os" "path/filepath" "reflect" "strings" "testing" - "github.com/aws/aws-sdk-go/aws/endpoints" - eventbridge_sdkv1 "github.com/aws/aws-sdk-go/service/eventbridge" + aws_sdkv2 "github.com/aws/aws-sdk-go-v2/aws" + eventbridge_sdkv2 "github.com/aws/aws-sdk-go-v2/service/eventbridge" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "github.com/google/go-cmp/cmp" @@ -325,32 +325,42 @@ func TestEndpointConfiguration(t *testing.T) { //nolint:paralleltest // uses t.S } func defaultEndpoint(region string) string { - r := endpoints.DefaultResolver() + r := eventbridge_sdkv2.NewDefaultEndpointResolverV2() - ep, err := r.EndpointFor(eventbridge_sdkv1.EndpointsID, region) + ep, err := r.ResolveEndpoint(context.Background(), eventbridge_sdkv2.EndpointParameters{ + Region: aws_sdkv2.String(region), + }) if err != nil { return err.Error() } - url, _ := url.Parse(ep.URL) - - if url.Path == "" { - url.Path = "/" + if ep.URI.Path == "" { + ep.URI.Path = "/" } - return url.String() + return ep.URI.String() } func callService(ctx context.Context, t *testing.T, meta *conns.AWSClient) string { t.Helper() - client := meta.EventsConn(ctx) - - req, _ := client.ListEventBusesRequest(&eventbridge_sdkv1.ListEventBusesInput{}) + var endpoint string - req.HTTPRequest.URL.Path = "/" + client := meta.EventsClient(ctx) - endpoint := req.HTTPRequest.URL.String() + _, err := client.ListEventBuses(ctx, &eventbridge_sdkv2.ListEventBusesInput{}, + func(opts *eventbridge_sdkv2.Options) { + opts.APIOptions = append(opts.APIOptions, + addRetrieveEndpointURLMiddleware(t, &endpoint), + addCancelRequestMiddleware(), + ) + }, + ) + if err == nil { + t.Fatal("Expected an error, got none") + } else if !errors.Is(err, errCancelOperation) { + t.Fatalf("Unexpected error: %s", err) + } return endpoint } diff --git a/internal/service/events/service_package_gen.go b/internal/service/events/service_package_gen.go index 727fc83c172..331b2fb1b5e 100644 --- a/internal/service/events/service_package_gen.go +++ b/internal/service/events/service_package_gen.go @@ -5,9 +5,8 @@ package events import ( "context" - aws_sdkv1 "github.com/aws/aws-sdk-go/aws" - session_sdkv1 "github.com/aws/aws-sdk-go/aws/session" - eventbridge_sdkv1 "github.com/aws/aws-sdk-go/service/eventbridge" + aws_sdkv2 "github.com/aws/aws-sdk-go-v2/aws" + eventbridge_sdkv2 "github.com/aws/aws-sdk-go-v2/service/eventbridge" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/types" "github.com/hashicorp/terraform-provider-aws/names" @@ -94,11 +93,15 @@ func (p *servicePackage) ServicePackageName() string { return names.Events } -// NewConn returns a new AWS SDK for Go v1 client for this service package's AWS API. -func (p *servicePackage) NewConn(ctx context.Context, config map[string]any) (*eventbridge_sdkv1.EventBridge, error) { - sess := config["session"].(*session_sdkv1.Session) +// NewClient returns a new AWS SDK for Go v2 client for this service package's AWS API. +func (p *servicePackage) NewClient(ctx context.Context, config map[string]any) (*eventbridge_sdkv2.Client, error) { + cfg := *(config["aws_sdkv2_config"].(*aws_sdkv2.Config)) - return eventbridge_sdkv1.New(sess.Copy(&aws_sdkv1.Config{Endpoint: aws_sdkv1.String(config["endpoint"].(string))})), nil + return eventbridge_sdkv2.NewFromConfig(cfg, func(o *eventbridge_sdkv2.Options) { + if endpoint := config["endpoint"].(string); endpoint != "" { + o.BaseEndpoint = aws_sdkv2.String(endpoint) + } + }), nil } func ServicePackage(ctx context.Context) conns.ServicePackage { diff --git a/internal/service/events/tags_gen.go b/internal/service/events/tags_gen.go index a8cc8785ab4..844769c9461 100644 --- a/internal/service/events/tags_gen.go +++ b/internal/service/events/tags_gen.go @@ -5,9 +5,9 @@ import ( "context" "fmt" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/aws/aws-sdk-go/service/eventbridge/eventbridgeiface" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" + awstypes "github.com/aws/aws-sdk-go-v2/service/eventbridge/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/logging" @@ -19,12 +19,12 @@ import ( // listTags lists events service tags. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. -func listTags(ctx context.Context, conn eventbridgeiface.EventBridgeAPI, identifier string) (tftags.KeyValueTags, error) { +func listTags(ctx context.Context, conn *eventbridge.Client, identifier string, optFns ...func(*eventbridge.Options)) (tftags.KeyValueTags, error) { input := &eventbridge.ListTagsForResourceInput{ ResourceARN: aws.String(identifier), } - output, err := conn.ListTagsForResourceWithContext(ctx, input) + output, err := conn.ListTagsForResource(ctx, input, optFns...) if err != nil { return tftags.New(ctx, nil), err @@ -36,7 +36,7 @@ func listTags(ctx context.Context, conn eventbridgeiface.EventBridgeAPI, identif // ListTags lists events service tags and set them in Context. // It is called from outside this package. func (p *servicePackage) ListTags(ctx context.Context, meta any, identifier string) error { - tags, err := listTags(ctx, meta.(*conns.AWSClient).EventsConn(ctx), identifier) + tags, err := listTags(ctx, meta.(*conns.AWSClient).EventsClient(ctx), identifier) if err != nil { return err @@ -52,11 +52,11 @@ func (p *servicePackage) ListTags(ctx context.Context, meta any, identifier stri // []*SERVICE.Tag handling // Tags returns events service tags. -func Tags(tags tftags.KeyValueTags) []*eventbridge.Tag { - result := make([]*eventbridge.Tag, 0, len(tags)) +func Tags(tags tftags.KeyValueTags) []awstypes.Tag { + result := make([]awstypes.Tag, 0, len(tags)) for k, v := range tags.Map() { - tag := &eventbridge.Tag{ + tag := awstypes.Tag{ Key: aws.String(k), Value: aws.String(v), } @@ -68,11 +68,11 @@ func Tags(tags tftags.KeyValueTags) []*eventbridge.Tag { } // KeyValueTags creates tftags.KeyValueTags from eventbridge service tags. -func KeyValueTags(ctx context.Context, tags []*eventbridge.Tag) tftags.KeyValueTags { +func KeyValueTags(ctx context.Context, tags []awstypes.Tag) tftags.KeyValueTags { m := make(map[string]*string, len(tags)) for _, tag := range tags { - m[aws.StringValue(tag.Key)] = tag.Value + m[aws.ToString(tag.Key)] = tag.Value } return tftags.New(ctx, m) @@ -80,7 +80,7 @@ func KeyValueTags(ctx context.Context, tags []*eventbridge.Tag) tftags.KeyValueT // getTagsIn returns events service tags from Context. // nil is returned if there are no input tags. -func getTagsIn(ctx context.Context) []*eventbridge.Tag { +func getTagsIn(ctx context.Context) []awstypes.Tag { if inContext, ok := tftags.FromContext(ctx); ok { if tags := Tags(inContext.TagsIn.UnwrapOrDefault()); len(tags) > 0 { return tags @@ -91,14 +91,14 @@ func getTagsIn(ctx context.Context) []*eventbridge.Tag { } // setTagsOut sets events service tags in Context. -func setTagsOut(ctx context.Context, tags []*eventbridge.Tag) { +func setTagsOut(ctx context.Context, tags []awstypes.Tag) { if inContext, ok := tftags.FromContext(ctx); ok { inContext.TagsOut = option.Some(KeyValueTags(ctx, tags)) } } // createTags creates events service tags for new resources. -func createTags(ctx context.Context, conn eventbridgeiface.EventBridgeAPI, identifier string, tags []*eventbridge.Tag) error { +func createTags(ctx context.Context, conn *eventbridge.Client, identifier string, tags []awstypes.Tag) error { if len(tags) == 0 { return nil } @@ -109,7 +109,7 @@ func createTags(ctx context.Context, conn eventbridgeiface.EventBridgeAPI, ident // updateTags updates events service tags. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. -func updateTags(ctx context.Context, conn eventbridgeiface.EventBridgeAPI, identifier string, oldTagsMap, newTagsMap any) error { +func updateTags(ctx context.Context, conn *eventbridge.Client, identifier string, oldTagsMap, newTagsMap any, optFns ...func(*eventbridge.Options)) error { oldTags := tftags.New(ctx, oldTagsMap) newTags := tftags.New(ctx, newTagsMap) @@ -120,10 +120,10 @@ func updateTags(ctx context.Context, conn eventbridgeiface.EventBridgeAPI, ident if len(removedTags) > 0 { input := &eventbridge.UntagResourceInput{ ResourceARN: aws.String(identifier), - TagKeys: aws.StringSlice(removedTags.Keys()), + TagKeys: removedTags.Keys(), } - _, err := conn.UntagResourceWithContext(ctx, input) + _, err := conn.UntagResource(ctx, input, optFns...) if err != nil { return fmt.Errorf("untagging resource (%s): %w", identifier, err) @@ -138,7 +138,7 @@ func updateTags(ctx context.Context, conn eventbridgeiface.EventBridgeAPI, ident Tags: Tags(updatedTags), } - _, err := conn.TagResourceWithContext(ctx, input) + _, err := conn.TagResource(ctx, input, optFns...) if err != nil { return fmt.Errorf("tagging resource (%s): %w", identifier, err) @@ -151,5 +151,5 @@ func updateTags(ctx context.Context, conn eventbridgeiface.EventBridgeAPI, ident // UpdateTags updates events service tags. // It is called from outside this package. func (p *servicePackage) UpdateTags(ctx context.Context, meta any, identifier string, oldTags, newTags any) error { - return updateTags(ctx, meta.(*conns.AWSClient).EventsConn(ctx), identifier, oldTags, newTags) + return updateTags(ctx, meta.(*conns.AWSClient).EventsClient(ctx), identifier, oldTags, newTags) } From 107633bab67f931d4bf04dd7ef649cfc0eb4ae13 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 14 Apr 2024 16:50:16 -0400 Subject: [PATCH 05/35] Run 'go get github.com/aws/aws-sdk-go-v2/service/eventbridge@v1.30.4 && go mod tidy'. --- go.mod | 1 + go.sum | 2 ++ 2 files changed, 3 insertions(+) diff --git a/go.mod b/go.mod index 64a42634b0e..be7281d3e88 100644 --- a/go.mod +++ b/go.mod @@ -82,6 +82,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.30.5 github.com/aws/aws-sdk-go-v2/service/emr v1.39.5 github.com/aws/aws-sdk-go-v2/service/emrserverless v1.17.5 + github.com/aws/aws-sdk-go-v2/service/eventbridge v1.30.4 github.com/aws/aws-sdk-go-v2/service/evidently v1.19.4 github.com/aws/aws-sdk-go-v2/service/finspace v1.24.1 github.com/aws/aws-sdk-go-v2/service/firehose v1.28.5 diff --git a/go.sum b/go.sum index 1a1a3893f19..b5a4a5fa465 100644 --- a/go.sum +++ b/go.sum @@ -184,6 +184,8 @@ github.com/aws/aws-sdk-go-v2/service/emr v1.39.5 h1:ni+E9GfbQ8CzjYSlJ+WbNYX7SAsL github.com/aws/aws-sdk-go-v2/service/emr v1.39.5/go.mod h1:7WusX+O5pwTnx2yobUO/P1C5HlBibmrQb5gKEPFjTYM= github.com/aws/aws-sdk-go-v2/service/emrserverless v1.17.5 h1:w7hZ1/CRiKvzAtkzlv7tcP/wqxh9kdm5nWj4fq6/+RE= github.com/aws/aws-sdk-go-v2/service/emrserverless v1.17.5/go.mod h1:TZrahLcSXIN/kO96kvxUzfLNLH8E6t3xodv8Zv5DHGs= +github.com/aws/aws-sdk-go-v2/service/eventbridge v1.30.4 h1:Vz4ilZcVXCR9yatX5yfMrkBldYggtkih3h7woHvzu5Q= +github.com/aws/aws-sdk-go-v2/service/eventbridge v1.30.4/go.mod h1:aIINXlt2xXhMeRsyCsLDUDohI8AdDm92gY9nIB6pv0M= github.com/aws/aws-sdk-go-v2/service/evidently v1.19.4 h1:DcRQTdvIQs+v+rQJ598v7WmgLSsla9C90mY4J+rccrU= github.com/aws/aws-sdk-go-v2/service/evidently v1.19.4/go.mod h1:ajhW/0n1t1jQKd2Kn46/99wcMj41TSPBJ3vSWocTvdE= github.com/aws/aws-sdk-go-v2/service/finspace v1.24.1 h1:1syXGgya/121hPyOlzi4RvV1lrtIGEHLlrYUiRsZbXo= From bb3be8104dbee5b3765d879162355aec67525482 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 14 Apr 2024 17:08:48 -0400 Subject: [PATCH 06/35] r/aws_cloudwatch_event_api_destination: Migrate to AWS SDK for Go v2. --- internal/service/events/api_destination.go | 186 ++++++++++-------- .../service/events/api_destination_test.go | 49 +++-- internal/service/events/exports_test.go | 11 ++ .../service/events/service_package_gen.go | 3 +- 4 files changed, 140 insertions(+), 109 deletions(-) create mode 100644 internal/service/events/exports_test.go diff --git a/internal/service/events/api_destination.go b/internal/service/events/api_destination.go index 33f9a8ecfcb..ae82ccc6f91 100644 --- a/internal/service/events/api_destination.go +++ b/internal/service/events/api_destination.go @@ -8,43 +8,53 @@ import ( "log" "github.com/YakDriver/regexache" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/service/eventbridge/types" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/enum" + "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/internal/verify" ) -// @SDKResource("aws_cloudwatch_event_api_destination") -func ResourceAPIDestination() *schema.Resource { +// @SDKResource("aws_cloudwatch_event_api_destination", name="API Destination") +func resourceAPIDestination() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceAPIDestinationCreate, ReadWithoutTimeout: resourceAPIDestinationRead, UpdateWithoutTimeout: resourceAPIDestinationUpdate, DeleteWithoutTimeout: resourceAPIDestinationDelete, + Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, Schema: map[string]*schema.Schema{ - "name": { + "arn": { Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.All( - validation.StringLenBetween(1, 64), - validation.StringMatch(regexache.MustCompile(`^[0-9A-Za-z_.-]+`), ""), - ), + Computed: true, + }, + "connection_arn": { + Type: schema.TypeString, + Required: true, + ValidateFunc: verify.ValidARN, }, "description": { Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringLenBetween(0, 512), }, + "http_method": { + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: enum.Validate[types.ApiDestinationHttpMethod](), + }, "invocation_endpoint": { Type: schema.TypeString, Required: true, @@ -55,19 +65,14 @@ func ResourceAPIDestination() *schema.Resource { ValidateFunc: validation.IntAtLeast(1), Default: 300, }, - "http_method": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice(eventbridge.ApiDestinationHttpMethod_Values(), true), - }, - "connection_arn": { - Type: schema.TypeString, - Required: true, - ValidateFunc: verify.ValidARN, - }, - "arn": { + "name": { Type: schema.TypeString, - Computed: true, + Required: true, + ForceNew: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 64), + validation.StringMatch(regexache.MustCompile(`^[0-9A-Za-z_.-]+`), ""), + ), }, }, } @@ -75,122 +80,137 @@ func ResourceAPIDestination() *schema.Resource { func resourceAPIDestinationCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - input := &eventbridge.CreateApiDestinationInput{} - - if name, ok := d.GetOk("name"); ok { - input.Name = aws.String(name.(string)) - } - if description, ok := d.GetOk("description"); ok { - input.Description = aws.String(description.(string)) + name := d.Get("name").(string) + input := &eventbridge.CreateApiDestinationInput{ + ConnectionArn: aws.String(d.Get("connection_arn").(string)), + HttpMethod: types.ApiDestinationHttpMethod(d.Get("http_method").(string)), + Name: aws.String(name), } - if invocationEndpoint, ok := d.GetOk("invocation_endpoint"); ok { - input.InvocationEndpoint = aws.String(invocationEndpoint.(string)) - } - if invocationRateLimitPerSecond, ok := d.GetOk("invocation_rate_limit_per_second"); ok { - input.InvocationRateLimitPerSecond = aws.Int64(int64(invocationRateLimitPerSecond.(int))) + + if v, ok := d.GetOk("description"); ok { + input.Description = aws.String(v.(string)) } - if httpMethod, ok := d.GetOk("http_method"); ok { - input.HttpMethod = aws.String(httpMethod.(string)) + + if v, ok := d.GetOk("invocation_endpoint"); ok { + input.InvocationEndpoint = aws.String(v.(string)) } - if connectionArn, ok := d.GetOk("connection_arn"); ok { - input.ConnectionArn = aws.String(connectionArn.(string)) + + if v, ok := d.GetOk("invocation_rate_limit_per_second"); ok { + input.InvocationRateLimitPerSecond = aws.Int32(int32(v.(int))) } - _, err := conn.CreateApiDestinationWithContext(ctx, input) + _, err := conn.CreateApiDestination(ctx, input) + if err != nil { - return sdkdiag.AppendErrorf(diags, "Creating EventBridge API Destination (%s) failed: %s", aws.StringValue(input.Name), err) + return sdkdiag.AppendErrorf(diags, "creating EventBridge API Destination (%s): %s", name, err) } - d.SetId(aws.StringValue(input.Name)) - - log.Printf("[INFO] EventBridge API Destination (%s) created", d.Id()) + d.SetId(name) return append(diags, resourceAPIDestinationRead(ctx, d, meta)...) } func resourceAPIDestinationRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - input := &eventbridge.DescribeApiDestinationInput{ - Name: aws.String(d.Id()), - } + output, err := findAPIDestinationByName(ctx, conn, d.Id()) - output, err := conn.DescribeApiDestinationWithContext(ctx, input) - if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { + if !d.IsNewResource() && tfresource.NotFound(err) { log.Printf("[WARN] EventBridge API Destination (%s) not found, removing from state", d.Id()) d.SetId("") return diags } + if err != nil { return sdkdiag.AppendErrorf(diags, "reading EventBridge API Destination (%s): %s", d.Id(), err) } d.Set("arn", output.ApiDestinationArn) - d.Set("name", output.Name) + d.Set("connection_arn", output.ConnectionArn) d.Set("description", output.Description) + d.Set("http_method", output.HttpMethod) d.Set("invocation_endpoint", output.InvocationEndpoint) d.Set("invocation_rate_limit_per_second", output.InvocationRateLimitPerSecond) - d.Set("http_method", output.HttpMethod) - d.Set("connection_arn", output.ConnectionArn) + d.Set("name", output.Name) return diags } func resourceAPIDestinationUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) - - input := &eventbridge.UpdateApiDestinationInput{} + conn := meta.(*conns.AWSClient).EventsClient(ctx) - if name, ok := d.GetOk("name"); ok { - input.Name = aws.String(name.(string)) + input := &eventbridge.UpdateApiDestinationInput{ + ConnectionArn: aws.String(d.Get("connection_arn").(string)), + HttpMethod: types.ApiDestinationHttpMethod(d.Get("http_method").(string)), + Name: aws.String(d.Id()), } - if description, ok := d.GetOk("description"); ok { - input.Description = aws.String(description.(string)) - } - if invocationEndpoint, ok := d.GetOk("invocation_endpoint"); ok { - input.InvocationEndpoint = aws.String(invocationEndpoint.(string)) - } - if invocationRateLimitPerSecond, ok := d.GetOk("invocation_rate_limit_per_second"); ok { - input.InvocationRateLimitPerSecond = aws.Int64(int64(invocationRateLimitPerSecond.(int))) + + if v, ok := d.GetOk("description"); ok { + input.Description = aws.String(v.(string)) } - if httpMethod, ok := d.GetOk("http_method"); ok { - input.HttpMethod = aws.String(httpMethod.(string)) + + if v, ok := d.GetOk("invocation_endpoint"); ok { + input.InvocationEndpoint = aws.String(v.(string)) } - if connectionArn, ok := d.GetOk("connection_arn"); ok { - input.ConnectionArn = aws.String(connectionArn.(string)) + + if v, ok := d.GetOk("invocation_rate_limit_per_second"); ok { + input.InvocationRateLimitPerSecond = aws.Int32(int32(v.(int))) } - log.Printf("[DEBUG] Updating EventBridge API Destination: %s", input) - _, err := conn.UpdateApiDestinationWithContext(ctx, input) + _, err := conn.UpdateApiDestination(ctx, input) + if err != nil { return sdkdiag.AppendErrorf(diags, "updating EventBridge API Destination (%s): %s", d.Id(), err) } + return append(diags, resourceAPIDestinationRead(ctx, d, meta)...) } func resourceAPIDestinationDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - log.Printf("[INFO] Deleting EventBridge API Destination (%s)", d.Id()) - input := &eventbridge.DeleteApiDestinationInput{ + log.Printf("[INFO] Deleting EventBridge API Destination: %s", d.Id()) + _, err := conn.DeleteApiDestination(ctx, &eventbridge.DeleteApiDestinationInput{ Name: aws.String(d.Id()), - } - - _, err := conn.DeleteApiDestinationWithContext(ctx, input) + }) - if tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { - log.Printf("[WARN] EventBridge API Destination (%s) not found", d.Id()) + if errs.IsA[*types.ResourceNotFoundException](err) { return diags } + if err != nil { return sdkdiag.AppendErrorf(diags, "deleting EventBridge API Destination (%s): %s", d.Id(), err) } - log.Printf("[INFO] EventBridge API Destination (%s) deleted", d.Id()) return diags } + +func findAPIDestinationByName(ctx context.Context, conn *eventbridge.Client, name string) (*eventbridge.DescribeApiDestinationOutput, error) { + input := &eventbridge.DescribeApiDestinationInput{ + Name: aws.String(name), + } + + output, err := conn.DescribeApiDestination(ctx, input) + + if errs.IsA[*types.ResourceNotFoundException](err) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + if output == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + return output, nil +} diff --git a/internal/service/events/api_destination_test.go b/internal/service/events/api_destination_test.go index 36a2c840ab0..64c826d9907 100644 --- a/internal/service/events/api_destination_test.go +++ b/internal/service/events/api_destination_test.go @@ -9,14 +9,15 @@ import ( "testing" "github.com/YakDriver/regexache" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" tfevents "github.com/hashicorp/terraform-provider-aws/internal/service/events" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/names" ) @@ -33,7 +34,7 @@ func TestAccEventsAPIDestination_basic(t *testing.T) { invocationEndpointModified := "https://example.com/modified" httpMethodModified := "POST" - resourceName := "aws_cloudwatch_event_api_destination.basic" + resourceName := "aws_cloudwatch_event_api_destination.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t) }, @@ -107,7 +108,7 @@ func TestAccEventsAPIDestination_optional(t *testing.T) { descriptionModified := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) invocationRateLimitPerSecondModified := 12 - resourceName := "aws_cloudwatch_event_api_destination.optional" + resourceName := "aws_cloudwatch_event_api_destination.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t) }, @@ -184,7 +185,7 @@ func TestAccEventsAPIDestination_disappears(t *testing.T) { invocationEndpoint := "https://example.com/" httpMethod := "GET" - resourceName := "aws_cloudwatch_event_api_destination.basic" + resourceName := "aws_cloudwatch_event_api_destination.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t) }, @@ -210,22 +211,24 @@ func TestAccEventsAPIDestination_disappears(t *testing.T) { func testAccCheckAPIDestinationDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) for _, rs := range s.RootModule().Resources { if rs.Type != "aws_cloudwatch_event_api_destination" { continue } - params := eventbridge.DescribeApiDestinationInput{ - Name: aws.String(rs.Primary.ID), - } + _, err := tfevents.FindAPIDestinationByName(ctx, conn, rs.Primary.ID) - resp, err := conn.DescribeApiDestinationWithContext(ctx, ¶ms) + if tfresource.NotFound(err) { + continue + } - if err == nil { - return fmt.Errorf("EventBridge API Destination (%s) still exists: %s", rs.Primary.ID, resp) + if err != nil { + return err } + + return fmt.Errorf("EventBridge API Destination %s still exists", rs.Primary.ID) } return nil @@ -239,19 +242,15 @@ func testAccCheckAPIDestinationExists(ctx context.Context, n string, v *eventbri return fmt.Errorf("Not found: %s", n) } - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) - params := eventbridge.DescribeApiDestinationInput{ - Name: aws.String(rs.Primary.ID), - } - resp, err := conn.DescribeApiDestinationWithContext(ctx, ¶ms) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) + + output, err := tfevents.FindAPIDestinationByName(ctx, conn, rs.Primary.ID) + if err != nil { return err } - if resp == nil { - return fmt.Errorf("EventBridge API Destination (%s) not found", n) - } - *v = *resp + *v = *output return nil } @@ -259,7 +258,7 @@ func testAccCheckAPIDestinationExists(ctx context.Context, n string, v *eventbri func testAccCheckAPIDestinationRecreated(i, j *eventbridge.DescribeApiDestinationOutput) resource.TestCheckFunc { return func(s *terraform.State) error { - if aws.StringValue(i.ApiDestinationArn) == aws.StringValue(j.ApiDestinationArn) { + if aws.ToString(i.ApiDestinationArn) == aws.ToString(j.ApiDestinationArn) { return fmt.Errorf("EventBridge API Destination not recreated") } return nil @@ -268,7 +267,7 @@ func testAccCheckAPIDestinationRecreated(i, j *eventbridge.DescribeApiDestinatio func testAccCheckAPIDestinationNotRecreated(i, j *eventbridge.DescribeApiDestinationOutput) resource.TestCheckFunc { return func(s *terraform.State) error { - if aws.StringValue(i.ApiDestinationArn) != aws.StringValue(j.ApiDestinationArn) { + if aws.ToString(i.ApiDestinationArn) != aws.ToString(j.ApiDestinationArn) { return fmt.Errorf("EventBridge API Destination was recreated") } return nil @@ -277,7 +276,7 @@ func testAccCheckAPIDestinationNotRecreated(i, j *eventbridge.DescribeApiDestina func testAccAPIDestinationConfig_basic(name, invocationEndpoint, httpMethod string) string { return fmt.Sprintf(` -resource "aws_cloudwatch_event_api_destination" "basic" { +resource "aws_cloudwatch_event_api_destination" "test" { name = %[1]q invocation_endpoint = %[2]q http_method = %[3]q @@ -299,7 +298,7 @@ resource "aws_cloudwatch_event_connection" "test" { func testAccAPIDestinationConfig_optional(name, invocationEndpoint, httpMethod, description string, invocationRateLimitPerSecond int64) string { return fmt.Sprintf(` -resource "aws_cloudwatch_event_api_destination" "optional" { +resource "aws_cloudwatch_event_api_destination" "test" { name = %[1]q invocation_endpoint = %[2]q http_method = %[3]q diff --git a/internal/service/events/exports_test.go b/internal/service/events/exports_test.go new file mode 100644 index 00000000000..dfb76f288bb --- /dev/null +++ b/internal/service/events/exports_test.go @@ -0,0 +1,11 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package events + +// Exports for use in tests only. +var ( + ResourceAPIDestination = resourceAPIDestination + + FindAPIDestinationByName = findAPIDestinationByName +) diff --git a/internal/service/events/service_package_gen.go b/internal/service/events/service_package_gen.go index 331b2fb1b5e..5b61b5b7252 100644 --- a/internal/service/events/service_package_gen.go +++ b/internal/service/events/service_package_gen.go @@ -42,8 +42,9 @@ func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePac func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePackageSDKResource { return []*types.ServicePackageSDKResource{ { - Factory: ResourceAPIDestination, + Factory: resourceAPIDestination, TypeName: "aws_cloudwatch_event_api_destination", + Name: "API Destination", }, { Factory: ResourceArchive, From 052c0e518c8b3d253b25b1d6f816234cf8854229 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 14 Apr 2024 17:24:43 -0400 Subject: [PATCH 07/35] r/aws_cloudwatch_event_archive: Migrate to AWS SDK for Go v2. --- internal/service/events/archive.go | 199 +++++++++--------- internal/service/events/archive_test.go | 34 ++- internal/service/events/exports_test.go | 2 + .../service/events/service_package_gen.go | 3 +- 4 files changed, 120 insertions(+), 118 deletions(-) diff --git a/internal/service/events/archive.go b/internal/service/events/archive.go index cddefc6d559..c1f90cb24e9 100644 --- a/internal/service/events/archive.go +++ b/internal/service/events/archive.go @@ -5,44 +5,39 @@ package events import ( "context" - "fmt" "log" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/service/eventbridge/types" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/internal/verify" ) -// @SDKResource("aws_cloudwatch_event_archive") -func ResourceArchive() *schema.Resource { +// @SDKResource("aws_cloudwatch_event_archive", name="Archive") +func resourceArchive() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceArchiveCreate, ReadWithoutTimeout: resourceArchiveRead, UpdateWithoutTimeout: resourceArchiveUpdate, DeleteWithoutTimeout: resourceArchiveDelete, + Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validArchiveName, - }, - "event_source_arn": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: verify.ValidARN, + "arn": { + Type: schema.TypeString, + Computed: true, }, "description": { Type: schema.TypeString, @@ -58,83 +53,117 @@ func ResourceArchive() *schema.Resource { return json }, }, + "event_source_arn": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: verify.ValidARN, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validArchiveName, + }, "retention_days": { Type: schema.TypeInt, Optional: true, }, - "arn": { - Type: schema.TypeString, - Computed: true, - }, }, } } func resourceArchiveCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - input, err := buildCreateArchiveInputStruct(d) + name := d.Get("name").(string) + input := &eventbridge.CreateArchiveInput{ + ArchiveName: aws.String(name), + EventSourceArn: aws.String(d.Get("event_source_arn").(string)), + } - if err != nil { - return sdkdiag.AppendErrorf(diags, "Creating EventBridge Archive parameters failed: %s", err) + if v, ok := d.GetOk("description"); ok { + input.Description = aws.String(v.(string)) } - log.Printf("[DEBUG] Creating EventBridge Archive: %s", input) + if v, ok := d.GetOk("event_pattern"); ok { + v, err := structure.NormalizeJsonString(v) + if err != nil { + return sdkdiag.AppendFromErr(diags, err) + } - _, err = conn.CreateArchiveWithContext(ctx, input) - if err != nil { - return sdkdiag.AppendErrorf(diags, "Creating EventBridge Archive failed: %s", err) + input.EventPattern = aws.String(v) } - d.SetId(d.Get("name").(string)) + if v, ok := d.GetOk("retention_days"); ok { + input.RetentionDays = aws.Int32(int32(v.(int))) + } - log.Printf("[INFO] EventBridge Archive (%s) created", d.Id()) + _, err := conn.CreateArchive(ctx, input) + + if err != nil { + return sdkdiag.AppendErrorf(diags, "creating EventBridge Archive (%s)): %s", name, err) + } + + d.SetId(name) return append(diags, resourceArchiveRead(ctx, d, meta)...) } func resourceArchiveRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) - input := &eventbridge.DescribeArchiveInput{ - ArchiveName: aws.String(d.Id()), - } + conn := meta.(*conns.AWSClient).EventsClient(ctx) - out, err := conn.DescribeArchiveWithContext(ctx, input) + output, err := findArchiveByName(ctx, conn, d.Id()) - if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { - log.Printf("[WARN] EventBridge archive (%s) not found, removing from state", d.Id()) + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] EventBridge Archive (%s) not found, removing from state", d.Id()) d.SetId("") return diags } if err != nil { - return sdkdiag.AppendErrorf(diags, "reading EventBridge archive (%s): %s", d.Id(), err) + return sdkdiag.AppendErrorf(diags, "reading EventBridge Archive (%s): %s", d.Id(), err) } - d.Set("name", out.ArchiveName) - d.Set("description", out.Description) - d.Set("event_pattern", out.EventPattern) - d.Set("event_source_arn", out.EventSourceArn) - d.Set("arn", out.ArchiveArn) - d.Set("retention_days", out.RetentionDays) + d.Set("arn", output.ArchiveArn) + d.Set("description", output.Description) + d.Set("event_pattern", output.EventPattern) + d.Set("event_source_arn", output.EventSourceArn) + d.Set("name", output.ArchiveName) + d.Set("retention_days", output.RetentionDays) return diags } func resourceArchiveUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - input, err := buildUpdateArchiveInputStruct(d) + input := &eventbridge.UpdateArchiveInput{ + ArchiveName: aws.String(d.Get("name").(string)), + } - if err != nil { - return sdkdiag.AppendErrorf(diags, "Creating EventBridge Archive parameters failed: %s", err) + if v, ok := d.GetOk("description"); ok { + input.Description = aws.String(v.(string)) + } + + if v, ok := d.GetOk("event_pattern"); ok { + v, err := structure.NormalizeJsonString(v) + if err != nil { + return sdkdiag.AppendFromErr(diags, err) + } + + input.EventPattern = aws.String(v) } - log.Printf("[DEBUG] Updating EventBridge Archive: %s", input) - _, err = conn.UpdateArchiveWithContext(ctx, input) + if v, ok := d.GetOk("retention_days"); ok { + input.RetentionDays = aws.Int32(int32(v.(int))) + } + + _, err := conn.UpdateArchive(ctx, input) + if err != nil { return sdkdiag.AppendErrorf(diags, "updating EventBridge Archive (%s): %s", d.Id(), err) } @@ -144,71 +173,45 @@ func resourceArchiveUpdate(ctx context.Context, d *schema.ResourceData, meta int func resourceArchiveDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - input := &eventbridge.DeleteArchiveInput{ - ArchiveName: aws.String(d.Get("name").(string)), + log.Printf("[INFO] Deleting EventBridge Archive: %s", d.Id()) + _, err := conn.DeleteArchive(ctx, &eventbridge.DeleteArchiveInput{ + ArchiveName: aws.String(d.Id()), + }) + + if errs.IsA[*types.ResourceNotFoundException](err) { + return diags } - _, err := conn.DeleteArchiveWithContext(ctx, input) if err != nil { - if tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { - return diags - } return sdkdiag.AppendErrorf(diags, "deleting EventBridge Archive (%s): %s", d.Id(), err) } return diags } -func buildCreateArchiveInputStruct(d *schema.ResourceData) (*eventbridge.CreateArchiveInput, error) { - input := eventbridge.CreateArchiveInput{ - ArchiveName: aws.String(d.Get("name").(string)), - } - - if v, ok := d.GetOk("event_pattern"); ok { - pattern, err := structure.NormalizeJsonString(v) - if err != nil { - return nil, fmt.Errorf("event pattern contains an invalid JSON: %w", err) - } - input.EventPattern = aws.String(pattern) - } - - if v, ok := d.GetOk("description"); ok { - input.Description = aws.String(v.(string)) - } - - if v, ok := d.GetOk("event_source_arn"); ok { - input.EventSourceArn = aws.String(v.(string)) - } - - if v, ok := d.GetOk("retention_days"); ok { - input.RetentionDays = aws.Int64(int64(v.(int))) +func findArchiveByName(ctx context.Context, conn *eventbridge.Client, name string) (*eventbridge.DescribeArchiveOutput, error) { + input := &eventbridge.DescribeArchiveInput{ + ArchiveName: aws.String(name), } - return &input, nil -} - -func buildUpdateArchiveInputStruct(d *schema.ResourceData) (*eventbridge.UpdateArchiveInput, error) { - input := eventbridge.UpdateArchiveInput{ - ArchiveName: aws.String(d.Get("name").(string)), - } + output, err := conn.DescribeArchive(ctx, input) - if v, ok := d.GetOk("event_pattern"); ok { - pattern, err := structure.NormalizeJsonString(v) - if err != nil { - return nil, fmt.Errorf("event pattern contains an invalid JSON: %w", err) + if errs.IsA[*types.ResourceNotFoundException](err) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: input, } - input.EventPattern = aws.String(pattern) } - if v, ok := d.GetOk("description"); ok { - input.Description = aws.String(v.(string)) + if err != nil { + return nil, err } - if v, ok := d.GetOk("retention_days"); ok { - input.RetentionDays = aws.Int64(int64(v.(int))) + if output == nil { + return nil, tfresource.NewEmptyResultError(input) } - return &input, nil + return output, nil } diff --git a/internal/service/events/archive_test.go b/internal/service/events/archive_test.go index 0d278260edd..3544cb01d1c 100644 --- a/internal/service/events/archive_test.go +++ b/internal/service/events/archive_test.go @@ -8,14 +8,14 @@ import ( "fmt" "testing" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" tfevents "github.com/hashicorp/terraform-provider-aws/internal/service/events" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/names" ) @@ -108,22 +108,24 @@ func TestAccEventsArchive_disappears(t *testing.T) { func testAccCheckArchiveDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) for _, rs := range s.RootModule().Resources { if rs.Type != "aws_cloudwatch_event_archive" { continue } - params := eventbridge.DescribeArchiveInput{ - ArchiveName: aws.String(rs.Primary.ID), - } + _, err := tfevents.FindArchiveByName(ctx, conn, rs.Primary.ID) - resp, err := conn.DescribeArchiveWithContext(ctx, ¶ms) + if tfresource.NotFound(err) { + continue + } - if err == nil { - return fmt.Errorf("EventBridge event bus (%s) still exists: %s", rs.Primary.ID, resp) + if err != nil { + return err } + + return fmt.Errorf("EventBridge Archive %s still exists", rs.Primary.ID) } return nil @@ -137,21 +139,15 @@ func testAccCheckArchiveExists(ctx context.Context, n string, v *eventbridge.Des return fmt.Errorf("Not found: %s", n) } - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) - params := eventbridge.DescribeArchiveInput{ - ArchiveName: aws.String(rs.Primary.ID), - } + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) + + output, err := tfevents.FindArchiveByName(ctx, conn, rs.Primary.ID) - resp, err := conn.DescribeArchiveWithContext(ctx, ¶ms) if err != nil { return err } - if resp == nil { - return fmt.Errorf("EventBridge archive (%s) not found", n) - } - - *v = *resp + *v = *output return nil } diff --git a/internal/service/events/exports_test.go b/internal/service/events/exports_test.go index dfb76f288bb..6a3844fdd8a 100644 --- a/internal/service/events/exports_test.go +++ b/internal/service/events/exports_test.go @@ -6,6 +6,8 @@ package events // Exports for use in tests only. var ( ResourceAPIDestination = resourceAPIDestination + ResourceArchive = resourceArchive FindAPIDestinationByName = findAPIDestinationByName + FindArchiveByName = findArchiveByName ) diff --git a/internal/service/events/service_package_gen.go b/internal/service/events/service_package_gen.go index 5b61b5b7252..511ea5bcd41 100644 --- a/internal/service/events/service_package_gen.go +++ b/internal/service/events/service_package_gen.go @@ -47,8 +47,9 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka Name: "API Destination", }, { - Factory: ResourceArchive, + Factory: resourceArchive, TypeName: "aws_cloudwatch_event_archive", + Name: "Archive", }, { Factory: ResourceBus, From 5f254540cc26c2654db8927ebdd7f6aa6968e2e0 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 15 Apr 2024 08:11:22 -0400 Subject: [PATCH 08/35] r/aws_cloudwatch_event_bus: Migrate to AWS SDK for Go v2. --- internal/service/events/bus.go | 36 +++++++++---------- internal/service/events/bus_test.go | 20 +++++------ internal/service/events/exports_test.go | 2 ++ .../service/events/service_package_gen.go | 2 +- 4 files changed, 29 insertions(+), 31 deletions(-) diff --git a/internal/service/events/bus.go b/internal/service/events/bus.go index 1a79ae189e2..f28bd848660 100644 --- a/internal/service/events/bus.go +++ b/internal/service/events/bus.go @@ -7,9 +7,9 @@ import ( "context" "log" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/service/eventbridge/types" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -24,7 +24,7 @@ import ( // @SDKResource("aws_cloudwatch_event_bus", name="Event Bus") // @Tags(identifierAttribute="arn") -func ResourceBus() *schema.Resource { +func resourceBus() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceBusCreate, ReadWithoutTimeout: resourceBusRead, @@ -62,7 +62,7 @@ func ResourceBus() *schema.Resource { func resourceBusCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) eventBusName := d.Get("name").(string) input := &eventbridge.CreateEventBusInput{ @@ -74,13 +74,13 @@ func resourceBusCreate(ctx context.Context, d *schema.ResourceData, meta interfa input.EventSourceName = aws.String(v.(string)) } - output, err := conn.CreateEventBusWithContext(ctx, input) + output, err := conn.CreateEventBus(ctx, input) // Some partitions (e.g. ISO) may not support tag-on-create. - if input.Tags != nil && errs.IsUnsupportedOperationInPartitionError(conn.PartitionID, err) { + if input.Tags != nil && errs.IsUnsupportedOperationInPartitionError(meta.(*conns.AWSClient).Partition, err) { input.Tags = nil - output, err = conn.CreateEventBusWithContext(ctx, input) + output, err = conn.CreateEventBus(ctx, input) } if err != nil { @@ -91,10 +91,10 @@ func resourceBusCreate(ctx context.Context, d *schema.ResourceData, meta interfa // For partitions not supporting tag-on-create, attempt tag after create. if tags := getTagsIn(ctx); input.Tags == nil && len(tags) > 0 { - err := createTags(ctx, conn, aws.StringValue(output.EventBusArn), tags) + err := createTags(ctx, conn, aws.ToString(output.EventBusArn), tags) // If default tags only, continue. Otherwise, error. - if v, ok := d.GetOk(names.AttrTags); (!ok || len(v.(map[string]interface{})) == 0) && errs.IsUnsupportedOperationInPartitionError(conn.PartitionID, err) { + if v, ok := d.GetOk(names.AttrTags); (!ok || len(v.(map[string]interface{})) == 0) && errs.IsUnsupportedOperationInPartitionError(meta.(*conns.AWSClient).Partition, err) { return append(diags, resourceBusRead(ctx, d, meta)...) } @@ -108,9 +108,9 @@ func resourceBusCreate(ctx context.Context, d *schema.ResourceData, meta interfa func resourceBusRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - output, err := FindEventBusByName(ctx, conn, d.Id()) + output, err := findEventBusByName(ctx, conn, d.Id()) if !d.IsNewResource() && tfresource.NotFound(err) { log.Printf("[WARN] EventBridge Event Bus (%s) not found, removing from state", d.Id()) @@ -138,14 +138,14 @@ func resourceBusUpdate(ctx context.Context, d *schema.ResourceData, meta interfa func resourceBusDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) log.Printf("[INFO] Deleting EventBridge Event Bus: %s", d.Id()) - _, err := conn.DeleteEventBusWithContext(ctx, &eventbridge.DeleteEventBusInput{ + _, err := conn.DeleteEventBus(ctx, &eventbridge.DeleteEventBusInput{ Name: aws.String(d.Id()), }) - if tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { + if errs.IsA[*types.ResourceNotFoundException](err) { return diags } @@ -156,14 +156,14 @@ func resourceBusDelete(ctx context.Context, d *schema.ResourceData, meta interfa return diags } -func FindEventBusByName(ctx context.Context, conn *eventbridge.EventBridge, name string) (*eventbridge.DescribeEventBusOutput, error) { +func findEventBusByName(ctx context.Context, conn *eventbridge.Client, name string) (*eventbridge.DescribeEventBusOutput, error) { input := &eventbridge.DescribeEventBusInput{ Name: aws.String(name), } - output, err := conn.DescribeEventBusWithContext(ctx, input) + output, err := conn.DescribeEventBus(ctx, input) - if tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { + if errs.IsA[*types.ResourceNotFoundException](err) { return nil, &retry.NotFoundError{ LastError: err, LastRequest: input, diff --git a/internal/service/events/bus_test.go b/internal/service/events/bus_test.go index caafa47d98f..5dde94adedf 100644 --- a/internal/service/events/bus_test.go +++ b/internal/service/events/bus_test.go @@ -10,8 +10,8 @@ import ( "testing" "github.com/YakDriver/regexache" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -196,7 +196,7 @@ func TestAccEventsBus_partnerEventSource(t *testing.T) { func testAccCheckBusDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) for _, rs := range s.RootModule().Resources { if rs.Type != "aws_cloudwatch_event_bus" { @@ -227,11 +227,7 @@ func testAccCheckBusExists(ctx context.Context, n string, v *eventbridge.Describ return fmt.Errorf("Not found: %s", n) } - if rs.Primary.ID == "" { - return fmt.Errorf("No EventBridge Event Bus ID is set") - } - - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) output, err := tfevents.FindEventBusByName(ctx, conn, rs.Primary.ID) @@ -247,8 +243,8 @@ func testAccCheckBusExists(ctx context.Context, n string, v *eventbridge.Describ func testAccCheckBusRecreated(i, j *eventbridge.DescribeEventBusOutput) resource.TestCheckFunc { return func(s *terraform.State) error { - if aws.StringValue(i.Arn) == aws.StringValue(j.Arn) { - return fmt.Errorf("EventBridge event bus not recreated") + if aws.ToString(i.Arn) == aws.ToString(j.Arn) { + return fmt.Errorf("EventBridge Event Bus not recreated") } return nil } @@ -256,8 +252,8 @@ func testAccCheckBusRecreated(i, j *eventbridge.DescribeEventBusOutput) resource func testAccCheckBusNotRecreated(i, j *eventbridge.DescribeEventBusOutput) resource.TestCheckFunc { return func(s *terraform.State) error { - if aws.StringValue(i.Arn) != aws.StringValue(j.Arn) { - return fmt.Errorf("EventBridge event bus was recreated") + if aws.ToString(i.Arn) != aws.ToString(j.Arn) { + return fmt.Errorf("EventBridge Event Bus was recreated") } return nil } diff --git a/internal/service/events/exports_test.go b/internal/service/events/exports_test.go index 6a3844fdd8a..864f3ac9cbf 100644 --- a/internal/service/events/exports_test.go +++ b/internal/service/events/exports_test.go @@ -7,7 +7,9 @@ package events var ( ResourceAPIDestination = resourceAPIDestination ResourceArchive = resourceArchive + ResourceBus = resourceBus FindAPIDestinationByName = findAPIDestinationByName FindArchiveByName = findArchiveByName + FindEventBusByName = findEventBusByName ) diff --git a/internal/service/events/service_package_gen.go b/internal/service/events/service_package_gen.go index 511ea5bcd41..47517f3e893 100644 --- a/internal/service/events/service_package_gen.go +++ b/internal/service/events/service_package_gen.go @@ -52,7 +52,7 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka Name: "Archive", }, { - Factory: ResourceBus, + Factory: resourceBus, TypeName: "aws_cloudwatch_event_bus", Name: "Event Bus", Tags: &types.ServicePackageResourceTags{ From 5b412dc94c7f3dab28e275c991d8ac7fbfaeb870 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 15 Apr 2024 08:13:45 -0400 Subject: [PATCH 09/35] d/aws_cloudwatch_event_bus: Migrate to AWS SDK for Go v2. --- internal/service/events/bus_data_source.go | 21 +++++++------------ .../service/events/service_package_gen.go | 3 ++- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/internal/service/events/bus_data_source.go b/internal/service/events/bus_data_source.go index 9983b11a356..0951d6ebdf1 100644 --- a/internal/service/events/bus_data_source.go +++ b/internal/service/events/bus_data_source.go @@ -6,16 +6,14 @@ package events import ( "context" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKDataSource("aws_cloudwatch_event_bus") -func DataSourceBus() *schema.Resource { +// @SDKDataSource("aws_cloudwatch_event_bus", name="Event Bus") +func dataSourceBus() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceBusRead, @@ -34,23 +32,18 @@ func DataSourceBus() *schema.Resource { func dataSourceBusRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - name := d.Get("name").(string) + eventBusName := d.Get("name").(string) + output, err := findEventBusByName(ctx, conn, eventBusName) - input := &eventbridge.DescribeEventBusInput{ - Name: aws.String(name), - } - - output, err := conn.DescribeEventBusWithContext(ctx, input) if err != nil { - return sdkdiag.AppendErrorf(diags, "reading EventBridge Bus (%s): %s", name, err) + return sdkdiag.AppendErrorf(diags, "reading EventBridge Event Bus (%s): %s", eventBusName, err) } + d.SetId(eventBusName) d.Set("arn", output.Arn) d.Set("name", output.Name) - d.SetId(name) - return diags } diff --git a/internal/service/events/service_package_gen.go b/internal/service/events/service_package_gen.go index 47517f3e893..89188a51f32 100644 --- a/internal/service/events/service_package_gen.go +++ b/internal/service/events/service_package_gen.go @@ -25,8 +25,9 @@ func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.Servic func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePackageSDKDataSource { return []*types.ServicePackageSDKDataSource{ { - Factory: DataSourceBus, + Factory: dataSourceBus, TypeName: "aws_cloudwatch_event_bus", + Name: "Event Bus", }, { Factory: DataSourceConnection, From 32ab277fcc235b8568bd300469f33bb8f7a10ed4 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 15 Apr 2024 08:20:12 -0400 Subject: [PATCH 10/35] r/aws_cloudwatch_event_bus_policy: Migrate to AWS SDK for Go v2. --- internal/service/events/bus_policy.go | 39 +++++++++-------- internal/service/events/bus_policy_test.go | 43 +++++++++++++++---- internal/service/events/exports_test.go | 2 + .../service/events/service_package_gen.go | 3 +- 4 files changed, 59 insertions(+), 28 deletions(-) diff --git a/internal/service/events/bus_policy.go b/internal/service/events/bus_policy.go index a9c72cc742a..4dc733edd2c 100644 --- a/internal/service/events/bus_policy.go +++ b/internal/service/events/bus_policy.go @@ -7,22 +7,23 @@ import ( "context" "log" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/service/eventbridge/types" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/internal/verify" ) -// @SDKResource("aws_cloudwatch_event_bus_policy") -func ResourceBusPolicy() *schema.Resource { +// @SDKResource("aws_cloudwatch_event_bus_policy", name="Event Bus Policy") +func resourceBusPolicy() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceBusPolicyPut, ReadWithoutTimeout: resourceBusPolicyRead, @@ -61,7 +62,7 @@ func ResourceBusPolicy() *schema.Resource { func resourceBusPolicyPut(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) policy, err := structure.NormalizeJsonString(d.Get("policy").(string)) if err != nil { @@ -79,7 +80,7 @@ func resourceBusPolicyPut(ctx context.Context, d *schema.ResourceData, meta inte Policy: aws.String(policy), } - _, err = conn.PutPermissionWithContext(ctx, input) + _, err = conn.PutPermission(ctx, input) if err != nil { return sdkdiag.AppendErrorf(diags, "creating EventBridge Event Bus (%s) Policy: %s", eventBusName, err) @@ -90,11 +91,11 @@ func resourceBusPolicyPut(ctx context.Context, d *schema.ResourceData, meta inte } _, err = tfresource.RetryWhenNotFound(ctx, propagationTimeout, func() (interface{}, error) { - return FindEventBusPolicyByName(ctx, conn, d.Id()) + return findEventBusPolicyByName(ctx, conn, d.Id()) }) if err != nil { - return sdkdiag.AppendErrorf(diags, "wait for EventBridge Event Bus (%s) Policy create: %s", d.Id(), err) + return sdkdiag.AppendErrorf(diags, "waiting for EventBridge Event Bus (%s) Policy create: %s", d.Id(), err) } return append(diags, resourceBusPolicyRead(ctx, d, meta)...) @@ -102,9 +103,9 @@ func resourceBusPolicyPut(ctx context.Context, d *schema.ResourceData, meta inte func resourceBusPolicyRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - policy, err := FindEventBusPolicyByName(ctx, conn, d.Id()) + policy, err := findEventBusPolicyByName(ctx, conn, d.Id()) if !d.IsNewResource() && tfresource.NotFound(err) { log.Printf("[WARN] EventBridge Event Bus (%s) Policy not found, removing from state", d.Id()) @@ -122,7 +123,7 @@ func resourceBusPolicyRead(ctx context.Context, d *schema.ResourceData, meta int } d.Set("event_bus_name", eventBusName) - policyToSet, err := verify.PolicyToSet(d.Get("policy").(string), aws.StringValue(policy)) + policyToSet, err := verify.PolicyToSet(d.Get("policy").(string), aws.ToString(policy)) if err != nil { return sdkdiag.AppendFromErr(diags, err) } @@ -134,15 +135,15 @@ func resourceBusPolicyRead(ctx context.Context, d *schema.ResourceData, meta int func resourceBusPolicyDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) log.Printf("[DEBUG] Deleting EventBridge Event Bus Policy: %s", d.Id()) - _, err := conn.RemovePermissionWithContext(ctx, &eventbridge.RemovePermissionInput{ + _, err := conn.RemovePermission(ctx, &eventbridge.RemovePermissionInput{ EventBusName: aws.String(d.Id()), - RemoveAllPermissions: aws.Bool(true), + RemoveAllPermissions: true, }) - if tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { + if errs.IsA[*types.ResourceNotFoundException](err) { return diags } @@ -153,14 +154,14 @@ func resourceBusPolicyDelete(ctx context.Context, d *schema.ResourceData, meta i return diags } -func FindEventBusPolicyByName(ctx context.Context, conn *eventbridge.EventBridge, name string) (*string, error) { - output, err := FindEventBusByName(ctx, conn, name) +func findEventBusPolicyByName(ctx context.Context, conn *eventbridge.Client, name string) (*string, error) { + output, err := findEventBusByName(ctx, conn, name) if err != nil { return nil, err } - if aws.StringValue(output.Policy) == "" { + if aws.ToString(output.Policy) == "" { return nil, &retry.NotFoundError{} } diff --git a/internal/service/events/bus_policy_test.go b/internal/service/events/bus_policy_test.go index 3991d4c9a6f..071c8a880e8 100644 --- a/internal/service/events/bus_policy_test.go +++ b/internal/service/events/bus_policy_test.go @@ -9,7 +9,7 @@ import ( "fmt" "testing" - "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go-v2/aws" awspolicy "github.com/hashicorp/awspolicyequivalence" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" @@ -17,6 +17,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" tfevents "github.com/hashicorp/terraform-provider-aws/internal/service/events" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/names" ) @@ -29,7 +30,7 @@ func TestAccEventsBusPolicy_basic(t *testing.T) { PreCheck: func() { acctest.PreCheck(ctx, t) }, ErrorCheck: acctest.ErrorCheck(t, names.EventsServiceID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, - CheckDestroy: testAccCheckBusDestroy(ctx), + CheckDestroy: testAccCheckBusPolicyDestroy(ctx), Steps: []resource.TestStep{ { Config: testAccBusPolicyConfig_basic(rName), @@ -63,7 +64,7 @@ func TestAccEventsBusPolicy_ignoreEquivalent(t *testing.T) { PreCheck: func() { acctest.PreCheck(ctx, t) }, ErrorCheck: acctest.ErrorCheck(t, names.EventsServiceID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, - CheckDestroy: testAccCheckBusDestroy(ctx), + CheckDestroy: testAccCheckBusPolicyDestroy(ctx), Steps: []resource.TestStep{ { Config: testAccBusPolicyConfig_order(rName), @@ -89,7 +90,7 @@ func TestAccEventsBusPolicy_disappears(t *testing.T) { PreCheck: func() { acctest.PreCheck(ctx, t) }, ErrorCheck: acctest.ErrorCheck(t, names.EventsServiceID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, - CheckDestroy: testAccCheckBusDestroy(ctx), + CheckDestroy: testAccCheckBusPolicyDestroy(ctx), Steps: []resource.TestStep{ { Config: testAccBusPolicyConfig_basic(rName), @@ -113,7 +114,7 @@ func TestAccEventsBusPolicy_disappears_EventBus(t *testing.T) { PreCheck: func() { acctest.PreCheck(ctx, t) }, ErrorCheck: acctest.ErrorCheck(t, names.EventsServiceID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, - CheckDestroy: testAccCheckBusDestroy(ctx), + CheckDestroy: testAccCheckBusPolicyDestroy(ctx), Steps: []resource.TestStep{ { Config: testAccBusPolicyConfig_basic(rName), @@ -127,6 +128,32 @@ func TestAccEventsBusPolicy_disappears_EventBus(t *testing.T) { }) } +func testAccCheckBusPolicyDestroy(ctx context.Context) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_cloudwatch_event_bus_policy" { + continue + } + + _, err := tfevents.FindEventBusPolicyByName(ctx, conn, rs.Primary.ID) + + if tfresource.NotFound(err) { + continue + } + + if err != nil { + return err + } + + return fmt.Errorf("EventBridge Event Bus Policy %s still exists", rs.Primary.ID) + } + + return nil + } +} + func testAccCheckBusPolicyExists(ctx context.Context, n string) resource.TestCheckFunc { return func(state *terraform.State) error { rs, ok := state.RootModule().Resources[n] @@ -134,7 +161,7 @@ func testAccCheckBusPolicyExists(ctx context.Context, n string) resource.TestChe return fmt.Errorf("Not found: %s", n) } - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) _, err := tfevents.FindEventBusPolicyByName(ctx, conn, rs.Primary.ID) @@ -149,7 +176,7 @@ func testAccBusPolicyDocument(ctx context.Context, n string) resource.TestCheckF return fmt.Errorf("Not found: %s", n) } - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) policy, err := tfevents.FindEventBusPolicyByName(ctx, conn, rs.Primary.ID) @@ -157,7 +184,7 @@ func testAccBusPolicyDocument(ctx context.Context, n string) resource.TestCheckF return err } - if equivalent, err := awspolicy.PoliciesAreEquivalent(rs.Primary.Attributes["policy"], aws.StringValue(policy)); err != nil || !equivalent { + if equivalent, err := awspolicy.PoliciesAreEquivalent(rs.Primary.Attributes["policy"], aws.ToString(policy)); err != nil || !equivalent { return errors.New(`EventBridge Event Bus Policies not equivalent`) } diff --git a/internal/service/events/exports_test.go b/internal/service/events/exports_test.go index 864f3ac9cbf..2d733bb7aba 100644 --- a/internal/service/events/exports_test.go +++ b/internal/service/events/exports_test.go @@ -8,8 +8,10 @@ var ( ResourceAPIDestination = resourceAPIDestination ResourceArchive = resourceArchive ResourceBus = resourceBus + ResourceBusPolicy = resourceBusPolicy FindAPIDestinationByName = findAPIDestinationByName FindArchiveByName = findArchiveByName FindEventBusByName = findEventBusByName + FindEventBusPolicyByName = findEventBusPolicyByName ) diff --git a/internal/service/events/service_package_gen.go b/internal/service/events/service_package_gen.go index 89188a51f32..d16613e8dda 100644 --- a/internal/service/events/service_package_gen.go +++ b/internal/service/events/service_package_gen.go @@ -61,8 +61,9 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka }, }, { - Factory: ResourceBusPolicy, + Factory: resourceBusPolicy, TypeName: "aws_cloudwatch_event_bus_policy", + Name: "Event Bus Policy", }, { Factory: ResourceConnection, From 23aa9fa5277b398ad8d88ab032b68d0eb5bd073a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 15 Apr 2024 12:16:43 -0400 Subject: [PATCH 11/35] r/aws_cloudwatch_event_connection: Migrate to AWS SDK for Go v2. --- internal/service/events/connection.go | 708 ++++++++++-------- internal/service/events/connection_test.go | 14 +- internal/service/events/exports_test.go | 2 + internal/service/events/find.go | 26 - .../service/events/service_package_gen.go | 3 +- internal/service/events/status.go | 29 - internal/service/events/wait.go | 69 -- 7 files changed, 415 insertions(+), 436 deletions(-) delete mode 100644 internal/service/events/status.go delete mode 100644 internal/service/events/wait.go diff --git a/internal/service/events/connection.go b/internal/service/events/connection.go index 3721f2b2214..7b60ccbbb92 100644 --- a/internal/service/events/connection.go +++ b/internal/service/events/connection.go @@ -5,271 +5,281 @@ package events import ( "context" + "errors" "fmt" "log" + "time" "github.com/YakDriver/regexache" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/service/eventbridge/types" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/enum" + "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -// @SDKResource("aws_cloudwatch_event_connection") -func ResourceConnection() *schema.Resource { - connectionHttpParameters := &schema.Resource{ - Schema: map[string]*schema.Schema{ - "body": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Optional: true, - }, - "value": { - Type: schema.TypeString, - Optional: true, - Sensitive: true, - }, - "is_value_secret": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - }, - }, - }, - "header": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Optional: true, - }, - "value": { - Type: schema.TypeString, - Optional: true, - Sensitive: true, - }, - "is_value_secret": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - }, - }, - }, - "query_string": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Optional: true, - }, - "value": { - Type: schema.TypeString, - Optional: true, - Sensitive: true, - }, - "is_value_secret": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - }, - }, - }, - }, - } - +// @SDKResource("aws_cloudwatch_event_connection", name="Connection") +func resourceConnection() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceConnectionCreate, ReadWithoutTimeout: resourceConnectionRead, UpdateWithoutTimeout: resourceConnectionUpdate, DeleteWithoutTimeout: resourceConnectionDelete, + Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.All( - validation.StringLenBetween(1, 64), - validation.StringMatch(regexache.MustCompile(`^[0-9A-Za-z_.-]+`), ""), - ), - }, - "description": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringLenBetween(0, 512), - }, - "authorization_type": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice(eventbridge.ConnectionAuthorizationType_Values(), true), - }, - "auth_parameters": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, - Elem: &schema.Resource{ + SchemaFunc: func() map[string]*schema.Schema { + connectionHttpParameters := func() *schema.Resource { + return &schema.Resource{ Schema: map[string]*schema.Schema{ - "api_key": { + "body": { Type: schema.TypeList, Optional: true, - MaxItems: 1, - ExactlyOneOf: []string{ - "auth_parameters.0.api_key", - "auth_parameters.0.basic", - "auth_parameters.0.oauth", - }, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + "is_value_secret": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, "key": { Type: schema.TypeString, - Required: true, - ValidateFunc: validation.All( - validation.StringLenBetween(1, 512), - ), + Optional: true, }, "value": { Type: schema.TypeString, - Required: true, + Optional: true, Sensitive: true, - ValidateFunc: validation.All( - validation.StringLenBetween(1, 512), - ), }, }, }, }, - "basic": { + "header": { Type: schema.TypeList, Optional: true, - MaxItems: 1, - ExactlyOneOf: []string{ - "auth_parameters.0.api_key", - "auth_parameters.0.basic", - "auth_parameters.0.oauth", - }, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "username": { + "is_value_secret": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "key": { Type: schema.TypeString, - Required: true, - ValidateFunc: validation.All( - validation.StringLenBetween(1, 512), - ), + Optional: true, }, - "password": { + "value": { Type: schema.TypeString, - Required: true, + Optional: true, Sensitive: true, - ValidateFunc: validation.All( - validation.StringLenBetween(1, 512), - ), }, }, }, }, - "oauth": { + "query_string": { Type: schema.TypeList, Optional: true, - MaxItems: 1, - ExactlyOneOf: []string{ - "auth_parameters.0.api_key", - "auth_parameters.0.basic", - "auth_parameters.0.oauth", - }, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "authorization_endpoint": { + "is_value_secret": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "key": { Type: schema.TypeString, - Required: true, - ValidateFunc: validation.All( - validation.StringLenBetween(1, 2048), - ), + Optional: true, }, - "http_method": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice(eventbridge.ConnectionOAuthHttpMethod_Values(), true), + "value": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + }, + }, + }, + }, + } + } + + return map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "auth_parameters": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "api_key": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ExactlyOneOf: []string{ + "auth_parameters.0.api_key", + "auth_parameters.0.basic", + "auth_parameters.0.oauth", + }, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 512), + ), + }, + "value": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 512), + ), + }, }, - "oauth_http_parameters": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, - Elem: connectionHttpParameters, + }, + }, + "basic": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ExactlyOneOf: []string{ + "auth_parameters.0.api_key", + "auth_parameters.0.basic", + "auth_parameters.0.oauth", + }, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "password": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 512), + ), + }, + "username": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 512), + ), + }, }, - "client_parameters": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "client_id": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.All( - validation.StringLenBetween(1, 512), - ), - }, - "client_secret": { - Type: schema.TypeString, - Required: true, - Sensitive: true, - ValidateFunc: validation.All( - validation.StringLenBetween(1, 512), - ), + }, + }, + "invocation_http_parameters": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: connectionHttpParameters(), + }, + "oauth": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + ExactlyOneOf: []string{ + "auth_parameters.0.api_key", + "auth_parameters.0.basic", + "auth_parameters.0.oauth", + }, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "authorization_endpoint": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 2048), + ), + }, + "client_parameters": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 512), + ), + }, + "client_secret": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 512), + ), + }, }, }, }, + "http_method": { + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: enum.Validate[types.ConnectionOAuthHttpMethod](), + }, + "oauth_http_parameters": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: connectionHttpParameters(), + }, }, }, }, }, - "invocation_http_parameters": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - Elem: connectionHttpParameters, - }, }, }, - }, - "arn": { - Type: schema.TypeString, - Computed: true, - }, - "secret_arn": { - Type: schema.TypeString, - Computed: true, - }, + "authorization_type": { + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: enum.Validate[types.ConnectionAuthorizationType](), + }, + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 512), + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 64), + validation.StringMatch(regexache.MustCompile(`^[0-9A-Za-z_.-]+`), ""), + ), + }, + "secret_arn": { + Type: schema.TypeString, + Computed: true, + }, + } }, } } func resourceConnectionCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) name := d.Get("name").(string) input := &eventbridge.CreateConnectionInput{ - AuthorizationType: aws.String(d.Get("authorization_type").(string)), + AuthorizationType: types.ConnectionAuthorizationType(d.Get("authorization_type").(string)), AuthParameters: expandCreateConnectionAuthRequestParameters(d.Get("auth_parameters").([]interface{})), Name: aws.String(name), } @@ -278,18 +288,16 @@ func resourceConnectionCreate(ctx context.Context, d *schema.ResourceData, meta input.Description = aws.String(v.(string)) } - _, err := conn.CreateConnectionWithContext(ctx, input) + _, err := conn.CreateConnection(ctx, input) if err != nil { - return sdkdiag.AppendErrorf(diags, "creating EventBridge connection (%s): %s", name, err) + return sdkdiag.AppendErrorf(diags, "creating EventBridge Connection (%s): %s", name, err) } d.SetId(name) - _, err = waitConnectionCreated(ctx, conn, d.Id()) - - if err != nil { - return sdkdiag.AppendErrorf(diags, "waiting for EventBridge connection (%s) to create: %s", d.Id(), err) + if _, err := waitConnectionCreated(ctx, conn, d.Id()); err != nil { + return sdkdiag.AppendErrorf(diags, "waiting for EventBridge Connection (%s) create: %s", d.Id(), err) } return append(diags, resourceConnectionRead(ctx, d, meta)...) @@ -297,46 +305,44 @@ func resourceConnectionCreate(ctx context.Context, d *schema.ResourceData, meta func resourceConnectionRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - output, err := FindConnectionByName(ctx, conn, d.Id()) + output, err := findConnectionByName(ctx, conn, d.Id()) if !d.IsNewResource() && tfresource.NotFound(err) { - log.Printf("[WARN] EventBridge connection (%s) not found, removing from state", d.Id()) + log.Printf("[WARN] EventBridge Connection (%s) not found, removing from state", d.Id()) d.SetId("") return diags } if err != nil { - return sdkdiag.AppendErrorf(diags, "reading EventBridge connection (%s): %s", d.Id(), err) + return sdkdiag.AppendErrorf(diags, "reading EventBridge Connection (%s): %s", d.Id(), err) } d.Set("arn", output.ConnectionArn) - d.Set("authorization_type", output.AuthorizationType) - d.Set("description", output.Description) - d.Set("name", output.Name) - d.Set("secret_arn", output.SecretArn) - if output.AuthParameters != nil { - authParameters := flattenConnectionAuthParameters(output.AuthParameters, d) - if err := d.Set("auth_parameters", authParameters); err != nil { + if err := d.Set("auth_parameters", flattenConnectionAuthParameters(output.AuthParameters, d)); err != nil { return sdkdiag.AppendErrorf(diags, "setting auth_parameters error: %s", err) } } + d.Set("authorization_type", output.AuthorizationType) + d.Set("description", output.Description) + d.Set("name", output.Name) + d.Set("secret_arn", output.SecretArn) return diags } func resourceConnectionUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) input := &eventbridge.UpdateConnectionInput{ Name: aws.String(d.Id()), } if v, ok := d.GetOk("authorization_type"); ok { - input.AuthorizationType = aws.String(v.(string)) + input.AuthorizationType = types.ConnectionAuthorizationType(v.(string)) } if v, ok := d.GetOk("auth_parameters"); ok { @@ -347,16 +353,14 @@ func resourceConnectionUpdate(ctx context.Context, d *schema.ResourceData, meta input.Description = aws.String(v.(string)) } - _, err := conn.UpdateConnectionWithContext(ctx, input) + _, err := conn.UpdateConnection(ctx, input) if err != nil { - return sdkdiag.AppendErrorf(diags, "updating EventBridge connection (%s): %s", d.Id(), err) + return sdkdiag.AppendErrorf(diags, "updating EventBridge Connection (%s): %s", d.Id(), err) } - _, err = waitConnectionUpdated(ctx, conn, d.Id()) - - if err != nil { - return sdkdiag.AppendErrorf(diags, "waiting for EventBridge connection (%s) to update: %s", d.Id(), err) + if _, err := waitConnectionUpdated(ctx, conn, d.Id()); err != nil { + return sdkdiag.AppendErrorf(diags, "waiting for EventBridge Connection (%s) update: %s", d.Id(), err) } return append(diags, resourceConnectionRead(ctx, d, meta)...) @@ -364,32 +368,137 @@ func resourceConnectionUpdate(ctx context.Context, d *schema.ResourceData, meta func resourceConnectionDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - log.Printf("[INFO] Deleting EventBridge connection (%s)", d.Id()) - _, err := conn.DeleteConnectionWithContext(ctx, &eventbridge.DeleteConnectionInput{ + log.Printf("[INFO] Deleting EventBridge Connection: %s", d.Id()) + _, err := conn.DeleteConnection(ctx, &eventbridge.DeleteConnectionInput{ Name: aws.String(d.Id()), }) - if tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { + if errs.IsA[*types.ResourceNotFoundException](err) { return diags } if err != nil { - return sdkdiag.AppendErrorf(diags, "deleting EventBridge connection (%s): %s", d.Id(), err) + return sdkdiag.AppendErrorf(diags, "deleting EventBridge Connection (%s): %s", d.Id(), err) } - _, err = waitConnectionDeleted(ctx, conn, d.Id()) + if _, err := waitConnectionDeleted(ctx, conn, d.Id()); err != nil { + return sdkdiag.AppendErrorf(diags, "waiting for EventBridge Connection (%s) delete: %s", d.Id(), err) + } + + return diags +} + +func findConnectionByName(ctx context.Context, conn *eventbridge.Client, name string) (*eventbridge.DescribeConnectionOutput, error) { + input := &eventbridge.DescribeConnectionInput{ + Name: aws.String(name), + } + + output, err := conn.DescribeConnection(ctx, input) + + if errs.IsA[*types.ResourceNotFoundException](err) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: input, + } + } if err != nil { - return sdkdiag.AppendErrorf(diags, "waiting for EventBridge connection (%s) to delete: %s", d.Id(), err) + return nil, err } - return diags + if output == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + return output, nil +} + +func statusConnectionState(ctx context.Context, conn *eventbridge.Client, name string) retry.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := findConnectionByName(ctx, conn, name) + + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return output, string(output.ConnectionState), nil + } +} + +func waitConnectionCreated(ctx context.Context, conn *eventbridge.Client, name string) (*eventbridge.DescribeConnectionOutput, error) { + const ( + timeout = 2 * time.Minute + ) + stateConf := &retry.StateChangeConf{ + Pending: enum.Slice(types.ConnectionStateCreating, types.ConnectionStateAuthorizing), + Target: enum.Slice(types.ConnectionStateAuthorized, types.ConnectionStateDeauthorized), + Refresh: statusConnectionState(ctx, conn, name), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*eventbridge.DescribeConnectionOutput); ok { + tfresource.SetLastError(err, errors.New(aws.ToString(output.StateReason))) + + return output, err + } + + return nil, err } -func expandCreateConnectionAuthRequestParameters(config []interface{}) *eventbridge.CreateConnectionAuthRequestParameters { - authParameters := &eventbridge.CreateConnectionAuthRequestParameters{} +func waitConnectionUpdated(ctx context.Context, conn *eventbridge.Client, name string) (*eventbridge.DescribeConnectionOutput, error) { + const ( + timeout = 2 * time.Minute + ) + stateConf := &retry.StateChangeConf{ + Pending: enum.Slice(types.ConnectionStateUpdating, types.ConnectionStateAuthorizing, types.ConnectionStateDeauthorizing), + Target: enum.Slice(types.ConnectionStateAuthorized, types.ConnectionStateDeauthorized), + Refresh: statusConnectionState(ctx, conn, name), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*eventbridge.DescribeConnectionOutput); ok { + tfresource.SetLastError(err, errors.New(aws.ToString(output.StateReason))) + + return output, err + } + + return nil, err +} + +func waitConnectionDeleted(ctx context.Context, conn *eventbridge.Client, name string) (*eventbridge.DescribeConnectionOutput, error) { + const ( + timeout = 2 * time.Minute + ) + stateConf := &retry.StateChangeConf{ + Pending: enum.Slice(types.ConnectionStateDeleting), + Target: []string{}, + Refresh: statusConnectionState(ctx, conn, name), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*eventbridge.DescribeConnectionOutput); ok { + tfresource.SetLastError(err, errors.New(aws.ToString(output.StateReason))) + + return output, err + } + + return nil, err +} + +func expandCreateConnectionAuthRequestParameters(config []interface{}) *types.CreateConnectionAuthRequestParameters { + authParameters := &types.CreateConnectionAuthRequestParameters{} for _, c := range config { param := c.(map[string]interface{}) if val, ok := param["api_key"]; ok { @@ -409,11 +518,11 @@ func expandCreateConnectionAuthRequestParameters(config []interface{}) *eventbri return authParameters } -func expandCreateConnectionAPIKeyAuthRequestParameters(config []interface{}) *eventbridge.CreateConnectionApiKeyAuthRequestParameters { +func expandCreateConnectionAPIKeyAuthRequestParameters(config []interface{}) *types.CreateConnectionApiKeyAuthRequestParameters { if len(config) == 0 { return nil } - apiKeyAuthParameters := &eventbridge.CreateConnectionApiKeyAuthRequestParameters{} + apiKeyAuthParameters := &types.CreateConnectionApiKeyAuthRequestParameters{} for _, c := range config { param := c.(map[string]interface{}) if val, ok := param["key"].(string); ok && val != "" { @@ -426,11 +535,11 @@ func expandCreateConnectionAPIKeyAuthRequestParameters(config []interface{}) *ev return apiKeyAuthParameters } -func expandCreateConnectionBasicAuthRequestParameters(config []interface{}) *eventbridge.CreateConnectionBasicAuthRequestParameters { +func expandCreateConnectionBasicAuthRequestParameters(config []interface{}) *types.CreateConnectionBasicAuthRequestParameters { if len(config) == 0 { return nil } - basicAuthParameters := &eventbridge.CreateConnectionBasicAuthRequestParameters{} + basicAuthParameters := &types.CreateConnectionBasicAuthRequestParameters{} for _, c := range config { param := c.(map[string]interface{}) if val, ok := param["username"].(string); ok && val != "" { @@ -443,18 +552,18 @@ func expandCreateConnectionBasicAuthRequestParameters(config []interface{}) *eve return basicAuthParameters } -func expandCreateConnectionOAuthAuthRequestParameters(config []interface{}) *eventbridge.CreateConnectionOAuthRequestParameters { +func expandCreateConnectionOAuthAuthRequestParameters(config []interface{}) *types.CreateConnectionOAuthRequestParameters { if len(config) == 0 { return nil } - oAuthParameters := &eventbridge.CreateConnectionOAuthRequestParameters{} + oAuthParameters := &types.CreateConnectionOAuthRequestParameters{} for _, c := range config { param := c.(map[string]interface{}) if val, ok := param["authorization_endpoint"].(string); ok && val != "" { oAuthParameters.AuthorizationEndpoint = aws.String(val) } if val, ok := param["http_method"].(string); ok && val != "" { - oAuthParameters.HttpMethod = aws.String(val) + oAuthParameters.HttpMethod = types.ConnectionOAuthHttpMethod(val) } if val, ok := param["oauth_http_parameters"]; ok { oAuthParameters.OAuthHttpParameters = expandConnectionHTTPParameters(val.([]interface{})) @@ -466,8 +575,8 @@ func expandCreateConnectionOAuthAuthRequestParameters(config []interface{}) *eve return oAuthParameters } -func expandCreateConnectionOAuthClientRequestParameters(config []interface{}) *eventbridge.CreateConnectionOAuthClientRequestParameters { - oAuthClientRequestParameters := &eventbridge.CreateConnectionOAuthClientRequestParameters{} +func expandCreateConnectionOAuthClientRequestParameters(config []interface{}) *types.CreateConnectionOAuthClientRequestParameters { + oAuthClientRequestParameters := &types.CreateConnectionOAuthClientRequestParameters{} for _, c := range config { param := c.(map[string]interface{}) if val, ok := param["client_id"].(string); ok && val != "" { @@ -480,11 +589,11 @@ func expandCreateConnectionOAuthClientRequestParameters(config []interface{}) *e return oAuthClientRequestParameters } -func expandConnectionHTTPParameters(config []interface{}) *eventbridge.ConnectionHttpParameters { +func expandConnectionHTTPParameters(config []interface{}) *types.ConnectionHttpParameters { if len(config) == 0 { return nil } - httpParameters := &eventbridge.ConnectionHttpParameters{} + httpParameters := &types.ConnectionHttpParameters{} for _, c := range config { param := c.(map[string]interface{}) if val, ok := param["body"]; ok { @@ -500,13 +609,13 @@ func expandConnectionHTTPParameters(config []interface{}) *eventbridge.Connectio return httpParameters } -func expandConnectionHTTPParametersBody(config []interface{}) []*eventbridge.ConnectionBodyParameter { +func expandConnectionHTTPParametersBody(config []interface{}) []types.ConnectionBodyParameter { if len(config) == 0 { return nil } - var parameters []*eventbridge.ConnectionBodyParameter + var parameters []types.ConnectionBodyParameter for _, c := range config { - parameter := eventbridge.ConnectionBodyParameter{} + parameter := types.ConnectionBodyParameter{} input := c.(map[string]interface{}) if val, ok := input["key"].(string); ok && val != "" { @@ -516,20 +625,20 @@ func expandConnectionHTTPParametersBody(config []interface{}) []*eventbridge.Con parameter.Value = aws.String(val) } if val, ok := input["is_value_secret"].(bool); ok { - parameter.IsValueSecret = aws.Bool(val) + parameter.IsValueSecret = val } - parameters = append(parameters, ¶meter) + parameters = append(parameters, parameter) } return parameters } -func expandConnectionHTTPParametersHeader(config []interface{}) []*eventbridge.ConnectionHeaderParameter { +func expandConnectionHTTPParametersHeader(config []interface{}) []types.ConnectionHeaderParameter { if len(config) == 0 { return nil } - var parameters []*eventbridge.ConnectionHeaderParameter + var parameters []types.ConnectionHeaderParameter for _, c := range config { - parameter := eventbridge.ConnectionHeaderParameter{} + parameter := types.ConnectionHeaderParameter{} input := c.(map[string]interface{}) if val, ok := input["key"].(string); ok && val != "" { @@ -539,20 +648,20 @@ func expandConnectionHTTPParametersHeader(config []interface{}) []*eventbridge.C parameter.Value = aws.String(val) } if val, ok := input["is_value_secret"].(bool); ok { - parameter.IsValueSecret = aws.Bool(val) + parameter.IsValueSecret = val } - parameters = append(parameters, ¶meter) + parameters = append(parameters, parameter) } return parameters } -func expandConnectionHTTPParametersQueryString(config []interface{}) []*eventbridge.ConnectionQueryStringParameter { +func expandConnectionHTTPParametersQueryString(config []interface{}) []types.ConnectionQueryStringParameter { if len(config) == 0 { return nil } - var parameters []*eventbridge.ConnectionQueryStringParameter + var parameters []types.ConnectionQueryStringParameter for _, c := range config { - parameter := eventbridge.ConnectionQueryStringParameter{} + parameter := types.ConnectionQueryStringParameter{} input := c.(map[string]interface{}) if val, ok := input["key"].(string); ok && val != "" { @@ -562,50 +671,47 @@ func expandConnectionHTTPParametersQueryString(config []interface{}) []*eventbri parameter.Value = aws.String(val) } if val, ok := input["is_value_secret"].(bool); ok { - parameter.IsValueSecret = aws.Bool(val) + parameter.IsValueSecret = val } - parameters = append(parameters, ¶meter) + parameters = append(parameters, parameter) } return parameters } -func flattenConnectionAuthParameters( - authParameters *eventbridge.ConnectionAuthResponseParameters, - resourceData *schema.ResourceData, -) []map[string]interface{} { +func flattenConnectionAuthParameters(authParameters *types.ConnectionAuthResponseParameters, d *schema.ResourceData) []map[string]interface{} { config := make(map[string]interface{}) if authParameters.ApiKeyAuthParameters != nil { - config["api_key"] = flattenConnectionAPIKeyAuthParameters(authParameters.ApiKeyAuthParameters, resourceData) + config["api_key"] = flattenConnectionAPIKeyAuthParameters(authParameters.ApiKeyAuthParameters, d) } if authParameters.BasicAuthParameters != nil { - config["basic"] = flattenConnectionBasicAuthParameters(authParameters.BasicAuthParameters, resourceData) + config["basic"] = flattenConnectionBasicAuthParameters(authParameters.BasicAuthParameters, d) } if authParameters.OAuthParameters != nil { - config["oauth"] = flattenConnectionOAuthParameters(authParameters.OAuthParameters, resourceData) + config["oauth"] = flattenConnectionOAuthParameters(authParameters.OAuthParameters, d) } if authParameters.InvocationHttpParameters != nil { - config["invocation_http_parameters"] = flattenConnectionHTTPParameters(authParameters.InvocationHttpParameters, resourceData, "auth_parameters.0.invocation_http_parameters") + config["invocation_http_parameters"] = flattenConnectionHTTPParameters(authParameters.InvocationHttpParameters, d, "auth_parameters.0.invocation_http_parameters") } result := []map[string]interface{}{config} return result } -func flattenConnectionAPIKeyAuthParameters(apiKeyAuthParameters *eventbridge.ConnectionApiKeyAuthResponseParameters, resourceData *schema.ResourceData) []map[string]interface{} { +func flattenConnectionAPIKeyAuthParameters(apiKeyAuthParameters *types.ConnectionApiKeyAuthResponseParameters, d *schema.ResourceData) []map[string]interface{} { if apiKeyAuthParameters == nil { return nil } config := make(map[string]interface{}) if apiKeyAuthParameters.ApiKeyName != nil { - config["key"] = aws.StringValue(apiKeyAuthParameters.ApiKeyName) + config["key"] = aws.ToString(apiKeyAuthParameters.ApiKeyName) } - if v, ok := resourceData.GetOk("auth_parameters.0.api_key.0.value"); ok { + if v, ok := d.GetOk("auth_parameters.0.api_key.0.value"); ok { config["value"] = v.(string) } @@ -613,17 +719,17 @@ func flattenConnectionAPIKeyAuthParameters(apiKeyAuthParameters *eventbridge.Con return result } -func flattenConnectionBasicAuthParameters(basicAuthParameters *eventbridge.ConnectionBasicAuthResponseParameters, resourceData *schema.ResourceData) []map[string]interface{} { +func flattenConnectionBasicAuthParameters(basicAuthParameters *types.ConnectionBasicAuthResponseParameters, d *schema.ResourceData) []map[string]interface{} { if basicAuthParameters == nil { return nil } config := make(map[string]interface{}) if basicAuthParameters.Username != nil { - config["username"] = aws.StringValue(basicAuthParameters.Username) + config["username"] = aws.ToString(basicAuthParameters.Username) } - if v, ok := resourceData.GetOk("auth_parameters.0.basic.0.password"); ok { + if v, ok := d.GetOk("auth_parameters.0.basic.0.password"); ok { config["password"] = v.(string) } @@ -631,36 +737,34 @@ func flattenConnectionBasicAuthParameters(basicAuthParameters *eventbridge.Conne return result } -func flattenConnectionOAuthParameters(oAuthParameters *eventbridge.ConnectionOAuthResponseParameters, resourceData *schema.ResourceData) []map[string]interface{} { +func flattenConnectionOAuthParameters(oAuthParameters *types.ConnectionOAuthResponseParameters, d *schema.ResourceData) []map[string]interface{} { if oAuthParameters == nil { return nil } config := make(map[string]interface{}) if oAuthParameters.AuthorizationEndpoint != nil { - config["authorization_endpoint"] = aws.StringValue(oAuthParameters.AuthorizationEndpoint) - } - if oAuthParameters.HttpMethod != nil { - config["http_method"] = aws.StringValue(oAuthParameters.HttpMethod) + config["authorization_endpoint"] = aws.ToString(oAuthParameters.AuthorizationEndpoint) } - config["oauth_http_parameters"] = flattenConnectionHTTPParameters(oAuthParameters.OAuthHttpParameters, resourceData, "auth_parameters.0.oauth.0.oauth_http_parameters") - config["client_parameters"] = flattenConnectionOAuthClientResponseParameters(oAuthParameters.ClientParameters, resourceData) + config["http_method"] = oAuthParameters.HttpMethod + config["oauth_http_parameters"] = flattenConnectionHTTPParameters(oAuthParameters.OAuthHttpParameters, d, "auth_parameters.0.oauth.0.oauth_http_parameters") + config["client_parameters"] = flattenConnectionOAuthClientResponseParameters(oAuthParameters.ClientParameters, d) result := []map[string]interface{}{config} return result } -func flattenConnectionOAuthClientResponseParameters(oAuthClientRequestParameters *eventbridge.ConnectionOAuthClientResponseParameters, resourceData *schema.ResourceData) []map[string]interface{} { +func flattenConnectionOAuthClientResponseParameters(oAuthClientRequestParameters *types.ConnectionOAuthClientResponseParameters, d *schema.ResourceData) []map[string]interface{} { if oAuthClientRequestParameters == nil { return nil } config := make(map[string]interface{}) if oAuthClientRequestParameters.ClientID != nil { - config["client_id"] = aws.StringValue(oAuthClientRequestParameters.ClientID) + config["client_id"] = aws.ToString(oAuthClientRequestParameters.ClientID) } - if v, ok := resourceData.GetOk("auth_parameters.0.oauth.0.client_parameters.0.client_secret"); ok { + if v, ok := d.GetOk("auth_parameters.0.oauth.0.client_parameters.0.client_secret"); ok { config["client_secret"] = v.(string) } @@ -668,11 +772,7 @@ func flattenConnectionOAuthClientResponseParameters(oAuthClientRequestParameters return result } -func flattenConnectionHTTPParameters( - httpParameters *eventbridge.ConnectionHttpParameters, - resourceData *schema.ResourceData, - path string, -) []map[string]interface{} { +func flattenConnectionHTTPParameters(httpParameters *types.ConnectionHttpParameters, d *schema.ResourceData, path string) []map[string]interface{} { if httpParameters == nil { return nil } @@ -680,12 +780,12 @@ func flattenConnectionHTTPParameters( var bodyParameters []map[string]interface{} for i, param := range httpParameters.BodyParameters { config := make(map[string]interface{}) - config["is_value_secret"] = aws.BoolValue(param.IsValueSecret) - config["key"] = aws.StringValue(param.Key) + config["is_value_secret"] = param.IsValueSecret + config["key"] = aws.ToString(param.Key) if param.Value != nil { - config["value"] = aws.StringValue(param.Value) - } else if v, ok := resourceData.GetOk(fmt.Sprintf("%s.0.body.%d.value", path, i)); ok { + config["value"] = aws.ToString(param.Value) + } else if v, ok := d.GetOk(fmt.Sprintf("%s.0.body.%d.value", path, i)); ok { config["value"] = v.(string) } bodyParameters = append(bodyParameters, config) @@ -694,12 +794,12 @@ func flattenConnectionHTTPParameters( var headerParameters []map[string]interface{} for i, param := range httpParameters.HeaderParameters { config := make(map[string]interface{}) - config["is_value_secret"] = aws.BoolValue(param.IsValueSecret) - config["key"] = aws.StringValue(param.Key) + config["is_value_secret"] = param.IsValueSecret + config["key"] = aws.ToString(param.Key) if param.Value != nil { - config["value"] = aws.StringValue(param.Value) - } else if v, ok := resourceData.GetOk(fmt.Sprintf("%s.0.header.%d.value", path, i)); ok { + config["value"] = aws.ToString(param.Value) + } else if v, ok := d.GetOk(fmt.Sprintf("%s.0.header.%d.value", path, i)); ok { config["value"] = v.(string) } headerParameters = append(headerParameters, config) @@ -708,12 +808,12 @@ func flattenConnectionHTTPParameters( var queryStringParameters []map[string]interface{} for i, param := range httpParameters.QueryStringParameters { config := make(map[string]interface{}) - config["is_value_secret"] = aws.BoolValue(param.IsValueSecret) - config["key"] = aws.StringValue(param.Key) + config["is_value_secret"] = param.IsValueSecret + config["key"] = aws.ToString(param.Key) if param.Value != nil { - config["value"] = aws.StringValue(param.Value) - } else if v, ok := resourceData.GetOk(fmt.Sprintf("%s.0.query_string.%d.value", path, i)); ok { + config["value"] = aws.ToString(param.Value) + } else if v, ok := d.GetOk(fmt.Sprintf("%s.0.query_string.%d.value", path, i)); ok { config["value"] = v.(string) } queryStringParameters = append(queryStringParameters, config) @@ -728,8 +828,8 @@ func flattenConnectionHTTPParameters( return result } -func expandUpdateConnectionAuthRequestParameters(config []interface{}) *eventbridge.UpdateConnectionAuthRequestParameters { - authParameters := &eventbridge.UpdateConnectionAuthRequestParameters{} +func expandUpdateConnectionAuthRequestParameters(config []interface{}) *types.UpdateConnectionAuthRequestParameters { + authParameters := &types.UpdateConnectionAuthRequestParameters{} for _, c := range config { param := c.(map[string]interface{}) if val, ok := param["api_key"]; ok { @@ -749,11 +849,11 @@ func expandUpdateConnectionAuthRequestParameters(config []interface{}) *eventbri return authParameters } -func expandUpdateConnectionAPIKeyAuthRequestParameters(config []interface{}) *eventbridge.UpdateConnectionApiKeyAuthRequestParameters { +func expandUpdateConnectionAPIKeyAuthRequestParameters(config []interface{}) *types.UpdateConnectionApiKeyAuthRequestParameters { if len(config) == 0 { return nil } - apiKeyAuthParameters := &eventbridge.UpdateConnectionApiKeyAuthRequestParameters{} + apiKeyAuthParameters := &types.UpdateConnectionApiKeyAuthRequestParameters{} for _, c := range config { param := c.(map[string]interface{}) if val, ok := param["key"].(string); ok && val != "" { @@ -766,11 +866,11 @@ func expandUpdateConnectionAPIKeyAuthRequestParameters(config []interface{}) *ev return apiKeyAuthParameters } -func expandUpdateConnectionBasicAuthRequestParameters(config []interface{}) *eventbridge.UpdateConnectionBasicAuthRequestParameters { +func expandUpdateConnectionBasicAuthRequestParameters(config []interface{}) *types.UpdateConnectionBasicAuthRequestParameters { if len(config) == 0 { return nil } - basicAuthParameters := &eventbridge.UpdateConnectionBasicAuthRequestParameters{} + basicAuthParameters := &types.UpdateConnectionBasicAuthRequestParameters{} for _, c := range config { param := c.(map[string]interface{}) if val, ok := param["username"].(string); ok && val != "" { @@ -783,18 +883,18 @@ func expandUpdateConnectionBasicAuthRequestParameters(config []interface{}) *eve return basicAuthParameters } -func expandUpdateConnectionOAuthAuthRequestParameters(config []interface{}) *eventbridge.UpdateConnectionOAuthRequestParameters { +func expandUpdateConnectionOAuthAuthRequestParameters(config []interface{}) *types.UpdateConnectionOAuthRequestParameters { if len(config) == 0 { return nil } - oAuthParameters := &eventbridge.UpdateConnectionOAuthRequestParameters{} + oAuthParameters := &types.UpdateConnectionOAuthRequestParameters{} for _, c := range config { param := c.(map[string]interface{}) if val, ok := param["authorization_endpoint"].(string); ok && val != "" { oAuthParameters.AuthorizationEndpoint = aws.String(val) } if val, ok := param["http_method"].(string); ok && val != "" { - oAuthParameters.HttpMethod = aws.String(val) + oAuthParameters.HttpMethod = types.ConnectionOAuthHttpMethod(val) } if val, ok := param["oauth_http_parameters"]; ok { oAuthParameters.OAuthHttpParameters = expandConnectionHTTPParameters(val.([]interface{})) @@ -806,8 +906,8 @@ func expandUpdateConnectionOAuthAuthRequestParameters(config []interface{}) *eve return oAuthParameters } -func expandUpdateConnectionOAuthClientRequestParameters(config []interface{}) *eventbridge.UpdateConnectionOAuthClientRequestParameters { - oAuthClientRequestParameters := &eventbridge.UpdateConnectionOAuthClientRequestParameters{} +func expandUpdateConnectionOAuthClientRequestParameters(config []interface{}) *types.UpdateConnectionOAuthClientRequestParameters { + oAuthClientRequestParameters := &types.UpdateConnectionOAuthClientRequestParameters{} for _, c := range config { param := c.(map[string]interface{}) if val, ok := param["client_id"].(string); ok && val != "" { diff --git a/internal/service/events/connection_test.go b/internal/service/events/connection_test.go index 456480446e3..c022c3933bc 100644 --- a/internal/service/events/connection_test.go +++ b/internal/service/events/connection_test.go @@ -10,8 +10,8 @@ import ( "testing" "github.com/YakDriver/regexache" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -580,7 +580,7 @@ func TestAccEventsConnection_disappears(t *testing.T) { func testAccCheckConnectionDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) for _, rs := range s.RootModule().Resources { if rs.Type != "aws_cloudwatch_event_connection" { @@ -597,7 +597,7 @@ func testAccCheckConnectionDestroy(ctx context.Context) resource.TestCheckFunc { return err } - return fmt.Errorf("EventBridge connection %s still exists", rs.Primary.ID) + return fmt.Errorf("EventBridge Connection %s still exists", rs.Primary.ID) } return nil @@ -611,7 +611,7 @@ func testAccCheckConnectionExists(ctx context.Context, n string, v *eventbridge. return fmt.Errorf("Not found: %s", n) } - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) output, err := tfevents.FindConnectionByName(ctx, conn, rs.Primary.ID) @@ -627,7 +627,7 @@ func testAccCheckConnectionExists(ctx context.Context, n string, v *eventbridge. func testAccCheckConnectionRecreated(i, j *eventbridge.DescribeConnectionOutput) resource.TestCheckFunc { return func(s *terraform.State) error { - if aws.StringValue(i.ConnectionArn) == aws.StringValue(j.ConnectionArn) { + if aws.ToString(i.ConnectionArn) == aws.ToString(j.ConnectionArn) { return fmt.Errorf("EventBridge Connection not recreated") } return nil @@ -636,7 +636,7 @@ func testAccCheckConnectionRecreated(i, j *eventbridge.DescribeConnectionOutput) func testAccCheckConnectionNotRecreated(i, j *eventbridge.DescribeConnectionOutput) resource.TestCheckFunc { return func(s *terraform.State) error { - if aws.StringValue(i.ConnectionArn) != aws.StringValue(j.ConnectionArn) { + if aws.ToString(i.ConnectionArn) != aws.ToString(j.ConnectionArn) { return fmt.Errorf("EventBridge Connection was recreated") } return nil diff --git a/internal/service/events/exports_test.go b/internal/service/events/exports_test.go index 2d733bb7aba..a41c9fe7414 100644 --- a/internal/service/events/exports_test.go +++ b/internal/service/events/exports_test.go @@ -9,9 +9,11 @@ var ( ResourceArchive = resourceArchive ResourceBus = resourceBus ResourceBusPolicy = resourceBusPolicy + ResourceConnection = resourceConnection FindAPIDestinationByName = findAPIDestinationByName FindArchiveByName = findArchiveByName + FindConnectionByName = findConnectionByName FindEventBusByName = findEventBusByName FindEventBusPolicyByName = findEventBusPolicyByName ) diff --git a/internal/service/events/find.go b/internal/service/events/find.go index fea8573a59f..bd2a9c713a0 100644 --- a/internal/service/events/find.go +++ b/internal/service/events/find.go @@ -11,34 +11,8 @@ import ( "github.com/aws/aws-sdk-go/service/eventbridge" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" - "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -func FindConnectionByName(ctx context.Context, conn *eventbridge.EventBridge, name string) (*eventbridge.DescribeConnectionOutput, error) { - input := &eventbridge.DescribeConnectionInput{ - Name: aws.String(name), - } - - output, err := conn.DescribeConnectionWithContext(ctx, input) - - if tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { - return nil, &retry.NotFoundError{ - LastError: err, - LastRequest: input, - } - } - - if err != nil { - return nil, err - } - - if output == nil { - return nil, tfresource.NewEmptyResultError(input) - } - - return output, nil -} - func FindTargetByThreePartKey(ctx context.Context, conn *eventbridge.EventBridge, busName, ruleName, targetID string) (*eventbridge.Target, error) { input := &eventbridge.ListTargetsByRuleInput{ Rule: aws.String(ruleName), diff --git a/internal/service/events/service_package_gen.go b/internal/service/events/service_package_gen.go index d16613e8dda..27f70d754e7 100644 --- a/internal/service/events/service_package_gen.go +++ b/internal/service/events/service_package_gen.go @@ -66,8 +66,9 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka Name: "Event Bus Policy", }, { - Factory: ResourceConnection, + Factory: resourceConnection, TypeName: "aws_cloudwatch_event_connection", + Name: "Connection", }, { Factory: ResourceEndpoint, diff --git a/internal/service/events/status.go b/internal/service/events/status.go deleted file mode 100644 index 37a7c3aef54..00000000000 --- a/internal/service/events/status.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package events - -import ( - "context" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" - "github.com/hashicorp/terraform-provider-aws/internal/tfresource" -) - -func statusConnectionState(ctx context.Context, conn *eventbridge.EventBridge, name string) retry.StateRefreshFunc { - return func() (interface{}, string, error) { - output, err := FindConnectionByName(ctx, conn, name) - - if tfresource.NotFound(err) { - return nil, "", nil - } - - if err != nil { - return nil, "", err - } - - return output, aws.StringValue(output.ConnectionState), nil - } -} diff --git a/internal/service/events/wait.go b/internal/service/events/wait.go deleted file mode 100644 index 0ab814c9fae..00000000000 --- a/internal/service/events/wait.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package events - -import ( - "context" - "time" - - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" -) - -const ( - connectionCreatedTimeout = 2 * time.Minute - connectionDeletedTimeout = 2 * time.Minute - connectionUpdatedTimeout = 2 * time.Minute -) - -func waitConnectionCreated(ctx context.Context, conn *eventbridge.EventBridge, id string) (*eventbridge.DescribeConnectionOutput, error) { - stateConf := &retry.StateChangeConf{ - Pending: []string{eventbridge.ConnectionStateCreating, eventbridge.ConnectionStateAuthorizing}, - Target: []string{eventbridge.ConnectionStateAuthorized, eventbridge.ConnectionStateDeauthorized}, - Refresh: statusConnectionState(ctx, conn, id), - Timeout: connectionCreatedTimeout, - } - - outputRaw, err := stateConf.WaitForStateContext(ctx) - - if v, ok := outputRaw.(*eventbridge.DescribeConnectionOutput); ok { - return v, err - } - - return nil, err -} - -func waitConnectionDeleted(ctx context.Context, conn *eventbridge.EventBridge, id string) (*eventbridge.DescribeConnectionOutput, error) { - stateConf := &retry.StateChangeConf{ - Pending: []string{eventbridge.ConnectionStateDeleting}, - Target: []string{}, - Refresh: statusConnectionState(ctx, conn, id), - Timeout: connectionDeletedTimeout, - } - - outputRaw, err := stateConf.WaitForStateContext(ctx) - - if v, ok := outputRaw.(*eventbridge.DescribeConnectionOutput); ok { - return v, err - } - - return nil, err -} - -func waitConnectionUpdated(ctx context.Context, conn *eventbridge.EventBridge, id string) (*eventbridge.DescribeConnectionOutput, error) { - stateConf := &retry.StateChangeConf{ - Pending: []string{eventbridge.ConnectionStateUpdating, eventbridge.ConnectionStateAuthorizing, eventbridge.ConnectionStateDeauthorizing}, - Target: []string{eventbridge.ConnectionStateAuthorized, eventbridge.ConnectionStateDeauthorized}, - Refresh: statusConnectionState(ctx, conn, id), - Timeout: connectionUpdatedTimeout, - } - - outputRaw, err := stateConf.WaitForStateContext(ctx) - - if v, ok := outputRaw.(*eventbridge.DescribeConnectionOutput); ok { - return v, err - } - - return nil, err -} From e83627e34b6737eb3f6afb23a505d28738151bce Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 15 Apr 2024 12:21:33 -0400 Subject: [PATCH 12/35] d/aws_cloudwatch_event_connection: Migrate to AWS SDK for Go v2. --- .../service/events/connection_data_source.go | 38 +++++++------------ .../service/events/service_package_gen.go | 3 +- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/internal/service/events/connection_data_source.go b/internal/service/events/connection_data_source.go index 4bae5239d03..388940c4377 100644 --- a/internal/service/events/connection_data_source.go +++ b/internal/service/events/connection_data_source.go @@ -5,26 +5,19 @@ package events import ( "context" - "log" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKDataSource("aws_cloudwatch_event_connection") -func DataSourceConnection() *schema.Resource { +// @SDKDataSource("aws_cloudwatch_event_connection", name="Connection) +func dataSourceConnection() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceConnectionRead, Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - }, "arn": { Type: schema.TypeString, Computed: true, @@ -33,6 +26,10 @@ func DataSourceConnection() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "name": { + Type: schema.TypeString, + Required: true, + }, "secret_arn": { Type: schema.TypeString, Computed: true, @@ -43,28 +40,21 @@ func DataSourceConnection() *schema.Resource { func dataSourceConnectionRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - d.SetId(d.Get("name").(string)) - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - input := &eventbridge.DescribeConnectionInput{ - Name: aws.String(d.Id()), - } + name := d.Get("name").(string) + output, err := findConnectionByName(ctx, conn, name) - log.Printf("[DEBUG] Reading EventBridge connection (%s)", d.Id()) - output, err := conn.DescribeConnectionWithContext(ctx, input) if err != nil { - return sdkdiag.AppendErrorf(diags, "getting EventBridge connection (%s): %s", d.Id(), err) - } - - if output == nil { - return sdkdiag.AppendErrorf(diags, "getting EventBridge connection (%s): empty response", d.Id()) + return sdkdiag.AppendErrorf(diags, "reading EventBridge Connection (%s): %s", name, err) } - log.Printf("[DEBUG] Found EventBridge connection: %#v", *output) + d.SetId(name) d.Set("arn", output.ConnectionArn) - d.Set("secret_arn", output.SecretArn) - d.Set("name", output.Name) d.Set("authorization_type", output.AuthorizationType) + d.Set("name", output.Name) + d.Set("secret_arn", output.SecretArn) + return diags } diff --git a/internal/service/events/service_package_gen.go b/internal/service/events/service_package_gen.go index 27f70d754e7..e43b58b435c 100644 --- a/internal/service/events/service_package_gen.go +++ b/internal/service/events/service_package_gen.go @@ -30,8 +30,9 @@ func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePac Name: "Event Bus", }, { - Factory: DataSourceConnection, + Factory: dataSourceConnection, TypeName: "aws_cloudwatch_event_connection", + Name: "Connection", }, { Factory: DataSourceSource, From ea5b2946b32154076868ed72d2896672ede17672 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 15 Apr 2024 14:33:09 -0400 Subject: [PATCH 13/35] r/aws_cloudwatch_event_endpoint: Migrate to AWS SDK for Go v2. --- internal/service/events/endpoint.go | 156 +++++++++--------- internal/service/events/endpoint_test.go | 6 +- internal/service/events/errors.go | 8 + internal/service/events/exports_test.go | 2 + .../service/events/service_package_gen.go | 2 +- 5 files changed, 90 insertions(+), 84 deletions(-) create mode 100644 internal/service/events/errors.go diff --git a/internal/service/events/endpoint.go b/internal/service/events/endpoint.go index b6065dbdb72..907e8e614fb 100644 --- a/internal/service/events/endpoint.go +++ b/internal/service/events/endpoint.go @@ -10,21 +10,23 @@ import ( "time" "github.com/YakDriver/regexache" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/service/eventbridge/types" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/enum" + "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/internal/verify" ) // @SDKResource("aws_cloudwatch_event_endpoint", name="Global Endpoint") -func ResourceEndpoint() *schema.Resource { +func resourceEndpoint() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceEndpointCreate, ReadWithoutTimeout: resourceEndpointRead, @@ -77,10 +79,10 @@ func ResourceEndpoint() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "state": { - Type: schema.TypeString, - Optional: true, - Default: eventbridge.ReplicationStateEnabled, - ValidateFunc: validation.StringInSlice(eventbridge.ReplicationState_Values(), false), + Type: schema.TypeString, + Optional: true, + Default: types.ReplicationStateEnabled, + ValidateDiagFunc: enum.Validate[types.ReplicationState](), }, }, }, @@ -142,17 +144,14 @@ func ResourceEndpoint() *schema.Resource { } func resourceEndpointCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - const ( - timeout = 2 * time.Minute - ) var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) name := d.Get("name").(string) input := &eventbridge.CreateEndpointInput{ EventBuses: expandEndpointEventBuses(d.Get("event_bus").([]interface{})), - RoutingConfig: expandRoutingConfig(d.Get("routing_config").([]interface{})[0].(map[string]interface{})), Name: aws.String(name), + RoutingConfig: expandRoutingConfig(d.Get("routing_config").([]interface{})[0].(map[string]interface{})), } if v, ok := d.GetOk("description"); ok { @@ -168,8 +167,8 @@ func resourceEndpointCreate(ctx context.Context, d *schema.ResourceData, meta in } _, err := tfresource.RetryWhenAWSErrMessageContains(ctx, propagationTimeout, func() (interface{}, error) { - return conn.CreateEndpointWithContext(ctx, input) - }, "ValidationException", "cannot be assumed by principal") + return conn.CreateEndpoint(ctx, input) + }, errCodeValidationException, "cannot be assumed by principal") if err != nil { return sdkdiag.AppendErrorf(diags, "creating EventBridge Global Endpoint (%s): %s", name, err) @@ -177,6 +176,9 @@ func resourceEndpointCreate(ctx context.Context, d *schema.ResourceData, meta in d.SetId(name) + const ( + timeout = 2 * time.Minute + ) if _, err := waitEndpointCreated(ctx, conn, d.Id(), timeout); err != nil { return sdkdiag.AppendErrorf(diags, "waiting for EventBridge Global Endpoint (%s) create: %s", d.Id(), err) } @@ -186,9 +188,9 @@ func resourceEndpointCreate(ctx context.Context, d *schema.ResourceData, meta in func resourceEndpointRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - output, err := FindEndpointByName(ctx, conn, d.Id()) + output, err := findEndpointByName(ctx, conn, d.Id()) if !d.IsNewResource() && tfresource.NotFound(err) { log.Printf("[WARN] EventBridge Global Endpoint (%s) not found, removing from state", d.Id()) @@ -227,11 +229,8 @@ func resourceEndpointRead(ctx context.Context, d *schema.ResourceData, meta inte } func resourceEndpointUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - const ( - timeout = 2 * time.Minute - ) var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) input := &eventbridge.UpdateEndpointInput{ Name: aws.String(d.Id()), @@ -259,12 +258,15 @@ func resourceEndpointUpdate(ctx context.Context, d *schema.ResourceData, meta in input.RoutingConfig = expandRoutingConfig(d.Get("routing_config").([]interface{})[0].(map[string]interface{})) } - _, err := conn.UpdateEndpointWithContext(ctx, input) + _, err := conn.UpdateEndpoint(ctx, input) if err != nil { return sdkdiag.AppendErrorf(diags, "updating EventBridge Global Endpoint (%s): %s", d.Id(), err) } + const ( + timeout = 2 * time.Minute + ) if _, err := waitEndpointUpdated(ctx, conn, d.Id(), timeout); err != nil { return sdkdiag.AppendErrorf(diags, "waiting for EventBridge Global Endpoint (%s) update: %s", d.Id(), err) } @@ -273,18 +275,15 @@ func resourceEndpointUpdate(ctx context.Context, d *schema.ResourceData, meta in } func resourceEndpointDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - const ( - timeout = 2 * time.Minute - ) var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) log.Printf("[INFO] Deleting EventBridge Global Endpoint: %s", d.Id()) - _, err := conn.DeleteEndpointWithContext(ctx, &eventbridge.DeleteEndpointInput{ + _, err := conn.DeleteEndpoint(ctx, &eventbridge.DeleteEndpointInput{ Name: aws.String(d.Id()), }) - if tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { + if errs.IsA[*types.ResourceNotFoundException](err) { return diags } @@ -292,6 +291,9 @@ func resourceEndpointDelete(ctx context.Context, d *schema.ResourceData, meta in return sdkdiag.AppendErrorf(diags, "deleting EventBridge Global Endpoint (%s): %s", d.Id(), err) } + const ( + timeout = 2 * time.Minute + ) if _, err := waitEndpointDeleted(ctx, conn, d.Id(), timeout); err != nil { return sdkdiag.AppendErrorf(diags, "waiting for EventBridge Global Endpoint (%s) delete: %s", d.Id(), err) } @@ -299,14 +301,14 @@ func resourceEndpointDelete(ctx context.Context, d *schema.ResourceData, meta in return diags } -func FindEndpointByName(ctx context.Context, conn *eventbridge.EventBridge, name string) (*eventbridge.DescribeEndpointOutput, error) { +func findEndpointByName(ctx context.Context, conn *eventbridge.Client, name string) (*eventbridge.DescribeEndpointOutput, error) { input := &eventbridge.DescribeEndpointInput{ Name: aws.String(name), } - output, err := conn.DescribeEndpointWithContext(ctx, input) + output, err := conn.DescribeEndpoint(ctx, input) - if tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { + if errs.IsA[*types.ResourceNotFoundException](err) { return nil, &retry.NotFoundError{ LastError: err, LastRequest: input, @@ -324,9 +326,9 @@ func FindEndpointByName(ctx context.Context, conn *eventbridge.EventBridge, name return output, nil } -func statusEndpointState(ctx context.Context, conn *eventbridge.EventBridge, name string) retry.StateRefreshFunc { +func statusEndpointState(ctx context.Context, conn *eventbridge.Client, name string) retry.StateRefreshFunc { return func() (interface{}, string, error) { - output, err := FindEndpointByName(ctx, conn, name) + output, err := findEndpointByName(ctx, conn, name) if tfresource.NotFound(err) { return nil, "", nil @@ -336,14 +338,14 @@ func statusEndpointState(ctx context.Context, conn *eventbridge.EventBridge, nam return nil, "", err } - return output, aws.StringValue(output.State), nil + return output, string(output.State), nil } } -func waitEndpointCreated(ctx context.Context, conn *eventbridge.EventBridge, name string, timeout time.Duration) (*eventbridge.DescribeEndpointOutput, error) { +func waitEndpointCreated(ctx context.Context, conn *eventbridge.Client, name string, timeout time.Duration) (*eventbridge.DescribeEndpointOutput, error) { stateConf := &retry.StateChangeConf{ - Pending: []string{eventbridge.EndpointStateCreating}, - Target: []string{eventbridge.EndpointStateActive}, + Pending: enum.Slice(types.EndpointStateCreating), + Target: enum.Slice(types.EndpointStateActive), Refresh: statusEndpointState(ctx, conn, name), Timeout: timeout, } @@ -351,7 +353,7 @@ func waitEndpointCreated(ctx context.Context, conn *eventbridge.EventBridge, nam outputRaw, err := stateConf.WaitForStateContext(ctx) if output, ok := outputRaw.(*eventbridge.DescribeEndpointOutput); ok { - tfresource.SetLastError(err, errors.New(aws.StringValue(output.StateReason))) + tfresource.SetLastError(err, errors.New(aws.ToString(output.StateReason))) return output, err } @@ -359,10 +361,10 @@ func waitEndpointCreated(ctx context.Context, conn *eventbridge.EventBridge, nam return nil, err } -func waitEndpointUpdated(ctx context.Context, conn *eventbridge.EventBridge, name string, timeout time.Duration) (*eventbridge.DescribeEndpointOutput, error) { +func waitEndpointUpdated(ctx context.Context, conn *eventbridge.Client, name string, timeout time.Duration) (*eventbridge.DescribeEndpointOutput, error) { stateConf := &retry.StateChangeConf{ - Pending: []string{eventbridge.EndpointStateUpdating}, - Target: []string{eventbridge.EndpointStateActive}, + Pending: enum.Slice(types.EndpointStateUpdating), + Target: enum.Slice(types.EndpointStateActive), Refresh: statusEndpointState(ctx, conn, name), Timeout: timeout, } @@ -370,7 +372,7 @@ func waitEndpointUpdated(ctx context.Context, conn *eventbridge.EventBridge, nam outputRaw, err := stateConf.WaitForStateContext(ctx) if output, ok := outputRaw.(*eventbridge.DescribeEndpointOutput); ok { - tfresource.SetLastError(err, errors.New(aws.StringValue(output.StateReason))) + tfresource.SetLastError(err, errors.New(aws.ToString(output.StateReason))) return output, err } @@ -378,9 +380,9 @@ func waitEndpointUpdated(ctx context.Context, conn *eventbridge.EventBridge, nam return nil, err } -func waitEndpointDeleted(ctx context.Context, conn *eventbridge.EventBridge, name string, timeout time.Duration) (*eventbridge.DescribeEndpointOutput, error) { +func waitEndpointDeleted(ctx context.Context, conn *eventbridge.Client, name string, timeout time.Duration) (*eventbridge.DescribeEndpointOutput, error) { stateConf := &retry.StateChangeConf{ - Pending: []string{eventbridge.EndpointStateDeleting}, + Pending: enum.Slice(types.EndpointStateDeleting), Target: []string{}, Refresh: statusEndpointState(ctx, conn, name), Timeout: timeout, @@ -389,7 +391,7 @@ func waitEndpointDeleted(ctx context.Context, conn *eventbridge.EventBridge, nam outputRaw, err := stateConf.WaitForStateContext(ctx) if output, ok := outputRaw.(*eventbridge.DescribeEndpointOutput); ok { - tfresource.SetLastError(err, errors.New(aws.StringValue(output.StateReason))) + tfresource.SetLastError(err, errors.New(aws.ToString(output.StateReason))) return output, err } @@ -397,12 +399,12 @@ func waitEndpointDeleted(ctx context.Context, conn *eventbridge.EventBridge, nam return nil, err } -func expandEndpointEventBus(tfMap map[string]interface{}) *eventbridge.EndpointEventBus { +func expandEndpointEventBus(tfMap map[string]interface{}) *types.EndpointEventBus { if tfMap == nil { return nil } - apiObject := &eventbridge.EndpointEventBus{} + apiObject := &types.EndpointEventBus{} if v, ok := tfMap["event_bus_arn"].(string); ok && v != "" { apiObject.EventBusArn = aws.String(v) @@ -411,12 +413,12 @@ func expandEndpointEventBus(tfMap map[string]interface{}) *eventbridge.EndpointE return apiObject } -func expandEndpointEventBuses(tfList []interface{}) []*eventbridge.EndpointEventBus { +func expandEndpointEventBuses(tfList []interface{}) []types.EndpointEventBus { if len(tfList) == 0 { return nil } - var apiObjects []*eventbridge.EndpointEventBus + var apiObjects []types.EndpointEventBus for _, tfMapRaw := range tfList { tfMap, ok := tfMapRaw.(map[string]interface{}) @@ -431,32 +433,32 @@ func expandEndpointEventBuses(tfList []interface{}) []*eventbridge.EndpointEvent continue } - apiObjects = append(apiObjects, apiObject) + apiObjects = append(apiObjects, *apiObject) } return apiObjects } -func expandReplicationConfig(tfMap map[string]interface{}) *eventbridge.ReplicationConfig { +func expandReplicationConfig(tfMap map[string]interface{}) *types.ReplicationConfig { if tfMap == nil { return nil } - apiObject := &eventbridge.ReplicationConfig{} + apiObject := &types.ReplicationConfig{} if v, ok := tfMap["state"].(string); ok && v != "" { - apiObject.State = aws.String(v) + apiObject.State = types.ReplicationState(v) } return apiObject } -func expandRoutingConfig(tfMap map[string]interface{}) *eventbridge.RoutingConfig { +func expandRoutingConfig(tfMap map[string]interface{}) *types.RoutingConfig { if tfMap == nil { return nil } - apiObject := &eventbridge.RoutingConfig{} + apiObject := &types.RoutingConfig{} if v, ok := tfMap["failover_config"].([]interface{}); ok && len(v) > 0 && v[0] != nil { apiObject.FailoverConfig = expandFailoverConfig(v[0].(map[string]interface{})) @@ -465,12 +467,12 @@ func expandRoutingConfig(tfMap map[string]interface{}) *eventbridge.RoutingConfi return apiObject } -func expandFailoverConfig(tfMap map[string]interface{}) *eventbridge.FailoverConfig { +func expandFailoverConfig(tfMap map[string]interface{}) *types.FailoverConfig { if tfMap == nil { return nil } - apiObject := &eventbridge.FailoverConfig{} + apiObject := &types.FailoverConfig{} if v, ok := tfMap["primary"].([]interface{}); ok && len(v) > 0 && v[0] != nil { apiObject.Primary = expandPrimary(v[0].(map[string]interface{})) @@ -483,12 +485,12 @@ func expandFailoverConfig(tfMap map[string]interface{}) *eventbridge.FailoverCon return apiObject } -func expandPrimary(tfMap map[string]interface{}) *eventbridge.Primary { +func expandPrimary(tfMap map[string]interface{}) *types.Primary { if tfMap == nil { return nil } - apiObject := &eventbridge.Primary{} + apiObject := &types.Primary{} if v, ok := tfMap["health_check"].(string); ok && v != "" { apiObject.HealthCheck = aws.String(v) @@ -497,12 +499,12 @@ func expandPrimary(tfMap map[string]interface{}) *eventbridge.Primary { return apiObject } -func expandSecondary(tfMap map[string]interface{}) *eventbridge.Secondary { +func expandSecondary(tfMap map[string]interface{}) *types.Secondary { if tfMap == nil { return nil } - apiObject := &eventbridge.Secondary{} + apiObject := &types.Secondary{} if v, ok := tfMap["route"].(string); ok && v != "" { apiObject.Route = aws.String(v) @@ -511,7 +513,7 @@ func expandSecondary(tfMap map[string]interface{}) *eventbridge.Secondary { return apiObject } -func flattenEndpointEventBus(apiObject *eventbridge.EndpointEventBus) map[string]interface{} { +func flattenEndpointEventBus(apiObject *types.EndpointEventBus) map[string]interface{} { if apiObject == nil { return nil } @@ -519,13 +521,13 @@ func flattenEndpointEventBus(apiObject *eventbridge.EndpointEventBus) map[string tfMap := map[string]interface{}{} if v := apiObject.EventBusArn; v != nil { - tfMap["event_bus_arn"] = aws.StringValue(v) + tfMap["event_bus_arn"] = aws.ToString(v) } return tfMap } -func flattenEndpointEventBuses(apiObjects []*eventbridge.EndpointEventBus) []interface{} { +func flattenEndpointEventBuses(apiObjects []types.EndpointEventBus) []interface{} { if len(apiObjects) == 0 { return nil } @@ -533,31 +535,25 @@ func flattenEndpointEventBuses(apiObjects []*eventbridge.EndpointEventBus) []int var tfList []interface{} for _, apiObject := range apiObjects { - if apiObject == nil { - continue - } - - tfList = append(tfList, flattenEndpointEventBus(apiObject)) + tfList = append(tfList, flattenEndpointEventBus(&apiObject)) } return tfList } -func flattenReplicationConfig(apiObject *eventbridge.ReplicationConfig) map[string]interface{} { +func flattenReplicationConfig(apiObject *types.ReplicationConfig) map[string]interface{} { if apiObject == nil { return nil } - tfMap := map[string]interface{}{} - - if v := apiObject.State; v != nil { - tfMap["state"] = aws.StringValue(v) + tfMap := map[string]interface{}{ + "state": apiObject.State, } return tfMap } -func flattenRoutingConfig(apiObject *eventbridge.RoutingConfig) map[string]interface{} { +func flattenRoutingConfig(apiObject *types.RoutingConfig) map[string]interface{} { if apiObject == nil { return nil } @@ -571,7 +567,7 @@ func flattenRoutingConfig(apiObject *eventbridge.RoutingConfig) map[string]inter return tfMap } -func flattenFailoverConfig(apiObject *eventbridge.FailoverConfig) map[string]interface{} { +func flattenFailoverConfig(apiObject *types.FailoverConfig) map[string]interface{} { if apiObject == nil { return nil } @@ -589,7 +585,7 @@ func flattenFailoverConfig(apiObject *eventbridge.FailoverConfig) map[string]int return tfMap } -func flattenPrimary(apiObject *eventbridge.Primary) map[string]interface{} { +func flattenPrimary(apiObject *types.Primary) map[string]interface{} { if apiObject == nil { return nil } @@ -597,13 +593,13 @@ func flattenPrimary(apiObject *eventbridge.Primary) map[string]interface{} { tfMap := map[string]interface{}{} if v := apiObject.HealthCheck; v != nil { - tfMap["health_check"] = aws.StringValue(v) + tfMap["health_check"] = aws.ToString(v) } return tfMap } -func flattenSecondary(apiObject *eventbridge.Secondary) map[string]interface{} { +func flattenSecondary(apiObject *types.Secondary) map[string]interface{} { if apiObject == nil { return nil } @@ -611,7 +607,7 @@ func flattenSecondary(apiObject *eventbridge.Secondary) map[string]interface{} { tfMap := map[string]interface{}{} if v := apiObject.Route; v != nil { - tfMap["route"] = aws.StringValue(v) + tfMap["route"] = aws.ToString(v) } return tfMap diff --git a/internal/service/events/endpoint_test.go b/internal/service/events/endpoint_test.go index e3fa5842770..3662026e269 100644 --- a/internal/service/events/endpoint_test.go +++ b/internal/service/events/endpoint_test.go @@ -8,7 +8,7 @@ import ( "fmt" "testing" - "github.com/aws/aws-sdk-go/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" @@ -262,7 +262,7 @@ func TestAccEventsEndpoint_updateRoutingConfig(t *testing.T) { func testAccCheckEndpointDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) for _, rs := range s.RootModule().Resources { if rs.Type != "aws_cloudwatch_event_endpoint" { @@ -293,7 +293,7 @@ func testAccCheckEndpointExists(ctx context.Context, n string, v *eventbridge.De return fmt.Errorf("Not found: %s", n) } - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) output, err := tfevents.FindEndpointByName(ctx, conn, rs.Primary.ID) diff --git a/internal/service/events/errors.go b/internal/service/events/errors.go new file mode 100644 index 00000000000..68a69833235 --- /dev/null +++ b/internal/service/events/errors.go @@ -0,0 +1,8 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package events + +const ( + errCodeValidationException = "ValidationException" +) diff --git a/internal/service/events/exports_test.go b/internal/service/events/exports_test.go index a41c9fe7414..0dc031f0235 100644 --- a/internal/service/events/exports_test.go +++ b/internal/service/events/exports_test.go @@ -10,10 +10,12 @@ var ( ResourceBus = resourceBus ResourceBusPolicy = resourceBusPolicy ResourceConnection = resourceConnection + ResourceEndpoint = resourceEndpoint FindAPIDestinationByName = findAPIDestinationByName FindArchiveByName = findArchiveByName FindConnectionByName = findConnectionByName + FindEndpointByName = findEndpointByName FindEventBusByName = findEventBusByName FindEventBusPolicyByName = findEventBusPolicyByName ) diff --git a/internal/service/events/service_package_gen.go b/internal/service/events/service_package_gen.go index e43b58b435c..4be9c6ab35b 100644 --- a/internal/service/events/service_package_gen.go +++ b/internal/service/events/service_package_gen.go @@ -72,7 +72,7 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka Name: "Connection", }, { - Factory: ResourceEndpoint, + Factory: resourceEndpoint, TypeName: "aws_cloudwatch_event_endpoint", Name: "Global Endpoint", }, From 485e18d66070541292ddcb04315c471e938aa7bf Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 15 Apr 2024 15:05:35 -0400 Subject: [PATCH 14/35] r/aws_cloudwatch_event_permission: Migrate to AWS SDK for Go v2. --- internal/service/events/exports_test.go | 14 +- internal/service/events/id.go | 26 -- internal/service/events/id_test.go | 86 ----- internal/service/events/permission.go | 293 ++++++++---------- internal/service/events/permission_test.go | 80 +---- .../service/events/service_package_gen.go | 3 +- 6 files changed, 149 insertions(+), 353 deletions(-) diff --git a/internal/service/events/exports_test.go b/internal/service/events/exports_test.go index 0dc031f0235..1a3e0d2cfe7 100644 --- a/internal/service/events/exports_test.go +++ b/internal/service/events/exports_test.go @@ -11,11 +11,13 @@ var ( ResourceBusPolicy = resourceBusPolicy ResourceConnection = resourceConnection ResourceEndpoint = resourceEndpoint + ResourcePermission = resourcePermission - FindAPIDestinationByName = findAPIDestinationByName - FindArchiveByName = findArchiveByName - FindConnectionByName = findConnectionByName - FindEndpointByName = findEndpointByName - FindEventBusByName = findEventBusByName - FindEventBusPolicyByName = findEventBusPolicyByName + FindAPIDestinationByName = findAPIDestinationByName + FindArchiveByName = findArchiveByName + FindConnectionByName = findConnectionByName + FindEndpointByName = findEndpointByName + FindEventBusByName = findEventBusByName + FindEventBusPolicyByName = findEventBusPolicyByName + FindPermissionByTwoPartKey = findPermissionByTwoPartKey ) diff --git a/internal/service/events/id.go b/internal/service/events/id.go index 8d563b11d78..95864a447fe 100644 --- a/internal/service/events/id.go +++ b/internal/service/events/id.go @@ -15,32 +15,6 @@ var ( partnerEventBusPattern = regexache.MustCompile(`^(?:arn:aws[\w-]*:events:[a-z]{2}-[a-z]+-[\w-]+:[0-9]{12}:event-bus\/)?aws\.partner(/[0-9A-Za-z_.-]+){2,}$`) ) -const permissionResourceIDSeparator = "/" - -func PermissionCreateResourceID(eventBusName, statementID string) string { - if eventBusName == "" || eventBusName == DefaultEventBusName { - return statementID - } - - parts := []string{eventBusName, statementID} - id := strings.Join(parts, permissionResourceIDSeparator) - - return id -} - -func PermissionParseResourceID(id string) (string, string, error) { - parts := strings.Split(id, permissionResourceIDSeparator) - - if len(parts) == 1 && parts[0] != "" { - return DefaultEventBusName, parts[0], nil - } - if len(parts) == 2 && parts[0] != "" && parts[1] != "" { - return parts[0], parts[1], nil - } - - return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected EVENTBUSNAME%[2]sSTATEMENTID or STATEMENTID", id, permissionResourceIDSeparator) -} - const ruleResourceIDSeparator = "/" func RuleCreateResourceID(eventBusName, ruleName string) string { diff --git a/internal/service/events/id_test.go b/internal/service/events/id_test.go index ba568bfcf40..0677f564363 100644 --- a/internal/service/events/id_test.go +++ b/internal/service/events/id_test.go @@ -9,92 +9,6 @@ import ( tfevents "github.com/hashicorp/terraform-provider-aws/internal/service/events" ) -func TestPermissionParseResourceID(t *testing.T) { - t.Parallel() - - testCases := []struct { - TestName string - InputID string - ExpectedError bool - ExpectedPart0 string - ExpectedPart1 string - }{ - { - TestName: "empty ID", - InputID: "", - ExpectedError: true, - }, - { - TestName: "single part", - InputID: "TestStatement", - ExpectedPart0: tfevents.DefaultEventBusName, - ExpectedPart1: "TestStatement", - }, - { - TestName: "two parts", - InputID: tfevents.PermissionCreateResourceID("TestEventBus", "TestStatement"), - ExpectedPart0: "TestEventBus", - ExpectedPart1: "TestStatement", - }, - { - TestName: "two parts with default event bus", - InputID: tfevents.PermissionCreateResourceID(tfevents.DefaultEventBusName, "TestStatement"), - ExpectedPart0: tfevents.DefaultEventBusName, - ExpectedPart1: "TestStatement", - }, - { - TestName: "partner event bus", - InputID: "aws.partner/example.com/Test/TestStatement", - ExpectedError: true, - }, - { - TestName: "empty both parts", - InputID: "/", - ExpectedError: true, - }, - { - TestName: "empty first part", - InputID: "/TestStatement", - ExpectedError: true, - }, - { - TestName: "empty second part", - InputID: "TestEventBus/", - ExpectedError: true, - }, - { - TestName: "three parts", - InputID: "TestEventBus/TestStatement/Suffix", - ExpectedError: true, - }, - } - - for _, testCase := range testCases { - testCase := testCase - t.Run(testCase.TestName, func(t *testing.T) { - t.Parallel() - - gotPart0, gotPart1, err := tfevents.PermissionParseResourceID(testCase.InputID) - - if err == nil && testCase.ExpectedError { - t.Fatalf("expected error, got no error") - } - - if err != nil && !testCase.ExpectedError { - t.Fatalf("got unexpected error: %s", err) - } - - if gotPart0 != testCase.ExpectedPart0 { - t.Errorf("got part 0 %s, expected %s", gotPart0, testCase.ExpectedPart0) - } - - if gotPart1 != testCase.ExpectedPart1 { - t.Errorf("got part 1 %s, expected %s", gotPart1, testCase.ExpectedPart1) - } - }) - } -} - func TestRuleParseResourceID(t *testing.T) { t.Parallel() diff --git a/internal/service/events/permission.go b/internal/service/events/permission.go index 6e338084f78..73e2c4bee1e 100644 --- a/internal/service/events/permission.go +++ b/internal/service/events/permission.go @@ -8,29 +8,31 @@ import ( "encoding/json" "fmt" "log" + "strings" "github.com/YakDriver/regexache" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/arn" - "github.com/aws/aws-sdk-go/aws/awsutil" - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/arn" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/service/eventbridge/types" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -// @SDKResource("aws_cloudwatch_event_permission") -func ResourcePermission() *schema.Resource { +// @SDKResource("aws_cloudwatch_event_permission", name="Permission") +func resourcePermission() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourcePermissionCreate, ReadWithoutTimeout: resourcePermissionRead, UpdateWithoutTimeout: resourcePermissionUpdate, DeleteWithoutTimeout: resourcePermissionDelete, + Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, @@ -90,12 +92,12 @@ func ResourcePermission() *schema.Resource { func resourcePermissionCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) eventBusName := d.Get("event_bus_name").(string) statementID := d.Get("statement_id").(string) - - input := eventbridge.PutPermissionInput{ + id := permissionCreateResourceID(eventBusName, statementID) + input := &eventbridge.PutPermissionInput{ Action: aws.String(d.Get("action").(string)), Condition: expandCondition(d.Get("condition").([]interface{})), EventBusName: aws.String(eventBusName), @@ -103,13 +105,12 @@ func resourcePermissionCreate(ctx context.Context, d *schema.ResourceData, meta StatementId: aws.String(statementID), } - log.Printf("[DEBUG] Creating EventBridge permission: %s", input) - _, err := conn.PutPermissionWithContext(ctx, &input) + _, err := conn.PutPermission(ctx, input) + if err != nil { - return sdkdiag.AppendErrorf(diags, "Creating EventBridge permission failed: %s", err) + return sdkdiag.AppendErrorf(diags, "creating EventBridge Permission (%s): %s", id, err) } - id := PermissionCreateResourceID(eventBusName, statementID) d.SetId(id) return append(diags, resourcePermissionRead(ctx, d, meta)...) @@ -118,60 +119,34 @@ func resourcePermissionCreate(ctx context.Context, d *schema.ResourceData, meta // See also: https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_DescribeEventBus.html func resourcePermissionRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - eventBusName, statementID, err := PermissionParseResourceID(d.Id()) + eventBusName, statementID, err := permissionParseResourceID(d.Id()) if err != nil { - return sdkdiag.AppendErrorf(diags, "reading EventBridge permission (%s): %s", d.Id(), err) - } - input := eventbridge.DescribeEventBusInput{ - Name: aws.String(eventBusName), + return sdkdiag.AppendFromErr(diags, err) } - var output *eventbridge.DescribeEventBusOutput - var policyStatement *PermissionPolicyStatement - - // Especially with concurrent PutPermission calls there can be a slight delay - err = retry.RetryContext(ctx, propagationTimeout, func() *retry.RetryError { - log.Printf("[DEBUG] Reading EventBridge bus: %s", input) - output, err = conn.DescribeEventBusWithContext(ctx, &input) - if err != nil { - return retry.NonRetryableError(fmt.Errorf("reading EventBridge permission (%s) failed: %w", d.Id(), err)) - } - policyStatement, err = getPolicyStatement(output, statementID) - if err != nil { - return retry.RetryableError(err) - } - return nil + outputRaw, err := tfresource.RetryWhenNotFound(ctx, propagationTimeout, func() (interface{}, error) { + return findPermissionByTwoPartKey(ctx, conn, eventBusName, statementID) }) - if tfresource.TimedOut(err) { - output, err = conn.DescribeEventBusWithContext(ctx, &input) - if output != nil { - policyStatement, err = getPolicyStatement(output, statementID) - } - } - if !d.IsNewResource() && tfresource.NotFound(err) { - log.Printf("[WARN] EventBridge permission (%s) not found, removing from state", d.Id()) + log.Printf("[WARN] EventBridge Permission (%s) not found, removing from state", d.Id()) d.SetId("") return diags } + if err != nil { - return sdkdiag.AppendErrorf(diags, "reading EventBridge permission (%s): %s", d.Id(), err) + return sdkdiag.AppendErrorf(diags, "reading EventBridge Permission (%s): %s", d.Id(), err) } - d.Set("action", policyStatement.Action) - busName := aws.StringValue(output.Name) - if busName == "" { - busName = DefaultEventBusName - } - d.Set("event_bus_name", busName) + policyStatement := outputRaw.(*permissionPolicyStatement) + d.Set("action", policyStatement.Action) if err := d.Set("condition", flattenPermissionPolicyStatementCondition(policyStatement.Condition)); err != nil { return sdkdiag.AppendErrorf(diags, "setting condition: %s", err) } - + d.Set("event_bus_name", eventBusName) switch principal := policyStatement.Principal.(type) { case string: d.Set("principal", principal) @@ -179,9 +154,8 @@ func resourcePermissionRead(ctx context.Context, d *schema.ResourceData, meta in if v, ok := principal["AWS"].(string); ok { if arn.IsARN(v) { principalARN, err := arn.Parse(v) - if err != nil { - return sdkdiag.AppendErrorf(diags, "parsing EventBridge Permission (%s) principal as ARN (%s): %s", d.Id(), v, err) + return sdkdiag.AppendFromErr(diags, err) } d.Set("principal", principalARN.AccountID) @@ -190,39 +164,21 @@ func resourcePermissionRead(ctx context.Context, d *schema.ResourceData, meta in } } } - d.Set("statement_id", policyStatement.Sid) return diags } -func getPolicyStatement(output *eventbridge.DescribeEventBusOutput, statementID string) (*PermissionPolicyStatement, error) { - var policyDoc PermissionPolicyDoc - - if output == nil || output.Policy == nil { - return nil, &retry.NotFoundError{ - Message: fmt.Sprintf("EventBridge permission %q not found", statementID), - LastResponse: output, - } - } - - err := json.Unmarshal([]byte(*output.Policy), &policyDoc) - if err != nil { - return nil, fmt.Errorf("reading EventBridge permission (%s): %w", statementID, err) - } - - return FindPermissionPolicyStatementByID(&policyDoc, statementID) -} - func resourcePermissionUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - eventBusName, statementID, err := PermissionParseResourceID(d.Id()) + eventBusName, statementID, err := permissionParseResourceID(d.Id()) if err != nil { - return sdkdiag.AppendErrorf(diags, "updating EventBridge permission (%s): %s", d.Id(), err) + return sdkdiag.AppendFromErr(diags, err) } - input := eventbridge.PutPermissionInput{ + + input := &eventbridge.PutPermissionInput{ Action: aws.String(d.Get("action").(string)), Condition: expandCondition(d.Get("condition").([]interface{})), EventBusName: aws.String(eventBusName), @@ -230,9 +186,10 @@ func resourcePermissionUpdate(ctx context.Context, d *schema.ResourceData, meta StatementId: aws.String(statementID), } - _, err = conn.PutPermissionWithContext(ctx, &input) + _, err = conn.PutPermission(ctx, input) + if err != nil { - return sdkdiag.AppendErrorf(diags, "updating EventBridge permission (%s): %s", d.Id(), err) + return sdkdiag.AppendErrorf(diags, "updating EventBridge Permission (%s): %s", d.Id(), err) } return append(diags, resourcePermissionRead(ctx, d, meta)...) @@ -240,122 +197,105 @@ func resourcePermissionUpdate(ctx context.Context, d *schema.ResourceData, meta func resourcePermissionDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) - eventBusName, statementID, err := PermissionParseResourceID(d.Id()) + eventBusName, statementID, err := permissionParseResourceID(d.Id()) if err != nil { - return sdkdiag.AppendErrorf(diags, "deleting EventBridge permission (%s): %s", d.Id(), err) + return sdkdiag.AppendFromErr(diags, err) } - input := eventbridge.RemovePermissionInput{ + + log.Printf("[DEBUG] Deleting EventBridge Permission: %s", d.Id()) + _, err = conn.RemovePermission(ctx, &eventbridge.RemovePermissionInput{ EventBusName: aws.String(eventBusName), StatementId: aws.String(statementID), - } + }) - log.Printf("[DEBUG] Delete EventBridge permission: %s", input) - _, err = conn.RemovePermissionWithContext(ctx, &input) - if tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { + if errs.IsA[*types.ResourceNotFoundException](err) { return diags } + if err != nil { - return sdkdiag.AppendErrorf(diags, "deleting EventBridge permission (%s): %s", d.Id(), err) + return sdkdiag.AppendErrorf(diags, "deleting EventBridge Permission (%s): %s", d.Id(), err) } return diags } -// https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutPermission.html#API_PutPermission_RequestParameters -func validatePermissionAction(v interface{}, k string) (ws []string, es []error) { - value := v.(string) - if (len(value) < 1) || (len(value) > 64) { - es = append(es, fmt.Errorf("%q must be between 1 and 64 characters", k)) +func findPermissionByTwoPartKey(ctx context.Context, conn *eventbridge.Client, eventBusName, statementID string) (*permissionPolicyStatement, error) { + output, err := findEventBusPolicyByName(ctx, conn, eventBusName) + + if err != nil { + return nil, err } - if !regexache.MustCompile(`^events:[A-Za-z]+$`).MatchString(value) { - es = append(es, fmt.Errorf("%q must be: events: followed by one or more alphabetic characters", k)) + var policyDoc permissionPolicyDoc + if err := json.Unmarshal([]byte(aws.ToString(output)), &policyDoc); err != nil { + return nil, err } - return -} -// https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutPermission.html#API_PutPermission_RequestParameters -func validatePermissionPrincipal(v interface{}, k string) (ws []string, es []error) { - value := v.(string) - if !regexache.MustCompile(`^(\d{12}|\*)$`).MatchString(value) { - es = append(es, fmt.Errorf("%q must be * or a 12 digit AWS account ID", k)) + for _, statement := range policyDoc.Statements { + if statement.Sid == statementID { + return &statement, nil + } } - return + + return nil, &retry.NotFoundError{} } -// https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutPermission.html#API_PutPermission_RequestParameters -func validatePermissionStatementID(v interface{}, k string) (ws []string, es []error) { - value := v.(string) - if (len(value) < 1) || (len(value) > 64) { - es = append(es, fmt.Errorf("%q must be between 1 and 64 characters", k)) +const permissionResourceIDSeparator = "/" + +func permissionCreateResourceID(eventBusName, statementID string) string { + if eventBusName == "" || eventBusName == DefaultEventBusName { + return statementID } - if !regexache.MustCompile(`^[0-9A-Za-z_-]+$`).MatchString(value) { - es = append(es, fmt.Errorf("%q must be one or more alphanumeric, hyphen, or underscore characters", k)) + parts := []string{eventBusName, statementID} + id := strings.Join(parts, permissionResourceIDSeparator) + + return id +} + +func permissionParseResourceID(id string) (string, string, error) { + parts := strings.Split(id, permissionResourceIDSeparator) + + if len(parts) == 1 && parts[0] != "" { + return DefaultEventBusName, parts[0], nil } - return + if len(parts) == 2 && parts[0] != "" && parts[1] != "" { + return parts[0], parts[1], nil + } + + return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected EVENTBUSNAME%[2]sSTATEMENTID or STATEMENTID", id, permissionResourceIDSeparator) } // PermissionPolicyDoc represents the Policy attribute of DescribeEventBus // See also: https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_DescribeEventBus.html -type PermissionPolicyDoc struct { +type permissionPolicyDoc struct { Version string ID string `json:"Id,omitempty"` - Statements []PermissionPolicyStatement `json:"Statement"` -} - -// String returns the string representation -func (d PermissionPolicyDoc) String() string { - return awsutil.Prettify(d) -} - -// GoString returns the string representation -func (d PermissionPolicyDoc) GoString() string { - return d.String() + Statements []permissionPolicyStatement `json:"Statement"` } // PermissionPolicyStatement represents the Statement attribute of PermissionPolicyDoc // See also: https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_DescribeEventBus.html -type PermissionPolicyStatement struct { +type permissionPolicyStatement struct { Sid string Effect string Action string - Condition *PermissionPolicyStatementCondition `json:"Condition,omitempty"` + Condition *permissionPolicyStatementCondition `json:"Condition,omitempty"` Principal interface{} // "*" or {"AWS": "arn:aws:iam::111111111111:root"} Resource string } -// String returns the string representation -func (s PermissionPolicyStatement) String() string { - return awsutil.Prettify(s) -} - -// GoString returns the string representation -func (s PermissionPolicyStatement) GoString() string { - return s.String() -} - // PermissionPolicyStatementCondition represents the Condition attribute of PermissionPolicyStatement // See also: https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_DescribeEventBus.html -type PermissionPolicyStatementCondition struct { +type permissionPolicyStatementCondition struct { Key string Type string Value string } -// String returns the string representation -func (c PermissionPolicyStatementCondition) String() string { - return awsutil.Prettify(c) -} - -// GoString returns the string representation -func (c PermissionPolicyStatementCondition) GoString() string { - return c.String() -} - -func (c *PermissionPolicyStatementCondition) UnmarshalJSON(b []byte) error { - var out PermissionPolicyStatementCondition +func (c *permissionPolicyStatementCondition) UnmarshalJSON(b []byte) error { + var out permissionPolicyStatementCondition // JSON representation: \"Condition\":{\"StringEquals\":{\"aws:PrincipalOrgID\":\"o-0123456789\"}} var data map[string]map[string]string @@ -365,7 +305,7 @@ func (c *PermissionPolicyStatementCondition) UnmarshalJSON(b []byte) error { for typeKey, typeValue := range data { for conditionKey, conditionValue := range typeValue { - out = PermissionPolicyStatementCondition{ + out = permissionPolicyStatementCondition{ Key: conditionKey, Type: typeKey, Value: conditionValue, @@ -377,30 +317,14 @@ func (c *PermissionPolicyStatementCondition) UnmarshalJSON(b []byte) error { return nil } -func FindPermissionPolicyStatementByID(policy *PermissionPolicyDoc, id string) ( - *PermissionPolicyStatement, error) { - log.Printf("[DEBUG] Finding statement (%s) in EventBridge permission policy: %s", id, policy) - for _, statement := range policy.Statements { - if statement.Sid == id { - return &statement, nil - } - } - - return nil, &retry.NotFoundError{ - LastRequest: id, - LastResponse: policy, - Message: fmt.Sprintf("Failed to find statement (%s) in EventBridge permission policy: %s", id, policy), - } -} - -func expandCondition(l []interface{}) *eventbridge.Condition { +func expandCondition(l []interface{}) *types.Condition { if len(l) == 0 || l[0] == nil { return nil } m := l[0].(map[string]interface{}) - condition := &eventbridge.Condition{ + condition := &types.Condition{ Key: aws.String(m["key"].(string)), Type: aws.String(m["type"].(string)), Value: aws.String(m["value"].(string)), @@ -409,7 +333,7 @@ func expandCondition(l []interface{}) *eventbridge.Condition { return condition } -func flattenPermissionPolicyStatementCondition(c *PermissionPolicyStatementCondition) []interface{} { +func flattenPermissionPolicyStatementCondition(c *permissionPolicyStatementCondition) []interface{} { if c == nil { return []interface{}{} } @@ -422,3 +346,38 @@ func flattenPermissionPolicyStatementCondition(c *PermissionPolicyStatementCondi return []interface{}{m} } + +// https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutPermission.html#API_PutPermission_RequestParameters +func validatePermissionAction(v interface{}, k string) (ws []string, es []error) { + value := v.(string) + if (len(value) < 1) || (len(value) > 64) { + es = append(es, fmt.Errorf("%q must be between 1 and 64 characters", k)) + } + + if !regexache.MustCompile(`^events:[A-Za-z]+$`).MatchString(value) { + es = append(es, fmt.Errorf("%q must be: events: followed by one or more alphabetic characters", k)) + } + return +} + +// https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutPermission.html#API_PutPermission_RequestParameters +func validatePermissionPrincipal(v interface{}, k string) (ws []string, es []error) { + value := v.(string) + if !regexache.MustCompile(`^(\d{12}|\*)$`).MatchString(value) { + es = append(es, fmt.Errorf("%q must be * or a 12 digit AWS account ID", k)) + } + return +} + +// https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutPermission.html#API_PutPermission_RequestParameters +func validatePermissionStatementID(v interface{}, k string) (ws []string, es []error) { + value := v.(string) + if (len(value) < 1) || (len(value) > 64) { + es = append(es, fmt.Errorf("%q must be between 1 and 64 characters", k)) + } + + if !regexache.MustCompile(`^[0-9A-Za-z_-]+$`).MatchString(value) { + es = append(es, fmt.Errorf("%q must be one or more alphanumeric, hyphen, or underscore characters", k)) + } + return +} diff --git a/internal/service/events/permission_test.go b/internal/service/events/permission_test.go index 15faced2c3f..340391ea304 100644 --- a/internal/service/events/permission_test.go +++ b/internal/service/events/permission_test.go @@ -5,22 +5,17 @@ package events_test import ( "context" - "encoding/json" "fmt" "testing" - "time" "github.com/YakDriver/regexache" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" tfevents "github.com/hashicorp/terraform-provider-aws/internal/service/events" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/names" ) @@ -276,90 +271,41 @@ func TestAccEventsPermission_disappears(t *testing.T) { }) } -func testAccCheckPermissionExists(ctx context.Context, pr string) resource.TestCheckFunc { +func testAccCheckPermissionExists(ctx context.Context, n string) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) - rs, ok := s.RootModule().Resources[pr] + rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not found: %s", pr) + return fmt.Errorf("Not found: %s", n) } - if rs.Primary.ID == "" { - return fmt.Errorf("No ID is set") - } + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) - eventBusName, statementID, err := tfevents.PermissionParseResourceID(rs.Primary.ID) - if err != nil { - return fmt.Errorf("error reading EventBridge permission (%s): %w", pr, err) - } - input := &eventbridge.DescribeEventBusInput{ - Name: aws.String(eventBusName), - } - debo, err := conn.DescribeEventBusWithContext(ctx, input) - if err != nil { - return fmt.Errorf("Reading EventBridge bus policy for '%s' failed: %w", pr, err) - } + _, err := tfevents.FindPermissionByTwoPartKey(ctx, conn, rs.Primary.Attributes["event_bus_name"], rs.Primary.Attributes["statement_id"]) - if debo.Policy == nil { - return fmt.Errorf("Not found: %s", pr) - } - - var policyDoc tfevents.PermissionPolicyDoc - err = json.Unmarshal([]byte(*debo.Policy), &policyDoc) - if err != nil { - return fmt.Errorf("Reading EventBridge bus policy for '%s' failed: %w", pr, err) - } - - _, err = tfevents.FindPermissionPolicyStatementByID(&policyDoc, statementID) return err } } func testAccCheckPermissionDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) for _, rs := range s.RootModule().Resources { if rs.Type != "aws_cloudwatch_event_permission" { continue } - eventBusName, statementID, err := tfevents.PermissionParseResourceID(rs.Primary.ID) - if err != nil { - return fmt.Errorf("error reading EventBridge permission (%s): %w", rs.Primary.ID, err) - } - input := &eventbridge.DescribeEventBusInput{ - Name: aws.String(eventBusName), + _, err := tfevents.FindPermissionByTwoPartKey(ctx, conn, rs.Primary.Attributes["event_bus_name"], rs.Primary.Attributes["statement_id"]) + + if tfresource.NotFound(err) { + continue } - err = retry.RetryContext(ctx, 1*time.Minute, func() *retry.RetryError { - debo, err := conn.DescribeEventBusWithContext(ctx, input) - if tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { - return nil - } - if err != nil { - return retry.NonRetryableError(err) - } - if debo.Policy == nil { - return nil - } - - var policyDoc tfevents.PermissionPolicyDoc - err = json.Unmarshal([]byte(*debo.Policy), &policyDoc) - if err != nil { - return retry.NonRetryableError(fmt.Errorf("Reading EventBridge permission '%s' failed: %w", rs.Primary.ID, err)) - } - - _, err = tfevents.FindPermissionPolicyStatementByID(&policyDoc, statementID) - if err == nil { - return retry.RetryableError(fmt.Errorf("EventBridge permission exists: %s", rs.Primary.ID)) - } - - return nil - }) if err != nil { return err } + + return fmt.Errorf("EventBridge Permission %s still exists", rs.Primary.ID) } return nil diff --git a/internal/service/events/service_package_gen.go b/internal/service/events/service_package_gen.go index 4be9c6ab35b..45326d0ba77 100644 --- a/internal/service/events/service_package_gen.go +++ b/internal/service/events/service_package_gen.go @@ -77,8 +77,9 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka Name: "Global Endpoint", }, { - Factory: ResourcePermission, + Factory: resourcePermission, TypeName: "aws_cloudwatch_event_permission", + Name: "Permission", }, { Factory: ResourceRule, From a5462fbaa4d1ae5a8e4524a08f70cf4056a39e6a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 15 Apr 2024 15:30:23 -0400 Subject: [PATCH 15/35] r/aws_cloudwatch_event_rule: Migrate to AWS SDK for Go v2. --- internal/service/events/exports_test.go | 19 +- internal/service/events/id.go | 44 ---- internal/service/events/id_test.go | 124 ----------- internal/service/events/rule.go | 160 +++++++++----- internal/service/events/rule_migrate.go | 8 +- internal/service/events/rule_test.go | 205 +++++++++++++----- .../service/events/service_package_gen.go | 2 +- 7 files changed, 271 insertions(+), 291 deletions(-) diff --git a/internal/service/events/exports_test.go b/internal/service/events/exports_test.go index 1a3e0d2cfe7..1a376d9406f 100644 --- a/internal/service/events/exports_test.go +++ b/internal/service/events/exports_test.go @@ -12,12 +12,17 @@ var ( ResourceConnection = resourceConnection ResourceEndpoint = resourceEndpoint ResourcePermission = resourcePermission + ResourceRule = resourceRule - FindAPIDestinationByName = findAPIDestinationByName - FindArchiveByName = findArchiveByName - FindConnectionByName = findConnectionByName - FindEndpointByName = findEndpointByName - FindEventBusByName = findEventBusByName - FindEventBusPolicyByName = findEventBusPolicyByName - FindPermissionByTwoPartKey = findPermissionByTwoPartKey + FindAPIDestinationByName = findAPIDestinationByName + FindArchiveByName = findArchiveByName + FindConnectionByName = findConnectionByName + FindEndpointByName = findEndpointByName + FindEventBusByName = findEventBusByName + FindEventBusPolicyByName = findEventBusPolicyByName + FindPermissionByTwoPartKey = findPermissionByTwoPartKey + FindRuleByTwoPartKey = findRuleByTwoPartKey + RuleEventPatternJSONDecoder = ruleEventPatternJSONDecoder + RuleCreateResourceID = ruleCreateResourceID + RuleParseResourceID = ruleParseResourceID ) diff --git a/internal/service/events/id.go b/internal/service/events/id.go index 95864a447fe..6e8c1219206 100644 --- a/internal/service/events/id.go +++ b/internal/service/events/id.go @@ -6,52 +6,8 @@ package events import ( "fmt" "strings" - - "github.com/YakDriver/regexache" -) - -var ( - eventBusARNPattern = regexache.MustCompile(`^arn:aws[\w-]*:events:[a-z]{2}-[a-z]+-[\w-]+:[0-9]{12}:event-bus\/[0-9A-Za-z_.-]+$`) - partnerEventBusPattern = regexache.MustCompile(`^(?:arn:aws[\w-]*:events:[a-z]{2}-[a-z]+-[\w-]+:[0-9]{12}:event-bus\/)?aws\.partner(/[0-9A-Za-z_.-]+){2,}$`) ) -const ruleResourceIDSeparator = "/" - -func RuleCreateResourceID(eventBusName, ruleName string) string { - if eventBusName == "" || eventBusName == DefaultEventBusName { - return ruleName - } - - parts := []string{eventBusName, ruleName} - id := strings.Join(parts, ruleResourceIDSeparator) - - return id -} - -func RuleParseResourceID(id string) (string, string, error) { - parts := strings.Split(id, ruleResourceIDSeparator) - - if len(parts) == 1 && parts[0] != "" { - return DefaultEventBusName, parts[0], nil - } - if len(parts) == 2 && parts[0] != "" && parts[1] != "" { - return parts[0], parts[1], nil - } - if len(parts) > 2 { - i := strings.LastIndex(id, ruleResourceIDSeparator) - eventBusName := id[:i] - ruleName := id[i+1:] - if eventBusARNPattern.MatchString(eventBusName) && ruleName != "" { - return eventBusName, ruleName, nil - } - if partnerEventBusPattern.MatchString(eventBusName) && ruleName != "" { - return eventBusName, ruleName, nil - } - } - - return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected EVENTBUSNAME%[2]sRULENAME or RULENAME", id, ruleResourceIDSeparator) -} - // Terraform resource IDs for Targets are not parseable as the separator used ("-") is also a valid character in both the rule name and the target ID. const ( diff --git a/internal/service/events/id_test.go b/internal/service/events/id_test.go index 0677f564363..6850aa2bcbd 100644 --- a/internal/service/events/id_test.go +++ b/internal/service/events/id_test.go @@ -9,130 +9,6 @@ import ( tfevents "github.com/hashicorp/terraform-provider-aws/internal/service/events" ) -func TestRuleParseResourceID(t *testing.T) { - t.Parallel() - - testCases := []struct { - TestName string - InputID string - ExpectedError bool - ExpectedPart0 string - ExpectedPart1 string - }{ - { - TestName: "empty ID", - InputID: "", - ExpectedError: true, - }, - { - TestName: "single part", - InputID: "TestRule", - ExpectedPart0: tfevents.DefaultEventBusName, - ExpectedPart1: "TestRule", - }, - { - TestName: "two parts", - InputID: tfevents.RuleCreateResourceID("TestEventBus", "TestRule"), - ExpectedPart0: "TestEventBus", - ExpectedPart1: "TestRule", - }, - { - TestName: "two parts with default event bus", - InputID: tfevents.RuleCreateResourceID(tfevents.DefaultEventBusName, "TestRule"), - ExpectedPart0: tfevents.DefaultEventBusName, - ExpectedPart1: "TestRule", - }, - { - TestName: "partner event bus 1", - InputID: "aws.partner/example.com/Test/TestRule", - ExpectedPart0: "aws.partner/example.com/Test", - ExpectedPart1: "TestRule", - }, - { - TestName: "partner event bus 2", - InputID: "aws.partner/example.net/id/18554d09-58ff-aa42-ba9c-c4c33899006f/test", - ExpectedPart0: "aws.partner/example.net/id/18554d09-58ff-aa42-ba9c-c4c33899006f", - ExpectedPart1: "test", - }, - { - TestName: "ARN event bus", - //lintignore:AWSAT003,AWSAT005 - InputID: tfevents.RuleCreateResourceID("arn:aws:events:us-east-2:123456789012:event-bus/default", "TestRule"), - //lintignore:AWSAT003,AWSAT005 - ExpectedPart0: "arn:aws:events:us-east-2:123456789012:event-bus/default", - ExpectedPart1: "TestRule", - }, - { - TestName: "ARN based partner event bus", - // lintignore:AWSAT003,AWSAT005 - InputID: "arn:aws:events:us-east-2:123456789012:event-bus/aws.partner/genesys.com/cloud/a12bc345-d678-90e1-2f34-gh5678i9012ej/_genesys/TestRule", - // lintignore:AWSAT003,AWSAT005 - ExpectedPart0: "arn:aws:events:us-east-2:123456789012:event-bus/aws.partner/genesys.com/cloud/a12bc345-d678-90e1-2f34-gh5678i9012ej/_genesys", - ExpectedPart1: "TestRule", - }, - { - TestName: "empty both parts", - InputID: "/", - ExpectedError: true, - }, - { - TestName: "empty first part", - InputID: "/TestRule", - ExpectedError: true, - }, - { - TestName: "empty second part", - InputID: "TestEventBus/", - ExpectedError: true, - }, - { - TestName: "empty partner event rule", - InputID: "aws.partner/example.com/Test/", - ExpectedError: true, - }, - { - TestName: "three parts", - InputID: "TestEventBus/TestRule/Suffix", - ExpectedError: true, - }, - { - TestName: "four parts", - InputID: "abc.partner/TestEventBus/TestRule/Suffix", - ExpectedError: true, - }, - { - TestName: "five parts", - InputID: "test/aws.partner/example.com/Test/TestRule", - ExpectedError: true, - }, - } - - for _, testCase := range testCases { - testCase := testCase - t.Run(testCase.TestName, func(t *testing.T) { - t.Parallel() - - gotPart0, gotPart1, err := tfevents.RuleParseResourceID(testCase.InputID) - - if err == nil && testCase.ExpectedError { - t.Fatalf("expected error, got no error") - } - - if err != nil && !testCase.ExpectedError { - t.Fatalf("got unexpected error: %s", err) - } - - if gotPart0 != testCase.ExpectedPart0 { - t.Errorf("got part 0 %s, expected %s", gotPart0, testCase.ExpectedPart0) - } - - if gotPart1 != testCase.ExpectedPart1 { - t.Errorf("got part 1 %s, expected %s", gotPart1, testCase.ExpectedPart1) - } - }) - } -} - func TestTargetParseImportID(t *testing.T) { t.Parallel() diff --git a/internal/service/events/rule.go b/internal/service/events/rule.go index 501a08393f6..145025e21ed 100644 --- a/internal/service/events/rule.go +++ b/internal/service/events/rule.go @@ -9,17 +9,20 @@ import ( "encoding/json" "fmt" "log" + "strings" "time" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/YakDriver/regexache" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/service/eventbridge/types" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/enum" "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" @@ -28,14 +31,9 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -const ( - ruleCreateRetryTimeout = 2 * time.Minute - ruleDeleteRetryTimeout = 5 * time.Minute -) - // @SDKResource("aws_cloudwatch_event_rule", name="Rule") // @Tags(identifierAttribute="arn") -func ResourceRule() *schema.Resource { +func resourceRule() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceRuleCreate, ReadWithoutTimeout: resourceRuleRead, @@ -78,7 +76,7 @@ func ResourceRule() *schema.Resource { ValidateFunc: validateEventPatternValue(), AtLeastOneOf: []string{"schedule_expression", "event_pattern"}, StateFunc: func(v interface{}) string { - json, _ := RuleEventPatternJSONDecoder(v.(string)) + json, _ := ruleEventPatternJSONDecoder(v.(string)) return json }, }, @@ -123,12 +121,9 @@ func ResourceRule() *schema.Resource { AtLeastOneOf: []string{"schedule_expression", "event_pattern"}, }, "state": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice( - eventbridge.RuleState_Values(), - false, - ), + Type: schema.TypeString, + Optional: true, + ValidateDiagFunc: enum.Validate[types.RuleState](), DiffSuppressFunc: func(k, oldValue, newValue string, d *schema.ResourceData) bool { if oldValue != "" && newValue == "" { return true @@ -149,7 +144,7 @@ func ResourceRule() *schema.Resource { func resourceRuleCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) name := create.Name(d.Get("name").(string), d.Get("name_prefix").(string)) input := expandPutRuleInput(d, name) @@ -158,7 +153,7 @@ func resourceRuleCreate(ctx context.Context, d *schema.ResourceData, meta interf arn, err := retryPutRule(ctx, conn, input) // Some partitions (e.g. ISO) may not support tag-on-create. - if input.Tags != nil && errs.IsUnsupportedOperationInPartitionError(conn.PartitionID, err) { + if input.Tags != nil && errs.IsUnsupportedOperationInPartitionError(meta.(*conns.AWSClient).Partition, err) { input.Tags = nil arn, err = retryPutRule(ctx, conn, input) @@ -168,11 +163,14 @@ func resourceRuleCreate(ctx context.Context, d *schema.ResourceData, meta interf return sdkdiag.AppendErrorf(diags, "creating EventBridge Rule (%s): %s", name, err) } - eventBusName, ruleName := aws.StringValue(input.EventBusName), aws.StringValue(input.Name) - d.SetId(RuleCreateResourceID(eventBusName, ruleName)) + eventBusName, ruleName := aws.ToString(input.EventBusName), aws.ToString(input.Name) + d.SetId(ruleCreateResourceID(eventBusName, ruleName)) - _, err = tfresource.RetryWhenNotFound(ctx, ruleCreateRetryTimeout, func() (interface{}, error) { - return FindRuleByTwoPartKey(ctx, conn, eventBusName, ruleName) + const ( + timeout = 2 * time.Minute + ) + _, err = tfresource.RetryWhenNotFound(ctx, timeout, func() (interface{}, error) { + return findRuleByTwoPartKey(ctx, conn, eventBusName, ruleName) }) if err != nil { @@ -184,7 +182,7 @@ func resourceRuleCreate(ctx context.Context, d *schema.ResourceData, meta interf err := createTags(ctx, conn, arn, tags) // If default tags only, continue. Otherwise, error. - if v, ok := d.GetOk(names.AttrTags); (!ok || len(v.(map[string]interface{})) == 0) && errs.IsUnsupportedOperationInPartitionError(conn.PartitionID, err) { + if v, ok := d.GetOk(names.AttrTags); (!ok || len(v.(map[string]interface{})) == 0) && errs.IsUnsupportedOperationInPartitionError(meta.(*conns.AWSClient).Partition, err) { return append(diags, resourceRuleRead(ctx, d, meta)...) } @@ -198,15 +196,14 @@ func resourceRuleCreate(ctx context.Context, d *schema.ResourceData, meta interf func resourceRuleRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) - - eventBusName, ruleName, err := RuleParseResourceID(d.Id()) + conn := meta.(*conns.AWSClient).EventsClient(ctx) + eventBusName, ruleName, err := ruleParseResourceID(d.Id()) if err != nil { return sdkdiag.AppendFromErr(diags, err) } - output, err := FindRuleByTwoPartKey(ctx, conn, eventBusName, ruleName) + output, err := findRuleByTwoPartKey(ctx, conn, eventBusName, ruleName) if !d.IsNewResource() && tfresource.NotFound(err) { log.Printf("[WARN] EventBridge Rule (%s) not found, removing from state", d.Id()) @@ -218,45 +215,44 @@ func resourceRuleRead(ctx context.Context, d *schema.ResourceData, meta interfac return sdkdiag.AppendErrorf(diags, "reading EventBridge Rule (%s): %s", d.Id(), err) } - arn := aws.StringValue(output.Arn) + arn := aws.ToString(output.Arn) d.Set("arn", arn) d.Set("description", output.Description) d.Set("event_bus_name", eventBusName) // Use event bus name from resource ID as API response may collapse any ARN. if output.EventPattern != nil { - pattern, err := RuleEventPatternJSONDecoder(aws.StringValue(output.EventPattern)) + pattern, err := ruleEventPatternJSONDecoder(aws.ToString(output.EventPattern)) if err != nil { - return sdkdiag.AppendErrorf(diags, "event pattern contains an invalid JSON: %s", err) + return sdkdiag.AppendFromErr(diags, err) } d.Set("event_pattern", pattern) } - switch aws.StringValue(output.State) { - case eventbridge.RuleStateEnabled, - eventbridge.RuleStateEnabledWithAllCloudtrailManagementEvents: + switch output.State { + case types.RuleStateEnabled, types.RuleStateEnabledWithAllCloudtrailManagementEvents: d.Set("is_enabled", true) default: d.Set("is_enabled", false) } - d.Set("state", output.State) d.Set("name", output.Name) - d.Set("name_prefix", create.NamePrefixFromName(aws.StringValue(output.Name))) + d.Set("name_prefix", create.NamePrefixFromName(aws.ToString(output.Name))) d.Set("role_arn", output.RoleArn) d.Set("schedule_expression", output.ScheduleExpression) + d.Set("state", output.State) return diags } func resourceRuleUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) if d.HasChangesExcept("tags", "tags_all") { - _, ruleName, err := RuleParseResourceID(d.Id()) - + _, ruleName, err := ruleParseResourceID(d.Id()) if err != nil { return sdkdiag.AppendFromErr(diags, err) } input := expandPutRuleInput(d, ruleName) + _, err = retryPutRule(ctx, conn, input) if err != nil { @@ -269,10 +265,9 @@ func resourceRuleUpdate(ctx context.Context, d *schema.ResourceData, meta interf func resourceRuleDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) - - eventBusName, ruleName, err := RuleParseResourceID(d.Id()) + conn := meta.(*conns.AWSClient).EventsClient(ctx) + eventBusName, ruleName, err := ruleParseResourceID(d.Id()) if err != nil { return sdkdiag.AppendFromErr(diags, err) } @@ -284,12 +279,15 @@ func resourceRuleDelete(ctx context.Context, d *schema.ResourceData, meta interf input.EventBusName = aws.String(eventBusName) } + const ( + timeout = 5 * time.Minute + ) log.Printf("[DEBUG] Deleting EventBridge Rule: %s", d.Id()) - _, err = tfresource.RetryWhenAWSErrMessageContains(ctx, ruleDeleteRetryTimeout, func() (interface{}, error) { - return conn.DeleteRuleWithContext(ctx, input) - }, "ValidationException", "Rule can't be deleted since it has targets") + _, err = tfresource.RetryWhenAWSErrMessageContains(ctx, timeout, func() (interface{}, error) { + return conn.DeleteRule(ctx, input) + }, errCodeValidationException, "Rule can't be deleted since it has targets") - if tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { + if errs.IsA[*types.ResourceNotFoundException](err) { return diags } @@ -300,29 +298,29 @@ func resourceRuleDelete(ctx context.Context, d *schema.ResourceData, meta interf return diags } -func retryPutRule(ctx context.Context, conn *eventbridge.EventBridge, input *eventbridge.PutRuleInput) (string, error) { +func retryPutRule(ctx context.Context, conn *eventbridge.Client, input *eventbridge.PutRuleInput) (string, error) { outputRaw, err := tfresource.RetryWhenAWSErrMessageContains(ctx, propagationTimeout, func() (interface{}, error) { - return conn.PutRuleWithContext(ctx, input) - }, "ValidationException", "cannot be assumed by principal") + return conn.PutRule(ctx, input) + }, errCodeValidationException, "cannot be assumed by principal") if err != nil { return "", err } - return aws.StringValue(outputRaw.(*eventbridge.PutRuleOutput).RuleArn), nil + return aws.ToString(outputRaw.(*eventbridge.PutRuleOutput).RuleArn), nil } -func FindRuleByTwoPartKey(ctx context.Context, conn *eventbridge.EventBridge, eventBusName, ruleName string) (*eventbridge.DescribeRuleOutput, error) { - input := eventbridge.DescribeRuleInput{ +func findRuleByTwoPartKey(ctx context.Context, conn *eventbridge.Client, eventBusName, ruleName string) (*eventbridge.DescribeRuleOutput, error) { + input := &eventbridge.DescribeRuleInput{ Name: aws.String(ruleName), } if eventBusName != "" { input.EventBusName = aws.String(eventBusName) } - output, err := conn.DescribeRuleWithContext(ctx, &input) + output, err := conn.DescribeRule(ctx, input) - if tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { + if errs.IsA[*types.ResourceNotFoundException](err) { return nil, &retry.NotFoundError{ LastError: err, LastRequest: input, @@ -340,8 +338,50 @@ func FindRuleByTwoPartKey(ctx context.Context, conn *eventbridge.EventBridge, ev return output, nil } -// RuleEventPatternJSONDecoder decodes unicode translation of <,>,& -func RuleEventPatternJSONDecoder(jsonString interface{}) (string, error) { +var ( + eventBusARNPattern = regexache.MustCompile(`^arn:aws[\w-]*:events:[a-z]{2}-[a-z]+-[\w-]+:[0-9]{12}:event-bus\/[0-9A-Za-z_.-]+$`) + partnerEventBusPattern = regexache.MustCompile(`^(?:arn:aws[\w-]*:events:[a-z]{2}-[a-z]+-[\w-]+:[0-9]{12}:event-bus\/)?aws\.partner(/[0-9A-Za-z_.-]+){2,}$`) +) + +const ruleResourceIDSeparator = "/" + +func ruleCreateResourceID(eventBusName, ruleName string) string { + if eventBusName == "" || eventBusName == DefaultEventBusName { + return ruleName + } + + parts := []string{eventBusName, ruleName} + id := strings.Join(parts, ruleResourceIDSeparator) + + return id +} + +func ruleParseResourceID(id string) (string, string, error) { + parts := strings.Split(id, ruleResourceIDSeparator) + + if len(parts) == 1 && parts[0] != "" { + return DefaultEventBusName, parts[0], nil + } + if len(parts) == 2 && parts[0] != "" && parts[1] != "" { + return parts[0], parts[1], nil + } + if len(parts) > 2 { + i := strings.LastIndex(id, ruleResourceIDSeparator) + eventBusName := id[:i] + ruleName := id[i+1:] + if eventBusARNPattern.MatchString(eventBusName) && ruleName != "" { + return eventBusName, ruleName, nil + } + if partnerEventBusPattern.MatchString(eventBusName) && ruleName != "" { + return eventBusName, ruleName, nil + } + } + + return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected EVENTBUSNAME%[2]sRULENAME or RULENAME", id, ruleResourceIDSeparator) +} + +// ruleEventPatternJSONDecoder decodes unicode translation of <,>,& +func ruleEventPatternJSONDecoder(jsonString interface{}) (string, error) { var j interface{} if jsonString == nil || jsonString.(string) == "" { @@ -382,7 +422,7 @@ func expandPutRuleInput(d *schema.ResourceData, name string) *eventbridge.PutRul } if v, ok := d.GetOk("event_pattern"); ok { - json, _ := RuleEventPatternJSONDecoder(v.(string)) + json, _ := ruleEventPatternJSONDecoder(v.(string)) apiObject.EventPattern = aws.String(json) } @@ -397,14 +437,14 @@ func expandPutRuleInput(d *schema.ResourceData, name string) *eventbridge.PutRul rawConfig := d.GetRawConfig() rawState := rawConfig.GetAttr("state") if rawState.IsKnown() && !rawState.IsNull() { - apiObject.State = aws.String(rawState.AsString()) + apiObject.State = types.RuleState(rawState.AsString()) } else { rawIsEnabled := rawConfig.GetAttr("is_enabled") if rawIsEnabled.IsKnown() && !rawIsEnabled.IsNull() { if rawIsEnabled.True() { - apiObject.State = aws.String(eventbridge.RuleStateEnabled) + apiObject.State = types.RuleStateEnabled } else { - apiObject.State = aws.String(eventbridge.RuleStateDisabled) + apiObject.State = types.RuleStateDisabled } } } @@ -414,7 +454,7 @@ func expandPutRuleInput(d *schema.ResourceData, name string) *eventbridge.PutRul func validateEventPatternValue() schema.SchemaValidateFunc { return func(v interface{}, k string) (ws []string, errors []error) { - json, err := RuleEventPatternJSONDecoder(v.(string)) + json, err := ruleEventPatternJSONDecoder(v.(string)) if err != nil { errors = append(errors, fmt.Errorf("%q contains an invalid JSON: %w", k, err)) diff --git a/internal/service/events/rule_migrate.go b/internal/service/events/rule_migrate.go index 75582280ff1..8ca2c2a2fc9 100644 --- a/internal/service/events/rule_migrate.go +++ b/internal/service/events/rule_migrate.go @@ -6,7 +6,7 @@ package events import ( "context" - "github.com/aws/aws-sdk-go/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/service/eventbridge/types" "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" @@ -35,7 +35,7 @@ func resourceRuleV0() *schema.Resource { Type: schema.TypeString, Optional: true, StateFunc: func(v interface{}) string { - json, _ := RuleEventPatternJSONDecoder(v.(string)) + json, _ := ruleEventPatternJSONDecoder(v.(string)) return json }, }, @@ -85,9 +85,9 @@ func resourceRuleUpgradeV0(ctx context.Context, rawState map[string]any, meta an }) if rawState["is_enabled"].(bool) { - rawState["state"] = eventbridge.RuleStateEnabled + rawState["state"] = types.RuleStateEnabled } else { - rawState["state"] = eventbridge.RuleStateDisabled + rawState["state"] = types.RuleStateDisabled } return rawState, nil diff --git a/internal/service/events/rule_test.go b/internal/service/events/rule_test.go index fdd94dd0fcb..6c59557f1db 100644 --- a/internal/service/events/rule_test.go +++ b/internal/service/events/rule_test.go @@ -10,8 +10,9 @@ import ( "testing" "github.com/YakDriver/regexache" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/service/eventbridge/types" "github.com/google/go-cmp/cmp" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" @@ -35,6 +36,130 @@ func testAccErrorCheckSkip(t *testing.T) resource.ErrorCheckFunc { ) } +func TestRuleParseResourceID(t *testing.T) { + t.Parallel() + + testCases := []struct { + TestName string + InputID string + ExpectedError bool + ExpectedPart0 string + ExpectedPart1 string + }{ + { + TestName: "empty ID", + InputID: "", + ExpectedError: true, + }, + { + TestName: "single part", + InputID: "TestRule", + ExpectedPart0: tfevents.DefaultEventBusName, + ExpectedPart1: "TestRule", + }, + { + TestName: "two parts", + InputID: tfevents.RuleCreateResourceID("TestEventBus", "TestRule"), + ExpectedPart0: "TestEventBus", + ExpectedPart1: "TestRule", + }, + { + TestName: "two parts with default event bus", + InputID: tfevents.RuleCreateResourceID(tfevents.DefaultEventBusName, "TestRule"), + ExpectedPart0: tfevents.DefaultEventBusName, + ExpectedPart1: "TestRule", + }, + { + TestName: "partner event bus 1", + InputID: "aws.partner/example.com/Test/TestRule", + ExpectedPart0: "aws.partner/example.com/Test", + ExpectedPart1: "TestRule", + }, + { + TestName: "partner event bus 2", + InputID: "aws.partner/example.net/id/18554d09-58ff-aa42-ba9c-c4c33899006f/test", + ExpectedPart0: "aws.partner/example.net/id/18554d09-58ff-aa42-ba9c-c4c33899006f", + ExpectedPart1: "test", + }, + { + TestName: "ARN event bus", + //lintignore:AWSAT003,AWSAT005 + InputID: tfevents.RuleCreateResourceID("arn:aws:events:us-east-2:123456789012:event-bus/default", "TestRule"), + //lintignore:AWSAT003,AWSAT005 + ExpectedPart0: "arn:aws:events:us-east-2:123456789012:event-bus/default", + ExpectedPart1: "TestRule", + }, + { + TestName: "ARN based partner event bus", + // lintignore:AWSAT003,AWSAT005 + InputID: "arn:aws:events:us-east-2:123456789012:event-bus/aws.partner/genesys.com/cloud/a12bc345-d678-90e1-2f34-gh5678i9012ej/_genesys/TestRule", + // lintignore:AWSAT003,AWSAT005 + ExpectedPart0: "arn:aws:events:us-east-2:123456789012:event-bus/aws.partner/genesys.com/cloud/a12bc345-d678-90e1-2f34-gh5678i9012ej/_genesys", + ExpectedPart1: "TestRule", + }, + { + TestName: "empty both parts", + InputID: "/", + ExpectedError: true, + }, + { + TestName: "empty first part", + InputID: "/TestRule", + ExpectedError: true, + }, + { + TestName: "empty second part", + InputID: "TestEventBus/", + ExpectedError: true, + }, + { + TestName: "empty partner event rule", + InputID: "aws.partner/example.com/Test/", + ExpectedError: true, + }, + { + TestName: "three parts", + InputID: "TestEventBus/TestRule/Suffix", + ExpectedError: true, + }, + { + TestName: "four parts", + InputID: "abc.partner/TestEventBus/TestRule/Suffix", + ExpectedError: true, + }, + { + TestName: "five parts", + InputID: "test/aws.partner/example.com/Test/TestRule", + ExpectedError: true, + }, + } + + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.TestName, func(t *testing.T) { + t.Parallel() + + gotPart0, gotPart1, err := tfevents.RuleParseResourceID(testCase.InputID) + + if err == nil && testCase.ExpectedError { + t.Fatalf("expected error, got no error") + } + + if err != nil && !testCase.ExpectedError { + t.Fatalf("got unexpected error: %s", err) + } + + if gotPart0 != testCase.ExpectedPart0 { + t.Errorf("got part 0 %s, expected %s", gotPart0, testCase.ExpectedPart0) + } + + if gotPart1 != testCase.ExpectedPart1 { + t.Errorf("got part 1 %s, expected %s", gotPart1, testCase.ExpectedPart1) + } + }) + } +} + func TestRuleEventPatternJSONDecoder(t *testing.T) { t.Parallel() @@ -523,12 +648,12 @@ func TestAccEventsRule_state(t *testing.T) { CheckDestroy: testAccCheckRuleDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccRuleConfig_state(rName, eventbridge.RuleStateDisabled), + Config: testAccRuleConfig_state(rName, string(types.RuleStateDisabled)), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckRuleExists(ctx, resourceName, &v1), resource.TestCheckResourceAttr(resourceName, "is_enabled", "false"), - resource.TestCheckResourceAttr(resourceName, "state", eventbridge.RuleStateDisabled), - testAccCheckRuleEnabled(ctx, resourceName, eventbridge.RuleStateDisabled), + resource.TestCheckResourceAttr(resourceName, "state", string(types.RuleStateDisabled)), + testAccCheckRuleEnabled(ctx, resourceName, types.RuleStateDisabled), ), }, { @@ -537,12 +662,12 @@ func TestAccEventsRule_state(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccRuleConfig_state(rName, eventbridge.RuleStateEnabled), + Config: testAccRuleConfig_state(rName, string(types.RuleStateEnabled)), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckRuleExists(ctx, resourceName, &v2), resource.TestCheckResourceAttr(resourceName, "is_enabled", "true"), - resource.TestCheckResourceAttr(resourceName, "state", eventbridge.RuleStateEnabled), - testAccCheckRuleEnabled(ctx, resourceName, eventbridge.RuleStateEnabled), + resource.TestCheckResourceAttr(resourceName, "state", string(types.RuleStateEnabled)), + testAccCheckRuleEnabled(ctx, resourceName, types.RuleStateEnabled), ), }, { @@ -551,12 +676,12 @@ func TestAccEventsRule_state(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccRuleConfig_state(rName, eventbridge.RuleStateEnabledWithAllCloudtrailManagementEvents), + Config: testAccRuleConfig_state(rName, string(types.RuleStateEnabledWithAllCloudtrailManagementEvents)), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckRuleExists(ctx, resourceName, &v3), resource.TestCheckResourceAttr(resourceName, "is_enabled", "true"), - resource.TestCheckResourceAttr(resourceName, "state", eventbridge.RuleStateEnabledWithAllCloudtrailManagementEvents), - testAccCheckRuleEnabled(ctx, resourceName, eventbridge.RuleStateEnabledWithAllCloudtrailManagementEvents), + resource.TestCheckResourceAttr(resourceName, "state", string(types.RuleStateEnabledWithAllCloudtrailManagementEvents)), + testAccCheckRuleEnabled(ctx, resourceName, types.RuleStateEnabledWithAllCloudtrailManagementEvents), ), }, { @@ -657,7 +782,7 @@ func TestAccEventsRule_migrateV0(t *testing.T) { testcases := map[string]struct { config string expectedIsEnabled string - expectedState string + expectedState types.RuleState }{ "basic": { config: testAccRuleConfig_basic(sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)), @@ -714,7 +839,7 @@ func TestAccEventsRule_migrateV0(t *testing.T) { }, Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "is_enabled", testcase.expectedIsEnabled), - resource.TestCheckResourceAttr(resourceName, "state", testcase.expectedState), + resource.TestCheckResourceAttr(resourceName, "state", string(testcase.expectedState)), testAccCheckRuleEnabled(ctx, resourceName, testcase.expectedState), ), }, @@ -733,20 +858,20 @@ func TestAccEventsRule_migrateV0_Equivalent(t *testing.T) { enabled bool state string expectedIsEnabled string - expectedState string + expectedState types.RuleState }{ "enabled": { enabled: true, - state: eventbridge.RuleStateEnabled, + state: string(types.RuleStateEnabled), expectedIsEnabled: "true", - expectedState: eventbridge.RuleStateEnabled, + expectedState: types.RuleStateEnabled, }, "disabled": { enabled: false, - state: eventbridge.RuleStateDisabled, + state: string(types.RuleStateDisabled), expectedIsEnabled: "false", - expectedState: eventbridge.RuleStateDisabled, + expectedState: types.RuleStateDisabled, }, } @@ -787,7 +912,7 @@ func TestAccEventsRule_migrateV0_Equivalent(t *testing.T) { }, Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "is_enabled", testcase.expectedIsEnabled), - resource.TestCheckResourceAttr(resourceName, "state", testcase.expectedState), + resource.TestCheckResourceAttr(resourceName, "state", string(testcase.expectedState)), testAccCheckRuleEnabled(ctx, resourceName, testcase.expectedState), ), }, @@ -804,19 +929,9 @@ func testAccCheckRuleExists(ctx context.Context, n string, v *eventbridge.Descri return fmt.Errorf("Not found: %s", n) } - if rs.Primary.ID == "" { - return fmt.Errorf("No EventBridge Rule ID is set") - } + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) - eventBusName, ruleName, err := tfevents.RuleParseResourceID(rs.Primary.ID) - - if err != nil { - return err - } - - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) - - output, err := tfevents.FindRuleByTwoPartKey(ctx, conn, eventBusName, ruleName) + output, err := tfevents.FindRuleByTwoPartKey(ctx, conn, rs.Primary.Attributes["event_bus_name"], rs.Primary.Attributes["name"]) if err != nil { return err @@ -828,28 +943,22 @@ func testAccCheckRuleExists(ctx context.Context, n string, v *eventbridge.Descri } } -func testAccCheckRuleEnabled(ctx context.Context, n string, want string) resource.TestCheckFunc { +func testAccCheckRuleEnabled(ctx context.Context, n string, want types.RuleState) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { return fmt.Errorf("Not found: %s", n) } - eventBusName, ruleName, err := tfevents.RuleParseResourceID(rs.Primary.ID) - - if err != nil { - return err - } - - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) - output, err := tfevents.FindRuleByTwoPartKey(ctx, conn, eventBusName, ruleName) + output, err := tfevents.FindRuleByTwoPartKey(ctx, conn, rs.Primary.Attributes["event_bus_name"], rs.Primary.Attributes["name"]) if err != nil { return err } - if got := aws.StringValue(output.State); got != want { + if got := output.State; got != want { return fmt.Errorf("EventBridge Rule State = %v, want %v", got, want) } @@ -859,20 +968,14 @@ func testAccCheckRuleEnabled(ctx context.Context, n string, want string) resourc func testAccCheckRuleDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) for _, rs := range s.RootModule().Resources { if rs.Type != "aws_cloudwatch_event_rule" { continue } - eventBusName, ruleName, err := tfevents.RuleParseResourceID(rs.Primary.ID) - - if err != nil { - return err - } - - _, err = tfevents.FindRuleByTwoPartKey(ctx, conn, eventBusName, ruleName) + _, err := tfevents.FindRuleByTwoPartKey(ctx, conn, rs.Primary.Attributes["event_bus_name"], rs.Primary.Attributes["name"]) if tfresource.NotFound(err) { continue @@ -891,7 +994,7 @@ func testAccCheckRuleDestroy(ctx context.Context) resource.TestCheckFunc { func testAccCheckRuleRecreated(i, j *eventbridge.DescribeRuleOutput) resource.TestCheckFunc { return func(s *terraform.State) error { - if aws.StringValue(i.Arn) == aws.StringValue(j.Arn) { + if aws.ToString(i.Arn) == aws.ToString(j.Arn) { return fmt.Errorf("EventBridge rule not recreated, but expected it to be") } return nil @@ -900,7 +1003,7 @@ func testAccCheckRuleRecreated(i, j *eventbridge.DescribeRuleOutput) resource.Te func testAccCheckRuleNotRecreated(i, j *eventbridge.DescribeRuleOutput) resource.TestCheckFunc { return func(s *terraform.State) error { - if aws.StringValue(i.Arn) != aws.StringValue(j.Arn) { + if aws.ToString(i.Arn) != aws.ToString(j.Arn) { return fmt.Errorf("EventBridge rule recreated, but expected it to not be") } return nil diff --git a/internal/service/events/service_package_gen.go b/internal/service/events/service_package_gen.go index 45326d0ba77..13bd9403710 100644 --- a/internal/service/events/service_package_gen.go +++ b/internal/service/events/service_package_gen.go @@ -82,7 +82,7 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka Name: "Permission", }, { - Factory: ResourceRule, + Factory: resourceRule, TypeName: "aws_cloudwatch_event_rule", Name: "Rule", Tags: &types.ServicePackageResourceTags{ From c41985586b374e981dac2830a97d52287d9b148f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 15 Apr 2024 16:30:39 -0400 Subject: [PATCH 16/35] d/aws_cloudwatch_event_source: Migrate to AWS SDK for Go v2. --- internal/service/events/generate.go | 2 +- internal/service/events/list_pages_gen.go | 41 +++++++---- .../service/events/service_package_gen.go | 3 +- internal/service/events/source_data_source.go | 68 ++++++++++++------- 4 files changed, 76 insertions(+), 38 deletions(-) diff --git a/internal/service/events/generate.go b/internal/service/events/generate.go index d193e6abab0..3aa2029d5b4 100644 --- a/internal/service/events/generate.go +++ b/internal/service/events/generate.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -//go:generate go run ../../generate/listpages/main.go -ListOps=ListEventBuses,ListRules,ListTargetsByRule +//go:generate go run ../../generate/listpages/main.go -AWSSDKVersion=2 -ListOps=ListEventBuses,ListEventSources,ListRules,ListTargetsByRule //go:generate go run ../../generate/tags/main.go -AWSSDKVersion=2 -ListTags -ListTagsInIDElem=ResourceARN -ServiceTagsSlice -TagInIDElem=ResourceARN -UpdateTags -CreateTags //go:generate go run ../../generate/servicepackage/main.go // ONLY generate directives and package declaration! Do not add anything else to this file. diff --git a/internal/service/events/list_pages_gen.go b/internal/service/events/list_pages_gen.go index 721c0a9a34c..377f7a69a50 100644 --- a/internal/service/events/list_pages_gen.go +++ b/internal/service/events/list_pages_gen.go @@ -1,23 +1,22 @@ -// Code generated by "internal/generate/listpages/main.go -ListOps=ListEventBuses,ListRules,ListTargetsByRule"; DO NOT EDIT. +// Code generated by "internal/generate/listpages/main.go -AWSSDKVersion=2 -ListOps=ListEventBuses,ListEventSources,ListRules,ListTargetsByRule"; DO NOT EDIT. package events import ( "context" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/aws/aws-sdk-go/service/eventbridge/eventbridgeiface" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" ) -func listEventBusesPages(ctx context.Context, conn eventbridgeiface.EventBridgeAPI, input *eventbridge.ListEventBusesInput, fn func(*eventbridge.ListEventBusesOutput, bool) bool) error { +func listEventBusesPages(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListEventBusesInput, fn func(*eventbridge.ListEventBusesOutput, bool) bool) error { for { - output, err := conn.ListEventBusesWithContext(ctx, input) + output, err := conn.ListEventBuses(ctx, input) if err != nil { return err } - lastPage := aws.StringValue(output.NextToken) == "" + lastPage := aws.ToString(output.NextToken) == "" if !fn(output, lastPage) || lastPage { break } @@ -26,14 +25,14 @@ func listEventBusesPages(ctx context.Context, conn eventbridgeiface.EventBridgeA } return nil } -func listRulesPages(ctx context.Context, conn eventbridgeiface.EventBridgeAPI, input *eventbridge.ListRulesInput, fn func(*eventbridge.ListRulesOutput, bool) bool) error { +func listEventSourcesPages(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListEventSourcesInput, fn func(*eventbridge.ListEventSourcesOutput, bool) bool) error { for { - output, err := conn.ListRulesWithContext(ctx, input) + output, err := conn.ListEventSources(ctx, input) if err != nil { return err } - lastPage := aws.StringValue(output.NextToken) == "" + lastPage := aws.ToString(output.NextToken) == "" if !fn(output, lastPage) || lastPage { break } @@ -42,14 +41,30 @@ func listRulesPages(ctx context.Context, conn eventbridgeiface.EventBridgeAPI, i } return nil } -func listTargetsByRulePages(ctx context.Context, conn eventbridgeiface.EventBridgeAPI, input *eventbridge.ListTargetsByRuleInput, fn func(*eventbridge.ListTargetsByRuleOutput, bool) bool) error { +func listRulesPages(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListRulesInput, fn func(*eventbridge.ListRulesOutput, bool) bool) error { for { - output, err := conn.ListTargetsByRuleWithContext(ctx, input) + output, err := conn.ListRules(ctx, input) if err != nil { return err } - lastPage := aws.StringValue(output.NextToken) == "" + lastPage := aws.ToString(output.NextToken) == "" + if !fn(output, lastPage) || lastPage { + break + } + + input.NextToken = output.NextToken + } + return nil +} +func listTargetsByRulePages(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListTargetsByRuleInput, fn func(*eventbridge.ListTargetsByRuleOutput, bool) bool) error { + for { + output, err := conn.ListTargetsByRule(ctx, input) + if err != nil { + return err + } + + lastPage := aws.ToString(output.NextToken) == "" if !fn(output, lastPage) || lastPage { break } diff --git a/internal/service/events/service_package_gen.go b/internal/service/events/service_package_gen.go index 13bd9403710..f70d11c1cbd 100644 --- a/internal/service/events/service_package_gen.go +++ b/internal/service/events/service_package_gen.go @@ -35,8 +35,9 @@ func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePac Name: "Connection", }, { - Factory: DataSourceSource, + Factory: dataSourceSource, TypeName: "aws_cloudwatch_event_source", + Name: "Source", }, } } diff --git a/internal/service/events/source_data_source.go b/internal/service/events/source_data_source.go index 1a95588d741..6ccba524424 100644 --- a/internal/service/events/source_data_source.go +++ b/internal/service/events/source_data_source.go @@ -5,18 +5,19 @@ package events import ( "context" - "log" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/service/eventbridge/types" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -// @SDKDataSource("aws_cloudwatch_event_source") -func DataSourceSource() *schema.Resource { +// @SDKDataSource("aws_cloudwatch_event_source", name="Source") +func dataSourceSource() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceSourceRead, @@ -25,17 +26,17 @@ func DataSourceSource() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "name_prefix": { + "created_by": { Type: schema.TypeString, - Optional: true, + Computed: true, }, "name": { Type: schema.TypeString, Computed: true, }, - "created_by": { + "name_prefix": { Type: schema.TypeString, - Computed: true, + Optional: true, }, "state": { Type: schema.TypeString, @@ -47,30 +48,21 @@ func DataSourceSource() *schema.Resource { func dataSourceSourceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) input := &eventbridge.ListEventSourcesInput{} + if v, ok := d.GetOk("name_prefix"); ok { input.NamePrefix = aws.String(v.(string)) } - log.Printf("[DEBUG] Listing EventBridge sources: %s", input) + es, err := findEventSource(ctx, conn, input) - resp, err := conn.ListEventSourcesWithContext(ctx, input) if err != nil { - return sdkdiag.AppendErrorf(diags, "listing EventBridge sources: %s", err) + return sdkdiag.AppendFromErr(diags, tfresource.SingularDataSourceFindError("EventBridge Source", err)) } - if resp == nil || len(resp.EventSources) == 0 { - return sdkdiag.AppendErrorf(diags, "no matching partner event source") - } - if len(resp.EventSources) > 1 { - return sdkdiag.AppendErrorf(diags, "multiple event sources matched; use additional constraints to reduce matches to a single event source") - } - - es := resp.EventSources[0] - - d.SetId(aws.StringValue(es.Name)) + d.SetId(aws.ToString(es.Name)) d.Set("arn", es.Arn) d.Set("created_by", es.CreatedBy) d.Set("name", es.Name) @@ -78,3 +70,33 @@ func dataSourceSourceRead(ctx context.Context, d *schema.ResourceData, meta inte return diags } + +func findEventSource(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListEventSourcesInput) (*types.EventSource, error) { + output, err := findEventSources(ctx, conn, input) + + if err != nil { + return nil, err + } + + return tfresource.AssertSingleValueResult(output) +} + +func findEventSources(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListEventSourcesInput) ([]types.EventSource, error) { + var output []types.EventSource + + err := listEventSourcesPages(ctx, conn, input, func(page *eventbridge.ListEventSourcesOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + output = append(output, page.EventSources...) + + return !lastPage + }) + + if err != nil { + return nil, err + } + + return output, nil +} From 6d9e85d91ae4ac9212f1812007eec9bd8137a0b0 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 15 Apr 2024 17:14:24 -0400 Subject: [PATCH 17/35] Add 'errs.APIError'. --- internal/errs/api.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 internal/errs/api.go diff --git a/internal/errs/api.go b/internal/errs/api.go new file mode 100644 index 00000000000..51b5df1aca9 --- /dev/null +++ b/internal/errs/api.go @@ -0,0 +1,16 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package errs + +import ( + smithy "github.com/aws/smithy-go" +) + +// APIError returns a new error suitable for checking via aws-sdk-go-base/tfawserr. +func APIError(code, message string) smithy.APIError { + return &smithy.GenericAPIError{ + Code: code, + Message: message, + } +} From 1198fb33a65ec14933b619ccc8ae9b1035cc34d6 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 15 Apr 2024 17:16:18 -0400 Subject: [PATCH 18/35] Tweak 'appconfig.NewClient'. --- internal/service/appconfig/service_package.go | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/internal/service/appconfig/service_package.go b/internal/service/appconfig/service_package.go index fa2742eca40..4bcca3d4550 100644 --- a/internal/service/appconfig/service_package.go +++ b/internal/service/appconfig/service_package.go @@ -5,7 +5,6 @@ package appconfig import ( "context" - "errors" aws_sdkv2 "github.com/aws/aws-sdk-go-v2/aws" retry_sdkv2 "github.com/aws/aws-sdk-go-v2/aws/retry" @@ -28,13 +27,11 @@ func (p *servicePackage) NewClient(ctx context.Context, config map[string]any) ( // if ongoing deployments are in-progress, thus we handle them // here for the service client. o.Retryer = conns.AddIsErrorRetryables(cfg.Retryer().(aws_sdkv2.RetryerV2), retry_sdkv2.IsErrorRetryableFunc(func(err error) aws_sdkv2.Ternary { - if err != nil { - var oe *smithy.OperationError - if errors.As(err, &oe) { - if oe.OperationName == "StartDeployment" { - if errs.IsA[*awstypes.ConflictException](err) { - return aws_sdkv2.TrueTernary - } + if v, ok := errs.As[*smithy.OperationError](err); ok { + switch v.OperationName { + case "StartDeployment": + if errs.IsA[*awstypes.ConflictException](err) { + return aws_sdkv2.TrueTernary } } } From 1ce7a1145232d2a34525101626c176d0ddd3a269 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 07:53:06 -0400 Subject: [PATCH 19/35] r/aws_cloudwatch_event_target: Migrate to AWS SDK for Go v2. --- internal/service/events/exports_test.go | 3 + internal/service/events/find.go | 59 -- internal/service/events/id.go | 56 -- internal/service/events/id_test.go | 177 ------ .../service/events/service_package_gen.go | 3 +- internal/service/events/target.go | 580 ++++++++++-------- internal/service/events/target_test.go | 236 +++++-- 7 files changed, 531 insertions(+), 583 deletions(-) delete mode 100644 internal/service/events/find.go delete mode 100644 internal/service/events/id.go delete mode 100644 internal/service/events/id_test.go diff --git a/internal/service/events/exports_test.go b/internal/service/events/exports_test.go index 1a376d9406f..7f3a5b5ff69 100644 --- a/internal/service/events/exports_test.go +++ b/internal/service/events/exports_test.go @@ -13,6 +13,7 @@ var ( ResourceEndpoint = resourceEndpoint ResourcePermission = resourcePermission ResourceRule = resourceRule + ResourceTarget = resourceTarget FindAPIDestinationByName = findAPIDestinationByName FindArchiveByName = findArchiveByName @@ -22,7 +23,9 @@ var ( FindEventBusPolicyByName = findEventBusPolicyByName FindPermissionByTwoPartKey = findPermissionByTwoPartKey FindRuleByTwoPartKey = findRuleByTwoPartKey + FindTargetByThreePartKey = findTargetByThreePartKey RuleEventPatternJSONDecoder = ruleEventPatternJSONDecoder RuleCreateResourceID = ruleCreateResourceID RuleParseResourceID = ruleParseResourceID + TargetParseImportID = targetParseImportID ) diff --git a/internal/service/events/find.go b/internal/service/events/find.go deleted file mode 100644 index bd2a9c713a0..00000000000 --- a/internal/service/events/find.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package events - -import ( - "context" - - "github.com/YakDriver/regexache" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" -) - -func FindTargetByThreePartKey(ctx context.Context, conn *eventbridge.EventBridge, busName, ruleName, targetID string) (*eventbridge.Target, error) { - input := &eventbridge.ListTargetsByRuleInput{ - Rule: aws.String(ruleName), - Limit: aws.Int64(100), // Set limit to allowed maximum to prevent API throttling - } - - if busName != "" { - input.EventBusName = aws.String(busName) - } - - var output *eventbridge.Target - - err := listTargetsByRulePages(ctx, conn, input, func(page *eventbridge.ListTargetsByRuleOutput, lastPage bool) bool { - if page == nil { - return !lastPage - } - - for _, v := range page.Targets { - if targetID == aws.StringValue(v.Id) { - output = v - return false - } - } - - return !lastPage - }) - - if tfawserr.ErrCodeEquals(err, "ValidationException", eventbridge.ErrCodeResourceNotFoundException) || (err != nil && regexache.MustCompile(" not found$").MatchString(err.Error())) { - return nil, &retry.NotFoundError{ - LastError: err, - LastRequest: input, - } - } - - if err != nil { - return nil, err - } - - if output == nil { - return nil, &retry.NotFoundError{} - } - - return output, nil -} diff --git a/internal/service/events/id.go b/internal/service/events/id.go deleted file mode 100644 index 6e8c1219206..00000000000 --- a/internal/service/events/id.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package events - -import ( - "fmt" - "strings" -) - -// Terraform resource IDs for Targets are not parseable as the separator used ("-") is also a valid character in both the rule name and the target ID. - -const ( - targetResourceIDSeparator = "-" - targetImportIDSeparator = "/" -) - -func TargetCreateResourceID(eventBusName, ruleName, targetID string) string { - var parts []string - - if eventBusName == "" || eventBusName == DefaultEventBusName { - parts = []string{ruleName, targetID} - } else { - parts = []string{eventBusName, ruleName, targetID} - } - - id := strings.Join(parts, targetResourceIDSeparator) - - return id -} - -func TargetParseImportID(id string) (string, string, string, error) { - parts := strings.Split(id, targetImportIDSeparator) - - if len(parts) == 2 && parts[0] != "" && parts[1] != "" { - return DefaultEventBusName, parts[0], parts[1], nil - } - if len(parts) == 3 && parts[0] != "" && parts[1] != "" && parts[2] != "" { - return parts[0], parts[1], parts[2], nil - } - if len(parts) > 3 { - iTarget := strings.LastIndex(id, targetImportIDSeparator) - targetID := id[iTarget+1:] - iRule := strings.LastIndex(id[:iTarget], targetImportIDSeparator) - eventBusName := id[:iRule] - ruleName := id[iRule+1 : iTarget] - if eventBusARNPattern.MatchString(eventBusName) && ruleName != "" && targetID != "" { - return eventBusName, ruleName, targetID, nil - } - if partnerEventBusPattern.MatchString(eventBusName) && ruleName != "" && targetID != "" { - return eventBusName, ruleName, targetID, nil - } - } - - return "", "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected EVENTBUSNAME%[2]sRULENAME%[2]sTARGETID or RULENAME%[2]sTARGETID", id, targetImportIDSeparator) -} diff --git a/internal/service/events/id_test.go b/internal/service/events/id_test.go deleted file mode 100644 index 6850aa2bcbd..00000000000 --- a/internal/service/events/id_test.go +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package events_test - -import ( - "testing" - - tfevents "github.com/hashicorp/terraform-provider-aws/internal/service/events" -) - -func TestTargetParseImportID(t *testing.T) { - t.Parallel() - - testCases := []struct { - TestName string - InputID string - ExpectedError bool - ExpectedPart0 string - ExpectedPart1 string - ExpectedPart2 string - }{ - { - TestName: "empty ID", - InputID: "", - ExpectedError: true, - }, - { - TestName: "single part", - InputID: "TestRule", - ExpectedError: true, - }, - { - TestName: "two parts", - InputID: "TestTarget/TestRule", - ExpectedPart0: tfevents.DefaultEventBusName, - ExpectedPart1: "TestTarget", - ExpectedPart2: "TestRule", - }, - { - TestName: "three parts", - InputID: "TestEventBus/TestRule/TestTarget", - ExpectedPart0: "TestEventBus", - ExpectedPart1: "TestRule", - ExpectedPart2: "TestTarget", - }, - { - TestName: "three parts with default event bus", - InputID: tfevents.DefaultEventBusName + "/TestRule/TestTarget", - ExpectedPart0: tfevents.DefaultEventBusName, - ExpectedPart1: "TestRule", - ExpectedPart2: "TestTarget", - }, - { - TestName: "empty two parts", - InputID: "/", - ExpectedError: true, - }, - { - TestName: "empty three parts", - InputID: "//", - ExpectedError: true, - }, - { - TestName: "empty first part of two", - InputID: "/TestTarget", - ExpectedError: true, - }, - { - TestName: "empty second part of two", - InputID: "TestRule/", - ExpectedError: true, - }, - { - TestName: "empty first part of three", - InputID: "/TestRule/TestTarget", - ExpectedError: true, - }, - { - TestName: "empty second part of three", - InputID: "TestEventBus//TestTarget", - ExpectedError: true, - }, - { - TestName: "empty third part of three", - InputID: "TestEventBus/TestRule/", - ExpectedError: true, - }, - { - TestName: "empty first two of three parts", - InputID: "//TestTarget", - ExpectedError: true, - }, - { - TestName: "empty first and third of three parts", - InputID: "/TestRule/", - ExpectedError: true, - }, - { - TestName: "empty final two of three parts", - InputID: "TestEventBus//", - ExpectedError: true, - }, - { - TestName: "partner event bus", - InputID: "aws.partner/example.com/Test/TestRule/TestTarget", - ExpectedPart0: "aws.partner/example.com/Test", - ExpectedPart1: "TestRule", - ExpectedPart2: "TestTarget", - }, - { - TestName: "ARN event bus", - InputID: "arn:aws:events:us-east-2:123456789012:event-bus/default/TestRule/TestTarget", //lintignore:AWSAT003,AWSAT005 - ExpectedPart0: "arn:aws:events:us-east-2:123456789012:event-bus/default", //lintignore:AWSAT003,AWSAT005 - ExpectedPart1: "TestRule", - ExpectedPart2: "TestTarget", - }, - { - TestName: "ARN based partner event bus", - // lintignore:AWSAT003,AWSAT005 - InputID: "arn:aws:events:us-east-2:123456789012:event-bus/aws.partner/genesys.com/cloud/a12bc345-d678-90e1-2f34-gh5678i9012ej/_genesys/TestRule/TestTarget", - // lintignore:AWSAT003,AWSAT005 - ExpectedPart0: "arn:aws:events:us-east-2:123456789012:event-bus/aws.partner/genesys.com/cloud/a12bc345-d678-90e1-2f34-gh5678i9012ej/_genesys", - ExpectedPart1: "TestRule", - ExpectedPart2: "TestTarget", - }, - { - TestName: "empty partner event rule and target", - InputID: "aws.partner/example.com/Test//", - ExpectedError: true, - }, - { - TestName: "four parts", - InputID: "aws.partner/example.com/Test/TestRule", - ExpectedError: true, - }, - { - TestName: "five parts", - InputID: "abc.partner/example.com/Test/TestRule/TestTarget", - ExpectedError: true, - }, - { - TestName: "six parts", - InputID: "test/aws.partner/example.com/Test/TestRule/TestTarget", - ExpectedError: true, - }, - } - - for _, testCase := range testCases { - testCase := testCase - t.Run(testCase.TestName, func(t *testing.T) { - t.Parallel() - - gotPart0, gotPart1, gotPart2, err := tfevents.TargetParseImportID(testCase.InputID) - - if err == nil && testCase.ExpectedError { - t.Fatalf("expected error, got no error") - } - - if err != nil && !testCase.ExpectedError { - t.Fatalf("got unexpected error: %s", err) - } - - if gotPart0 != testCase.ExpectedPart0 { - t.Errorf("got part 0 %s, expected %s", gotPart0, testCase.ExpectedPart0) - } - - if gotPart1 != testCase.ExpectedPart1 { - t.Errorf("got part 1 %s, expected %s", gotPart1, testCase.ExpectedPart1) - } - - if gotPart2 != testCase.ExpectedPart2 { - t.Errorf("got part 2 %s, expected %s", gotPart2, testCase.ExpectedPart2) - } - }) - } -} diff --git a/internal/service/events/service_package_gen.go b/internal/service/events/service_package_gen.go index f70d11c1cbd..7182fcf97ef 100644 --- a/internal/service/events/service_package_gen.go +++ b/internal/service/events/service_package_gen.go @@ -91,8 +91,9 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka }, }, { - Factory: ResourceTarget, + Factory: resourceTarget, TypeName: "aws_cloudwatch_event_target", + Name: "Target", }, } } diff --git a/internal/service/events/target.go b/internal/service/events/target.go index 0d6084faf41..99d20979104 100644 --- a/internal/service/events/target.go +++ b/internal/service/events/target.go @@ -9,26 +9,31 @@ import ( "fmt" "log" "math" + "strings" "github.com/YakDriver/regexache" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/service/eventbridge/types" + "github.com/hashicorp/aws-sdk-go-base/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/enum" + "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" "github.com/hashicorp/terraform-provider-aws/internal/flex" + tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" "github.com/hashicorp/terraform-provider-aws/internal/verify" ) -// @SDKResource("aws_cloudwatch_event_target") -func ResourceTarget() *schema.Resource { +// @SDKResource("aws_cloudwatch_event_target", name="Target") +func resourceTarget() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceTargetCreate, ReadWithoutTimeout: resourceTargetRead, @@ -36,7 +41,20 @@ func ResourceTarget() *schema.Resource { DeleteWithoutTimeout: resourceTargetDelete, Importer: &schema.ResourceImporter{ - StateContext: resourceTargetImport, + StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + busName, ruleName, targetID, err := targetParseImportID(d.Id()) + if err != nil { + return []*schema.ResourceData{}, err + } + + id := targetCreateResourceID(busName, ruleName, targetID) + d.SetId(id) + d.Set("target_id", targetID) + d.Set("rule", ruleName) + d.Set("event_bus_name", busName) + + return []*schema.ResourceData{d}, nil + }, }, SchemaVersion: 1, @@ -139,9 +157,9 @@ func ResourceTarget() *schema.Resource { ValidateFunc: validation.StringLenBetween(1, 255), }, "launch_type": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice(eventbridge.LaunchType_Values(), false), + Type: schema.TypeString, + Optional: true, + ValidateDiagFunc: enum.Validate[types.LaunchType](), }, "network_configuration": { Type: schema.TypeList, @@ -179,9 +197,9 @@ func ResourceTarget() *schema.Resource { ValidateFunc: validation.StringLenBetween(0, 255), }, "type": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice(eventbridge.PlacementStrategyType_Values(), false), + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: enum.Validate[types.PlacementStrategyType](), }, }, }, @@ -197,9 +215,9 @@ func ResourceTarget() *schema.Resource { Optional: true, }, "type": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice(eventbridge.PlacementConstraintType_Values(), false), + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: enum.Validate[types.PlacementConstraintType](), }, }, }, @@ -210,9 +228,9 @@ func ResourceTarget() *schema.Resource { ValidateFunc: validation.StringLenBetween(0, 1600), }, "propagate_tags": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice(eventbridge.PropagateTags_Values(), false), + Type: schema.TypeString, + Optional: true, + ValidateDiagFunc: enum.Validate[types.PropagateTags](), }, "tags": tftags.TagsSchema(), "task_count": { @@ -471,8 +489,7 @@ func ResourceTarget() *schema.Resource { func resourceTargetCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) rule := d.Get("rule").(string) @@ -487,12 +504,11 @@ func resourceTargetCreate(ctx context.Context, d *schema.ResourceData, meta inte if v, ok := d.GetOk("event_bus_name"); ok { busName = v.(string) } - id := TargetCreateResourceID(busName, rule, targetID) + id := targetCreateResourceID(busName, rule, targetID) - input := buildPutTargetInputStruct(ctx, d) + input := expandPutTargetsInput(ctx, d) - log.Printf("[DEBUG] Creating EventBridge Target: %s", input) - output, err := conn.PutTargetsWithContext(ctx, input) + output, err := conn.PutTargets(ctx, input) if err == nil && output != nil { err = putTargetsError(output.FailedEntries) @@ -509,12 +525,10 @@ func resourceTargetCreate(ctx context.Context, d *schema.ResourceData, meta inte func resourceTargetRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) busName := d.Get("event_bus_name").(string) - - t, err := FindTargetByThreePartKey(ctx, conn, busName, d.Get("rule").(string), d.Get("target_id").(string)) + target, err := findTargetByThreePartKey(ctx, conn, busName, d.Get("rule").(string), d.Get("target_id").(string)) if !d.IsNewResource() && tfresource.NotFound(err) { log.Printf("[WARN] EventBridge Target (%s) not found, removing from state", d.Id()) @@ -526,77 +540,77 @@ func resourceTargetRead(ctx context.Context, d *schema.ResourceData, meta interf return sdkdiag.AppendErrorf(diags, "reading EventBridge Target (%s): %s", d.Id(), err) } - d.Set("arn", t.Arn) - d.Set("target_id", t.Id) - d.Set("input", t.Input) - d.Set("input_path", t.InputPath) - d.Set("role_arn", t.RoleArn) + d.Set("arn", target.Arn) d.Set("event_bus_name", busName) + d.Set("input", target.Input) + d.Set("input_path", target.InputPath) + d.Set("role_arn", target.RoleArn) + d.Set("target_id", target.Id) - if t.RunCommandParameters != nil { - if err := d.Set("run_command_targets", flattenTargetRunParameters(t.RunCommandParameters)); err != nil { + if target.RunCommandParameters != nil { + if err := d.Set("run_command_targets", flattenTargetRunParameters(target.RunCommandParameters)); err != nil { return sdkdiag.AppendErrorf(diags, "setting run_command_targets: %s", err) } } - if t.HttpParameters != nil { - if err := d.Set("http_target", []interface{}{flattenTargetHTTPParameters(t.HttpParameters)}); err != nil { + if target.HttpParameters != nil { + if err := d.Set("http_target", []interface{}{flattenTargetHTTPParameters(target.HttpParameters)}); err != nil { return sdkdiag.AppendErrorf(diags, "setting http_target: %s", err) } } else { d.Set("http_target", nil) } - if t.RedshiftDataParameters != nil { - if err := d.Set("redshift_target", flattenTargetRedshiftParameters(t.RedshiftDataParameters)); err != nil { + if target.RedshiftDataParameters != nil { + if err := d.Set("redshift_target", flattenTargetRedshiftParameters(target.RedshiftDataParameters)); err != nil { return sdkdiag.AppendErrorf(diags, "setting redshift_target: %s", err) } } - if t.EcsParameters != nil { - if err := d.Set("ecs_target", flattenTargetECSParameters(ctx, t.EcsParameters)); err != nil { + if target.EcsParameters != nil { + if err := d.Set("ecs_target", flattenTargetECSParameters(ctx, target.EcsParameters)); err != nil { return sdkdiag.AppendErrorf(diags, "setting ecs_target: %s", err) } } - if t.BatchParameters != nil { - if err := d.Set("batch_target", flattenTargetBatchParameters(t.BatchParameters)); err != nil { + if target.BatchParameters != nil { + if err := d.Set("batch_target", flattenTargetBatchParameters(target.BatchParameters)); err != nil { return sdkdiag.AppendErrorf(diags, "setting batch_target: %s", err) } } - if t.KinesisParameters != nil { - if err := d.Set("kinesis_target", flattenTargetKinesisParameters(t.KinesisParameters)); err != nil { + if target.KinesisParameters != nil { + if err := d.Set("kinesis_target", flattenTargetKinesisParameters(target.KinesisParameters)); err != nil { return sdkdiag.AppendErrorf(diags, "setting kinesis_target: %s", err) } } - if t.SageMakerPipelineParameters != nil { - if err := d.Set("sagemaker_pipeline_target", flattenTargetSageMakerPipelineParameters(t.SageMakerPipelineParameters)); err != nil { + if target.SageMakerPipelineParameters != nil { + if err := d.Set("sagemaker_pipeline_target", flattenTargetSageMakerPipelineParameters(target.SageMakerPipelineParameters)); err != nil { return sdkdiag.AppendErrorf(diags, "setting sagemaker_pipeline_parameters: %s", err) } } - if t.SqsParameters != nil { - if err := d.Set("sqs_target", flattenTargetSQSParameters(t.SqsParameters)); err != nil { + if target.SqsParameters != nil { + if err := d.Set("sqs_target", flattenTargetSQSParameters(target.SqsParameters)); err != nil { return sdkdiag.AppendErrorf(diags, "setting sqs_target: %s", err) } } - if t.InputTransformer != nil { - if err := d.Set("input_transformer", flattenInputTransformer(t.InputTransformer)); err != nil { + if target.InputTransformer != nil { + if err := d.Set("input_transformer", flattenInputTransformer(target.InputTransformer)); err != nil { return sdkdiag.AppendErrorf(diags, "setting input_transformer: %s", err) } } - if t.RetryPolicy != nil { - if err := d.Set("retry_policy", flattenTargetRetryPolicy(t.RetryPolicy)); err != nil { + if target.RetryPolicy != nil { + if err := d.Set("retry_policy", flattenTargetRetryPolicy(target.RetryPolicy)); err != nil { return sdkdiag.AppendErrorf(diags, "setting retry_policy: %s", err) } } - if t.DeadLetterConfig != nil { - if err := d.Set("dead_letter_config", flattenTargetDeadLetterConfig(t.DeadLetterConfig)); err != nil { + if target.DeadLetterConfig != nil { + if err := d.Set("dead_letter_config", flattenTargetDeadLetterConfig(target.DeadLetterConfig)); err != nil { return sdkdiag.AppendErrorf(diags, "setting dead_letter_config: %s", err) } } @@ -606,13 +620,11 @@ func resourceTargetRead(ctx context.Context, d *schema.ResourceData, meta interf func resourceTargetUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics + conn := meta.(*conns.AWSClient).EventsClient(ctx) - conn := meta.(*conns.AWSClient).EventsConn(ctx) + input := expandPutTargetsInput(ctx, d) - input := buildPutTargetInputStruct(ctx, d) - - log.Printf("[DEBUG] Updating EventBridge Target: %s", input) - output, err := conn.PutTargetsWithContext(ctx, input) + output, err := conn.PutTargets(ctx, input) if err == nil && output != nil { err = putTargetsError(output.FailedEntries) @@ -627,11 +639,10 @@ func resourceTargetUpdate(ctx context.Context, d *schema.ResourceData, meta inte func resourceTargetDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics - - conn := meta.(*conns.AWSClient).EventsConn(ctx) + conn := meta.(*conns.AWSClient).EventsClient(ctx) input := &eventbridge.RemoveTargetsInput{ - Ids: []*string{aws.String(d.Get("target_id").(string))}, + Ids: []string{d.Get("target_id").(string)}, Rule: aws.String(d.Get("rule").(string)), } @@ -640,13 +651,13 @@ func resourceTargetDelete(ctx context.Context, d *schema.ResourceData, meta inte } log.Printf("[DEBUG] Deleting EventBridge Target: %s", d.Id()) - output, err := conn.RemoveTargetsWithContext(ctx, input) + output, err := conn.RemoveTargets(ctx, input) if err == nil && output != nil { err = removeTargetsError(output.FailedEntries) } - if tfawserr.ErrCodeEquals(err, eventbridge.ErrCodeResourceNotFoundException) { + if errs.IsA[*types.ResourceNotFoundException](err) { return diags } @@ -657,138 +668,233 @@ func resourceTargetDelete(ctx context.Context, d *schema.ResourceData, meta inte return diags } -func putTargetError(apiObject *eventbridge.PutTargetsResultEntry) error { - if apiObject == nil { - return nil +func findTargetByThreePartKey(ctx context.Context, conn *eventbridge.Client, busName, ruleName, targetID string) (*types.Target, error) { + input := &eventbridge.ListTargetsByRuleInput{ + Rule: aws.String(ruleName), + Limit: aws.Int32(100), // Set limit to allowed maximum to prevent API throttling + } + if busName != "" { + input.EventBusName = aws.String(busName) + } + + return findTarget(ctx, conn, input, func(v *types.Target) bool { + return targetID == aws.ToString(v.Id) + }) +} + +func findTarget(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListTargetsByRuleInput, filter tfslices.Predicate[*types.Target]) (*types.Target, error) { + output, err := findTargets(ctx, conn, input, filter) + + if err != nil { + return nil, err + } + + return tfresource.AssertSingleValueResult(output) +} + +func findTargets(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListTargetsByRuleInput, filter tfslices.Predicate[*types.Target]) ([]types.Target, error) { + var output []types.Target + + err := listTargetsByRulePages(ctx, conn, input, func(page *eventbridge.ListTargetsByRuleOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.Targets { + if filter(&v) { + output = append(output, v) + } + } + + return !lastPage + }) + + if tfawserr.ErrCodeEquals(err, errCodeValidationException) || errs.IsA[*types.ResourceNotFoundException](err) || (err != nil && regexache.MustCompile(" not found$").MatchString(err.Error())) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + return output, nil +} + +// Terraform resource IDs for Targets are not parseable as the separator used ("-") is also a valid character in both the rule name and the target ID. +const ( + targetResourceIDSeparator = "-" + targetImportIDSeparator = "/" +) + +func targetCreateResourceID(eventBusName, ruleName, targetID string) string { + var parts []string + + if eventBusName == "" || eventBusName == DefaultEventBusName { + parts = []string{ruleName, targetID} + } else { + parts = []string{eventBusName, ruleName, targetID} } - return awserr.New(aws.StringValue(apiObject.ErrorCode), aws.StringValue(apiObject.ErrorMessage), nil) + id := strings.Join(parts, targetResourceIDSeparator) + + return id } -func putTargetsError(apiObjects []*eventbridge.PutTargetsResultEntry) error { +func targetParseImportID(id string) (string, string, string, error) { + parts := strings.Split(id, targetImportIDSeparator) + + if len(parts) == 2 && parts[0] != "" && parts[1] != "" { + return DefaultEventBusName, parts[0], parts[1], nil + } + if len(parts) == 3 && parts[0] != "" && parts[1] != "" && parts[2] != "" { + return parts[0], parts[1], parts[2], nil + } + if len(parts) > 3 { + iTarget := strings.LastIndex(id, targetImportIDSeparator) + targetID := id[iTarget+1:] + iRule := strings.LastIndex(id[:iTarget], targetImportIDSeparator) + eventBusName := id[:iRule] + ruleName := id[iRule+1 : iTarget] + if eventBusARNPattern.MatchString(eventBusName) && ruleName != "" && targetID != "" { + return eventBusName, ruleName, targetID, nil + } + if partnerEventBusPattern.MatchString(eventBusName) && ruleName != "" && targetID != "" { + return eventBusName, ruleName, targetID, nil + } + } + + return "", "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected EVENTBUSNAME%[2]sRULENAME%[2]sTARGETID or RULENAME%[2]sTARGETID", id, targetImportIDSeparator) +} + +func putTargetError(apiObject types.PutTargetsResultEntry) error { + return errs.APIError(aws.ToString(apiObject.ErrorCode), aws.ToString(apiObject.ErrorMessage)) +} + +func putTargetsError(apiObjects []types.PutTargetsResultEntry) error { var errs []error for _, apiObject := range apiObjects { if err := putTargetError(apiObject); err != nil { - errs = append(errs, fmt.Errorf("%s: %w", aws.StringValue(apiObject.TargetId), err)) + errs = append(errs, fmt.Errorf("%s: %w", aws.ToString(apiObject.TargetId), err)) } } return errors.Join(errs...) } -func removeTargetError(apiObject *eventbridge.RemoveTargetsResultEntry) error { - if apiObject == nil { - return nil - } - - return awserr.New(aws.StringValue(apiObject.ErrorCode), aws.StringValue(apiObject.ErrorMessage), nil) +func removeTargetError(apiObject types.RemoveTargetsResultEntry) error { + return errs.APIError(aws.ToString(apiObject.ErrorCode), aws.ToString(apiObject.ErrorMessage)) } -func removeTargetsError(apiObjects []*eventbridge.RemoveTargetsResultEntry) error { +func removeTargetsError(apiObjects []types.RemoveTargetsResultEntry) error { var errs []error for _, apiObject := range apiObjects { if err := removeTargetError(apiObject); err != nil { - errs = append(errs, fmt.Errorf("%s: %w", aws.StringValue(apiObject.TargetId), err)) + errs = append(errs, fmt.Errorf("%s: %w", aws.ToString(apiObject.TargetId), err)) } } return errors.Join(errs...) } -func buildPutTargetInputStruct(ctx context.Context, d *schema.ResourceData) *eventbridge.PutTargetsInput { - e := &eventbridge.Target{ +func expandPutTargetsInput(ctx context.Context, d *schema.ResourceData) *eventbridge.PutTargetsInput { + target := types.Target{ Arn: aws.String(d.Get("arn").(string)), Id: aws.String(d.Get("target_id").(string)), } if v, ok := d.GetOk("input"); ok { - e.Input = aws.String(v.(string)) + target.Input = aws.String(v.(string)) } + if v, ok := d.GetOk("input_path"); ok { - e.InputPath = aws.String(v.(string)) + target.InputPath = aws.String(v.(string)) } if v, ok := d.GetOk("role_arn"); ok { - e.RoleArn = aws.String(v.(string)) + target.RoleArn = aws.String(v.(string)) } if v, ok := d.GetOk("run_command_targets"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - e.RunCommandParameters = expandTargetRunParameters(v.([]interface{})) + target.RunCommandParameters = expandTargetRunParameters(v.([]interface{})) } if v, ok := d.GetOk("ecs_target"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - e.EcsParameters = expandTargetECSParameters(ctx, v.([]interface{})) + target.EcsParameters = expandTargetECSParameters(ctx, v.([]interface{})) } if v, ok := d.GetOk("redshift_target"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - e.RedshiftDataParameters = expandTargetRedshiftParameters(v.([]interface{})) + target.RedshiftDataParameters = expandTargetRedshiftParameters(v.([]interface{})) } if v, ok := d.GetOk("http_target"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - e.HttpParameters = expandTargetHTTPParameters(v.([]interface{})[0].(map[string]interface{})) + target.HttpParameters = expandTargetHTTPParameters(v.([]interface{})[0].(map[string]interface{})) } if v, ok := d.GetOk("batch_target"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - e.BatchParameters = expandTargetBatchParameters(v.([]interface{})) + target.BatchParameters = expandTargetBatchParameters(v.([]interface{})) } if v, ok := d.GetOk("kinesis_target"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - e.KinesisParameters = expandTargetKinesisParameters(v.([]interface{})) + target.KinesisParameters = expandTargetKinesisParameters(v.([]interface{})) } if v, ok := d.GetOk("sqs_target"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - e.SqsParameters = expandTargetSQSParameters(v.([]interface{})) + target.SqsParameters = expandTargetSQSParameters(v.([]interface{})) } if v, ok := d.GetOk("sagemaker_pipeline_target"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - e.SageMakerPipelineParameters = expandTargetSageMakerPipelineParameters(v.([]interface{})) + target.SageMakerPipelineParameters = expandTargetSageMakerPipelineParameters(v.([]interface{})) } if v, ok := d.GetOk("input_transformer"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - e.InputTransformer = expandTransformerParameters(v.([]interface{})) + target.InputTransformer = expandTransformerParameters(v.([]interface{})) } if v, ok := d.GetOk("retry_policy"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - e.RetryPolicy = expandRetryPolicyParameters(v.([]interface{})) + target.RetryPolicy = expandRetryPolicyParameters(v.([]interface{})) } if v, ok := d.GetOk("dead_letter_config"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - e.DeadLetterConfig = expandDeadLetterParametersConfig(v.([]interface{})) + target.DeadLetterConfig = expandDeadLetterParametersConfig(v.([]interface{})) } - input := eventbridge.PutTargetsInput{ + input := &eventbridge.PutTargetsInput{ Rule: aws.String(d.Get("rule").(string)), - Targets: []*eventbridge.Target{e}, + Targets: []types.Target{target}, } + if v, ok := d.GetOk("event_bus_name"); ok { input.EventBusName = aws.String(v.(string)) } - return &input + return input } -func expandTargetRunParameters(config []interface{}) *eventbridge.RunCommandParameters { - commands := make([]*eventbridge.RunCommandTarget, 0) +func expandTargetRunParameters(config []interface{}) *types.RunCommandParameters { + commands := make([]types.RunCommandTarget, 0) for _, c := range config { param := c.(map[string]interface{}) - command := &eventbridge.RunCommandTarget{ + command := types.RunCommandTarget{ Key: aws.String(param["key"].(string)), - Values: flex.ExpandStringList(param["values"].([]interface{})), + Values: flex.ExpandStringValueList(param["values"].([]interface{})), } commands = append(commands, command) } - command := &eventbridge.RunCommandParameters{ + command := &types.RunCommandParameters{ RunCommandTargets: commands, } return command } -func expandTargetRedshiftParameters(config []interface{}) *eventbridge.RedshiftDataParameters { - redshiftParameters := &eventbridge.RedshiftDataParameters{} +func expandTargetRedshiftParameters(config []interface{}) *types.RedshiftDataParameters { + redshiftParameters := &types.RedshiftDataParameters{} for _, c := range config { param := c.(map[string]interface{}) @@ -796,7 +902,7 @@ func expandTargetRedshiftParameters(config []interface{}) *eventbridge.RedshiftD redshiftParameters.Sql = aws.String(param["sql"].(string)) if val, ok := param["with_event"].(bool); ok { - redshiftParameters.WithEvent = aws.Bool(val) + redshiftParameters.WithEvent = val } if val, ok := param["statement_name"].(string); ok && val != "" { @@ -815,8 +921,8 @@ func expandTargetRedshiftParameters(config []interface{}) *eventbridge.RedshiftD return redshiftParameters } -func expandTargetECSParameters(ctx context.Context, tfList []interface{}) *eventbridge.EcsParameters { - ecsParameters := &eventbridge.EcsParameters{} +func expandTargetECSParameters(ctx context.Context, tfList []interface{}) *types.EcsParameters { + ecsParameters := &types.EcsParameters{} for _, c := range tfList { tfMap := c.(map[string]interface{}) tags := tftags.New(ctx, tfMap["tags"].(map[string]interface{})) @@ -830,7 +936,7 @@ func expandTargetECSParameters(ctx context.Context, tfList []interface{}) *event } if v, ok := tfMap["launch_type"].(string); ok && v != "" { - ecsParameters.LaunchType = aws.String(v) + ecsParameters.LaunchType = types.LaunchType(v) } if v, ok := tfMap["network_configuration"]; ok { @@ -850,42 +956,42 @@ func expandTargetECSParameters(ctx context.Context, tfList []interface{}) *event } if v, ok := tfMap["propagate_tags"].(string); ok && v != "" { - ecsParameters.PropagateTags = aws.String(v) + ecsParameters.PropagateTags = types.PropagateTags(v) } if len(tags) > 0 { ecsParameters.Tags = Tags(tags.IgnoreAWS()) } - ecsParameters.EnableExecuteCommand = aws.Bool(tfMap["enable_execute_command"].(bool)) - ecsParameters.EnableECSManagedTags = aws.Bool(tfMap["enable_ecs_managed_tags"].(bool)) - ecsParameters.TaskCount = aws.Int64(int64(tfMap["task_count"].(int))) + ecsParameters.EnableExecuteCommand = tfMap["enable_execute_command"].(bool) + ecsParameters.EnableECSManagedTags = tfMap["enable_ecs_managed_tags"].(bool) + ecsParameters.TaskCount = aws.Int32(int32(tfMap["task_count"].(int))) ecsParameters.TaskDefinitionArn = aws.String(tfMap["task_definition_arn"].(string)) } return ecsParameters } -func expandRetryPolicyParameters(rp []interface{}) *eventbridge.RetryPolicy { - retryPolicy := &eventbridge.RetryPolicy{} +func expandRetryPolicyParameters(rp []interface{}) *types.RetryPolicy { + retryPolicy := &types.RetryPolicy{} for _, v := range rp { params := v.(map[string]interface{}) if val, ok := params["maximum_event_age_in_seconds"].(int); ok { - retryPolicy.MaximumEventAgeInSeconds = aws.Int64(int64(val)) + retryPolicy.MaximumEventAgeInSeconds = aws.Int32(int32(val)) } if val, ok := params["maximum_retry_attempts"].(int); ok { - retryPolicy.MaximumRetryAttempts = aws.Int64(int64(val)) + retryPolicy.MaximumRetryAttempts = aws.Int32(int32(val)) } } return retryPolicy } -func expandDeadLetterParametersConfig(dlp []interface{}) *eventbridge.DeadLetterConfig { - deadLetterConfig := &eventbridge.DeadLetterConfig{} +func expandDeadLetterParametersConfig(dlp []interface{}) *types.DeadLetterConfig { + deadLetterConfig := &types.DeadLetterConfig{} for _, v := range dlp { params := v.(map[string]interface{}) @@ -898,40 +1004,40 @@ func expandDeadLetterParametersConfig(dlp []interface{}) *eventbridge.DeadLetter return deadLetterConfig } -func expandTargetECSParametersNetworkConfiguration(nc []interface{}) *eventbridge.NetworkConfiguration { +func expandTargetECSParametersNetworkConfiguration(nc []interface{}) *types.NetworkConfiguration { if len(nc) == 0 { return nil } - awsVpcConfig := &eventbridge.AwsVpcConfiguration{} + awsVpcConfig := &types.AwsVpcConfiguration{} raw := nc[0].(map[string]interface{}) if val, ok := raw["security_groups"]; ok { - awsVpcConfig.SecurityGroups = flex.ExpandStringSet(val.(*schema.Set)) + awsVpcConfig.SecurityGroups = flex.ExpandStringValueSet(val.(*schema.Set)) } - awsVpcConfig.Subnets = flex.ExpandStringSet(raw["subnets"].(*schema.Set)) + awsVpcConfig.Subnets = flex.ExpandStringValueSet(raw["subnets"].(*schema.Set)) if val, ok := raw["assign_public_ip"].(bool); ok { - awsVpcConfig.AssignPublicIp = aws.String(eventbridge.AssignPublicIpDisabled) + awsVpcConfig.AssignPublicIp = types.AssignPublicIpDisabled if val { - awsVpcConfig.AssignPublicIp = aws.String(eventbridge.AssignPublicIpEnabled) + awsVpcConfig.AssignPublicIp = types.AssignPublicIpEnabled } } - return &eventbridge.NetworkConfiguration{AwsvpcConfiguration: awsVpcConfig} + return &types.NetworkConfiguration{AwsvpcConfiguration: awsVpcConfig} } -func expandTargetBatchParameters(config []interface{}) *eventbridge.BatchParameters { - batchParameters := &eventbridge.BatchParameters{} +func expandTargetBatchParameters(config []interface{}) *types.BatchParameters { + batchParameters := &types.BatchParameters{} for _, c := range config { param := c.(map[string]interface{}) batchParameters.JobDefinition = aws.String(param["job_definition"].(string)) batchParameters.JobName = aws.String(param["job_name"].(string)) if v, ok := param["array_size"].(int); ok && v > 1 && v <= 10000 { - arrayProperties := &eventbridge.BatchArrayProperties{} - arrayProperties.Size = aws.Int64(int64(v)) + arrayProperties := &types.BatchArrayProperties{} + arrayProperties.Size = int32(v) batchParameters.ArrayProperties = arrayProperties } if v, ok := param["job_attempts"].(int); ok && v > 0 && v <= 10 { - retryStrategy := &eventbridge.BatchRetryStrategy{} - retryStrategy.Attempts = aws.Int64(int64(v)) + retryStrategy := &types.BatchRetryStrategy{} + retryStrategy.Attempts = int32(v) batchParameters.RetryStrategy = retryStrategy } } @@ -939,8 +1045,8 @@ func expandTargetBatchParameters(config []interface{}) *eventbridge.BatchParamet return batchParameters } -func expandTargetKinesisParameters(config []interface{}) *eventbridge.KinesisParameters { - kinesisParameters := &eventbridge.KinesisParameters{} +func expandTargetKinesisParameters(config []interface{}) *types.KinesisParameters { + kinesisParameters := &types.KinesisParameters{} for _, c := range config { param := c.(map[string]interface{}) if v, ok := param["partition_key_path"].(string); ok && v != "" { @@ -951,8 +1057,8 @@ func expandTargetKinesisParameters(config []interface{}) *eventbridge.KinesisPar return kinesisParameters } -func expandTargetSQSParameters(config []interface{}) *eventbridge.SqsParameters { - sqsParameters := &eventbridge.SqsParameters{} +func expandTargetSQSParameters(config []interface{}) *types.SqsParameters { + sqsParameters := &types.SqsParameters{} for _, c := range config { param := c.(map[string]interface{}) if v, ok := param["message_group_id"].(string); ok && v != "" { @@ -963,12 +1069,12 @@ func expandTargetSQSParameters(config []interface{}) *eventbridge.SqsParameters return sqsParameters } -func expandTargetSageMakerPipelineParameterList(tfList []interface{}) []*eventbridge.SageMakerPipelineParameter { +func expandTargetSageMakerPipelineParameterList(tfList []interface{}) []types.SageMakerPipelineParameter { if len(tfList) == 0 { return nil } - var result []*eventbridge.SageMakerPipelineParameter + var result []types.SageMakerPipelineParameter for _, tfMapRaw := range tfList { if tfMapRaw == nil { @@ -977,7 +1083,7 @@ func expandTargetSageMakerPipelineParameterList(tfList []interface{}) []*eventbr tfMap := tfMapRaw.(map[string]interface{}) - apiObject := &eventbridge.SageMakerPipelineParameter{} + apiObject := types.SageMakerPipelineParameter{} if v, ok := tfMap["name"].(string); ok && v != "" { apiObject.Name = aws.String(v) @@ -993,8 +1099,8 @@ func expandTargetSageMakerPipelineParameterList(tfList []interface{}) []*eventbr return result } -func expandTargetSageMakerPipelineParameters(config []interface{}) *eventbridge.SageMakerPipelineParameters { - sageMakerPipelineParameters := &eventbridge.SageMakerPipelineParameters{} +func expandTargetSageMakerPipelineParameters(config []interface{}) *types.SageMakerPipelineParameters { + sageMakerPipelineParameters := &types.SageMakerPipelineParameters{} for _, c := range config { param := c.(map[string]interface{}) if v, ok := param["pipeline_parameter_list"].(*schema.Set); ok && v.Len() > 0 { @@ -1005,39 +1111,39 @@ func expandTargetSageMakerPipelineParameters(config []interface{}) *eventbridge. return sageMakerPipelineParameters } -func expandTargetHTTPParameters(tfMap map[string]interface{}) *eventbridge.HttpParameters { +func expandTargetHTTPParameters(tfMap map[string]interface{}) *types.HttpParameters { if tfMap == nil { return nil } - apiObject := &eventbridge.HttpParameters{} + apiObject := &types.HttpParameters{} if v, ok := tfMap["header_parameters"].(map[string]interface{}); ok && len(v) > 0 { - apiObject.HeaderParameters = flex.ExpandStringMap(v) + apiObject.HeaderParameters = flex.ExpandStringValueMap(v) } if v, ok := tfMap["path_parameter_values"].([]interface{}); ok && len(v) > 0 { - apiObject.PathParameterValues = flex.ExpandStringList(v) + apiObject.PathParameterValues = flex.ExpandStringValueList(v) } if v, ok := tfMap["query_string_parameters"].(map[string]interface{}); ok && len(v) > 0 { - apiObject.QueryStringParameters = flex.ExpandStringMap(v) + apiObject.QueryStringParameters = flex.ExpandStringValueMap(v) } return apiObject } -func expandTransformerParameters(config []interface{}) *eventbridge.InputTransformer { - transformerParameters := &eventbridge.InputTransformer{} +func expandTransformerParameters(config []interface{}) *types.InputTransformer { + transformerParameters := &types.InputTransformer{} - inputPathsMaps := map[string]*string{} + inputPathsMaps := map[string]string{} for _, c := range config { param := c.(map[string]interface{}) inputPaths := param["input_paths"].(map[string]interface{}) for k, v := range inputPaths { - inputPathsMaps[k] = aws.String(v.(string)) + inputPathsMaps[k] = v.(string) } transformerParameters.InputTemplate = aws.String(param["input_template"].(string)) } @@ -1046,14 +1152,14 @@ func expandTransformerParameters(config []interface{}) *eventbridge.InputTransfo return transformerParameters } -func flattenTargetRunParameters(runCommand *eventbridge.RunCommandParameters) []map[string]interface{} { +func flattenTargetRunParameters(runCommand *types.RunCommandParameters) []map[string]interface{} { result := make([]map[string]interface{}, 0) for _, x := range runCommand.RunCommandTargets { config := make(map[string]interface{}) - config["key"] = aws.StringValue(x.Key) - config["values"] = flex.FlattenStringList(x.Values) + config["key"] = aws.ToString(x.Key) + config["values"] = x.Values result = append(result, config) } @@ -1061,24 +1167,20 @@ func flattenTargetRunParameters(runCommand *eventbridge.RunCommandParameters) [] return result } -func flattenTargetECSParameters(ctx context.Context, ecsParameters *eventbridge.EcsParameters) []map[string]interface{} { +func flattenTargetECSParameters(ctx context.Context, ecsParameters *types.EcsParameters) []map[string]interface{} { config := make(map[string]interface{}) if ecsParameters.Group != nil { - config["group"] = aws.StringValue(ecsParameters.Group) + config["group"] = aws.ToString(ecsParameters.Group) } - if ecsParameters.LaunchType != nil { - config["launch_type"] = aws.StringValue(ecsParameters.LaunchType) - } + config["launch_type"] = ecsParameters.LaunchType config["network_configuration"] = flattenTargetECSParametersNetworkConfiguration(ecsParameters.NetworkConfiguration) if ecsParameters.PlatformVersion != nil { - config["platform_version"] = aws.StringValue(ecsParameters.PlatformVersion) + config["platform_version"] = aws.ToString(ecsParameters.PlatformVersion) } - if ecsParameters.PropagateTags != nil { - config["propagate_tags"] = aws.StringValue(ecsParameters.PropagateTags) - } + config["propagate_tags"] = ecsParameters.PropagateTags if ecsParameters.PlacementConstraints != nil { config["placement_constraint"] = flattenTargetPlacementConstraints(ecsParameters.PlacementConstraints) @@ -1093,99 +1195,96 @@ func flattenTargetECSParameters(ctx context.Context, ecsParameters *eventbridge. } config["tags"] = KeyValueTags(ctx, ecsParameters.Tags).IgnoreAWS().Map() - config["enable_execute_command"] = aws.BoolValue(ecsParameters.EnableExecuteCommand) - config["enable_ecs_managed_tags"] = aws.BoolValue(ecsParameters.EnableECSManagedTags) - config["task_count"] = aws.Int64Value(ecsParameters.TaskCount) - config["task_definition_arn"] = aws.StringValue(ecsParameters.TaskDefinitionArn) + config["enable_execute_command"] = ecsParameters.EnableExecuteCommand + config["enable_ecs_managed_tags"] = ecsParameters.EnableECSManagedTags + config["task_count"] = aws.ToInt32(ecsParameters.TaskCount) + config["task_definition_arn"] = aws.ToString(ecsParameters.TaskDefinitionArn) result := []map[string]interface{}{config} return result } -func flattenTargetRedshiftParameters(redshiftParameters *eventbridge.RedshiftDataParameters) []map[string]interface{} { +func flattenTargetRedshiftParameters(redshiftParameters *types.RedshiftDataParameters) []map[string]interface{} { config := make(map[string]interface{}) if redshiftParameters == nil { return []map[string]interface{}{config} } - config["database"] = aws.StringValue(redshiftParameters.Database) - config["db_user"] = aws.StringValue(redshiftParameters.DbUser) - config["secrets_manager_arn"] = aws.StringValue(redshiftParameters.SecretManagerArn) - config["sql"] = aws.StringValue(redshiftParameters.Sql) - config["statement_name"] = aws.StringValue(redshiftParameters.StatementName) - config["with_event"] = aws.BoolValue(redshiftParameters.WithEvent) + config["database"] = aws.ToString(redshiftParameters.Database) + config["db_user"] = aws.ToString(redshiftParameters.DbUser) + config["secrets_manager_arn"] = aws.ToString(redshiftParameters.SecretManagerArn) + config["sql"] = aws.ToString(redshiftParameters.Sql) + config["statement_name"] = aws.ToString(redshiftParameters.StatementName) + config["with_event"] = redshiftParameters.WithEvent result := []map[string]interface{}{config} return result } -func flattenTargetECSParametersNetworkConfiguration(nc *eventbridge.NetworkConfiguration) []interface{} { +func flattenTargetECSParametersNetworkConfiguration(nc *types.NetworkConfiguration) []interface{} { if nc == nil { return nil } result := make(map[string]interface{}) - result["security_groups"] = flex.FlattenStringSet(nc.AwsvpcConfiguration.SecurityGroups) - result["subnets"] = flex.FlattenStringSet(nc.AwsvpcConfiguration.Subnets) - - if nc.AwsvpcConfiguration.AssignPublicIp != nil { - result["assign_public_ip"] = aws.StringValue(nc.AwsvpcConfiguration.AssignPublicIp) == eventbridge.AssignPublicIpEnabled - } + result["security_groups"] = nc.AwsvpcConfiguration.SecurityGroups + result["subnets"] = nc.AwsvpcConfiguration.Subnets + result["assign_public_ip"] = nc.AwsvpcConfiguration.AssignPublicIp == types.AssignPublicIpEnabled return []interface{}{result} } -func flattenTargetBatchParameters(batchParameters *eventbridge.BatchParameters) []map[string]interface{} { +func flattenTargetBatchParameters(batchParameters *types.BatchParameters) []map[string]interface{} { config := make(map[string]interface{}) - config["job_definition"] = aws.StringValue(batchParameters.JobDefinition) - config["job_name"] = aws.StringValue(batchParameters.JobName) + config["job_definition"] = aws.ToString(batchParameters.JobDefinition) + config["job_name"] = aws.ToString(batchParameters.JobName) if batchParameters.ArrayProperties != nil { - config["array_size"] = int(aws.Int64Value(batchParameters.ArrayProperties.Size)) + config["array_size"] = batchParameters.ArrayProperties.Size } if batchParameters.RetryStrategy != nil { - config["job_attempts"] = int(aws.Int64Value(batchParameters.RetryStrategy.Attempts)) + config["job_attempts"] = batchParameters.RetryStrategy.Attempts } result := []map[string]interface{}{config} return result } -func flattenTargetKinesisParameters(kinesisParameters *eventbridge.KinesisParameters) []map[string]interface{} { +func flattenTargetKinesisParameters(kinesisParameters *types.KinesisParameters) []map[string]interface{} { config := make(map[string]interface{}) - config["partition_key_path"] = aws.StringValue(kinesisParameters.PartitionKeyPath) + config["partition_key_path"] = aws.ToString(kinesisParameters.PartitionKeyPath) result := []map[string]interface{}{config} return result } -func flattenTargetSageMakerPipelineParameters(sageMakerParameters *eventbridge.SageMakerPipelineParameters) []map[string]interface{} { +func flattenTargetSageMakerPipelineParameters(sageMakerParameters *types.SageMakerPipelineParameters) []map[string]interface{} { config := make(map[string]interface{}) config["pipeline_parameter_list"] = flattenTargetSageMakerPipelineParameter(sageMakerParameters.PipelineParameterList) result := []map[string]interface{}{config} return result } -func flattenTargetSageMakerPipelineParameter(pcs []*eventbridge.SageMakerPipelineParameter) []map[string]interface{} { +func flattenTargetSageMakerPipelineParameter(pcs []types.SageMakerPipelineParameter) []map[string]interface{} { if len(pcs) == 0 { return nil } results := make([]map[string]interface{}, 0) for _, pc := range pcs { c := make(map[string]interface{}) - c["name"] = aws.StringValue(pc.Name) - c["value"] = aws.StringValue(pc.Value) + c["name"] = aws.ToString(pc.Name) + c["value"] = aws.ToString(pc.Value) results = append(results, c) } return results } -func flattenTargetSQSParameters(sqsParameters *eventbridge.SqsParameters) []map[string]interface{} { +func flattenTargetSQSParameters(sqsParameters *types.SqsParameters) []map[string]interface{} { config := make(map[string]interface{}) - config["message_group_id"] = aws.StringValue(sqsParameters.MessageGroupId) + config["message_group_id"] = aws.ToString(sqsParameters.MessageGroupId) result := []map[string]interface{}{config} return result } -func flattenTargetHTTPParameters(apiObject *eventbridge.HttpParameters) map[string]interface{} { +func flattenTargetHTTPParameters(apiObject *types.HttpParameters) map[string]interface{} { if apiObject == nil { return nil } @@ -1193,58 +1292,54 @@ func flattenTargetHTTPParameters(apiObject *eventbridge.HttpParameters) map[stri tfMap := map[string]interface{}{} if v := apiObject.HeaderParameters; v != nil { - tfMap["header_parameters"] = aws.StringValueMap(v) + tfMap["header_parameters"] = v } if v := apiObject.PathParameterValues; v != nil { - tfMap["path_parameter_values"] = aws.StringValueSlice(v) + tfMap["path_parameter_values"] = v } if v := apiObject.QueryStringParameters; v != nil { - tfMap["query_string_parameters"] = aws.StringValueMap(v) + tfMap["query_string_parameters"] = v } return tfMap } -func flattenInputTransformer(inputTransformer *eventbridge.InputTransformer) []map[string]interface{} { +func flattenInputTransformer(inputTransformer *types.InputTransformer) []map[string]interface{} { config := make(map[string]interface{}) - inputPathsMap := make(map[string]string) - for k, v := range inputTransformer.InputPathsMap { - inputPathsMap[k] = aws.StringValue(v) - } - config["input_template"] = aws.StringValue(inputTransformer.InputTemplate) - config["input_paths"] = inputPathsMap + config["input_template"] = aws.ToString(inputTransformer.InputTemplate) + config["input_paths"] = inputTransformer.InputPathsMap result := []map[string]interface{}{config} return result } -func flattenTargetRetryPolicy(rp *eventbridge.RetryPolicy) []map[string]interface{} { +func flattenTargetRetryPolicy(rp *types.RetryPolicy) []map[string]interface{} { config := make(map[string]interface{}) - config["maximum_event_age_in_seconds"] = aws.Int64Value(rp.MaximumEventAgeInSeconds) - config["maximum_retry_attempts"] = aws.Int64Value(rp.MaximumRetryAttempts) + config["maximum_event_age_in_seconds"] = aws.ToInt32(rp.MaximumEventAgeInSeconds) + config["maximum_retry_attempts"] = aws.ToInt32(rp.MaximumRetryAttempts) result := []map[string]interface{}{config} return result } -func flattenTargetDeadLetterConfig(dlc *eventbridge.DeadLetterConfig) []map[string]interface{} { +func flattenTargetDeadLetterConfig(dlc *types.DeadLetterConfig) []map[string]interface{} { config := make(map[string]interface{}) - config["arn"] = aws.StringValue(dlc.Arn) + config["arn"] = aws.ToString(dlc.Arn) result := []map[string]interface{}{config} return result } -func expandTargetPlacementConstraints(tfList []interface{}) []*eventbridge.PlacementConstraint { +func expandTargetPlacementConstraints(tfList []interface{}) []types.PlacementConstraint { if len(tfList) == 0 { return nil } - var result []*eventbridge.PlacementConstraint + var result []types.PlacementConstraint for _, tfMapRaw := range tfList { if tfMapRaw == nil { @@ -1253,14 +1348,14 @@ func expandTargetPlacementConstraints(tfList []interface{}) []*eventbridge.Place tfMap := tfMapRaw.(map[string]interface{}) - apiObject := &eventbridge.PlacementConstraint{} + apiObject := types.PlacementConstraint{} if v, ok := tfMap["expression"].(string); ok && v != "" { apiObject.Expression = aws.String(v) } if v, ok := tfMap["type"].(string); ok && v != "" { - apiObject.Type = aws.String(v) + apiObject.Type = types.PlacementConstraintType(v) } result = append(result, apiObject) @@ -1269,12 +1364,12 @@ func expandTargetPlacementConstraints(tfList []interface{}) []*eventbridge.Place return result } -func expandTargetPlacementStrategies(tfList []interface{}) []*eventbridge.PlacementStrategy { +func expandTargetPlacementStrategies(tfList []interface{}) []types.PlacementStrategy { if len(tfList) == 0 { return nil } - var result []*eventbridge.PlacementStrategy + var result []types.PlacementStrategy for _, tfMapRaw := range tfList { if tfMapRaw == nil { @@ -1283,14 +1378,14 @@ func expandTargetPlacementStrategies(tfList []interface{}) []*eventbridge.Placem tfMap := tfMapRaw.(map[string]interface{}) - apiObject := &eventbridge.PlacementStrategy{} + apiObject := types.PlacementStrategy{} if v, ok := tfMap["field"].(string); ok && v != "" { apiObject.Field = aws.String(v) } if v, ok := tfMap["type"].(string); ok && v != "" { - apiObject.Type = aws.String(v) + apiObject.Type = types.PlacementStrategyType(v) } result = append(result, apiObject) @@ -1299,12 +1394,12 @@ func expandTargetPlacementStrategies(tfList []interface{}) []*eventbridge.Placem return result } -func expandTargetCapacityProviderStrategy(tfList []interface{}) []*eventbridge.CapacityProviderStrategyItem { +func expandTargetCapacityProviderStrategy(tfList []interface{}) []types.CapacityProviderStrategyItem { if len(tfList) == 0 { return nil } - var result []*eventbridge.CapacityProviderStrategyItem + var result []types.CapacityProviderStrategyItem for _, tfMapRaw := range tfList { if tfMapRaw == nil { @@ -1313,14 +1408,14 @@ func expandTargetCapacityProviderStrategy(tfList []interface{}) []*eventbridge.C cp := tfMapRaw.(map[string]interface{}) - apiObject := &eventbridge.CapacityProviderStrategyItem{} + apiObject := types.CapacityProviderStrategyItem{} if val, ok := cp["base"]; ok { - apiObject.Base = aws.Int64(int64(val.(int))) + apiObject.Base = int32(val.(int)) } if val, ok := cp["weight"]; ok { - apiObject.Weight = aws.Int64(int64(val.(int))) + apiObject.Weight = int32(val.(int)) } if val, ok := cp["capacity_provider"]; ok { @@ -1333,16 +1428,16 @@ func expandTargetCapacityProviderStrategy(tfList []interface{}) []*eventbridge.C return result } -func flattenTargetPlacementConstraints(pcs []*eventbridge.PlacementConstraint) []map[string]interface{} { +func flattenTargetPlacementConstraints(pcs []types.PlacementConstraint) []map[string]interface{} { if len(pcs) == 0 { return nil } results := make([]map[string]interface{}, 0) for _, pc := range pcs { c := make(map[string]interface{}) - c["type"] = aws.StringValue(pc.Type) + c["type"] = pc.Type if pc.Expression != nil { - c["expression"] = aws.StringValue(pc.Expression) + c["expression"] = aws.ToString(pc.Expression) } results = append(results, c) @@ -1350,16 +1445,16 @@ func flattenTargetPlacementConstraints(pcs []*eventbridge.PlacementConstraint) [ return results } -func flattenTargetPlacementStrategies(pcs []*eventbridge.PlacementStrategy) []map[string]interface{} { +func flattenTargetPlacementStrategies(pcs []types.PlacementStrategy) []map[string]interface{} { if len(pcs) == 0 { return nil } results := make([]map[string]interface{}, 0) for _, pc := range pcs { c := make(map[string]interface{}) - c["type"] = aws.StringValue(pc.Type) + c["type"] = pc.Type if pc.Field != nil { - c["field"] = aws.StringValue(pc.Field) + c["field"] = aws.ToString(pc.Field) } results = append(results, c) @@ -1367,36 +1462,17 @@ func flattenTargetPlacementStrategies(pcs []*eventbridge.PlacementStrategy) []ma return results } -func flattenTargetCapacityProviderStrategy(cps []*eventbridge.CapacityProviderStrategyItem) []map[string]interface{} { +func flattenTargetCapacityProviderStrategy(cps []types.CapacityProviderStrategyItem) []map[string]interface{} { if cps == nil { return nil } results := make([]map[string]interface{}, 0) for _, cp := range cps { s := make(map[string]interface{}) - s["capacity_provider"] = aws.StringValue(cp.CapacityProvider) - if cp.Weight != nil { - s["weight"] = aws.Int64Value(cp.Weight) - } - if cp.Base != nil { - s["base"] = aws.Int64Value(cp.Base) - } + s["capacity_provider"] = aws.ToString(cp.CapacityProvider) + s["weight"] = cp.Weight + s["base"] = cp.Base results = append(results, s) } return results } - -func resourceTargetImport(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - busName, ruleName, targetID, err := TargetParseImportID(d.Id()) - if err != nil { - return []*schema.ResourceData{}, err - } - - id := TargetCreateResourceID(busName, ruleName, targetID) - d.SetId(id) - d.Set("target_id", targetID) - d.Set("rule", ruleName) - d.Set("event_bus_name", busName) - - return []*schema.ResourceData{d}, nil -} diff --git a/internal/service/events/target_test.go b/internal/service/events/target_test.go index 0e732f428aa..7807ab33404 100644 --- a/internal/service/events/target_test.go +++ b/internal/service/events/target_test.go @@ -12,8 +12,7 @@ import ( "testing" "github.com/YakDriver/regexache" - "github.com/aws/aws-sdk-go/aws/endpoints" - "github.com/aws/aws-sdk-go/service/eventbridge" + "github.com/aws/aws-sdk-go-v2/service/eventbridge/types" sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" @@ -24,9 +23,176 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) +func TestTargetParseImportID(t *testing.T) { + t.Parallel() + + testCases := []struct { + TestName string + InputID string + ExpectedError bool + ExpectedPart0 string + ExpectedPart1 string + ExpectedPart2 string + }{ + { + TestName: "empty ID", + InputID: "", + ExpectedError: true, + }, + { + TestName: "single part", + InputID: "TestRule", + ExpectedError: true, + }, + { + TestName: "two parts", + InputID: "TestTarget/TestRule", + ExpectedPart0: tfevents.DefaultEventBusName, + ExpectedPart1: "TestTarget", + ExpectedPart2: "TestRule", + }, + { + TestName: "three parts", + InputID: "TestEventBus/TestRule/TestTarget", + ExpectedPart0: "TestEventBus", + ExpectedPart1: "TestRule", + ExpectedPart2: "TestTarget", + }, + { + TestName: "three parts with default event bus", + InputID: tfevents.DefaultEventBusName + "/TestRule/TestTarget", + ExpectedPart0: tfevents.DefaultEventBusName, + ExpectedPart1: "TestRule", + ExpectedPart2: "TestTarget", + }, + { + TestName: "empty two parts", + InputID: "/", + ExpectedError: true, + }, + { + TestName: "empty three parts", + InputID: "//", + ExpectedError: true, + }, + { + TestName: "empty first part of two", + InputID: "/TestTarget", + ExpectedError: true, + }, + { + TestName: "empty second part of two", + InputID: "TestRule/", + ExpectedError: true, + }, + { + TestName: "empty first part of three", + InputID: "/TestRule/TestTarget", + ExpectedError: true, + }, + { + TestName: "empty second part of three", + InputID: "TestEventBus//TestTarget", + ExpectedError: true, + }, + { + TestName: "empty third part of three", + InputID: "TestEventBus/TestRule/", + ExpectedError: true, + }, + { + TestName: "empty first two of three parts", + InputID: "//TestTarget", + ExpectedError: true, + }, + { + TestName: "empty first and third of three parts", + InputID: "/TestRule/", + ExpectedError: true, + }, + { + TestName: "empty final two of three parts", + InputID: "TestEventBus//", + ExpectedError: true, + }, + { + TestName: "partner event bus", + InputID: "aws.partner/example.com/Test/TestRule/TestTarget", + ExpectedPart0: "aws.partner/example.com/Test", + ExpectedPart1: "TestRule", + ExpectedPart2: "TestTarget", + }, + { + TestName: "ARN event bus", + InputID: "arn:aws:events:us-east-2:123456789012:event-bus/default/TestRule/TestTarget", //lintignore:AWSAT003,AWSAT005 + ExpectedPart0: "arn:aws:events:us-east-2:123456789012:event-bus/default", //lintignore:AWSAT003,AWSAT005 + ExpectedPart1: "TestRule", + ExpectedPart2: "TestTarget", + }, + { + TestName: "ARN based partner event bus", + // lintignore:AWSAT003,AWSAT005 + InputID: "arn:aws:events:us-east-2:123456789012:event-bus/aws.partner/genesys.com/cloud/a12bc345-d678-90e1-2f34-gh5678i9012ej/_genesys/TestRule/TestTarget", + // lintignore:AWSAT003,AWSAT005 + ExpectedPart0: "arn:aws:events:us-east-2:123456789012:event-bus/aws.partner/genesys.com/cloud/a12bc345-d678-90e1-2f34-gh5678i9012ej/_genesys", + ExpectedPart1: "TestRule", + ExpectedPart2: "TestTarget", + }, + { + TestName: "empty partner event rule and target", + InputID: "aws.partner/example.com/Test//", + ExpectedError: true, + }, + { + TestName: "four parts", + InputID: "aws.partner/example.com/Test/TestRule", + ExpectedError: true, + }, + { + TestName: "five parts", + InputID: "abc.partner/example.com/Test/TestRule/TestTarget", + ExpectedError: true, + }, + { + TestName: "six parts", + InputID: "test/aws.partner/example.com/Test/TestRule/TestTarget", + ExpectedError: true, + }, + } + + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.TestName, func(t *testing.T) { + t.Parallel() + + gotPart0, gotPart1, gotPart2, err := tfevents.TargetParseImportID(testCase.InputID) + + if err == nil && testCase.ExpectedError { + t.Fatalf("expected error, got no error") + } + + if err != nil && !testCase.ExpectedError { + t.Fatalf("got unexpected error: %s", err) + } + + if gotPart0 != testCase.ExpectedPart0 { + t.Errorf("got part 0 %s, expected %s", gotPart0, testCase.ExpectedPart0) + } + + if gotPart1 != testCase.ExpectedPart1 { + t.Errorf("got part 1 %s, expected %s", gotPart1, testCase.ExpectedPart1) + } + + if gotPart2 != testCase.ExpectedPart2 { + t.Errorf("got part 2 %s, expected %s", gotPart2, testCase.ExpectedPart2) + } + }) + } +} + func TestAccEventsTarget_basic(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" snsTopicResourceName := "aws_sns_topic.test" @@ -83,7 +249,7 @@ func TestAccEventsTarget_basic(t *testing.T) { func TestAccEventsTarget_disappears(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" @@ -107,7 +273,7 @@ func TestAccEventsTarget_disappears(t *testing.T) { func TestAccEventsTarget_eventBusName(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" @@ -138,13 +304,7 @@ func TestAccEventsTarget_eventBusName(t *testing.T) { func TestAccEventsTarget_eventBusARN(t *testing.T) { ctx := acctest.Context(t) - - // "ValidationException: Adding an EventBus as a target within an account is not allowed." - if got, want := acctest.Partition(), endpoints.AwsUsGovPartitionID; got == want { - t.Skipf("EventBridge Target EventBus ARNs are not supported in %s partition", got) - } - - var v eventbridge.Target + var v types.Target ruleName := sdkacctest.RandomWithPrefix("tf-acc-test-rule") targetID := sdkacctest.RandomWithPrefix("tf-acc-test-target") originEventBusName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -152,7 +312,7 @@ func TestAccEventsTarget_eventBusARN(t *testing.T) { resourceName := "aws_cloudwatch_event_target.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(ctx, t) }, + PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionNot(t, names.USGovCloudPartitionID) }, ErrorCheck: acctest.ErrorCheck(t, names.EventsServiceID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckTargetDestroy(ctx), @@ -179,7 +339,7 @@ func TestAccEventsTarget_eventBusARN(t *testing.T) { func TestAccEventsTarget_generatedTargetID(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target ruleName := sdkacctest.RandomWithPrefix("tf-acc-cw-event-rule-missing-target-id") snsTopicName := sdkacctest.RandomWithPrefix("tf-acc") resourceName := "aws_cloudwatch_event_target.test" @@ -212,7 +372,7 @@ func TestAccEventsTarget_generatedTargetID(t *testing.T) { func TestAccEventsTarget_RetryPolicy_deadLetter(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" kinesisStreamResourceName := "aws_kinesis_stream.test" @@ -250,7 +410,7 @@ func TestAccEventsTarget_RetryPolicy_deadLetter(t *testing.T) { func TestAccEventsTarget_full(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target ruleName := sdkacctest.RandomWithPrefix("tf-acc-cw-event-rule-full") ssmDocumentName := sdkacctest.RandomWithPrefix("tf_ssm_Document") targetID := sdkacctest.RandomWithPrefix("tf-acc-cw-target-full") @@ -286,7 +446,7 @@ func TestAccEventsTarget_full(t *testing.T) { func TestAccEventsTarget_ssmDocument(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix("tf_ssm_Document") resourceName := "aws_cloudwatch_event_target.test" @@ -318,7 +478,7 @@ func TestAccEventsTarget_ssmDocument(t *testing.T) { func TestAccEventsTarget_http(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix("tf_http_target") resourceName := "aws_cloudwatch_event_target.test" @@ -354,7 +514,7 @@ func TestAccEventsTarget_http(t *testing.T) { // https://github.com/hashicorp/terraform-provider-aws/issues/23805 func TestAccEventsTarget_http_params(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix("tf_http_target") resourceName := "aws_cloudwatch_event_target.test" @@ -405,7 +565,7 @@ func TestAccEventsTarget_http_params(t *testing.T) { func TestAccEventsTarget_ecs(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" iamRoleResourceName := "aws_iam_role.test" @@ -443,7 +603,7 @@ func TestAccEventsTarget_ecs(t *testing.T) { func TestAccEventsTarget_redshift(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" @@ -478,7 +638,7 @@ func TestAccEventsTarget_redshift(t *testing.T) { // Reference: https://github.com/hashicorp/terraform-provider-aws/issues/16078 func TestAccEventsTarget_ecsWithoutLaunchType(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" iamRoleResourceName := "aws_iam_role.test" @@ -539,7 +699,7 @@ func TestAccEventsTarget_ecsWithBlankLaunchType(t *testing.T) { t.Skip("skipping long-running test in short mode") } - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" iamRoleResourceName := "aws_iam_role.test" @@ -596,7 +756,7 @@ func TestAccEventsTarget_ecsWithBlankLaunchType(t *testing.T) { func TestAccEventsTarget_ecsWithBlankTaskCount(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" @@ -626,7 +786,7 @@ func TestAccEventsTarget_ecsWithBlankTaskCount(t *testing.T) { func TestAccEventsTarget_ecsFull(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" @@ -664,7 +824,7 @@ func TestAccEventsTarget_ecsFull(t *testing.T) { func TestAccEventsTarget_ecsCapacityProvider(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" @@ -698,7 +858,7 @@ func TestAccEventsTarget_ecsCapacityProvider(t *testing.T) { func TestAccEventsTarget_ecsPlacementStrategy(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" @@ -733,7 +893,7 @@ func TestAccEventsTarget_ecsPlacementStrategy(t *testing.T) { func TestAccEventsTarget_batch(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix("tf_batch_target") resourceName := "aws_cloudwatch_event_target.test" batchJobDefinitionResourceName := "aws_batch_job_definition.test" @@ -765,7 +925,7 @@ func TestAccEventsTarget_batch(t *testing.T) { func TestAccEventsTarget_kinesis(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix("tf_kinesis_target") resourceName := "aws_cloudwatch_event_target.test" @@ -794,7 +954,7 @@ func TestAccEventsTarget_kinesis(t *testing.T) { func TestAccEventsTarget_sqs(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" @@ -824,7 +984,7 @@ func TestAccEventsTarget_sqs(t *testing.T) { func TestAccEventsTarget_sageMakerPipeline(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" @@ -860,7 +1020,7 @@ func TestAccEventsTarget_sageMakerPipeline(t *testing.T) { func TestAccEventsTarget_Input_transformer(t *testing.T) { ctx := acctest.Context(t) resourceName := "aws_cloudwatch_event_target.test" - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix("tf_input_transformer") tooManyInputPaths := make([]string, 101) @@ -917,7 +1077,7 @@ func TestAccEventsTarget_Input_transformer(t *testing.T) { func TestAccEventsTarget_inputTransformerJSONString(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" @@ -949,7 +1109,7 @@ func TestAccEventsTarget_partnerEventBus(t *testing.T) { t.Skipf("Environment variable %s is not set", key) } - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" snsTopicResourceName := "aws_sns_topic.test" @@ -982,7 +1142,7 @@ func TestAccEventsTarget_partnerEventBus(t *testing.T) { func TestAccEventsTarget_ecsNoPropagateTags(t *testing.T) { ctx := acctest.Context(t) - var v eventbridge.Target + var v types.Target rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_target.test" @@ -1012,14 +1172,14 @@ func TestAccEventsTarget_ecsNoPropagateTags(t *testing.T) { }) } -func testAccCheckTargetExists(ctx context.Context, n string, v *eventbridge.Target) resource.TestCheckFunc { +func testAccCheckTargetExists(ctx context.Context, n string, v *types.Target) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { return fmt.Errorf("Not found: %s", n) } - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) output, err := tfevents.FindTargetByThreePartKey(ctx, conn, rs.Primary.Attributes["event_bus_name"], rs.Primary.Attributes["rule"], rs.Primary.Attributes["target_id"]) @@ -1035,7 +1195,7 @@ func testAccCheckTargetExists(ctx context.Context, n string, v *eventbridge.Targ func testAccCheckTargetDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).EventsConn(ctx) + conn := acctest.Provider.Meta().(*conns.AWSClient).EventsClient(ctx) for _, rs := range s.RootModule().Resources { if rs.Type != "aws_cloudwatch_event_target" { From fa8fb7fbcdfa4a4c5b392157eed6953c2e30d775 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 08:01:10 -0400 Subject: [PATCH 20/35] 'verify.MapLenBetween' -> 'verify.MapSizeBetween'. --- internal/service/s3/object.go | 2 +- internal/verify/validate.go | 4 ++-- internal/verify/validate_test.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/service/s3/object.go b/internal/service/s3/object.go index 1322fdcc029..03088937417 100644 --- a/internal/service/s3/object.go +++ b/internal/service/s3/object.go @@ -206,7 +206,7 @@ func resourceObject() *schema.Resource { Type: schema.TypeMap, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, - ValidateDiagFunc: verify.MapLenBetween(0, 0), + ValidateDiagFunc: verify.MapSizeBetween(0, 0), }, }, }, diff --git a/internal/verify/validate.go b/internal/verify/validate.go index 427254b8077..3d5ee7dcf40 100644 --- a/internal/verify/validate.go +++ b/internal/verify/validate.go @@ -530,7 +530,7 @@ func MapKeysAre(keyValidators ...schema.SchemaValidateDiagFunc) schema.SchemaVal } } -func MapLenBetween(min, max int) schema.SchemaValidateDiagFunc { +func MapSizeBetween(min, max int) schema.SchemaValidateDiagFunc { return func(v interface{}, path cty.Path) diag.Diagnostics { var diags diag.Diagnostics m := v.(map[string]interface{}) @@ -538,7 +538,7 @@ func MapLenBetween(min, max int) schema.SchemaValidateDiagFunc { if l := len(m); l < min || l > max { diags = append(diags, diag.Diagnostic{ Severity: diag.Error, - Summary: "Bad map length", + Summary: "Bad map size", Detail: fmt.Sprintf("Map must contain at least %d elements and at most %d elements: length=%d", min, max, l), AttributePath: path, }) diff --git a/internal/verify/validate_test.go b/internal/verify/validate_test.go index 3052363e598..b67e3e90945 100644 --- a/internal/verify/validate_test.go +++ b/internal/verify/validate_test.go @@ -812,7 +812,7 @@ func TestMapLenBetween(t *testing.T) { }, }, } - f := MapLenBetween(2, 4) + f := MapSizeBetween(2, 4) for _, testCase := range testCases { testCase := testCase t.Run(testCase.name, func(t *testing.T) { From 8690755d6ee8bff582d50091b816648739a414a5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 08:07:35 -0400 Subject: [PATCH 21/35] Add 'verify.MapSizeAtMost'. --- internal/verify/validate.go | 18 +++++++++++++ internal/verify/validate_test.go | 43 +++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/internal/verify/validate.go b/internal/verify/validate.go index 3d5ee7dcf40..f3fd8909e49 100644 --- a/internal/verify/validate.go +++ b/internal/verify/validate.go @@ -530,6 +530,24 @@ func MapKeysAre(keyValidators ...schema.SchemaValidateDiagFunc) schema.SchemaVal } } +func MapSizeAtMost(max int) schema.SchemaValidateDiagFunc { + return func(v interface{}, path cty.Path) diag.Diagnostics { + var diags diag.Diagnostics + m := v.(map[string]interface{}) + + if l := len(m); l > max { + diags = append(diags, diag.Diagnostic{ + Severity: diag.Error, + Summary: "Bad map size", + Detail: fmt.Sprintf("Map must contain at most %d elements: length=%d", max, l), + AttributePath: path, + }) + } + + return diags + } +} + func MapSizeBetween(min, max int) schema.SchemaValidateDiagFunc { return func(v interface{}, path cty.Path) diag.Diagnostics { var diags diag.Diagnostics diff --git a/internal/verify/validate_test.go b/internal/verify/validate_test.go index b67e3e90945..5d5005a7e8e 100644 --- a/internal/verify/validate_test.go +++ b/internal/verify/validate_test.go @@ -778,7 +778,48 @@ func TestValidServicePrincipal(t *testing.T) { } } -func TestMapLenBetween(t *testing.T) { +func TestMapSizeAtMost(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + value interface{} + wantErr bool + }{ + { + name: "too long", + value: map[string]interface{}{ + "K1": "V1", + "K2": "V2", + "K3": "V3", + "K4": "V4", + "K5": "V5", + }, + wantErr: true, + }, + { + name: "ok", + value: map[string]interface{}{ + "K1": "V1", + "K2": "V2", + }, + }, + } + f := MapSizeAtMost(4) + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + + diags := f(testCase.value, cty.Path{}) + if got, want := diags.HasError(), testCase.wantErr; got != want { + t.Errorf("got = %v, want = %v", got, want) + } + }) + } +} + +func TestMapSizeBetween(t *testing.T) { t.Parallel() testCases := []struct { From f55f4aceec4340109ceb14d4d98d3f75904fd141 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 08:26:23 -0400 Subject: [PATCH 22/35] Add 'verify.MapKeyNoMatch'. --- internal/verify/validate.go | 31 ++++++++++++++++++++++++ internal/verify/validate_test.go | 41 ++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/internal/verify/validate.go b/internal/verify/validate.go index f3fd8909e49..13ba536e454 100644 --- a/internal/verify/validate.go +++ b/internal/verify/validate.go @@ -7,6 +7,8 @@ import ( "encoding/json" "fmt" "net" + "regexp" + "slices" "strconv" "strings" "time" @@ -20,6 +22,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/errs" + tfmaps "github.com/hashicorp/terraform-provider-aws/internal/maps" itypes "github.com/hashicorp/terraform-provider-aws/internal/types" "github.com/hashicorp/terraform-provider-aws/internal/types/timestamp" ) @@ -516,6 +519,34 @@ func IsServicePrincipal(value string) (valid bool) { return servicePrincipalRegexp.MatchString(value) } +func MapKeyNoMatch(r *regexp.Regexp, message string) schema.SchemaValidateDiagFunc { + return func(v interface{}, path cty.Path) diag.Diagnostics { + var diags diag.Diagnostics + m := v.(map[string]interface{}) + keys := tfmaps.Keys(m) + + slices.Sort(keys) + for _, k := range keys { + if ok := r.MatchString(k); ok { + var detail string + if message != "" { + detail = fmt.Sprintf("Map key '%s' %s", k, message) + } else { + detail = fmt.Sprintf("Map key '%s' must not match regular expression '%s'", k, r) + } + diags = append(diags, diag.Diagnostic{ + Severity: diag.Error, + Summary: "Bad map key", + Detail: detail, + AttributePath: path, + }) + } + } + + return diags + } +} + func MapKeysAre(keyValidators ...schema.SchemaValidateDiagFunc) schema.SchemaValidateDiagFunc { return func(v interface{}, path cty.Path) diag.Diagnostics { var diags diag.Diagnostics diff --git a/internal/verify/validate_test.go b/internal/verify/validate_test.go index 5d5005a7e8e..449beb7339f 100644 --- a/internal/verify/validate_test.go +++ b/internal/verify/validate_test.go @@ -778,6 +778,47 @@ func TestValidServicePrincipal(t *testing.T) { } } +func TestMapKeyNoMatch(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + value interface{} + wantErr bool + }{ + { + name: "two invalid keys", + value: map[string]interface{}{ + "Ka": "V1", + "K2": "V2", + "Kb": "V3", + "Kc": "V4", + "K5": "V5", + }, + wantErr: true, + }, + { + name: "ok", + value: map[string]interface{}{ + "Ka": "V1", + "Kb": "V2", + }, + }, + } + f := MapKeyNoMatch(regexache.MustCompile(`^.*\d$`), "must not end with a digit") + for _, testCase := range testCases { + testCase := testCase + t.Run(testCase.name, func(t *testing.T) { + t.Parallel() + + diags := f(testCase.value, cty.Path{}) + if got, want := diags.HasError(), testCase.wantErr; got != want { + t.Errorf("got = %v, want = %v", got, want) + } + }) + } +} + func TestMapSizeAtMost(t *testing.T) { t.Parallel() From 95717aa108242937da176e2f26821064a47a32eb Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 08:27:05 -0400 Subject: [PATCH 23/35] r/aws_cloudwatch_event_target: Use 'verify.MapKeyNoMatch'. --- internal/service/events/target.go | 6 ++--- internal/service/events/validate.go | 36 ----------------------------- 2 files changed, 3 insertions(+), 39 deletions(-) diff --git a/internal/service/events/target.go b/internal/service/events/target.go index 99d20979104..0c6403717df 100644 --- a/internal/service/events/target.go +++ b/internal/service/events/target.go @@ -318,9 +318,9 @@ func resourceTarget() *schema.Resource { Type: schema.TypeMap, Optional: true, Elem: &schema.Schema{Type: schema.TypeString}, - ValidateFunc: validation.All( - mapMaxItems(targetInputTransformerMaxInputPaths), - mapKeysDoNotMatch(regexache.MustCompile(`^AWS.*$`), "input_path must not start with \"AWS\""), + ValidateDiagFunc: validation.AllDiag( + verify.MapSizeAtMost(targetInputTransformerMaxInputPaths), + verify.MapKeyNoMatch(regexache.MustCompile(`^AWS.*$`), `must not start with "AWS"`), ), }, "input_template": { diff --git a/internal/service/events/validate.go b/internal/service/events/validate.go index f831bd43f80..cb2931ff58a 100644 --- a/internal/service/events/validate.go +++ b/internal/service/events/validate.go @@ -5,12 +5,10 @@ package events import ( "fmt" - "regexp" "github.com/YakDriver/regexache" "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/verify" ) @@ -51,40 +49,6 @@ func validateTargetID(v interface{}, k string) (ws []string, errors []error) { return } -func mapKeysDoNotMatch(r *regexp.Regexp, message string) schema.SchemaValidateFunc { - return func(i interface{}, k string) (warnings []string, errors []error) { - m, ok := i.(map[string]interface{}) - if !ok { - errors = append(errors, fmt.Errorf("expected type of %s to be map", k)) - return warnings, errors - } - - for key := range m { - if ok := r.MatchString(key); ok { - errors = append(errors, fmt.Errorf("%s: %s: %s", k, message, key)) - } - } - - return warnings, errors - } -} - -func mapMaxItems(max int) schema.SchemaValidateFunc { - return func(i interface{}, k string) (warnings []string, errors []error) { - m, ok := i.(map[string]interface{}) - if !ok { - errors = append(errors, fmt.Errorf("expected type of %s to be map", k)) - return warnings, errors - } - - if len(m) > max { - errors = append(errors, fmt.Errorf("expected number of items in %s to be less than or equal to %d, got %d", k, max, len(m))) - } - - return warnings, errors - } -} - var validArchiveName = validation.All( validation.StringLenBetween(1, 48), validation.StringMatch(regexache.MustCompile(`^`+validNameCharClass+`$`), ""), From 2225d08b8f296daf5b6578a81397485c24902981 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 08:30:02 -0400 Subject: [PATCH 24/35] events: Generate additional listers. --- internal/service/events/generate.go | 2 +- internal/service/events/list_pages_gen.go | 50 ++++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/internal/service/events/generate.go b/internal/service/events/generate.go index 3aa2029d5b4..a3e13b1704c 100644 --- a/internal/service/events/generate.go +++ b/internal/service/events/generate.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -//go:generate go run ../../generate/listpages/main.go -AWSSDKVersion=2 -ListOps=ListEventBuses,ListEventSources,ListRules,ListTargetsByRule +//go:generate go run ../../generate/listpages/main.go -AWSSDKVersion=2 -ListOps=ListApiDestinations,ListArchives,ListConnections,ListEventBuses,ListEventSources,ListRules,ListTargetsByRule //go:generate go run ../../generate/tags/main.go -AWSSDKVersion=2 -ListTags -ListTagsInIDElem=ResourceARN -ServiceTagsSlice -TagInIDElem=ResourceARN -UpdateTags -CreateTags //go:generate go run ../../generate/servicepackage/main.go // ONLY generate directives and package declaration! Do not add anything else to this file. diff --git a/internal/service/events/list_pages_gen.go b/internal/service/events/list_pages_gen.go index 377f7a69a50..c3a10698a16 100644 --- a/internal/service/events/list_pages_gen.go +++ b/internal/service/events/list_pages_gen.go @@ -1,4 +1,4 @@ -// Code generated by "internal/generate/listpages/main.go -AWSSDKVersion=2 -ListOps=ListEventBuses,ListEventSources,ListRules,ListTargetsByRule"; DO NOT EDIT. +// Code generated by "internal/generate/listpages/main.go -AWSSDKVersion=2 -ListOps=ListApiDestinations,ListArchives,ListConnections,ListEventBuses,ListEventSources,ListRules,ListTargetsByRule"; DO NOT EDIT. package events @@ -9,6 +9,54 @@ import ( "github.com/aws/aws-sdk-go-v2/service/eventbridge" ) +func listAPIDestinationsPages(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListApiDestinationsInput, fn func(*eventbridge.ListApiDestinationsOutput, bool) bool) error { + for { + output, err := conn.ListApiDestinations(ctx, input) + if err != nil { + return err + } + + lastPage := aws.ToString(output.NextToken) == "" + if !fn(output, lastPage) || lastPage { + break + } + + input.NextToken = output.NextToken + } + return nil +} +func listArchivesPages(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListArchivesInput, fn func(*eventbridge.ListArchivesOutput, bool) bool) error { + for { + output, err := conn.ListArchives(ctx, input) + if err != nil { + return err + } + + lastPage := aws.ToString(output.NextToken) == "" + if !fn(output, lastPage) || lastPage { + break + } + + input.NextToken = output.NextToken + } + return nil +} +func listConnectionsPages(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListConnectionsInput, fn func(*eventbridge.ListConnectionsOutput, bool) bool) error { + for { + output, err := conn.ListConnections(ctx, input) + if err != nil { + return err + } + + lastPage := aws.ToString(output.NextToken) == "" + if !fn(output, lastPage) || lastPage { + break + } + + input.NextToken = output.NextToken + } + return nil +} func listEventBusesPages(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListEventBusesInput, fn func(*eventbridge.ListEventBusesOutput, bool) bool) error { for { output, err := conn.ListEventBuses(ctx, input) From ac24c00f14977ea7323c4dcb88213f6de4bc8d49 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 08:47:58 -0400 Subject: [PATCH 25/35] events: Tidy up sweepers. --- internal/service/events/sweep.go | 347 ++++++++++++------------------ internal/service/events/target.go | 15 +- 2 files changed, 142 insertions(+), 220 deletions(-) diff --git a/internal/service/events/sweep.go b/internal/service/events/sweep.go index 7e0333d3f5a..9051c9a2aca 100644 --- a/internal/service/events/sweep.go +++ b/internal/service/events/sweep.go @@ -4,16 +4,14 @@ package events import ( - "encoding/json" "fmt" "log" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/eventbridge" - "github.com/hashicorp/go-multierror" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eventbridge" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-provider-aws/internal/sweep" - "github.com/hashicorp/terraform-provider-aws/internal/sweep/awsv1" + "github.com/hashicorp/terraform-provider-aws/internal/sweep/awsv2" ) func RegisterSweepers() { @@ -48,11 +46,6 @@ func RegisterSweepers() { F: sweepConnection, }) - resource.AddTestSweepers("aws_cloudwatch_event_permission", &resource.Sweeper{ - Name: "aws_cloudwatch_event_permission", - F: sweepPermissions, - }) - resource.AddTestSweepers("aws_cloudwatch_event_rule", &resource.Sweeper{ Name: "aws_cloudwatch_event_rule", F: sweepRules, @@ -73,48 +66,44 @@ func sweepAPIDestination(region string) error { if err != nil { return fmt.Errorf("Error getting client: %w", err) } - conn := client.EventsConn(ctx) - - var sweeperErrs *multierror.Error - + conn := client.EventsClient(ctx) input := &eventbridge.ListApiDestinationsInput{ - Limit: aws.Int64(100), + Limit: aws.Int32(100), } - var apiDestinations []*eventbridge.ApiDestination - for { - output, err := conn.ListApiDestinationsWithContext(ctx, input) + sweepResources := make([]sweep.Sweepable, 0) - if awsv1.SkipSweepError(err) { - log.Printf("[WARN] Skipping EventBridge API Destination sweep for %s: %s", region, err) - return nil + err = listAPIDestinationsPages(ctx, conn, input, func(page *eventbridge.ListApiDestinationsOutput, lastPage bool) bool { + if page == nil { + return !lastPage } - if err != nil { - return fmt.Errorf("Error retrieving EventBridge API Destinations: %w", err) + for _, v := range page.ApiDestinations { + r := resourceAPIDestination() + d := r.Data(nil) + d.SetId(aws.ToString(v.Name)) + + sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) } - apiDestinations = append(apiDestinations, output.ApiDestinations...) + return !lastPage + }) - if aws.StringValue(output.NextToken) == "" { - break - } - input.NextToken = output.NextToken + if awsv2.SkipSweepError(err) { + log.Printf("[WARN] Skipping EventBridge API Destination sweep for %s: %s", region, err) + return nil } - for _, apiDestination := range apiDestinations { - input := &eventbridge.DeleteApiDestinationInput{ - Name: apiDestination.Name, - } - _, err := conn.DeleteApiDestinationWithContext(ctx, input) - if err != nil { - sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("Error deleting EventBridge Api Destination (%s): %w", *apiDestination.Name, err)) - continue - } + if err != nil { + return fmt.Errorf("error listing EventBridge API Destinations (%s): %w", region, err) } - log.Printf("[INFO] Deleted %d EventBridge Api Destinations", len(apiDestinations)) + err = sweep.SweepOrchestrator(ctx, sweepResources) + + if err != nil { + return fmt.Errorf("error sweeping EventBridge API Destinations (%s): %w", region, err) + } - return sweeperErrs.ErrorOrNil() + return nil } func sweepArchives(region string) error { @@ -123,46 +112,39 @@ func sweepArchives(region string) error { if err != nil { return fmt.Errorf("Error getting client: %w", err) } - conn := client.EventsConn(ctx) - + conn := client.EventsClient(ctx) input := &eventbridge.ListArchivesInput{} + sweepResources := make([]sweep.Sweepable, 0) - for { - output, err := conn.ListArchivesWithContext(ctx, input) - - if awsv1.SkipSweepError(err) { - log.Printf("[WARN] Skipping EventBridge archive sweep for %s: %s", region, err) - return nil + err = listArchivesPages(ctx, conn, input, func(page *eventbridge.ListArchivesOutput, lastPage bool) bool { + if page == nil { + return !lastPage } - if err != nil { - return fmt.Errorf("Error retrieving EventBridge archive: %w", err) - } + for _, v := range page.Archives { + r := resourceArchive() + d := r.Data(nil) + d.SetId(aws.ToString(v.ArchiveName)) - if len(output.Archives) == 0 { - log.Print("[DEBUG] No EventBridge archives to sweep") - return nil + sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) } - for _, archive := range output.Archives { - name := aws.StringValue(archive.ArchiveName) - if name == "default" { - continue - } + return !lastPage + }) - log.Printf("[INFO] Deleting EventBridge archive (%s)", name) - _, err := conn.DeleteArchiveWithContext(ctx, &eventbridge.DeleteArchiveInput{ - ArchiveName: aws.String(name), - }) - if err != nil { - return fmt.Errorf("Error deleting EventBridge archive (%s): %w", name, err) - } - } + if awsv2.SkipSweepError(err) { + log.Printf("[WARN] Skipping EventBridge Archive sweep for %s: %s", region, err) + return nil + } - if output.NextToken == nil { - break - } - input.NextToken = output.NextToken + if err != nil { + return fmt.Errorf("error listing EventBridge Archives (%s): %w", region, err) + } + + err = sweep.SweepOrchestrator(ctx, sweepResources) + + if err != nil { + return fmt.Errorf("error sweeping EventBridge Archives (%s): %w", region, err) } return nil @@ -174,23 +156,24 @@ func sweepBuses(region string) error { if err != nil { return fmt.Errorf("Error getting client: %w", err) } - conn := client.EventsConn(ctx) - var sweeperErrs *multierror.Error + conn := client.EventsClient(ctx) + input := &eventbridge.ListEventBusesInput{} sweepResources := make([]sweep.Sweepable, 0) - input := &eventbridge.ListEventBusesInput{} err = listEventBusesPages(ctx, conn, input, func(page *eventbridge.ListEventBusesOutput, lastPage bool) bool { if page == nil { return !lastPage } for _, eventBus := range page.EventBuses { - name := aws.StringValue(eventBus.Name) + name := aws.ToString(eventBus.Name) + if name == DefaultEventBusName { + log.Printf("[INFO] Skipping EventBridge Event Bus %s", name) continue } - r := ResourceBus() + r := resourceBus() d := r.Data(nil) d.SetId(name) @@ -200,19 +183,22 @@ func sweepBuses(region string) error { return !lastPage }) - if awsv1.SkipSweepError(err) { - log.Printf("[WARN] Skipping EventBridge event bus sweep for %s: %s", region, err) - return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + if awsv2.SkipSweepError(err) { + log.Printf("[WARN] Skipping EventBridge Event Bus sweep for %s: %s", region, err) + return nil } + if err != nil { - sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing EventBridge event buses: %w", err)) + return fmt.Errorf("error listing EventBridge Event Buses (%s): %w", region, err) } - if err := sweep.SweepOrchestrator(ctx, sweepResources); err != nil { - sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error sweeping EventBridge Event Buses: %w", err)) + err = sweep.SweepOrchestrator(ctx, sweepResources) + + if err != nil { + return fmt.Errorf("error sweeping EventBridge Event Buses (%s): %w", region, err) } - return sweeperErrs.ErrorOrNil() + return nil } func sweepConnection(region string) error { @@ -221,88 +207,41 @@ func sweepConnection(region string) error { if err != nil { return fmt.Errorf("Error getting client: %w", err) } - conn := client.EventsConn(ctx) - - var sweeperErrs *multierror.Error - + conn := client.EventsClient(ctx) input := &eventbridge.ListConnectionsInput{ - Limit: aws.Int64(100), - } - var connections []*eventbridge.Connection - for { - output, err := conn.ListConnectionsWithContext(ctx, input) - - if awsv1.SkipSweepError(err) { - log.Printf("[WARN] Skipping EventBridge Connection sweep for %s: %s", region, err) - return nil - } - - if err != nil { - return fmt.Errorf("Error retrieving EventBridge Connections: %w", err) - } - - if aws.StringValue(output.NextToken) == "" { - break - } - input.NextToken = output.NextToken + Limit: aws.Int32(100), } + sweepResources := make([]sweep.Sweepable, 0) - for _, connection := range connections { - input := &eventbridge.DeleteConnectionInput{ - Name: connection.Name, - } - _, err := conn.DeleteConnectionWithContext(ctx, input) - if err != nil { - sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("Error deleting EventBridge Connection (%s): %w", *connection.Name, err)) - continue + err = listConnectionsPages(ctx, conn, input, func(page *eventbridge.ListConnectionsOutput, lastPage bool) bool { + if page == nil { + return !lastPage } - } - - log.Printf("[INFO] Deleted %d EventBridge Connections", len(connections)) - - return sweeperErrs.ErrorOrNil() -} -func sweepPermissions(region string) error { - ctx := sweep.Context(region) - client, err := sweep.SharedRegionalSweepClient(ctx, region) - if err != nil { - return fmt.Errorf("Error getting client: %w", err) - } - conn := client.EventsConn(ctx) + for _, v := range page.Connections { + r := resourceConnection() + d := r.Data(nil) + d.SetId(aws.ToString(v.Name)) - output, err := conn.DescribeEventBusWithContext(ctx, &eventbridge.DescribeEventBusInput{}) - if err != nil { - if awsv1.SkipSweepError(err) { - log.Printf("[WARN] Skipping EventBridge Permission sweep for %s: %s", region, err) - return nil + sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) } - return fmt.Errorf("Error retrieving EventBridge Permissions: %w", err) - } - policy := aws.StringValue(output.Policy) + return !lastPage + }) - if policy == "" { - log.Print("[DEBUG] No EventBridge Permissions to sweep") + if awsv2.SkipSweepError(err) { + log.Printf("[WARN] Skipping EventBridge Connection sweep for %s: %s", region, err) return nil } - var policyDoc PermissionPolicyDoc - err = json.Unmarshal([]byte(policy), &policyDoc) if err != nil { - return fmt.Errorf("Parsing EventBridge Permissions policy %q failed: %w", policy, err) + return fmt.Errorf("error listing EventBridge Connections (%s): %w", region, err) } - for _, statement := range policyDoc.Statements { - sid := statement.Sid + err = sweep.SweepOrchestrator(ctx, sweepResources) - log.Printf("[INFO] Deleting EventBridge Permission %s", sid) - _, err := conn.RemovePermissionWithContext(ctx, &eventbridge.RemovePermissionInput{ - StatementId: aws.String(sid), - }) - if err != nil { - return fmt.Errorf("Error deleting EventBridge Permission %s: %w", sid, err) - } + if err != nil { + return fmt.Errorf("error sweeping EventBridge Connections (%s): %w", region, err) } return nil @@ -314,18 +253,17 @@ func sweepRules(region string) error { if err != nil { return fmt.Errorf("error getting client: %w", err) } - conn := client.EventsConn(ctx) + conn := client.EventsClient(ctx) input := &eventbridge.ListEventBusesInput{} - var sweeperErrs *multierror.Error + sweepResources := make([]sweep.Sweepable, 0) err = listEventBusesPages(ctx, conn, input, func(page *eventbridge.ListEventBusesOutput, lastPage bool) bool { if page == nil { return !lastPage } - for _, eventBus := range page.EventBuses { - eventBusName := aws.StringValue(eventBus.Name) - + for _, v := range page.EventBuses { + eventBusName := aws.ToString(v.Name) input := &eventbridge.ListRulesInput{ EventBusName: aws.String(eventBusName), } @@ -335,47 +273,43 @@ func sweepRules(region string) error { return !lastPage } - for _, rule := range page.Rules { - ruleName := aws.StringValue(rule.Name) + for _, v := range page.Rules { + ruleName := aws.ToString(v.Name) - log.Printf("[DEBUG] Deleting EventBridge Rule: %s/%s", eventBusName, ruleName) - _, err := conn.DeleteRuleWithContext(ctx, &eventbridge.DeleteRuleInput{ - EventBusName: aws.String(eventBusName), - Force: aws.Bool(true), - Name: aws.String(ruleName), - }) + r := resourceRule() + d := r.Data(nil) + d.SetId(ruleCreateResourceID(eventBusName, ruleName)) - if err != nil { - sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error deleting EventBridge Rule (%s/%s): %w", eventBusName, ruleName, err)) - continue - } + sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) } return !lastPage }) - if awsv1.SkipSweepError(err) { - continue - } - if err != nil { - sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing EventBridge Rules (%s): %w", region, err)) + continue } } return !lastPage }) - if awsv1.SkipSweepError(err) { + if awsv2.SkipSweepError(err) { log.Printf("[WARN] Skipping EventBridge Rule sweep for %s: %s", region, err) - return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + return nil } if err != nil { - sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing EventBridge event buses (%s): %w", region, err)) + return fmt.Errorf("error listing EventBridge Rules (%s): %w", region, err) + } + + err = sweep.SweepOrchestrator(ctx, sweepResources) + + if err != nil { + return fmt.Errorf("error sweeping EventBridge Rules (%s): %w", region, err) } - return sweeperErrs.ErrorOrNil() + return nil } func sweepTargets(region string) error { @@ -384,18 +318,17 @@ func sweepTargets(region string) error { if err != nil { return fmt.Errorf("error getting client: %w", err) } - conn := client.EventsConn(ctx) + conn := client.EventsClient(ctx) input := &eventbridge.ListEventBusesInput{} - var sweeperErrs *multierror.Error + sweepResources := make([]sweep.Sweepable, 0) err = listEventBusesPages(ctx, conn, input, func(page *eventbridge.ListEventBusesOutput, lastPage bool) bool { if page == nil { return !lastPage } - for _, eventBus := range page.EventBuses { - eventBusName := aws.StringValue(eventBus.Name) - + for _, v := range page.EventBuses { + eventBusName := aws.ToString(v.Name) input := &eventbridge.ListRulesInput{ EventBusName: aws.String(eventBusName), } @@ -405,9 +338,8 @@ func sweepTargets(region string) error { return !lastPage } - for _, rule := range page.Rules { - ruleName := aws.StringValue(rule.Name) - + for _, v := range page.Rules { + ruleName := aws.ToString(v.Name) input := &eventbridge.ListTargetsByRuleInput{ EventBusName: aws.String(eventBusName), Rule: aws.String(ruleName), @@ -418,58 +350,49 @@ func sweepTargets(region string) error { return !lastPage } - for _, target := range page.Targets { - targetID := aws.StringValue(target.Id) - - log.Printf("[DEBUG] Deleting EventBridge Target: %s/%s/%s", eventBusName, ruleName, targetID) - _, err := conn.RemoveTargetsWithContext(ctx, &eventbridge.RemoveTargetsInput{ - EventBusName: aws.String(eventBusName), - Force: aws.Bool(true), - Ids: aws.StringSlice([]string{targetID}), - Rule: aws.String(ruleName), - }) - - if err != nil { - sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error deleting EventBridge Target (%s/%s/%s): %w", eventBusName, ruleName, targetID, err)) - continue - } + for _, v := range page.Targets { + targetID := aws.ToString(v.Id) + + r := resourceTarget() + d := r.Data(nil) + d.SetId(targetCreateResourceID(eventBusName, ruleName, targetID)) + + sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) } return !lastPage }) - if awsv1.SkipSweepError(err) { - continue - } - if err != nil { - sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing EventBridge Targets (%s): %w", region, err)) + continue } } return !lastPage }) - if awsv1.SkipSweepError(err) { - continue - } - if err != nil { - sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing EventBridge Rules (%s): %w", region, err)) + continue } } return !lastPage }) - if awsv1.SkipSweepError(err) { - log.Printf("[WARN] Skipping EventBridge Rule sweep for %s: %s", region, err) - return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + if awsv2.SkipSweepError(err) { + log.Printf("[WARN] Skipping EventBridge Target sweep for %s: %s", region, err) + return nil } if err != nil { - sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing EventBridge event buses (%s): %w", region, err)) + return fmt.Errorf("error listing EventBridge Targets (%s): %w", region, err) } - return sweeperErrs.ErrorOrNil() + err = sweep.SweepOrchestrator(ctx, sweepResources) + + if err != nil { + return fmt.Errorf("error sweeping EventBridge Targets (%s): %w", region, err) + } + + return nil } diff --git a/internal/service/events/target.go b/internal/service/events/target.go index 0c6403717df..399e347dd1a 100644 --- a/internal/service/events/target.go +++ b/internal/service/events/target.go @@ -491,8 +491,7 @@ func resourceTargetCreate(ctx context.Context, d *schema.ResourceData, meta inte var diags diag.Diagnostics conn := meta.(*conns.AWSClient).EventsClient(ctx) - rule := d.Get("rule").(string) - + ruleName := d.Get("rule").(string) var targetID string if v, ok := d.GetOk("target_id"); ok { targetID = v.(string) @@ -500,11 +499,11 @@ func resourceTargetCreate(ctx context.Context, d *schema.ResourceData, meta inte targetID = id.UniqueId() d.Set("target_id", targetID) } - var busName string + var eventBusName string if v, ok := d.GetOk("event_bus_name"); ok { - busName = v.(string) + eventBusName = v.(string) } - id := targetCreateResourceID(busName, rule, targetID) + id := targetCreateResourceID(eventBusName, ruleName, targetID) input := expandPutTargetsInput(ctx, d) @@ -527,8 +526,8 @@ func resourceTargetRead(ctx context.Context, d *schema.ResourceData, meta interf var diags diag.Diagnostics conn := meta.(*conns.AWSClient).EventsClient(ctx) - busName := d.Get("event_bus_name").(string) - target, err := findTargetByThreePartKey(ctx, conn, busName, d.Get("rule").(string), d.Get("target_id").(string)) + eventBusName := d.Get("event_bus_name").(string) + target, err := findTargetByThreePartKey(ctx, conn, eventBusName, d.Get("rule").(string), d.Get("target_id").(string)) if !d.IsNewResource() && tfresource.NotFound(err) { log.Printf("[WARN] EventBridge Target (%s) not found, removing from state", d.Id()) @@ -541,7 +540,7 @@ func resourceTargetRead(ctx context.Context, d *schema.ResourceData, meta interf } d.Set("arn", target.Arn) - d.Set("event_bus_name", busName) + d.Set("event_bus_name", eventBusName) d.Set("input", target.Input) d.Set("input_path", target.InputPath) d.Set("role_arn", target.RoleArn) From f70d0d08c26d7fbdfe4dd4e5573e1c34503f728a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 08:49:27 -0400 Subject: [PATCH 26/35] Run 'make cleantidy'. --- tools/tfsdk2fw/go.mod | 1 + tools/tfsdk2fw/go.sum | 2 ++ 2 files changed, 3 insertions(+) diff --git a/tools/tfsdk2fw/go.mod b/tools/tfsdk2fw/go.mod index 2eb38954f0a..e3b02cb7783 100644 --- a/tools/tfsdk2fw/go.mod +++ b/tools/tfsdk2fw/go.mod @@ -99,6 +99,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.30.5 // indirect github.com/aws/aws-sdk-go-v2/service/emr v1.39.5 // indirect github.com/aws/aws-sdk-go-v2/service/emrserverless v1.17.5 // indirect + github.com/aws/aws-sdk-go-v2/service/eventbridge v1.30.4 // indirect github.com/aws/aws-sdk-go-v2/service/evidently v1.19.4 // indirect github.com/aws/aws-sdk-go-v2/service/finspace v1.24.1 // indirect github.com/aws/aws-sdk-go-v2/service/firehose v1.28.5 // indirect diff --git a/tools/tfsdk2fw/go.sum b/tools/tfsdk2fw/go.sum index 47580fcdf1c..236954a775d 100644 --- a/tools/tfsdk2fw/go.sum +++ b/tools/tfsdk2fw/go.sum @@ -184,6 +184,8 @@ github.com/aws/aws-sdk-go-v2/service/emr v1.39.5 h1:ni+E9GfbQ8CzjYSlJ+WbNYX7SAsL github.com/aws/aws-sdk-go-v2/service/emr v1.39.5/go.mod h1:7WusX+O5pwTnx2yobUO/P1C5HlBibmrQb5gKEPFjTYM= github.com/aws/aws-sdk-go-v2/service/emrserverless v1.17.5 h1:w7hZ1/CRiKvzAtkzlv7tcP/wqxh9kdm5nWj4fq6/+RE= github.com/aws/aws-sdk-go-v2/service/emrserverless v1.17.5/go.mod h1:TZrahLcSXIN/kO96kvxUzfLNLH8E6t3xodv8Zv5DHGs= +github.com/aws/aws-sdk-go-v2/service/eventbridge v1.30.4 h1:Vz4ilZcVXCR9yatX5yfMrkBldYggtkih3h7woHvzu5Q= +github.com/aws/aws-sdk-go-v2/service/eventbridge v1.30.4/go.mod h1:aIINXlt2xXhMeRsyCsLDUDohI8AdDm92gY9nIB6pv0M= github.com/aws/aws-sdk-go-v2/service/evidently v1.19.4 h1:DcRQTdvIQs+v+rQJ598v7WmgLSsla9C90mY4J+rccrU= github.com/aws/aws-sdk-go-v2/service/evidently v1.19.4/go.mod h1:ajhW/0n1t1jQKd2Kn46/99wcMj41TSPBJ3vSWocTvdE= github.com/aws/aws-sdk-go-v2/service/finspace v1.24.1 h1:1syXGgya/121hPyOlzi4RvV1lrtIGEHLlrYUiRsZbXo= From 5f825b1408b4badc2cb82de8f6d7a61fd7c13235 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 08:57:57 -0400 Subject: [PATCH 27/35] Exclude 'list_pages_gen.go' from '-in-func-name' semgrep check. --- internal/generate/servicesemgrep/service.tmpl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/generate/servicesemgrep/service.tmpl b/internal/generate/servicesemgrep/service.tmpl index 7858b411c33..104987a8b5a 100644 --- a/internal/generate/servicesemgrep/service.tmpl +++ b/internal/generate/servicesemgrep/service.tmpl @@ -7,6 +7,8 @@ paths: include: - internal/service/{{ .ProviderPackage }} + exclude: + - internal/service/{{ .ProviderPackage }}/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: From f7001aca9273de19e68ed223b20ddf32f6c0571f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 08:58:18 -0400 Subject: [PATCH 28/35] Run 'make gen'. --- .ci/.semgrep-service-name0.yml | 156 ++++++++++++++++++++++++++++++--- .ci/.semgrep-service-name1.yml | 152 ++++++++++++++++++++++++++++++++ .ci/.semgrep-service-name2.yml | 138 +++++++++++++++++++++++++++++ .ci/.semgrep-service-name3.yml | 134 ++++++++++++++++++++++++++++ 4 files changed, 566 insertions(+), 14 deletions(-) diff --git a/.ci/.semgrep-service-name0.yml b/.ci/.semgrep-service-name0.yml index f79ee33fc5d..39c66dbb1fe 100644 --- a/.ci/.semgrep-service-name0.yml +++ b/.ci/.semgrep-service-name0.yml @@ -7,6 +7,8 @@ rules: paths: include: - internal/service/accessanalyzer + exclude: + - internal/service/accessanalyzer/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -66,6 +68,8 @@ rules: paths: include: - internal/service/account + exclude: + - internal/service/account/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -125,6 +129,8 @@ rules: paths: include: - internal/service/acm + exclude: + - internal/service/acm/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -184,6 +190,8 @@ rules: paths: include: - internal/service/acmpca + exclude: + - internal/service/acmpca/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -243,6 +251,8 @@ rules: paths: include: - internal/service/grafana + exclude: + - internal/service/grafana/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -287,6 +297,8 @@ rules: paths: include: - internal/service/amp + exclude: + - internal/service/amp/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -346,6 +358,8 @@ rules: paths: include: - internal/service/amplify + exclude: + - internal/service/amplify/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -405,6 +419,8 @@ rules: paths: include: - internal/service/apigateway + exclude: + - internal/service/apigateway/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -464,6 +480,8 @@ rules: paths: include: - internal/service/apigatewayv2 + exclude: + - internal/service/apigatewayv2/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -523,6 +541,8 @@ rules: paths: include: - internal/service/appautoscaling + exclude: + - internal/service/appautoscaling/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -582,6 +602,8 @@ rules: paths: include: - internal/service/appconfig + exclude: + - internal/service/appconfig/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -641,6 +663,8 @@ rules: paths: include: - internal/service/appfabric + exclude: + - internal/service/appfabric/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -700,6 +724,8 @@ rules: paths: include: - internal/service/appflow + exclude: + - internal/service/appflow/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -759,6 +785,8 @@ rules: paths: include: - internal/service/appintegrations + exclude: + - internal/service/appintegrations/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -818,6 +846,8 @@ rules: paths: include: - internal/service/appintegrations + exclude: + - internal/service/appintegrations/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -862,6 +892,8 @@ rules: paths: include: - internal/service/appautoscaling + exclude: + - internal/service/appautoscaling/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -906,6 +938,8 @@ rules: paths: include: - internal/service/applicationinsights + exclude: + - internal/service/applicationinsights/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -965,6 +999,8 @@ rules: paths: include: - internal/service/appmesh + exclude: + - internal/service/appmesh/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1024,6 +1060,8 @@ rules: paths: include: - internal/service/servicecatalogappregistry + exclude: + - internal/service/servicecatalogappregistry/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1068,6 +1106,8 @@ rules: paths: include: - internal/service/apprunner + exclude: + - internal/service/apprunner/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1127,6 +1167,8 @@ rules: paths: include: - internal/service/appstream + exclude: + - internal/service/appstream/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1186,6 +1228,8 @@ rules: paths: include: - internal/service/appsync + exclude: + - internal/service/appsync/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1245,6 +1289,8 @@ rules: paths: include: - internal/service/athena + exclude: + - internal/service/athena/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1304,6 +1350,8 @@ rules: paths: include: - internal/service/auditmanager + exclude: + - internal/service/auditmanager/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1363,6 +1411,8 @@ rules: paths: include: - internal/service/autoscaling + exclude: + - internal/service/autoscaling/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1422,6 +1472,8 @@ rules: paths: include: - internal/service/autoscalingplans + exclude: + - internal/service/autoscalingplans/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1481,6 +1533,8 @@ rules: paths: include: - internal/service/backup + exclude: + - internal/service/backup/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1540,6 +1594,8 @@ rules: paths: include: - internal/service/batch + exclude: + - internal/service/batch/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1599,6 +1655,8 @@ rules: paths: include: - internal/service/bcmdataexports + exclude: + - internal/service/bcmdataexports/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1658,6 +1716,8 @@ rules: paths: include: - internal/service/elasticbeanstalk + exclude: + - internal/service/elasticbeanstalk/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1702,6 +1762,8 @@ rules: paths: include: - internal/service/bedrock + exclude: + - internal/service/bedrock/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1761,6 +1823,8 @@ rules: paths: include: - internal/service/bedrockagent + exclude: + - internal/service/bedrockagent/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1820,6 +1884,8 @@ rules: paths: include: - internal/service/budgets + exclude: + - internal/service/budgets/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1879,6 +1945,8 @@ rules: paths: include: - internal/service/ce + exclude: + - internal/service/ce/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1944,6 +2012,8 @@ rules: paths: include: - internal/service/chime + exclude: + - internal/service/chime/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2003,6 +2073,8 @@ rules: paths: include: - internal/service/chimesdkmediapipelines + exclude: + - internal/service/chimesdkmediapipelines/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2062,6 +2134,8 @@ rules: paths: include: - internal/service/chimesdkvoice + exclude: + - internal/service/chimesdkvoice/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2121,6 +2195,8 @@ rules: paths: include: - internal/service/cleanrooms + exclude: + - internal/service/cleanrooms/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2180,6 +2256,8 @@ rules: paths: include: - internal/service/cloud9 + exclude: + - internal/service/cloud9/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2239,6 +2317,8 @@ rules: paths: include: - internal/service/cloudcontrol + exclude: + - internal/service/cloudcontrol/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2298,6 +2378,8 @@ rules: paths: include: - internal/service/cloudcontrol + exclude: + - internal/service/cloudcontrol/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2342,6 +2424,8 @@ rules: paths: include: - internal/service/cloudformation + exclude: + - internal/service/cloudformation/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2401,6 +2485,8 @@ rules: paths: include: - internal/service/cloudfront + exclude: + - internal/service/cloudfront/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2460,6 +2546,8 @@ rules: paths: include: - internal/service/cloudfrontkeyvaluestore + exclude: + - internal/service/cloudfrontkeyvaluestore/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2519,6 +2607,8 @@ rules: paths: include: - internal/service/cloudhsmv2 + exclude: + - internal/service/cloudhsmv2/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2563,6 +2653,8 @@ rules: paths: include: - internal/service/cloudhsmv2 + exclude: + - internal/service/cloudhsmv2/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2622,6 +2714,8 @@ rules: paths: include: - internal/service/cloudsearch + exclude: + - internal/service/cloudsearch/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2681,6 +2775,8 @@ rules: paths: include: - internal/service/cloudtrail + exclude: + - internal/service/cloudtrail/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2741,6 +2837,8 @@ rules: paths: include: - internal/service/cloudwatch + exclude: + - internal/service/cloudwatch/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2800,6 +2898,8 @@ rules: paths: include: - internal/service/events + exclude: + - internal/service/events/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2844,6 +2944,8 @@ rules: paths: include: - internal/service/evidently + exclude: + - internal/service/evidently/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2888,6 +2990,8 @@ rules: paths: include: - internal/service/logs + exclude: + - internal/service/logs/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2932,6 +3036,8 @@ rules: paths: include: - internal/service/logs + exclude: + - internal/service/logs/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2976,6 +3082,8 @@ rules: paths: include: - internal/service/oam + exclude: + - internal/service/oam/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3020,6 +3128,8 @@ rules: paths: include: - internal/service/rum + exclude: + - internal/service/rum/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3064,6 +3174,8 @@ rules: paths: include: - internal/service/codeartifact + exclude: + - internal/service/codeartifact/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3123,6 +3235,8 @@ rules: paths: include: - internal/service/codebuild + exclude: + - internal/service/codebuild/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3182,6 +3296,8 @@ rules: paths: include: - internal/service/codecatalyst + exclude: + - internal/service/codecatalyst/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3241,6 +3357,8 @@ rules: paths: include: - internal/service/codecommit + exclude: + - internal/service/codecommit/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3300,6 +3418,8 @@ rules: paths: include: - internal/service/deploy + exclude: + - internal/service/deploy/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3344,6 +3464,8 @@ rules: paths: include: - internal/service/codeguruprofiler + exclude: + - internal/service/codeguruprofiler/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3403,6 +3525,8 @@ rules: paths: include: - internal/service/codegurureviewer + exclude: + - internal/service/codegurureviewer/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3462,6 +3586,8 @@ rules: paths: include: - internal/service/codepipeline + exclude: + - internal/service/codepipeline/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3521,6 +3647,8 @@ rules: paths: include: - internal/service/codestarconnections + exclude: + - internal/service/codestarconnections/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3580,6 +3708,8 @@ rules: paths: include: - internal/service/codestarnotifications + exclude: + - internal/service/codestarnotifications/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3639,6 +3769,8 @@ rules: paths: include: - internal/service/cognitoidentity + exclude: + - internal/service/cognitoidentity/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3698,6 +3830,8 @@ rules: paths: include: - internal/service/cognitoidp + exclude: + - internal/service/cognitoidp/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3742,6 +3876,8 @@ rules: paths: include: - internal/service/cognitoidp + exclude: + - internal/service/cognitoidp/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3801,6 +3937,8 @@ rules: paths: include: - internal/service/comprehend + exclude: + - internal/service/comprehend/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3860,6 +3998,8 @@ rules: paths: include: - internal/service/computeoptimizer + exclude: + - internal/service/computeoptimizer/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3919,6 +4059,8 @@ rules: paths: include: - internal/service/configservice + exclude: + - internal/service/configservice/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3943,17 +4085,3 @@ rules: - pattern-not-regex: "^TestAccConfigService" - pattern-regex: ^TestAcc.* severity: WARNING - - id: configservice-in-const-name - languages: - - go - message: Do not use "ConfigService" in const name inside configservice package - paths: - include: - - internal/service/configservice - patterns: - - pattern: const $NAME = ... - - metavariable-pattern: - metavariable: $NAME - patterns: - - pattern-regex: "(?i)ConfigService" - severity: WARNING diff --git a/.ci/.semgrep-service-name1.yml b/.ci/.semgrep-service-name1.yml index 955fad88a0e..0a19db5027d 100644 --- a/.ci/.semgrep-service-name1.yml +++ b/.ci/.semgrep-service-name1.yml @@ -1,5 +1,19 @@ # Generated by internal/generate/servicesemgrep/main.go; DO NOT EDIT. rules: + - id: configservice-in-const-name + languages: + - go + message: Do not use "ConfigService" in const name inside configservice package + paths: + include: + - internal/service/configservice + patterns: + - pattern: const $NAME = ... + - metavariable-pattern: + metavariable: $NAME + patterns: + - pattern-regex: "(?i)ConfigService" + severity: WARNING - id: configservice-in-var-name languages: - go @@ -21,6 +35,8 @@ rules: paths: include: - internal/service/connect + exclude: + - internal/service/connect/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -83,6 +99,8 @@ rules: paths: include: - internal/service/connectcases + exclude: + - internal/service/connectcases/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -142,6 +160,8 @@ rules: paths: include: - internal/service/controltower + exclude: + - internal/service/controltower/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -201,6 +221,8 @@ rules: paths: include: - internal/service/cur + exclude: + - internal/service/cur/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -245,6 +267,8 @@ rules: paths: include: - internal/service/ce + exclude: + - internal/service/ce/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -289,6 +313,8 @@ rules: paths: include: - internal/service/costoptimizationhub + exclude: + - internal/service/costoptimizationhub/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -348,6 +374,8 @@ rules: paths: include: - internal/service/cur + exclude: + - internal/service/cur/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -407,6 +435,8 @@ rules: paths: include: - internal/service/customerprofiles + exclude: + - internal/service/customerprofiles/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -466,6 +496,8 @@ rules: paths: include: - internal/service/dms + exclude: + - internal/service/dms/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -510,6 +542,8 @@ rules: paths: include: - internal/service/dms + exclude: + - internal/service/dms/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -554,6 +588,8 @@ rules: paths: include: - internal/service/dataexchange + exclude: + - internal/service/dataexchange/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -613,6 +649,8 @@ rules: paths: include: - internal/service/datapipeline + exclude: + - internal/service/datapipeline/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -672,6 +710,8 @@ rules: paths: include: - internal/service/datasync + exclude: + - internal/service/datasync/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -731,6 +771,8 @@ rules: paths: include: - internal/service/datazone + exclude: + - internal/service/datazone/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -790,6 +832,8 @@ rules: paths: include: - internal/service/dax + exclude: + - internal/service/dax/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -849,6 +893,8 @@ rules: paths: include: - internal/service/deploy + exclude: + - internal/service/deploy/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -909,6 +955,8 @@ rules: paths: include: - internal/service/detective + exclude: + - internal/service/detective/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -968,6 +1016,8 @@ rules: paths: include: - internal/service/devicefarm + exclude: + - internal/service/devicefarm/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1027,6 +1077,8 @@ rules: paths: include: - internal/service/devopsguru + exclude: + - internal/service/devopsguru/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1086,6 +1138,8 @@ rules: paths: include: - internal/service/directconnect + exclude: + - internal/service/directconnect/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1145,6 +1199,8 @@ rules: paths: include: - internal/service/ds + exclude: + - internal/service/ds/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1189,6 +1245,8 @@ rules: paths: include: - internal/service/dlm + exclude: + - internal/service/dlm/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1248,6 +1306,8 @@ rules: paths: include: - internal/service/dms + exclude: + - internal/service/dms/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1307,6 +1367,8 @@ rules: paths: include: - internal/service/docdb + exclude: + - internal/service/docdb/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1366,6 +1428,8 @@ rules: paths: include: - internal/service/docdbelastic + exclude: + - internal/service/docdbelastic/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1425,6 +1489,8 @@ rules: paths: include: - internal/service/ds + exclude: + - internal/service/ds/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1484,6 +1550,8 @@ rules: paths: include: - internal/service/dynamodb + exclude: + - internal/service/dynamodb/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1588,6 +1656,8 @@ rules: paths: include: - internal/service/ecr + exclude: + - internal/service/ecr/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1647,6 +1717,8 @@ rules: paths: include: - internal/service/ecrpublic + exclude: + - internal/service/ecrpublic/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1706,6 +1778,8 @@ rules: paths: include: - internal/service/ecs + exclude: + - internal/service/ecs/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1765,6 +1839,8 @@ rules: paths: include: - internal/service/efs + exclude: + - internal/service/efs/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1824,6 +1900,8 @@ rules: paths: include: - internal/service/eks + exclude: + - internal/service/eks/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1883,6 +1961,8 @@ rules: paths: include: - internal/service/elasticache + exclude: + - internal/service/elasticache/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1942,6 +2022,8 @@ rules: paths: include: - internal/service/elasticbeanstalk + exclude: + - internal/service/elasticbeanstalk/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2001,6 +2083,8 @@ rules: paths: include: - internal/service/elb + exclude: + - internal/service/elb/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2045,6 +2129,8 @@ rules: paths: include: - internal/service/elbv2 + exclude: + - internal/service/elbv2/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2089,6 +2175,8 @@ rules: paths: include: - internal/service/elasticsearch + exclude: + - internal/service/elasticsearch/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2148,6 +2236,8 @@ rules: paths: include: - internal/service/elasticsearch + exclude: + - internal/service/elasticsearch/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2192,6 +2282,8 @@ rules: paths: include: - internal/service/elastictranscoder + exclude: + - internal/service/elastictranscoder/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2251,6 +2343,8 @@ rules: paths: include: - internal/service/elb + exclude: + - internal/service/elb/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2310,6 +2404,8 @@ rules: paths: include: - internal/service/elbv2 + exclude: + - internal/service/elbv2/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2369,6 +2465,8 @@ rules: paths: include: - internal/service/emr + exclude: + - internal/service/emr/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2428,6 +2526,8 @@ rules: paths: include: - internal/service/emrcontainers + exclude: + - internal/service/emrcontainers/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2487,6 +2587,8 @@ rules: paths: include: - internal/service/emrserverless + exclude: + - internal/service/emrserverless/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2546,6 +2648,8 @@ rules: paths: include: - internal/service/events + exclude: + - internal/service/events/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2590,6 +2694,8 @@ rules: paths: include: - internal/service/events + exclude: + - internal/service/events/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2649,6 +2755,8 @@ rules: paths: include: - internal/service/evidently + exclude: + - internal/service/evidently/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2708,6 +2816,8 @@ rules: paths: include: - internal/service/finspace + exclude: + - internal/service/finspace/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2767,6 +2877,8 @@ rules: paths: include: - internal/service/firehose + exclude: + - internal/service/firehose/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2826,6 +2938,8 @@ rules: paths: include: - internal/service/fis + exclude: + - internal/service/fis/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2885,6 +2999,8 @@ rules: paths: include: - internal/service/fms + exclude: + - internal/service/fms/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2944,6 +3060,8 @@ rules: paths: include: - internal/service/fsx + exclude: + - internal/service/fsx/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3003,6 +3121,8 @@ rules: paths: include: - internal/service/gamelift + exclude: + - internal/service/gamelift/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3062,6 +3182,8 @@ rules: paths: include: - internal/service/glacier + exclude: + - internal/service/glacier/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3121,6 +3243,8 @@ rules: paths: include: - internal/service/globalaccelerator + exclude: + - internal/service/globalaccelerator/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3180,6 +3304,8 @@ rules: paths: include: - internal/service/glue + exclude: + - internal/service/glue/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3239,6 +3365,8 @@ rules: paths: include: - internal/service/grafana + exclude: + - internal/service/grafana/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3298,6 +3426,8 @@ rules: paths: include: - internal/service/greengrass + exclude: + - internal/service/greengrass/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3357,6 +3487,8 @@ rules: paths: include: - internal/service/groundstation + exclude: + - internal/service/groundstation/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3416,6 +3548,8 @@ rules: paths: include: - internal/service/guardduty + exclude: + - internal/service/guardduty/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3475,6 +3609,8 @@ rules: paths: include: - internal/service/healthlake + exclude: + - internal/service/healthlake/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3534,6 +3670,8 @@ rules: paths: include: - internal/service/iam + exclude: + - internal/service/iam/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3593,6 +3731,8 @@ rules: paths: include: - internal/service/identitystore + exclude: + - internal/service/identitystore/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3652,6 +3792,8 @@ rules: paths: include: - internal/service/imagebuilder + exclude: + - internal/service/imagebuilder/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3711,6 +3853,8 @@ rules: paths: include: - internal/service/inspector + exclude: + - internal/service/inspector/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3770,6 +3914,8 @@ rules: paths: include: - internal/service/inspector2 + exclude: + - internal/service/inspector2/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3829,6 +3975,8 @@ rules: paths: include: - internal/service/inspector2 + exclude: + - internal/service/inspector2/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3873,6 +4021,8 @@ rules: paths: include: - internal/service/internetmonitor + exclude: + - internal/service/internetmonitor/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3932,6 +4082,8 @@ rules: paths: include: - internal/service/iot + exclude: + - internal/service/iot/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: diff --git a/.ci/.semgrep-service-name2.yml b/.ci/.semgrep-service-name2.yml index 739cfda2514..9dac636bd47 100644 --- a/.ci/.semgrep-service-name2.yml +++ b/.ci/.semgrep-service-name2.yml @@ -50,6 +50,8 @@ rules: paths: include: - internal/service/iotanalytics + exclude: + - internal/service/iotanalytics/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -109,6 +111,8 @@ rules: paths: include: - internal/service/iotevents + exclude: + - internal/service/iotevents/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -183,6 +187,8 @@ rules: paths: include: - internal/service/ivs + exclude: + - internal/service/ivs/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -242,6 +248,8 @@ rules: paths: include: - internal/service/ivschat + exclude: + - internal/service/ivschat/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -301,6 +309,8 @@ rules: paths: include: - internal/service/kafka + exclude: + - internal/service/kafka/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -360,6 +370,8 @@ rules: paths: include: - internal/service/kafkaconnect + exclude: + - internal/service/kafkaconnect/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -419,6 +431,8 @@ rules: paths: include: - internal/service/kendra + exclude: + - internal/service/kendra/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -478,6 +492,8 @@ rules: paths: include: - internal/service/keyspaces + exclude: + - internal/service/keyspaces/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -537,6 +553,8 @@ rules: paths: include: - internal/service/kinesis + exclude: + - internal/service/kinesis/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -596,6 +614,8 @@ rules: paths: include: - internal/service/kinesisanalytics + exclude: + - internal/service/kinesisanalytics/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -655,6 +675,8 @@ rules: paths: include: - internal/service/kinesisanalyticsv2 + exclude: + - internal/service/kinesisanalyticsv2/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -714,6 +736,8 @@ rules: paths: include: - internal/service/kinesisvideo + exclude: + - internal/service/kinesisvideo/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -773,6 +797,8 @@ rules: paths: include: - internal/service/kms + exclude: + - internal/service/kms/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -832,6 +858,8 @@ rules: paths: include: - internal/service/lakeformation + exclude: + - internal/service/lakeformation/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -891,6 +919,8 @@ rules: paths: include: - internal/service/lambda + exclude: + - internal/service/lambda/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -950,6 +980,8 @@ rules: paths: include: - internal/service/launchwizard + exclude: + - internal/service/launchwizard/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1009,6 +1041,8 @@ rules: paths: include: - internal/service/lexmodels + exclude: + - internal/service/lexmodels/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1053,6 +1087,8 @@ rules: paths: include: - internal/service/lexmodels + exclude: + - internal/service/lexmodels/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1097,6 +1133,8 @@ rules: paths: include: - internal/service/lexmodels + exclude: + - internal/service/lexmodels/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1141,6 +1179,8 @@ rules: paths: include: - internal/service/lexmodels + exclude: + - internal/service/lexmodels/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1200,6 +1240,8 @@ rules: paths: include: - internal/service/lexv2models + exclude: + - internal/service/lexv2models/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1244,6 +1286,8 @@ rules: paths: include: - internal/service/lexv2models + exclude: + - internal/service/lexv2models/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1303,6 +1347,8 @@ rules: paths: include: - internal/service/licensemanager + exclude: + - internal/service/licensemanager/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1362,6 +1408,8 @@ rules: paths: include: - internal/service/lightsail + exclude: + - internal/service/lightsail/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1421,6 +1469,8 @@ rules: paths: include: - internal/service/location + exclude: + - internal/service/location/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1480,6 +1530,8 @@ rules: paths: include: - internal/service/location + exclude: + - internal/service/location/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1524,6 +1576,8 @@ rules: paths: include: - internal/service/logs + exclude: + - internal/service/logs/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1583,6 +1637,8 @@ rules: paths: include: - internal/service/lookoutmetrics + exclude: + - internal/service/lookoutmetrics/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1642,6 +1698,8 @@ rules: paths: include: - internal/service/m2 + exclude: + - internal/service/m2/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1701,6 +1759,8 @@ rules: paths: include: - internal/service/macie2 + exclude: + - internal/service/macie2/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1760,6 +1820,8 @@ rules: paths: include: - internal/service/grafana + exclude: + - internal/service/grafana/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1804,6 +1866,8 @@ rules: paths: include: - internal/service/mediaconnect + exclude: + - internal/service/mediaconnect/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1863,6 +1927,8 @@ rules: paths: include: - internal/service/mediaconvert + exclude: + - internal/service/mediaconvert/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1922,6 +1988,8 @@ rules: paths: include: - internal/service/medialive + exclude: + - internal/service/medialive/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1981,6 +2049,8 @@ rules: paths: include: - internal/service/mediapackage + exclude: + - internal/service/mediapackage/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2040,6 +2110,8 @@ rules: paths: include: - internal/service/mediapackagev2 + exclude: + - internal/service/mediapackagev2/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2099,6 +2171,8 @@ rules: paths: include: - internal/service/mediastore + exclude: + - internal/service/mediastore/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2158,6 +2232,8 @@ rules: paths: include: - internal/service/memorydb + exclude: + - internal/service/memorydb/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2217,6 +2293,8 @@ rules: paths: include: - internal/service/meta + exclude: + - internal/service/meta/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2276,6 +2354,8 @@ rules: paths: include: - internal/service/mq + exclude: + - internal/service/mq/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2335,6 +2415,8 @@ rules: paths: include: - internal/service/kafka + exclude: + - internal/service/kafka/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2379,6 +2461,8 @@ rules: paths: include: - internal/service/mwaa + exclude: + - internal/service/mwaa/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2438,6 +2522,8 @@ rules: paths: include: - internal/service/neptune + exclude: + - internal/service/neptune/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2497,6 +2583,8 @@ rules: paths: include: - internal/service/neptunegraph + exclude: + - internal/service/neptunegraph/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2556,6 +2644,8 @@ rules: paths: include: - internal/service/networkfirewall + exclude: + - internal/service/networkfirewall/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2615,6 +2705,8 @@ rules: paths: include: - internal/service/networkmanager + exclude: + - internal/service/networkmanager/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2674,6 +2766,8 @@ rules: paths: include: - internal/service/oam + exclude: + - internal/service/oam/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2733,6 +2827,8 @@ rules: paths: include: - internal/service/opensearch + exclude: + - internal/service/opensearch/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2792,6 +2888,8 @@ rules: paths: include: - internal/service/osis + exclude: + - internal/service/osis/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2836,6 +2934,8 @@ rules: paths: include: - internal/service/opensearchserverless + exclude: + - internal/service/opensearchserverless/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2895,6 +2995,8 @@ rules: paths: include: - internal/service/opensearch + exclude: + - internal/service/opensearch/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2939,6 +3041,8 @@ rules: paths: include: - internal/service/opsworks + exclude: + - internal/service/opsworks/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2998,6 +3102,8 @@ rules: paths: include: - internal/service/organizations + exclude: + - internal/service/organizations/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3057,6 +3163,8 @@ rules: paths: include: - internal/service/osis + exclude: + - internal/service/osis/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3116,6 +3224,8 @@ rules: paths: include: - internal/service/outposts + exclude: + - internal/service/outposts/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3175,6 +3285,8 @@ rules: paths: include: - internal/service/paymentcryptography + exclude: + - internal/service/paymentcryptography/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3234,6 +3346,8 @@ rules: paths: include: - internal/service/pcaconnectorad + exclude: + - internal/service/pcaconnectorad/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3293,6 +3407,8 @@ rules: paths: include: - internal/service/pinpoint + exclude: + - internal/service/pinpoint/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3352,6 +3468,8 @@ rules: paths: include: - internal/service/pipes + exclude: + - internal/service/pipes/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3414,6 +3532,8 @@ rules: paths: include: - internal/service/polly + exclude: + - internal/service/polly/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3473,6 +3593,8 @@ rules: paths: include: - internal/service/pricing + exclude: + - internal/service/pricing/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3532,6 +3654,8 @@ rules: paths: include: - internal/service/amp + exclude: + - internal/service/amp/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3576,6 +3700,8 @@ rules: paths: include: - internal/service/amp + exclude: + - internal/service/amp/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3620,6 +3746,8 @@ rules: paths: include: - internal/service/qbusiness + exclude: + - internal/service/qbusiness/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3679,6 +3807,8 @@ rules: paths: include: - internal/service/qldb + exclude: + - internal/service/qldb/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3738,6 +3868,8 @@ rules: paths: include: - internal/service/quicksight + exclude: + - internal/service/quicksight/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3797,6 +3929,8 @@ rules: paths: include: - internal/service/ram + exclude: + - internal/service/ram/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3859,6 +3993,8 @@ rules: paths: include: - internal/service/rbin + exclude: + - internal/service/rbin/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3918,6 +4054,8 @@ rules: paths: include: - internal/service/rds + exclude: + - internal/service/rds/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: diff --git a/.ci/.semgrep-service-name3.yml b/.ci/.semgrep-service-name3.yml index 9b6dca65828..f0991fbb868 100644 --- a/.ci/.semgrep-service-name3.yml +++ b/.ci/.semgrep-service-name3.yml @@ -35,6 +35,8 @@ rules: paths: include: - internal/service/rbin + exclude: + - internal/service/rbin/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -79,6 +81,8 @@ rules: paths: include: - internal/service/redshift + exclude: + - internal/service/redshift/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -138,6 +142,8 @@ rules: paths: include: - internal/service/redshiftdata + exclude: + - internal/service/redshiftdata/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -197,6 +203,8 @@ rules: paths: include: - internal/service/redshiftdata + exclude: + - internal/service/redshiftdata/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -241,6 +249,8 @@ rules: paths: include: - internal/service/redshiftserverless + exclude: + - internal/service/redshiftserverless/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -300,6 +310,8 @@ rules: paths: include: - internal/service/rekognition + exclude: + - internal/service/rekognition/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -359,6 +371,8 @@ rules: paths: include: - internal/service/resourceexplorer2 + exclude: + - internal/service/resourceexplorer2/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -418,6 +432,8 @@ rules: paths: include: - internal/service/resourcegroups + exclude: + - internal/service/resourcegroups/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -477,6 +493,8 @@ rules: paths: include: - internal/service/resourcegroupstaggingapi + exclude: + - internal/service/resourcegroupstaggingapi/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -521,6 +539,8 @@ rules: paths: include: - internal/service/resourcegroupstaggingapi + exclude: + - internal/service/resourcegroupstaggingapi/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -580,6 +600,8 @@ rules: paths: include: - internal/service/rolesanywhere + exclude: + - internal/service/rolesanywhere/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -639,6 +661,8 @@ rules: paths: include: - internal/service/route53 + exclude: + - internal/service/route53/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -698,6 +722,8 @@ rules: paths: include: - internal/service/route53domains + exclude: + - internal/service/route53domains/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -757,6 +783,8 @@ rules: paths: include: - internal/service/route53recoverycontrolconfig + exclude: + - internal/service/route53recoverycontrolconfig/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -816,6 +844,8 @@ rules: paths: include: - internal/service/route53recoveryreadiness + exclude: + - internal/service/route53recoveryreadiness/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -875,6 +905,8 @@ rules: paths: include: - internal/service/route53resolver + exclude: + - internal/service/route53resolver/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -934,6 +966,8 @@ rules: paths: include: - internal/service/rum + exclude: + - internal/service/rum/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -993,6 +1027,8 @@ rules: paths: include: - internal/service/s3 + exclude: + - internal/service/s3/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1052,6 +1088,8 @@ rules: paths: include: - internal/service/s3 + exclude: + - internal/service/s3/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1096,6 +1134,8 @@ rules: paths: include: - internal/service/s3control + exclude: + - internal/service/s3control/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1155,6 +1195,8 @@ rules: paths: include: - internal/service/s3outposts + exclude: + - internal/service/s3outposts/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1214,6 +1256,8 @@ rules: paths: include: - internal/service/sagemaker + exclude: + - internal/service/sagemaker/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1273,6 +1317,8 @@ rules: paths: include: - internal/service/scheduler + exclude: + - internal/service/scheduler/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1332,6 +1378,8 @@ rules: paths: include: - internal/service/schemas + exclude: + - internal/service/schemas/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1391,6 +1439,8 @@ rules: paths: include: - internal/service/simpledb + exclude: + - internal/service/simpledb/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1435,6 +1485,8 @@ rules: paths: include: - internal/service/secretsmanager + exclude: + - internal/service/secretsmanager/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1494,6 +1546,8 @@ rules: paths: include: - internal/service/securityhub + exclude: + - internal/service/securityhub/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1553,6 +1607,8 @@ rules: paths: include: - internal/service/securitylake + exclude: + - internal/service/securitylake/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1612,6 +1668,8 @@ rules: paths: include: - internal/service/serverlessrepo + exclude: + - internal/service/serverlessrepo/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1656,6 +1714,8 @@ rules: paths: include: - internal/service/serverlessrepo + exclude: + - internal/service/serverlessrepo/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1700,6 +1760,8 @@ rules: paths: include: - internal/service/serverlessrepo + exclude: + - internal/service/serverlessrepo/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1759,6 +1821,8 @@ rules: paths: include: - internal/service/servicecatalog + exclude: + - internal/service/servicecatalog/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1818,6 +1882,8 @@ rules: paths: include: - internal/service/servicecatalogappregistry + exclude: + - internal/service/servicecatalogappregistry/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1877,6 +1943,8 @@ rules: paths: include: - internal/service/servicediscovery + exclude: + - internal/service/servicediscovery/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1936,6 +2004,8 @@ rules: paths: include: - internal/service/servicequotas + exclude: + - internal/service/servicequotas/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -1995,6 +2065,8 @@ rules: paths: include: - internal/service/ses + exclude: + - internal/service/ses/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2054,6 +2126,8 @@ rules: paths: include: - internal/service/sesv2 + exclude: + - internal/service/sesv2/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2113,6 +2187,8 @@ rules: paths: include: - internal/service/sfn + exclude: + - internal/service/sfn/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2172,6 +2248,8 @@ rules: paths: include: - internal/service/shield + exclude: + - internal/service/shield/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2231,6 +2309,8 @@ rules: paths: include: - internal/service/signer + exclude: + - internal/service/signer/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2290,6 +2370,8 @@ rules: paths: include: - internal/service/simpledb + exclude: + - internal/service/simpledb/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2349,6 +2431,8 @@ rules: paths: include: - internal/service/sns + exclude: + - internal/service/sns/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2408,6 +2492,8 @@ rules: paths: include: - internal/service/sqs + exclude: + - internal/service/sqs/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2467,6 +2553,8 @@ rules: paths: include: - internal/service/ssm + exclude: + - internal/service/ssm/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2528,6 +2616,8 @@ rules: paths: include: - internal/service/ssmcontacts + exclude: + - internal/service/ssmcontacts/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2587,6 +2677,8 @@ rules: paths: include: - internal/service/ssmincidents + exclude: + - internal/service/ssmincidents/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2646,6 +2738,8 @@ rules: paths: include: - internal/service/ssmsap + exclude: + - internal/service/ssmsap/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2705,6 +2799,8 @@ rules: paths: include: - internal/service/sso + exclude: + - internal/service/sso/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2764,6 +2860,8 @@ rules: paths: include: - internal/service/ssoadmin + exclude: + - internal/service/ssoadmin/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2823,6 +2921,8 @@ rules: paths: include: - internal/service/sfn + exclude: + - internal/service/sfn/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2867,6 +2967,8 @@ rules: paths: include: - internal/service/storagegateway + exclude: + - internal/service/storagegateway/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2926,6 +3028,8 @@ rules: paths: include: - internal/service/sts + exclude: + - internal/service/sts/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -2985,6 +3089,8 @@ rules: paths: include: - internal/service/swf + exclude: + - internal/service/swf/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3044,6 +3150,8 @@ rules: paths: include: - internal/service/synthetics + exclude: + - internal/service/synthetics/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3103,6 +3211,8 @@ rules: paths: include: - internal/service/timestreamwrite + exclude: + - internal/service/timestreamwrite/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3162,6 +3272,8 @@ rules: paths: include: - internal/service/transcribe + exclude: + - internal/service/transcribe/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3221,6 +3333,8 @@ rules: paths: include: - internal/service/transcribe + exclude: + - internal/service/transcribe/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3265,6 +3379,8 @@ rules: paths: include: - internal/service/transfer + exclude: + - internal/service/transfer/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3354,6 +3470,8 @@ rules: paths: include: - internal/service/verifiedpermissions + exclude: + - internal/service/verifiedpermissions/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3428,6 +3546,8 @@ rules: paths: include: - internal/service/vpclattice + exclude: + - internal/service/vpclattice/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3517,6 +3637,8 @@ rules: paths: include: - internal/service/waf + exclude: + - internal/service/waf/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3577,6 +3699,8 @@ rules: paths: include: - internal/service/wafregional + exclude: + - internal/service/wafregional/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3636,6 +3760,8 @@ rules: paths: include: - internal/service/wafv2 + exclude: + - internal/service/wafv2/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3710,6 +3836,8 @@ rules: paths: include: - internal/service/wellarchitected + exclude: + - internal/service/wellarchitected/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3769,6 +3897,8 @@ rules: paths: include: - internal/service/worklink + exclude: + - internal/service/worklink/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3828,6 +3958,8 @@ rules: paths: include: - internal/service/workspaces + exclude: + - internal/service/workspaces/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: @@ -3887,6 +4019,8 @@ rules: paths: include: - internal/service/xray + exclude: + - internal/service/xray/list_pages_gen.go patterns: - pattern: func $NAME( ... ) { ... } - metavariable-pattern: From ea6467c2a615e1d9f1b9e2b2d41a62d5b1ddebff Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 08:58:35 -0400 Subject: [PATCH 29/35] Fix semgrep 'ci.events-in-func-name'. --- internal/service/events/source_data_source.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/events/source_data_source.go b/internal/service/events/source_data_source.go index 6ccba524424..ce5fb35d422 100644 --- a/internal/service/events/source_data_source.go +++ b/internal/service/events/source_data_source.go @@ -71,7 +71,7 @@ func dataSourceSourceRead(ctx context.Context, d *schema.ResourceData, meta inte return diags } -func findEventSource(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListEventSourcesInput) (*types.EventSource, error) { +func findEventSource(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListEventSourcesInput) (*types.EventSource, error) { // nosemgrep:ci.events-in-func-name output, err := findEventSources(ctx, conn, input) if err != nil { @@ -81,7 +81,7 @@ func findEventSource(ctx context.Context, conn *eventbridge.Client, input *event return tfresource.AssertSingleValueResult(output) } -func findEventSources(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListEventSourcesInput) ([]types.EventSource, error) { +func findEventSources(ctx context.Context, conn *eventbridge.Client, input *eventbridge.ListEventSourcesInput) ([]types.EventSource, error) { // nosemgrep:ci.events-in-func-name var output []types.EventSource err := listEventSourcesPages(ctx, conn, input, func(page *eventbridge.ListEventSourcesOutput, lastPage bool) bool { From 1745afd604591ce92a93f90ca923d53b5818cea0 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 09:12:48 -0400 Subject: [PATCH 30/35] events: Fix sweepers. --- internal/service/events/exports_test.go | 1 + internal/service/events/sweep.go | 3 +++ internal/service/events/target.go | 2 +- internal/service/events/target_migrate.go | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/internal/service/events/exports_test.go b/internal/service/events/exports_test.go index 7f3a5b5ff69..cc7f20b3ca2 100644 --- a/internal/service/events/exports_test.go +++ b/internal/service/events/exports_test.go @@ -28,4 +28,5 @@ var ( RuleCreateResourceID = ruleCreateResourceID RuleParseResourceID = ruleParseResourceID TargetParseImportID = targetParseImportID + TargetStateUpgradeV0 = targetStateUpgradeV0 ) diff --git a/internal/service/events/sweep.go b/internal/service/events/sweep.go index 9051c9a2aca..1402645a8db 100644 --- a/internal/service/events/sweep.go +++ b/internal/service/events/sweep.go @@ -356,6 +356,9 @@ func sweepTargets(region string) error { r := resourceTarget() d := r.Data(nil) d.SetId(targetCreateResourceID(eventBusName, ruleName, targetID)) + d.Set("event_bus_name", eventBusName) + d.Set("rule", ruleName) + d.Set("target_id", targetID) sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) } diff --git a/internal/service/events/target.go b/internal/service/events/target.go index 399e347dd1a..741ed1c5067 100644 --- a/internal/service/events/target.go +++ b/internal/service/events/target.go @@ -61,7 +61,7 @@ func resourceTarget() *schema.Resource { StateUpgraders: []schema.StateUpgrader{ { Type: resourceTargetV0().CoreConfigSchema().ImpliedType(), - Upgrade: TargetStateUpgradeV0, + Upgrade: targetStateUpgradeV0, Version: 0, }, }, diff --git a/internal/service/events/target_migrate.go b/internal/service/events/target_migrate.go index 952f2bdfc1e..f302b89d8f4 100644 --- a/internal/service/events/target_migrate.go +++ b/internal/service/events/target_migrate.go @@ -172,7 +172,7 @@ func resourceTargetV0() *schema.Resource { } } -func TargetStateUpgradeV0(_ context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) { +func targetStateUpgradeV0(_ context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) { if rawState == nil { rawState = map[string]interface{}{} } From 9b6885612a930405f4f01e11d1ff1f17565edb20 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 10:17:04 -0400 Subject: [PATCH 31/35] Fix golangci-lint 'staticcheck/SA4023'. --- internal/service/events/target.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/internal/service/events/target.go b/internal/service/events/target.go index 741ed1c5067..4af36729ee0 100644 --- a/internal/service/events/target.go +++ b/internal/service/events/target.go @@ -776,9 +776,7 @@ func putTargetsError(apiObjects []types.PutTargetsResultEntry) error { var errs []error for _, apiObject := range apiObjects { - if err := putTargetError(apiObject); err != nil { - errs = append(errs, fmt.Errorf("%s: %w", aws.ToString(apiObject.TargetId), err)) - } + errs = append(errs, fmt.Errorf("%s: %w", aws.ToString(apiObject.TargetId), putTargetError(apiObject))) } return errors.Join(errs...) @@ -792,9 +790,7 @@ func removeTargetsError(apiObjects []types.RemoveTargetsResultEntry) error { var errs []error for _, apiObject := range apiObjects { - if err := removeTargetError(apiObject); err != nil { - errs = append(errs, fmt.Errorf("%s: %w", aws.ToString(apiObject.TargetId), err)) - } + errs = append(errs, fmt.Errorf("%s: %w", aws.ToString(apiObject.TargetId), removeTargetError(apiObject))) } return errors.Join(errs...) From 534636194ba7cd7566e5263a579ed87f35083290 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 10:20:20 -0400 Subject: [PATCH 32/35] Cosmetics. --- internal/service/ec2/ebs_fast_snapshot_restore.go | 2 +- internal/service/ec2/errors.go | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/internal/service/ec2/ebs_fast_snapshot_restore.go b/internal/service/ec2/ebs_fast_snapshot_restore.go index 1f79ed8e9df..aa5413f3cdb 100644 --- a/internal/service/ec2/ebs_fast_snapshot_restore.go +++ b/internal/service/ec2/ebs_fast_snapshot_restore.go @@ -93,7 +93,7 @@ func (r *ebsFastSnapshotRestoreResource) Create(ctx context.Context, request res output, err := conn.EnableFastSnapshotRestores(ctx, input) if err == nil && output != nil { - err = EnableFastSnapshotRestoreItemsError(output.Unsuccessful) + err = enableFastSnapshotRestoreItemsError(output.Unsuccessful) } if err != nil { diff --git a/internal/service/ec2/errors.go b/internal/service/ec2/errors.go index aa1f4c79e07..5931dfde738 100644 --- a/internal/service/ec2/errors.go +++ b/internal/service/ec2/errors.go @@ -12,6 +12,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform-provider-aws/internal/errs" ) const ( @@ -193,19 +194,19 @@ func UnsuccessfulItemsError(apiObjects []*ec2.UnsuccessfulItem) error { return errors.Join(errs...) } -func EnableFastSnapshotRestoreStateItemError(apiObject *awstypes.EnableFastSnapshotRestoreStateError) error { +func enableFastSnapshotRestoreStateItemError(apiObject *awstypes.EnableFastSnapshotRestoreStateError) error { if apiObject == nil { return nil } - return awserr.New(aws_sdkv2.ToString(apiObject.Code), aws_sdkv2.ToString(apiObject.Message), nil) + return errs.APIError(aws_sdkv2.ToString(apiObject.Code), aws_sdkv2.ToString(apiObject.Message)) } -func EnableFastSnapshotRestoreStateItemsError(apiObjects []awstypes.EnableFastSnapshotRestoreStateErrorItem) error { +func enableFastSnapshotRestoreStateItemsError(apiObjects []awstypes.EnableFastSnapshotRestoreStateErrorItem) error { var errs []error for _, apiObject := range apiObjects { - if err := EnableFastSnapshotRestoreStateItemError(apiObject.Error); err != nil { + if err := enableFastSnapshotRestoreStateItemError(apiObject.Error); err != nil { errs = append(errs, fmt.Errorf("%s: %w", aws_sdkv2.ToString(apiObject.AvailabilityZone), err)) } } @@ -213,11 +214,11 @@ func EnableFastSnapshotRestoreStateItemsError(apiObjects []awstypes.EnableFastSn return errors.Join(errs...) } -func EnableFastSnapshotRestoreItemsError(apiObjects []awstypes.EnableFastSnapshotRestoreErrorItem) error { +func enableFastSnapshotRestoreItemsError(apiObjects []awstypes.EnableFastSnapshotRestoreErrorItem) error { var errs []error for _, apiObject := range apiObjects { - if err := EnableFastSnapshotRestoreStateItemsError(apiObject.FastSnapshotRestoreStateErrors); err != nil { + if err := enableFastSnapshotRestoreStateItemsError(apiObject.FastSnapshotRestoreStateErrors); err != nil { errs = append(errs, fmt.Errorf("%s: %w", aws_sdkv2.ToString(apiObject.SnapshotId), err)) } } From fe4c614cd80b8be65e64e9e90a6602c6bc11f370 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 10:29:02 -0400 Subject: [PATCH 33/35] Fix 'TestAccEventsRule_state'. --- internal/service/events/rule_test.go | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/internal/service/events/rule_test.go b/internal/service/events/rule_test.go index 6c59557f1db..e4e591affb2 100644 --- a/internal/service/events/rule_test.go +++ b/internal/service/events/rule_test.go @@ -637,7 +637,7 @@ func TestAccEventsRule_isEnabled(t *testing.T) { func TestAccEventsRule_state(t *testing.T) { ctx := acctest.Context(t) - var v1, v2, v3 eventbridge.DescribeRuleOutput + var v1, v2 eventbridge.DescribeRuleOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_cloudwatch_event_rule.test" @@ -675,20 +675,6 @@ func TestAccEventsRule_state(t *testing.T) { ImportState: true, ImportStateVerify: true, }, - { - Config: testAccRuleConfig_state(rName, string(types.RuleStateEnabledWithAllCloudtrailManagementEvents)), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckRuleExists(ctx, resourceName, &v3), - resource.TestCheckResourceAttr(resourceName, "is_enabled", "true"), - resource.TestCheckResourceAttr(resourceName, "state", string(types.RuleStateEnabledWithAllCloudtrailManagementEvents)), - testAccCheckRuleEnabled(ctx, resourceName, types.RuleStateEnabledWithAllCloudtrailManagementEvents), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, }, }) } From d5d5eacafe45189f473e49b8f8f699fb96fb0c00 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 10:34:27 -0400 Subject: [PATCH 34/35] Tidy up 'testAccTargetConfig_ecsPlacementStrategy'. --- internal/service/events/target_test.go | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/internal/service/events/target_test.go b/internal/service/events/target_test.go index 7807ab33404..91a4d4080e4 100644 --- a/internal/service/events/target_test.go +++ b/internal/service/events/target_test.go @@ -2113,22 +2113,13 @@ resource "aws_ecs_capacity_provider" "test" { name = %[1]q auto_scaling_group_provider { - auto_scaling_group_arn = aws_autoscaling_group.test.arn - managed_termination_protection = "DISABLED" - managed_draining = "ENABLED" - - managed_scaling { - maximum_scaling_step_size = 1 - minimum_scaling_step_size = 1 - status = "ENABLED" - target_capacity = 1 - } + auto_scaling_group_arn = aws_autoscaling_group.test.arn } } resource "aws_ecs_cluster_capacity_providers" "test" { cluster_name = aws_ecs_cluster.test.name - capacity_providers = ["%[1]s"] + capacity_providers = [%[1]q] default_capacity_provider_strategy { capacity_provider = %[1]q From 23d1281e334657a9cf5fb8e72e02ac67ee84130a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 16 Apr 2024 11:21:47 -0400 Subject: [PATCH 35/35] Fix 'TestAccEventsTarget_Input_transformer'. --- internal/service/events/target_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/events/target_test.go b/internal/service/events/target_test.go index 91a4d4080e4..42c1f724c7b 100644 --- a/internal/service/events/target_test.go +++ b/internal/service/events/target_test.go @@ -1053,7 +1053,7 @@ func TestAccEventsTarget_Input_transformer(t *testing.T) { Steps: []resource.TestStep{ { Config: testAccTargetConfig_inputTransformer(rName, tooManyInputPaths), - ExpectError: regexache.MustCompile(`.*expected number of items in.* to be less than or equal to.*`), + ExpectError: regexache.MustCompile(`Map must contain at most \d+ elements: length=\d+`), }, { Config: testAccTargetConfig_inputTransformer(rName, validInputPaths),