mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-07-10 15:55:01 +00:00
messing with disks
Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
parent
f04b729db2
commit
5bf5754cb3
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -1,9 +1,13 @@
|
|||||||
{
|
{
|
||||||
"git.alwaysSignOff": true,
|
"git.alwaysSignOff": true,
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
|
"Burstable",
|
||||||
|
"cdrom",
|
||||||
"CLRF",
|
"CLRF",
|
||||||
"iothread",
|
"iothread",
|
||||||
"keyctl",
|
"keyctl",
|
||||||
|
"mbps",
|
||||||
|
"NUMA",
|
||||||
"proxmoxtf",
|
"proxmoxtf",
|
||||||
"qcow",
|
"qcow",
|
||||||
"rootfs",
|
"rootfs",
|
||||||
|
@ -8,15 +8,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func createAgent(d *schema.ResourceData, updateBody *vms.UpdateRequestBody) {
|
func createAgent(d *schema.ResourceData, updateBody *vms.UpdateRequestBody) {
|
||||||
agent := d.Get(mkResourceVirtualEnvironmentVMAgent).([]interface{})
|
agent := d.Get(mkAgent).([]interface{})
|
||||||
if len(agent) > 0 {
|
if len(agent) > 0 {
|
||||||
agentBlock := agent[0].(map[string]interface{})
|
agentBlock := agent[0].(map[string]interface{})
|
||||||
|
|
||||||
agentEnabled := types.CustomBool(
|
agentEnabled := types.CustomBool(
|
||||||
agentBlock[mkResourceVirtualEnvironmentVMAgentEnabled].(bool),
|
agentBlock[mkAgentEnabled].(bool),
|
||||||
)
|
)
|
||||||
agentTrim := types.CustomBool(agentBlock[mkResourceVirtualEnvironmentVMAgentTrim].(bool))
|
agentTrim := types.CustomBool(agentBlock[mkAgentTrim].(bool))
|
||||||
agentType := agentBlock[mkResourceVirtualEnvironmentVMAgentType].(string)
|
agentType := agentBlock[mkAgentType].(string)
|
||||||
|
|
||||||
updateBody.Agent = &vms.CustomAgent{
|
updateBody.Agent = &vms.CustomAgent{
|
||||||
Enabled: &agentEnabled,
|
Enabled: &agentEnabled,
|
||||||
@ -30,7 +30,7 @@ func customAgent(d *schema.ResourceData, resource *schema.Resource) (*vms.Custom
|
|||||||
agentBlock, err := structure.GetSchemaBlock(
|
agentBlock, err := structure.GetSchemaBlock(
|
||||||
resource,
|
resource,
|
||||||
d,
|
d,
|
||||||
[]string{mkResourceVirtualEnvironmentVMAgent},
|
[]string{mkAgent},
|
||||||
0,
|
0,
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
@ -39,10 +39,10 @@ func customAgent(d *schema.ResourceData, resource *schema.Resource) (*vms.Custom
|
|||||||
}
|
}
|
||||||
|
|
||||||
agentEnabled := types.CustomBool(
|
agentEnabled := types.CustomBool(
|
||||||
agentBlock[mkResourceVirtualEnvironmentVMAgentEnabled].(bool),
|
agentBlock[mkAgentEnabled].(bool),
|
||||||
)
|
)
|
||||||
agentTrim := types.CustomBool(agentBlock[mkResourceVirtualEnvironmentVMAgentTrim].(bool))
|
agentTrim := types.CustomBool(agentBlock[mkAgentTrim].(bool))
|
||||||
agentType := agentBlock[mkResourceVirtualEnvironmentVMAgentType].(string)
|
agentType := agentBlock[mkAgentType].(string)
|
||||||
|
|
||||||
return &vms.CustomAgent{
|
return &vms.CustomAgent{
|
||||||
Enabled: &agentEnabled,
|
Enabled: &agentEnabled,
|
||||||
@ -53,64 +53,64 @@ func customAgent(d *schema.ResourceData, resource *schema.Resource) (*vms.Custom
|
|||||||
|
|
||||||
func setAgent(d *schema.ResourceData, clone bool, vmConfig *vms.GetResponseData) error {
|
func setAgent(d *schema.ResourceData, clone bool, vmConfig *vms.GetResponseData) error {
|
||||||
// Compare the agent configuration to the one stored in the state.
|
// Compare the agent configuration to the one stored in the state.
|
||||||
currentAgent := d.Get(mkResourceVirtualEnvironmentVMAgent).([]interface{})
|
currentAgent := d.Get(mkAgent).([]interface{})
|
||||||
|
|
||||||
if !clone || len(currentAgent) > 0 {
|
if !clone || len(currentAgent) > 0 {
|
||||||
if vmConfig.Agent != nil {
|
if vmConfig.Agent != nil {
|
||||||
agent := map[string]interface{}{}
|
agent := map[string]interface{}{}
|
||||||
|
|
||||||
if vmConfig.Agent.Enabled != nil {
|
if vmConfig.Agent.Enabled != nil {
|
||||||
agent[mkResourceVirtualEnvironmentVMAgentEnabled] = bool(*vmConfig.Agent.Enabled)
|
agent[mkAgentEnabled] = bool(*vmConfig.Agent.Enabled)
|
||||||
} else {
|
} else {
|
||||||
agent[mkResourceVirtualEnvironmentVMAgentEnabled] = false
|
agent[mkAgentEnabled] = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if vmConfig.Agent.TrimClonedDisks != nil {
|
if vmConfig.Agent.TrimClonedDisks != nil {
|
||||||
agent[mkResourceVirtualEnvironmentVMAgentTrim] = bool(
|
agent[mkAgentTrim] = bool(
|
||||||
*vmConfig.Agent.TrimClonedDisks,
|
*vmConfig.Agent.TrimClonedDisks,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
agent[mkResourceVirtualEnvironmentVMAgentTrim] = false
|
agent[mkAgentTrim] = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(currentAgent) > 0 {
|
if len(currentAgent) > 0 {
|
||||||
currentAgentBlock := currentAgent[0].(map[string]interface{})
|
currentAgentBlock := currentAgent[0].(map[string]interface{})
|
||||||
currentAgentTimeout := currentAgentBlock[mkResourceVirtualEnvironmentVMAgentTimeout].(string)
|
currentAgentTimeout := currentAgentBlock[mkAgentTimeout].(string)
|
||||||
|
|
||||||
if currentAgentTimeout != "" {
|
if currentAgentTimeout != "" {
|
||||||
agent[mkResourceVirtualEnvironmentVMAgentTimeout] = currentAgentTimeout
|
agent[mkAgentTimeout] = currentAgentTimeout
|
||||||
} else {
|
} else {
|
||||||
agent[mkResourceVirtualEnvironmentVMAgentTimeout] = dvResourceVirtualEnvironmentVMAgentTimeout
|
agent[mkAgentTimeout] = dvAgentTimeout
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
agent[mkResourceVirtualEnvironmentVMAgentTimeout] = dvResourceVirtualEnvironmentVMAgentTimeout
|
agent[mkAgentTimeout] = dvAgentTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
if vmConfig.Agent.Type != nil {
|
if vmConfig.Agent.Type != nil {
|
||||||
agent[mkResourceVirtualEnvironmentVMAgentType] = *vmConfig.Agent.Type
|
agent[mkAgentType] = *vmConfig.Agent.Type
|
||||||
} else {
|
} else {
|
||||||
agent[mkResourceVirtualEnvironmentVMAgentType] = ""
|
agent[mkAgentType] = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
if clone {
|
if clone {
|
||||||
if len(currentAgent) > 0 {
|
if len(currentAgent) > 0 {
|
||||||
return d.Set(mkResourceVirtualEnvironmentVMAgent, []interface{}{agent})
|
return d.Set(mkAgent, []interface{}{agent})
|
||||||
}
|
}
|
||||||
} else if len(currentAgent) > 0 ||
|
} else if len(currentAgent) > 0 ||
|
||||||
agent[mkResourceVirtualEnvironmentVMAgentEnabled] != dvResourceVirtualEnvironmentVMAgentEnabled ||
|
agent[mkAgentEnabled] != dvAgentEnabled ||
|
||||||
agent[mkResourceVirtualEnvironmentVMAgentTimeout] != dvResourceVirtualEnvironmentVMAgentTimeout ||
|
agent[mkAgentTimeout] != dvAgentTimeout ||
|
||||||
agent[mkResourceVirtualEnvironmentVMAgentTrim] != dvResourceVirtualEnvironmentVMAgentTrim ||
|
agent[mkAgentTrim] != dvAgentTrim ||
|
||||||
agent[mkResourceVirtualEnvironmentVMAgentType] != dvResourceVirtualEnvironmentVMAgentType {
|
agent[mkAgentType] != dvAgentType {
|
||||||
return d.Set(mkResourceVirtualEnvironmentVMAgent, []interface{}{agent})
|
return d.Set(mkAgent, []interface{}{agent})
|
||||||
|
|
||||||
}
|
}
|
||||||
} else if clone {
|
} else if clone {
|
||||||
if len(currentAgent) > 0 {
|
if len(currentAgent) > 0 {
|
||||||
return d.Set(mkResourceVirtualEnvironmentVMAgent, []interface{}{})
|
return d.Set(mkAgent, []interface{}{})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return d.Set(mkResourceVirtualEnvironmentVMAgent, []interface{}{})
|
return d.Set(mkAgent, []interface{}{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
753
proxmoxtf/resource/vm/disk.go
Normal file
753
proxmoxtf/resource/vm/disk.go
Normal file
@ -0,0 +1,753 @@
|
|||||||
|
package vm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/vms"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/validator"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure"
|
||||||
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||||
|
)
|
||||||
|
|
||||||
|
func diskSchema() *schema.Schema {
|
||||||
|
return &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The disk devices",
|
||||||
|
Optional: true,
|
||||||
|
DefaultFunc: func() (interface{}, error) {
|
||||||
|
return []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
mkDiskDatastoreID: dvDiskDatastoreID,
|
||||||
|
mkDiskPathInDatastore: nil,
|
||||||
|
mkDiskFileID: dvDiskFileID,
|
||||||
|
mkDiskInterface: dvDiskInterface,
|
||||||
|
mkDiskSize: dvDiskSize,
|
||||||
|
mkDiskIOThread: dvDiskIOThread,
|
||||||
|
mkDiskSSD: dvDiskSSD,
|
||||||
|
mkDiskDiscard: dvDiskDiscard,
|
||||||
|
mkDiskCache: dvDiskCache,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkDiskInterface: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The datastore name",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
mkDiskDatastoreID: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The datastore id",
|
||||||
|
Optional: true,
|
||||||
|
Default: dvDiskDatastoreID,
|
||||||
|
},
|
||||||
|
mkDiskPathInDatastore: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The in-datastore path to disk image",
|
||||||
|
Computed: true,
|
||||||
|
Optional: true,
|
||||||
|
Default: nil,
|
||||||
|
},
|
||||||
|
mkDiskFileFormat: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The file format",
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Computed: true,
|
||||||
|
ValidateDiagFunc: validator.FileFormat(),
|
||||||
|
},
|
||||||
|
mkDiskFileID: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The file id for a disk image",
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Default: dvDiskFileID,
|
||||||
|
ValidateDiagFunc: validator.FileID(),
|
||||||
|
},
|
||||||
|
mkDiskSize: {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Description: "The disk size in gigabytes",
|
||||||
|
Optional: true,
|
||||||
|
Default: dvDiskSize,
|
||||||
|
ValidateDiagFunc: validation.ToDiagFunc(validation.IntAtLeast(1)),
|
||||||
|
},
|
||||||
|
mkDiskIOThread: {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Description: "Whether to use iothreads for this disk drive",
|
||||||
|
Optional: true,
|
||||||
|
Default: dvDiskIOThread,
|
||||||
|
},
|
||||||
|
mkDiskSSD: {
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Description: "Whether to use ssd for this disk drive",
|
||||||
|
Optional: true,
|
||||||
|
Default: dvDiskSSD,
|
||||||
|
},
|
||||||
|
mkDiskDiscard: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "Whether to pass discard/trim requests to the underlying storage.",
|
||||||
|
Optional: true,
|
||||||
|
Default: dvDiskDiscard,
|
||||||
|
},
|
||||||
|
mkDiskCache: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The drive’s cache mode",
|
||||||
|
Optional: true,
|
||||||
|
Default: dvDiskCache,
|
||||||
|
ValidateDiagFunc: validation.ToDiagFunc(
|
||||||
|
validation.StringInSlice([]string{
|
||||||
|
"none",
|
||||||
|
"writethrough",
|
||||||
|
"writeback",
|
||||||
|
"unsafe",
|
||||||
|
"directsync",
|
||||||
|
}, false),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
mkDiskSpeed: {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The speed limits",
|
||||||
|
Optional: true,
|
||||||
|
DefaultFunc: func() (interface{}, error) {
|
||||||
|
return []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
mkDiskSpeedRead: dvDiskSpeedRead,
|
||||||
|
mkDiskSpeedReadBurstable: dvDiskSpeedReadBurstable,
|
||||||
|
mkDiskSpeedWrite: dvDiskSpeedWrite,
|
||||||
|
mkDiskSpeedWriteBurstable: dvDiskSpeedWriteBurstable,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkDiskSpeedRead: {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Description: "The maximum read speed in megabytes per second",
|
||||||
|
Optional: true,
|
||||||
|
Default: dvDiskSpeedRead,
|
||||||
|
},
|
||||||
|
mkDiskSpeedReadBurstable: {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Description: "The maximum burstable read speed in megabytes per second",
|
||||||
|
Optional: true,
|
||||||
|
Default: dvDiskSpeedReadBurstable,
|
||||||
|
},
|
||||||
|
mkDiskSpeedWrite: {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Description: "The maximum write speed in megabytes per second",
|
||||||
|
Optional: true,
|
||||||
|
Default: dvDiskSpeedWrite,
|
||||||
|
},
|
||||||
|
mkDiskSpeedWriteBurstable: {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Description: "The maximum burstable write speed in megabytes per second",
|
||||||
|
Optional: true,
|
||||||
|
Default: dvDiskSpeedWriteBurstable,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MaxItems: 1,
|
||||||
|
MinItems: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateDisk1(
|
||||||
|
ctx context.Context, vmConfig *vms.GetResponseData, d *schema.ResourceData, vmAPI *vms.Client,
|
||||||
|
) (map[string]*vms.CustomStorageDevice, error) {
|
||||||
|
allDiskInfo := getDiskInfo(vmConfig, d)
|
||||||
|
|
||||||
|
diskDeviceObjects, e := vmGetDiskDeviceObjects(d, nil)
|
||||||
|
if e != nil {
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
|
||||||
|
disk := d.Get(mkDisk).([]interface{})
|
||||||
|
for i := range disk {
|
||||||
|
diskBlock := disk[i].(map[string]interface{})
|
||||||
|
diskInterface := diskBlock[mkDiskInterface].(string)
|
||||||
|
dataStoreID := diskBlock[mkDiskDatastoreID].(string)
|
||||||
|
diskSize := int64(diskBlock[mkDiskSize].(int))
|
||||||
|
prefix := diskDigitPrefix(diskInterface)
|
||||||
|
|
||||||
|
currentDiskInfo := allDiskInfo[diskInterface]
|
||||||
|
configuredDiskInfo := diskDeviceObjects[prefix][diskInterface]
|
||||||
|
|
||||||
|
if currentDiskInfo == nil {
|
||||||
|
diskUpdateBody := &vms.UpdateRequestBody{}
|
||||||
|
|
||||||
|
switch prefix {
|
||||||
|
case "virtio":
|
||||||
|
if diskUpdateBody.VirtualIODevices == nil {
|
||||||
|
diskUpdateBody.VirtualIODevices = vms.CustomStorageDevices{}
|
||||||
|
}
|
||||||
|
|
||||||
|
diskUpdateBody.VirtualIODevices[diskInterface] = configuredDiskInfo
|
||||||
|
case "sata":
|
||||||
|
if diskUpdateBody.SATADevices == nil {
|
||||||
|
diskUpdateBody.SATADevices = vms.CustomStorageDevices{}
|
||||||
|
}
|
||||||
|
|
||||||
|
diskUpdateBody.SATADevices[diskInterface] = configuredDiskInfo
|
||||||
|
case "scsi":
|
||||||
|
if diskUpdateBody.SCSIDevices == nil {
|
||||||
|
diskUpdateBody.SCSIDevices = vms.CustomStorageDevices{}
|
||||||
|
}
|
||||||
|
|
||||||
|
diskUpdateBody.SCSIDevices[diskInterface] = configuredDiskInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
e = vmAPI.UpdateVM(ctx, diskUpdateBody)
|
||||||
|
if e != nil {
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if diskSize < currentDiskInfo.Size.InGigabytes() {
|
||||||
|
return nil, fmt.Errorf("disk resize fails requests size (%dG) is lower than current size (%s)",
|
||||||
|
diskSize,
|
||||||
|
*currentDiskInfo.Size,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteOriginalDisk := types.CustomBool(true)
|
||||||
|
|
||||||
|
diskMoveBody := &vms.MoveDiskRequestBody{
|
||||||
|
DeleteOriginalDisk: &deleteOriginalDisk,
|
||||||
|
Disk: diskInterface,
|
||||||
|
TargetStorage: dataStoreID,
|
||||||
|
}
|
||||||
|
|
||||||
|
diskResizeBody := &vms.ResizeDiskRequestBody{
|
||||||
|
Disk: diskInterface,
|
||||||
|
Size: types.DiskSizeFromGigabytes(diskSize),
|
||||||
|
}
|
||||||
|
|
||||||
|
moveDisk := false
|
||||||
|
|
||||||
|
if dataStoreID != "" {
|
||||||
|
moveDisk = true
|
||||||
|
|
||||||
|
if allDiskInfo[diskInterface] != nil {
|
||||||
|
fileIDParts := strings.Split(allDiskInfo[diskInterface].FileVolume, ":")
|
||||||
|
moveDisk = dataStoreID != fileIDParts[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if moveDisk {
|
||||||
|
moveDiskTimeout := d.Get(mkTimeoutMoveDisk).(int)
|
||||||
|
|
||||||
|
e = vmAPI.MoveVMDisk(ctx, diskMoveBody, moveDiskTimeout)
|
||||||
|
if e != nil {
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if diskSize > currentDiskInfo.Size.InGigabytes() {
|
||||||
|
e = vmAPI.ResizeVMDisk(ctx, diskResizeBody)
|
||||||
|
if e != nil {
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allDiskInfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func vmCreateCustomDisks(ctx context.Context, d *schema.ResourceData, m interface{}) error {
|
||||||
|
vmID, err := strconv.Atoi(d.Id())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the ID of the next disk.
|
||||||
|
disk := d.Get(mkDisk).([]interface{})
|
||||||
|
diskCount := 0
|
||||||
|
|
||||||
|
for _, d := range disk {
|
||||||
|
block := d.(map[string]interface{})
|
||||||
|
fileID, _ := block[mkDiskFileID].(string)
|
||||||
|
|
||||||
|
if fileID == "" {
|
||||||
|
diskCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve some information about the disk schema.
|
||||||
|
resourceSchema := VM().Schema
|
||||||
|
diskSchemaElem := resourceSchema[mkDisk].Elem
|
||||||
|
diskSchemaResource := diskSchemaElem.(*schema.Resource)
|
||||||
|
diskSpeedResource := diskSchemaResource.Schema[mkDiskSpeed]
|
||||||
|
|
||||||
|
// Generate the commands required to import the specified disks.
|
||||||
|
commands := []string{}
|
||||||
|
importedDiskCount := 0
|
||||||
|
|
||||||
|
for _, d := range disk {
|
||||||
|
block := d.(map[string]interface{})
|
||||||
|
|
||||||
|
fileID, _ := block[mkDiskFileID].(string)
|
||||||
|
|
||||||
|
if fileID == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
datastoreID, _ := block[mkDiskDatastoreID].(string)
|
||||||
|
fileFormat, _ := block[mkDiskFileFormat].(string)
|
||||||
|
size, _ := block[mkDiskSize].(int)
|
||||||
|
speed := block[mkDiskSpeed].([]interface{})
|
||||||
|
diskInterface, _ := block[mkDiskInterface].(string)
|
||||||
|
ioThread := types.CustomBool(block[mkDiskIOThread].(bool))
|
||||||
|
ssd := types.CustomBool(block[mkDiskSSD].(bool))
|
||||||
|
discard, _ := block[mkDiskDiscard].(string)
|
||||||
|
cache, _ := block[mkDiskCache].(string)
|
||||||
|
|
||||||
|
if fileFormat == "" {
|
||||||
|
fileFormat = dvDiskFileFormat
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(speed) == 0 {
|
||||||
|
diskSpeedDefault, err := diskSpeedResource.DefaultValue()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
speed = diskSpeedDefault.([]interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
speedBlock := speed[0].(map[string]interface{})
|
||||||
|
speedLimitRead := speedBlock[mkDiskSpeedRead].(int)
|
||||||
|
speedLimitReadBurstable := speedBlock[mkDiskSpeedReadBurstable].(int)
|
||||||
|
speedLimitWrite := speedBlock[mkDiskSpeedWrite].(int)
|
||||||
|
speedLimitWriteBurstable := speedBlock[mkDiskSpeedWriteBurstable].(int)
|
||||||
|
|
||||||
|
diskOptions := ""
|
||||||
|
|
||||||
|
if ioThread {
|
||||||
|
diskOptions += ",iothread=1"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ssd {
|
||||||
|
diskOptions += ",ssd=1"
|
||||||
|
}
|
||||||
|
|
||||||
|
if discard != "" {
|
||||||
|
diskOptions += fmt.Sprintf(",discard=%s", discard)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cache != "" {
|
||||||
|
diskOptions += fmt.Sprintf(",cache=%s", cache)
|
||||||
|
}
|
||||||
|
|
||||||
|
if speedLimitRead > 0 {
|
||||||
|
diskOptions += fmt.Sprintf(",mbps_rd=%d", speedLimitRead)
|
||||||
|
}
|
||||||
|
|
||||||
|
if speedLimitReadBurstable > 0 {
|
||||||
|
diskOptions += fmt.Sprintf(",mbps_rd_max=%d", speedLimitReadBurstable)
|
||||||
|
}
|
||||||
|
|
||||||
|
if speedLimitWrite > 0 {
|
||||||
|
diskOptions += fmt.Sprintf(",mbps_wr=%d", speedLimitWrite)
|
||||||
|
}
|
||||||
|
|
||||||
|
if speedLimitWriteBurstable > 0 {
|
||||||
|
diskOptions += fmt.Sprintf(",mbps_wr_max=%d", speedLimitWriteBurstable)
|
||||||
|
}
|
||||||
|
|
||||||
|
filePathTmp := fmt.Sprintf(
|
||||||
|
"/tmp/vm-%d-disk-%d.%s",
|
||||||
|
vmID,
|
||||||
|
diskCount+importedDiskCount,
|
||||||
|
fileFormat,
|
||||||
|
)
|
||||||
|
|
||||||
|
//nolint:lll
|
||||||
|
commands = append(
|
||||||
|
commands,
|
||||||
|
`set -e`,
|
||||||
|
`try_sudo(){ if [ $(sudo -n echo tfpve 2>&1 | grep "tfpve" | wc -l) -gt 0 ]; then sudo $1; else $1; fi }`,
|
||||||
|
fmt.Sprintf(`file_id="%s"`, fileID),
|
||||||
|
fmt.Sprintf(`file_format="%s"`, fileFormat),
|
||||||
|
fmt.Sprintf(`datastore_id_target="%s"`, datastoreID),
|
||||||
|
fmt.Sprintf(`disk_options="%s"`, diskOptions),
|
||||||
|
fmt.Sprintf(`disk_size="%d"`, size),
|
||||||
|
fmt.Sprintf(`disk_interface="%s"`, diskInterface),
|
||||||
|
fmt.Sprintf(`file_path_tmp="%s"`, filePathTmp),
|
||||||
|
fmt.Sprintf(`vm_id="%d"`, vmID),
|
||||||
|
`source_image=$(try_sudo "pvesm path $file_id")`,
|
||||||
|
`imported_disk="$(try_sudo "qm importdisk $vm_id $source_image $datastore_id_target -format $file_format" | grep "unused0" | cut -d ":" -f 3 | cut -d "'" -f 1)"`,
|
||||||
|
`disk_id="${datastore_id_target}:$imported_disk${disk_options}"`,
|
||||||
|
`try_sudo "qm set $vm_id -${disk_interface} $disk_id"`,
|
||||||
|
`try_sudo "qm resize $vm_id ${disk_interface} ${disk_size}G"`,
|
||||||
|
)
|
||||||
|
|
||||||
|
importedDiskCount++
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the commands on the node and wait for the result.
|
||||||
|
// This is a highly experimental approach to disk imports and is not recommended by Proxmox.
|
||||||
|
if len(commands) > 0 {
|
||||||
|
config := m.(proxmoxtf.ProviderConfiguration)
|
||||||
|
|
||||||
|
api, err := config.GetClient()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeName := d.Get(mkNodeName).(string)
|
||||||
|
|
||||||
|
out, err := api.SSH().ExecuteNodeCommands(ctx, nodeName, commands)
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "pvesm: not found") {
|
||||||
|
return fmt.Errorf("The configured SSH user '%s' does not have the required permissions to import disks. "+
|
||||||
|
"Make sure `sudo` is installed and the user is a member of sudoers.", api.SSH().Username())
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tflog.Debug(ctx, "vmCreateCustomDisks", map[string]interface{}{
|
||||||
|
"output": string(out),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func vmGetDiskDeviceObjects(
|
||||||
|
d *schema.ResourceData,
|
||||||
|
disks []interface{},
|
||||||
|
) (map[string]map[string]vms.CustomStorageDevice, error) {
|
||||||
|
var diskDevice []interface{}
|
||||||
|
|
||||||
|
if disks != nil {
|
||||||
|
diskDevice = disks
|
||||||
|
} else {
|
||||||
|
diskDevice = d.Get(mkDisk).([]interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
diskDeviceObjects := map[string]map[string]vms.CustomStorageDevice{}
|
||||||
|
resource := VM()
|
||||||
|
|
||||||
|
for _, diskEntry := range diskDevice {
|
||||||
|
diskDevice := vms.CustomStorageDevice{
|
||||||
|
Enabled: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
block := diskEntry.(map[string]interface{})
|
||||||
|
datastoreID, _ := block[mkDiskDatastoreID].(string)
|
||||||
|
pathInDatastore := ""
|
||||||
|
|
||||||
|
if untyped, hasPathInDatastore := block[mkDiskPathInDatastore]; hasPathInDatastore {
|
||||||
|
pathInDatastore = untyped.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
fileFormat, _ := block[mkDiskFileFormat].(string)
|
||||||
|
fileID, _ := block[mkDiskFileID].(string)
|
||||||
|
size, _ := block[mkDiskSize].(int)
|
||||||
|
diskInterface, _ := block[mkDiskInterface].(string)
|
||||||
|
ioThread := types.CustomBool(block[mkDiskIOThread].(bool))
|
||||||
|
ssd := types.CustomBool(block[mkDiskSSD].(bool))
|
||||||
|
discard := block[mkDiskDiscard].(string)
|
||||||
|
cache := block[mkDiskCache].(string)
|
||||||
|
|
||||||
|
speedBlock, err := structure.GetSchemaBlock(
|
||||||
|
resource,
|
||||||
|
d,
|
||||||
|
[]string{mkDisk, mkDiskSpeed},
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return diskDeviceObjects, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if fileFormat == "" {
|
||||||
|
fileFormat = dvDiskFileFormat
|
||||||
|
}
|
||||||
|
|
||||||
|
if fileID != "" {
|
||||||
|
diskDevice.Enabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if pathInDatastore != "" {
|
||||||
|
if datastoreID != "" {
|
||||||
|
diskDevice.FileVolume = fmt.Sprintf("%s:%s", datastoreID, pathInDatastore)
|
||||||
|
} else {
|
||||||
|
// FileVolume is absolute path in the host filesystem
|
||||||
|
diskDevice.FileVolume = pathInDatastore
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
diskDevice.FileVolume = fmt.Sprintf("%s:%d", datastoreID, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
diskDevice.ID = &datastoreID
|
||||||
|
diskDevice.Interface = &diskInterface
|
||||||
|
diskDevice.Format = &fileFormat
|
||||||
|
diskDevice.FileID = &fileID
|
||||||
|
diskSize := types.DiskSizeFromGigabytes(int64(size))
|
||||||
|
diskDevice.Size = &diskSize
|
||||||
|
diskDevice.IOThread = &ioThread
|
||||||
|
diskDevice.Discard = &discard
|
||||||
|
diskDevice.Cache = &cache
|
||||||
|
|
||||||
|
if !strings.HasPrefix(diskInterface, "virtio") {
|
||||||
|
diskDevice.SSD = &ssd
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(speedBlock) > 0 {
|
||||||
|
speedLimitRead := speedBlock[mkDiskSpeedRead].(int)
|
||||||
|
speedLimitReadBurstable := speedBlock[mkDiskSpeedReadBurstable].(int)
|
||||||
|
speedLimitWrite := speedBlock[mkDiskSpeedWrite].(int)
|
||||||
|
speedLimitWriteBurstable := speedBlock[mkDiskSpeedWriteBurstable].(int)
|
||||||
|
|
||||||
|
if speedLimitRead > 0 {
|
||||||
|
diskDevice.MaxReadSpeedMbps = &speedLimitRead
|
||||||
|
}
|
||||||
|
|
||||||
|
if speedLimitReadBurstable > 0 {
|
||||||
|
diskDevice.BurstableReadSpeedMbps = &speedLimitReadBurstable
|
||||||
|
}
|
||||||
|
|
||||||
|
if speedLimitWrite > 0 {
|
||||||
|
diskDevice.MaxWriteSpeedMbps = &speedLimitWrite
|
||||||
|
}
|
||||||
|
|
||||||
|
if speedLimitWriteBurstable > 0 {
|
||||||
|
diskDevice.BurstableWriteSpeedMbps = &speedLimitWriteBurstable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
baseDiskInterface := diskDigitPrefix(diskInterface)
|
||||||
|
|
||||||
|
if baseDiskInterface != "virtio" && baseDiskInterface != "scsi" &&
|
||||||
|
baseDiskInterface != "sata" {
|
||||||
|
errorMsg := fmt.Sprintf(
|
||||||
|
"Defined disk interface not supported. Interface was %s, but only virtio, sata and scsi are supported",
|
||||||
|
diskInterface,
|
||||||
|
)
|
||||||
|
|
||||||
|
return diskDeviceObjects, errors.New(errorMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, present := diskDeviceObjects[baseDiskInterface]; !present {
|
||||||
|
diskDeviceObjects[baseDiskInterface] = map[string]vms.CustomStorageDevice{}
|
||||||
|
}
|
||||||
|
|
||||||
|
diskDeviceObjects[baseDiskInterface][diskInterface] = diskDevice
|
||||||
|
}
|
||||||
|
|
||||||
|
return diskDeviceObjects, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readDisk1(ctx context.Context, d *schema.ResourceData,
|
||||||
|
vmConfig *vms.GetResponseData, vmID int, api proxmox.Client, nodeName string, clone []interface{},
|
||||||
|
) diag.Diagnostics {
|
||||||
|
currentDiskList := d.Get(mkDisk).([]interface{})
|
||||||
|
diskMap := map[string]interface{}{}
|
||||||
|
diskObjects := getDiskInfo(vmConfig, d)
|
||||||
|
|
||||||
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
|
for di, dd := range diskObjects {
|
||||||
|
if dd == nil || dd.FileVolume == "none" || strings.HasPrefix(di, "ide") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if dd.IsCloudInitDrive(vmID) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
disk := map[string]interface{}{}
|
||||||
|
|
||||||
|
datastoreID, pathInDatastore, hasDatastoreID := strings.Cut(dd.FileVolume, ":")
|
||||||
|
if !hasDatastoreID {
|
||||||
|
// when no ':' separator is found, 'Cut' places the whole string to 'datastoreID',
|
||||||
|
// we want it in 'pathInDatastore' (it is absolute filesystem path)
|
||||||
|
pathInDatastore = datastoreID
|
||||||
|
datastoreID = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
disk[mkDiskDatastoreID] = datastoreID
|
||||||
|
disk[mkDiskPathInDatastore] = pathInDatastore
|
||||||
|
|
||||||
|
if dd.Format == nil {
|
||||||
|
disk[mkDiskFileFormat] = dvDiskFileFormat
|
||||||
|
|
||||||
|
if datastoreID != "" {
|
||||||
|
// disk format may not be returned by config API if it is default for the storage, and that may be different
|
||||||
|
// from the default qcow2, so we need to read it from the storage API to make sure we have the correct value
|
||||||
|
volume, err := api.Node(nodeName).Storage(datastoreID).GetDatastoreFile(ctx, dd.FileVolume)
|
||||||
|
if err != nil {
|
||||||
|
diags = append(diags, diag.FromErr(err)...)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
disk[mkDiskFileFormat] = volume.FileFormat
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
disk[mkDiskFileFormat] = dd.Format
|
||||||
|
}
|
||||||
|
|
||||||
|
if dd.FileID != nil {
|
||||||
|
disk[mkDiskFileID] = dd.FileID
|
||||||
|
}
|
||||||
|
|
||||||
|
disk[mkDiskInterface] = di
|
||||||
|
disk[mkDiskSize] = dd.Size.InGigabytes()
|
||||||
|
|
||||||
|
if dd.BurstableReadSpeedMbps != nil ||
|
||||||
|
dd.BurstableWriteSpeedMbps != nil ||
|
||||||
|
dd.MaxReadSpeedMbps != nil ||
|
||||||
|
dd.MaxWriteSpeedMbps != nil {
|
||||||
|
speed := map[string]interface{}{}
|
||||||
|
|
||||||
|
if dd.MaxReadSpeedMbps != nil {
|
||||||
|
speed[mkDiskSpeedRead] = *dd.MaxReadSpeedMbps
|
||||||
|
} else {
|
||||||
|
speed[mkDiskSpeedRead] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if dd.BurstableReadSpeedMbps != nil {
|
||||||
|
speed[mkDiskSpeedReadBurstable] = *dd.BurstableReadSpeedMbps
|
||||||
|
} else {
|
||||||
|
speed[mkDiskSpeedReadBurstable] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if dd.MaxWriteSpeedMbps != nil {
|
||||||
|
speed[mkDiskSpeedWrite] = *dd.MaxWriteSpeedMbps
|
||||||
|
} else {
|
||||||
|
speed[mkDiskSpeedWrite] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if dd.BurstableWriteSpeedMbps != nil {
|
||||||
|
speed[mkDiskSpeedWriteBurstable] = *dd.BurstableWriteSpeedMbps
|
||||||
|
} else {
|
||||||
|
speed[mkDiskSpeedWriteBurstable] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
disk[mkDiskSpeed] = []interface{}{speed}
|
||||||
|
} else {
|
||||||
|
disk[mkDiskSpeed] = []interface{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if dd.IOThread != nil {
|
||||||
|
disk[mkDiskIOThread] = *dd.IOThread
|
||||||
|
} else {
|
||||||
|
disk[mkDiskIOThread] = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if dd.SSD != nil {
|
||||||
|
disk[mkDiskSSD] = *dd.SSD
|
||||||
|
} else {
|
||||||
|
disk[mkDiskSSD] = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if dd.Discard != nil {
|
||||||
|
disk[mkDiskDiscard] = *dd.Discard
|
||||||
|
} else {
|
||||||
|
disk[mkDiskDiscard] = dvDiskDiscard
|
||||||
|
}
|
||||||
|
|
||||||
|
if dd.Cache != nil {
|
||||||
|
disk[mkDiskCache] = *dd.Cache
|
||||||
|
} else {
|
||||||
|
disk[mkDiskCache] = dvDiskCache
|
||||||
|
}
|
||||||
|
|
||||||
|
diskMap[di] = disk
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(clone) == 0 || len(currentDiskList) > 0 {
|
||||||
|
orderedDiskList := orderedListFromMap(diskMap)
|
||||||
|
err := d.Set(mkDisk, orderedDiskList)
|
||||||
|
diags = append(diags, diag.FromErr(err)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateDisk(d *schema.ResourceData, vmConfig *vms.GetResponseData, updateBody *vms.UpdateRequestBody) error {
|
||||||
|
// Prepare the new disk device configuration.
|
||||||
|
if !d.HasChange(mkDisk) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
diskDeviceObjects, err := vmGetDiskDeviceObjects(d, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
diskDeviceInfo := getDiskInfo(vmConfig, d)
|
||||||
|
|
||||||
|
for prefix, diskMap := range diskDeviceObjects {
|
||||||
|
if diskMap == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range diskMap {
|
||||||
|
if diskDeviceInfo[key] == nil {
|
||||||
|
// TODO: create a new disk here
|
||||||
|
return fmt.Errorf("missing %s device %s", prefix, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp := *diskDeviceInfo[key]
|
||||||
|
tmp.BurstableReadSpeedMbps = value.BurstableReadSpeedMbps
|
||||||
|
tmp.BurstableWriteSpeedMbps = value.BurstableWriteSpeedMbps
|
||||||
|
tmp.MaxReadSpeedMbps = value.MaxReadSpeedMbps
|
||||||
|
tmp.MaxWriteSpeedMbps = value.MaxWriteSpeedMbps
|
||||||
|
tmp.Cache = value.Cache
|
||||||
|
|
||||||
|
switch prefix {
|
||||||
|
case "virtio":
|
||||||
|
{
|
||||||
|
if updateBody.VirtualIODevices == nil {
|
||||||
|
updateBody.VirtualIODevices = vms.CustomStorageDevices{}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateBody.VirtualIODevices[key] = tmp
|
||||||
|
}
|
||||||
|
case "sata":
|
||||||
|
{
|
||||||
|
if updateBody.SATADevices == nil {
|
||||||
|
updateBody.SATADevices = vms.CustomStorageDevices{}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateBody.SATADevices[key] = tmp
|
||||||
|
}
|
||||||
|
case "scsi":
|
||||||
|
{
|
||||||
|
if updateBody.SCSIDevices == nil {
|
||||||
|
updateBody.SCSIDevices = vms.CustomStorageDevices{}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateBody.SCSIDevices[key] = tmp
|
||||||
|
}
|
||||||
|
case "ide":
|
||||||
|
{
|
||||||
|
// Investigate whether to support IDE mapping.
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("device prefix %s not supported", prefix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
492
proxmoxtf/resource/vm/vm_test.go
Normal file
492
proxmoxtf/resource/vm/vm_test.go
Normal file
@ -0,0 +1,492 @@
|
|||||||
|
/*
|
||||||
|
* 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 vm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestVMInstantiation tests whether the VM instance can be instantiated.
|
||||||
|
func TestVMInstantiation(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
s := VM()
|
||||||
|
if s == nil {
|
||||||
|
t.Fatalf("Cannot instantiate VM")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestVMSchema tests the VM schema.
|
||||||
|
func TestVMSchema(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
s := VM()
|
||||||
|
|
||||||
|
test.AssertRequiredArguments(t, s, []string{
|
||||||
|
mkNodeName,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, s, []string{
|
||||||
|
mkACPI,
|
||||||
|
mkAgent,
|
||||||
|
mkAudioDevice,
|
||||||
|
mkBIOS,
|
||||||
|
mkBootOrder,
|
||||||
|
mkCDROM,
|
||||||
|
mkClone,
|
||||||
|
mkCPU,
|
||||||
|
mkDescription,
|
||||||
|
mkDisk,
|
||||||
|
mkEFIDisk,
|
||||||
|
mkInitialization,
|
||||||
|
mkHostPCI,
|
||||||
|
mkHostUSB,
|
||||||
|
mkKeyboardLayout,
|
||||||
|
mkKVMArguments,
|
||||||
|
mkMachine,
|
||||||
|
mkMemory,
|
||||||
|
mkName,
|
||||||
|
mkNetworkDevice,
|
||||||
|
mkOperatingSystem,
|
||||||
|
mkPoolID,
|
||||||
|
mkSerialDevice,
|
||||||
|
mkStarted,
|
||||||
|
mkTabletDevice,
|
||||||
|
mkTemplate,
|
||||||
|
mkVMID,
|
||||||
|
mkSCSIHardware,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertComputedAttributes(t, s, []string{
|
||||||
|
mkIPv4Addresses,
|
||||||
|
mkIPv6Addresses,
|
||||||
|
mkMACAddresses,
|
||||||
|
mkNetworkInterfaceNames,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, s, map[string]schema.ValueType{
|
||||||
|
mkACPI: schema.TypeBool,
|
||||||
|
mkAgent: schema.TypeList,
|
||||||
|
mkAudioDevice: schema.TypeList,
|
||||||
|
mkBIOS: schema.TypeString,
|
||||||
|
mkBootOrder: schema.TypeList,
|
||||||
|
mkCDROM: schema.TypeList,
|
||||||
|
mkCPU: schema.TypeList,
|
||||||
|
mkDescription: schema.TypeString,
|
||||||
|
mkDisk: schema.TypeList,
|
||||||
|
mkEFIDisk: schema.TypeList,
|
||||||
|
mkHostPCI: schema.TypeList,
|
||||||
|
mkHostUSB: schema.TypeList,
|
||||||
|
mkInitialization: schema.TypeList,
|
||||||
|
mkIPv4Addresses: schema.TypeList,
|
||||||
|
mkIPv6Addresses: schema.TypeList,
|
||||||
|
mkKeyboardLayout: schema.TypeString,
|
||||||
|
mkKVMArguments: schema.TypeString,
|
||||||
|
mkMachine: schema.TypeString,
|
||||||
|
mkMemory: schema.TypeList,
|
||||||
|
mkName: schema.TypeString,
|
||||||
|
mkNetworkDevice: schema.TypeList,
|
||||||
|
mkMACAddresses: schema.TypeList,
|
||||||
|
mkNetworkInterfaceNames: schema.TypeList,
|
||||||
|
mkOperatingSystem: schema.TypeList,
|
||||||
|
mkPoolID: schema.TypeString,
|
||||||
|
mkSerialDevice: schema.TypeList,
|
||||||
|
mkStarted: schema.TypeBool,
|
||||||
|
mkTabletDevice: schema.TypeBool,
|
||||||
|
mkTemplate: schema.TypeBool,
|
||||||
|
mkVMID: schema.TypeInt,
|
||||||
|
mkSCSIHardware: schema.TypeString,
|
||||||
|
})
|
||||||
|
|
||||||
|
agentSchema := test.AssertNestedSchemaExistence(t, s, mkAgent)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, agentSchema, []string{
|
||||||
|
mkAgentEnabled,
|
||||||
|
mkAgentTimeout,
|
||||||
|
mkAgentTrim,
|
||||||
|
mkAgentType,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, agentSchema, map[string]schema.ValueType{
|
||||||
|
mkAgentEnabled: schema.TypeBool,
|
||||||
|
mkAgentTrim: schema.TypeBool,
|
||||||
|
mkAgentType: schema.TypeString,
|
||||||
|
})
|
||||||
|
|
||||||
|
audioDeviceSchema := test.AssertNestedSchemaExistence(t, s, mkAudioDevice)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, audioDeviceSchema, []string{
|
||||||
|
mkAudioDeviceDevice,
|
||||||
|
mkAudioDeviceDriver,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, audioDeviceSchema, map[string]schema.ValueType{
|
||||||
|
mkAudioDeviceDevice: schema.TypeString,
|
||||||
|
mkAudioDeviceDriver: schema.TypeString,
|
||||||
|
})
|
||||||
|
|
||||||
|
cdromSchema := test.AssertNestedSchemaExistence(t, s, mkCDROM)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, cdromSchema, []string{
|
||||||
|
mkCDROMEnabled,
|
||||||
|
mkCDROMFileID,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, cdromSchema, map[string]schema.ValueType{
|
||||||
|
mkCDROMEnabled: schema.TypeBool,
|
||||||
|
mkCDROMFileID: schema.TypeString,
|
||||||
|
})
|
||||||
|
|
||||||
|
cloneSchema := test.AssertNestedSchemaExistence(t, s, mkClone)
|
||||||
|
|
||||||
|
test.AssertRequiredArguments(t, cloneSchema, []string{
|
||||||
|
mkCloneVMID,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, cloneSchema, []string{
|
||||||
|
mkCloneDatastoreID,
|
||||||
|
mkCloneNodeName,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, cloneSchema, map[string]schema.ValueType{
|
||||||
|
mkCloneDatastoreID: schema.TypeString,
|
||||||
|
mkCloneNodeName: schema.TypeString,
|
||||||
|
mkCloneVMID: schema.TypeInt,
|
||||||
|
})
|
||||||
|
|
||||||
|
cpuSchema := test.AssertNestedSchemaExistence(t, s, mkCPU)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, cpuSchema, []string{
|
||||||
|
mkCPUArchitecture,
|
||||||
|
mkCPUCores,
|
||||||
|
mkCPUFlags,
|
||||||
|
mkCPUHotplugged,
|
||||||
|
mkCPUNUMA,
|
||||||
|
mkCPUSockets,
|
||||||
|
mkCPUType,
|
||||||
|
mkCPUUnits,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, cpuSchema, map[string]schema.ValueType{
|
||||||
|
mkCPUArchitecture: schema.TypeString,
|
||||||
|
mkCPUCores: schema.TypeInt,
|
||||||
|
mkCPUFlags: schema.TypeList,
|
||||||
|
mkCPUHotplugged: schema.TypeInt,
|
||||||
|
mkCPUNUMA: schema.TypeBool,
|
||||||
|
mkCPUSockets: schema.TypeInt,
|
||||||
|
mkCPUType: schema.TypeString,
|
||||||
|
mkCPUUnits: schema.TypeInt,
|
||||||
|
})
|
||||||
|
|
||||||
|
diskSchema := test.AssertNestedSchemaExistence(t, s, mkDisk)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, diskSchema, []string{
|
||||||
|
mkDiskDatastoreID,
|
||||||
|
mkDiskPathInDatastore,
|
||||||
|
mkDiskFileFormat,
|
||||||
|
mkDiskFileID,
|
||||||
|
mkDiskSize,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, diskSchema, map[string]schema.ValueType{
|
||||||
|
mkDiskDatastoreID: schema.TypeString,
|
||||||
|
mkDiskPathInDatastore: schema.TypeString,
|
||||||
|
mkDiskFileFormat: schema.TypeString,
|
||||||
|
mkDiskFileID: schema.TypeString,
|
||||||
|
mkDiskSize: schema.TypeInt,
|
||||||
|
})
|
||||||
|
|
||||||
|
diskSpeedSchema := test.AssertNestedSchemaExistence(
|
||||||
|
t,
|
||||||
|
diskSchema,
|
||||||
|
mkDiskSpeed,
|
||||||
|
)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, diskSpeedSchema, []string{
|
||||||
|
mkDiskSpeedRead,
|
||||||
|
mkDiskSpeedReadBurstable,
|
||||||
|
mkDiskSpeedWrite,
|
||||||
|
mkDiskSpeedWriteBurstable,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, diskSpeedSchema, map[string]schema.ValueType{
|
||||||
|
mkDiskSpeedRead: schema.TypeInt,
|
||||||
|
mkDiskSpeedReadBurstable: schema.TypeInt,
|
||||||
|
mkDiskSpeedWrite: schema.TypeInt,
|
||||||
|
mkDiskSpeedWriteBurstable: schema.TypeInt,
|
||||||
|
})
|
||||||
|
|
||||||
|
efiDiskSchema := test.AssertNestedSchemaExistence(t, s, mkEFIDisk)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, efiDiskSchema, []string{
|
||||||
|
mkEFIDiskDatastoreID,
|
||||||
|
mkEFIDiskFileFormat,
|
||||||
|
mkEFIDiskType,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, efiDiskSchema, map[string]schema.ValueType{
|
||||||
|
mkEFIDiskDatastoreID: schema.TypeString,
|
||||||
|
mkEFIDiskFileFormat: schema.TypeString,
|
||||||
|
mkEFIDiskType: schema.TypeString,
|
||||||
|
})
|
||||||
|
|
||||||
|
initializationSchema := test.AssertNestedSchemaExistence(
|
||||||
|
t,
|
||||||
|
s,
|
||||||
|
mkInitialization,
|
||||||
|
)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, initializationSchema, []string{
|
||||||
|
mkInitializationDatastoreID,
|
||||||
|
mkInitializationInterface,
|
||||||
|
mkInitializationDNS,
|
||||||
|
mkInitializationIPConfig,
|
||||||
|
mkInitializationUserAccount,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, initializationSchema, map[string]schema.ValueType{
|
||||||
|
mkInitializationDatastoreID: schema.TypeString,
|
||||||
|
mkInitializationInterface: schema.TypeString,
|
||||||
|
mkInitializationDNS: schema.TypeList,
|
||||||
|
mkInitializationIPConfig: schema.TypeList,
|
||||||
|
mkInitializationUserAccount: schema.TypeList,
|
||||||
|
})
|
||||||
|
|
||||||
|
hostPCISchema := test.AssertNestedSchemaExistence(t, s, mkHostPCI)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, hostPCISchema, []string{
|
||||||
|
mkHostPCIDeviceMDev,
|
||||||
|
mkHostPCIDevicePCIE,
|
||||||
|
mkHostPCIDeviceROMBAR,
|
||||||
|
mkHostPCIDeviceROMFile,
|
||||||
|
mkHostPCIDeviceXVGA,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, hostPCISchema, map[string]schema.ValueType{
|
||||||
|
mkHostPCIDevice: schema.TypeString,
|
||||||
|
mkHostPCIDeviceMDev: schema.TypeString,
|
||||||
|
mkHostPCIDevicePCIE: schema.TypeBool,
|
||||||
|
mkHostPCIDeviceROMBAR: schema.TypeBool,
|
||||||
|
mkHostPCIDeviceROMFile: schema.TypeString,
|
||||||
|
mkHostPCIDeviceXVGA: schema.TypeBool,
|
||||||
|
})
|
||||||
|
|
||||||
|
hostUSBSchema := test.AssertNestedSchemaExistence(t, s, mkHostUSB)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, hostUSBSchema, []string{
|
||||||
|
mkHostUSBDeviceMapping,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, hostUSBSchema, map[string]schema.ValueType{
|
||||||
|
mkHostUSBDevice: schema.TypeString,
|
||||||
|
mkHostUSBDeviceUSB3: schema.TypeBool,
|
||||||
|
})
|
||||||
|
|
||||||
|
initializationDNSSchema := test.AssertNestedSchemaExistence(
|
||||||
|
t,
|
||||||
|
initializationSchema,
|
||||||
|
mkInitializationDNS,
|
||||||
|
)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, initializationDNSSchema, []string{
|
||||||
|
mkInitializationDNSDomain,
|
||||||
|
mkInitializationDNSServer,
|
||||||
|
mkInitializationDNSServers,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, initializationDNSSchema, map[string]schema.ValueType{
|
||||||
|
mkInitializationDNSDomain: schema.TypeString,
|
||||||
|
mkInitializationDNSServer: schema.TypeString,
|
||||||
|
mkInitializationDNSServers: schema.TypeList,
|
||||||
|
})
|
||||||
|
|
||||||
|
initializationIPConfigSchema := test.AssertNestedSchemaExistence(
|
||||||
|
t,
|
||||||
|
initializationSchema,
|
||||||
|
mkInitializationIPConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, initializationIPConfigSchema, []string{
|
||||||
|
mkInitializationIPConfigIPv4,
|
||||||
|
mkInitializationIPConfigIPv6,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, initializationIPConfigSchema, map[string]schema.ValueType{
|
||||||
|
mkInitializationIPConfigIPv4: schema.TypeList,
|
||||||
|
mkInitializationIPConfigIPv6: schema.TypeList,
|
||||||
|
})
|
||||||
|
|
||||||
|
initializationIPConfigIPv4Schema := test.AssertNestedSchemaExistence(
|
||||||
|
t,
|
||||||
|
initializationIPConfigSchema,
|
||||||
|
mkInitializationIPConfigIPv4,
|
||||||
|
)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, initializationIPConfigIPv4Schema, []string{
|
||||||
|
mkInitializationIPConfigIPv4Address,
|
||||||
|
mkInitializationIPConfigIPv4Gateway,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, initializationIPConfigIPv4Schema, map[string]schema.ValueType{
|
||||||
|
mkInitializationIPConfigIPv4Address: schema.TypeString,
|
||||||
|
mkInitializationIPConfigIPv4Gateway: schema.TypeString,
|
||||||
|
})
|
||||||
|
|
||||||
|
initializationIPConfigIPv6Schema := test.AssertNestedSchemaExistence(
|
||||||
|
t,
|
||||||
|
initializationIPConfigSchema,
|
||||||
|
mkInitializationIPConfigIPv6,
|
||||||
|
)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, initializationIPConfigIPv6Schema, []string{
|
||||||
|
mkInitializationIPConfigIPv6Address,
|
||||||
|
mkInitializationIPConfigIPv6Gateway,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, initializationIPConfigIPv6Schema, map[string]schema.ValueType{
|
||||||
|
mkInitializationIPConfigIPv6Address: schema.TypeString,
|
||||||
|
mkInitializationIPConfigIPv6Gateway: schema.TypeString,
|
||||||
|
})
|
||||||
|
|
||||||
|
initializationUserAccountSchema := test.AssertNestedSchemaExistence(
|
||||||
|
t,
|
||||||
|
initializationSchema,
|
||||||
|
mkInitializationUserAccount,
|
||||||
|
)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, initializationUserAccountSchema, []string{
|
||||||
|
mkInitializationUserAccountKeys,
|
||||||
|
mkInitializationUserAccountPassword,
|
||||||
|
mkInitializationUserAccountUsername,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, initializationUserAccountSchema, map[string]schema.ValueType{
|
||||||
|
mkInitializationUserAccountKeys: schema.TypeList,
|
||||||
|
mkInitializationUserAccountPassword: schema.TypeString,
|
||||||
|
mkInitializationUserAccountUsername: schema.TypeString,
|
||||||
|
})
|
||||||
|
|
||||||
|
memorySchema := test.AssertNestedSchemaExistence(t, s, mkMemory)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, memorySchema, []string{
|
||||||
|
mkMemoryDedicated,
|
||||||
|
mkMemoryFloating,
|
||||||
|
mkMemoryShared,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, memorySchema, map[string]schema.ValueType{
|
||||||
|
mkMemoryDedicated: schema.TypeInt,
|
||||||
|
mkMemoryFloating: schema.TypeInt,
|
||||||
|
mkMemoryShared: schema.TypeInt,
|
||||||
|
})
|
||||||
|
|
||||||
|
networkDeviceSchema := test.AssertNestedSchemaExistence(
|
||||||
|
t,
|
||||||
|
s,
|
||||||
|
mkNetworkDevice,
|
||||||
|
)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, networkDeviceSchema, []string{
|
||||||
|
mkNetworkDeviceBridge,
|
||||||
|
mkNetworkDeviceEnabled,
|
||||||
|
mkNetworkDeviceMACAddress,
|
||||||
|
mkNetworkDeviceModel,
|
||||||
|
mkNetworkDeviceRateLimit,
|
||||||
|
mkNetworkDeviceVLANID,
|
||||||
|
mkNetworkDeviceMTU,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, networkDeviceSchema, map[string]schema.ValueType{
|
||||||
|
mkNetworkDeviceBridge: schema.TypeString,
|
||||||
|
mkNetworkDeviceEnabled: schema.TypeBool,
|
||||||
|
mkNetworkDeviceMACAddress: schema.TypeString,
|
||||||
|
mkNetworkDeviceModel: schema.TypeString,
|
||||||
|
mkNetworkDeviceRateLimit: schema.TypeFloat,
|
||||||
|
mkNetworkDeviceVLANID: schema.TypeInt,
|
||||||
|
mkNetworkDeviceMTU: schema.TypeInt,
|
||||||
|
})
|
||||||
|
|
||||||
|
operatingSystemSchema := test.AssertNestedSchemaExistence(
|
||||||
|
t,
|
||||||
|
s,
|
||||||
|
mkOperatingSystem,
|
||||||
|
)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, operatingSystemSchema, []string{
|
||||||
|
mkOperatingSystemType,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, operatingSystemSchema, map[string]schema.ValueType{
|
||||||
|
mkOperatingSystemType: schema.TypeString,
|
||||||
|
})
|
||||||
|
|
||||||
|
serialDeviceSchema := test.AssertNestedSchemaExistence(
|
||||||
|
t,
|
||||||
|
s,
|
||||||
|
mkSerialDevice,
|
||||||
|
)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, serialDeviceSchema, []string{
|
||||||
|
mkSerialDeviceDevice,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, serialDeviceSchema, map[string]schema.ValueType{
|
||||||
|
mkSerialDeviceDevice: schema.TypeString,
|
||||||
|
})
|
||||||
|
|
||||||
|
vgaSchema := test.AssertNestedSchemaExistence(t, s, mkVGA)
|
||||||
|
|
||||||
|
test.AssertOptionalArguments(t, vgaSchema, []string{
|
||||||
|
mkVGAEnabled,
|
||||||
|
mkVGAMemory,
|
||||||
|
mkVGAType,
|
||||||
|
})
|
||||||
|
|
||||||
|
test.AssertValueTypes(t, vgaSchema, map[string]schema.ValueType{
|
||||||
|
mkVGAEnabled: schema.TypeBool,
|
||||||
|
mkVGAMemory: schema.TypeInt,
|
||||||
|
mkVGAType: schema.TypeString,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_parseImportIDWIthNodeName(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
value string
|
||||||
|
valid bool
|
||||||
|
expectedNodeName string
|
||||||
|
expectedID string
|
||||||
|
}{
|
||||||
|
{"empty", "", false, "", ""},
|
||||||
|
{"missing slash", "invalid", false, "", ""},
|
||||||
|
{"valid", "host/id", true, "host", "id"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
nodeName, id, err := parseImportIDWithNodeName(tt.value)
|
||||||
|
|
||||||
|
if !tt.valid {
|
||||||
|
require.Error(t, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, tt.expectedNodeName, nodeName)
|
||||||
|
require.Equal(t, tt.expectedID, id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,492 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 resource
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/test"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TestVMInstantiation tests whether the VM instance can be instantiated.
|
|
||||||
func TestVMInstantiation(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
s := VM()
|
|
||||||
if s == nil {
|
|
||||||
t.Fatalf("Cannot instantiate VM")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestVMSchema tests the VM schema.
|
|
||||||
func TestVMSchema(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
s := VM()
|
|
||||||
|
|
||||||
test.AssertRequiredArguments(t, s, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMNodeName,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, s, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMACPI,
|
|
||||||
mkResourceVirtualEnvironmentVMAgent,
|
|
||||||
mkResourceVirtualEnvironmentVMAudioDevice,
|
|
||||||
mkResourceVirtualEnvironmentVMBIOS,
|
|
||||||
mkResourceVirtualEnvironmentVMBootOrder,
|
|
||||||
mkResourceVirtualEnvironmentVMCDROM,
|
|
||||||
mkResourceVirtualEnvironmentVMClone,
|
|
||||||
mkResourceVirtualEnvironmentVMCPU,
|
|
||||||
mkResourceVirtualEnvironmentVMDescription,
|
|
||||||
mkResourceVirtualEnvironmentVMDisk,
|
|
||||||
mkResourceVirtualEnvironmentVMEFIDisk,
|
|
||||||
mkResourceVirtualEnvironmentVMInitialization,
|
|
||||||
mkResourceVirtualEnvironmentVMHostPCI,
|
|
||||||
mkResourceVirtualEnvironmentVMHostUSB,
|
|
||||||
mkResourceVirtualEnvironmentVMKeyboardLayout,
|
|
||||||
mkResourceVirtualEnvironmentVMKVMArguments,
|
|
||||||
mkResourceVirtualEnvironmentVMMachine,
|
|
||||||
mkResourceVirtualEnvironmentVMMemory,
|
|
||||||
mkResourceVirtualEnvironmentVMName,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDevice,
|
|
||||||
mkResourceVirtualEnvironmentVMOperatingSystem,
|
|
||||||
mkResourceVirtualEnvironmentVMPoolID,
|
|
||||||
mkResourceVirtualEnvironmentVMSerialDevice,
|
|
||||||
mkResourceVirtualEnvironmentVMStarted,
|
|
||||||
mkResourceVirtualEnvironmentVMTabletDevice,
|
|
||||||
mkResourceVirtualEnvironmentVMTemplate,
|
|
||||||
mkResourceVirtualEnvironmentVMVMID,
|
|
||||||
mkResourceVirtualEnvironmentVMSCSIHardware,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertComputedAttributes(t, s, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMIPv4Addresses,
|
|
||||||
mkResourceVirtualEnvironmentVMIPv6Addresses,
|
|
||||||
mkResourceVirtualEnvironmentVMMACAddresses,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkInterfaceNames,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, s, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMACPI: schema.TypeBool,
|
|
||||||
mkResourceVirtualEnvironmentVMAgent: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMAudioDevice: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMBIOS: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMBootOrder: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMCDROM: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMCPU: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMDescription: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMDisk: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMEFIDisk: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMHostPCI: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMHostUSB: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMInitialization: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMIPv4Addresses: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMIPv6Addresses: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMKeyboardLayout: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMKVMArguments: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMMachine: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMMemory: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMName: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDevice: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMMACAddresses: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkInterfaceNames: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMOperatingSystem: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMPoolID: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMSerialDevice: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMStarted: schema.TypeBool,
|
|
||||||
mkResourceVirtualEnvironmentVMTabletDevice: schema.TypeBool,
|
|
||||||
mkResourceVirtualEnvironmentVMTemplate: schema.TypeBool,
|
|
||||||
mkResourceVirtualEnvironmentVMVMID: schema.TypeInt,
|
|
||||||
mkResourceVirtualEnvironmentVMSCSIHardware: schema.TypeString,
|
|
||||||
})
|
|
||||||
|
|
||||||
agentSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMAgent)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, agentSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMAgentEnabled,
|
|
||||||
mkResourceVirtualEnvironmentVMAgentTimeout,
|
|
||||||
mkResourceVirtualEnvironmentVMAgentTrim,
|
|
||||||
mkResourceVirtualEnvironmentVMAgentType,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, agentSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMAgentEnabled: schema.TypeBool,
|
|
||||||
mkResourceVirtualEnvironmentVMAgentTrim: schema.TypeBool,
|
|
||||||
mkResourceVirtualEnvironmentVMAgentType: schema.TypeString,
|
|
||||||
})
|
|
||||||
|
|
||||||
audioDeviceSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMAudioDevice)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, audioDeviceSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMAudioDeviceDevice,
|
|
||||||
mkResourceVirtualEnvironmentVMAudioDeviceDriver,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, audioDeviceSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMAudioDeviceDevice: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMAudioDeviceDriver: schema.TypeString,
|
|
||||||
})
|
|
||||||
|
|
||||||
cdromSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMCDROM)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, cdromSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMCDROMEnabled,
|
|
||||||
mkResourceVirtualEnvironmentVMCDROMFileID,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, cdromSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMCDROMEnabled: schema.TypeBool,
|
|
||||||
mkResourceVirtualEnvironmentVMCDROMFileID: schema.TypeString,
|
|
||||||
})
|
|
||||||
|
|
||||||
cloneSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMClone)
|
|
||||||
|
|
||||||
test.AssertRequiredArguments(t, cloneSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMCloneVMID,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, cloneSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMCloneDatastoreID,
|
|
||||||
mkResourceVirtualEnvironmentVMCloneNodeName,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, cloneSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMCloneDatastoreID: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMCloneNodeName: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMCloneVMID: schema.TypeInt,
|
|
||||||
})
|
|
||||||
|
|
||||||
cpuSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMCPU)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, cpuSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMCPUArchitecture,
|
|
||||||
mkResourceVirtualEnvironmentVMCPUCores,
|
|
||||||
mkResourceVirtualEnvironmentVMCPUFlags,
|
|
||||||
mkResourceVirtualEnvironmentVMCPUHotplugged,
|
|
||||||
mkResourceVirtualEnvironmentVMCPUNUMA,
|
|
||||||
mkResourceVirtualEnvironmentVMCPUSockets,
|
|
||||||
mkResourceVirtualEnvironmentVMCPUType,
|
|
||||||
mkResourceVirtualEnvironmentVMCPUUnits,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, cpuSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMCPUArchitecture: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMCPUCores: schema.TypeInt,
|
|
||||||
mkResourceVirtualEnvironmentVMCPUFlags: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMCPUHotplugged: schema.TypeInt,
|
|
||||||
mkResourceVirtualEnvironmentVMCPUNUMA: schema.TypeBool,
|
|
||||||
mkResourceVirtualEnvironmentVMCPUSockets: schema.TypeInt,
|
|
||||||
mkResourceVirtualEnvironmentVMCPUType: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMCPUUnits: schema.TypeInt,
|
|
||||||
})
|
|
||||||
|
|
||||||
diskSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMDisk)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, diskSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMDiskDatastoreID,
|
|
||||||
mkResourceVirtualEnvironmentVMDiskPathInDatastore,
|
|
||||||
mkResourceVirtualEnvironmentVMDiskFileFormat,
|
|
||||||
mkResourceVirtualEnvironmentVMDiskFileID,
|
|
||||||
mkResourceVirtualEnvironmentVMDiskSize,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, diskSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMDiskDatastoreID: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMDiskPathInDatastore: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMDiskFileFormat: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMDiskFileID: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMDiskSize: schema.TypeInt,
|
|
||||||
})
|
|
||||||
|
|
||||||
diskSpeedSchema := test.AssertNestedSchemaExistence(
|
|
||||||
t,
|
|
||||||
diskSchema,
|
|
||||||
mkResourceVirtualEnvironmentVMDiskSpeed,
|
|
||||||
)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, diskSpeedSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMDiskSpeedRead,
|
|
||||||
mkResourceVirtualEnvironmentVMDiskSpeedReadBurstable,
|
|
||||||
mkResourceVirtualEnvironmentVMDiskSpeedWrite,
|
|
||||||
mkResourceVirtualEnvironmentVMDiskSpeedWriteBurstable,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, diskSpeedSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMDiskSpeedRead: schema.TypeInt,
|
|
||||||
mkResourceVirtualEnvironmentVMDiskSpeedReadBurstable: schema.TypeInt,
|
|
||||||
mkResourceVirtualEnvironmentVMDiskSpeedWrite: schema.TypeInt,
|
|
||||||
mkResourceVirtualEnvironmentVMDiskSpeedWriteBurstable: schema.TypeInt,
|
|
||||||
})
|
|
||||||
|
|
||||||
efiDiskSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMEFIDisk)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, efiDiskSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMEFIDiskDatastoreID,
|
|
||||||
mkResourceVirtualEnvironmentVMEFIDiskFileFormat,
|
|
||||||
mkResourceVirtualEnvironmentVMEFIDiskType,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, efiDiskSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMEFIDiskDatastoreID: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMEFIDiskFileFormat: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMEFIDiskType: schema.TypeString,
|
|
||||||
})
|
|
||||||
|
|
||||||
initializationSchema := test.AssertNestedSchemaExistence(
|
|
||||||
t,
|
|
||||||
s,
|
|
||||||
mkResourceVirtualEnvironmentVMInitialization,
|
|
||||||
)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, initializationSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationDatastoreID,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationInterface,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationDNS,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfig,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationUserAccount,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, initializationSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationDatastoreID: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationInterface: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationDNS: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfig: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationUserAccount: schema.TypeList,
|
|
||||||
})
|
|
||||||
|
|
||||||
hostPCISchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMHostPCI)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, hostPCISchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMHostPCIDeviceMDev,
|
|
||||||
mkResourceVirtualEnvironmentVMHostPCIDevicePCIE,
|
|
||||||
mkResourceVirtualEnvironmentVMHostPCIDeviceROMBAR,
|
|
||||||
mkResourceVirtualEnvironmentVMHostPCIDeviceROMFile,
|
|
||||||
mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, hostPCISchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMHostPCIDevice: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMHostPCIDeviceMDev: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMHostPCIDevicePCIE: schema.TypeBool,
|
|
||||||
mkResourceVirtualEnvironmentVMHostPCIDeviceROMBAR: schema.TypeBool,
|
|
||||||
mkResourceVirtualEnvironmentVMHostPCIDeviceROMFile: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMHostPCIDeviceXVGA: schema.TypeBool,
|
|
||||||
})
|
|
||||||
|
|
||||||
hostUSBSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMHostUSB)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, hostUSBSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMHostUSBDeviceMapping,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, hostUSBSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMHostUSBDevice: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMHostUSBDeviceUSB3: schema.TypeBool,
|
|
||||||
})
|
|
||||||
|
|
||||||
initializationDNSSchema := test.AssertNestedSchemaExistence(
|
|
||||||
t,
|
|
||||||
initializationSchema,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationDNS,
|
|
||||||
)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, initializationDNSSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationDNSDomain,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationDNSServer,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationDNSServers,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, initializationDNSSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationDNSDomain: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationDNSServer: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationDNSServers: schema.TypeList,
|
|
||||||
})
|
|
||||||
|
|
||||||
initializationIPConfigSchema := test.AssertNestedSchemaExistence(
|
|
||||||
t,
|
|
||||||
initializationSchema,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfig,
|
|
||||||
)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, initializationIPConfigSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, initializationIPConfigSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6: schema.TypeList,
|
|
||||||
})
|
|
||||||
|
|
||||||
initializationIPConfigIPv4Schema := test.AssertNestedSchemaExistence(
|
|
||||||
t,
|
|
||||||
initializationIPConfigSchema,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4,
|
|
||||||
)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, initializationIPConfigIPv4Schema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4Address,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4Gateway,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, initializationIPConfigIPv4Schema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4Address: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv4Gateway: schema.TypeString,
|
|
||||||
})
|
|
||||||
|
|
||||||
initializationIPConfigIPv6Schema := test.AssertNestedSchemaExistence(
|
|
||||||
t,
|
|
||||||
initializationIPConfigSchema,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6,
|
|
||||||
)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, initializationIPConfigIPv6Schema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6Address,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6Gateway,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, initializationIPConfigIPv6Schema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6Address: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationIPConfigIPv6Gateway: schema.TypeString,
|
|
||||||
})
|
|
||||||
|
|
||||||
initializationUserAccountSchema := test.AssertNestedSchemaExistence(
|
|
||||||
t,
|
|
||||||
initializationSchema,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationUserAccount,
|
|
||||||
)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, initializationUserAccountSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationUserAccountKeys,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationUserAccountPassword,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationUserAccountUsername,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, initializationUserAccountSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationUserAccountKeys: schema.TypeList,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationUserAccountPassword: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMInitializationUserAccountUsername: schema.TypeString,
|
|
||||||
})
|
|
||||||
|
|
||||||
memorySchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMMemory)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, memorySchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMMemoryDedicated,
|
|
||||||
mkResourceVirtualEnvironmentVMMemoryFloating,
|
|
||||||
mkResourceVirtualEnvironmentVMMemoryShared,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, memorySchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMMemoryDedicated: schema.TypeInt,
|
|
||||||
mkResourceVirtualEnvironmentVMMemoryFloating: schema.TypeInt,
|
|
||||||
mkResourceVirtualEnvironmentVMMemoryShared: schema.TypeInt,
|
|
||||||
})
|
|
||||||
|
|
||||||
networkDeviceSchema := test.AssertNestedSchemaExistence(
|
|
||||||
t,
|
|
||||||
s,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDevice,
|
|
||||||
)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, networkDeviceSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceBridge,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceEnabled,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceModel,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceRateLimit,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceVLANID,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceMTU,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, networkDeviceSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceBridge: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceEnabled: schema.TypeBool,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceMACAddress: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceModel: schema.TypeString,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceRateLimit: schema.TypeFloat,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceVLANID: schema.TypeInt,
|
|
||||||
mkResourceVirtualEnvironmentVMNetworkDeviceMTU: schema.TypeInt,
|
|
||||||
})
|
|
||||||
|
|
||||||
operatingSystemSchema := test.AssertNestedSchemaExistence(
|
|
||||||
t,
|
|
||||||
s,
|
|
||||||
mkResourceVirtualEnvironmentVMOperatingSystem,
|
|
||||||
)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, operatingSystemSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMOperatingSystemType,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, operatingSystemSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMOperatingSystemType: schema.TypeString,
|
|
||||||
})
|
|
||||||
|
|
||||||
serialDeviceSchema := test.AssertNestedSchemaExistence(
|
|
||||||
t,
|
|
||||||
s,
|
|
||||||
mkResourceVirtualEnvironmentVMSerialDevice,
|
|
||||||
)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, serialDeviceSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMSerialDeviceDevice,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, serialDeviceSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMSerialDeviceDevice: schema.TypeString,
|
|
||||||
})
|
|
||||||
|
|
||||||
vgaSchema := test.AssertNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentVMVGA)
|
|
||||||
|
|
||||||
test.AssertOptionalArguments(t, vgaSchema, []string{
|
|
||||||
mkResourceVirtualEnvironmentVMVGAEnabled,
|
|
||||||
mkResourceVirtualEnvironmentVMVGAMemory,
|
|
||||||
mkResourceVirtualEnvironmentVMVGAType,
|
|
||||||
})
|
|
||||||
|
|
||||||
test.AssertValueTypes(t, vgaSchema, map[string]schema.ValueType{
|
|
||||||
mkResourceVirtualEnvironmentVMVGAEnabled: schema.TypeBool,
|
|
||||||
mkResourceVirtualEnvironmentVMVGAMemory: schema.TypeInt,
|
|
||||||
mkResourceVirtualEnvironmentVMVGAType: schema.TypeString,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_parseImportIDWIthNodeName(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
value string
|
|
||||||
valid bool
|
|
||||||
expectedNodeName string
|
|
||||||
expectedID string
|
|
||||||
}{
|
|
||||||
{"empty", "", false, "", ""},
|
|
||||||
{"missing slash", "invalid", false, "", ""},
|
|
||||||
{"valid", "host/id", true, "host", "id"},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
tt := tt
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
nodeName, id, err := parseImportIDWithNodeName(tt.value)
|
|
||||||
|
|
||||||
if !tt.valid {
|
|
||||||
require.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, tt.expectedNodeName, nodeName)
|
|
||||||
require.Equal(t, tt.expectedID, id)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user