diff --git a/internal/acctest/acctest.go b/internal/acctest/acctest.go index aa4aff0329f..8d05da9f569 100644 --- a/internal/acctest/acctest.go +++ b/internal/acctest/acctest.go @@ -92,7 +92,12 @@ var Provider *schema.Provider var testAccProviderConfigure sync.Once func init() { - Provider = provider.Provider() + var err error + Provider, err = provider.New(context.Background()) + + if err != nil { + panic(err) + } // Always allocate a new provider instance each invocation, otherwise gRPC // ProviderConfigure() can overwrite configuration during concurrent testing. @@ -117,11 +122,16 @@ func protoV5ProviderFactoriesInit(providerNames ...string) map[string]func() (tf return factories } -func factoriesInit(providers *[]*schema.Provider, providerNames []string) map[string]func() (*schema.Provider, error) { +func factoriesInit(t *testing.T, providers *[]*schema.Provider, providerNames []string) map[string]func() (*schema.Provider, error) { + ctx := context.Background() var factories = make(map[string]func() (*schema.Provider, error), len(providerNames)) for _, name := range providerNames { - p := provider.Provider() + p, err := provider.New(ctx) + + if err != nil { + t.Fatal(err) + } factories[name] = func() (*schema.Provider, error) { //nolint:unparam return p, nil @@ -140,8 +150,8 @@ func factoriesInit(providers *[]*schema.Provider, providerNames []string) map[st // For cross-region testing: Typically paired with PreCheckMultipleRegion and ConfigAlternateRegionProvider. // // For cross-account testing: Typically paired with PreCheckAlternateAccount and ConfigAlternateAccountProvider. -func FactoriesAlternate(providers *[]*schema.Provider) map[string]func() (*schema.Provider, error) { - return factoriesInit(providers, []string{ +func FactoriesAlternate(t *testing.T, providers *[]*schema.Provider) map[string]func() (*schema.Provider, error) { + return factoriesInit(t, providers, []string{ ProviderName, ProviderNameAlternate, }) diff --git a/internal/acctest/ec2_classic.go b/internal/acctest/ec2_classic.go index 954d4a12ec4..340d3d95067 100644 --- a/internal/acctest/ec2_classic.go +++ b/internal/acctest/ec2_classic.go @@ -36,16 +36,22 @@ func PreCheckEC2Classic(t *testing.T) { // Since we are outside the scope of the Terraform configuration we must // call Configure() to properly initialize the provider configuration. testAccProviderEc2ClassicConfigure.Do(func() { - ProviderEC2Classic = provider.Provider() + ctx := context.Background() + var err error + ProviderEC2Classic, err = provider.New(ctx) + + if err != nil { + t.Fatal(err) + } config := map[string]interface{}{ "region": EC2ClassicRegion(), } - err := ProviderEC2Classic.Configure(context.Background(), terraform.NewResourceConfigRaw(config)) + diags := ProviderEC2Classic.Configure(ctx, terraform.NewResourceConfigRaw(config)) - if err != nil { - t.Fatal(err) + if diags.HasError() { + t.Fatal(diags) } }) diff --git a/internal/acctest/provider_test.go b/internal/acctest/provider_test.go index ee42761a4e9..179c432b0b2 100644 --- a/internal/acctest/provider_test.go +++ b/internal/acctest/provider_test.go @@ -1,6 +1,7 @@ package acctest_test import ( + "context" "fmt" "reflect" "strings" @@ -19,13 +20,17 @@ import ( ) func TestProvider(t *testing.T) { - if err := provider.Provider().InternalValidate(); err != nil { - t.Fatalf("err: %s", err) + p, err := provider.New(context.Background()) + + if err != nil { + t.Fatal(err) } -} -func TestProvider_impl(t *testing.T) { - var _ *schema.Provider = provider.Provider() + err = p.InternalValidate() + + if err != nil { + t.Fatal(err) + } } func TestReverseDNS(t *testing.T) { @@ -523,7 +528,12 @@ func TestAccProvider_AssumeRole_empty(t *testing.T) { // Replaces FactoriesInternal. func testAccProviderFactoriesInternal(t *testing.T, v **schema.Provider) map[string]func() (*schema.Provider, error) { //nolint:unparam - p := provider.Provider() + p, err := provider.New(context.Background()) + + if err != nil { + t.Fatal(err) + } + *v = p return map[string]func() (*schema.Provider, error){ diff --git a/internal/provider/factory.go b/internal/provider/factory.go index d470aba9e0e..0fad2b36297 100644 --- a/internal/provider/factory.go +++ b/internal/provider/factory.go @@ -12,7 +12,12 @@ import ( // ProtoV5ProviderServerFactory returns a muxed terraform-plugin-go protocol v5 provider factory function. // This factory function is suitable for use with the terraform-plugin-go Serve function. func ProtoV5ProviderServerFactory(ctx context.Context) (func() tfprotov5.ProviderServer, error) { - primary := Provider() + primary, err := New(ctx) + + if err != nil { + return nil, err + } + servers := []func() tfprotov5.ProviderServer{ primary.GRPCProvider, providerserver.NewProtocol5(fwprovider.New(primary)), diff --git a/internal/provider/fwprovider/duration.go b/internal/provider/fwprovider/duration.go index 17ae38c17d3..5f591c257b8 100644 --- a/internal/provider/fwprovider/duration.go +++ b/internal/provider/fwprovider/duration.go @@ -1,3 +1,4 @@ +// TODO: Move this to a shared 'types' package. package fwprovider import ( diff --git a/internal/provider/fwprovider/duration_test.go b/internal/provider/fwprovider/duration_test.go index 9c91be74646..b1f2ed23eb7 100644 --- a/internal/provider/fwprovider/duration_test.go +++ b/internal/provider/fwprovider/duration_test.go @@ -1,3 +1,4 @@ +// TODO: Move this to a shared 'types' package. package fwprovider_test import ( diff --git a/internal/provider/fwprovider/provider.go b/internal/provider/fwprovider/provider.go index 9403a0f119a..4ad98ab6151 100644 --- a/internal/provider/fwprovider/provider.go +++ b/internal/provider/fwprovider/provider.go @@ -6,10 +6,12 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/service/meta" "github.com/hashicorp/terraform-provider-aws/names" ) -// New returns a new Terraform Plugin Framework-style provider instance. +// New returns a new, initialized Terraform Plugin Framework-style provider instance. +// The provider instance is fully configured once the `Configure` method has been called. func New(primary interface{ Meta() interface{} }) tfsdk.Provider { return &provider{ Primary: primary, @@ -308,6 +310,16 @@ func (p *provider) GetDataSources(ctx context.Context) (map[string]tfsdk.DataSou var diags diag.Diagnostics dataSources := make(map[string]tfsdk.DataSourceType) + // TODO: This should be done via service-level self-registration and initializatin in the primary provider. + t, err := meta.NewDataSourceARNType(ctx) + + if err != nil { + diags.AddError("UhOh", err.Error()) + return nil, diags + } + + dataSources["aws_arn"] = t + return dataSources, diags } diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 04c065e59d8..19a22192286 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -191,11 +191,9 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -// Provider returns a *schema.Provider. -func Provider() *schema.Provider { - // TODO: Move the validation to this, requires conditional schemas - // TODO: Move the configuration to this, requires validation - +// New returns a new, initialized Terraform Plugin SDK v2-style provider instance. +// The provider instance is fully configured once the `ConfigureContextFunc` has been called. +func New(_ context.Context) (*schema.Provider, error) { // The actual provider provider := &schema.Provider{ // This schema must match exactly the Terraform Protocol v6 (Terraform Plugin Framework) provider's schema. @@ -740,7 +738,7 @@ func Provider() *schema.Provider { "aws_location_route_calculator": location.DataSourceRouteCalculator(), "aws_location_tracker": location.DataSourceTracker(), - "aws_arn": meta.DataSourceARN(), + // "aws_arn": meta.DataSourceARN(), // Now implemented using Terraform Plugin Framework. "aws_billing_service_account": meta.DataSourceBillingServiceAccount(), "aws_default_tags": meta.DataSourceDefaultTags(), "aws_ip_ranges": meta.DataSourceIPRanges(), @@ -2119,7 +2117,7 @@ func Provider() *schema.Provider { return providerConfigure(ctx, d, terraformVersion) } - return provider + return provider, nil } func providerConfigure(ctx context.Context, d *schema.ResourceData, terraformVersion string) (interface{}, diag.Diagnostics) { diff --git a/internal/service/apigateway/acc_test.go b/internal/service/apigateway/acc_test.go index eed22fcfced..367c616acf5 100644 --- a/internal/service/apigateway/acc_test.go +++ b/internal/service/apigateway/acc_test.go @@ -48,13 +48,19 @@ func testAccPreCheckEdgeDomainName(t *testing.T) { // Since we are outside the scope of the Terraform configuration we must // call Configure() to properly initialize the provider configuration. testAccProviderEdgeDomainNameConfigure.Do(func() { - testAccProviderEdgeDomainName = provider.Provider() + ctx := context.Background() + var err error + testAccProviderEdgeDomainName, err = provider.New(ctx) + + if err != nil { + t.Fatal(err) + } config := map[string]interface{}{ "region": region, } - diags := testAccProviderEdgeDomainName.Configure(context.Background(), terraform.NewResourceConfigRaw(config)) + diags := testAccProviderEdgeDomainName.Configure(ctx, terraform.NewResourceConfigRaw(config)) if diags != nil && diags.HasError() { for _, d := range diags { diff --git a/internal/service/cognitoidp/acc_test.go b/internal/service/cognitoidp/acc_test.go index 340052456f4..8e6a763f6cc 100644 --- a/internal/service/cognitoidp/acc_test.go +++ b/internal/service/cognitoidp/acc_test.go @@ -45,13 +45,19 @@ func testAccPreCheckUserPoolCustomDomain(t *testing.T) { // Since we are outside the scope of the Terraform configuration we must // call Configure() to properly initialize the provider configuration. testAccProviderCognitoUserPoolCustomDomainConfigure.Do(func() { - testAccProviderCognitoUserPoolCustomDomain = provider.Provider() + ctx := context.Background() + var err error + testAccProviderCognitoUserPoolCustomDomain, err = provider.New(ctx) + + if err != nil { + t.Fatal(err) + } config := map[string]interface{}{ "region": region, } - diags := testAccProviderCognitoUserPoolCustomDomain.Configure(context.Background(), terraform.NewResourceConfigRaw(config)) + diags := testAccProviderCognitoUserPoolCustomDomain.Configure(ctx, terraform.NewResourceConfigRaw(config)) if diags != nil && diags.HasError() { for _, d := range diags { diff --git a/internal/service/cur/acc_test.go b/internal/service/cur/acc_test.go index 6491f3de25b..df5ff5ba93f 100644 --- a/internal/service/cur/acc_test.go +++ b/internal/service/cur/acc_test.go @@ -40,13 +40,19 @@ func testAccPreCheck(t *testing.T) { // Since we are outside the scope of the Terraform configuration we must // call Configure() to properly initialize the provider configuration. testAccProviderCurConfigure.Do(func() { - testAccProviderCur = provider.Provider() + ctx := context.Background() + var err error + testAccProviderCur, err = provider.New(ctx) + + if err != nil { + t.Fatal(err) + } config := map[string]interface{}{ "region": testAccGetRegion(), } - diags := testAccProviderCur.Configure(context.Background(), terraform.NewResourceConfigRaw(config)) + diags := testAccProviderCur.Configure(ctx, terraform.NewResourceConfigRaw(config)) if diags != nil && diags.HasError() { for _, d := range diags { diff --git a/internal/service/directconnect/connection_confirmation_test.go b/internal/service/directconnect/connection_confirmation_test.go index 0207e0c3dd2..a1554748fd4 100644 --- a/internal/service/directconnect/connection_confirmation_test.go +++ b/internal/service/directconnect/connection_confirmation_test.go @@ -35,7 +35,7 @@ func TestAccDirectConnectConnectionConfirmation_basic(t *testing.T) { acctest.PreCheckAlternateAccount(t) }, ErrorCheck: acctest.ErrorCheck(t, directconnect.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: testAccCheckHostedConnectionDestroy(altProviderFunc), Steps: []resource.TestStep{ { diff --git a/internal/service/docdb/cluster_test.go b/internal/service/docdb/cluster_test.go index db8521133f2..434c240398d 100644 --- a/internal/service/docdb/cluster_test.go +++ b/internal/service/docdb/cluster_test.go @@ -322,7 +322,7 @@ func TestAccDocDBCluster_GlobalClusterIdentifier_PrimarySecondaryClusters(t *tes testAccPreCheckGlobalCluster(t) }, ErrorCheck: acctest.ErrorCheck(t, docdb.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: testAccCheckClusterDestroy, Steps: []resource.TestStep{ { diff --git a/internal/service/ec2/vpc_peering_connection_accepter_test.go b/internal/service/ec2/vpc_peering_connection_accepter_test.go index f0fc851e7f3..3585257ed33 100644 --- a/internal/service/ec2/vpc_peering_connection_accepter_test.go +++ b/internal/service/ec2/vpc_peering_connection_accepter_test.go @@ -80,7 +80,7 @@ func TestAccVPCPeeringConnectionAccepter_differentRegionSameAccount(t *testing.T acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: testAccVPCPeeringConnectionAccepterDestroy, Steps: []resource.TestStep{ { diff --git a/internal/service/ec2/vpc_peering_connection_options_test.go b/internal/service/ec2/vpc_peering_connection_options_test.go index 36d86fafab5..1cbb8507195 100644 --- a/internal/service/ec2/vpc_peering_connection_options_test.go +++ b/internal/service/ec2/vpc_peering_connection_options_test.go @@ -118,7 +118,7 @@ func TestAccVPCPeeringConnectionOptions_differentRegionSameAccount(t *testing.T) acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: testAccCheckVPCPeeringConnectionDestroy, Steps: []resource.TestStep{ { diff --git a/internal/service/efs/replication_configuration_test.go b/internal/service/efs/replication_configuration_test.go index 7dd4dbf0939..42aaa50fbf9 100644 --- a/internal/service/efs/replication_configuration_test.go +++ b/internal/service/efs/replication_configuration_test.go @@ -66,7 +66,7 @@ func TestAccEFSReplicationConfiguration_disappears(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, efs.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -98,7 +98,7 @@ func TestAccEFSReplicationConfiguration_allAttributes(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, efs.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { diff --git a/internal/service/fms/acc_test.go b/internal/service/fms/acc_test.go index a15aaf1a8fc..299f5697295 100644 --- a/internal/service/fms/acc_test.go +++ b/internal/service/fms/acc_test.go @@ -40,13 +40,19 @@ func testAccPreCheckAdmin(t *testing.T) { // Since we are outside the scope of the Terraform configuration we must // call Configure() to properly initialize the provider configuration. testAccProviderAdminConfigure.Do(func() { - testAccProviderAdmin = provider.Provider() + ctx := context.Background() + var err error + testAccProviderAdmin, err = provider.New(ctx) + + if err != nil { + t.Fatal(err) + } config := map[string]interface{}{ "region": testAccGetAdminRegion(), } - diags := testAccProviderAdmin.Configure(context.Background(), terraform.NewResourceConfigRaw(config)) + diags := testAccProviderAdmin.Configure(ctx, terraform.NewResourceConfigRaw(config)) if diags != nil && diags.HasError() { for _, d := range diags { diff --git a/internal/service/lightsail/acc_test.go b/internal/service/lightsail/acc_test.go index c094b887092..f5c7e788c81 100644 --- a/internal/service/lightsail/acc_test.go +++ b/internal/service/lightsail/acc_test.go @@ -32,11 +32,6 @@ var testAccProviderLightsailDomain *schema.Provider // testAccProviderLightsailDomainConfigure ensures the provider is only configured once var testAccProviderLightsailDomainConfigure sync.Once -// Prevent panic with acctest.CheckResourceDisappears -func init() { - testAccProviderLightsailDomain = provider.Provider() -} - // testAccPreCheckDomain verifies AWS credentials and that Lightsail Domains is supported func testAccPreCheckDomain(t *testing.T) { acctest.PreCheckPartitionHasService(lightsail.EndpointsID, t) @@ -50,11 +45,19 @@ func testAccPreCheckDomain(t *testing.T) { // Since we are outside the scope of the Terraform configuration we must // call Configure() to properly initialize the provider configuration. testAccProviderLightsailDomainConfigure.Do(func() { + ctx := context.Background() + var err error + testAccProviderLightsailDomain, err = provider.New(ctx) + + if err != nil { + t.Fatal(err) + } + config := map[string]interface{}{ "region": region, } - diags := testAccProviderLightsailDomain.Configure(context.Background(), terraform.NewResourceConfigRaw(config)) + diags := testAccProviderLightsailDomain.Configure(ctx, terraform.NewResourceConfigRaw(config)) if diags != nil && diags.HasError() { for _, d := range diags { diff --git a/internal/service/meta/arn.go b/internal/service/meta/arn.go new file mode 100644 index 00000000000..d5b16470a7b --- /dev/null +++ b/internal/service/meta/arn.go @@ -0,0 +1,175 @@ +// TODO: Move this to a shared 'types' package. +package meta + +import ( + "context" + "fmt" + + "github.com/aws/aws-sdk-go-v2/aws/arn" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +type arnType uint8 + +const ( + ARNType arnType = iota +) + +var ( + _ xattr.TypeWithValidate = ARNType +) + +func (t arnType) TerraformType(_ context.Context) tftypes.Type { + return tftypes.String +} + +func (t arnType) ValueFromTerraform(_ context.Context, in tftypes.Value) (attr.Value, error) { + if !in.IsKnown() { + return ARN{Unknown: true}, nil + } + if in.IsNull() { + return ARN{Null: true}, nil + } + var s string + err := in.As(&s) + if err != nil { + return nil, err + } + a, err := arn.Parse(s) + if err != nil { + return nil, err + } + return ARN{Value: a}, nil +} + +// Equal returns true if `o` is also an ARNType. +func (t arnType) Equal(o attr.Type) bool { + _, ok := o.(arnType) + return ok +} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// type. +func (t arnType) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return nil, fmt.Errorf("cannot apply AttributePathStep %T to %s", step, t.String()) +} + +// String returns a human-friendly description of the ARNType. +func (t arnType) String() string { + return "types.ARNType" +} + +// Validate implements type validation. +func (t arnType) Validate(ctx context.Context, in tftypes.Value, path path.Path) diag.Diagnostics { + var diags diag.Diagnostics + + if !in.Type().Is(tftypes.String) { + diags.AddAttributeError( + path, + "ARN Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Expected String value, received %T with value: %v", in, in), + ) + return diags + } + + if !in.IsKnown() || in.IsNull() { + return diags + } + + var value string + err := in.As(&value) + if err != nil { + diags.AddAttributeError( + path, + "ARN Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Cannot convert value to arn.ARN: %s", err), + ) + return diags + } + + if !arn.IsARN(value) { + diags.AddAttributeError( + path, + "ARN Type Validation Error", + fmt.Sprintf("Value %q cannot be parsed as an ARN.", value), + ) + return diags + } + + return diags +} + +func (t arnType) Description() string { + return `An Amazon Resource Name.` +} + +type ARN struct { + Unknown bool + Null bool + Value arn.ARN +} + +func (a ARN) Type(_ context.Context) attr.Type { + return ARNType +} + +func (a ARN) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + t := ARNType.TerraformType(ctx) + if a.Null { + return tftypes.NewValue(t, nil), nil + } + if a.Unknown { + return tftypes.NewValue(t, tftypes.UnknownValue), nil + } + return tftypes.NewValue(t, a.Value.String()), nil +} + +// Equal returns true if `other` is a *ARN and has the same value as `a`. +func (a ARN) Equal(other attr.Value) bool { + o, ok := other.(ARN) + if !ok { + return false + } + if a.Unknown != o.Unknown { + return false + } + if a.Null != o.Null { + return false + } + return a.Value == o.Value +} + +// IsNull returns true if the Value is not set, or is explicitly set to null. +func (a ARN) IsNull() bool { + return a.Null +} + +// IsUnknown returns true if the Value is not yet known. +func (a ARN) IsUnknown() bool { + return a.Unknown +} + +// String returns a summary representation of either the underlying Value, +// or UnknownValueString (``) when IsUnknown() returns true, +// or NullValueString (``) when IsNull() return true. +// +// This is an intentionally lossy representation, that are best suited for +// logging and error reporting, as they are not protected by +// compatibility guarantees within the framework. +func (a ARN) String() string { + if a.IsUnknown() { + return attr.UnknownValueString + } + + if a.IsNull() { + return attr.NullValueString + } + + return a.Value.String() +} diff --git a/internal/service/meta/arn_data_source_fw.go b/internal/service/meta/arn_data_source_fw.go new file mode 100644 index 00000000000..beebfa77b6b --- /dev/null +++ b/internal/service/meta/arn_data_source_fw.go @@ -0,0 +1,110 @@ +// Code generated by tools/tfsdk2fw/main.go. Manual editing is required. + +package meta + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +// TODO: Remove +var NewDataSourceARNType = newDataSourceARNType + +func init() { + registerDataSourceTypeFactory("aws_arn", newDataSourceARNType) +} + +// newDataSourceARNType instantiates a new DataSourceType for the aws_arn data source. +func newDataSourceARNType(ctx context.Context) (tfsdk.DataSourceType, error) { + return &dataSourceARNType{}, nil +} + +type dataSourceARNType struct{} + +// GetSchema returns the schema for this data source. +func (t *dataSourceARNType) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) { + schema := tfsdk.Schema{ + Attributes: map[string]tfsdk.Attribute{ + "account": { + Type: types.StringType, + Computed: true, + }, + "arn": { + Type: ARNType, + Required: true, + }, + "id": { + Type: types.StringType, + Optional: true, + Computed: true, + }, + "partition": { + Type: types.StringType, + Computed: true, + }, + "region": { + Type: types.StringType, + Computed: true, + }, + "resource": { + Type: types.StringType, + Computed: true, + }, + "service": { + Type: types.StringType, + Computed: true, + }, + }, + } + + return schema, nil +} + +// NewDataSource instantiates a new DataSource of this DataSourceType. +func (t *dataSourceARNType) NewDataSource(ctx context.Context, provider tfsdk.Provider) (tfsdk.DataSource, diag.Diagnostics) { + return &dataSourceARN{}, nil +} + +type dataSourceARN struct{} + +// Read is called when the provider must read data source values in order to update state. +// Config values should be read from the ReadDataSourceRequest and new state values set on the ReadDataSourceResponse. +func (d *dataSourceARN) Read(ctx context.Context, request tfsdk.ReadDataSourceRequest, response *tfsdk.ReadDataSourceResponse) { + tflog.Trace(ctx, "dataSourceARN.Read enter") + + var config dataSourceARNData + + response.Diagnostics.Append(request.Config.Get(ctx, &config)...) + + if response.Diagnostics.HasError() { + return + } + + state := config + arn := &state.ARN.Value + id := arn.String() + + state.Account = &arn.AccountID + state.ID = &id + state.Partition = &arn.Partition + state.Region = &arn.Region + state.Resource = &arn.Resource + state.Service = &arn.Service + + response.Diagnostics.Append(response.State.Set(ctx, &state)...) +} + +// TODO: Generate this structure definition. +type dataSourceARNData struct { + Account *string `tfsdk:"account"` + ARN ARN `tfsdk:"arn"` + ID *string `tfsdk:"id"` + Partition *string `tfsdk:"partition"` + Region *string `tfsdk:"region"` + Resource *string `tfsdk:"resource"` + Service *string `tfsdk:"service"` +} diff --git a/internal/service/meta/arn_test.go b/internal/service/meta/arn_test.go new file mode 100644 index 00000000000..9c46659b2a9 --- /dev/null +++ b/internal/service/meta/arn_test.go @@ -0,0 +1,111 @@ +// TODO: Move this to a shared 'types' package. +package meta_test + +import ( + "context" + "testing" + + "github.com/aws/aws-sdk-go-v2/aws/arn" + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" + "github.com/hashicorp/terraform-provider-aws/internal/service/meta" +) + +func TestARNTypeValueFromTerraform(t *testing.T) { + t.Parallel() + + tests := map[string]struct { + val tftypes.Value + expected attr.Value + expectError bool + }{ + "null value": { + val: tftypes.NewValue(tftypes.String, nil), + expected: meta.ARN{Null: true}, + }, + "unknown value": { + val: tftypes.NewValue(tftypes.String, tftypes.UnknownValue), + expected: meta.ARN{Unknown: true}, + }, + "valid ARN": { + val: tftypes.NewValue(tftypes.String, "arn:aws:rds:us-east-1:123456789012:db:test"), // lintignore:AWSAT003,AWSAT005 + expected: meta.ARN{Value: arn.ARN{ + Partition: "aws", + Service: "rds", + Region: "us-east-1", // lintignore:AWSAT003 + AccountID: "123456789012", + Resource: "db:test", + }}, + }, + "invalid duration": { + val: tftypes.NewValue(tftypes.String, "not ok"), + expectError: true, + }, + } + + for name, test := range tests { + name, test := name, test + t.Run(name, func(t *testing.T) { + ctx := context.TODO() + val, err := meta.ARNType.ValueFromTerraform(ctx, test.val) + + if err == nil && test.expectError { + t.Fatal("expected error, got no error") + } + if err != nil && !test.expectError { + t.Fatalf("got unexpected error: %s", err) + } + + if diff := cmp.Diff(val, test.expected); diff != "" { + t.Errorf("unexpected diff (+wanted, -got): %s", diff) + } + }) + } +} + +func TestARNTypeValidate(t *testing.T) { + t.Parallel() + + type testCase struct { + val tftypes.Value + expectError bool + } + tests := map[string]testCase{ + "not a string": { + val: tftypes.NewValue(tftypes.Bool, true), + expectError: true, + }, + "unknown string": { + val: tftypes.NewValue(tftypes.String, tftypes.UnknownValue), + }, + "null string": { + val: tftypes.NewValue(tftypes.String, nil), + }, + "valid string": { + val: tftypes.NewValue(tftypes.String, "arn:aws:rds:us-east-1:123456789012:db:test"), // lintignore:AWSAT003,AWSAT005 + }, + "invalid string": { + val: tftypes.NewValue(tftypes.String, "not ok"), + expectError: true, + }, + } + + for name, test := range tests { + name, test := name, test + t.Run(name, func(t *testing.T) { + ctx := context.TODO() + + diags := meta.ARNType.Validate(ctx, test.val, path.Root("test")) + + if !diags.HasError() && test.expectError { + t.Fatal("expected error, got no error") + } + + if diags.HasError() && !test.expectError { + t.Fatalf("got unexpected error: %#v", diags) + } + }) + } +} diff --git a/internal/service/meta/svcimpl.go b/internal/service/meta/svcimpl.go new file mode 100644 index 00000000000..82422e746bc --- /dev/null +++ b/internal/service/meta/svcimpl.go @@ -0,0 +1,10 @@ +package meta + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +func registerDataSourceTypeFactory(name string, factory func(context.Context) (tfsdk.DataSourceType, error)) { +} diff --git a/internal/service/pricing/acc_test.go b/internal/service/pricing/acc_test.go index 73024ae7f94..f079426d083 100644 --- a/internal/service/pricing/acc_test.go +++ b/internal/service/pricing/acc_test.go @@ -37,13 +37,19 @@ func testAccPreCheck(t *testing.T) { // Since we are outside the scope of the Terraform configuration we must // call Configure() to properly initialize the provider configuration. testAccProviderPricingConfigure.Do(func() { - testAccProviderPricing = provider.Provider() + ctx := context.Background() + var err error + testAccProviderPricing, err = provider.New(ctx) + + if err != nil { + t.Fatal(err) + } config := map[string]interface{}{ "region": testAccGetRegion(), } - diags := testAccProviderPricing.Configure(context.Background(), terraform.NewResourceConfigRaw(config)) + diags := testAccProviderPricing.Configure(ctx, terraform.NewResourceConfigRaw(config)) if diags != nil && diags.HasError() { for _, d := range diags { diff --git a/internal/service/rds/cluster_test.go b/internal/service/rds/cluster_test.go index 7f4ef3bcb29..bab9c304ab5 100644 --- a/internal/service/rds/cluster_test.go +++ b/internal/service/rds/cluster_test.go @@ -860,7 +860,7 @@ func TestAccRDSCluster_ReplicationSourceIdentifier_kmsKeyID(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckClusterDestroyWithProvider, &providers), Steps: []resource.TestStep{ { @@ -1299,7 +1299,7 @@ func TestAccRDSCluster_GlobalClusterIdentifier_primarySecondaryClusters(t *testi testAccPreCheckGlobalCluster(t) }, ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: testAccCheckClusterDestroy, Steps: []resource.TestStep{ { @@ -1333,7 +1333,7 @@ func TestAccRDSCluster_GlobalClusterIdentifier_replicationSourceIdentifier(t *te testAccPreCheckGlobalCluster(t) }, ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: testAccCheckClusterDestroy, Steps: []resource.TestStep{ { @@ -1370,7 +1370,7 @@ func TestAccRDSCluster_GlobalClusterIdentifier_secondaryClustersWriteForwarding( testAccPreCheckGlobalCluster(t) }, ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: testAccCheckClusterDestroy, Steps: []resource.TestStep{ { diff --git a/internal/service/route53/key_signing_key_test.go b/internal/service/route53/key_signing_key_test.go index b1151c3b9ce..e133cd82dc1 100644 --- a/internal/service/route53/key_signing_key_test.go +++ b/internal/service/route53/key_signing_key_test.go @@ -288,13 +288,19 @@ func testAccPreCheckKeySigningKey(t *testing.T) { // Since we are outside the scope of the Terraform configuration we must // call Configure() to properly initialize the provider configuration. testAccProviderRoute53KeySigningKeyConfigure.Do(func() { - testAccProviderRoute53KeySigningKey = provider.Provider() + ctx := context.Background() + var err error + testAccProviderRoute53KeySigningKey, err = provider.New(ctx) + + if err != nil { + t.Fatal(err) + } testAccRecordConfig_config := map[string]interface{}{ "region": region, } - diags := testAccProviderRoute53KeySigningKey.Configure(context.Background(), terraform.NewResourceConfigRaw(testAccRecordConfig_config)) + diags := testAccProviderRoute53KeySigningKey.Configure(ctx, terraform.NewResourceConfigRaw(testAccRecordConfig_config)) if diags != nil && diags.HasError() { for _, d := range diags { diff --git a/internal/service/route53/query_log_test.go b/internal/service/route53/query_log_test.go index 07925e9771a..c65294b07dd 100644 --- a/internal/service/route53/query_log_test.go +++ b/internal/service/route53/query_log_test.go @@ -238,13 +238,19 @@ func testAccPreCheckQueryLog(t *testing.T) { // Since we are outside the scope of the Terraform configuration we must // call Configure() to properly initialize the provider configuration. testAccProviderRoute53QueryLogConfigure.Do(func() { - testAccProviderRoute53QueryLog = provider.Provider() + ctx := context.Background() + var err error + testAccProviderRoute53QueryLog, err = provider.New(ctx) + + if err != nil { + t.Fatal(err) + } testAccRecordConfig_config := map[string]interface{}{ "region": region, } - diags := testAccProviderRoute53QueryLog.Configure(context.Background(), terraform.NewResourceConfigRaw(testAccRecordConfig_config)) + diags := testAccProviderRoute53QueryLog.Configure(ctx, terraform.NewResourceConfigRaw(testAccRecordConfig_config)) if diags != nil && diags.HasError() { for _, d := range diags { diff --git a/internal/service/s3/bucket_replication_configuration_test.go b/internal/service/s3/bucket_replication_configuration_test.go index b93675162de..3f2db55cd0c 100644 --- a/internal/service/s3/bucket_replication_configuration_test.go +++ b/internal/service/s3/bucket_replication_configuration_test.go @@ -33,7 +33,7 @@ func TestAccS3BucketReplicationConfiguration_basic(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -130,7 +130,7 @@ func TestAccS3BucketReplicationConfiguration_multipleDestinationsEmptyFilter(t * acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -189,7 +189,7 @@ func TestAccS3BucketReplicationConfiguration_multipleDestinationsNonEmptyFilter( acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -254,7 +254,7 @@ func TestAccS3BucketReplicationConfiguration_twoDestination(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -308,7 +308,7 @@ func TestAccS3BucketReplicationConfiguration_configurationRuleDestinationAccessC acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -385,7 +385,7 @@ func TestAccS3BucketReplicationConfiguration_configurationRuleDestinationAddAcce acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -453,7 +453,7 @@ func TestAccS3BucketReplicationConfiguration_replicationTimeControl(t *testing.T acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -506,7 +506,7 @@ func TestAccS3BucketReplicationConfiguration_replicaModifications(t *testing.T) acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -554,7 +554,7 @@ func TestAccS3BucketReplicationConfiguration_withoutId(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -595,7 +595,7 @@ func TestAccS3BucketReplicationConfiguration_withoutStorageClass(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -637,7 +637,7 @@ func TestAccS3BucketReplicationConfiguration_schemaV2(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -681,7 +681,7 @@ func TestAccS3BucketReplicationConfiguration_schemaV2SameRegion(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -725,7 +725,7 @@ func TestAccS3BucketReplicationConfiguration_schemaV2DestinationMetrics(t *testi acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -764,7 +764,7 @@ func TestAccS3BucketReplicationConfiguration_existingObjectReplication(t *testin resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -810,7 +810,7 @@ func TestAccS3BucketReplicationConfiguration_filter_emptyConfigurationBlock(t *t resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -852,7 +852,7 @@ func TestAccS3BucketReplicationConfiguration_filter_emptyPrefix(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -898,7 +898,7 @@ func TestAccS3BucketReplicationConfiguration_filter_tagFilter(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -942,7 +942,7 @@ func TestAccS3BucketReplicationConfiguration_filter_andOperator(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -1017,7 +1017,7 @@ func TestAccS3BucketReplicationConfiguration_filter_withoutId(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -1054,7 +1054,7 @@ func TestAccS3BucketReplicationConfiguration_withoutPrefix(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -1084,7 +1084,7 @@ func TestAccS3BucketReplicationConfiguration_migrate_noChange(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { @@ -1126,7 +1126,7 @@ func TestAccS3BucketReplicationConfiguration_migrate_withChange(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketReplicationConfigurationDestroy, &providers), Steps: []resource.TestStep{ { diff --git a/internal/service/s3/bucket_test.go b/internal/service/s3/bucket_test.go index d5af6e399e6..de8e84c2864 100644 --- a/internal/service/s3/bucket_test.go +++ b/internal/service/s3/bucket_test.go @@ -1135,7 +1135,7 @@ func TestAccS3Bucket_Replication_basic(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketDestroyWithProvider, &providers), Steps: []resource.TestStep{ { @@ -1186,7 +1186,7 @@ func TestAccS3Bucket_Replication_multipleDestinationsEmptyFilter(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketDestroyWithProvider, &providers), Steps: []resource.TestStep{ { @@ -1253,7 +1253,7 @@ func TestAccS3Bucket_Replication_multipleDestinationsNonEmptyFilter(t *testing.T acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketDestroyWithProvider, &providers), Steps: []resource.TestStep{ { @@ -1324,7 +1324,7 @@ func TestAccS3Bucket_Replication_twoDestination(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketDestroyWithProvider, &providers), Steps: []resource.TestStep{ { @@ -1382,7 +1382,7 @@ func TestAccS3Bucket_Replication_ruleDestinationAccessControlTranslation(t *test acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketDestroyWithProvider, &providers), Steps: []resource.TestStep{ { @@ -1430,7 +1430,7 @@ func TestAccS3Bucket_Replication_ruleDestinationAddAccessControlTranslation(t *t acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketDestroyWithProvider, &providers), Steps: []resource.TestStep{ { @@ -1478,7 +1478,7 @@ func TestAccS3Bucket_Replication_withoutStorageClass(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketDestroyWithProvider, &providers), Steps: []resource.TestStep{ { @@ -1511,7 +1511,7 @@ func TestAccS3Bucket_Replication_expectVersioningValidationError(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketDestroyWithProvider, &providers), Steps: []resource.TestStep{ { @@ -1538,7 +1538,7 @@ func TestAccS3Bucket_Replication_withoutPrefix(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketDestroyWithProvider, &providers), Steps: []resource.TestStep{ { @@ -1575,7 +1575,7 @@ func TestAccS3Bucket_Replication_schemaV2(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketDestroyWithProvider, &providers), Steps: []resource.TestStep{ { @@ -1690,7 +1690,7 @@ func TestAccS3Bucket_Replication_RTC_valid(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), - ProviderFactories: acctest.FactoriesAlternate(&providers), + ProviderFactories: acctest.FactoriesAlternate(t, &providers), CheckDestroy: acctest.CheckWithProviders(testAccCheckBucketDestroyWithProvider, &providers), Steps: []resource.TestStep{ { diff --git a/internal/service/waf/acc_test.go b/internal/service/waf/acc_test.go index e3f0387287c..f2822af2aff 100644 --- a/internal/service/waf/acc_test.go +++ b/internal/service/waf/acc_test.go @@ -45,13 +45,19 @@ func testAccPreCheckLoggingConfiguration(t *testing.T) { // Since we are outside the scope of the Terraform configuration we must // call Configure() to properly initialize the provider configuration. testAccProviderWafLoggingConfigurationConfigure.Do(func() { - testAccProviderWafLoggingConfiguration = provider.Provider() + ctx := context.Background() + var err error + testAccProviderWafLoggingConfiguration, err = provider.New(ctx) + + if err != nil { + t.Fatal(err) + } config := map[string]interface{}{ "region": region, } - diags := testAccProviderWafLoggingConfiguration.Configure(context.Background(), terraform.NewResourceConfigRaw(config)) + diags := testAccProviderWafLoggingConfiguration.Configure(ctx, terraform.NewResourceConfigRaw(config)) if diags != nil && diags.HasError() { for _, d := range diags { diff --git a/tools/tfsdk2fw/datasource.tmpl b/tools/tfsdk2fw/datasource.tmpl index 7e3292e5506..fcd6c58257e 100644 --- a/tools/tfsdk2fw/datasource.tmpl +++ b/tools/tfsdk2fw/datasource.tmpl @@ -1,20 +1,24 @@ -// Code generated by tools/tfsdk2fx/main.go. Manual editing is required. +// Code generated by tools/tfsdk2fw/main.go. Manual editing is required. -package TODO +package {{ .PackageName }} import ( "context" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/hashicorp/terraform-plugin-framework/types" "github.com/hashicorp/terraform-plugin-log/tflog" ) func init() { - // registerDataSourceType(TODO, &dataSource{{ .Name }}Type{}) + registerDataSourceTypeFactory("{{ .TFTypeName }}", newDataSource{{ .Name }}Type) } -var _ tfsdk.DataSourceType = &dataSource{{ .Name }}Type{} +// newDataSource{{ .Name }}Type instantiates a new DataSourceType for the {{ .TFTypeName }} data source. +func newDataSource{{ .Name }}Type(ctx context.Context) (tfsdk.DataSourceType, error) { + return &dataSource{{ .Name }}Type{}, nil +} type dataSource{{ .Name }}Type struct {} @@ -34,4 +38,6 @@ type dataSource{{ .Name }} struct {} // Read is called when the provider must read data source values in order to update state. // Config values should be read from the ReadDataSourceRequest and new state values set on the ReadDataSourceResponse. -func (d *dataSource{{ .Name }}) Read(ctx context.Context, request tfsdk.ReadDataSourceRequest, response *tfsdk.ReadDataSourceResponse) {} \ No newline at end of file +func (d *dataSource{{ .Name }}) Read(ctx context.Context, request tfsdk.ReadDataSourceRequest, response *tfsdk.ReadDataSourceResponse) { + tflog.Trace(ctx, "dataSource{{ .Name }}.Read enter") +} \ No newline at end of file diff --git a/tools/tfsdk2fw/main.go b/tools/tfsdk2fw/main.go index 34f26cdf02b..5f43596a2ac 100644 --- a/tools/tfsdk2fw/main.go +++ b/tools/tfsdk2fw/main.go @@ -25,7 +25,7 @@ var ( func usage() { fmt.Fprintf(os.Stderr, "Usage:\n") - fmt.Fprintf(os.Stderr, "\ttfsdk2fx [-resource |-data-source ] \n\n") + fmt.Fprintf(os.Stderr, "\ttfsdk2fw [-resource |-data-source ] \n\n") } func main() { @@ -34,13 +34,14 @@ func main() { args := flag.Args() - if len(args) < 2 || (*dataSourceType == "" && *resourceType == "") { + if len(args) < 3 || (*dataSourceType == "" && *resourceType == "") { flag.Usage() os.Exit(2) } - name := args[0] - outputFilename := args[1] + packageName := args[0] + name := args[1] + outputFilename := args[2] ui := &cli.BasicUi{ Reader: os.Stdin, @@ -48,8 +49,9 @@ func main() { ErrorWriter: os.Stderr, } migrator := &migrator{ - Name: name, - Ui: ui, + Name: name, + PackageName: packageName, + Ui: ui, } p := provider.Provider() @@ -64,6 +66,7 @@ func main() { migrator.Resource = resource migrator.Template = datasourceImpl + migrator.TFTypeName = v } else if v := *resourceType; v != "" { resource, ok := p.ResourcesMap[v] @@ -74,6 +77,7 @@ func main() { migrator.Resource = resource migrator.Template = resourceImpl + migrator.TFTypeName = v } if err := migrator.migrate(outputFilename); err != nil { @@ -83,10 +87,12 @@ func main() { } type migrator struct { - Name string - Resource *schema.Resource - Template string - Ui cli.Ui + Name string + PackageName string + Resource *schema.Resource + Template string + TFTypeName string + Ui cli.Ui } // migrate generates an identical schema into the specified output file. @@ -169,8 +175,10 @@ func (m *migrator) generateTemplateData() (*templateData, error) { schema := sb.String() templateData := &templateData{ - Name: m.Name, - Schema: schema, + Name: m.Name, + PackageName: m.PackageName, + Schema: schema, + TFTypeName: m.TFTypeName, } return templateData, nil @@ -407,6 +415,10 @@ func (e emitter) emitAttribute(path []string, property *schema.Schema) error { } } + if property.ValidateFunc != nil || property.ValidateDiagFunc != nil { + fprintf(e.SchemaWriter, "// TODO Validate,\n") + } + fprintf(e.SchemaWriter, "}") return nil @@ -539,8 +551,10 @@ func unsupportedTypeError(path []string, typ string) error { } type templateData struct { - Name string - Schema string + Name string // e.g. Instance + PackageName string // e.g. ec2 + Schema string + TFTypeName string // e.g. aws_instance } //go:embed datasource.tmpl diff --git a/tools/tfsdk2fw/resource.tmpl b/tools/tfsdk2fw/resource.tmpl index 8c81b465a1d..7a2aacf3b54 100644 --- a/tools/tfsdk2fw/resource.tmpl +++ b/tools/tfsdk2fw/resource.tmpl @@ -1 +1 @@ -// Code generated by tools/tfsdk2fx/main.go. Manual editing is required. +// Code generated by tools/tfsdk2fw/main.go. Manual editing is required.