Feat/add datasource to query machine types (#968)

* feat(iaas): add datasource to query machine types

Signed-off-by: Mauritz Uphoff <mauritz.uphoff@stackit.cloud>

* review

Signed-off-by: Mauritz Uphoff <mauritz.uphoff@stackit.cloud>

* review

Signed-off-by: Mauritz Uphoff <mauritz.uphoff@stackit.cloud>

---------

Signed-off-by: Mauritz Uphoff <mauritz.uphoff@stackit.cloud>
This commit is contained in:
Mauritz Uphoff 2025-08-28 13:23:11 +02:00 committed by GitHub
parent 64787fff67
commit fedaf72b62
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 662 additions and 0 deletions

View file

@ -0,0 +1,70 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "stackit_machine_type Data Source - stackit"
subcategory: ""
description: |-
Machine type data source.
~> This datasource is in beta and may be subject to breaking changes in the future. Use with caution. See our guide https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/opting_into_beta_resources for how to opt-in to use beta resources.
---
# stackit_machine_type (Data Source)
Machine type data source.
~> This datasource is in beta and may be subject to breaking changes in the future. Use with caution. See our [guide](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/guides/opting_into_beta_resources) for how to opt-in to use beta resources.
## Example Usage
```terraform
data "stackit_machine_type" "two_vcpus_filter" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
filter = "vcpus==2"
}
data "stackit_machine_type" "filter_sorted_ascending_false" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
filter = "vcpus >= 2 && ram >= 2048"
sort_ascending = false
}
data "stackit_machine_type" "intel_icelake_generic_filter" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
filter = "extraSpecs.cpu==\"intel-icelake-generic\" && vcpus == 2"
}
# returns warning
data "stackit_machine_type" "no_match" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
filter = "vcpus == 99"
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `filter` (String) Expr-lang filter for filtering machine types.
Examples:
- vcpus == 2
- ram >= 2048
- extraSpecs.cpu == "intel-icelake-generic"
- extraSpecs.cpu == "intel-icelake-generic" && vcpus == 2
See https://expr-lang.org/docs/language-definition for syntax.
- `project_id` (String) STACKIT Project ID.
### Optional
- `sort_ascending` (Boolean) Sort machine types by name ascending (`true`) or descending (`false`). Defaults to `false`
### Read-Only
- `description` (String) Machine type description.
- `disk` (Number) Disk size in GB.
- `extra_specs` (Map of String) Extra specs (e.g., CPU type, overcommit ratio).
- `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`image_id`".
- `name` (String) Name of the machine type (e.g. 's1.2').
- `ram` (Number) RAM size in MB.
- `vcpus` (Number) Number of vCPUs.

View file

@ -0,0 +1,21 @@
data "stackit_machine_type" "two_vcpus_filter" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
filter = "vcpus==2"
}
data "stackit_machine_type" "filter_sorted_ascending_false" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
filter = "vcpus >= 2 && ram >= 2048"
sort_ascending = false
}
data "stackit_machine_type" "intel_icelake_generic_filter" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
filter = "extraSpecs.cpu==\"intel-icelake-generic\" && vcpus == 2"
}
# returns warning
data "stackit_machine_type" "no_match" {
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
filter = "vcpus == 99"
}

View file

@ -88,6 +88,9 @@ var (
//go:embed testdata/resource-server-max-server-attachments.tf //go:embed testdata/resource-server-max-server-attachments.tf
resourceServerMaxAttachmentConfig string resourceServerMaxAttachmentConfig string
//go:embed testdata/datasource-machinetype.tf
dataSourceMachineTypeConfig string
) )
const ( const (
@ -487,6 +490,10 @@ var testConfigKeyPairMaxUpdated = func() config.Variables {
return updatedConfig return updatedConfig
}() }()
var testConfigMachineTypeVars = config.Variables{
"project_id": config.StringVariable(testutil.ProjectId),
}
// if no local file is provided the test should create a default file and work with this instead of failing // if no local file is provided the test should create a default file and work with this instead of failing
var localFileForIaasImage os.File var localFileForIaasImage os.File
@ -4054,6 +4061,47 @@ func TestAccProject(t *testing.T) {
}) })
} }
func TestAccMachineType(t *testing.T) {
t.Logf("TestAccMachineType projectid: %s", testutil.ConvertConfigVariable(testConfigMachineTypeVars["project_id"]))
resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
ConfigVariables: testConfigMachineTypeVars,
Config: fmt.Sprintf("%s\n%s", dataSourceMachineTypeConfig, testutil.IaaSProviderConfigWithBetaResourcesEnabled()),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.stackit_machine_type.two_vcpus_filter", "project_id", testutil.ConvertConfigVariable(testConfigMachineTypeVars["project_id"])),
resource.TestCheckResourceAttrSet("data.stackit_machine_type.two_vcpus_filter", "id"),
resource.TestCheckResourceAttrSet("data.stackit_machine_type.two_vcpus_filter", "name"),
resource.TestCheckResourceAttrSet("data.stackit_machine_type.two_vcpus_filter", "vcpus"),
resource.TestCheckResourceAttr("data.stackit_machine_type.two_vcpus_filter", "vcpus", "2"),
resource.TestCheckResourceAttrSet("data.stackit_machine_type.two_vcpus_filter", "ram"),
resource.TestCheckResourceAttrSet("data.stackit_machine_type.two_vcpus_filter", "disk"),
resource.TestCheckResourceAttrSet("data.stackit_machine_type.two_vcpus_filter", "description"),
resource.TestCheckResourceAttrSet("data.stackit_machine_type.two_vcpus_filter", "extra_specs.cpu"),
resource.TestCheckResourceAttr("data.stackit_machine_type.filter_sorted_ascending_false", "project_id", testutil.ConvertConfigVariable(testConfigMachineTypeVars["project_id"])),
resource.TestCheckResourceAttrSet("data.stackit_machine_type.filter_sorted_ascending_false", "id"),
resource.TestCheckResourceAttrSet("data.stackit_machine_type.filter_sorted_ascending_false", "name"),
resource.TestCheckResourceAttrSet("data.stackit_machine_type.filter_sorted_ascending_false", "vcpus"),
resource.TestCheckResourceAttrSet("data.stackit_machine_type.filter_sorted_ascending_false", "ram"),
resource.TestCheckResourceAttrSet("data.stackit_machine_type.filter_sorted_ascending_false", "disk"),
resource.TestCheckResourceAttrSet("data.stackit_machine_type.filter_sorted_ascending_false", "description"),
resource.TestCheckResourceAttrSet("data.stackit_machine_type.filter_sorted_ascending_false", "extra_specs.cpu"),
resource.TestCheckResourceAttr("data.stackit_machine_type.no_match", "project_id", testutil.ConvertConfigVariable(testConfigMachineTypeVars["project_id"])),
resource.TestCheckNoResourceAttr("data.stackit_machine_type.no_match", "description"),
resource.TestCheckNoResourceAttr("data.stackit_machine_type.no_match", "disk"),
resource.TestCheckNoResourceAttr("data.stackit_machine_type.no_match", "extra_specs"),
resource.TestCheckNoResourceAttr("data.stackit_machine_type.no_match", "id"),
resource.TestCheckNoResourceAttr("data.stackit_machine_type.no_match", "name"),
resource.TestCheckNoResourceAttr("data.stackit_machine_type.no_match", "ram"),
),
},
},
})
}
func testAccCheckDestroy(s *terraform.State) error { func testAccCheckDestroy(s *terraform.State) error {
checkFunctions := []func(s *terraform.State) error{ checkFunctions := []func(s *terraform.State) error{
testAccCheckNetworkV1Destroy, testAccCheckNetworkV1Destroy,

View file

@ -0,0 +1,245 @@
package machineType
import (
"context"
"fmt"
"net/http"
"sort"
"strings"
"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/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/stackitcloud/stackit-sdk-go/services/iaas"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/features"
iaasUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/utils"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate"
)
// Ensure the implementation satisfies the expected interfaces.
var _ datasource.DataSource = &machineTypeDataSource{}
type DataSourceModel struct {
Id types.String `tfsdk:"id"` // required by Terraform to identify state
ProjectId types.String `tfsdk:"project_id"`
SortAscending types.Bool `tfsdk:"sort_ascending"`
Filter types.String `tfsdk:"filter"`
Description types.String `tfsdk:"description"`
Disk types.Int64 `tfsdk:"disk"`
ExtraSpecs types.Map `tfsdk:"extra_specs"`
Name types.String `tfsdk:"name"`
Ram types.Int64 `tfsdk:"ram"`
Vcpus types.Int64 `tfsdk:"vcpus"`
}
// NewMachineTypeDataSource instantiates the data source
func NewMachineTypeDataSource() datasource.DataSource {
return &machineTypeDataSource{}
}
type machineTypeDataSource struct {
client *iaas.APIClient
}
func (d *machineTypeDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_machine_type"
}
func (d *machineTypeDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
providerData, ok := conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
if !ok {
return
}
features.CheckBetaResourcesEnabled(ctx, &providerData, &resp.Diagnostics, "stackit_machine_type", "datasource")
if resp.Diagnostics.HasError() {
return
}
client := iaasUtils.ConfigureClient(ctx, &providerData, &resp.Diagnostics)
if resp.Diagnostics.HasError() {
return
}
d.client = client
tflog.Info(ctx, "IAAS client configured")
}
func (d *machineTypeDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: features.AddBetaDescription("Machine type data source.", core.Datasource),
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Description: "Terraform's internal resource ID. It is structured as \"`project_id`,`image_id`\".",
Computed: true,
},
"project_id": schema.StringAttribute{
Description: "STACKIT Project ID.",
Required: true,
Validators: []validator.String{
validate.UUID(),
validate.NoSeparator(),
},
},
"sort_ascending": schema.BoolAttribute{
Description: "Sort machine types by name ascending (`true`) or descending (`false`). Defaults to `false`",
Optional: true,
},
"filter": schema.StringAttribute{
Description: `Expr-lang filter for filtering machine types.
Examples:
- vcpus == 2
- ram >= 2048
- extraSpecs.cpu == "intel-icelake-generic"
- extraSpecs.cpu == "intel-icelake-generic" && vcpus == 2
See https://expr-lang.org/docs/language-definition for syntax.`,
Required: true,
},
"description": schema.StringAttribute{
Description: "Machine type description.",
Computed: true,
},
"disk": schema.Int64Attribute{
Description: "Disk size in GB.",
Computed: true,
},
"extra_specs": schema.MapAttribute{
Description: "Extra specs (e.g., CPU type, overcommit ratio).",
ElementType: types.StringType,
Computed: true,
},
"name": schema.StringAttribute{
Description: "Name of the machine type (e.g. 's1.2').",
Computed: true,
},
"ram": schema.Int64Attribute{
Description: "RAM size in MB.",
Computed: true,
},
"vcpus": schema.Int64Attribute{
Description: "Number of vCPUs.",
Computed: true,
},
},
}
}
func (d *machineTypeDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { // nolint:gocritic // function signature required by Terraform
var model DataSourceModel
resp.Diagnostics.Append(req.Config.Get(ctx, &model)...)
if resp.Diagnostics.HasError() {
return
}
projectId := model.ProjectId.ValueString()
sortAscending := model.SortAscending.ValueBool()
ctx = tflog.SetField(ctx, "project_id", projectId)
ctx = tflog.SetField(ctx, "filter_is_null", model.Filter.IsNull())
ctx = tflog.SetField(ctx, "filter_is_unknown", model.Filter.IsUnknown())
listMachineTypeReq := d.client.ListMachineTypes(ctx, projectId)
if !model.Filter.IsNull() && !model.Filter.IsUnknown() && strings.TrimSpace(model.Filter.ValueString()) != "" {
listMachineTypeReq = listMachineTypeReq.Filter(strings.TrimSpace(model.Filter.ValueString()))
}
apiResp, err := listMachineTypeReq.Execute()
if err != nil {
utils.LogError(ctx, &resp.Diagnostics, err, "Failed to read machine types",
fmt.Sprintf("Unable to retrieve machine types for project %q %s.", projectId, err),
map[int]string{
http.StatusForbidden: fmt.Sprintf("Access denied to project %q.", projectId),
},
)
resp.State.RemoveResource(ctx)
return
}
if apiResp.Items == nil || len(*apiResp.Items) == 0 {
core.LogAndAddWarning(ctx, &resp.Diagnostics, "No machine types found", "No matching machine types.")
return
}
// Convert items to []*iaas.MachineType
machineTypes := make([]*iaas.MachineType, len(*apiResp.Items))
for i := range *apiResp.Items {
machineTypes[i] = &(*apiResp.Items)[i]
}
sorted, err := sortMachineTypeByName(machineTypes, sortAscending)
if err != nil {
core.LogAndAddWarning(ctx, &resp.Diagnostics, "Unable to sort", err.Error())
return
}
if err := mapDataSourceFields(ctx, sorted[0], &model); err != nil {
core.LogAndAddError(ctx, &resp.Diagnostics, "Error reading machine type", fmt.Sprintf("Failed to translate API response: %v", err))
return
}
resp.Diagnostics.Append(resp.State.Set(ctx, model)...)
if resp.Diagnostics.HasError() {
return
}
tflog.Info(ctx, "Successfully read machine type")
}
func mapDataSourceFields(ctx context.Context, machineType *iaas.MachineType, model *DataSourceModel) error {
if machineType == nil || model == nil {
return fmt.Errorf("nil input provided")
}
if machineType.Name == nil || *machineType.Name == "" {
return fmt.Errorf("machine type name is missing")
}
model.Id = utils.BuildInternalTerraformId(model.ProjectId.ValueString(), *machineType.Name)
model.Name = types.StringPointerValue(machineType.Name)
model.Description = types.StringPointerValue(machineType.Description)
model.Disk = types.Int64PointerValue(machineType.Disk)
model.Ram = types.Int64PointerValue(machineType.Ram)
model.Vcpus = types.Int64PointerValue(machineType.Vcpus)
extra := types.MapNull(types.StringType)
if machineType.ExtraSpecs != nil && len(*machineType.ExtraSpecs) > 0 {
var diags diag.Diagnostics
extra, diags = types.MapValueFrom(ctx, types.StringType, *machineType.ExtraSpecs)
if diags.HasError() {
return fmt.Errorf("converting extraspecs: %w", core.DiagsToError(diags))
}
}
model.ExtraSpecs = extra
return nil
}
func sortMachineTypeByName(input []*iaas.MachineType, ascending bool) ([]*iaas.MachineType, error) {
if input == nil {
return nil, fmt.Errorf("input slice is nil")
}
// Filter out nil or missing name
var filtered []*iaas.MachineType
for _, m := range input {
if m != nil && m.Name != nil {
filtered = append(filtered, m)
}
}
sort.SliceStable(filtered, func(i, j int) bool {
if ascending {
return *filtered[i].Name < *filtered[j].Name
}
return *filtered[i].Name > *filtered[j].Name
})
return filtered, nil
}

View file

@ -0,0 +1,241 @@
package machineType
import (
"context"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/stackitcloud/stackit-sdk-go/core/utils"
"github.com/stackitcloud/stackit-sdk-go/services/iaas"
)
func TestMapDataSourceFields(t *testing.T) {
tests := []struct {
name string
initial DataSourceModel
input *iaas.MachineType
expected DataSourceModel
expectError bool
}{
{
name: "valid simple values",
initial: DataSourceModel{
ProjectId: types.StringValue("pid"),
},
input: &iaas.MachineType{
Name: utils.Ptr("s1.2"),
Description: utils.Ptr("general-purpose small"),
Disk: utils.Ptr(int64(20)),
Ram: utils.Ptr(int64(2048)),
Vcpus: utils.Ptr(int64(2)),
ExtraSpecs: &map[string]interface{}{
"cpu": "amd-epycrome-7702",
"overcommit": "1",
"environment": "general",
},
},
expected: DataSourceModel{
Id: types.StringValue("pid,s1.2"),
ProjectId: types.StringValue("pid"),
Name: types.StringValue("s1.2"),
Description: types.StringValue("general-purpose small"),
Disk: types.Int64Value(20),
Ram: types.Int64Value(2048),
Vcpus: types.Int64Value(2),
ExtraSpecs: types.MapValueMust(types.StringType, map[string]attr.Value{
"cpu": types.StringValue("amd-epycrome-7702"),
"overcommit": types.StringValue("1"),
"environment": types.StringValue("general"),
}),
},
expectError: false,
},
{
name: "missing name should fail",
initial: DataSourceModel{
ProjectId: types.StringValue("pid-456"),
},
input: &iaas.MachineType{
Description: utils.Ptr("gp-medium"),
},
expected: DataSourceModel{},
expectError: true,
},
{
name: "nil machineType should fail",
initial: DataSourceModel{},
input: nil,
expected: DataSourceModel{},
expectError: true,
},
{
name: "empty extraSpecs should return null map",
initial: DataSourceModel{
ProjectId: types.StringValue("pid-789"),
},
input: &iaas.MachineType{
Name: utils.Ptr("m1.noextras"),
Description: utils.Ptr("no extras"),
Disk: utils.Ptr(int64(10)),
Ram: utils.Ptr(int64(1024)),
Vcpus: utils.Ptr(int64(1)),
ExtraSpecs: &map[string]interface{}{},
},
expected: DataSourceModel{
Id: types.StringValue("pid-789,m1.noextras"),
ProjectId: types.StringValue("pid-789"),
Name: types.StringValue("m1.noextras"),
Description: types.StringValue("no extras"),
Disk: types.Int64Value(10),
Ram: types.Int64Value(1024),
Vcpus: types.Int64Value(1),
ExtraSpecs: types.MapNull(types.StringType),
},
expectError: false,
},
{
name: "nil extrasSpecs should return null map",
initial: DataSourceModel{
ProjectId: types.StringValue("pid-987"),
},
input: &iaas.MachineType{
Name: utils.Ptr("g1.nil"),
Description: utils.Ptr("missing extras"),
Disk: utils.Ptr(int64(40)),
Ram: utils.Ptr(int64(8096)),
Vcpus: utils.Ptr(int64(4)),
ExtraSpecs: nil,
},
expected: DataSourceModel{
Id: types.StringValue("pid-987,g1.nil"),
ProjectId: types.StringValue("pid-987"),
Name: types.StringValue("g1.nil"),
Description: types.StringValue("missing extras"),
Disk: types.Int64Value(40),
Ram: types.Int64Value(8096),
Vcpus: types.Int64Value(4),
ExtraSpecs: types.MapNull(types.StringType),
},
expectError: false,
},
{
name: "invalid extraSpecs with non-string values",
initial: DataSourceModel{
ProjectId: types.StringValue("test-err"),
},
input: &iaas.MachineType{
Name: utils.Ptr("invalid"),
Description: utils.Ptr("bad map"),
Disk: utils.Ptr(int64(10)),
Ram: utils.Ptr(int64(4096)),
Vcpus: utils.Ptr(int64(2)),
ExtraSpecs: &map[string]interface{}{
"cpu": "intel",
"burst": true, // not a string
"gen": 8, // not a string
},
},
expected: DataSourceModel{},
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := mapDataSourceFields(context.Background(), tt.input, &tt.initial)
if tt.expectError {
if err == nil {
t.Errorf("expected error but got none")
}
return
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
diff := cmp.Diff(tt.expected, tt.initial)
if diff != "" {
t.Errorf("unexpected diff (-want +got):\n%s", diff)
}
// Extra sanity check for proper ID format
if id := tt.initial.Id.ValueString(); !strings.HasPrefix(id, tt.initial.ProjectId.ValueString()+",") {
t.Errorf("unexpected ID format: got %q", id)
}
})
}
}
func TestSortMachineTypeByName(t *testing.T) {
tests := []struct {
name string
input []*iaas.MachineType
ascending bool
expected []string
expectError bool
}{
{
name: "ascending order",
input: []*iaas.MachineType{{Name: utils.Ptr("zeta")}, {Name: utils.Ptr("alpha")}, {Name: utils.Ptr("gamma")}},
ascending: true,
expected: []string{"alpha", "gamma", "zeta"},
},
{
name: "descending order",
input: []*iaas.MachineType{{Name: utils.Ptr("zeta")}, {Name: utils.Ptr("alpha")}, {Name: utils.Ptr("gamma")}},
ascending: false,
expected: []string{"zeta", "gamma", "alpha"},
},
{
name: "handles nil names",
input: []*iaas.MachineType{{Name: utils.Ptr("beta")}, nil, {Name: nil}, {Name: utils.Ptr("alpha")}},
ascending: true,
expected: []string{"alpha", "beta"},
},
{
name: "empty input",
input: []*iaas.MachineType{},
ascending: true,
expected: nil,
expectError: false,
},
{
name: "nil input",
input: nil,
ascending: true,
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sorted, err := sortMachineTypeByName(tt.input, tt.ascending)
if tt.expectError {
if err == nil {
t.Errorf("expected error but got none")
}
return
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
var result []string
for _, mt := range sorted {
if mt.Name != nil {
result = append(result, *mt.Name)
}
}
if diff := cmp.Diff(tt.expected, result); diff != "" {
t.Errorf("unexpected sorted order (-want +got):\n%s", diff)
}
})
}
}

View file

@ -0,0 +1,18 @@
variable "project_id" {}
data "stackit_machine_type" "two_vcpus_filter" {
project_id = var.project_id
filter = "vcpus==2"
}
data "stackit_machine_type" "filter_sorted_ascending_false" {
project_id = var.project_id
filter = "vcpus >= 2 && ram >= 2048"
sort_ascending = false
}
# returns warning
data "stackit_machine_type" "no_match" {
project_id = var.project_id
filter = "vcpus == 99"
}

View file

@ -136,6 +136,23 @@ func IaaSProviderConfig() string {
) )
} }
func IaaSProviderConfigWithBetaResourcesEnabled() string {
if IaaSCustomEndpoint == "" {
return `
provider "stackit" {
enable_beta_resources = true
default_region = "eu01"
}`
}
return fmt.Sprintf(`
provider "stackit" {
enable_beta_resources = true
iaas_custom_endpoint = "%s"
}`,
IaaSCustomEndpoint,
)
}
func IaaSProviderConfigWithExperiments() string { func IaaSProviderConfigWithExperiments() string {
if IaaSCustomEndpoint == "" { if IaaSCustomEndpoint == "" {
return ` return `

View file

@ -27,6 +27,7 @@ import (
iaasAffinityGroup "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/affinitygroup" iaasAffinityGroup "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/affinitygroup"
iaasImage "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/image" iaasImage "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/image"
iaasKeyPair "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/keypair" iaasKeyPair "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/keypair"
machineType "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/machinetype"
iaasNetwork "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/network" iaasNetwork "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/network"
iaasNetworkArea "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/networkarea" iaasNetworkArea "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/networkarea"
iaasNetworkAreaRoute "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/networkarearoute" iaasNetworkAreaRoute "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/networkarearoute"
@ -476,6 +477,7 @@ func (p *Provider) DataSources(_ context.Context) []func() datasource.DataSource
logMeInstance.NewInstanceDataSource, logMeInstance.NewInstanceDataSource,
logMeCredential.NewCredentialDataSource, logMeCredential.NewCredentialDataSource,
logAlertGroup.NewLogAlertGroupDataSource, logAlertGroup.NewLogAlertGroupDataSource,
machineType.NewMachineTypeDataSource,
mariaDBInstance.NewInstanceDataSource, mariaDBInstance.NewInstanceDataSource,
mariaDBCredential.NewCredentialDataSource, mariaDBCredential.NewCredentialDataSource,
mongoDBFlexInstance.NewInstanceDataSource, mongoDBFlexInstance.NewInstanceDataSource,