diff --git a/docs/data-sources/instance_type.md b/docs/data-sources/instance_type.md index 296e71cca..9ded9f18a 100644 --- a/docs/data-sources/instance_type.md +++ b/docs/data-sources/instance_type.md @@ -58,3 +58,5 @@ The Linode Instance Type resource exports the following attributes: * `transfer` - The monthly outbound transfer amount, in MB. * `vcpus` - The number of VCPU cores this Linode Type offers. + +* `accelerated_devices` - The number of VPUs this Linode Type offers. diff --git a/docs/data-sources/instance_types.md b/docs/data-sources/instance_types.md index 1e373b5e6..b3be04949 100644 --- a/docs/data-sources/instance_types.md +++ b/docs/data-sources/instance_types.md @@ -88,6 +88,8 @@ Each Linode Instance type will be stored in the `types` attribute and will expor * `vcpus` - The number of VCPU cores this Linode Type offers. +* `accelerated_devices` - The number of VPUs this Linode Type offers. + ## Filterable Fields * `class` diff --git a/docs/data-sources/instances.md b/docs/data-sources/instances.md index da947af8f..ea7a6c7ac 100644 --- a/docs/data-sources/instances.md +++ b/docs/data-sources/instances.md @@ -119,6 +119,8 @@ Each Linode instance will be stored in the `instances` attribute and will export * `specs.0.vcpus` - The number of vcpus this Linode has access to. Typically a Linode will choose to boot with all of its available vcpus, but this can be configured in a Config Profile. +* `specs.0.accelerated_devices` - The number of VPUs this Linode has access to. + * `specs.0.transfer` - The amount of network transfer this Linode is allotted each month. * [`disk`](#disks) - A list of disks associated with the Linode. diff --git a/docs/resources/instance.md b/docs/resources/instance.md index 7cde3da4f..6b539847c 100644 --- a/docs/resources/instance.md +++ b/docs/resources/instance.md @@ -371,6 +371,8 @@ This Linode Instance resource exports the following attributes: * `specs.0.vcpus` - The number of vcpus this Linode has access to. Typically a Linode will choose to boot with all of its available vcpus, but this can be configured in a Config Profile. +* `specs.0.accelerated_devices` - The number of VPUs this Linode has access to. + * `specs.0.transfer` - The amount of network transfer this Linode is allotted each month. * `backups` - Information about this Linode's backups status. diff --git a/linode/instance/flatten.go b/linode/instance/flatten.go index adf6decd8..bc594ea25 100644 --- a/linode/instance/flatten.go +++ b/linode/instance/flatten.go @@ -191,10 +191,11 @@ func flattenInstanceConfigs( func flattenInstanceSpecs(instance linodego.Instance) []map[string]int { return []map[string]int{{ - "vcpus": instance.Specs.VCPUs, - "disk": instance.Specs.Disk, - "memory": instance.Specs.Memory, - "transfer": instance.Specs.Transfer, + "vcpus": instance.Specs.VCPUs, + "disk": instance.Specs.Disk, + "memory": instance.Specs.Memory, + "transfer": instance.Specs.Transfer, + "accelerated_devices": instance.Specs.AcceleratedDevices, }} } diff --git a/linode/instance/flatten_unit_test.go b/linode/instance/flatten_unit_test.go index 58ad8c1b7..b672d4b0b 100644 --- a/linode/instance/flatten_unit_test.go +++ b/linode/instance/flatten_unit_test.go @@ -61,11 +61,12 @@ func TestFlattenInstanceAlerts(t *testing.T) { Hypervisor: "kvm", HostUUID: "3a3ddd59d9a78bb8de041391075df44de62bfec8", Specs: &linodego.InstanceSpec{ - Disk: 81920, - GPUs: 0, - Memory: 4096, - Transfer: 4000, - VCPUs: 2, + Disk: 81920, + GPUs: 0, + Memory: 4096, + Transfer: 4000, + VCPUs: 2, + AcceleratedDevices: 3, }, WatchdogEnabled: true, Tags: []string{"example tag", "another example"}, @@ -340,10 +341,11 @@ func TestFlattenInstanceSpecs(t *testing.T) { Type: "g6-standard-1", Status: linodego.InstanceRunning, Specs: &linodego.InstanceSpec{ - VCPUs: 2, - Disk: 50, - Memory: 4096, - Transfer: 2000, + VCPUs: 2, + Disk: 50, + Memory: 4096, + Transfer: 2000, + AcceleratedDevices: 3, }, } @@ -351,10 +353,11 @@ func TestFlattenInstanceSpecs(t *testing.T) { expected := []map[string]int{ { - "vcpus": 2, - "disk": 50, - "memory": 4096, - "transfer": 2000, + "vcpus": 2, + "disk": 50, + "memory": 4096, + "transfer": 2000, + "accelerated_devices": 3, }, } diff --git a/linode/instance/resource_test.go b/linode/instance/resource_test.go index 82afbedfe..2312b62d2 100644 --- a/linode/instance/resource_test.go +++ b/linode/instance/resource_test.go @@ -115,6 +115,45 @@ func TestAccResourceInstance_basic_smoke(t *testing.T) { }) } +func TestAccResourceInstance_vpu(t *testing.T) { + t.Parallel() + + resName := "linode_instance.foobar" + var instance linodego.Instance + instanceName := acctest.RandomWithPrefix("tf_test_vpu") + rootPass := acctest.RandString(64) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, + CheckDestroy: acceptance.CheckInstanceDestroy, + + Steps: []resource.TestStep{ + { + Config: tmpl.VPU(t, instanceName, acceptance.PublicKeyMaterial, "us-lax", rootPass), + Check: resource.ComposeTestCheckFunc( + acceptance.CheckInstanceExists(resName, &instance), + resource.TestCheckResourceAttr(resName, "label", instanceName), + resource.TestCheckResourceAttr(resName, "type", "g1-accelerated-netint-vpu-t1u1-s"), + resource.TestCheckResourceAttr(resName, "image", acceptance.TestImageLatest), + resource.TestCheckResourceAttr(resName, "region", "us-lax"), + resource.TestCheckResourceAttr(resName, "group", "tf_test"), + resource.TestCheckResourceAttr(resName, "swap_size", "256"), + resource.TestCheckResourceAttrSet(resName, "host_uuid"), + resource.TestCheckResourceAttrSet(resName, "specs.0.accelerated_devices"), + ), + }, + + { + ResourceName: resName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"root_pass", "authorized_keys", "image", "resize_disk", "migration_type", "firewall_id", "capabilities"}, + }, + }, + }) +} + func TestAccResourceInstance_watchdogDisabled(t *testing.T) { t.Parallel() diff --git a/linode/instance/schema_datasource.go b/linode/instance/schema_datasource.go index b762529db..fe151664f 100644 --- a/linode/instance/schema_datasource.go +++ b/linode/instance/schema_datasource.go @@ -151,6 +151,11 @@ var instanceDataSourceSchema = map[string]*schema.Schema{ Computed: true, Description: "The amount of network transfer this Linode is allotted each month.", }, + "accelerated_devices": { + Type: schema.TypeInt, + Computed: true, + Description: "The number of VPUs this Linode Type offers.", + }, }, }, }, diff --git a/linode/instance/schema_resource.go b/linode/instance/schema_resource.go index fd678b227..1d445fe33 100644 --- a/linode/instance/schema_resource.go +++ b/linode/instance/schema_resource.go @@ -532,6 +532,11 @@ var resourceSchema = map[string]*schema.Schema{ Computed: true, Description: "The amount of network transfer this Linode is allotted each month.", }, + "accelerated_devices": { + Type: schema.TypeInt, + Computed: true, + Description: "The number of VPUs this Linode Type offers.", + }, }, }, }, diff --git a/linode/instance/tmpl/template.go b/linode/instance/tmpl/template.go index 4f13cb533..bdac1857e 100644 --- a/linode/instance/tmpl/template.go +++ b/linode/instance/tmpl/template.go @@ -42,6 +42,17 @@ func Basic(t testing.TB, label, pubKey, region string, rootPass string) string { }) } +func VPU(t testing.TB, label, pubKey, region string, rootPass string) string { + return acceptance.ExecuteTemplate(t, + "instance_vpu", TemplateData{ + Label: label, + PubKey: pubKey, + Image: acceptance.TestImageLatest, + Region: region, + RootPass: rootPass, + }) +} + func Updates(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_updates", TemplateData{ diff --git a/linode/instance/tmpl/templates/vpu.gotf b/linode/instance/tmpl/templates/vpu.gotf new file mode 100644 index 000000000..20a6a0d11 --- /dev/null +++ b/linode/instance/tmpl/templates/vpu.gotf @@ -0,0 +1,17 @@ +{{ define "instance_vpu" }} + +{{ template "e2e_test_firewall" . }} + +resource "linode_instance" "foobar" { + label = "{{.Label}}" + group = "tf_test" + type = "g1-accelerated-netint-vpu-t1u1-s" + image = "{{.Image}}" + region = "{{ .Region }}" + root_pass = "{{ .RootPass }}" + swap_size = 256 + authorized_keys = ["{{.PubKey}}"] + firewall_id = linode_firewall.e2e_test_firewall.id +} + +{{ end }} \ No newline at end of file diff --git a/linode/instancetype/datasource_test.go b/linode/instancetype/datasource_test.go index 1d2e129a4..98cac60f7 100644 --- a/linode/instancetype/datasource_test.go +++ b/linode/instancetype/datasource_test.go @@ -66,6 +66,11 @@ func TestAccDataSourceLinodeInstanceType_basic(t *testing.T) { "vcpus", strconv.FormatInt(int64(targetType.VCPUs), 10), ), + resource.TestCheckResourceAttr( + resourceName, + "accelerated_devices", + strconv.FormatInt(int64(targetType.AcceleratedDevices), 10), + ), resource.TestCheckResourceAttr( resourceName, "network_out", diff --git a/linode/instancetype/framework_datasource_schema.go b/linode/instancetype/framework_datasource_schema.go index 351808cff..81d02511a 100644 --- a/linode/instancetype/framework_datasource_schema.go +++ b/linode/instancetype/framework_datasource_schema.go @@ -70,6 +70,10 @@ var Attributes = map[string]schema.Attribute{ Description: "The number of VCPU cores this Linode Type offers.", Computed: true, }, + "accelerated_devices": schema.Int64Attribute{ + Description: "The number of VPUs this Linode Type offers.", + Computed: true, + }, } var frameworkDatasourceSchema = schema.Schema{ diff --git a/linode/instancetype/framework_models.go b/linode/instancetype/framework_models.go index 810e0c3e4..27309355c 100644 --- a/linode/instancetype/framework_models.go +++ b/linode/instancetype/framework_models.go @@ -13,17 +13,18 @@ import ( ) type DataSourceModel struct { - ID types.String `tfsdk:"id"` - Label types.String `tfsdk:"label"` - Disk types.Int64 `tfsdk:"disk"` - Class types.String `tfsdk:"class"` - Price types.List `tfsdk:"price"` - Addons types.List `tfsdk:"addons"` - RegionPrices types.List `tfsdk:"region_prices"` - NetworkOut types.Int64 `tfsdk:"network_out"` - Memory types.Int64 `tfsdk:"memory"` - Transfer types.Int64 `tfsdk:"transfer"` - VCPUs types.Int64 `tfsdk:"vcpus"` + ID types.String `tfsdk:"id"` + Label types.String `tfsdk:"label"` + Disk types.Int64 `tfsdk:"disk"` + Class types.String `tfsdk:"class"` + Price types.List `tfsdk:"price"` + Addons types.List `tfsdk:"addons"` + RegionPrices types.List `tfsdk:"region_prices"` + NetworkOut types.Int64 `tfsdk:"network_out"` + Memory types.Int64 `tfsdk:"memory"` + Transfer types.Int64 `tfsdk:"transfer"` + VCPUs types.Int64 `tfsdk:"vcpus"` + AcceleratedDevices types.Int64 `tfsdk:"accelerated_devices"` } func (data *DataSourceModel) ParseLinodeType( @@ -57,6 +58,7 @@ func (data *DataSourceModel) ParseLinodeType( data.Memory = types.Int64Value(int64(linodeType.Memory)) data.Transfer = types.Int64Value(int64(linodeType.Transfer)) data.VCPUs = types.Int64Value(int64(linodeType.VCPUs)) + data.AcceleratedDevices = types.Int64Value(int64(linodeType.AcceleratedDevices)) return nil } diff --git a/linode/instancetype/framework_models_unit_test.go b/linode/instancetype/framework_models_unit_test.go index 139da18ff..392f10b03 100644 --- a/linode/instancetype/framework_models_unit_test.go +++ b/linode/instancetype/framework_models_unit_test.go @@ -13,16 +13,17 @@ import ( func TestParseLinodeType(t *testing.T) { mockLinodeType := &linodego.LinodeType{ - ID: "g6-standard-2", - Disk: 81920, - Class: linodego.ClassStandard, - Label: "Linode 4GB", - NetworkOut: 1000, - Memory: 4096, - Transfer: 4000, - VCPUs: 2, - GPUs: 0, - Successor: "", + ID: "g6-standard-2", + Disk: 81920, + Class: linodego.ClassStandard, + Label: "Linode 4GB", + NetworkOut: 1000, + Memory: 4096, + Transfer: 4000, + VCPUs: 2, + GPUs: 0, + AcceleratedDevices: 3, + Successor: "", Price: &linodego.LinodePrice{ Hourly: 0.03, Monthly: 20, @@ -50,4 +51,5 @@ func TestParseLinodeType(t *testing.T) { assert.Equal(t, types.Int64Value(4096), data.Memory) assert.Equal(t, types.Int64Value(4000), data.Transfer) assert.Equal(t, types.Int64Value(2), data.VCPUs) + assert.Equal(t, types.Int64Value(3), data.AcceleratedDevices) } diff --git a/linode/instancetypes/datasource_test.go b/linode/instancetypes/datasource_test.go index 6661f84be..8948f01ca 100644 --- a/linode/instancetypes/datasource_test.go +++ b/linode/instancetypes/datasource_test.go @@ -31,6 +31,7 @@ func TestAccDataSourceInstanceTypes_basic(t *testing.T) { resource.TestCheckResourceAttrSet(resourceName, "types.0.memory"), resource.TestCheckResourceAttrSet(resourceName, "types.0.transfer"), resource.TestCheckResourceAttrSet(resourceName, "types.0.vcpus"), + resource.TestCheckResourceAttrSet(resourceName, "types.0.accelerated_devices"), resource.TestCheckResourceAttrSet(resourceName, "types.0.price.0.hourly"), resource.TestCheckResourceAttrSet(resourceName, "types.0.price.0.monthly"), resource.TestCheckResourceAttrSet(resourceName, "types.0.addons.0.backups.0.price.0.hourly"), diff --git a/linode/instancetypes/framework_models_unit_test.go b/linode/instancetypes/framework_models_unit_test.go index 1a872676a..990d09f98 100644 --- a/linode/instancetypes/framework_models_unit_test.go +++ b/linode/instancetypes/framework_models_unit_test.go @@ -15,16 +15,17 @@ import ( func TestParseInstanceTypes(t *testing.T) { mockTypes := []linodego.LinodeType{ { - ID: "g6-standard-2", - Disk: 81920, - Class: linodego.ClassStandard, - Label: "Linode 4GB", - NetworkOut: 1000, - Memory: 4096, - Transfer: 4000, - VCPUs: 2, - GPUs: 0, - Successor: "", + ID: "g6-standard-2", + Disk: 81920, + Class: linodego.ClassStandard, + Label: "Linode 4GB", + NetworkOut: 1000, + Memory: 4096, + Transfer: 4000, + VCPUs: 2, + AcceleratedDevices: 3, + GPUs: 0, + Successor: "", Price: &linodego.LinodePrice{ Hourly: 0.03, Monthly: 20, @@ -81,6 +82,7 @@ func TestParseInstanceTypes(t *testing.T) { assert.Equal(t, model.Types[i].Memory, types.Int64Value(int64(mockType.Memory)), "Memory size doesn't match") assert.Equal(t, model.Types[i].Transfer, types.Int64Value(int64(mockType.Transfer)), "Transfer size doesn't match") assert.Equal(t, model.Types[i].VCPUs, types.Int64Value(int64(mockType.VCPUs)), "VCPUs count doesn't match") + assert.Equal(t, model.Types[i].AcceleratedDevices, types.Int64Value(int64(mockType.AcceleratedDevices)), "Accelerated devices count doesn't match") // Assertions for Price assert.NotNil(t, model.Types[i].Price, "Price should not be nil")