From ac90449bdd4782e0c58930b638cb3e8f4e313725 Mon Sep 17 00:00:00 2001 From: "Jonas L." Date: Thu, 12 Sep 2024 15:34:23 +0200 Subject: [PATCH] refactor: move data.hcloud_server_type(s) to Plugin Framework (#959) Related to #752 --- hcloud/plugin_provider.go | 3 + hcloud/provider.go | 3 - hcloud/provider_test.go | 3 - internal/servertype/data_source.go | 458 ++++++++++++++++-------- internal/servertype/data_source.md | 15 + internal/servertype/data_source_list.md | 15 + internal/servertype/data_source_test.go | 79 ++++ 7 files changed, 412 insertions(+), 164 deletions(-) create mode 100644 internal/servertype/data_source.md create mode 100644 internal/servertype/data_source_list.md diff --git a/hcloud/plugin_provider.go b/hcloud/plugin_provider.go index 29b3c22bb..c4f5b12ee 100644 --- a/hcloud/plugin_provider.go +++ b/hcloud/plugin_provider.go @@ -20,6 +20,7 @@ import ( "github.com/hetznercloud/hcloud-go/hcloud" "github.com/hetznercloud/terraform-provider-hcloud/internal/datacenter" "github.com/hetznercloud/terraform-provider-hcloud/internal/location" + "github.com/hetznercloud/terraform-provider-hcloud/internal/servertype" "github.com/hetznercloud/terraform-provider-hcloud/internal/sshkey" "github.com/hetznercloud/terraform-provider-hcloud/internal/util/tflogutil" ) @@ -172,6 +173,8 @@ func (p *PluginProvider) DataSources(_ context.Context) []func() datasource.Data datacenter.NewDataSourceList, location.NewDataSource, location.NewDataSourceList, + servertype.NewDataSource, + servertype.NewDataSourceList, sshkey.NewDataSource, sshkey.NewDataSourceList, } diff --git a/hcloud/provider.go b/hcloud/provider.go index e31cbca05..30a553a0e 100644 --- a/hcloud/provider.go +++ b/hcloud/provider.go @@ -27,7 +27,6 @@ import ( "github.com/hetznercloud/terraform-provider-hcloud/internal/network" "github.com/hetznercloud/terraform-provider-hcloud/internal/rdns" "github.com/hetznercloud/terraform-provider-hcloud/internal/server" - "github.com/hetznercloud/terraform-provider-hcloud/internal/servertype" "github.com/hetznercloud/terraform-provider-hcloud/internal/volume" ) @@ -118,8 +117,6 @@ func Provider() *schema.Provider { placementgroup.DataSourceListType: placementgroup.DataSourceList(), server.DataSourceType: server.DataSource(), server.DataSourceListType: server.DataSourceList(), - servertype.DataSourceType: servertype.DataSource(), - servertype.DataSourceListType: servertype.ServerTypesDataSource(), volume.DataSourceType: volume.DataSource(), volume.DataSourceListType: volume.DataSourceList(), }, diff --git a/hcloud/provider_test.go b/hcloud/provider_test.go index 11447900d..7a2f7fc02 100644 --- a/hcloud/provider_test.go +++ b/hcloud/provider_test.go @@ -13,7 +13,6 @@ import ( "github.com/hetznercloud/terraform-provider-hcloud/internal/primaryip" "github.com/hetznercloud/terraform-provider-hcloud/internal/rdns" "github.com/hetznercloud/terraform-provider-hcloud/internal/server" - "github.com/hetznercloud/terraform-provider-hcloud/internal/servertype" "github.com/hetznercloud/terraform-provider-hcloud/internal/snapshot" "github.com/hetznercloud/terraform-provider-hcloud/internal/volume" "github.com/stretchr/testify/assert" @@ -81,8 +80,6 @@ func TestProvider_DataSources(t *testing.T) { placementgroup.DataSourceListType, server.DataSourceType, server.DataSourceListType, - servertype.DataSourceType, - servertype.DataSourceListType, volume.DataSourceType, volume.DataSourceListType, } diff --git a/internal/servertype/data_source.go b/internal/servertype/data_source.go index 3b0d3e9dd..691391a1f 100644 --- a/internal/servertype/data_source.go +++ b/internal/servertype/data_source.go @@ -2,212 +2,354 @@ package servertype import ( "context" + _ "embed" "strconv" - "time" "github.com/hetznercloud/terraform-provider-hcloud/internal/deprecation" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hetznercloud/hcloud-go/hcloud" "github.com/hetznercloud/terraform-provider-hcloud/internal/util/datasourceutil" "github.com/hetznercloud/terraform-provider-hcloud/internal/util/hcloudutil" + "github.com/hetznercloud/terraform-provider-hcloud/internal/util/merge" ) const ( - // DataSourceType is the type name of the Hetzner Cloud Server Type - // data source. + // DataSourceType is the type name of the Hetzner Cloud server type datasource. DataSourceType = "hcloud_server_type" - // ServerTypesDataSourceType is the type name of the Hetzner Cloud Server Types - // data source. + // DataSourceListType is the type name of the Hetzner Cloud server type list datasource. DataSourceListType = "hcloud_server_types" ) -// getCommonDataSchema returns a new common schema used by all server type data sources. -func getCommonDataSchema() map[string]*schema.Schema { - return deprecation.AddToSchema(map[string]*schema.Schema{ - "id": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "name": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "description": { - Type: schema.TypeString, - Computed: true, - }, - "cores": { - Type: schema.TypeInt, - Computed: true, - }, - "memory": { - Type: schema.TypeInt, - Computed: true, - }, - "disk": { - Type: schema.TypeInt, - Computed: true, - }, - "storage_type": { - Type: schema.TypeString, - Computed: true, - }, - "cpu_type": { - Type: schema.TypeString, - Computed: true, - }, - "architecture": { - Type: schema.TypeString, - Computed: true, - }, - "included_traffic": { - Type: schema.TypeInt, - Deprecated: "The field is deprecated and will always report 0 after 2024-08-05.", - Computed: true, - }, - }) +type resourceData struct { + ID types.Int64 `tfsdk:"id"` + Name types.String `tfsdk:"name"` + Description types.String `tfsdk:"description"` + Cores types.Int32 `tfsdk:"cores"` + Memory types.Int32 `tfsdk:"memory"` + Disk types.Int32 `tfsdk:"disk"` + StorageType types.String `tfsdk:"storage_type"` + CPUType types.String `tfsdk:"cpu_type"` + Architecture types.String `tfsdk:"architecture"` + IncludedTraffic types.Int64 `tfsdk:"included_traffic"` + + deprecation.DeprecationModel } -// DataSource creates a new Terraform schema for the hcloud_server_type data -// source. -func DataSource() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceHcloudServerTypeRead, - Schema: getCommonDataSchema(), - } +var resourceDataAttrTypes = merge.Maps( + map[string]attr.Type{ + "id": types.Int64Type, + "name": types.StringType, + "description": types.StringType, + "cores": types.Int32Type, + "memory": types.Int32Type, + "disk": types.Int32Type, + "storage_type": types.StringType, + "cpu_type": types.StringType, + "architecture": types.StringType, + "included_traffic": types.Int64Type, + }, + deprecation.AttrTypes(), +) + +func newResourceData(ctx context.Context, in *hcloud.ServerType) (resourceData, diag.Diagnostics) { + var data resourceData + var diags diag.Diagnostics + var newDiags diag.Diagnostics + + data.ID = types.Int64Value(int64(in.ID)) + data.Name = types.StringValue(in.Name) + data.Description = types.StringValue(in.Description) + data.Cores = types.Int32Value(int32(in.Cores)) + data.Memory = types.Int32Value(int32(in.Memory)) + data.Disk = types.Int32Value(int32(in.Disk)) + data.StorageType = types.StringValue(string(in.StorageType)) + data.CPUType = types.StringValue(string(in.CPUType)) + data.Architecture = types.StringValue(string(in.Architecture)) + data.IncludedTraffic = types.Int64Value(in.IncludedTraffic) // nolint:staticcheck // Keep as long as it is available + + data.DeprecationModel, newDiags = deprecation.NewDeprecationModel(ctx, in) + diags.Append(newDiags...) + + return data, diags } -// ServerTypesDataSource creates a new Terraform schema for the -// hcloud_server_types data source. -func ServerTypesDataSource() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceHcloudServerTypeListRead, - Schema: map[string]*schema.Schema{ - "server_types": { - Type: schema.TypeList, +func getCommonDataSchema() map[string]schema.Attribute { + return merge.Maps( + map[string]schema.Attribute{ + "id": schema.Int64Attribute{ + Optional: true, Computed: true, - Elem: &schema.Resource{ - Schema: getCommonDataSchema(), - }, }, - "server_type_ids": { - Type: schema.TypeList, - Optional: true, - Deprecated: "Use server_types list instead", - Elem: &schema.Schema{Type: schema.TypeString}, + "name": schema.StringAttribute{ + Optional: true, + Computed: true, }, - "names": { - Type: schema.TypeList, - Computed: true, - Deprecated: "Use server_types list instead", - Elem: &schema.Schema{Type: schema.TypeString}, + "description": schema.StringAttribute{ + Computed: true, }, - "descriptions": { - Type: schema.TypeList, - Computed: true, - Deprecated: "Use server_types list instead", - Elem: &schema.Schema{Type: schema.TypeString}, + "cores": schema.Int32Attribute{ + Computed: true, + }, + "memory": schema.Int32Attribute{ + Computed: true, + }, + "disk": schema.Int32Attribute{ + Computed: true, + }, + "storage_type": schema.StringAttribute{ + Computed: true, + }, + "cpu_type": schema.StringAttribute{ + Computed: true, + }, + "architecture": schema.StringAttribute{ + Computed: true, + }, + "included_traffic": schema.Int64Attribute{ + Computed: true, + DeprecationMessage: "The field is deprecated and will always report 0 after 2024-08-05.", }, }, + deprecation.DataSourceSchema(), + ) +} + +// Single +var _ datasource.DataSource = (*dataSource)(nil) +var _ datasource.DataSourceWithConfigure = (*dataSource)(nil) +var _ datasource.DataSourceWithConfigValidators = (*dataSource)(nil) + +type dataSource struct { + client *hcloud.Client +} + +func NewDataSource() datasource.DataSource { + return &dataSource{} +} + +// Metadata should return the full name of the data source. +func (d *dataSource) Metadata(_ context.Context, _ datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = DataSourceType +} + +// Configure enables provider-level data or clients to be set in the +// provider-defined DataSource type. It is separately executed for each +// ReadDataSource RPC. +func (d *dataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + var newDiags diag.Diagnostics + + d.client, newDiags = hcloudutil.ConfigureClient(req.ProviderData) + resp.Diagnostics.Append(newDiags...) + if resp.Diagnostics.HasError() { + return } } -func dataSourceHcloudServerTypeRead(ctx context.Context, data *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*hcloud.Client) +//go:embed data_source.md +var dataSourceMarkdownDescription string - if id, ok := data.GetOk("id"); ok { - d, _, err := client.ServerType.GetByID(ctx, id.(int)) +// Schema should return the schema for this data source. +func (d *dataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema.Attributes = getCommonDataSchema() + resp.Schema.MarkdownDescription = dataSourceMarkdownDescription +} + +// ConfigValidators returns a list of ConfigValidators. Each ConfigValidator's Validate method will be called when validating the data source. +func (d *dataSource) ConfigValidators(_ context.Context) []datasource.ConfigValidator { + return []datasource.ConfigValidator{ + datasourcevalidator.ExactlyOneOf( + path.MatchRoot("id"), + path.MatchRoot("name"), + ), + } +} + +// Read is called when the provider must read data source values in +// order to update state. Config values should be read from the +// ReadRequest and new state values set on the ReadResponse. +func (d *dataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data resourceData + + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + var result *hcloud.ServerType + var err error + + switch { + case !data.ID.IsNull(): + result, _, err = d.client.ServerType.GetByID(ctx, int(data.ID.ValueInt64())) if err != nil { - return hcloudutil.ErrorToDiag(err) + resp.Diagnostics.Append(hcloudutil.APIErrorDiagnostics(err)...) + return } - if d == nil { - return diag.Errorf("no server type found with id %d", id) + if result == nil { + resp.Diagnostics.Append(hcloudutil.NotFoundDiagnostic("server type", "id", data.ID.String())) + return } - setServerTypeSchema(data, d) - return nil - } - if name, ok := data.GetOk("name"); ok { - d, _, err := client.ServerType.GetByName(ctx, name.(string)) + case !data.Name.IsNull(): + result, _, err = d.client.ServerType.GetByName(ctx, data.Name.ValueString()) if err != nil { - return hcloudutil.ErrorToDiag(err) + resp.Diagnostics.Append(hcloudutil.APIErrorDiagnostics(err)...) + return } - if d == nil { - return diag.Errorf("no server type found with name %v", name) + if result == nil { + resp.Diagnostics.Append(hcloudutil.NotFoundDiagnostic("server type", "name", data.Name.String())) + return } - setServerTypeSchema(data, d) - return nil + default: + // Should not happen, see [dataSource.ConfigValidators] + resp.Diagnostics.AddError("Unexpected internal error", "") + return } - return diag.Errorf("please specify an id, or a name to lookup for a server type") + data, diags := newResourceData(ctx, result) + resp.Diagnostics.Append(diags...) + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) } -func setServerTypeSchema(d *schema.ResourceData, t *hcloud.ServerType) { - for key, val := range getServerTypeAttributes(t) { - if key == "id" { - d.SetId(strconv.Itoa(val.(int))) - } else { - d.Set(key, val) - } +// List +var _ datasource.DataSource = (*dataSourceList)(nil) +var _ datasource.DataSourceWithConfigure = (*dataSourceList)(nil) + +type dataSourceList struct { + client *hcloud.Client +} + +func NewDataSourceList() datasource.DataSource { + return &dataSourceList{} +} + +// Metadata should return the full name of the data source. +func (d *dataSourceList) Metadata(_ context.Context, _ datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = DataSourceListType +} + +// Configure enables provider-level data or clients to be set in the +// provider-defined DataSource type. It is separately executed for each +// ReadDataSource RPC. +func (d *dataSourceList) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + var newDiags diag.Diagnostics + + d.client, newDiags = hcloudutil.ConfigureClient(req.ProviderData) + resp.Diagnostics.Append(newDiags...) + if resp.Diagnostics.HasError() { + return + } +} + +//go:embed data_source_list.md +var dataSourceListMarkdownDescription string + +// Schema should return the schema for this data source. +func (d *dataSourceList) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema.Attributes = map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Optional: true, + }, + "server_type_ids": schema.ListAttribute{ + Optional: true, + DeprecationMessage: "Use server_types list instead", + ElementType: types.StringType, + }, + "names": schema.ListAttribute{ + Optional: true, + DeprecationMessage: "Use server_types list instead", + ElementType: types.StringType, + }, + "descriptions": schema.ListAttribute{ + Optional: true, + DeprecationMessage: "Use server_types list instead", + ElementType: types.StringType, + }, + "server_types": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: getCommonDataSchema(), + }, + Computed: true, + }, } - deprecation.SetData(d, t) -} - -func getServerTypeAttributes(t *hcloud.ServerType) map[string]interface{} { - return map[string]interface{}{ - "id": t.ID, - "name": t.Name, - "description": t.Description, - "cores": t.Cores, - "memory": t.Memory, - "disk": t.Disk, - "storage_type": t.StorageType, - "cpu_type": t.CPUType, - "architecture": t.Architecture, - "included_traffic": t.IncludedTraffic, // nolint:staticcheck // Keep as long as it is available + resp.Schema.MarkdownDescription = dataSourceListMarkdownDescription +} + +type resourceDataList struct { + ID types.String `tfsdk:"id"` + ServerTypeIDs types.List `tfsdk:"server_type_ids"` + Names types.List `tfsdk:"names"` + Descriptions types.List `tfsdk:"descriptions"` + ServerTypes types.List `tfsdk:"server_types"` +} + +func newResourceDataList(ctx context.Context, in []*hcloud.ServerType) (resourceDataList, diag.Diagnostics) { + var data resourceDataList + var diags diag.Diagnostics + var newDiags diag.Diagnostics + + ids := make([]string, len(in)) + names := make([]string, len(in)) + descriptions := make([]string, len(in)) + tfItems := make([]resourceData, len(in)) + + for i, item := range in { + ids[i] = strconv.Itoa(item.ID) + names[i] = item.Name + descriptions[i] = item.Description + + tfItem, newDiags := newResourceData(ctx, item) + diags.Append(newDiags...) + tfItems[i] = tfItem } + + data.ID = types.StringValue(datasourceutil.ListID(ids)) + + data.ServerTypes, newDiags = types.ListValueFrom(ctx, types.ObjectType{AttrTypes: resourceDataAttrTypes}, tfItems) + diags.Append(newDiags...) + + data.ServerTypeIDs, newDiags = types.ListValueFrom(ctx, types.StringType, ids) + diags.Append(newDiags...) + data.Names, newDiags = types.ListValueFrom(ctx, types.StringType, names) + diags.Append(newDiags...) + data.Descriptions, newDiags = types.ListValueFrom(ctx, types.StringType, descriptions) + diags.Append(newDiags...) + + return data, diags } -func dataSourceHcloudServerTypeListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client := m.(*hcloud.Client) - allServerTypes, err := client.ServerType.All(ctx) - if err != nil { - return hcloudutil.ErrorToDiag(err) +// Read is called when the provider must read data source values in +// order to update state. Config values should be read from the +// ReadRequest and new state values set on the ReadResponse. +func (d *dataSourceList) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data resourceDataList + + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return } - names := make([]string, len(allServerTypes)) - descriptions := make([]string, len(allServerTypes)) - ids := make([]string, len(allServerTypes)) - tfServerTypes := make([]map[string]interface{}, len(allServerTypes)) - for i, serverType := range allServerTypes { - ids[i] = strconv.Itoa(serverType.ID) - descriptions[i] = serverType.Description - names[i] = serverType.Name - - tfServerType := getServerTypeAttributes(serverType) - if !serverType.IsDeprecated() { - tfServerType["is_deprecated"] = false - tfServerType["deprecation_announced"] = nil - tfServerType["unavailable_after"] = nil - } else { - tfServerType["is_deprecated"] = true - tfServerType["deprecation_announced"] = serverType.DeprecationAnnounced().Format(time.RFC3339) - tfServerType["unavailable_after"] = serverType.UnavailableAfter().Format(time.RFC3339) - } + var result []*hcloud.ServerType + var err error - tfServerTypes[i] = tfServerType + result, err = d.client.ServerType.All(ctx) + if err != nil { + resp.Diagnostics.Append(hcloudutil.APIErrorDiagnostics(err)...) + return } - d.SetId(datasourceutil.ListID(ids)) - d.Set("server_type_ids", ids) - d.Set("names", names) - d.Set("descriptions", descriptions) - d.Set("server_types", tfServerTypes) + data, diags := newResourceDataList(ctx, result) + resp.Diagnostics.Append(diags...) - return nil + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) } diff --git a/internal/servertype/data_source.md b/internal/servertype/data_source.md new file mode 100644 index 000000000..d2fd0b663 --- /dev/null +++ b/internal/servertype/data_source.md @@ -0,0 +1,15 @@ +Provides details about a specific Hetzner Cloud Server Type. + +Use this resource to get detailed information about specific Server Type. + +## Example Usage + +```hcl +data "hcloud_server_type" "by_name" { + name = "cx22" +} + +data "hcloud_server_type" "by_id" { + id = 1 +} +``` diff --git a/internal/servertype/data_source_list.md b/internal/servertype/data_source_list.md new file mode 100644 index 000000000..408e7a5f0 --- /dev/null +++ b/internal/servertype/data_source_list.md @@ -0,0 +1,15 @@ +Provides a list of available Hetzner Cloud Server Types. + +## Example Usage + +```hcl +data "hcloud_server_types" "all" {} + +resource "hcloud_server" "workers" { + count = 3 + + name = "node${count.index}" + image = "debian-12" + server_type = element(data.hcloud_server_types.all.names, count.index) +} +``` diff --git a/internal/servertype/data_source_test.go b/internal/servertype/data_source_test.go index 9c8113a2b..66a0f33dc 100644 --- a/internal/servertype/data_source_test.go +++ b/internal/servertype/data_source_test.go @@ -61,6 +61,49 @@ func TestAccDataSource(t *testing.T) { }) } +func TestAccDataSource_UpgradePluginFramework(t *testing.T) { + tmplMan := testtemplate.Manager{} + + byName := &servertype.DData{ServerTypeName: teste2e.TestServerType} + byName.SetRName("by_name") + + byID := &servertype.DData{ServerTypeID: "22"} + byID.SetRName("by_id") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: teste2e.PreCheck(t), + Steps: []resource.TestStep{ + { + ExternalProviders: map[string]resource.ExternalProvider{ + "hcloud": { + VersionConstraint: "1.48.1", + Source: "hetznercloud/hcloud", + }, + }, + + Config: tmplMan.Render(t, + "testdata/d/hcloud_server_type", byName, + "testdata/d/hcloud_server_type", byID, + "testdata/r/terraform_data_resource", byName, + "testdata/r/terraform_data_resource", byID, + ), + }, + { + ProtoV6ProviderFactories: teste2e.ProtoV6ProviderFactories(), + + Config: tmplMan.Render(t, + "testdata/d/hcloud_server_type", byName, + "testdata/d/hcloud_server_type", byID, + "testdata/r/terraform_data_resource", byName, + "testdata/r/terraform_data_resource", byID, + ), + + PlanOnly: true, + }, + }, + }) +} + func TestAccDataSourceList(t *testing.T) { tmplMan := testtemplate.Manager{} @@ -101,3 +144,39 @@ func TestAccDataSourceList(t *testing.T) { }, }) } + +func TestAccDataSourceList_UpgradePluginFramework(t *testing.T) { + tmplMan := testtemplate.Manager{} + + all := &servertype.DDataList{} + all.SetRName("all") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: teste2e.PreCheck(t), + Steps: []resource.TestStep{ + { + ExternalProviders: map[string]resource.ExternalProvider{ + "hcloud": { + VersionConstraint: "1.48.1", + Source: "hetznercloud/hcloud", + }, + }, + + Config: tmplMan.Render(t, + "testdata/d/hcloud_server_types", all, + "testdata/r/terraform_data_resource", all, + ), + }, + { + ProtoV6ProviderFactories: teste2e.ProtoV6ProviderFactories(), + + Config: tmplMan.Render(t, + "testdata/d/hcloud_server_types", all, + "testdata/r/terraform_data_resource", all, + ), + + PlanOnly: true, + }, + }, + }) +}