diff --git a/docs/resources/virtual_environment_vm.md b/docs/resources/virtual_environment_vm.md index bbcbb991..da3725ed 100644 --- a/docs/resources/virtual_environment_vm.md +++ b/docs/resources/virtual_environment_vm.md @@ -136,7 +136,7 @@ output "ubuntu_vm_public_key" { - `enabled` - (Optional) Whether to enable the CDROM drive (defaults to `false`). - `file_id` - (Optional) A file ID for an ISO file (defaults to `cdrom` as - in the physical drive). + in the physical drive). Use `none` to leave the CDROM drive empty. - `interface` - (Optional) A hardware interface to connect CDROM drive to, must be `ideN` (defaults to `ide3`). Note that `q35` machine type only supports `ide0` and `ide2`. diff --git a/example/resource_virtual_environment_vm.tf b/example/resource_virtual_environment_vm.tf index bbbb1df2..39eea863 100644 --- a/example/resource_virtual_environment_vm.tf +++ b/example/resource_virtual_environment_vm.tf @@ -88,6 +88,11 @@ resource "proxmox_virtual_environment_vm" "example_template" { machine = "q35" name = "terraform-provider-proxmox-example-template" + cdrom { + enabled = true + file_id = "none" + } + network_device { mtu = 1450 queues = 2 diff --git a/fwprovider/test/resource_vm_cdrom_test.go b/fwprovider/test/resource_vm_cdrom_test.go new file mode 100644 index 00000000..9de19bbf --- /dev/null +++ b/fwprovider/test/resource_vm_cdrom_test.go @@ -0,0 +1,76 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccResourceVMCDROM(t *testing.T) { + t.Parallel() + + te := InitEnvironment(t) + + tests := []struct { + name string + steps []resource.TestStep + }{ + {"default cdrom", []resource.TestStep{ + { + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_cdrom" { + node_name = "{{.NodeName}}" + started = false + name = "test-cdrom" + cdrom { + enabled = true + } + }`), + Check: ResourceAttributes("proxmox_virtual_environment_vm.test_cdrom", map[string]string{ + "cdrom.0.enabled": "true", + }), + }, + { + RefreshState: true, + }, + }}, + {"none cdrom", []resource.TestStep{ + { + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_cdrom" { + node_name = "{{.NodeName}}" + started = false + name = "test-cdrom" + cdrom { + enabled = true + file_id = "none" + } + }`), + Check: ResourceAttributes("proxmox_virtual_environment_vm.test_cdrom", map[string]string{ + "cdrom.0.enabled": "true", + "cdrom.0.file_id": "none", + }), + }, + { + RefreshState: true, + }, + }}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: te.AccProviders, + Steps: tt.steps, + }) + }) + } +} diff --git a/fwprovider/test/resource_vm_disks_test.go b/fwprovider/test/resource_vm_disks_test.go new file mode 100644 index 00000000..7c1c7259 --- /dev/null +++ b/fwprovider/test/resource_vm_disks_test.go @@ -0,0 +1,544 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package test + +import ( + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/plancheck" +) + +func TestAccResourceVMDisks(t *testing.T) { + t.Parallel() + + te := InitEnvironment(t) + + tests := []struct { + name string + steps []resource.TestStep + }{ + {"create disk with default parameters, then update it", []resource.TestStep{ + { + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_disk" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk" + + disk { + // note: default qcow2 is not supported by lvm (?) + file_format = "raw" + datastore_id = "local-lvm" + interface = "virtio0" + size = 8 + } + }`), + Check: resource.ComposeTestCheckFunc( + ResourceAttributes("proxmox_virtual_environment_vm.test_disk", map[string]string{ + "disk.0.aio": "io_uring", + "disk.0.backup": "true", + "disk.0.cache": "none", + "disk.0.discard": "ignore", + "disk.0.file_id": "", + "disk.0.datastore_id": "local-lvm", + "disk.0.file_format": "raw", + "disk.0.interface": "virtio0", + "disk.0.iothread": "false", + "disk.0.path_in_datastore": `vm-\d+-disk-\d+`, + "disk.0.replicate": "true", + "disk.0.size": "8", + "disk.0.ssd": "false", + }), + ), + }, + { + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_disk" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk" + + disk { + // note: default qcow2 is not supported by lvm (?) + file_format = "raw" + datastore_id = "local-lvm" + interface = "virtio0" + size = 8 + replicate = false + aio = "native" + speed { + iops_read = 100 + iops_read_burstable = 1000 + iops_write = 400 + iops_write_burstable = 800 + } + } + }`), + Check: resource.ComposeTestCheckFunc( + ResourceAttributes("proxmox_virtual_environment_vm.test_disk", map[string]string{ + "disk.0.aio": "native", + "disk.0.backup": "true", + "disk.0.cache": "none", + "disk.0.discard": "ignore", + "disk.0.file_id": "", + "disk.0.datastore_id": "local-lvm", + "disk.0.file_format": "raw", + "disk.0.interface": "virtio0", + "disk.0.iothread": "false", + "disk.0.path_in_datastore": `vm-\d+-disk-\d+`, + "disk.0.replicate": "false", + "disk.0.size": "8", + "disk.0.ssd": "false", + "disk.0.speed.0.iops_read": "100", + "disk.0.speed.0.iops_read_burstable": "1000", + "disk.0.speed.0.iops_write": "400", + "disk.0.speed.0.iops_write_burstable": "800", + }), + ), + }, + }}, + {"create disk from an image", []resource.TestStep{{ + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_download_file" "test_disk_image" { + content_type = "iso" + datastore_id = "local" + node_name = "{{.NodeName}}" + url = "{{.CloudImagesServer}}/jammy/current/jammy-server-cloudimg-amd64.img" + overwrite_unmanaged = true + } + resource "proxmox_virtual_environment_vm" "test_disk" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk" + disk { + datastore_id = "local-lvm" + file_id = proxmox_virtual_environment_download_file.test_disk_image.id + interface = "virtio0" + iothread = true + discard = "on" + size = 20 + } + }`), + Check: resource.ComposeTestCheckFunc( + ResourceAttributes("proxmox_virtual_environment_vm.test_disk", map[string]string{ + "disk.0.cache": "none", + "disk.0.datastore_id": "local-lvm", + "disk.0.discard": "on", + "disk.0.file_format": "raw", + "disk.0.interface": "virtio0", + "disk.0.iothread": "true", + "disk.0.path_in_datastore": `vm-\d+-disk-\d+`, + "disk.0.size": "20", + "disk.0.ssd": "false", + }), + ), + }}}, + {"clone default disk without overrides", []resource.TestStep{ + { + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_disk_template" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk-template" + template = "true" + + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "virtio0" + size = 8 + } + } + resource "proxmox_virtual_environment_vm" "test_disk" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk" + + clone { + vm_id = proxmox_virtual_environment_vm.test_disk_template.id + } + }`), + Check: resource.ComposeTestCheckFunc( + // fully cloned disk, does not have any attributes in state + resource.TestCheckNoResourceAttr("proxmox_virtual_environment_vm.test_disk", "disk.0"), + ResourceAttributes("proxmox_virtual_environment_vm.test_disk", map[string]string{}), + ), + }, + { + RefreshState: true, + }, + }}, + {"multiple disks", []resource.TestStep{ + { + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_disk" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk" + template = "true" + + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "virtio0" + size = 8 + } + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "scsi0" + size = 8 + } + }`), + Check: ResourceAttributes("proxmox_virtual_environment_vm.test_disk", map[string]string{ + "disk.0.interface": "virtio0", + "disk.0.path_in_datastore": `vm-\d+-disk-1`, + "disk.1.interface": "scsi0", + "disk.1.path_in_datastore": `vm-\d+-disk-0`, + }), + }, + { + RefreshState: true, + }, + }}, + {"adding disks", []resource.TestStep{ + { + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_disk" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk" + + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "scsi0" + size = 8 + } + }`), + Check: ResourceAttributes("proxmox_virtual_environment_vm.test_disk", map[string]string{ + "disk.0.interface": "scsi0", + "disk.0.path_in_datastore": `vm-\d+-disk-0`, + }), + }, + { + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_disk" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk" + + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "scsi0" + size = 8 + } + + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "scsi1" + size = 8 + } + }`), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + plancheck.ExpectResourceAction("proxmox_virtual_environment_vm.test_disk", plancheck.ResourceActionUpdate), + }, + }, + Check: ResourceAttributes("proxmox_virtual_environment_vm.test_disk", map[string]string{ + "disk.0.interface": "scsi0", + "disk.0.path_in_datastore": `vm-\d+-disk-0`, + "disk.1.interface": "scsi1", + "disk.1.path_in_datastore": `vm-\d+-disk-1`, + }), + }, + { + RefreshState: true, + }, + }}, + {"removing disks", []resource.TestStep{ + { + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_disk" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk" + + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "scsi0" + size = 8 + } + + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "scsi1" + size = 8 + } + }`), + Check: ResourceAttributes("proxmox_virtual_environment_vm.test_disk", map[string]string{ + "disk.0.interface": "scsi0", + "disk.0.path_in_datastore": `vm-\d+-disk-0`, + "disk.1.interface": "scsi1", + "disk.1.path_in_datastore": `vm-\d+-disk-1`, + }), + }, + { + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_disk" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk" + + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "scsi0" + size = 8 + } + }`), + ExpectError: regexp.MustCompile(`deletion of disks not supported`), + }, + }}, + {"efi disk", []resource.TestStep{ + { + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_efi_disk" { + node_name = "{{.NodeName}}" + started = false + name = "test-efi-disk" + + efi_disk { + datastore_id = "local-lvm" + type = "4m" + } + }`), + Check: resource.ComposeTestCheckFunc( + ResourceAttributes("proxmox_virtual_environment_vm.test_efi_disk", map[string]string{ + "efi_disk.0.datastore_id": "local-lvm", + "efi_disk.0.type": "4m", + }), + ), + }, + { + RefreshState: true, + }, + }}, + {"ide disks", []resource.TestStep{ + { + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_disks" { + node_name = "{{.NodeName}}" + started = false + name = "test-disks-ide" + + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "ide0" + size = 8 + } + }`), + Check: ResourceAttributes("proxmox_virtual_environment_vm.test_disks", map[string]string{ + "disk.0.interface": "ide0", + "disk.0.path_in_datastore": `vm-\d+-disk-0`, + }), + }, + { + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_disks" { + node_name = "{{.NodeName}}" + started = false + name = "test-disks-ide" + + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "ide0" + size = 8 + } + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "ide1" + size = 8 + } + }`), + Check: ResourceAttributes("proxmox_virtual_environment_vm.test_disks", map[string]string{ + "disk.#": "2", + }), + }, + { + RefreshState: true, + }, + }}, + {"clone disk with overrides", []resource.TestStep{ + { + SkipFunc: func() (bool, error) { + // this test is failing because of https://github.com/bpg/terraform-provider-proxmox/issues/873 + return true, nil + }, + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_disk3_template" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk-template" + template = "true" + + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "scsi0" + size = 8 + discard = "on" + iothread = true + ssd = true + } + } + resource "proxmox_virtual_environment_vm" "test_disk" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk" + + clone { + vm_id = proxmox_virtual_environment_vm.test_disk_template.id + } + + disk { + interface = "scsi0" + //size = 10 + } + }`), + Check: ResourceAttributes("proxmox_virtual_environment_vm.test_disk", map[string]string{ + "disk.0.datastore_id": "local-lvm", + "disk.0.discard": "on", + "disk.0.file_format": "raw", + "disk.0.interface": "scsi0", + "disk.0.iothread": "true", + "disk.0.path_in_datastore": `vm-\d+-disk-\d+`, + "disk.0.size": "8", + "disk.0.ssd": "true", + }), + }, + { + RefreshState: true, + Destroy: false, + }, + }}, + {"clone with disk resize", []resource.TestStep{ + { + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_disk_template" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk-template" + template = "true" + + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "virtio0" + size = 8 + } + } + resource "proxmox_virtual_environment_vm" "test_disk" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk" + + clone { + vm_id = proxmox_virtual_environment_vm.test_disk_template.id + } + + disk { + datastore_id = "local-lvm" + interface = "virtio0" + size = 10 + } + }`), + Check: resource.ComposeTestCheckFunc( + ResourceAttributes("proxmox_virtual_environment_vm.test_disk", map[string]string{ + "disk.0.datastore_id": "local-lvm", + "disk.0.interface": "virtio0", + "disk.0.size": "10", + }), + ), + }, + { + RefreshState: true, + }, + }}, + {"clone with adding disk", []resource.TestStep{ + { + SkipFunc: func() (bool, error) { + // this test is failing because of "Attribute 'disk.1.size' expected to be set" + return true, nil + }, + Config: te.RenderConfig(` + resource "proxmox_virtual_environment_vm" "test_disk_template" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk-template" + template = "true" + + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "virtio0" + size = 8 + } + } + resource "proxmox_virtual_environment_vm" "test_disk" { + node_name = "{{.NodeName}}" + started = false + name = "test-disk" + + clone { + vm_id = proxmox_virtual_environment_vm.test_disk_template.id + } + + disk { + file_format = "raw" + datastore_id = "local-lvm" + interface = "scsi0" + size = 10 + } + }`), + Check: resource.ComposeTestCheckFunc( + ResourceAttributes("proxmox_virtual_environment_vm.test_disk", map[string]string{ + "disk.1.datastore_id": "local-lvm", + "disk.1.interface": "virtio0", + "disk.1.size": "8", + "disk.0.datastore_id": "local-lvm", + "disk.0.interface": "scsi0", + "disk.0.size": "10", + }), + ), + }, + { + RefreshState: true, + }, + }}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: te.AccProviders, + Steps: tt.steps, + }) + }) + } +} diff --git a/fwprovider/test/resource_vm_test.go b/fwprovider/test/resource_vm_test.go index 2d45afc3..adb886f3 100644 --- a/fwprovider/test/resource_vm_test.go +++ b/fwprovider/test/resource_vm_test.go @@ -7,11 +7,9 @@ package test import ( - "regexp" "testing" "github.com/hashicorp/terraform-plugin-testing/helper/resource" - "github.com/hashicorp/terraform-plugin-testing/plancheck" ) func TestAccResourceVM(t *testing.T) { @@ -451,554 +449,3 @@ func TestAccResourceVMNetwork(t *testing.T) { }) } } - -func TestAccResourceVMDisks(t *testing.T) { - t.Parallel() - - te := InitEnvironment(t) - - tests := []struct { - name string - steps []resource.TestStep - }{ - {"create disk with default parameters, then update it", []resource.TestStep{ - { - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_vm" "test_disk1" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk1" - - disk { - // note: default qcow2 is not supported by lvm (?) - file_format = "raw" - datastore_id = "local-lvm" - interface = "virtio0" - size = 8 - } - }`), - Check: resource.ComposeTestCheckFunc( - ResourceAttributes("proxmox_virtual_environment_vm.test_disk1", map[string]string{ - "disk.0.aio": "io_uring", - "disk.0.backup": "true", - "disk.0.cache": "none", - "disk.0.discard": "ignore", - "disk.0.file_id": "", - "disk.0.datastore_id": "local-lvm", - "disk.0.file_format": "raw", - "disk.0.interface": "virtio0", - "disk.0.iothread": "false", - "disk.0.path_in_datastore": `vm-\d+-disk-\d+`, - "disk.0.replicate": "true", - "disk.0.size": "8", - "disk.0.ssd": "false", - }), - ), - }, - { - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_vm" "test_disk1" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk1" - - disk { - // note: default qcow2 is not supported by lvm (?) - file_format = "raw" - datastore_id = "local-lvm" - interface = "virtio0" - size = 8 - replicate = false - aio = "native" - speed { - iops_read = 100 - iops_read_burstable = 1000 - iops_write = 400 - iops_write_burstable = 800 - } - } - }`), - Check: resource.ComposeTestCheckFunc( - ResourceAttributes("proxmox_virtual_environment_vm.test_disk1", map[string]string{ - "disk.0.aio": "native", - "disk.0.backup": "true", - "disk.0.cache": "none", - "disk.0.discard": "ignore", - "disk.0.file_id": "", - "disk.0.datastore_id": "local-lvm", - "disk.0.file_format": "raw", - "disk.0.interface": "virtio0", - "disk.0.iothread": "false", - "disk.0.path_in_datastore": `vm-\d+-disk-\d+`, - "disk.0.replicate": "false", - "disk.0.size": "8", - "disk.0.ssd": "false", - "disk.0.speed.0.iops_read": "100", - "disk.0.speed.0.iops_read_burstable": "1000", - "disk.0.speed.0.iops_write": "400", - "disk.0.speed.0.iops_write_burstable": "800", - }), - ), - }, - }}, - {"create disk from an image", []resource.TestStep{{ - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_download_file" "test_disk2_image" { - content_type = "iso" - datastore_id = "local" - node_name = "{{.NodeName}}" - url = "{{.CloudImagesServer}}/jammy/current/jammy-server-cloudimg-amd64.img" - overwrite_unmanaged = true - } - resource "proxmox_virtual_environment_vm" "test_disk2" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk2" - disk { - datastore_id = "local-lvm" - file_id = proxmox_virtual_environment_download_file.test_disk2_image.id - interface = "virtio0" - iothread = true - discard = "on" - size = 20 - } - }`), - Check: resource.ComposeTestCheckFunc( - ResourceAttributes("proxmox_virtual_environment_vm.test_disk2", map[string]string{ - "disk.0.cache": "none", - "disk.0.datastore_id": "local-lvm", - "disk.0.discard": "on", - "disk.0.file_format": "raw", - "disk.0.interface": "virtio0", - "disk.0.iothread": "true", - "disk.0.path_in_datastore": `vm-\d+-disk-\d+`, - "disk.0.size": "20", - "disk.0.ssd": "false", - }), - ), - }}}, - {"clone default disk without overrides", []resource.TestStep{ - { - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_vm" "test_disk3_template" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk3-template" - template = "true" - - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "virtio0" - size = 8 - } - } - resource "proxmox_virtual_environment_vm" "test_disk3" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk3" - - clone { - vm_id = proxmox_virtual_environment_vm.test_disk3_template.id - } - }`), - Check: resource.ComposeTestCheckFunc( - // fully cloned disk, does not have any attributes in state - resource.TestCheckNoResourceAttr("proxmox_virtual_environment_vm.test_disk3", "disk.0"), - ResourceAttributes("proxmox_virtual_environment_vm.test_disk3", map[string]string{}), - ), - }, - { - RefreshState: true, - }, - }}, - {"multiple disks", []resource.TestStep{ - { - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_vm" "test_disk4" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk4" - template = "true" - - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "virtio0" - size = 8 - } - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "scsi0" - size = 8 - } - }`), - Check: ResourceAttributes("proxmox_virtual_environment_vm.test_disk4", map[string]string{ - "disk.0.interface": "virtio0", - "disk.0.path_in_datastore": `vm-\d+-disk-1`, - "disk.1.interface": "scsi0", - "disk.1.path_in_datastore": `vm-\d+-disk-0`, - }), - }, - { - RefreshState: true, - }, - }}, - {"adding disks", []resource.TestStep{ - { - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_vm" "test_disk" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk" - - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "scsi0" - size = 8 - } - }`), - Check: ResourceAttributes("proxmox_virtual_environment_vm.test_disk", map[string]string{ - "disk.0.interface": "scsi0", - "disk.0.path_in_datastore": `vm-\d+-disk-0`, - }), - }, - { - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_vm" "test_disk" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk" - - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "scsi0" - size = 8 - } - - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "scsi1" - size = 8 - } - }`), - ConfigPlanChecks: resource.ConfigPlanChecks{ - PreApply: []plancheck.PlanCheck{ - plancheck.ExpectResourceAction("proxmox_virtual_environment_vm.test_disk", plancheck.ResourceActionUpdate), - }, - }, - Check: ResourceAttributes("proxmox_virtual_environment_vm.test_disk", map[string]string{ - "disk.0.interface": "scsi0", - "disk.0.path_in_datastore": `vm-\d+-disk-0`, - "disk.1.interface": "scsi1", - "disk.1.path_in_datastore": `vm-\d+-disk-1`, - }), - }, - { - RefreshState: true, - }, - }}, - {"removing disks", []resource.TestStep{ - { - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_vm" "test_disk" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk" - - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "scsi0" - size = 8 - } - - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "scsi1" - size = 8 - } - }`), - Check: ResourceAttributes("proxmox_virtual_environment_vm.test_disk", map[string]string{ - "disk.0.interface": "scsi0", - "disk.0.path_in_datastore": `vm-\d+-disk-0`, - "disk.1.interface": "scsi1", - "disk.1.path_in_datastore": `vm-\d+-disk-1`, - }), - }, - { - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_vm" "test_disk" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk" - - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "scsi0" - size = 8 - } - }`), - ExpectError: regexp.MustCompile(`deletion of disks not supported`), - }, - }}, - - {"cdrom", []resource.TestStep{ - { - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_vm" "test_cdrom" { - node_name = "{{.NodeName}}" - started = false - name = "test-cdrom" - cdrom { - enabled = true - } - }`), - Check: resource.ComposeTestCheckFunc( - ResourceAttributes("proxmox_virtual_environment_vm.test_cdrom", map[string]string{ - "cdrom.0.enabled": "true", - }), - ), - }, - { - RefreshState: true, - }, - }}, - {"efi disk", []resource.TestStep{ - { - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_vm" "test_efi_disk" { - node_name = "{{.NodeName}}" - started = false - name = "test-efi-disk" - - efi_disk { - datastore_id = "local-lvm" - type = "4m" - } - }`), - Check: resource.ComposeTestCheckFunc( - ResourceAttributes("proxmox_virtual_environment_vm.test_efi_disk", map[string]string{ - "efi_disk.0.datastore_id": "local-lvm", - "efi_disk.0.type": "4m", - }), - ), - }, - { - RefreshState: true, - }, - }}, - {"ide disks", []resource.TestStep{ - { - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_vm" "test_disks" { - node_name = "{{.NodeName}}" - started = false - name = "test-disks-ide" - - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "ide0" - size = 8 - } - }`), - Check: ResourceAttributes("proxmox_virtual_environment_vm.test_disks", map[string]string{ - "disk.0.interface": "ide0", - "disk.0.path_in_datastore": `vm-\d+-disk-0`, - }), - }, - { - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_vm" "test_disks" { - node_name = "{{.NodeName}}" - started = false - name = "test-disks-ide" - - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "ide0" - size = 8 - } - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "ide1" - size = 8 - } - }`), - Check: ResourceAttributes("proxmox_virtual_environment_vm.test_disks", map[string]string{ - "disk.#": "2", - }), - }, - { - RefreshState: true, - }, - }}, - {"clone disk with overrides", []resource.TestStep{ - { - SkipFunc: func() (bool, error) { - // this test is failing because of https://github.com/bpg/terraform-provider-proxmox/issues/873 - return true, nil - }, - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_vm" "test_disk3_template" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk3-template" - template = "true" - - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "scsi0" - size = 8 - discard = "on" - iothread = true - ssd = true - } - } - resource "proxmox_virtual_environment_vm" "test_disk3" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk3" - - clone { - vm_id = proxmox_virtual_environment_vm.test_disk3_template.id - } - - disk { - interface = "scsi0" - //size = 10 - } - }`), - Check: ResourceAttributes("proxmox_virtual_environment_vm.test_disk3", map[string]string{ - "disk.0.datastore_id": "local-lvm", - "disk.0.discard": "on", - "disk.0.file_format": "raw", - "disk.0.interface": "scsi0", - "disk.0.iothread": "true", - "disk.0.path_in_datastore": `vm-\d+-disk-\d+`, - "disk.0.size": "8", - "disk.0.ssd": "true", - }), - }, - { - RefreshState: true, - Destroy: false, - }, - }}, - {"clone with disk resize", []resource.TestStep{ - { - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_vm" "test_disk3_template" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk3-template" - template = "true" - - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "virtio0" - size = 8 - } - } - resource "proxmox_virtual_environment_vm" "test_disk3" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk3" - - clone { - vm_id = proxmox_virtual_environment_vm.test_disk3_template.id - } - - disk { - datastore_id = "local-lvm" - interface = "virtio0" - size = 10 - } - }`), - Check: resource.ComposeTestCheckFunc( - ResourceAttributes("proxmox_virtual_environment_vm.test_disk3", map[string]string{ - "disk.0.datastore_id": "local-lvm", - "disk.0.interface": "virtio0", - "disk.0.size": "10", - }), - ), - }, - { - RefreshState: true, - }, - }}, - {"clone with adding disk", []resource.TestStep{ - { - SkipFunc: func() (bool, error) { - // this test is failing because of "Attribute 'disk.1.size' expected to be set" - return true, nil - }, - Config: te.RenderConfig(` - resource "proxmox_virtual_environment_vm" "test_disk3_template" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk3-template" - template = "true" - - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "virtio0" - size = 8 - } - } - resource "proxmox_virtual_environment_vm" "test_disk3" { - node_name = "{{.NodeName}}" - started = false - name = "test-disk3" - - clone { - vm_id = proxmox_virtual_environment_vm.test_disk3_template.id - } - - disk { - file_format = "raw" - datastore_id = "local-lvm" - interface = "scsi0" - size = 10 - } - }`), - Check: resource.ComposeTestCheckFunc( - ResourceAttributes("proxmox_virtual_environment_vm.test_disk3", map[string]string{ - "disk.1.datastore_id": "local-lvm", - "disk.1.interface": "virtio0", - "disk.1.size": "8", - "disk.0.datastore_id": "local-lvm", - "disk.0.interface": "scsi0", - "disk.0.size": "10", - }), - ), - }, - { - RefreshState: true, - }, - }}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - - resource.Test(t, resource.TestCase{ - ProtoV6ProviderFactories: te.AccProviders, - Steps: tt.steps, - }) - }) - } -} diff --git a/proxmoxtf/resource/vm/vm.go b/proxmoxtf/resource/vm/vm.go index 95f53c19..f546c7f0 100644 --- a/proxmoxtf/resource/vm/vm.go +++ b/proxmoxtf/resource/vm/vm.go @@ -427,11 +427,14 @@ func VM() *schema.Resource { Default: dvCDROMEnabled, }, mkCDROMFileID: { - Type: schema.TypeString, - Description: "The file id", - Optional: true, - Default: dvCDROMFileID, - ValidateDiagFunc: validators.FileID(), + Type: schema.TypeString, + Description: "The file id", + Optional: true, + Default: dvCDROMFileID, + ValidateDiagFunc: validation.AnyDiag( + validation.ToDiagFunc(validation.StringInSlice([]string{"none", "cdrom"}, false)), + validators.FileID(), + ), }, mkCDROMInterface: { Type: schema.TypeString,